|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.