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