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