#include <machine/asm.h>
#include <machine/cpu.h>
#include "assym.h"
#define FPEMU_VERSION (1 << 11)
#define FP_TABLE2(name,ep0,ep1,ep2,ep3) \
ldil L%$fpemu_tbl$name, t1 ! \
ldo R%$fpemu_tbl$name(t1), t1 ! \
ldwx,s r1(t1), t2 ! \
bv r0(t2) ! \
copy r0, ret0 ! \
.label $fpemu_tbl$name ! \
.import ep0##_##name, code ! \
.import ep1##_##name, code ! \
.import ep2##_##name, code ! \
.import ep3##_##name, code ! \
.word ep0##_##name, ep1##_##name, ep2##_##name, ep3##_##name
#define FP_TABLE3(name,ep0,ep1,ep2,ep3,ep4,ep5,ep6,ep7,ep8,ep9,epa,epb,epc,epd,epe,epf) \
ldil L%$fpemu_tbl$name, t1 ! \
ldo R%$fpemu_tbl$name(t1), t1 ! \
ldwx,s r1(t1), t2 ! \
bv r0(t2) ! \
nop ! \
.label $fpemu_tbl$name ! \
.import ep0##_##name, code ! \
.import ep1##_##name, code ! \
.import ep2##_##name, code ! \
.import ep3##_##name, code ! \
.import ep4##_##name, code ! \
.import ep5##_##name, code ! \
.import ep6##_##name, code ! \
.import ep7##_##name, code ! \
.import ep8##_##name, code ! \
.import ep9##_##name, code ! \
.import epa##_##name, code ! \
.import epb##_##name, code ! \
.import epc##_##name, code ! \
.import epd##_##name, code ! \
.import epe##_##name, code ! \
.import epf##_##name, code ! \
.word ep0##_##name, ep1##_##name, ep2##_##name, ep3##_##name, \
ep4##_##name, ep5##_##name, ep6##_##name, ep7##_##name, \
ep8##_##name, ep9##_##name, epa##_##name, epb##_##name, \
epc##_##name, epe##_##name, epf##_##name
.text
LEAF_ENTRY(fpu_emulate)
copy arg0, t4
extru arg0, 18, 3, r31
extru arg0, 20, 2, r1
extru arg0, 22, 2, t3
subi,<> 1, t3, r0
extru arg0, 16, 2, r31
extru,<> arg0, 10, 5, t1
ldi 32, t1
extru,<> arg0, 31, 5, t2
b,n $fpemu_nzt
nop
nop
$fpemu_nzt
copy arg2, arg3
copy arg2, arg1
sh3add t1, arg2, arg0
sh3add t2, arg2, arg2
stw r0, 32*8+0(arg1)
stw r0, 32*8+4(arg1)
extru,= t4, 24, 1, r0
addi 4, arg0, arg0
comib,=,n 2, t3, $fpemu0c_2
nop
extru,= t4, 24, 1, r0
addi 4, arg2, arg2
comib,=,n 0, t3, $fpemu0c_0
comib,=,n 1, t3, $fpemu0c_1
comib,=,n 3, t3, $fpemu0c_3
$fpemu0c_0
comib,=,n 2, r1, $fpemu_exit
comib,=,n 0, r31, $fpemu0c_0_0
comib,=,n 1, r31, $fpemu_exit
comib,=,n 2, r31, $fpemu0c_0_2
comib,=,n 3, r31, $fpemu0c_0_3
comib,=,n 4, r31, $fpemu0c_0_4
comib,=,n 5, r31, $fpemu0c_0_5
comib,=,n 6, r31, $fpemu_exit
comib,=,n 7, r31, $fpemu_exit
$fpemu0c_0_0
ldi FPEMU_VERSION, t4
stw t4, 0(arg3)
bv 0(rp)
copy r0, ret0
$fpemu0c_0_2
subi 3, r1, r1
ldw 0*4(arg0), t1
ldw 1*4(arg0), t2
ldw 2*4(arg0), t3
blr,n r1, r0
ldw 3*4(arg0), t4
stw t3, 2*4(arg2)
stw t4, 3*4(arg2)
nop
nop
nop
stw t2, 1*4(arg2)
stw t1, 0*4(arg2)
bv 0(rp)
copy r0, ret0
$fpemu0c_0_3
subi 3, r1, r1
ldw 0*4(arg0), t1
ldw 1*4(arg0), t2
ldw 2*4(arg0), t3
ldw 3*4(arg0), t4
blr,n r1, r0
depi 0, 0, 1, t1
stw t3, 2*4(arg2)
stw t4, 3*4(arg2)
nop
nop
nop
stw t2, 1*4(arg2)
stw t1, 0*4(arg2)
bv 0(rp)
copy r0, ret0
$fpemu0c_0_4
FP_TABLE2(fsqrt,sgl,dbl,invalid,invalid)
$fpemu0c_0_5
FP_TABLE2(frnd,sgl,dbl,invalid,quad)
$fpemu0c_1
extru t4, 20, 4, r1
comib,=,n 0, r31, $fpemu0c_1_0
comib,=,n 1, r31, $fpemu0c_1_1
comib,=,n 2, r31, $fpemu0c_1_2
comib,=,n 3, r31, $fpemu0c_1_3
$fpemu0c_1_0
FP_TABLE3(fcnvff, invalid, dbl_to_sgl, invalid, quad_to_sgl, sgl_to_dbl, invalid, invalid, quad_to_dbl, invalid, invalid, invalid, invalid, sgl_to_quad, dbl_to_quad, invalid, invalid)
$fpemu0c_1_1
FP_TABLE3(fcnvxf, sgl_to_sgl, dbl_to_sgl, invalid, quad_to_sgl, sgl_to_dbl, dbl_to_dbl, invalid, quad_to_dbl, invalid, invalid, invalid, invalid, sgl_to_quad, dbl_to_quad, invalid, quad_to_quad)
$fpemu0c_1_2
FP_TABLE3(fcnvfx, sgl_to_sgl, dbl_to_sgl, invalid, quad_to_sgl, sgl_to_dbl, dbl_to_dbl, invalid, quad_to_dbl, invalid, invalid, invalid, invalid, sgl_to_quad, dbl_to_quad, invalid, quad_to_quad)
$fpemu0c_1_3
FP_TABLE3(fcnvfxt, sgl_to_sgl, dbl_to_sgl, invalid, quad_to_sgl, sgl_to_dbl, dbl_to_dbl, invalid, quad_to_dbl, invalid, invalid, invalid, invalid, sgl_to_quad, dbl_to_quad, invalid, quad_to_quad)
$fpemu0c_2
comib,=,n 1, r31, $fpemu0c_2_1
comib,<>,n 0, r31, $fpemu_exit
$fpemu0c_2_0
extru,<> t4, 15, 5, t1
ldi 32, t1
sh3add t1, arg3, arg1
extru,= t4, 19, 1, r0
addi 4, arg1, arg1
extru t4, 31, 5, arg2
FP_TABLE2(fcmp,sgl,dbl,invalid,invalid)
$fpemu0c_2_1
comib,<>,n 0, r1, $fpemu_exit
ldw 0(arg3), t1
ldi 0, ret0
extru,<> t1, 5, 1, r0
bv,n r0(rp)
mtctl r0, pcsq
mfctl pcsq, t2
mtctl t2, pcsq
mtctl t2, pcsq
mtctl r0, pcoq
mfctl pcoq, t2
mtctl t2, pcoq
ldo 4(t2), t2
bv r0(rp)
mtctl t2, pcoq
$fpemu0c_3
extru,<> t4, 15, 5, t1
ldi 32, t1
extru,= t4, 19, 1, r0
addi 4, arg1, arg1
blr r31, r0
nop
b $fpemu0c_3_0
sh3add t1, arg1, arg1
b $fpemu0c_3_1
sh3add t1, arg1, arg1
b $fpemu0c_3_2
sh3add t1, arg1, arg1
b $fpemu0c_3_3
sh3add t1, arg1, arg1
b $fpemu0c_3_4
sh3add t1, arg1, arg1
b $fpemu_exit
sh3add t1, arg1, arg1
b $fpemu_exit
sh3add t1, arg1, arg1
b $fpemu_exit
sh3add t1, arg1, arg1
$fpemu0c_3_0
FP_TABLE2(fadd,sgl,dbl,invalid,invalid)
$fpemu0c_3_1
FP_TABLE2(fsub,sgl,dbl,invalid,invalid)
$fpemu0c_3_2
bb,>= t4, 23, $fpemu0c_3_2_f
nop
FP_TABLE2(xmpy,s,u,s,u)
$fpemu0c_3_2_f
FP_TABLE2(fmpy,sgl,dbl,invalid,invalid)
$fpemu0c_3_3
FP_TABLE2(fdiv,sgl,dbl,invalid,invalid)
$fpemu0c_3_4
FP_TABLE2(frem,sgl,dbl,invalid,invalid)
.export $fpemu_exit, code
$fpemu_exit
invalid_fsqrt
invalid_frnd
invalid_fcnvff
sgl_to_quad_fcnvff
dbl_to_quad_fcnvff
quad_to_sgl_fcnvff
quad_to_dbl_fcnvff
invalid_fcnvxf
sgl_to_quad_fcnvxf
dbl_to_quad_fcnvxf
quad_to_sgl_fcnvxf
quad_to_dbl_fcnvxf
quad_to_quad_fcnvxf
invalid_fcnvfx
sgl_to_quad_fcnvfx
dbl_to_quad_fcnvfx
quad_to_sgl_fcnvfx
quad_to_dbl_fcnvfx
quad_to_quad_fcnvfx
invalid_fcnvfxt
sgl_to_quad_fcnvfxt
dbl_to_quad_fcnvfxt
quad_to_sgl_fcnvfxt
quad_to_dbl_fcnvfxt
quad_to_quad_fcnvfxt
invalid_fcmp
invalid_fadd
invalid_fsub
invalid_fmpy
invalid_fdiv
invalid_frem
bv 0(rp)
ldi HPPA_FPU_ILL, ret0
EXIT(fpu_emulate)
.end