diff options
Diffstat (limited to 'sim/testsuite/frv/testutils.inc')
-rw-r--r-- | sim/testsuite/frv/testutils.inc | 656 |
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 |