Annotation of nono/exp/optestm88k/optestm88k_main.c, revision 1.1.1.4

1.1.1.4 ! root        1: /* vi:set ts=4: */
1.1       root        2: /*
                      3:  * nono
                      4:  * Copyright (C) 2021 nono project
                      5:  * Licensed under nono-license.txt
                      6:  */
                      7: 
                      8: #include "optestm88k_main.h"
1.1.1.3   root        9: #include <ieeefp.h>
                     10: #include <getopt.h>
1.1       root       11: #include <setjmp.h>
                     12: #include <signal.h>
1.1.1.3   root       13: #include <stdio.h>
1.1       root       14: #include <stdlib.h>
1.1.1.4 ! root       15: #include <string.h>
1.1       root       16: #include <sys/siginfo.h>
                     17: 
                     18: // グローバルワーク (r2 でアセンブラに渡される)
1.1.1.3   root       19: // define の値を code.s と揃えること
                     20: int global_work[6];
1.1       root       21: 
                     22: // オーバーフロー例外なら 1、除算例外なら 2 をセットする。
                     23: // テスト前に 0 で初期化しておくこと。
                     24: #define exception_occurred (global_work[0])
1.1.1.3   root       25: // 例外を期待しないなら 0、期待するなら例外ごとのマスク値 (テスト側が書く)
1.1       root       26: #define exception_expected (global_work[1])
1.1.1.3   root       27: // 期待値と結果 (表示用)
                     28: #define expected_val   (global_work[2])
                     29: #define expected_val2  (global_work[3])
                     30: #define actual_val (global_work[4])
                     31: #define actual_val2    (global_work[5])
                     32: 
                     33: static void
                     34: usage()
                     35: {
                     36:    printf("usage: %s [<testname>]\n", getprogname());
                     37:    exit(1);
                     38: }
1.1       root       39: 
                     40: static void
