1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-21 03:00:19 +02:00

MIPS: Build and pass all test cases on mips64.

* include/lightning/jit_mips.h, lib/jit_mips-cpu.c,
	lib/jit_mips-sz.c, lib/jit_mips.c, size: Build and
	pass all test cases on Irix big endian mips using
	the 64 bit abi.
This commit is contained in:
pcpa 2013-10-04 00:01:31 -03:00
parent 485584546a
commit 52bfc67192
6 changed files with 704 additions and 263 deletions

View file

@ -1,3 +1,10 @@
2013-10-03 Paulo Andrade <pcpa@gnu.org>
* include/lightning/jit_mips.h, lib/jit_mips-cpu.c,
lib/jit_mips-sz.c, lib/jit_mips.c, size: Build and
pass all test cases on Irix big endian mips using
the 64 bit abi.
2013-10-02 Paulo Andrade <pcpa@gnu.org> 2013-10-02 Paulo Andrade <pcpa@gnu.org>
* include/lightning/jit_mips.h: Add proper mips abi detection. * include/lightning/jit_mips.h: Add proper mips abi detection.

View file

@ -23,11 +23,8 @@
#define JIT_HASH_CONSTS 1 #define JIT_HASH_CONSTS 1
#define JIT_NUM_OPERANDS 3 #define JIT_NUM_OPERANDS 3
#if _MIPS_SIM == _ABIN32 #if _MIPS_SIM != _ABIO32
# define NEW_ABI 1 # define NEW_ABI 1
#elif _MIPS_SIM != _ABIO32
/* FIXME port to _ABI64 */
# error "Unsupported ABI"
#endif #endif
/* /*

View file

@ -308,39 +308,39 @@ static void _nop(jit_state_t*,jit_int32_t);
# define h_ri(hc,rt,im) _hrri(_jit,hc,0,rt,im) # define h_ri(hc,rt,im) _hrri(_jit,hc,0,rt,im)
# define rrit(rt,rd,im,tc) _hrrrit(_jit,0,0,rt,rd,im,tc) # define rrit(rt,rd,im,tc) _hrrrit(_jit,0,0,rt,rd,im,tc)
# define LUI(rt,im) h_ri(MIPS_LUI,rt,im) # define LUI(rt,im) h_ri(MIPS_LUI,rt,im)
# if __WORDSIZE == 32
# define ADDU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_ADDU) # define ADDU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_ADDU)
# define DADDU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_DADDU)
# define ADDIU(rt,rs,im) hrri(MIPS_ADDIU,rs,rt,im) # define ADDIU(rt,rs,im) hrri(MIPS_ADDIU,rs,rt,im)
# define DADDIU(rt,rs,im) hrri(MIPS_DADDIU,rs,rt,im)
# define SUBU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_SUBU) # define SUBU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_SUBU)
# define DSUBU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_DSUBU)
# define MULT(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_MULT) # define MULT(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_MULT)
# define MULTU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_MULTU) # define MULTU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_MULTU)
# define DMULT(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DMULT)
# define DMULTU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DMULTU)
# define DIV(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DIV) # define DIV(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DIV)
# define DIVU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DIVU) # define DIVU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DIVU)
# define DDIV(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DDIV)
# define DDIVU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DDIVU)
# define SLLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SLLV) # define SLLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SLLV)
# define SLL(rd,rt,sa) rrit(rt,rd,sa,MIPS_SLL) # define SLL(rd,rt,sa) rrit(rt,rd,sa,MIPS_SLL)
# define DSLLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSLLV)
# define DSLL(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSLL)
# define DSLL32(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSLL32)
# define SRAV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SRAV) # define SRAV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SRAV)
# define SRA(rd,rt,sa) rrit(rt,rd,sa,MIPS_SRA) # define SRA(rd,rt,sa) rrit(rt,rd,sa,MIPS_SRA)
# define SRLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SRLV) # define SRLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SRLV)
# define SRL(rd,rt,sa) rrit(rt,rd,sa,MIPS_SRL) # define SRL(rd,rt,sa) rrit(rt,rd,sa,MIPS_SRL)
# define ROTR(rd,rt,sa) hrrrit(MIPS_SPECIAL,1,rt,rd,sa,MIPS_DSRL) # define DSRAV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSRAV)
# define INS(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,pos,pos+size-1,MIPS_DINS) # define DSRA(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRA)
# else # define DSRA32(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRA32)
# define ADDU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_DADDU) # define DSRLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSRLV)
# define ADDIU(rt,rs,im) hrri(MIPS_DADDIU,rs,rt,im) # define DSRL(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRL)
# define SUBU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_DSUBU) # define DSRL32(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRL32)
# define MULT(rs, rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DMULT)
# define MULTU(rs, rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DMULTU)
# define DIV(rs, rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DDIV)
# define DIVU(rs, rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DDIVU)
# define SLLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSLLV)
# define SLL(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSLL)
# define SRAV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSRAV)
# define SRA(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRA)
# define SRLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSRLV)
# define SRL(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRL)
# define ROTR(rd,rt,sa) hrrrit(MIPS_SPECIAL,1,rt,rd,sa,MIPS_SRL)
# define INS(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,pos,pos+size-1,MIPS_INS) # define INS(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,pos,pos+size-1,MIPS_INS)
# endif # define DINS(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,pos,pos+size-1,MIPS_DINS)
# define ROTR(rd,rt,sa) hrrrit(MIPS_SPECIAL,1,rt,rd,sa,MIPS_SRL)
# define DROTR(rd,rt,sa) hrrrit(MIPS_SPECIAL,1,rt,rd,sa,MIPS_DSRL)
# define MFHI(rd) rrr_t(_ZERO_REGNO,_ZERO_REGNO,rd,MIPS_MFHI) # define MFHI(rd) rrr_t(_ZERO_REGNO,_ZERO_REGNO,rd,MIPS_MFHI)
# define MFLO(rd) rrr_t(_ZERO_REGNO,_ZERO_REGNO,rd,MIPS_MFLO) # define MFLO(rd) rrr_t(_ZERO_REGNO,_ZERO_REGNO,rd,MIPS_MFLO)
# define MTHI(rs) rrr_t(rs,_ZERO_REGNO,_ZERO_REGNO,MIPS_MTHI) # define MTHI(rs) rrr_t(rs,_ZERO_REGNO,_ZERO_REGNO,MIPS_MTHI)
@ -359,6 +359,7 @@ static void _nop(jit_state_t*,jit_int32_t);
# define LWU(rt,of,rb) hrri(MIPS_LWU,rb,rt,of) # define LWU(rt,of,rb) hrri(MIPS_LWU,rb,rt,of)
# define LD(rt,of,rb) hrri(MIPS_LD,rb,rt,of) # define LD(rt,of,rb) hrri(MIPS_LD,rb,rt,of)
# define SB(rt,of,rb) hrri(MIPS_SB,rb,rt,of) # define SB(rt,of,rb) hrri(MIPS_SB,rb,rt,of)
# define SH(rt,of,rb) hrri(MIPS_SH,rb,rt,of)
# define SW(rt,of,rb) hrri(MIPS_SW,rb,rt,of) # define SW(rt,of,rb) hrri(MIPS_SW,rb,rt,of)
# define SD(rt,of,rb) hrri(MIPS_SD,rb,rt,of) # define SD(rt,of,rb) hrri(MIPS_SD,rb,rt,of)
# define WSBH(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,MIPS_WSBH,MIPS_BSHFL) # define WSBH(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,MIPS_WSBH,MIPS_BSHFL)
@ -379,8 +380,24 @@ static void _nop(jit_state_t*,jit_int32_t);
# define J(i0) hi(MIPS_J,i0) # define J(i0) hi(MIPS_J,i0)
# define MOVZ(rd,rs,rt) hrrrit(0,rs,rt,rd,0,MIPS_MOVZ) # define MOVZ(rd,rs,rt) hrrrit(0,rs,rt,rd,0,MIPS_MOVZ)
# define comr(r0,r1) xori(r0,r1,-1) # define comr(r0,r1) xori(r0,r1,-1)
# define negr(r0,r1) SUBU(r0,_ZERO_REGNO,r1) # define negr(r0,r1) subr(r0,_ZERO_REGNO,r1)
# if __WORDSIZE == 32
# define addr(rd,rs,rt) ADDU(rd,rs,rt) # define addr(rd,rs,rt) ADDU(rd,rs,rt)
# define addiu(r0,r1,i0) ADDIU(r0,r1,i0)
# define subr(rd,rs,rt) SUBU(rd,rs,rt)
# define mult(rs,rt) MULT(rs,rt)
# define multu(rs,rt) MULTU(rs,rt)
# define div(rs,rt) DIV(rs,rt)
# define divu(rs,rt) DIVU(rs,rt)
# else
# define addr(rd,rs,rt) DADDU(rd,rs,rt)
# define addiu(r0,r1,i0) DADDIU(r0,r1,i0)
# define subr(rd,rs,rt) DSUBU(rd,rs,rt)
# define mult(rs,rt) DMULT(rs,rt)
# define multu(rs,rt) DMULTU(rs,rt)
# define div(rs,rt) DDIV(rs,rt)
# define divu(rs,rt) DDIVU(rs,rt)
# endif
# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0) # define addi(r0,r1,i0) _addi(_jit,r0,r1,i0)
static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
#define addcr(r0,r1,r2) _addcr(_jit,r0,r1,r2) #define addcr(r0,r1,r2) _addcr(_jit,r0,r1,r2)
@ -391,7 +408,6 @@ static void _addci(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
static void _addxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); static void _addxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0) # define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0)
static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define subr(rd,rs,rt) SUBU(rd,rs,rt)
# define subi(r0,r1,i0) _subi(_jit,r0,r1,i0) # define subi(r0,r1,i0) _subi(_jit,r0,r1,i0)
static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define subcr(r0,r1,r2) _subcr(_jit,r0,r1,r2) # define subcr(r0,r1,r2) _subcr(_jit,r0,r1,r2)
@ -442,12 +458,24 @@ static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0) # define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0)
static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# if __WORDSIZE == 32
# define lshr(r0,r1,r2) SLLV(r0,r1,r2) # define lshr(r0,r1,r2) SLLV(r0,r1,r2)
# define lshi(r0,r1,i0) SLL(r0,r1,i0) # define lshi(r0,r1,i0) SLL(r0,r1,i0)
# define rshr(r0,r1,r2) SRAV(r0,r1,r2) # define rshr(r0,r1,r2) SRAV(r0,r1,r2)
# define rshi(r0,r1,i0) SRA(r0,r1,i0) # define rshi(r0,r1,i0) SRA(r0,r1,i0)
# define rshr_u(r0,r1,r2) SRLV(r0,r1,r2) # define rshr_u(r0,r1,r2) SRLV(r0,r1,r2)
# define rshi_u(r0,r1,i0) SRL(r0,r1,i0) # define rshi_u(r0,r1,i0) SRL(r0,r1,i0)
# else
# define lshr(r0,r1,r2) DSLLV(r0,r1,r2)
# define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0)
static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define rshr(r0,r1,r2) DSRAV(r0,r1,r2)
# define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0)
static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define rshr_u(r0,r1,r2) DSRLV(r0,r1,r2)
# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0)
static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# endif
# define andr(r0,r1,r2) AND(r0,r1,r2) # define andr(r0,r1,r2) AND(r0,r1,r2)
# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0) # define andi(r0,r1,i0) _andi(_jit,r0,r1,i0)
static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
@ -518,7 +546,6 @@ static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define str_c(r0,r1) SB(r1,0,r0) # define str_c(r0,r1) SB(r1,0,r0)
# define sti_c(i0,r0) _sti_c(_jit,i0,r0) # define sti_c(i0,r0) _sti_c(_jit,i0,r0)
static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t); static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t);
# define SH(rt,of,rb) hrri(MIPS_SH,rb,rt,of)
# define str_s(r0,r1) SH(r1,0,r0) # define str_s(r0,r1) SH(r1,0,r0)
# define sti_s(i0,r0) _sti_s(_jit,i0,r0) # define sti_s(i0,r0) _sti_s(_jit,i0,r0)
static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t); static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t);
@ -526,7 +553,7 @@ static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t);
# define sti_i(i0,r0) _sti_i(_jit,i0,r0) # define sti_i(i0,r0) _sti_i(_jit,i0,r0)
static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t);
# if __WORDSIZE == 64 # if __WORDSIZE == 64
# define str_l(r0, r1) SD(r0, 0, r1) # define str_l(r0,r1) SD(r1,0,r0)
# define sti_l(i0,r0) _sti_l(_jit,i0,r0) # define sti_l(i0,r0) _sti_l(_jit,i0,r0)
static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t); static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t);
# endif # endif
@ -561,7 +588,7 @@ static void _extr_c(jit_state_t*,jit_int32_t,jit_int32_t);
static void _extr_s(jit_state_t*,jit_int32_t,jit_int32_t); static void _extr_s(jit_state_t*,jit_int32_t,jit_int32_t);
# define extr_us(r0,r1) ANDI(r0,r1,0xffff) # define extr_us(r0,r1) ANDI(r0,r1,0xffff)
# if __WORDSIZE == 64 # if __WORDSIZE == 64
# define extr_i(r0,r1) SLL(r0, r0, 0) # define extr_i(r0,r1) SLL(r0,r1,0)
# define extr_ui(r0,r1) _extr_ui(_jit,r0,r1) # define extr_ui(r0,r1) _extr_ui(_jit,r0,r1)
static void _extr_ui(jit_state_t*,jit_int32_t,jit_int32_t); static void _extr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
# endif # endif
@ -753,7 +780,7 @@ _addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
if (i0 == 0) if (i0 == 0)
movr(r0, r1); movr(r0, r1);
else if (can_sign_extend_short_p(i0)) else if (can_sign_extend_short_p(i0))
ADDIU(r0, r1, i0); addiu(r0, r1, i0);
else { else {
reg = jit_get_reg(jit_class_gpr); reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0); movi(rn(reg), i0);
@ -771,13 +798,13 @@ _addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
jit_carry = jit_get_reg(jit_class_gpr); jit_carry = jit_get_reg(jit_class_gpr);
if (r0 == r1) { if (r0 == r1) {
t0 = jit_get_reg(jit_class_gpr); t0 = jit_get_reg(jit_class_gpr);
ADDU(rn(t0), r1, r2); addr(rn(t0), r1, r2);
SLTU(rn(jit_carry), rn(t0), r1); SLTU(rn(jit_carry), rn(t0), r1);
movr(r0, rn(t0)); movr(r0, rn(t0));
jit_unget_reg(t0); jit_unget_reg(t0);
} }
else { else {
ADDU(r0, r1, r2); addr(r0, r1, r2);
SLTU(rn(jit_carry), r0, r1); SLTU(rn(jit_carry), r0, r1);
} }
} }
@ -792,7 +819,7 @@ _addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
t0 = jit_get_reg(jit_class_gpr); t0 = jit_get_reg(jit_class_gpr);
if (r0 == r1) { if (r0 == r1) {
if (can_sign_extend_short_p(i0)) if (can_sign_extend_short_p(i0))
ADDIU(rn(t0), r1, i0); addiu(rn(t0), r1, i0);
else { else {
movi(rn(t0), i0); movi(rn(t0), i0);
addr(rn(t0), r1, rn(t0)); addr(rn(t0), r1, rn(t0));
@ -802,7 +829,7 @@ _addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
} }
else { else {
if (can_sign_extend_short_p(i0)) if (can_sign_extend_short_p(i0))
ADDIU(r0, r1, i0); addiu(r0, r1, i0);
else { else {
movi(rn(t0), i0); movi(rn(t0), i0);
addr(r0, r1, rn(t0)); addr(r0, r1, rn(t0));
@ -845,7 +872,7 @@ _subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
if (i0 == 0) if (i0 == 0)
movr(r0, r1); movr(r0, r1);
else if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) else if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000)
ADDIU(r0, r1, -i0); addiu(r0, r1, -i0);
else { else {
reg = jit_get_reg(jit_class_gpr); reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0); movi(rn(reg), i0);
@ -863,13 +890,13 @@ _subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
jit_carry = jit_get_reg(jit_class_gpr); jit_carry = jit_get_reg(jit_class_gpr);
if (r0 == r1) { if (r0 == r1) {
t0 = jit_get_reg(jit_class_gpr); t0 = jit_get_reg(jit_class_gpr);
SUBU(rn(t0), r1, r2); subr(rn(t0), r1, r2);
SLTU(rn(jit_carry), r1, rn(t0)); SLTU(rn(jit_carry), r1, rn(t0));
movr(r0, rn(t0)); movr(r0, rn(t0));
jit_unget_reg(t0); jit_unget_reg(t0);
} }
else { else {
SUBU(r0, r1, r2); subr(r0, r1, r2);
SLTU(rn(jit_carry), r1, r0); SLTU(rn(jit_carry), r1, r0);
} }
} }
@ -884,7 +911,7 @@ _subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
t0 = jit_get_reg(jit_class_gpr); t0 = jit_get_reg(jit_class_gpr);
if (r0 == r1) { if (r0 == r1) {
if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000)
ADDIU(rn(t0), r1, -i0); addiu(rn(t0), r1, -i0);
else { else {
movi(rn(t0), i0); movi(rn(t0), i0);
subr(rn(t0), r1, rn(t0)); subr(rn(t0), r1, rn(t0));
@ -894,7 +921,7 @@ _subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
} }
else { else {
if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000)
ADDIU(r0, r1, -i0); addiu(r0, r1, -i0);
else { else {
movi(rn(t0), i0); movi(rn(t0), i0);
subr(r0, r1, rn(t0)); subr(r0, r1, rn(t0));
@ -933,7 +960,7 @@ _subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
static void static void
_mulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) _mulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{ {
MULTU(r1, r2); multu(r1, r2);
MFLO(r0); MFLO(r0);
} }
@ -953,9 +980,9 @@ _iqmulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) jit_int32_t r2, jit_int32_t r3, jit_bool_t sign)
{ {
if (sign) if (sign)
MULT(r2, r3); mult(r2, r3);
else else
MULTU(r2, r3); multu(r2, r3);
MFLO(r0); MFLO(r0);
MFHI(r1); MFHI(r1);
} }
@ -974,7 +1001,7 @@ _iqmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
static void static void
_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) _divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{ {
DIV(r1, r2); div(r1, r2);
MFLO(r0); MFLO(r0);
} }
@ -991,7 +1018,7 @@ _divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
static void static void
_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) _divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{ {
DIVU(r1, r2); divu(r1, r2);
MFLO(r0); MFLO(r0);
} }
@ -1010,9 +1037,9 @@ _iqdivr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) jit_int32_t r2, jit_int32_t r3, jit_bool_t sign)
{ {
if (sign) if (sign)
DIV(r2, r3); div(r2, r3);
else else
DIVU(r2, r3); divu(r2, r3);
MFLO(r0); MFLO(r0);
MFHI(r1); MFHI(r1);
} }
@ -1031,7 +1058,7 @@ _iqdivi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
static void static void
_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) _remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{ {
DIV(r1, r2); div(r1, r2);
MFHI(r0); MFHI(r0);
} }
@ -1048,7 +1075,7 @@ _remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
static void static void
_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) _remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{ {
DIVU(r1, r2); divu(r1, r2);
MFHI(r0); MFHI(r0);
} }
@ -1062,6 +1089,38 @@ _remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
jit_unget_reg(reg); jit_unget_reg(reg);
} }
#if __WORDSIZE == 64
static void
_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
assert(i0 >= 0 && i0 <= 63);
if (i0 < 32)
DSLL(r0, r1, i0);
else
DSLL32(r0, r1, i0 - 32);
}
static void
_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
assert(i0 >= 0 && i0 <= 63);
if (i0 < 32)
DSRA(r0, r1, i0);
else
DSRA32(r0, r1, i0 - 32);
}
static void
_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
assert(i0 >= 0 && i0 <= 63);
if (i0 < 32)
DSRL(r0, r1, i0);
else
DSRL32(r0, r1, i0 - 32);
}
#endif
static void static void
_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) _andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{ {
@ -1110,7 +1169,7 @@ _movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
if (i0 == 0) if (i0 == 0)
OR(r0, _ZERO_REGNO, _ZERO_REGNO); OR(r0, _ZERO_REGNO, _ZERO_REGNO);
else if (can_sign_extend_short_p(i0)) else if (can_sign_extend_short_p(i0))
ADDIU(r0, _ZERO_REGNO, i0); addiu(r0, _ZERO_REGNO, i0);
else if (can_zero_extend_short_p(i0)) else if (can_zero_extend_short_p(i0))
ORI(r0, _ZERO_REGNO, i0); ORI(r0, _ZERO_REGNO, i0);
else { else {
@ -1118,20 +1177,20 @@ _movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
LUI(r0, i0 >> 16); LUI(r0, i0 >> 16);
else if (can_zero_extend_int_p(i0)) { else if (can_zero_extend_int_p(i0)) {
if (i0 & 0xffff0000) { if (i0 & 0xffff0000) {
ORI(r0, r0, i0 >> 16); ORI(r0, _ZERO_REGNO, i0 >> 16);
SLL(r0, r0, 16); lshi(r0, r0, 16);
} }
} }
# if __WORDSIZE == 64 # if __WORDSIZE == 64
else { else {
movi(r0, (jit_uword_t)i0 >> 32); movi(r0, (jit_uword_t)i0 >> 32);
if (i0 & 0xffff0000) { if (i0 & 0xffff0000) {
SLL(r0, r0, 16); lshi(r0, r0, 16);
ORI(r0, r0, i0 >> 16); ORI(r0, r0, i0 >> 16);
SLL(r0, r0, 16); lshi(r0, r0, 16);
} }
else else
SLL(r0, r0, 32); lshi(r0, r0, 32);
} }
# endif # endif
if (i0 & 0xffff) if (i0 & 0xffff)
@ -1151,9 +1210,9 @@ _movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
# else # else
LUI(r0, i0 >> 48); LUI(r0, i0 >> 48);
ORI(r0, r0, i0 >> 32); ORI(r0, r0, i0 >> 32);
SLL(r0, r0, 16); lshi(r0, r0, 16);
ORI(r0, r0, i0 >> 16); ORI(r0, r0, i0 >> 16);
SLL(r0, r0, 16); lshi(r0, r0, 16);
ORI(r0, r0, i0); ORI(r0, r0, i0);
# endif # endif
@ -1599,6 +1658,9 @@ _htonr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
else { else {
/* FIXME rewrite in a more sane way, but unlikely to be used /* FIXME rewrite in a more sane way, but unlikely to be used
* in near time... */ * in near time... */
# if __WORDSIZE == 64
# error htonr only implemented for 32 bit
# endif
rg0 = jit_get_reg(jit_class_gpr); rg0 = jit_get_reg(jit_class_gpr);
rg1 = jit_get_reg(jit_class_gpr); rg1 = jit_get_reg(jit_class_gpr);
LUI(rn(rg0), 0xff00); LUI(rn(rg0), 0xff00);
@ -1627,8 +1689,8 @@ _extr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
if (jit_mips2_p()) if (jit_mips2_p())
SEB(r0, r1); SEB(r0, r1);
else { else {
SLL(r0, r1, 24); lshi(r0, r1, __WORDSIZE - 8);
SRA(r0, r0, 24); rshi(r0, r0, __WORDSIZE - 8);
} }
} }
@ -1638,8 +1700,8 @@ _extr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
if (jit_mips2_p()) if (jit_mips2_p())
SEH(r0, r1); SEH(r0, r1);
else { else {
SLL(r0, r1, 16); lshi(r0, r1, __WORDSIZE - 16);
SRA(r0, r0, 16); rshi(r0, r0, __WORDSIZE - 16);
} }
} }
@ -1647,8 +1709,8 @@ _extr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
static void static void
_extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) _extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{ {
movr(r0, r1); lshi(r0, r1, 32);
INS(r0, _ZERO_REGNO, 32, 32); rshi_u(r0, r0, 32);
} }
# endif # endif
@ -2259,14 +2321,14 @@ _boaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr); t2 = jit_get_reg(jit_class_gpr);
SLT(rn(t0), r1, _ZERO_REGNO); /* t0 = r1 < 0 */ SLT(rn(t0), r1, _ZERO_REGNO); /* t0 = r1 < 0 */
ADDU(rn(t1), r0, r1); /* t1 = r0 + r1 */ addr(rn(t1), r0, r1); /* t1 = r0 + r1 */
SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */ SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */
SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */ SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */
MOVZ(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */ MOVZ(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */
w = _jit->pc.w; w = _jit->pc.w;
BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */ /* delay slot */
ADDU(r0, r0, r1); addr(r0, r0, r1);
jit_unget_reg(t2); jit_unget_reg(t2);
jit_unget_reg(t1); jit_unget_reg(t1);
jit_unget_reg(t0); jit_unget_reg(t0);
@ -2287,14 +2349,14 @@ _boaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr); t2 = jit_get_reg(jit_class_gpr);
SLTI(rn(t0), _ZERO_REGNO, i1); SLTI(rn(t0), _ZERO_REGNO, i1);
ADDIU(rn(t1), r0, i1); addiu(rn(t1), r0, i1);
SLT(rn(t2), r0, rn(t1)); SLT(rn(t2), r0, rn(t1));
SLT(rn(t1), rn(t1), r0); SLT(rn(t1), rn(t1), r0);
MOVZ(rn(t1), rn(t2), rn(t0)); MOVZ(rn(t1), rn(t2), rn(t0));
w = _jit->pc.w; w = _jit->pc.w;
BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */ /* delay slot */
ADDIU(r0, r0, i1); addiu(r0, r0, i1);
jit_unget_reg(t2); jit_unget_reg(t2);
jit_unget_reg(t1); jit_unget_reg(t1);
jit_unget_reg(t0); jit_unget_reg(t0);
@ -2317,7 +2379,7 @@ _boaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
t0 = jit_get_reg(jit_class_gpr); t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
ADDU(rn(t0), r0, r1); addr(rn(t0), r0, r1);
SLTU(rn(t1), rn(t0), r0); SLTU(rn(t1), rn(t0), r0);
w = _jit->pc.w; w = _jit->pc.w;
BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
@ -2338,7 +2400,7 @@ _boaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
if (can_sign_extend_short_p(i0)) { if (can_sign_extend_short_p(i0)) {
t0 = jit_get_reg(jit_class_gpr); t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
ADDIU(rn(t0), r0, i1); addiu(rn(t0), r0, i1);
SLTU(rn(t1), rn(t0), r0); SLTU(rn(t1), rn(t0), r0);
w = _jit->pc.w; w = _jit->pc.w;
BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
@ -2369,14 +2431,14 @@ _bxaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr); t2 = jit_get_reg(jit_class_gpr);
SLT(rn(t0), r1, _ZERO_REGNO); /* t0 = r1 < 0 */ SLT(rn(t0), r1, _ZERO_REGNO); /* t0 = r1 < 0 */
ADDU(rn(t1), r0, r1); /* t1 = r0 + r1 */ addr(rn(t1), r0, r1); /* t1 = r0 + r1 */
SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */ SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */
SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */ SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */
MOVZ(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */ MOVZ(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */
w = _jit->pc.w; w = _jit->pc.w;
BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */ /* delay slot */
ADDU(r0, r0, r1); addr(r0, r0, r1);
jit_unget_reg(t2); jit_unget_reg(t2);
jit_unget_reg(t1); jit_unget_reg(t1);
jit_unget_reg(t0); jit_unget_reg(t0);
@ -2397,14 +2459,14 @@ _bxaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr); t2 = jit_get_reg(jit_class_gpr);
SLTI(rn(t0), _ZERO_REGNO, i1); SLTI(rn(t0), _ZERO_REGNO, i1);
ADDIU(rn(t1), r0, i1); addiu(rn(t1), r0, i1);
SLT(rn(t2), r0, rn(t1)); SLT(rn(t2), r0, rn(t1));
SLT(rn(t1), rn(t1), r0); SLT(rn(t1), rn(t1), r0);
MOVZ(rn(t1), rn(t2), rn(t0)); MOVZ(rn(t1), rn(t2), rn(t0));
w = _jit->pc.w; w = _jit->pc.w;
BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */ /* delay slot */
ADDIU(r0, r0, i1); addiu(r0, r0, i1);
jit_unget_reg(t2); jit_unget_reg(t2);
jit_unget_reg(t1); jit_unget_reg(t1);
jit_unget_reg(t0); jit_unget_reg(t0);
@ -2427,7 +2489,7 @@ _bxaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
t0 = jit_get_reg(jit_class_gpr); t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
ADDU(rn(t0), r0, r1); addr(rn(t0), r0, r1);
SLTU(rn(t1), rn(t0), r0); SLTU(rn(t1), rn(t0), r0);
w = _jit->pc.w; w = _jit->pc.w;
BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
@ -2448,7 +2510,7 @@ _bxaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
if (can_sign_extend_short_p(i0)) { if (can_sign_extend_short_p(i0)) {
t0 = jit_get_reg(jit_class_gpr); t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
ADDIU(rn(t0), r0, i1); addiu(rn(t0), r0, i1);
SLTU(rn(t1), rn(t0), r0); SLTU(rn(t1), rn(t0), r0);
w = _jit->pc.w; w = _jit->pc.w;
BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
@ -2479,14 +2541,14 @@ _bosubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr); t2 = jit_get_reg(jit_class_gpr);
SLT(rn(t0), _ZERO_REGNO, r1); /* t0 = 0 < r1 */ SLT(rn(t0), _ZERO_REGNO, r1); /* t0 = 0 < r1 */
SUBU(rn(t1), r0, r1); /* t1 = r0 - r1 */ subr(rn(t1), r0, r1); /* t1 = r0 - r1 */
SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */ SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */
SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */ SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */
MOVZ(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */ MOVZ(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */
w = _jit->pc.w; w = _jit->pc.w;
BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */ /* delay slot */
SUBU(r0, r0, r1); subr(r0, r0, r1);
jit_unget_reg(t2); jit_unget_reg(t2);
jit_unget_reg(t1); jit_unget_reg(t1);
jit_unget_reg(t0); jit_unget_reg(t0);
@ -2507,14 +2569,14 @@ _bosubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr); t2 = jit_get_reg(jit_class_gpr);
SLTI(rn(t0), _ZERO_REGNO, i1); SLTI(rn(t0), _ZERO_REGNO, i1);
ADDIU(rn(t1), r0, -i1); addiu(rn(t1), r0, -i1);
SLT(rn(t2), rn(t1), r0); SLT(rn(t2), rn(t1), r0);
SLT(rn(t1), r0, rn(t1)); SLT(rn(t1), r0, rn(t1));
MOVZ(rn(t1), rn(t2), rn(t0)); MOVZ(rn(t1), rn(t2), rn(t0));
w = _jit->pc.w; w = _jit->pc.w;
BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */ /* delay slot */
ADDIU(r0, r0, -i1); addiu(r0, r0, -i1);
jit_unget_reg(t2); jit_unget_reg(t2);
jit_unget_reg(t1); jit_unget_reg(t1);
jit_unget_reg(t0); jit_unget_reg(t0);
@ -2537,7 +2599,7 @@ _bosubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
t0 = jit_get_reg(jit_class_gpr); t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
SUBU(rn(t0), r0, r1); subr(rn(t0), r0, r1);
SLTU(rn(t1), r0, rn(t0)); SLTU(rn(t1), r0, rn(t0));
w = _jit->pc.w; w = _jit->pc.w;
BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
@ -2558,7 +2620,7 @@ _bosubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) { if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) {
t0 = jit_get_reg(jit_class_gpr); t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
ADDIU(rn(t0), r0, -i1); addiu(rn(t0), r0, -i1);
SLTU(rn(t1), r0, rn(t0)); SLTU(rn(t1), r0, rn(t0));
w = _jit->pc.w; w = _jit->pc.w;
BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
@ -2589,14 +2651,14 @@ _bxsubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr); t2 = jit_get_reg(jit_class_gpr);
SLT(rn(t0), _ZERO_REGNO, r1); /* t0 = 0 < r1 */ SLT(rn(t0), _ZERO_REGNO, r1); /* t0 = 0 < r1 */
SUBU(rn(t1), r0, r1); /* t1 = r0 - r1 */ subr(rn(t1), r0, r1); /* t1 = r0 - r1 */
SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */ SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */
SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */ SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */
MOVZ(rn(t1), rn(t2), rn(t0)); /* if (t0 == 0) t1 = t2 */ MOVZ(rn(t1), rn(t2), rn(t0)); /* if (t0 == 0) t1 = t2 */
w = _jit->pc.w; w = _jit->pc.w;
BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */ /* delay slot */
SUBU(r0, r0, r1); subr(r0, r0, r1);
jit_unget_reg(t2); jit_unget_reg(t2);
jit_unget_reg(t1); jit_unget_reg(t1);
jit_unget_reg(t0); jit_unget_reg(t0);
@ -2617,14 +2679,14 @@ _bxsubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr); t2 = jit_get_reg(jit_class_gpr);
SLTI(rn(t0), _ZERO_REGNO, i1); SLTI(rn(t0), _ZERO_REGNO, i1);
ADDIU(rn(t1), r0, -i1); addiu(rn(t1), r0, -i1);
SLT(rn(t2), rn(t1), r0); SLT(rn(t2), rn(t1), r0);
SLT(rn(t1), r0, rn(t1)); SLT(rn(t1), r0, rn(t1));
MOVZ(rn(t1), rn(t2), rn(t0)); MOVZ(rn(t1), rn(t2), rn(t0));
w = _jit->pc.w; w = _jit->pc.w;
BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */ /* delay slot */
ADDIU(r0, r0, -i1); addiu(r0, r0, -i1);
jit_unget_reg(t2); jit_unget_reg(t2);
jit_unget_reg(t1); jit_unget_reg(t1);
jit_unget_reg(t0); jit_unget_reg(t0);
@ -2647,7 +2709,7 @@ _bxsubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
t0 = jit_get_reg(jit_class_gpr); t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
SUBU(rn(t0), r0, r1); subr(rn(t0), r0, r1);
SLTU(rn(t1), r0, rn(t0)); SLTU(rn(t1), r0, rn(t0));
w = _jit->pc.w; w = _jit->pc.w;
BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
@ -2668,7 +2730,7 @@ _bxsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) { if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) {
t0 = jit_get_reg(jit_class_gpr); t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr); t1 = jit_get_reg(jit_class_gpr);
ADDIU(rn(t0), r0, -i1); addiu(rn(t0), r0, -i1);
SLTU(rn(t1), r0, rn(t0)); SLTU(rn(t1), r0, rn(t0));
w = _jit->pc.w; w = _jit->pc.w;
BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
@ -2868,6 +2930,7 @@ _patch_abs(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
} u; } u;
u.w = instr; u.w = instr;
#if __WORDSIZE == 32
i.op = u.i[0]; i.op = u.i[0];
assert(i.hc.b == MIPS_LUI); assert(i.hc.b == MIPS_LUI);
i.is.b = label >> 16; i.is.b = label >> 16;
@ -2876,6 +2939,26 @@ _patch_abs(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
assert(i.hc.b == MIPS_ORI); assert(i.hc.b == MIPS_ORI);
i.is.b = label; i.is.b = label;
u.i[1] = i.op; u.i[1] = i.op;
#else
i.op = u.i[0];
assert(i.hc.b == MIPS_LUI);
i.is.b = label >> 48;
u.i[0] = i.op;
i.op = u.i[1];
assert(i.hc.b == MIPS_ORI);
i.is.b = label >> 32;
u.i[1] = i.op;
/* lshi */
i.op = u.i[3];
assert(i.hc.b == MIPS_ORI);
i.is.b = label >> 16;
u.i[3] = i.op;
/* lshi */
i.op = u.i[5];
assert(i.hc.b == MIPS_ORI);
i.is.b = label;
u.i[5] = i.op;
#endif
} }
static void static void

