|
|
1.1 root 1: |
2: | nono
3: | Copyright (C) 2021 nono project
4: | Licensed under nono-license.txt
5: |
6:
7: | アセンブラのテストコードのうち固定部分
8:
1.1.1.3 ! root 9: | main.c と揃えること
! 10: .equiv exception_occurred, (0 * 4)
! 11: .equiv exception_expected, (1 * 4)
! 12: .equiv expected_val, (2 * 4)
! 13: .equiv expected_val2, (3 * 4)
! 14: .equiv actual_val, (4 * 4)
! 15: .equiv actual_val2, (5 * 4)
! 16:
! 17: | RoundMode を設定
! 18: | 入力: %r12 に設定したい Round Mode (bit15, 14 の位置)
! 19: | 破壊: %r6
! 20: set_rnd_mode:
! 21: fldcr %r6, %fcr63
! 22: and %r6, %r6, 0x3fff
! 23: or %r6, %r6, %r12
! 24: fstcr %r6, %fcr63
! 25: jmp %r1
! 26:
! 27:
1.1 root 28: | 汎用演算命令のテストベース
29: |
30: | r3 の指す先は
31: | +0 = exp_rd
32: | +4 ここからテストコード(可変長)
33: .globl test_generic
34: test_generic:
35: | 例外は起きない
1.1.1.3 ! root 36: st %r0, %r2, exception_expected
1.1 root 37:
38: | r1 を退避してテストコードへジャンプ
1.1.1.2 root 39: or %r5, %r0, %r1
1.1 root 40: addu %r12, %r3, 4
41: jsr %r12 | test
1.1.1.2 root 42: or %r1, %r0, %r5
1.1 root 43:
1.1.1.3 ! root 44: | 結果表示用
! 45: st %r6, %r2, expected_val
! 46: st %r8, %r2, actual_val
! 47:
! 48: | r2[exception_occurred] は例外が起きたら 1、起きなければ 0。
1.1 root 49: | これを最後に r2 はつぶして、戻り値として使う。
1.1.1.3 ! root 50: ld %r2, %r2, exception_occurred
1.1 root 51:
52: | rD をチェック。
1.1.1.2 root 53: | 実行結果は r8 に、期待値は r3[0] に入っている。
1.1 root 54: | cmp 結果の bit0 は %0 なので直前の例外結果と OR できる。
1.1.1.2 root 55: ld %r6, %r3, 0
56: cmp %r6, %r6, %r8
57: or %r2, %r2, %r6
1.1 root 58:
59: | ここで r2 は
60: | 例外の期待と結果が異なれば bit0(0x01) がセットされている、
61: | 演算の期待と結果が異なれば bit3(0x08) がセットされているので
62: | 0x09 で AND すると、全部成功すれば 0、そうでなければ非 0 になる。
63: and %r2, %r2, 0x9
64: jmp %r1
65:
66: | add/sub 命令のテストベース
67: |
68: | r3 の指す先は
69: | +0 [0] = exp_rd (rD の期待値)
70: | +4.b [4] = cin (Cy の入力値)
71: | +5.b [5] = exp_cy (Cy の期待値)
72: | +6.b [6] = exp_ex (例外を期待するなら 1)
73: | +8 [2] ここからテストコード(可変長)
74: .globl test_addsub
75: test_addsub:
76: | 例外期待の有無を _main.c の exception_expected に書き戻す
77: ld.bu %r12, %r3, 6
1.1.1.3 ! root 78: st %r12, %r2, exception_expected
1.1 root 79:
80: | Cy の初期値をセット
81: | cin == 1 ならセット、cin == 0 ならクリア
82: ld.bu %r12, %r3, 4
83: or.c %r13, %r0, %r0
84: addu.co %r0, %r12, %r13
85:
86: | r1 を退避してテストコードへジャンプ
1.1.1.2 root 87: or %r5, %r0, %r1
1.1 root 88: addu %r12, %r3, 8
89: jsr %r12 | test
1.1.1.2 root 90: or %r1, %r0, %r5
1.1 root 91:
1.1.1.3 ! root 92: | 結果表示用
! 93: st %r6, %r2, expected_val
! 94: st %r8, %r2, actual_val
! 95:
! 96: | r2[exception_occurred] は例外が起きたら 1、起きなければ 0。
1.1 root 97: | r3.b[6] は例外期待なら 1、例外が起きないことを期待なら 0。
98: | よって r2[0] と r3[2] を XOR して 0 になれば成功。
99: | これを最後に r2 はつぶして、戻り値として使う。
1.1.1.3 ! root 100: ld %r2, %r2, exception_occurred
1.1 root 101: ld.bu %r13, %r3, 6
102: xor %r2, %r2, %r13
103:
104: | rD をチェック。
1.1.1.2 root 105: | 実行結果は r8 に、期待値は r6 に入っている。
1.1 root 106: | cmp 結果の bit0 は %0 なので直前の例外結果と OR できる。
1.1.1.2 root 107: cmp %r8, %r8, %r6
108: or %r2, %r2, %r8
1.1 root 109:
110: | Cy をチェック。
111: | 実行結果は Cy に、期待値は r3.b[5] にある。
112: ld.bu %r12, %r3, 5
113: add.ci %r13, %r0, %r0 | Get Cy
114: cmp %r13, %r13, %r12
115: or %r2, %r2, %r13
116:
117: | ここで r2 は
118: | 例外の期待と結果が異なれば bit0(0x01) がセットされている、
119: | 演算の期待と結果が異なれば bit3(0x08) がセットされているので
120: | 0x09 で AND すると、全部成功すれば 0、そうでなければ非 0 になる。
121: and %r2, %r2, 0x9
122: jmp %r1
123:
124: | div 命令のテストベース
125: |
126: | r3 の指す先は
1.1.1.3 ! root 127: | +0 [0] = exp_ex (Integer Divide 例外を期待するなら 2)
! 128: | +4 ここからテストコード (可変長)
1.1 root 129: .globl test_div
130: test_div:
131: | 例外期待の有無を _main.c の exception_expected に書き戻す
1.1.1.3 ! root 132: ld %r12, %r3, 0
! 133: st %r12, %r2, exception_expected
1.1 root 134:
135: | r1 を退避してテストコードへジャンプ
1.1.1.2 root 136: or %r5, %r0, %r1
1.1.1.3 ! root 137: addu %r12, %r3, 4
1.1 root 138: jsr %r12 | test
1.1.1.2 root 139: or %r1, %r0, %r5
1.1 root 140:
1.1.1.3 ! root 141: | 結果表示用
! 142: st %r6, %r2, expected_val
! 143: st %r8, %r2, actual_val
! 144:
! 145: | r2[exception_occurred] は IntDiv 例外が起きたら 2。
! 146: | r3[0] は IntDiv 例外期待なら 2、起きないことを期待なら 0。
! 147: | よって r2[exception_occurred] と r3[0] を XOR して 0 になれば成功。
1.1 root 148: | これを最後に r2 はつぶして戻り値として使う。
1.1.1.3 ! root 149: ld %r2, %r2, exception_occurred
! 150: ld %r13, %r3, 0
1.1 root 151: xor %r2, %r2, %r13
152:
153: | rD をチェック。
1.1.1.2 root 154: | 実行結果は r8 に、期待値は r6 に入っている。
1.1 root 155: | cmp 結果の bit0-1 は %0 なので直前の例外結果と OR できる。
1.1.1.2 root 156: cmp %r8, %r8, %r6
157: or %r2, %r2, %r8
1.1 root 158:
159: | ここで r2 は
160: | 例外の期待と結果が異なれば bit0-1(0x03) がセットされている、
161: | 演算の期待と結果が異なれば bit3(0x08) がセットされているので
162: | 0x0b で AND すると、全部成功すれば 0、そうでなければ非 0 になる。
163: and %r2, %r2, 0xb
164: jmp %r1
1.1.1.2 root 165:
1.1.1.3 ! root 166: | FP 命令(結果が 32bit の場合)のテストベース
1.1.1.2 root 167: |
168: | r3 の指す先は
1.1.1.3 ! root 169: | +0.w [0] = RoundMode
! 170: | +2.w [1] = exp_ex (例外を期待するなら 0x1000)
1.1.1.2 root 171: | +4 ここからテストコード
1.1.1.3 ! root 172: .globl test_fop_s
! 173: test_fop_s:
1.1.1.2 root 174: | 例外期待の有無を _main.c の exception_expected に書き戻す
1.1.1.3 ! root 175: ld.h %r12, %r3, 2
! 176: st %r12, %r2, exception_expected
1.1.1.2 root 177:
1.1.1.3 ! root 178: | r1 を退避して..
1.1.1.2 root 179: or %r5, %r0, %r1
1.1.1.3 ! root 180: | RoundMode を設定してテストコードへジャンプ
! 181: ld.h %r12, %r3, 0
! 182: bsr set_rnd_mode
1.1.1.2 root 183: addu %r12, %r3, 4
184: jsr %r12 | test
185: or %r1, %r0, %r5
186:
1.1.1.3 ! root 187: | 結果表示用
! 188: st %r6, %r2, expected_val
! 189: st %r8, %r2, actual_val
! 190:
! 191: | r2[exception_occurred] は FltInv 例外が起きたら 0x1000。
! 192: | r3[1] は FltInv 例外期待なら 0x1000、起きないことを期待なら 0。
! 193: | よって r2[exception_occurred] と r3[1] を XOR して 0 になれば成功。
1.1.1.2 root 194: | これを最後に r2 はつぶして戻り値として使う。
1.1.1.3 ! root 195: ld %r2, %r2, exception_occurred
! 196: ld.h %r13, %r3, 2
! 197: xor %r2, %r2, %r13
! 198:
! 199: | rD をチェック。
! 200: | 実行結果は r8 に、期待値は r6 に入っている。
! 201: cmp %r6, %r6, %r8
! 202: or %r2, %r2, %r6
! 203:
! 204: | ここで r2 は
! 205: | 例外の期待と結果が異なれば bit12(0x1000) がセットされている、
! 206: | 演算の期待と結果が異なれば bit3(0x08) がセットされているので
! 207: | 0x1008 で AND すると、全部成功すれば 0、そうでなければ非 0 になる。
! 208: and %r2, %r2, 0x1008
! 209: jmp %r1
! 210:
! 211: | FP 命令(結果が 64bit の場合)のテストベース
! 212: |
! 213: | r3 の指す先は
! 214: | +0.w [0] = RoundMode
! 215: | +2.w [1] = exp_ex (例外を期待するなら 0x1000)
! 216: | +4 ここからテストコード
! 217: .globl test_fop_d
! 218: test_fop_d:
! 219: | 例外期待の有無を _main.c の exception_expected に書き戻す
! 220: ld.h %r12, %r3, 2
! 221: st %r12, %r2, exception_expected
! 222:
! 223: | r1 を退避して..
! 224: or %r5, %r0, %r1
! 225: | RoundMode を設定してテストコードへジャンプ
! 226: ld.h %r12, %r3, 0
! 227: bsr set_rnd_mode
! 228: addu %r12, %r3, 4
! 229: jsr %r12 | test
! 230: or %r1, %r0, %r5
! 231:
! 232: | 結果表示用
! 233: st %r6, %r2, expected_val
! 234: st %r7, %r2, expected_val2
! 235: st %r8, %r2, actual_val
! 236: st %r9, %r2, actual_val2
! 237:
! 238: | r2[exception_occurred] は FltInv 例外が起きたら 0x1000。
! 239: | r3[1] は FltInv 例外期待なら 0x1000、起きないことを期待なら 0。
! 240: | よって r2[exception_occurred] と r3[1] を XOR して 0 になれば成功。
! 241: | これを最後に r2 はつぶして戻り値として使う。
! 242: ld %r2, %r2, exception_occurred
! 243: ld.h %r13, %r3, 2
1.1.1.2 root 244: xor %r2, %r2, %r13
245:
246: | rD, rD+1 をチェック。
247: | 実行結果は r8(,r9) に、期待値は r6(,r7) に入っている。
248: cmp %r6, %r6, %r8
249: cmp %r7, %r7, %r9
250: or %r2, %r2, %r6
251: or %r2, %r2, %r7
252:
253: | ここで r2 は
254: | 例外の期待と結果が異なれば bit12(0x1000) がセットされている、
255: | 演算の期待と結果が異なれば bit3(0x08) がセットされているので
256: | 0x1008 で AND すると、全部成功すれば 0、そうでなければ非 0 になる。
257: and %r2, %r2, 0x1008
258: jmp %r1
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.