--- nono/m680x0/testacc.cpp 2026/04/29 17:04:28 1.1 +++ nono/m680x0/testacc.cpp 2026/04/29 17:04:34 1.1.1.3 @@ -1,32 +1,53 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // -#include "header.h" -#include #include "m68030core.h" #include "m68030acc.h" +#include // パフォーマンステストの秒数 #define PERF_SEC (3) -void usage(); +[[noreturn]] void usage(); -m68kcpu *cpu; +static m68kcpu *cpu; -int argc; // getopt(3) 処理後の argc -const char **argv; // getopt(3) 処理後の argv -const char *testname; // 現在のテスト名 -int total_errcnt; // 総エラー数 -int errcnt; // 現在のセクションのエラー数 -char where[256]; // エラー発生箇所 -volatile int perf_signaled; // パフォーマンス測定用 -struct timeval perf_start; // パフォーマンス測定開始時刻 -uint64 perf_count; // パフォーマンス測定用。処理回数 +static int argc; // getopt(3) 処理後の argc +static char **argv; // getopt(3) 処理後の argv +static const char *testname; // 現在のテスト名 +static int total_errcnt; // 総エラー数 +static int errcnt; // 現在のセクションのエラー数 +static char where[256]; // エラー発生箇所 +static volatile int perf_signaled; // パフォーマンス測定用 +static struct timeval perf_start; // パフォーマンス測定開始時刻 +static uint64 perf_count; // パフォーマンス測定用。処理回数 + +// value を16進数で指定のビット数分の文字列にする +static std::string +hex(uint32 value, int sz) +{ + char buf[32]; + + switch (sz) { + case 8: + snprintf(buf, sizeof(buf), "%02x", value); + break; + case 16: + snprintf(buf, sizeof(buf), "%04x", value); + break; + case 32: + default: + snprintf(buf, sizeof(buf), "%08x", value); + break; + } + return std::string(buf); +} // 整数(32bitまで)を検査する -void +static void __unused xp_equal(uint32 expected, uint32 actual, const char *name) { if (expected != actual) { @@ -40,7 +61,7 @@ xp_equal(uint32 expected, uint32 actual, } // 値(32bitまで)と CCR を検査する -void +static void xp_equal(uint32 actValue, m68030ccr& actCCR, uint32 expValue, bool expX, bool expN, bool expZ, bool expV, bool expC) { @@ -74,7 +95,7 @@ xp_equal(uint32 actValue, m68030ccr& act } // 値(64bit)と CCR を検査する -void +static void __unused xp_equal64(uint64 actValue, m68030ccr& actCCR, uint64 expValue, bool expX, bool expN, bool expZ, bool expV, bool expC) { @@ -112,7 +133,7 @@ xp_equal64(uint64 actValue, m68030ccr& a // このテストを実行するかどうか // 引数なしなら全部実行。 // 引数ありなら一致すれば実行。 -bool +static bool check_exec(const char *name) { if (argc == 0) { @@ -129,14 +150,13 @@ check_exec(const char *name) // サイズ部を除いて一致するか // add に対して addx が一致しないようにアンダーバーまでで調べる - char name2[strlen(name) + 1]; - strcpy(name2, name); - char *u = strchr(name2, '_'); - if (u) { - *u = '\0'; + std::string name2(name); + int u = name2.find('_'); + if (u != std::string::npos) { + name2.erase(u, name2.size() - u); } for (int i = 0; i < argc; i++) { - if (strcmp(name2, argv[i]) == 0) { + if (strcmp(name2.c_str(), argv[i]) == 0) { return true; } } @@ -149,7 +169,7 @@ check_exec(const char *name) return; \ start_test_func(__FUNCTION__) -void +static void start_test_func(const char *name) { testname = name; @@ -158,7 +178,7 @@ start_test_func(const char *name) errcnt = 0; } -void +static void end_test() { if (errcnt == 0) { @@ -177,13 +197,13 @@ end_test() #define END_PERF \ end_perf_func() -void +static void signal_alarm(int signo) { perf_signaled = 1; } -void +static void start_perf_func(const char *name) { testname = name; @@ -200,7 +220,7 @@ start_perf_func(const char *name) setitimer(ITIMER_REAL, &it, NULL); } -void +static void end_perf_func() { struct timeval end, result; @@ -213,7 +233,7 @@ end_perf_func() } // 乱数 -uint32 +static uint32 xor32() { static uint32 y = 2463534242; @@ -225,14 +245,14 @@ xor32() // sz ビット目(最下位を0とする)を立てた値を返す // sz は 0..63 -uint64 +static uint64 BIT(int sz) { return (1ULL << sz); } // 下位 sz ビットがすべて 1 の値を返す -uint32 +static uint32 MASK(int sz) { return (1ULL << sz) - 1; @@ -240,7 +260,7 @@ MASK(int sz) // value を sz ビット符号付き整数とした時、負かどうかを返す // sz は 8, 16, 32 -bool +static bool ISNEG(uint64 value, int sz) { return ((value & BIT(sz - 1)) != 0); @@ -250,7 +270,7 @@ ISNEG(uint64 value, int sz) // add,sub // -uint32 add_table[] = { +static uint32 add_table[] = { 0x00000000, 0x00000001, 0x0000007f, @@ -264,7 +284,7 @@ uint32 add_table[] = { 0xffffffff, }; -void +static void test_add(int sz) { for (int i = 0; i < countof(add_table); i++) { @@ -274,8 +294,8 @@ test_add(int sz) uint64 tmp = src + dst; uint64 res = tmp & MASK(sz); - sprintf(where, "%0*" PRIx64 " + %0*" PRIx64, - (sz / 4), src, (sz / 4), dst); + std::string w = hex(src, sz) + " + " + hex(dst, sz); + strlcpy(where, w.c_str(), sizeof(where)); bool C = tmp & BIT(sz); bool V = ((res ^ src) & (res ^ dst)) & BIT(sz - 1); @@ -294,7 +314,7 @@ test_add(int sz) } } -void +static void test_add_8() { start_test(); @@ -302,7 +322,7 @@ test_add_8() end_test(); } -void +static void test_add_16() { start_test(); @@ -310,7 +330,7 @@ test_add_16() end_test(); } -void +static void test_add_32() { start_test(); @@ -318,7 +338,7 @@ test_add_32() end_test(); } -void +static void test_sub(int sz) { for (int i = 0; i < countof(add_table); i++) { @@ -335,8 +355,8 @@ test_sub(int sz) tmp = (uint64)dst - (uint64)src; } uint64 res = tmp & MASK(sz); - sprintf(where, "%0*" PRIx64 " - %0*" PRIx64, - (sz / 4), dst, (sz / 4), src); + std::string w = hex(dst, sz) + " - " + hex(src, sz); + strlcpy(where, w.c_str(), sizeof(where)); bool C = tmp & BIT(sz); bool V = ((src ^ dst) & (res ^ dst)) & BIT(sz - 1); @@ -355,7 +375,7 @@ test_sub(int sz) } } -void +static void test_sub_8() { start_test(); @@ -363,7 +383,7 @@ test_sub_8() end_test(); } -void +static void test_sub_16() { start_test(); @@ -371,7 +391,7 @@ test_sub_16() end_test(); } -void +static void test_sub_32() { start_test(); @@ -383,7 +403,7 @@ test_sub_32() // // addx // -struct { +static struct { uint32 src, dst; bool inX; uint32 res; @@ -397,7 +417,7 @@ struct { { 0x7fffffff, 0x80000000, 1, 0x00000000, 0, 1, 0, 1 }, }; -void +static void test_addx_32() { start_test(); @@ -426,7 +446,7 @@ test_addx_32() // ローテート/シフト系のパフォーマンス測定 #define DEFINE_PERF_ROTATE(name) \ -void \ +static void \ __CONCAT(perf_,name)() \ { \ START_PERF; \ @@ -449,7 +469,7 @@ DEFINE_PERF_ROTATE(lsr_32) DEFINE_PERF_ROTATE(roxr_32) DEFINE_PERF_ROTATE(ror_32) -void +static void perf_add_32() { START_PERF; @@ -487,7 +507,7 @@ main(int ac, char *av[]) ac -= optind; av += optind; argc = ac; - argv = (const char **)av; + argv = av; // 本当はコンストラクタを呼ぶべきだが、そうすると必要なオブジェクトが // 芋づる式に増えて正しく解決するのは面倒。ここのテストではとりあえず