View file

@ -1,6 +1,6 @@
#if __WORDSIZE == 32 #if __WORDSIZE == 32
#if defined(_ABIN32) #if NEW_ABI
#define JIT_INSTR_MAX 44 #define JIT_INSTR_MAX 44
0, 0,
0, 0,
@ -348,11 +348,11 @@
12, 12,
0, 0,
0, 0,
#endif /* _ABIN32 */ #endif /* NEW_ABI */
#endif /* __WORDSIZE */ #endif /* __WORDSIZE */
#if __WORDSIZE == 32 #if __WORDSIZE == 32
#if !defined(_ABIN32) #if !NEW_ABI
#define JIT_INSTR_MAX 96 #define JIT_INSTR_MAX 96
0, 0,
0, 0,
@ -700,5 +700,355 @@
0, 0,
0, 0,
0, 0,
#endif /* _ABIN32 */ #endif /* NEW_ABI */
#endif /* __WORDSIZE */
#if __WORDSIZE == 64
#define JIT_INSTR_MAX 44
0,
0,
0,
0,
0,
0,
0,
44,
0,
4,
28,
12,
36,
28,
28,
4,
28,
12,
36,
28,
28,
8,
32,
12,
32,
12,
32,
8,
32,
8,
32,
12,
16,
12,
16,
8,
32,
8,
32,
4,
28,
4,
28,
4,
28,
4,
4,
4,
4,
4,
4,
4,
8,
4,
4,
4,
4,
8,
12,
8,
12,
12,
12,
8,
12,
8,
12,
4,
8,
4,
8,
8,
8,
4,
28,
8,
4,
8,
4,
4,
8,
4,
4,
12,
4,
12,
4,
12,
4,
12,
4,
12,
4,
12,
4,
12,
8,
4,
8,
4,
8,
4,
8,
4,
8,
4,
8,
4,
8,
4,
4,
12,
4,
12,
4,
12,
4,
12,
8,
4,
8,
4,
8,
4,
8,
4,
12,
12,
12,
12,
12,
16,
12,
16,
8,
36,
12,
12,
12,
12,
12,
16,
12,
16,
8,
32,
12,
12,
12,
12,
28,
28,
16,
20,
28,
28,
16,
20,
28,
28,
16,
20,
28,
28,
16,
20,
0,
8,
12,
32,
44,
0,
4,
16,
4,
16,
4,
16,
4,
16,
4,
4,
4,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
8,
8,
8,
4,
4,
12,
4,
12,
8,
4,
4,
12,
8,
4,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
0,
4,
16,
4,
16,
4,
16,
4,
16,
4,
4,
4,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
16,
28,
8,
8,
8,
4,
4,
12,
4,
12,
8,
4,
4,
12,
8,
4,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
12,
24,
0,
0,
0,
0,
0,
0,
0,
4,
12,
0,
0,
#endif /* __WORDSIZE */ #endif /* __WORDSIZE */

