--- nono/exp/optestm88k/optestm88k_code.s 2026/04/29 17:05:00 1.1.1.2 +++ nono/exp/optestm88k/optestm88k_code.s 2026/04/29 17:05:04 1.1.1.3 @@ -6,6 +6,25 @@ | アセンブラのテストコードのうち固定部分 +| main.c と揃えること + .equiv exception_occurred, (0 * 4) + .equiv exception_expected, (1 * 4) + .equiv expected_val, (2 * 4) + .equiv expected_val2, (3 * 4) + .equiv actual_val, (4 * 4) + .equiv actual_val2, (5 * 4) + +| RoundMode を設定 +| 入力: %r12 に設定したい Round Mode (bit15, 14 の位置) +| 破壊: %r6 +set_rnd_mode: + fldcr %r6, %fcr63 + and %r6, %r6, 0x3fff + or %r6, %r6, %r12 + fstcr %r6, %fcr63 + jmp %r1 + + | 汎用演算命令のテストベース | | r3 の指す先は @@ -14,7 +33,7 @@ .globl test_generic test_generic: | 例外は起きない - st %r0, %r2, 4 + st %r0, %r2, exception_expected | r1 を退避してテストコードへジャンプ or %r5, %r0, %r1 @@ -22,9 +41,13 @@ test_generic: jsr %r12 | test or %r1, %r0, %r5 - | r2[0] の指す先(exception_occurred) は例外が起きたら 1、起きなければ 0。 + | 結果表示用 + st %r6, %r2, expected_val + st %r8, %r2, actual_val + + | r2[exception_occurred] は例外が起きたら 1、起きなければ 0。 | これを最後に r2 はつぶして、戻り値として使う。 - ld %r2, %r2, 0 + ld %r2, %r2, exception_occurred | rD をチェック。 | 実行結果は r8 に、期待値は r3[0] に入っている。 @@ -52,7 +75,7 @@ test_generic: test_addsub: | 例外期待の有無を _main.c の exception_expected に書き戻す ld.bu %r12, %r3, 6 - st %r12, %r2, 4 + st %r12, %r2, exception_expected | Cy の初期値をセット | cin == 1 ならセット、cin == 0 ならクリア @@ -66,11 +89,15 @@ test_addsub: jsr %r12 | test or %r1, %r0, %r5 - | r2[0] の指す先(exception_occurred) は例外が起きたら 1、起きなければ 0。 + | 結果表示用 + st %r6, %r2, expected_val + st %r8, %r2, actual_val + + | r2[exception_occurred] は例外が起きたら 1、起きなければ 0。 | r3.b[6] は例外期待なら 1、例外が起きないことを期待なら 0。 | よって r2[0] と r3[2] を XOR して 0 になれば成功。 | これを最後に r2 はつぶして、戻り値として使う。 - ld %r2, %r2, 0 + ld %r2, %r2, exception_occurred ld.bu %r13, %r3, 6 xor %r2, %r2, %r13 @@ -97,27 +124,30 @@ test_addsub: | div 命令のテストベース | | r3 の指す先は -| +0 [0] = exp_rd (rD の期待値) -| +4 [1] = exp_ex (Integer Divide 例外を期待するなら 2) -| +8 [3] ここからテストコード (可変長) +| +0 [0] = exp_ex (Integer Divide 例外を期待するなら 2) +| +4 ここからテストコード (可変長) .globl test_div test_div: | 例外期待の有無を _main.c の exception_expected に書き戻す - ld %r12, %r3, 4 - st %r12, %r2, 4 + ld %r12, %r3, 0 + st %r12, %r2, exception_expected | r1 を退避してテストコードへジャンプ or %r5, %r0, %r1 - addu %r12, %r3, 8 + addu %r12, %r3, 4 jsr %r12 | test or %r1, %r0, %r5 - | r2[0] の指す先(exception_occurred) は IntDiv 例外が起きたら 2。 - | r3[1] は IntDiv 例外期待なら 2、起きないことを期待なら 0。 - | よって r2[0] と r3[1] を XOR して 0 になれば成功。 + | 結果表示用 + st %r6, %r2, expected_val + st %r8, %r2, actual_val + + | r2[exception_occurred] は IntDiv 例外が起きたら 2。 + | r3[0] は IntDiv 例外期待なら 2、起きないことを期待なら 0。 + | よって r2[exception_occurred] と r3[0] を XOR して 0 になれば成功。 | これを最後に r2 はつぶして戻り値として使う。 - ld %r2, %r2, 0 - ld %r13, %r3, 4 + ld %r2, %r2, exception_occurred + ld %r13, %r3, 0 xor %r2, %r2, %r13 | rD をチェック。 @@ -133,29 +163,84 @@ test_div: and %r2, %r2, 0xb jmp %r1 -| flt 命令のテストベース +| FP 命令(結果が 32bit の場合)のテストベース | | r3 の指す先は -| +0 [0] = exp_ex (例外を期待するなら 0x1000) +| +0.w [0] = RoundMode +| +2.w [1] = exp_ex (例外を期待するなら 0x1000) | +4 ここからテストコード -.globl test_flt -test_flt: +.globl test_fop_s +test_fop_s: | 例外期待の有無を _main.c の exception_expected に書き戻す - ld %r12, %r3, 0 - st %r12, %r2, 4 + ld.h %r12, %r3, 2 + st %r12, %r2, exception_expected - | r1 を退避してテストコードへジャンプ + | r1 を退避して.. or %r5, %r0, %r1 + | RoundMode を設定してテストコードへジャンプ + ld.h %r12, %r3, 0 + bsr set_rnd_mode addu %r12, %r3, 4 jsr %r12 | test or %r1, %r0, %r5 - | r2[0] の指す先(exception_occurred) は FltInv 例外が起きたら 8。 - | r3[0] は FltInv 例外期待なら 0x1000、起きないことを期待なら 0。 - | よって r2[0] と r3[0] を XOR して 0 になれば成功。 + | 結果表示用 + st %r6, %r2, expected_val + st %r8, %r2, actual_val + + | r2[exception_occurred] は FltInv 例外が起きたら 0x1000。 + | r3[1] は FltInv 例外期待なら 0x1000、起きないことを期待なら 0。 + | よって r2[exception_occurred] と r3[1] を XOR して 0 になれば成功。 | これを最後に r2 はつぶして戻り値として使う。 - ld %r2, %r2, 0 - ld %r13, %r3, 0 + ld %r2, %r2, exception_occurred + ld.h %r13, %r3, 2 + xor %r2, %r2, %r13 + + | rD をチェック。 + | 実行結果は r8 に、期待値は r6 に入っている。 + cmp %r6, %r6, %r8 + or %r2, %r2, %r6 + + | ここで r2 は + | 例外の期待と結果が異なれば bit12(0x1000) がセットされている、 + | 演算の期待と結果が異なれば bit3(0x08) がセットされているので + | 0x1008 で AND すると、全部成功すれば 0、そうでなければ非 0 になる。 + and %r2, %r2, 0x1008 + jmp %r1 + +| FP 命令(結果が 64bit の場合)のテストベース +| +| r3 の指す先は +| +0.w [0] = RoundMode +| +2.w [1] = exp_ex (例外を期待するなら 0x1000) +| +4 ここからテストコード +.globl test_fop_d +test_fop_d: + | 例外期待の有無を _main.c の exception_expected に書き戻す + ld.h %r12, %r3, 2 + st %r12, %r2, exception_expected + + | r1 を退避して.. + or %r5, %r0, %r1 + | RoundMode を設定してテストコードへジャンプ + ld.h %r12, %r3, 0 + bsr set_rnd_mode + addu %r12, %r3, 4 + jsr %r12 | test + or %r1, %r0, %r5 + + | 結果表示用 + st %r6, %r2, expected_val + st %r7, %r2, expected_val2 + st %r8, %r2, actual_val + st %r9, %r2, actual_val2 + + | r2[exception_occurred] は FltInv 例外が起きたら 0x1000。 + | r3[1] は FltInv 例外期待なら 0x1000、起きないことを期待なら 0。 + | よって r2[exception_occurred] と r3[1] を XOR して 0 になれば成功。 + | これを最後に r2 はつぶして戻り値として使う。 + ld %r2, %r2, exception_occurred + ld.h %r13, %r3, 2 xor %r2, %r2, %r13 | rD, rD+1 をチェック。