|
|
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" ! 8: #include <setjmp.h> ! 9: #include <signal.h> ! 10: #include <stdlib.h> ! 11: #include <sys/siginfo.h> ! 12: ! 13: // グローバルワーク (r2 でアセンブラに渡される) ! 14: int global_work[2]; ! 15: ! 16: // オーバーフロー例外なら 1、除算例外なら 2 をセットする。 ! 17: // テスト前に 0 で初期化しておくこと。 ! 18: #define exception_occurred (global_work[0]) ! 19: // 例外を期待するなら 1 か 2、期待しないなら 0 (テスト側が書く) ! 20: #define exception_expected (global_work[1]) ! 21: ! 22: static void ! 23: sigfpe(int signo, siginfo_t *si, void *ctx) ! 24: { ! 25: if (si->si_signo == SIGFPE) { ! 26: if (si->si_code == FPE_INTOVF) { ! 27: exception_occurred = 1; ! 28: return; ! 29: } else if (si->si_code == FPE_INTDIV) { ! 30: exception_occurred = 2; ! 31: return; ! 32: } ! 33: } ! 34: // XXX ! 35: exception_occurred = -1; ! 36: } ! 37: ! 38: int ! 39: main(int ac, char *av[]) ! 40: { ! 41: char cause[64]; ! 42: struct testentry *t; ! 43: func_t func; ! 44: const char *arg_name = ""; ! 45: int i; ! 46: int j; ! 47: int num; ! 48: int res; ! 49: ! 50: if (ac >= 2) { ! 51: arg_name = av[1]; ! 52: } ! 53: ! 54: struct sigaction act; ! 55: memset(&act, 0, sizeof(act)); ! 56: act.sa_sigaction = sigfpe; ! 57: act.sa_flags = SA_SIGINFO; ! 58: sigaction(SIGFPE, &act, NULL); ! 59: ! 60: for (i = j = 0; test_table[i].code != NULL; i++, j = 0) { ! 61: t = &test_table[i]; ! 62: ! 63: if (strncasecmp(t->testname, arg_name, strlen(arg_name)) != 0) { ! 64: break; ! 65: } ! 66: ! 67: if (j == 0) { ! 68: // テスト数を数える ! 69: for (num = 0; t->testdata[num] != NULL; num++) ! 70: ; ! 71: ! 72: printf("%s (%d) ... ", t->testname, num); ! 73: fflush(stdout); ! 74: } ! 75: ! 76: for (; j < num; j++) { ! 77: exception_occurred = 0; ! 78: ! 79: res = (t->code)(global_work, t->testdata[j]); ! 80: // 失敗なら非 0 を返す ! 81: // bit3 は演算結果が期待と異なる ! 82: // bit0 は例外有無が期待と異なる ! 83: if (res != 0) { ! 84: cause[0] = '\0'; ! 85: if ((res & 8)) { ! 86: strlcpy(cause, "incorrect result", sizeof(cause)); ! 87: } ! 88: if ((res & 1)) { ! 89: if (cause[0]) { ! 90: strlcat(cause, ", ", sizeof(cause)); ! 91: } ! 92: if (exception_expected) { ! 93: // 例外を期待したが、例外が起きなかった。 ! 94: strlcat(cause, "exception not occurred", sizeof(cause)); ! 95: } else { ! 96: // 例外が起きないことを期待したのに例外が起きた。 ! 97: strlcat(cause, "exception occurred", sizeof(cause)); ! 98: } ! 99: } ! 100: printf("FAILED (%s) at test_%s_%d\n", ! 101: cause, t->testname, j); ! 102: exit(1); ! 103: } ! 104: } ! 105: ! 106: printf("ok\n"); ! 107: } ! 108: ! 109: return 0; ! 110: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.