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

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

unix.superglobalmegacorp.com

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