aboutsummaryrefslogtreecommitdiff
path: root/sim/testsuite/frv/testutils.inc
diff options
context:
space:
mode:
Diffstat (limited to 'sim/testsuite/frv/testutils.inc')
-rw-r--r--sim/testsuite/frv/testutils.inc656
1 files changed, 656 insertions, 0 deletions
diff --git a/sim/testsuite/frv/testutils.inc b/sim/testsuite/frv/testutils.inc
new file mode 100644
index 0000000..8261b4fa
--- /dev/null
+++ b/sim/testsuite/frv/testutils.inc
@@ -0,0 +1,656 @@
+# gr28-gr31, fr31, icc3, fcc3 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:
+ ; enable data and insn caches in copy-back mode
+ ; Also enable all registers
+ or_spr_immed 0xc80003c0,hsr0
+ and_spr_immed 0xfffff3ff,hsr0
+
+ ; turn on psr.nem, psr.cm, psr.ef, psr.em, psr.esr,
+ ; disable external interrupts
+ or_spr_immed 0x69f8,psr
+
+ ; If fsr exists, enable all fp_exceptions except inexact
+ movsg psr,gr28
+ srli gr28,28,gr28
+ subicc gr28,0x2,gr0,icc3 ; is fr400?
+ beq icc3,0,nofsr0
+ or_spr_immed 0x3d000000,fsr0
+nofsr0:
+
+ ; Set the stack pointer
+ sethi.p 0x7,sp
+ setlo 0xfffc,sp ; TODO -- what's a good value for this?
+
+ ; Set the TBR address
+ sethi.p 0xf,gr28
+ setlo 0xf000,gr28
+ movgs gr28,tbr ; TODO -- what's a good value for this?
+
+ ; Go to user mode -- causes too many problems
+ ;and_spr_immed 0xfffffffb,psr
+ .endm
+
+; Set GR with another GR
+ .macro set_gr_gr src targ
+ addi \src,0,\targ
+ .endm
+
+; Set GR with immediate value
+ .macro set_gr_immed val reg
+ .if (\val >= -32768) && (\val <= 23767)
+ setlos \val,\reg
+ .else
+ setlo.p %lo(\val),\reg
+ sethi %hi(\val),\reg
+ .endif
+ .endm
+
+ .macro set_gr_limmed valh vall reg
+ sethi.p \valh,\reg
+ setlo \vall,\reg
+ .endm
+
+; Set GR with address value
+ .macro set_gr_addr addr reg
+ sethi.p %hi(\addr),\reg
+ setlo %lo(\addr),\reg
+ .endm
+
+; Set GR with SPR
+ .macro set_gr_spr src targ
+ movsg \src,\targ
+ .endm
+
+; Set GR with a value from memory
+ .macro set_gr_mem addr reg
+ set_gr_addr \addr,gr28
+ ldi @(gr28,0),\reg
+ .endm
+
+; Increment GR with immediate value
+ .macro inc_gr_immed val reg
+ .if (\val >= -2048) && (\val <= 2047)
+ addi \reg,\val,\reg
+ .else
+ set_gr_immed \val,gr28
+ add \reg,gr28,\reg
+ .endif
+ .endm
+
+; AND GR with immediate value
+ .macro and_gr_immed val reg
+ .if (\val >= -2048) && (\val <= 2047)
+ andi \reg,\val,\reg
+ .else
+ set_gr_immed \val,gr28
+ and \reg,gr28,\reg
+ .endif
+ .endm
+
+; OR GR with immediate value
+ .macro or_gr_immed val reg
+ .if (\val >= -2048) && (\val <= 2047)
+ ori \reg,\val,\reg
+ .else
+ set_gr_immed \val,gr28
+ or \reg,gr28,\reg
+ .endif
+ .endm
+
+; Set FR with another FR
+ .macro set_fr_fr src targ
+ fmovs \src,\targ
+ .endm
+
+; Set FR with integer immediate value
+ .macro set_fr_iimmed valh vall reg
+ set_gr_limmed \valh,\vall,gr28
+ movgf gr28,\reg
+ .endm
+
+; Set FR with integer immediate value
+ .macro set_fr_immed val reg
+ set_gr_immed \val,gr28
+ movgf gr28,\reg
+ .endm
+
+; Set FR with a value from memory
+ .macro set_fr_mem addr reg
+ set_gr_addr \addr,gr28
+ ldfi @(gr28,0),\reg
+ .endm
+
+; Set double FR with another double FR
+ .macro set_dfr_dfr src targ
+ fmovd \src,\targ
+ .endm
+
+; Set double FR with a value from memory
+ .macro set_dfr_mem addr reg
+ set_gr_addr \addr,gr28
+ lddfi @(gr28,0),\reg
+ .endm
+
+; Set CPR with immediate value
+ .macro set_cpr_immed val reg
+ addi sp,-4,gr28
+ set_gr_immed \val,gr29
+ st gr29,@(gr28,gr0)
+ ldc @(gr28,gr0),\reg
+ .endm
+
+ .macro set_cpr_limmed valh vall reg
+ addi sp,-4,gr28
+ set_gr_limmed \valh,\vall,gr29
+ st gr29,@(gr28,gr0)
+ ldc @(gr28,gr0),\reg
+ .endm
+
+; Set SPR with immediate value
+ .macro set_spr_immed val reg
+ set_gr_immed \val,gr28
+ movgs gr28,\reg
+ .endm
+
+ .macro set_spr_limmed valh vall reg
+ set_gr_limmed \valh,\vall,gr28
+ movgs gr28,\reg
+ .endm
+
+ .macro set_spr_addr addr reg
+ set_gr_addr \addr,gr28
+ movgs gr28,\reg
+ .endm
+
+; increment SPR with immediate value
+ .macro inc_spr_immed val reg
+ movsg \reg,gr28
+ inc_gr_immed \val,gr28
+ movgs gr28,\reg
+ .endm
+
+; OR spr with immediate value
+ .macro or_spr_immed val reg
+ movsg \reg,gr28
+ set_gr_immed \val,gr29
+ or gr28,gr29,gr28
+ movgs gr28,\reg
+ .endm
+
+; AND spr with immediate value
+ .macro and_spr_immed val reg
+ movsg \reg,gr28
+ set_gr_immed \val,gr29
+ and gr28,gr29,gr28
+ movgs gr28,\reg
+ .endm
+
+; Set accumulator with immediate value
+ .macro set_acc_immed val reg
+ set_fr_immed \val,fr31
+ mwtacc fr31,\reg
+ .endm
+
+; Set accumulator guard with immediate value
+ .macro set_accg_immed val reg
+ set_fr_immed \val,fr31
+ mwtaccg fr31,\reg
+ .endm
+
+; Set memory with immediate value
+ .macro set_mem_immed val base
+ set_gr_immed \val,gr28
+ sti gr28,@(\base,0)
+ .endm
+
+ .macro set_mem_limmed valh vall base
+ set_gr_limmed \valh,\vall,gr28
+ sti gr28,@(\base,0)
+ .endm
+
+; Set memory with GR value
+ .macro set_mem_gr reg addr
+ set_gr_addr \addr,gr28
+ sti \reg,@(gr28,0)
+ .endm
+
+; Test the value of a general register against another general register
+ .macro test_gr_gr reg1 reg2
+ subcc \reg1,\reg2,gr0,icc3
+ beq icc3,0,test_gr\@
+ fail
+test_gr\@:
+ .endm
+
+; Test the value of an immediate against a general register
+ .macro test_gr_immed val reg
+ .if (\val >= -512) && (\val <= 511)
+ subicc \reg,\val,gr0,icc3
+ .else
+ set_gr_immed \val,gr28
+ subcc \reg,gr28,gr0,icc3
+ .endif
+ beq icc3,0,test_gr\@
+ fail
+test_gr\@:
+ .endm
+
+ .macro test_gr_limmed valh vall reg
+ set_gr_limmed \valh,\vall,gr28
+ subcc \reg,gr28,gr0,icc3
+ beq icc3,0,test_gr\@
+ fail
+test_gr\@:
+ .endm
+
+; Test the value of an floating register against an integer immediate
+ .macro test_fr_limmed valh vall reg
+ movfg \reg,gr29
+ set_gr_limmed \valh,\vall,gr28
+ subcc gr29,gr28,gr0,icc3
+ beq icc3,0,test_gr\@
+ fail
+test_gr\@:
+ .endm
+
+ .macro test_fr_iimmed val reg
+ movfg \reg,gr29
+ set_gr_immed \val,gr28
+ subcc gr29,gr28,gr0,icc3
+ beq icc3,0,test_gr\@
+ fail
+test_gr\@:
+ .endm
+
+; Test the value of a floating register against another floating point register
+ .macro test_fr_fr reg1 reg2
+ fcmps \reg1,\reg2,fcc3
+ fbeq fcc3,0,test_gr\@
+ fail
+test_gr\@:
+ .endm
+
+; Test the value of a double floating register against another
+; double floating point register
+ .macro test_dfr_dfr reg1 reg2
+ fcmpd \reg1,\reg2,fcc3
+ fbeq fcc3,0,test_gr\@
+ fail
+test_gr\@:
+ .endm
+
+; Test the value of a special purpose register against an integer immediate
+ .macro test_spr_immed val reg
+ movsg \reg,gr29
+ set_gr_immed \val,gr28
+ subcc gr29,gr28,gr0,icc3
+ beq icc3,0,test_gr\@
+ fail
+test_gr\@:
+ .endm
+
+ .macro test_spr_limmed valh vall reg
+ movsg \reg,gr29
+ set_gr_limmed \valh,\vall,gr28
+ subcc gr29,gr28,gr0,icc3
+ beq icc3,0,test_gr\@
+ fail
+test_gr\@:
+ .endm
+
+ .macro test_spr_gr spr gr
+ movsg \spr,gr28
+ test_gr_gr \gr,gr28
+ .endm
+
+ .macro test_spr_addr addr reg
+ movsg \reg,gr29
+ set_gr_addr \addr,gr28
+ test_gr_gr gr28,gr29
+ .endm
+
+; Test spr bits masked and shifted against the given value
+ .macro test_spr_bits mask,shift,val,reg
+ movsg \reg,gr28
+ set_gr_immed \mask,gr29
+ and gr28,gr29,gr28
+ srli gr28,\shift,gr29
+ test_gr_immed \val,gr29
+ .endm
+
+
+; Test the value of an accumulator against an integer immediate
+ .macro test_acc_immed val reg
+ mrdacc \reg,fr31
+ test_fr_iimmed \val,fr31
+ .endm
+
+; Test the value of an accumulator against an integer immediate
+ .macro test_acc_limmed valh vall reg
+ mrdacc \reg,fr31
+ test_fr_limmed \valh,\vall,fr31
+ .endm
+
+; Test the value of an accumulator guard against an integer immediate
+ .macro test_accg_immed val reg
+ mrdaccg \reg,fr31
+ test_fr_iimmed \val,fr31
+ .endm
+
+; Test CPR agains an immediate value
+ .macro test_cpr_limmed valh vall reg
+ addi sp,-4,gr31
+ stc \reg,@(gr31,gr0)
+ test_mem_limmed \valh,\vall,gr31
+ .endm
+
+; Test the value of an immediate against memory
+ .macro test_mem_immed val base
+ ldi @(\base,0),gr29
+ .if (\val >= -512) && (\val <= 511)
+ subicc gr29,\val,gr0,icc3
+ .else
+ set_gr_immed \val,gr28
+ subcc gr29,gr28,gr0,icc3
+ .endif
+ beq icc3,0,test_gr\@
+ fail
+test_gr\@:
+ .endm
+
+ .macro test_mem_limmed valh vall base
+ ldi @(\base,0),gr29
+ set_gr_limmed \valh,\vall,gr28
+ subcc gr29,gr28,gr0,icc3
+ beq icc3,0,test_gr\@
+ fail
+test_gr\@:
+ .endm
+
+; Set an integer condition code
+ .macro set_icc mask iccno
+ set_gr_immed 4,gr29
+ smuli gr29,\iccno,gr30
+ addi gr31,16,gr31
+ set_gr_immed 0xf,gr28
+ sll gr28,gr31,gr28
+ not gr28,gr28
+ movsg ccr,gr29
+ and gr28,gr29,gr29
+ set_gr_immed \mask,gr28
+ sll gr28,gr31,gr28
+ or gr28,gr29,gr29
+ movgs gr29,ccr
+ .endm
+; started here
+; Test the condition codes
+ .macro test_icc N Z V C iccno
+ .if (\N == 1)
+ bp \iccno,0,fail\@
+ .else
+ bn \iccno,0,fail\@
+ .endif
+ .if (\Z == 1)
+ bne \iccno,0,fail\@
+ .else
+ beq \iccno,0,fail\@
+ .endif
+ .if (\V == 1)
+ bnv \iccno,0,fail\@
+ .else
+ bv \iccno,0,fail\@
+ .endif
+ .if (\C == 1)
+ bnc \iccno,0,fail\@
+ .else
+ bc \iccno,0,fail\@
+ .endif
+ bra test_cc\@
+fail\@:
+ fail
+test_cc\@:
+ .endm
+
+; Set an floating point condition code
+ .macro set_fcc mask fccno
+ set_gr_immed 4,gr29
+ smuli gr29,\fccno,gr30
+ set_gr_immed 0xf,gr28
+ sll gr28,gr31,gr28
+ not gr28,gr28
+ movsg ccr,gr29
+ and gr28,gr29,gr29
+ set_gr_immed \mask,gr28
+ sll gr28,gr31,gr28
+ or gr28,gr29,gr29
+ movgs gr29,ccr
+ .endm
+
+; Test the condition codes
+ .macro test_fcc val fccno
+ set_gr_immed 4,gr29
+ smuli gr29,\fccno,gr30
+ movsg ccr,gr29
+ srl gr29,gr31,gr29
+ andi gr29,0xf,gr29
+ test_gr_immed \val,gr29
+ .endm
+
+; Set PSR.ET
+ .macro set_psr_et val
+ movsg psr,gr28
+ .if (\val == 1)
+ ori gr28,1,gr28 ; Turn on SPR.ET
+ .else
+ andi gr28,0xfffffffe,gr28 ; Turn off SPR.ET
+ .endif
+ movgs gr28,psr
+ .endm
+
+; Floating point constants
+ .macro float_constants
+f0: .float 0.0
+f1: .float 1.0
+f2: .float 2.0
+f3: .float 3.0
+f6: .float 6.0
+f9: .float 9.0
+fn0: .float -0.0
+fn1: .float -1.0
+finf: .long 0x7f800000
+fninf: .long 0xff800000
+fmax: .long 0x7f7fffff
+fmin: .long 0xff7fffff
+feps: .long 0x00400000
+fneps: .long 0x80400000
+fnan1: .long 0x7fc00000
+fnan2: .long 0x7f800001
+ .endm
+
+ .macro double_constants
+d0: .double 0.0
+d1: .double 1.0
+d2: .double 2.0
+d3: .double 3.0
+d6: .double 6.0
+d9: .double 9.0
+dn0: .double -0.0
+dn1: .double -1.0
+dinf: .long 0x7ff00000
+ .long 0x00000000
+dninf: .long 0xfff00000
+ .long 0x00000000
+dmax: .long 0x7fefffff
+ .long 0xffffffff
+dmin: .long 0xffefffff
+ .long 0xffffffff
+deps: .long 0x00080000
+ .long 0x00000000
+dneps: .long 0x80080000
+ .long 0x00000000
+dnan1: .long 0x7ff80000
+ .long 0x00000000
+dnan2: .long 0x7ff00000
+ .long 0x00000001
+ .endm
+
+; Load floating point constants
+ .macro load_float_constants
+ set_fr_mem fninf,fr0
+ set_fr_mem fmin,fr4
+ set_fr_mem fn1,fr8
+ set_fr_mem fneps,fr12
+ set_fr_mem fn0,fr16
+ set_fr_mem f0,fr20
+ set_fr_mem feps,fr24
+ set_fr_mem f1,fr28
+ set_fr_mem f2,fr32
+ set_fr_mem f3,fr36
+ set_fr_mem f6,fr40
+ set_fr_mem f9,fr44
+ set_fr_mem fmax,fr48
+ set_fr_mem finf,fr52
+ set_fr_mem fnan1,fr56
+ set_fr_mem fnan2,fr60
+ .endm
+
+ .macro load_float_constants1
+ set_fr_mem fninf,fr1
+ set_fr_mem fmin,fr5
+ set_fr_mem fn1,fr9
+ set_fr_mem fneps,fr13
+ set_fr_mem fn0,fr17
+ set_fr_mem f0,fr21
+ set_fr_mem feps,fr25
+ set_fr_mem f1,fr29
+ set_fr_mem f2,fr33
+ set_fr_mem f3,fr37
+ set_fr_mem f6,fr41
+ set_fr_mem f9,fr45
+ set_fr_mem fmax,fr49
+ set_fr_mem finf,fr53
+ set_fr_mem fnan1,fr57
+ set_fr_mem fnan2,fr61
+ .endm
+
+ .macro load_float_constants2
+ set_fr_mem fninf,fr2
+ set_fr_mem fmin,fr6
+ set_fr_mem fn1,fr10
+ set_fr_mem fneps,fr14
+ set_fr_mem fn0,fr18
+ set_fr_mem f0,fr22
+ set_fr_mem feps,fr26
+ set_fr_mem f1,fr30
+ set_fr_mem f2,fr34
+ set_fr_mem f3,fr38
+ set_fr_mem f6,fr42
+ set_fr_mem f9,fr46
+ set_fr_mem fmax,fr50
+ set_fr_mem finf,fr54
+ set_fr_mem fnan1,fr58
+ set_fr_mem fnan2,fr62
+ .endm
+
+ .macro load_float_constants3
+ set_fr_mem fninf,fr3
+ set_fr_mem fmin,fr7
+ set_fr_mem fn1,fr11
+ set_fr_mem fneps,fr15
+ set_fr_mem fn0,fr19
+ set_fr_mem f0,fr23
+ set_fr_mem feps,fr27
+ set_fr_mem f1,fr31
+ set_fr_mem f2,fr35
+ set_fr_mem f3,fr39
+ set_fr_mem f6,fr43
+ set_fr_mem f9,fr47
+ set_fr_mem fmax,fr51
+ set_fr_mem finf,fr55
+ set_fr_mem fnan1,fr59
+ set_fr_mem fnan2,fr63
+ .endm
+
+ .macro load_double_constants
+ set_dfr_mem dninf,fr0
+ set_dfr_mem dmin,fr4
+ set_dfr_mem dn1,fr8
+ set_dfr_mem dneps,fr12
+ set_dfr_mem dn0,fr16
+ set_dfr_mem d0,fr20
+ set_dfr_mem deps,fr24
+ set_dfr_mem d1,fr28
+ set_dfr_mem d2,fr32
+ set_dfr_mem d3,fr36
+ set_dfr_mem d6,fr40
+ set_dfr_mem d9,fr44
+ set_dfr_mem dmax,fr48
+ set_dfr_mem dinf,fr52
+ set_dfr_mem dnan1,fr56
+ set_dfr_mem dnan2,fr60
+ .endm
+
+; Lock the insn cache at the given address
+ .macro lock_insn_cache address
+ icpl \address,gr0,1
+ .endm
+
+; Lock the data cache at the given address
+ .macro lock_data_cache address
+ dcpl \address,gr0,1
+ .endm
+
+; Invalidate the data cache at the given address
+ .macro invalidate_data_cache address
+ dci @(\address,gr0)
+ .endm
+
+; Flush the data cache at the given address
+ .macro flush_data_cache address
+ dcf @(\address,gr0)
+ .endm
+
+; Write a bctrlr 0,0 insn at the address contained in the given register
+ .macro set_bctrlr_0_0 address
+ set_mem_immed 0x80382000,\address ; bctrlr 0,0
+ flush_data_cache \address
+ .endm
+
+; Exit with return code
+ .macro exit rc
+ setlos #1,gr7
+ set_gr_immed \rc,gr8
+ tira gr0,#0
+ .endm
+
+; Pass the test case
+ .macro pass
+pass\@:
+ setlos.p #5,gr10
+ setlos #1,gr8
+ setlos #5,gr7
+ set_gr_addr passmsg,gr9
+ tira gr0,#0
+ exit #0
+ .endm
+
+; Fail the testcase
+ .macro fail
+fail\@:
+ setlos.p #5,gr10
+ setlos #1,gr8
+ setlos #5,gr7
+ set_gr_addr failmsg,gr9
+ tira gr0,#0
+ exit #1
+ .endm