View file

@ -1074,7 +1074,7 @@ _emit_code(jit_state_t *_jit)
case_wr(st, _i); case_wr(st, _i);
#if __WORDSIZE == 64 #if __WORDSIZE == 64
case_rr(st, _l); case_rr(st, _l);
case_rw(st, _l); case_wr(st, _l);
#endif #endif
case_rrr(stx, _c); case_rrr(stx, _c);
case_wrr(stx, _c); case_wrr(stx, _c);

12
size.c
View file

@ -55,10 +55,12 @@ main(int argc, char *argv[])
fprintf(fp, "#if !defined(__ARM_PCS_VFP)\n"); fprintf(fp, "#if !defined(__ARM_PCS_VFP)\n");
# endif # endif
#elif defined(__mips__) #elif defined(__mips__)
# if defined(_ABIN32) # if __WORDSIZE == 32
fprintf(fp, "#if defined(_ABIN32)\n"); # if NEW_ABI
fprintf(fp, "#if NEW_ABI\n");
# else # else
fprintf(fp, "#if !defined(_ABIN32)\n"); fprintf(fp, "#if !NEW_ABI\n");
# endif
# endif # endif
#elif defined(__ppc__) #elif defined(__ppc__)
fprintf(fp, "#if defined(__ppc__)\n"); fprintf(fp, "#if defined(__ppc__)\n");
@ -71,7 +73,9 @@ main(int argc, char *argv[])
#if defined(__arm__) #if defined(__arm__)
fprintf(fp, "#undef /* __ARM_PCS_VFP */\n"); fprintf(fp, "#undef /* __ARM_PCS_VFP */\n");
#elif defined(__mips__) #elif defined(__mips__)
fprintf(fp, "#endif /* _ABIN32 */\n"); # if __WORDSIZE == 32
fprintf(fp, "#endif /* NEW_ABI */\n");
# endif
#elif defined(__ppc__) #elif defined(__ppc__)
fprintf(fp, "#endif /* __ppc__ */\n"); fprintf(fp, "#endif /* __ppc__ */\n");
#elif defined(__powerpc__) #elif defined(__powerpc__)