1.1.1.2   root       41: signal_handler(int signo, siginfo_t *si, void *ctx)
1.1       root       42: {
1.1.1.3   root       43:    switch (si->si_signo) {
                     44:     case SIGFPE:
1.1       root       45:        if (si->si_code == FPE_INTOVF) {
1.1.1.3   root       46:            exception_occurred = 0x0001;
1.1       root       47:            return;
                     48:        } else if (si->si_code == FPE_INTDIV) {
1.1.1.3   root       49:            exception_occurred = 0x0002;
1.1       root       50:            return;
                     51:        }
1.1.1.2   root       52:        printf("%s: signo=SIGFPE si_code=%x\n", __func__, si->si_code);
1.1.1.3   root       53:        break;
                     54:     case SIGILL:
1.1.1.2   root       55:        if (si->si_code == ILL_ILLOPC) {
                     56:            exception_occurred = 0x1000;
                     57:            return;
                     58:        }
                     59:        printf("%s: signo=SIGILL si_code=%x\n", __func__, si->si_code);
1.1.1.3   root       60:        break;
                     61: 
                     62:     default:
                     63:        printf("%s: signo=%d si_code=%x\n", __func__,
                     64:            si->si_signo, si->si_code);
                     65:        break;
1.1       root       66:    }
                     67:    // XXX
                     68:    exception_occurred = -1;
                     69: }
                     70: 
                     71: int
                     72: main(int ac, char *av[])
                     73: {
1.1.1.3   root       74:    char cause[128];
1.1       root       75:    struct testentry *t;
                     76:    func_t func;
                     77:    const char *arg_name = "";
1.1.1.3   root       78:    int c;
1.1       root       79:    int i;
                     80:    int j;
                     81:    int num;
                     82:    int res;
1.1.1.3   root       83:    int failed;
                     84:    int total_failed;
                     85:    fp_rnd rnd_backup;
                     86: 
                     87:    while ((c = getopt(ac, av, "")) != -1) {
                     88:        switch (c) {
                     89:         default:
                     90:            usage();
                     91:            break;
                     92:        }
                     93:    }
                     94:    ac -= optind;
                     95:    av += optind;
                     96:    if (ac > 1) {
                     97:        usage();
1.1       root       98:    }
1.1.1.3   root       99:    if (ac == 1) {
                    100:        arg_name = av[0];
                    101:    }
                    102: 
                    103:    rnd_backup = fpgetround();
1.1       root      104: 
                    105:    struct sigaction act;
                    106:    memset(&act, 0, sizeof(act));
1.1.1.2   root      107:    act.sa_sigaction = signal_handler;
1.1       root      108:    act.sa_flags = SA_SIGINFO;
                    109:    sigaction(SIGFPE, &act, NULL);
1.1.1.2   root      110:    sigaction(SIGILL, &act, NULL);
1.1       root      111: 
1.1.1.3   root      112:    total_failed = 0;
1.1       root      113:    for (i = j = 0; test_table[i].code != NULL; i++, j = 0) {
1.1.1.3   root      114:        failed = 0;
1.1       root      115:        t = &test_table[i];
                    116: 
                    117:        if (strncasecmp(t->testname, arg_name, strlen(arg_name)) != 0) {
1.1.1.3   root      118:            continue;
1.1       root      119:        }
                    120: 
                    121:        if (j == 0) {
                    122:            // テスト数を数える
                    123:            for (num = 0; t->testdata[num] != NULL; num++)
                    124:                ;
                    125: 
                    126:            printf("%s (%d) ... ", t->testname, num);
                    127:            fflush(stdout);
                    128:        }
                    129: 
                    130:        for (; j < num; j++) {
                    131:            exception_occurred = 0;
                    132: 
                    133:            res = (t->code)(global_work, t->testdata[j]);
                    134:            // 失敗なら非 0 を返す
                    135:            // bit3 は演算結果が期待と異なる
1.1.1.3   root      136:            // それ以外のビットが立っていれば例外有無が期待と異なる
1.1       root      137:            if (res != 0) {
                    138:                cause[0] = '\0';
                    139:                if ((res & 8)) {
1.1.1.3   root      140: #define SNPRINTF(s, fmt...)    n += snprintf((s) + n, sizeof(s) - n, fmt)
                    141:                    int n = 0;
                    142:                    SNPRINTF(cause, "0x%08x", expected_val);
                    143:                    if (t->quad) {
                    144:                        SNPRINTF(cause, "'%08x", expected_val2);
                    145:                    }
                    146:                    SNPRINTF(cause, " expected but 0x%08x", actual_val);
                    147:                    if (t->quad) {
                    148:                        SNPRINTF(cause, "'%08x", actual_val2);
                    149:                    }
                    150:                    res &= ~8;
1.1       root      151:                }
1.1.1.3   root      152:                if (res != 0) {
1.1       root      153:                    if (cause[0]) {
                    154:                        strlcat(cause, ", ", sizeof(cause));
                    155:                    }
                    156:                    if (exception_expected) {
                    157:                        // 例外を期待したが、例外が起きなかった。
                    158:                        strlcat(cause, "exception not occurred", sizeof(cause));
                    159:                    } else {
                    160:                        // 例外が起きないことを期待したのに例外が起きた。
                    161:                        strlcat(cause, "exception occurred", sizeof(cause));
                    162:                    }
                    163:                }
1.1.1.3   root      164:                if (failed == 0) {
                    165:                    printf("\n");
                    166:                }
1.1       root      167:                printf("FAILED (%s) at test_%s_%d\n",
                    168:                    cause, t->testname, j);
1.1.1.3   root      169:                failed++;
1.1       root      170:            }
                    171:        }
                    172: 
1.1.1.3   root      173:        if (failed == 0) {
                    174:            printf("ok\n");
                    175:        }
                    176:        total_failed += failed;
                    177:    }
                    178: 
                    179:    if (total_failed != 0) {
                    180:        printf("%d failed!\n", total_failed);
1.1       root      181:    }
                    182: 
1.1.1.3   root      183:    fpsetround(rnd_backup);
1.1       root      184:    return 0;
                    185: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.