File:  [Isaki's NoNo m68k/m88k emulator] / nono / exp / optestm88k / optestm88k_code.s
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:04 2026 UTC (3 months ago) by root
Branches: MAIN, Isaki
CVS tags: v027, v026, v025, v024, v023, v022, v021, v020, v019, v018, v017, v016, v015, v014, HEAD
nono 0.2.3

|
| nono
| Copyright (C) 2021 nono project
| Licensed under nono-license.txt
|

| アセンブラのテストコードのうち固定部分

| 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 の指す先は
|  +0   = exp_rd
|  +4   ここからテストコード(可変長)
.globl test_generic
test_generic:
	| 例外は起きない
	st	%r0, %r2, exception_expected

	| r1 を退避してテストコードへジャンプ
	or	%r5, %r0, %r1
	addu	%r12, %r3, 4
	jsr	%r12		| test
	or	%r1, %r0, %r5

	| 結果表示用
	st	%r6, %r2, expected_val
	st	%r8, %r2, actual_val

	| r2[exception_occurred] は例外が起きたら 1、起きなければ 0。
	| これを最後に r2 はつぶして、戻り値として使う。
	ld	%r2, %r2, exception_occurred

	| rD をチェック。
	| 実行結果は r8 に、期待値は r3[0] に入っている。
	| cmp 結果の bit0 は %0 なので直前の例外結果と OR できる。
	ld	%r6, %r3, 0
	cmp	%r6, %r6, %r8
	or	%r2, %r2, %r6

	| ここで r2 は
	| 例外の期待と結果が異なれば bit0(0x01) がセットされている、
	| 演算の期待と結果が異なれば bit3(0x08) がセットされているので
	| 0x09 で AND すると、全部成功すれば 0、そうでなければ非 0 になる。
	and	%r2, %r2, 0x9
	jmp	%r1

| add/sub 命令のテストベース
|
| r3 の指す先は
|  +0   [0] = exp_rd (rD の期待値)
|  +4.b [4] = cin    (Cy の入力値)
|  +5.b [5] = exp_cy (Cy の期待値)
|  +6.b [6] = exp_ex (例外を期待するなら 1)
|  +8   [2] ここからテストコード(可変長)
.globl test_addsub
test_addsub:
	| 例外期待の有無を _main.c の exception_expected に書き戻す
	ld.bu	%r12, %r3, 6
	st	%r12, %r2, exception_expected

	| Cy の初期値をセット
	| cin == 1 ならセット、cin == 0 ならクリア
	ld.bu	%r12, %r3, 4
	or.c	%r13, %r0, %r0
	addu.co	%r0, %r12, %r13

	| r1 を退避してテストコードへジャンプ
	or	%r5, %r0, %r1
	addu	%r12, %r3, 8
	jsr	%r12		| test
	or	%r1, %r0, %r5

	| 結果表示用
	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, exception_occurred
	ld.bu	%r13, %r3, 6
	xor	%r2, %r2, %r13

	| rD をチェック。
	| 実行結果は r8 に、期待値は r6 に入っている。
	| cmp 結果の bit0 は %0 なので直前の例外結果と OR できる。
	cmp	%r8, %r8, %r6
	or	%r2, %r2, %r8

	| Cy をチェック。
	| 実行結果は Cy に、期待値は r3.b[5] にある。
	ld.bu	%r12, %r3, 5
	add.ci	%r13, %r0, %r0	| Get Cy
	cmp	%r13, %r13, %r12
	or	%r2, %r2, %r13

	| ここで r2 は
	| 例外の期待と結果が異なれば bit0(0x01) がセットされている、
	| 演算の期待と結果が異なれば bit3(0x08) がセットされているので
	| 0x09 で AND すると、全部成功すれば 0、そうでなければ非 0 になる。
	and	%r2, %r2, 0x9
	jmp	%r1

| div 命令のテストベース
|
| r3 の指す先は
|  +0   [0] = exp_ex (Integer Divide 例外を期待するなら 2)
|  +4   ここからテストコード (可変長)
.globl	test_div
test_div:
	| 例外期待の有無を _main.c の exception_expected に書き戻す
	ld	%r12, %r3, 0
	st	%r12, %r2, exception_expected

	| r1 を退避してテストコードへジャンプ
	or	%r5, %r0, %r1
	addu	%r12, %r3, 4
	jsr	%r12		| test
	or	%r1, %r0, %r5

	| 結果表示用
	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, exception_occurred
	ld	%r13, %r3, 0
	xor	%r2, %r2, %r13

	| rD をチェック。
	| 実行結果は r8 に、期待値は r6 に入っている。
	| cmp 結果の bit0-1 は %0 なので直前の例外結果と OR できる。
	cmp	%r8, %r8, %r6
	or	%r2, %r2, %r8

	| ここで r2 は
	| 例外の期待と結果が異なれば bit0-1(0x03) がセットされている、
	| 演算の期待と結果が異なれば bit3(0x08) がセットされているので
	| 0x0b で AND すると、全部成功すれば 0、そうでなければ非 0 になる。
	and	%r2, %r2, 0xb
	jmp	%r1

| FP 命令(結果が 32bit の場合)のテストベース
|
| r3 の指す先は
|  +0.w	[0] = RoundMode
|  +2.w	[1] = exp_ex (例外を期待するなら 0x1000)
|  +4   ここからテストコード
.globl	test_fop_s
test_fop_s:
	| 例外期待の有無を _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	%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, 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 をチェック。
	| 実行結果は r8(,r9) に、期待値は r6(,r7) に入っている。
	cmp	%r6, %r6, %r8
	cmp	%r7, %r7, %r9
	or	%r2, %r2, %r6
	or	%r2, %r2, %r7

	| ここで r2 は
	| 例外の期待と結果が異なれば bit12(0x1000) がセットされている、
	| 演算の期待と結果が異なれば bit3(0x08) がセットされているので
	| 0x1008 で AND すると、全部成功すれば 0、そうでなければ非 0 になる。
	and	%r2, %r2, 0x1008
	jmp	%r1

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.