summaryrefslogtreecommitdiff
path: root/sim/testsuite/sim/fr30/testutils.inc
diff options
context:
space:
mode:
Diffstat (limited to 'sim/testsuite/sim/fr30/testutils.inc')
-rw-r--r--sim/testsuite/sim/fr30/testutils.inc306
1 files changed, 306 insertions, 0 deletions
diff --git a/sim/testsuite/sim/fr30/testutils.inc b/sim/testsuite/sim/fr30/testutils.inc
new file mode 100644
index 00000000000..7523d6f6aa5
--- /dev/null
+++ b/sim/testsuite/sim/fr30/testutils.inc
@@ -0,0 +1,306 @@
+# r0, r4-r6 are used as tmps, consider them call clobbered by these macros.
+
+ .macro start
+ .data
+failmsg:
+ .ascii "fail\n"
+passmsg:
+ .ascii "pass\n"
+ .text
+ .global _start
+_start:
+ ldi32 0x7fffc,sp ; TODO -- what's a good value for this?
+ ldi32 0xffc00,r0
+ mov r0,tbr ; defined in manual
+ mov sp,usp
+ mov sp,ssp
+ .endm
+
+; Exit with return code
+ .macro exit rc
+ ldi32 \rc,r4
+ ldi32 #1,r0
+ int #10
+ .endm
+
+; Pass the test case
+ .macro pass
+ ldi32 #5,r6
+ ldi32 #passmsg,r5
+ ldi32 #1,r4
+ ldi32 #5,r0
+ int #10
+ exit #0
+ .endm
+
+; Fail the testcase
+ .macro fail
+ ldi32 #5,r6
+ ldi32 #failmsg,r5
+ ldi32 #1,r4
+ ldi32 #5,r0
+ int #10
+ exit #1
+ .endm
+
+; Load an immediate value into a general register
+; TODO: use minimal sized insn
+ .macro mvi_h_gr val reg
+ ldi32 \val,\reg
+ .endm
+
+; Load an immediate value into a dedicated register
+ .macro mvi_h_dr val reg
+ ldi32 \val,r0
+ mov r0,\reg
+ .endm
+
+; Load a general register into another general register
+ .macro mvr_h_gr src targ
+ mov \src,\targ
+ .endm
+
+; Store an immediate into a word in memory
+ .macro mvi_h_mem val addr
+ mvi_h_gr \val r4
+ mvr_h_mem r4,\addr
+ .endm
+
+; Store a register into a word in memory
+ .macro mvr_h_mem reg addr
+ st \reg,@\addr
+ .endm
+
+; Store the current ps on the stack
+ .macro save_ps
+ st ps,@-r15
+ .endm
+
+; Load a word value from memory
+ .macro ldmem_h_gr addr reg
+ ld @\addr,\reg
+ .endm
+
+; Add 2 general registers
+ .macro add_h_gr reg1 reg2
+ add \reg1,\reg2
+ .endm
+
+; Increment a register by and immediate
+ .macro inci_h_gr inc reg
+ mvi_h_gr \inc,r4
+ add r4,\reg
+ .endm
+
+; Test the value of an immediate against a general register
+ .macro test_h_gr val reg
+ .if (\val >= 0) && (\val <= 15)
+ cmp \val,\reg
+ .else
+ .if (\val < 0) && (\val >= -16)
+ cmp2 \val,\reg
+ .else
+ ldi32 \val,r4
+ cmp r4,\reg
+ .endif
+ .endif
+ beq test_gr\@
+ fail
+test_gr\@:
+ .endm
+
+; compare two general registers
+ .macro testr_h_gr reg1 reg2
+ cmp \reg1,\reg2
+ beq testr_gr\@
+ fail
+testr_gr\@:
+ .endm
+
+; Test the value of an immediate against a dedicated register
+ .macro test_h_dr val reg
+ mov \reg,r5
+ test_h_gr \val r5
+ .endm
+
+; Test the value of an general register against a dedicated register
+ .macro testr_h_dr gr dr
+ mov \dr,r5
+ testr_h_gr \gr r5
+ .endm
+
+; Compare an immediate with word in memory
+ .macro test_h_mem val addr
+ ldmem_h_gr \addr r5
+ test_h_gr \val r5
+ .endm
+
+; Compare a general register with word in memory
+ .macro testr_h_mem reg addr
+ ldmem_h_gr \addr r5
+ testr_h_gr \reg r5
+ .endm
+
+; Set the condition codes
+ .macro set_cc mask
+ andccr 0xf0
+ orccr \mask
+ .endm
+
+; Set the stack mode
+ .macro set_s_user
+ orccr 0x20
+ .endm
+
+ .macro set_s_system
+ andccr 0x1f
+ .endm
+
+; Test the stack mode
+ .macro test_s_user
+ mvr_h_gr ps,r0
+ mvi_h_gr 0x20,r4
+ and r4,r0
+ test_h_gr 0x20,r0
+ .endm
+
+ .macro test_s_system
+ mvr_h_gr ps,r0
+ mvi_h_gr 0x20,r4
+ and r4,r0
+ test_h_gr 0x0,r0
+ .endm
+
+; Set the interrupt bit
+ .macro set_i val
+ .if (\val == 1)
+ orccr 0x10
+ .else
+ andccr 0x2f
+ .endif
+ .endm
+
+; Test the stack mode
+ .macro test_i val
+ mvr_h_gr ps,r0
+ mvi_h_gr 0x10,r4
+ and r4,r0
+ .if (\val == 1)
+ test_h_gr 0x10,r0
+ .else
+ test_h_gr 0x0,r0
+ .endif
+ .endm
+
+; Set the ilm
+ .macro set_ilm val
+ stilm \val
+ .endm
+
+; Test the ilm
+ .macro test_ilm val
+ mvr_h_gr ps,r0
+ mvi_h_gr 0x1f0000,r4
+ and r4,r0
+ mvi_h_gr \val,r5
+ mvi_h_gr 0x1f,r4
+ and r4,r5
+ lsl 15,r5
+ lsl 1,r5
+ testr_h_gr r0,r5
+ .endm
+
+; Test the condition codes
+ .macro test_cc N Z V C
+ .if (\N == 1)
+ bp fail\@
+ .else
+ bn fail\@
+ .endif
+ .if (\Z == 1)
+ bne fail\@
+ .else
+ beq fail\@
+ .endif
+ .if (\V == 1)
+ bnv fail\@
+ .else
+ bv fail\@
+ .endif
+ .if (\C == 1)
+ bnc fail\@
+ .else
+ bc fail\@
+ .endif
+ bra test_cc\@
+fail\@:
+ fail
+test_cc\@:
+ .endm
+
+; Set the division bits
+ .macro set_dbits val
+ mvr_h_gr ps,r5
+ mvi_h_gr 0xfffff8ff,r4
+ and r4,r5
+ mvi_h_gr \val,r0
+ mvi_h_gr 3,r4
+ and r4,r0
+ lsl 9,r0
+ or r0,r5
+ mvr_h_gr r5,ps
+ .endm
+
+; Test the division bits
+ .macro test_dbits val
+ mvr_h_gr ps,r0
+ lsr 9,r0
+ mvi_h_gr 3,r4
+ and r4,r0
+ test_h_gr \val,r0
+ .endm
+
+; Save the return pointer
+ .macro save_rp
+ st rp,@-R15
+ .ENDM
+
+; restore the return pointer
+ .macro restore_rp
+ ld @R15+,rp
+ .endm
+
+; Ensure branch taken
+ .macro take_branch opcode
+ \opcode take_br\@
+ fail
+take_br\@:
+ .endm
+
+ .macro take_branch_d opcode val
+ \opcode take_brd\@
+ ldi:8 \val,r0
+ fail
+take_brd\@:
+ test_h_gr \val,r0
+ .endm
+
+; Ensure branch not taken
+ .macro no_branch opcode
+ \opcode no_brf\@
+ bra no_brs\@
+no_brf\@:
+ fail
+no_brs\@:
+ .endm
+
+ .macro no_branch_d opcode val
+ \opcode no_brdf\@
+ ldi:8 \val,r0
+ bra no_brds\@
+no_brdf\@:
+ fail
+no_brds\@:
+ test_h_gr \val,r0
+ .endm
+