1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-01 04:10:18 +02:00
guile/lib/jit_mips-cpu.c
pcpa e304bc8bf9 Pass all but the (not yet implemented) qmul and qdiv tests in sparc
* check/float.tst: Add sparc to list of known NaN and +-Inf
	to integer conversion.

	* check/lightning.c: Define __sparc__ to preprocessor in
	the sparc backend.

	* include/lightning/jit_private.h: Correct wrong definition
	of emit_stxi_d, that has lived for a long time, but would
	cause problems whenever needing to spill/reload a float
	register.

	* include/lightning/jit_sparc.h: Can only use %g2,%g3,%g4
	for scratch variables, as other "global" registers are
	reserved for the system, e.g. libc.
	  Reorder float register naming to make it easier to
	access odd float registers, so that generating code for
	pusharg and getarg is easier for the IR.

	* lib/jit_mips-cpu.c, lib/jit_ppc-cpu.c: Update to match
	new code in jit_sparc-cpu.c. It must call jit_get_reg
	with jit_class_nospill if using the register to move
	an unconditional branch address to it, as the reload
	will not happen (actually could happen in the delay
	slot...)

	* lib/jit_sparc-cpu.c: Correct wrong macro definition for
	ldxr_s.
	  Properly implement div* and implement rem. Div* needs
	to use the y register, and rem* needs to be synthesized.
	  Correct b?sub* macro definitions.

	* lib/jit_sparc-fpu.c: Correct reversed float to/from double
	conversion.
	  Correct wrong jit_get_reg call asking for a gpr and then
	using the fpr with that number.
	  Correct wrong branch displacement computation for
	conditional branches.

	* lib/jit_sparc.c: Correct getarg_d and pushargi_d implementation.
	  Add rem* entries to the switch converting IR to machine code.

	* lib/lightning.c: Correct a problem detected when adding
	the jit_class_nospill flag to jit_get_reg, that was caused
	when having a branch to an "epilog" node, what would cause
	the code to think all registers in unknown state were live,
	while in truth, all registers in unknown state in the
	"just after return" point are actually dead.
2013-02-19 01:06:18 -03:00

3029 lines
81 KiB
C

/*
* Copyright (C) 2012 Free Software Foundation, Inc.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#if PROTO
typedef union {
struct { jit_uint32_t _:26; jit_uint32_t b : 6; } hc;
struct { jit_uint32_t _:21; jit_uint32_t b : 5; } rs;
struct { jit_uint32_t _:21; jit_uint32_t b : 5; } fm;
struct { jit_uint32_t _:16; jit_uint32_t b : 5; } rt;
struct { jit_uint32_t _:16; jit_uint32_t b : 5; } ft;
struct { jit_uint32_t _:11; jit_uint32_t b : 5; } rd;
struct { jit_uint32_t _:11; jit_uint32_t b : 5; } fs;
struct { jit_uint32_t _: 6; jit_uint32_t b : 5; } ic;
struct { jit_uint32_t _: 6; jit_uint32_t b : 5; } fd;
struct { jit_uint32_t _: 6; jit_uint32_t b : 10; } tr;
struct { jit_uint32_t _: 6; jit_uint32_t b : 20; } br;
struct { jit_uint32_t b : 6; } tc;
struct { jit_uint32_t b : 11; } cc;
struct { jit_uint32_t b : 16; } is;
struct { jit_uint32_t b : 26; } ii;
int op;
} jit_instr_t;
/* FIXME */
# define jit_mips2_p() 0
# define _ZERO_REGNO 0
# define _T0_REGNO 0x08
# define _T1_REGNO 0x09
# define _T2_REGNO 0x0a
# define _T3_REGNO 0x0b
# define _T4_REGNO 0x0c
# define _T5_REGNO 0x0d
# define _T6_REGNO 0x0e
# define _T7_REGNO 0x0f
# define _S0_REGNO 0x10
# define _S1_REGNO 0x11
# define _S2_REGNO 0x12
# define _S3_REGNO 0x13
# define _S4_REGNO 0x14
# define _S5_REGNO 0x15
# define _S6_REGNO 0x16
# define _S7_REGNO 0x17
# define _T8_REGNO 0x18
# define _T9_REGNO 0x19
# define _SP_REGNO 0x1d
# define _BP_REGNO 0x1e
# define _RA_REGNO 0x1f
# define _F16_REGNO 16
# define _F18_REGNO 18
# define _F20_REGNO 20
# define _F22_REGNO 22
# define _F24_REGNO 24
# define _F26_REGNO 26
# define _F28_REGNO 28
# define _F30_REGNO 30
# if __WORDSIZE == 32
# define stack_framesize 104
# define ldi(u, v) ldi_i(u, v)
# define ldxi(u, v, w) ldxi_i(u, v, w)
# define sti(u, v) sti_i(u, v)
# define stxi(u, v, w) stxi_i(u, v, w)
# else
# define stack_framesize 144
# define ldi(u, v) ldi_l(u, v)
# define ldxi(u, v, w) ldxi_l(u, v, w)
# define sti(u, v) sti_l(u, v)
# define stxi(u, v, w) stxi_l(u, v, w)
# endif
# define can_sign_extend_short_p(im) ((im) >= -32678 && (im) <= 32767)
# define can_zero_extend_short_p(im) ((im) >= 0 && (im) <= 65535)
# if __WORDSIZE == 32
# define can_sign_extend_int_p(im) 1
# define can_zero_extend_int_p(im) 1
# else
# define can_sign_extend_int_p(im) \
(((im) >= 0 && (im) <= 0x7fffffffL) || \
((im) < 0 && (im) >= -0x80000000L))
# define can_zero_extend_int_p(im) ((im) >= 0 && (im) <= 0xffffffff)
# endif
# define MIPS_SPECIAL 0x00
# define MIPS_REGIMM 0x01
# define MIPS_J 0x02
# define MIPS_SRL 0x02
# define MIPS_JAL 0x03
# define MIPS_SRA 0x03
# define MIPS_BEQ 0x04
# define MIPS_BNE 0x05
# define MIPS_BLEZ 0x06
# define MIPS_BGTZ 0x07
# define MIPS_ADDI 0x08
# define MIPS_ADDIU 0x09
# define MIPS_SLTI 0x0a
# define MIPS_SLTIU 0x0b
# define MIPS_ANDI 0x0c
# define MIPS_ORI 0x0d
# define MIPS_XORI 0x0e
# define MIPS_LUI 0x0f
# define MIPS_COP0 0x10
# define MIPS_COP1 0x11
# define MIPS_COP2 0x12
# define MIPS_COP1X 0x13
# define MIPS_BEQL 0x14
# define MIPS_BNEL 0x15
# define MIPS_BLEZL 0x16
# define MIPS_BGTZL 0x17
# define MIPS_DADDI 0x18
# define MIPS_DADDIU 0x19
# define MIPS_LDL 0x1a
# define MIPS_LDR 0x1b
# define MIPS_SPECIAL2 0x1c
# define MIPS_JALX 0x1d
# define MIPS_SPECIAL3 0x1f
# define MIPS_LB 0x20
# define MIPS_LH 0x21
# define MIPS_LWL 0x22
# define MIPS_LW 0x23
# define MIPS_LBU 0x24
# define MIPS_LHU 0x25
# define MIPS_LWR 0x26
# define MIPS_LWU 0x27
# define MIPS_SB 0x28
# define MIPS_SH 0x29
# define MIPS_SWL 0x2a
# define MIPS_SW 0x2b
# define MIPS_SWR 0x2e
# define MIPS_CACHE 0x2f
# define MIPS_LL 0x30
# define MIPS_LWC1 0x31
# define MIPS_LWC2 0x32
# define MIPS_PREF 0x33
# define MIPS_LLD 0x34
# define MIPS_LDC1 0x35
# define MIPS_LDC2 0x36
# define MIPS_LD 0x37
# define MIPS_SC 0x38
# define MIPS_SCD 0x3c
# define MIPS_SDC1 0x3d
# define MIPS_SDC2 0x3e
# define MIPS_SWC1 0x39
# define MIPS_SWC2 0x3a
# define MIPS_SD 0x3f
# define MIPS_MF 0x00
# define MIPS_DMF 0x01
# define MIPS_CF 0x02
# define MIPS_MFH 0x03
# define MIPS_MT 0x04
# define MIPS_DMT 0x05
# define MIPS_CT 0x06
# define MIPS_MTH 0x07
# define MIPS_BC 0x08
# define MIPS_WRPGPR 0x0e
# define MIPS_BGZAL 0x11
# define MIPS_MFMC0 0x11
# define MIPS_BCF 0x00
# define MIPS_BLTZ 0x00
# define MIPS_BCT 0x01
# define MIPS_BGEZ 0x01
# define MIPS_BCFL 0x02
# define MIPS_BLTZL 0x02
# define MIPS_BCTL 0x03
# define MIPS_BGEZL 0x03
# define MIPS_TGEI 0x08
# define MIPS_TGEIU 0x09
# define MIPS_TLTI 0x0a
# define MIPS_TLTIU 0x0b
# define MIPS_TEQI 0x0c
# define MIPS_TNEI 0x0e
# define MIPS_BLTZAL 0x10
# define MIPS_BGEZAL 0x11
# define MIPS_BLTZALL 0x12
# define MIPS_BGEZALL 0x13
# define MIPS_SYNCI 0x1f
# define MIPS_WSBH 0x02
# define MIPS_DBSH 0x02
# define MIPS_DSHD 0x05
# define MIPS_SEB 0x10
# define MIPS_SEH 0x18
# define MIPS_MADD 0x00
# define MIPS_SLL 0x00
# define MIPS_EXT 0x00
# define MIPS_DEXTM 0x01
# define MIPS_MADDU 0x01
# define MIPS_MOVFT 0x01
# define MIPS_TLBR 0x01
# define MIPS_MUL 0x02
# define MIPS_DEXTU 0x02
# define MIPS_TLBWI 0x02
# define MIPS_DEXT 0x03
# define MIPS_SLLV 0x04
# define MIPS_INS 0x04
# define MIPS_MSUB 0x04
# define MIPS_DINSM 0x05
# define MIPS_MSUBU 0x05
# define MIPS_SRLV 0x06
# define MIPS_DINSU 0x06
# define MIPS_TLBWR 0x06
# define MIPS_SRAV 0x07
# define MIPS_DINS 0x07
# define MIPS_JR 0x08
# define MIPS_TLBP 0x08
# define MIPS_JALR 0x09
# define MIPS_MOVZ 0x0a
# define MIPS_MOVN 0x0b
# define MIPS_SYSCALL 0x0c
# define MIPS_BREAK 0x0d
# define MIPS_PREFX 0x0f
# define MIPS_SYNC 0x0f
# define MIPS_MFHI 0x10
# define MIPS_MTHI 0x11
# define MIPS_MFLO 0x12
# define MIPS_MTLO 0x13
# define MIPS_DSLLV 0x14
# define MIPS_DSRLV 0x16
# define MIPS_DSRAV 0x17
# define MIPS_MULT 0x18
# define MIPS_ERET 0x18
# define MIPS_MULTU 0x19
# define MIPS_DIV 0x1a
# define MIPS_DIVU 0x1b
# define MIPS_DMULT 0x1c
# define MIPS_DMULTU 0x1d
# define MIPS_DDIV 0x1e
# define MIPS_DDIVU 0x1f
# define MIPS_DERET 0x1f
# define MIPS_ADD 0x20
# define MIPS_CLZ 0x20
# define MIPS_BSHFL 0x20
# define MIPS_ADDU 0x21
# define MIPS_CLO 0x21
# define MIPS_SUB 0x22
# define MIPS_SUBU 0x23
# define MIPS_AND 0x24
# define MIPS_DCLZ 0x24
# define MIPS_DBSHFL 0x24
# define MIPS_OR 0x25
# define MIPS_DCLO 0x25
# define MIPS_XOR 0x26
# define MIPS_NOR 0x27
# define MIPS_SLT 0x2a
# define MIPS_SLTU 0x2b
# define MIPS_DADD 0x2c
# define MIPS_DADDU 0x2d
# define MIPS_DSUB 0x2e
# define MIPS_DSUBU 0x2f
# define MIPS_TGE 0x30
# define MIPS_TGEU 0x31
# define MIPS_TLT 0x32
# define MIPS_TLTU 0x33
# define MIPS_TEQ 0x34
# define MIPS_TNE 0x36
# define MIPS_DSLL 0x38
# define MIPS_DSRL 0x3a
# define MIPS_DSRA 0x3b
# define MIPS_DSLL32 0x3c
# define MIPS_DSRL32 0x3e
# define MIPS_DSRA32 0x3f
# define MIPS_SDBPP 0x3f
# define ii(i) *_jit->pc.ui++ = i
static void
_hrrrit(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,
jit_int32_t, jit_int32_t);
# define hrrrit(hc,rs,rt,rd,im,tc) _hrrrit(_jit,hc,rs,rt,rd,im,tc)
# define hrrr_t(hc,rs,rt,rd,tc) hrrrit(hc,rs,rt,rd,0,tc)
# define rrr_t(rs,rt,rd,tc) hrrr_t(0,rs,rt,rd,tc)
# define hrri(hc,rs,rt,im) _hrri(_jit,hc,rs,rt,im)
static void _hrri(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
# define hi(hc,im) _hi(_jit,hc,im)
static void _hi(jit_state_t*,jit_int32_t,jit_int32_t);
# define NOP(i0) _nop(_jit, i0)
static void _nop(jit_state_t*,jit_int32_t);
# 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 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 ADDIU(rt,rs,im) hrri(MIPS_ADDIU,rs,rt,im)
# define SUBU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_SUBU)
# 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 DIV(rs, rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DIV)
# define DIVU(rs, rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DIVU)
# define SLLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SLLV)
# define SLL(rd,rt,sa) rrit(rt,rd,sa,MIPS_SLL)
# define SRAV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SRAV)
# define SRA(rd,rt,sa) rrit(rt,rd,sa,MIPS_SRA)
# define SRLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SRLV)
# 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 INS(rt,rs,pos,size) hrriit(MIPS_SPECIAL3,rs,rt,pos,pos+size-1,MIPS_DINS)
# else
# define ADDU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_DADDU)
# define ADDIU(rt,rs,im) hrri(MIPS_DADDIU,rs,rt,im)
# define SUBU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_DSUBU)
# 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) hrriit(MIPS_SPECIAL3,rs,rt,pos,pos+size-1,MIPS_INS)
# endif
# 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 MTHI(rs) rrr_t(rs,_ZERO_REGNO,_ZERO_REGNO,MIPS_MTHI)
# define MTLO(rs) rrr_t(rs,_ZERO_REGNO,_ZERO_REGNO,MIPS_MTLO)
# define AND(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_AND)
# define ANDI(rt,rs,im) hrri(MIPS_ANDI,rs,rt,im)
# define OR(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_OR)
# define ORI(rt,rs,im) hrri(MIPS_ORI,rs,rt,im)
# define XOR(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_XOR)
# define XORI(rt,rs,im) hrri(MIPS_XORI,rs,rt,im)
# define LB(rt,of,rb) hrri(MIPS_LB,rb,rt,of)
# define LBU(rt,of,rb) hrri(MIPS_LBU,rb,rt,of)
# define LH(rt,of,rb) hrri(MIPS_LH,rb,rt,of)
# define LHU(rt,of,rb) hrri(MIPS_LHU,rb,rt,of)
# define LW(rt,of,rb) hrri(MIPS_LW,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 SB(rt,of,rb) hrri(MIPS_SB,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 WSBH(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,MIPS_WSBH,MIPS_BSHFL)
# define SEB(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,MIPS_SEB,MIPS_BSHFL)
# define SEH(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,MIPS_SEH,MIPS_BSHFL)
# define SLT(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_SLT)
# define SLTU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_SLTU)
# define SLTI(rt,rs,im) hrri(MIPS_SLTI,rs,rt,im)
# define SLTIU(rt,rs,im) hrri(MIPS_SLTIU,rs,rt,im)
# define BLTZ(rs,im) hrri(MIPS_REGIMM,rs,MIPS_BLTZ,im)
# define BLEZ(rs,im) hrri(MIPS_BLEZ,rs,_ZERO_REGNO,im)
# define BEQ(rs,rt,im) hrri(MIPS_BEQ,rs,rt,im)
# define BGEZ(rs,im) hrri(MIPS_REGIMM,rs,MIPS_BGEZ,im)
# define BGTZ(rs,im) hrri(MIPS_BGTZ,rs,_ZERO_REGNO,im)
# define BNE(rs,rt,im) hrri(MIPS_BNE,rs,rt,im)
# define JALR(r0) hrrrit(MIPS_SPECIAL,r0,0,_RA_REGNO,0,MIPS_JALR)
# define JR(r0) hrrrit(MIPS_SPECIAL,r0,0,0,0,MIPS_JR)
# define J(i0) hi(MIPS_J, i0)
# define MOVZ(rd,rs,rt) hrrrit(0,rs,rt,rd,0,MIPS_MOVZ)
# define comr(r0,r1) xori(r0, r1, -1)
# define negr(r0,r1) SUBU(r0,_ZERO_REGNO,r1)
# define addr(rd,rs,rt) ADDU(rd,rs,rt)
# 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);
#define addcr(r0, r1, r2) _addcr(_jit, r0, r1, r2)
static void _addcr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
#define addci(r0, r1, i0) _addci(_jit, r0, r1, i0)
static void _addci(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
# define addxr(r0, r1, r2) _addxr(_jit, r0, r1, r2)
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)
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)
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)
static void _subcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define subci(r0, r1, i0) _subci(_jit, r0, r1, i0)
static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define subxr(r0, r1, r2) _subxr(_jit, r0, r1, r2)
static void _subxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define subxi(r0, r1, i0) _subxi(_jit, r0, r1, i0)
static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define mulr(r0,r1,r2) _mulr(_jit,r0,r1,r2)
static void _mulr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define muli(r0,r1,i0) _muli(_jit,r0,r1,i0)
static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define qmulr(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,1)
# define qmulr_u(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,0)
# define iqmulr(r0,r1,r2,r3,cc) _iqmulr(_jit,r0,r1,r2,r3,cc)
static void _iqmulr(jit_state_t*,jit_int32_t,jit_int32_t,
jit_int32_t,jit_int32_t,jit_bool_t);
# define qmuli(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,1)
# define qmuli_u(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,0)
# define iqmuli(r0,r1,r2,i0,cc) _iqmuli(_jit,r0,r1,r2,i0,cc)
static void _iqmuli(jit_state_t*,jit_int32_t,jit_int32_t,
jit_int32_t,jit_word_t,jit_bool_t);
# define divr(r0,r1,r2) _divr(_jit,r0,r1,r2)
static void _divr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define divi(r0,r1,i0) _divi(_jit,r0,r1,i0)
static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define divr_u(r0,r1,r2) _divr_u(_jit,r0,r1,r2)
static void _divr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0)
static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define qdivr(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,1)
# define qdivr_u(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,0)
# define iqdivr(r0,r1,r2,r3,cc) _iqdivr(_jit,r0,r1,r2,r3,cc)
static void _iqdivr(jit_state_t*,jit_int32_t,jit_int32_t,
jit_int32_t,jit_int32_t,jit_bool_t);
# define qdivi(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,1)
# define qdivi_u(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,0)
# define iqdivi(r0,r1,r2,i0,cc) _iqdivi(_jit,r0,r1,r2,i0,cc)
static void _iqdivi(jit_state_t*,jit_int32_t,jit_int32_t,
jit_int32_t,jit_word_t,jit_bool_t);
# define remr(r0,r1,r2) _remr(_jit,r0,r1,r2)
static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define remi(r0,r1,i0) _remi(_jit,r0,r1,i0)
static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2)
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)
static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define lshr(r0, r1, r2) SLLV(r0, r1, r2)
# define lshi(r0, r1, i0) SLL(r0, r1, i0)
# define rshr(r0, r1, r2) SRAV(r0, r1, r2)
# define rshi(r0, r1, i0) SRA(r0, r1, i0)
# define rshr_u(r0, r1, r2) SRLV(r0, r1, r2)
# define rshi_u(r0, r1, i0) SRL(r0, r1, i0)
# define andr(r0, r1, r2) AND(r0, r1, r2)
# 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);
# define orr(r0, r1, r2) OR(r0, r1, r2)
# define ori(r0, r1, i0) _ori(_jit, r0, r1, i0)
static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define xorr(r0, r1, r2) XOR(r0, r1, r2)
# define xori(r0, r1, i0) _xori(_jit, r0, r1, i0)
static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define movr(r0, r1) orr(r0, r1, _ZERO_REGNO)
# define movi(r0, i0) _movi(_jit, r0, i0)
static void _movi(jit_state_t*,jit_int32_t,jit_word_t);
# define movi_p(r0, i0) _movi_p(_jit, r0, i0)
static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t);
# define ldr_c(r0, r1) LB(r0, 0, r1)
# define ldi_c(r0, i0) _ldi_c(_jit, r0, i0)
static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t);
# define ldr_uc(r0, r1) LBU(r0, 0, r1)
# define ldi_uc(r0, i0) _ldi_uc(_jit, r0, i0)
static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t);
# define ldr_s(r0, r1) LH(r0, 0, r1)
# define ldi_s(r0, i0) _ldi_s(_jit, r0, i0)
static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t);
# define ldr_us(r0, r1) LHU(r0, 0, r1)
# define ldi_us(r0, i0) _ldi_us(_jit, r0, i0)
static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t);
# define ldr_i(r0, r1) LW(r0, 0, r1)
# define ldi_i(r0, i0) _ldi_i(_jit, r0, i0)
static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t);
# if __WORDSIZE == 64
# define ldr_ui(r0, r1) LWU(r0, 0, r1)
# define ldi_ui(r0, i0) _ldi_ui(_jit, r0, i0)
static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t);
# define ldr_l(r0, r1) LD(r0, 0, r1)
# define ldi_l(r0, i0) _ldi_l(_jit, r0, i0)
static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t);
# endif
# define ldxr_c(r0, r1, r2) _ldxr_c(_jit, r0, r1, r2)
static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define ldxi_c(r0, r1, i0) _ldxi_c(_jit, r0, r1, i0)
static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define ldxr_uc(r0, r1, r2) _ldxr_uc(_jit, r0, r1, r2)
static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define ldxi_uc(r0, r1, i0) _ldxi_uc(_jit, r0, r1, i0)
static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define ldxr_s(r0, r1, r2) _ldxr_s(_jit, r0, r1, r2)
static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define ldxi_s(r0, r1, i0) _ldxi_s(_jit, r0, r1, i0)
static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define ldxr_us(r0, r1, r2) _ldxr_us(_jit, r0, r1, r2)
static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define ldxi_us(r0, r1, i0) _ldxi_us(_jit, r0, r1, i0)
static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define ldxr_i(r0, r1, r2) _ldxr_i(_jit, r0, r1, r2)
static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define ldxi_i(r0, r1, i0) _ldxi_i(_jit, r0, r1, i0)
static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# if __WORDSIZE == 64
# define ldxr_ui(r0, r1, r2) _ldxr_ui(_jit, r0, r1, r2)
static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define ldxi_ui(r0, r1, i0) _ldxi_ui(_jit, r0, r1, i0)
static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define ldxr_l(r0, r1, r2) _ldxr_l(_jit, r0, r1, r2)
static void _ldxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define ldxi_l(r0, r1, i0) _ldxi_l(_jit, r0, r1, i0)
static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# endif
# define str_c(r0, r1) SB(r1, 0, r0)
# define sti_c(i0, r0) _sti_c(_jit, i0, r0)
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 sti_s(i0, r0) _sti_s(_jit, i0, r0)
static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t);
# define str_i(r0, r1) SW(r1, 0, r0)
# define sti_i(i0, r0) _sti_i(_jit, i0, r0)
static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t);
# if __WORDSIZE == 64
# define str_l(r0, r1) SD(r0, 0, r1)
# define sti_l(i0, r0) _sti_l(_jit, i0, r0)
static void _sti_l(jit_state_t*,jit_int32_t,jit_word_t);
# endif
# define stxr_c(r0, r1, r2) _stxr_c(_jit, r0, r1, r2)
static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define stxi_c(i0, r0, r1) _stxi_c(_jit, i0, r0, r1)
static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define stxr_s(r0, r1, r2) _stxr_s(_jit, r0, r1, r2)
static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define stxi_s(i0, r0, r1) _stxi_s(_jit, i0, r0, r1)
static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define stxr_i(r0, r1, r2) _stxr_i(_jit, r0, r1, r2)
static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define stxi_i(i0, r0, r1) _stxi_i(_jit, i0, r0, r1)
static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# if __WORDSIZE == 64
# define stxr_l(r0, r1, r2) _stxr_l(_jit, r0, r1, r2)
static void _stxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define stxi_l(i0, r0, r1) _stxi_l(_jit, i0, r0, r1)
static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# endif
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define htonr(r0,r1) _htonr(_jit,r0,r1)
static void _htonr(jit_state_t*,jit_int32_t,jit_int32_t);
# else
# define htonr(r0,r1) movr(r0,r1)
# endif
# define extr_c(r0,r1) _extr_c(_jit,r0,r1)
static void _extr_c(jit_state_t*,jit_int32_t,jit_int32_t);
# define extr_uc(r0,r1) ANDI(r0, r1, 0xff)
# define extr_s(r0,r1) _extr_s(_jit,r0,r1)
static void _extr_s(jit_state_t*,jit_int32_t,jit_int32_t);
# define extr_us(r0,r1) ANDI(r0, r1, 0xffff)
# if __WORDSIZE == 64
# define extr_i(r0,r1) SLL(r0, r0, 0)
# define extr_ui(r0,r1) _extr_ui(_jit,r0,r1)
static void _extr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
# endif
# define ltr(r0, r1, r2) SLT(r0, r1, r2)
# define lti(r0, r1, i0) _lti(_jit, r0, r1, i0)
static void _lti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define ltr_u(r0, r1, r2) SLTU(r0, r1, r2)
# define lti_u(r0, r1, i0) _lti_u(_jit, r0, r1, i0)
static void _lti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
#define ler(r0, r1, r2) _ler(_jit, r0, r1, r2)
static void _ler(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
#define lei(r0, r1, i0) _lei(_jit, r0, r1, i0)
static void _lei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
#define ler_u(r0, r1, r2) _ler_u(_jit, r0, r1, r2)
static void _ler_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
#define lei_u(r0, r1, i0) _lei_u(_jit, r0, r1, i0)
static void _lei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
#define eqr(r0, r1, r2) _eqr(_jit, r0, r1, r2)
static void _eqr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
#define eqi(r0, r1, i0) _eqi(_jit, r0, r1, i0)
static void _eqi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
#define ger(r0, r1, r2) _ger(_jit, r0, r1, r2)
static void _ger(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
#define gei(r0, r1, i0) _gei(_jit, r0, r1, i0)
static void _gei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
#define ger_u(r0, r1, i0) _ger_u(_jit, r0, r1, i0)
static void _ger_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
#define gei_u(r0, r1, i0) _gei_u(_jit, r0, r1, i0)
static void _gei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define gtr(r0, r1, r2) SLT(r0, r2, r1)
#define gti(r0, r1, i0) _gti(_jit, r0, r1, i0)
static void _gti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define gtr_u(r0, r1, r2) SLTU(r0, r2, r1)
# define gti_u(r0, r1, i0) _gti_u(_jit, r0, r1, i0)
static void _gti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
#define ner(r0, r1, r2) _ner(_jit, r0, r1, r2)
static void _ner(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
#define nei(r0, r1, i0) _nei(_jit, r0, r1, i0)
static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
#define bltr(i0, r0, r1) _bltr(_jit, i0, r0, r1)
static jit_word_t _bltr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
#define bltr_u(i0, r0, r1) _bltr_u(_jit, i0, r0, r1)
static jit_word_t _bltr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
#define blti(i0, r0, i1) _blti(_jit, i0, r0, i1)
static jit_word_t _blti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
#define blti_u(i0, r0, i1) _blti_u(_jit, i0, r0, i1)
static jit_word_t _blti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
#define bler(i0, r0, r1) _bler(_jit, i0, r0, r1)
static jit_word_t _bler(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
#define bler_u(i0, r0, r1) _bler_u(_jit, i0, r0, r1)
static jit_word_t _bler_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
#define blei(i0, r0, i1) _blei(_jit, i0, r0, i1)
static jit_word_t _blei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
#define blei_u(i0, r0, i1) _blei_u(_jit, i0, r0, i1)
static jit_word_t _blei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
#define beqr(i0, r0, r1) _beqr(_jit, i0, r0, r1)
static jit_word_t _beqr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
#define beqi(i0, r0, i1) _beqi(_jit, i0, r0, i1)
static jit_word_t _beqi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
#define bger(i0, r0, r1) _bger(_jit, i0, r0, r1)
static jit_word_t _bger(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
#define bger_u(i0, r0, r1) _bger_u(_jit, i0, r0, r1)
static jit_word_t _bger_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
#define bgei(i0, r0, i1) _bgei(_jit, i0, r0, i1)
static jit_word_t _bgei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
#define bgei_u(i0, r0, i1) _bgei_u(_jit, i0, r0, i1)
static jit_word_t _bgei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
#define bgtr(i0, r0, r1) _bgtr(_jit, i0, r0, r1)
static jit_word_t _bgtr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
#define bgtr_u(i0, r0, r1) _bgtr_u(_jit, i0, r0, r1)
static jit_word_t _bgtr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
#define bgti(i0, r0, i1) _bgti(_jit, i0, r0, i1)
static jit_word_t _bgti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
#define bgti_u(i0, r0, i1) _bgti_u(_jit, i0, r0, i1)
static jit_word_t _bgti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
#define bner(i0, r0, r1) _bner(_jit, i0, r0, r1)
static jit_word_t _bner(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
#define bnei(i0, r0, i1) _bnei(_jit, i0, r0, i1)
static jit_word_t _bnei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
# define jmpr(r0) _jmpr(_jit, r0)
static void _jmpr(jit_state_t*,jit_int32_t);
# define jmpi(i0) _jmpi(_jit, i0)
static jit_word_t _jmpi(jit_state_t*,jit_word_t);
# define boaddr(i0, r0, r1) _boaddr(_jit, i0, r0, r1)
static jit_word_t _boaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define boaddi(i0, r0, i1) _boaddi(_jit, i0, r0, i1)
static jit_word_t _boaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
# define boaddr_u(i0, r0, r1) _boaddr_u(_jit, i0, r0, r1)
static jit_word_t _boaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define boaddi_u(i0, r0, i1) _boaddi_u(_jit, i0, r0, i1)
static jit_word_t _boaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
# define bxaddr(i0, r0, r1) _bxaddr(_jit, i0, r0, r1)
static jit_word_t _bxaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define bxaddi(i0, r0, i1) _bxaddi(_jit, i0, r0, i1)
static jit_word_t _bxaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
# define bxaddr_u(i0, r0, r1) _bxaddr_u(_jit, i0, r0, r1)
static jit_word_t _bxaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define bxaddi_u(i0, r0, i1) _bxaddi_u(_jit, i0, r0, i1)
static jit_word_t _bxaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
# define bosubr(i0, r0, r1) _bosubr(_jit, i0, r0, r1)
static jit_word_t _bosubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define bosubi(i0, r0, i1) _bosubi(_jit, i0, r0, i1)
static jit_word_t _bosubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
# define bosubr_u(i0, r0, r1) _bosubr_u(_jit, i0, r0, r1)
static jit_word_t _bosubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define bosubi_u(i0, r0, i1) _bosubi_u(_jit, i0, r0, i1)
static jit_word_t _bosubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
# define bxsubr(i0, r0, r1) _bxsubr(_jit, i0, r0, r1)
static jit_word_t _bxsubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define bxsubi(i0, r0, i1) _bxsubi(_jit, i0, r0, i1)
static jit_word_t _bxsubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
# define bxsubr_u(i0, r0, r1) _bxsubr_u(_jit, i0, r0, r1)
static jit_word_t _bxsubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define bxsubi_u(i0, r0, i1) _bxsubi_u(_jit, i0, r0, i1)
static jit_word_t _bxsubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
# define bmsr(i0, r0, r1) _bmsr(_jit, i0, r0, r1)
static jit_word_t _bmsr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define bmsi(i0, r0, i1) _bmsi(_jit, i0, r0, i1)
static jit_word_t _bmsi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
# define bmcr(i0, r0, r1) _bmcr(_jit, i0, r0, r1)
static jit_word_t _bmcr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define bmci(i0, r0, i1) _bmci(_jit, i0, r0, i1)
static jit_word_t _bmci(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
# define callr(r0) _callr(_jit, r0)
static void _callr(jit_state_t*,jit_int32_t);
# define calli(i0) _calli(_jit, i0)
static void _calli(jit_state_t*,jit_word_t);
# define calli_p(i0) _calli_p(_jit, i0)
static jit_word_t _calli_p(jit_state_t*,jit_word_t);
# define prolog(node) _prolog(_jit, node)
static void _prolog(jit_state_t*,jit_node_t*);
# define epilog(node) _epilog(_jit, node)
static void _epilog(jit_state_t*,jit_node_t*);
#define patch_abs(instr, label) _patch_abs(_jit, instr, label)
static void _patch_abs(jit_state_t*,jit_word_t,jit_word_t);
#define patch_at(jump, label) _patch_at(_jit, jump, label)
static void _patch_at(jit_state_t*,jit_word_t,jit_word_t);
#endif
#if CODE
static void
_hrrrit(jit_state_t *_jit,jit_int32_t hc,
jit_int32_t rs, jit_int32_t rt, jit_int32_t rd,
jit_int32_t ic, jit_int32_t tc)
{
jit_instr_t i;
i.tc.b = tc;
i.ic.b = ic;
i.rd.b = rd;
i.rt.b = rt;
i.rs.b = rs;
i.hc.b = hc;
ii(i.op);
}
static void
_hrri(jit_state_t *_jit, jit_int32_t hc,
jit_int32_t rs, jit_int32_t rt, jit_int32_t im)
{
jit_instr_t i;
i.op = 0;
i.is.b = im;
i.rt.b = rt;
i.rs.b = rs;
i.hc.b = hc;
ii(i.op);
}
static void
_hi(jit_state_t *_jit, jit_int32_t hc, jit_int32_t im)
{
jit_instr_t i;
i.ii.b = im;
i.hc.b = hc;
ii(i.op);
}
static void
_nop(jit_state_t *_jit, jit_int32_t i0)
{
while (i0--)
ii(0);
}
static void
_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (i0 == 0)
movr(r0, r1);
else if (can_sign_extend_short_p(i0))
ADDIU(r0, r1, i0);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
addr(r0, r1, rn(reg));
jit_unget_reg(reg);
}
}
static void
_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_int32_t t0;
if (jit_carry == _NOREG)
jit_carry = jit_get_reg(jit_class_gpr);
if (r0 == r1) {
t0 = jit_get_reg(jit_class_gpr);
ADDU(rn(t0), r1, r2);
SLTU(rn(jit_carry), rn(t0), r1);
movr(r0, rn(t0));
jit_unget_reg(t0);
}
else {
ADDU(r0, r1, r2);
SLTU(rn(jit_carry), r0, r1);
}
}
static void
_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t t0;
if (jit_carry == _NOREG)
jit_carry = jit_get_reg(jit_class_gpr);
t0 = jit_get_reg(jit_class_gpr);
if (r0 == r1) {
if (can_sign_extend_short_p(i0))
ADDIU(rn(t0), r1, i0);
else {
movi(rn(t0), i0);
addr(rn(t0), r1, rn(t0));
}
SLTU(rn(jit_carry), rn(t0), r1);
movr(r0, rn(t0));
}
else {
if (can_sign_extend_short_p(i0))
ADDIU(r0, r1, i0);
else {
movi(rn(t0), i0);
addr(r0, r1, rn(t0));
}
SLTU(rn(jit_carry), r0, r1);
}
jit_unget_reg(t0);
}
static void
_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_int32_t t0;
assert(jit_carry != _NOREG);
t0 = jit_get_reg(jit_class_gpr);
movr(rn(t0), rn(jit_carry));
addcr(r0, r1, r2);
addcr(r0, r0, rn(t0));
jit_unget_reg(t0);
}
static void
_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t t0;
assert(jit_carry != _NOREG);
t0 = jit_get_reg(jit_class_gpr);
movr(rn(t0), rn(jit_carry));
addci(r0, r1, i0);
addcr(r0, r0, rn(t0));
jit_unget_reg(t0);
}
static void
_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (i0 == 0)
movr(r0, r1);
else if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000)
ADDIU(r0, r1, -i0);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
subr(r0, r1, rn(reg));
jit_unget_reg(reg);
}
}
static void
_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_int32_t t0;
if (jit_carry == _NOREG)
jit_carry = jit_get_reg(jit_class_gpr);
if (r0 == r1) {
t0 = jit_get_reg(jit_class_gpr);
SUBU(rn(t0), r1, r2);
SLTU(rn(jit_carry), r1, rn(t0));
movr(r0, rn(t0));
jit_unget_reg(t0);
}
else {
SUBU(r0, r1, r2);
SLTU(rn(jit_carry), r1, r0);
}
}
static void
_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t t0;
if (jit_carry == _NOREG)
jit_carry = jit_get_reg(jit_class_gpr);
t0 = jit_get_reg(jit_class_gpr);
if (r0 == r1) {
if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000)
ADDIU(rn(t0), r1, -i0);
else {
movi(rn(t0), i0);
subr(rn(t0), r1, rn(t0));
}
SLTU(rn(jit_carry), r1, rn(t0));
movr(r0, rn(t0));
}
else {
if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000)
ADDIU(r0, r1, -i0);
else {
movi(rn(t0), i0);
subr(r0, r1, rn(t0));
}
SLTU(rn(jit_carry), r1, r0);
}
jit_unget_reg(t0);
}
static void
_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_int32_t t0;
assert(jit_carry != _NOREG);
t0 = jit_get_reg(jit_class_gpr);
movr(rn(t0), rn(jit_carry));
subcr(r0, r1, r2);
subcr(r0, r0, rn(t0));
jit_unget_reg(t0);
}
static void
_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t t0;
assert(jit_carry != _NOREG);
t0 = jit_get_reg(jit_class_gpr);
movr(rn(t0), rn(jit_carry));
subci(r0, r1, i0);
subcr(r0, r0, rn(t0));
jit_unget_reg(t0);
}
static void
_mulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
MULTU(r1, r2);
MFLO(r0);
}
static void
_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
mulr(r0, r1, rn(reg));
jit_unget_reg(reg);
}
static void
_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)
{
if (sign)
MULT(r2, r3);
else
MULTU(r2, r3);
MFLO(r0);
MFHI(r1);
}
static void
_iqmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
jit_int32_t r2, jit_word_t i0, jit_bool_t sign)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
iqmulr(r0, r1, r2, rn(reg), sign);
jit_unget_reg(reg);
}
static void
_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
DIV(r1, r2);
MFLO(r0);
}
static void
_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
divr(r0, r1, rn(reg));
jit_unget_reg(reg);
}
static void
_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
DIVU(r1, r2);
MFLO(r0);
}
static void
_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
divr_u(r0, r1, rn(reg));
jit_unget_reg(reg);
}
static void
_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)
{
if (sign)
DIV(r2, r3);
else
DIVU(r2, r3);
MFLO(r0);
MFHI(r1);
}
static void
_iqdivi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
jit_int32_t r2, jit_word_t i0, jit_bool_t sign)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
iqdivr(r0, r1, r2, rn(reg), sign);
jit_unget_reg(reg);
}
static void
_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
DIV(r1, r2);
MFHI(r0);
}
static void
_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
remr(r0, r1, rn(reg));
jit_unget_reg(reg);
}
static void
_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
DIVU(r1, r2);
MFHI(r0);
}
static void
_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
remr_u(r0, r1, rn(reg));
jit_unget_reg(reg);
}
static void
_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_zero_extend_short_p(i0))
ANDI(r0, r1, i0);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
AND(r0, r1, rn(reg));
jit_unget_reg(reg);
}
}
static void
_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_zero_extend_short_p(i0))
ORI(r0, r1, i0);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
OR(r0, r1, rn(reg));
jit_unget_reg(reg);
}
}
static void
_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_zero_extend_short_p(i0))
XORI(r0, r1, i0);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
XOR(r0, r1, rn(reg));
jit_unget_reg(reg);
}
}
static void
_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{
if (i0 == 0)
OR(r0, _ZERO_REGNO, _ZERO_REGNO);
else if (can_sign_extend_short_p(i0))
ADDIU(r0, _ZERO_REGNO, i0);
else if (can_zero_extend_short_p(i0))
ORI(r0, _ZERO_REGNO, i0);
else {
if (can_sign_extend_int_p(i0))
LUI(r0, i0 >> 16);
else if (can_zero_extend_int_p(i0)) {
if (i0 & 0xffff0000) {
ORI(r0, r0, i0 >> 16);
SLL(r0, r0, 16);
}
}
# if __WORDSIZE == 64
else {
movi(r0, (jit_uword_t)i0 >> 32);
if (i0 & 0xffff0000) {
SLL(r0, r0, 16);
ORI(r0, r0, i0 >> 16);
SLL(r0, r0, 16);
}
else
SLL(r0, r0, 32);
}
# endif
if (i0 & 0xffff)
ORI(r0, r0, i0);
}
}
static jit_word_t
_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{
jit_word_t w;
w = _jit->pc.w;
# if __WORDSIZE == 32
LUI(r0, i0 >> 16);
ORI(r0, r0, i0);
# else
LUI(r0, i0 >> 48);
ORI(r0, r0, i0 >> 32);
SLL(r0, r0, 16);
ORI(r0, r0, i0 >> 16);
SLL(r0, r0, 16);
ORI(r0, r0, i0);
# endif
return (w);
}
static void
_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LB(r0, i0, _ZERO_REGNO);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ldr_c(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LBU(r0, i0, _ZERO_REGNO);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ldr_uc(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LH(r0, i0, _ZERO_REGNO);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ldr_s(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LHU(r0, i0, _ZERO_REGNO);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ldr_us(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LW(r0, i0, _ZERO_REGNO);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ldr_i(r0, rn(reg));
jit_unget_reg(reg);
}
}
#if __WORDSIZE == 64
static void
_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LWU(r0, i0, _ZERO_REGNO);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ldr_ui(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LD(r0, i0, _ZERO_REGNO);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ldr_l(r0, rn(reg));
jit_unget_reg(reg);
}
}
#endif
static void
_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
addr(rn(reg), r1, r2);
ldr_c(r0, rn(reg));
jit_unget_reg(reg);
}
static void
_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LB(r0, i0, r1);
else {
reg = jit_get_reg(jit_class_gpr);
addi(rn(reg), r1, i0);
ldr_c(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
addr(rn(reg), r1, r2);
ldr_uc(r0, rn(reg));
jit_unget_reg(reg);
}
static void
_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LBU(r0, i0, r1);
else {
reg = jit_get_reg(jit_class_gpr);
addi(rn(reg), r1, i0);
ldr_uc(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
addr(rn(reg), r1, r2);
ldr_s(r0, rn(reg));
jit_unget_reg(reg);
}
static void
_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LH(r0, i0, r1);
else {
reg = jit_get_reg(jit_class_gpr);
addi(rn(reg), r1, i0);
ldr_s(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
addr(rn(reg), r1, r2);
ldr_us(r0, rn(reg));
jit_unget_reg(reg);
}
static void
_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LHU(r0, i0, r1);
else {
reg = jit_get_reg(jit_class_gpr);
addi(rn(reg), r1, i0);
ldr_us(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
addr(rn(reg), r1, r2);
ldr_i(r0, rn(reg));
jit_unget_reg(reg);
}
static void
_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LW(r0, i0, r1);
else {
reg = jit_get_reg(jit_class_gpr);
addi(rn(reg), r1, i0);
ldr_i(r0, rn(reg));
jit_unget_reg(reg);
}
}
#if __WORDSIZE == 64
static void
_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
addr(rn(reg), r1, r2);
ldr_ui(r0, rn(reg));
jit_unget_reg(reg);
}
static void
_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LWU(r0, i0, r1);
else {
reg = jit_get_reg(jit_class_gpr);
addi(rn(reg), r1, i0);
ldr_ui(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
_ldxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
addr(rn(reg), r1, r2);
ldr_l(r0, rn(reg));
jit_unget_reg(reg);
}
static void
_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
LD(r0, i0, r1);
else {
reg = jit_get_reg(jit_class_gpr);
addi(rn(reg), r1, i0);
ldr_l(r0, rn(reg));
jit_unget_reg(reg);
}
}
#endif
static void
_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
SB(r0, i0, _ZERO_REGNO);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
str_c(rn(reg), r0);
jit_unget_reg(reg);
}
}
static void
_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
SH(r0, i0, _ZERO_REGNO);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
str_s(rn(reg), r0);
jit_unget_reg(reg);
}
}
static void
_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
SW(r0, i0, _ZERO_REGNO);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
str_i(rn(reg), r0);
jit_unget_reg(reg);
}
}
#if __WORDSIZE == 64
static void
_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
SD(r0, i0, _ZERO_REGNO);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
str_l(rn(reg), r0);
jit_unget_reg(reg);
}
}
#endif
static void
_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
addr(rn(reg), r0, r1);
str_c(rn(reg), r2);
jit_unget_reg(reg);
}
static void
_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
SB(r1, i0, r0);
else {
reg = jit_get_reg(jit_class_gpr);
addi(rn(reg), r0, i0);
str_c(rn(reg), r1);
jit_unget_reg(reg);
}
}
static void
_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
addr(rn(reg), r0, r1);
str_s(rn(reg), r2);
jit_unget_reg(reg);
}
static void
_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
SH(r1, i0, r0);
else {
reg = jit_get_reg(jit_class_gpr);
addi(rn(reg), r0, i0);
str_s(rn(reg), r1);
jit_unget_reg(reg);
}
}
static void
_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
addr(rn(reg), r0, r1);
str_i(rn(reg), r2);
jit_unget_reg(reg);
}
static void
_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
SW(r1, i0, r0);
else {
reg = jit_get_reg(jit_class_gpr);
addi(rn(reg), r0, i0);
str_i(rn(reg), r1);
jit_unget_reg(reg);
}
}
#if __WORDSIZE == 64
static void
_stxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
addr(rn(reg), r0, r1);
str_l(rn(reg), r2);
jit_unget_reg(reg);
}
static void
_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
SD(r1, i0, r0);
else {
reg = jit_get_reg(jit_class_gpr);
addi(rn(reg), r0, i0);
str_l(rn(reg), r1);
jit_unget_reg(reg);
}
}
#endif
# if __BYTE_ORDER == __LITTLE_ENDIAN
static void
_htonr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t rg0;
jit_int32_t rg1;
if (jit_mips2_p()) {
WSBH(r0, r1);
ROTR(r0, r0, 16);
}
else {
/* FIXME rewrite in a more sane way, but unlikely to be used
* in near time... */
rg0 = jit_get_reg(jit_class_gpr);
rg1 = jit_get_reg(jit_class_gpr);
LUI(rn(rg0), 0xff00);
ORI(rn(rg0), rn(rg0), 0xff00);
AND(rn(rg1), r1, rn(rg0));
SRL(rn(rg0), rn(rg0), 8);
AND(rn(rg0), r1, rn(rg0));
SRL(rn(rg1), rn(rg1), 8);
SLL(rn(rg0), rn(rg0), 8);
OR(r0, rn(rg0), rn(rg1));
ANDI(rn(rg1), r0, 0xffff);
LUI(rn(rg0), 0xffff);
AND(rn(rg0), r0, rn(rg0));
SLL(rn(rg1), rn(rg1), 16);
SRL(rn(rg0), rn(rg0), 16);
OR(r0, rn(rg0), rn(rg1));
jit_unget_reg(rg0);
jit_unget_reg(rg1);
}
}
# endif
static void
_extr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (jit_mips2_p())
SEB(r0, r1);
else {
SLL(r0, r1, 24);
SRA(r0, r0, 24);
}
}
static void
_extr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (jit_mips2_p())
SEH(r0, r1);
else {
SLL(r0, r1, 16);
SRA(r0, r0, 16);
}
}
# if __WORDSIZE == 64
static void
_extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
movr(r0, r1);
INS(r0, _RZERO_REGNO, 32, 32);
}
# endif
static void
_lti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
SLTI(r0, r1, i0);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ltr(r0, r1, rn(reg));
jit_unget_reg(reg);
}
}
static void
_lti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_short_p(i0))
SLTIU(r0, r1, i0);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ltr_u(r0, r1, rn(reg));
jit_unget_reg(reg);
}
}
static void
_ler(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
SLT(r0, r2, r1);
XORI(r0, r0, 1);
}
static void
_lei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (i0 == 0) {
SLT(r0, _ZERO_REGNO, r1);
XORI(r0, r0, 1);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ler(r0, r1, rn(reg));
jit_unget_reg(reg);
}
}
static void
_ler_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
SLTU(r0, r2, r1);
XORI(r0, r0, 1);
}
static void
_lei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (i0 == 0) {
SLTU(r0, _ZERO_REGNO, r1);
XORI(r0, r0, 1);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ler_u(r0, r1, rn(reg));
jit_unget_reg(reg);
}
}
static void
_eqr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
subr(r0, r1, r2);
SLTU(r0, _ZERO_REGNO, r0);
XORI(r0, r0, 1);
}
static void
_eqi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
if (i0) {
subi(r0, r1, i0);
SLTU(r0, _ZERO_REGNO, r0);
}
else
SLTU(r0, _ZERO_REGNO, r1);
XORI(r0, r0, 1);
}
static void
_ger(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
SLT(r0, r1, r2);
XORI(r0, r0, 1);
}
static void
_gei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ger(r0, r1, rn(reg));
jit_unget_reg(reg);
}
static void
_ger_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
SLTU(r0, r1, r2);
XORI(r0, r0, 1);
}
static void
_gei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
ger_u(r0, r1, rn(reg));
jit_unget_reg(reg);
}
static void
_gti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (i0 == 0)
SLT(r0, _ZERO_REGNO, r1);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
SLT(r0, rn(reg), r1);
jit_unget_reg(reg);
}
}
static void
_gti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (i0 == 0)
SLTU(r0, _ZERO_REGNO, r1);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
SLTU(r0, rn(reg), r1);
jit_unget_reg(reg);
}
}
static void
_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
subr(r0, r1, r2);
SLTU(r0, _ZERO_REGNO, r0);
}
static void
_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
if (i0) {
subi(r0, r1, i0);
SLTU(r0, _ZERO_REGNO, r0);
}
else
SLTU(r0, _ZERO_REGNO, r1);
}
static jit_word_t
_bltr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
SLT(rn(reg), r0, r1);
w = _jit->pc.w;
BNE(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
jit_unget_reg(reg);
return (w);
}
static jit_word_t
_bltr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
SLTU(rn(reg), r0, r1);
w = _jit->pc.w;
BNE(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
jit_unget_reg(reg);
return (w);
}
static jit_word_t
_blti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_word_t d;
jit_int32_t reg;
jit_bool_t zero_p;
if (!(zero_p = i1 == 0))
reg = jit_get_reg(jit_class_gpr);
if (can_sign_extend_short_p(i1)) {
if (!zero_p)
SLTI(rn(reg), r0, i1);
w = _jit->pc.w;
d = ((i0 - w) >> 2) - 1;
if (!zero_p)
BNE(rn(reg), _ZERO_REGNO, d);
else
BLTZ(r0, d);
NOP(1);
}
else {
movi(rn(reg), i1);
w = bltr(i0, r0, rn(reg));
}
if (!zero_p)
jit_unget_reg(reg);
return (w);
}
static jit_word_t
_blti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
if (can_sign_extend_short_p(i1)) {
SLTIU(rn(reg), r0, i1);
w = _jit->pc.w;
BNE(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
}
else {
movi(rn(reg), i1);
w = bltr_u(i0, r0, rn(reg));
}
jit_unget_reg(reg);
return (w);
}
static jit_word_t
_bler(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
SLT(rn(reg), r1, r0);
w = _jit->pc.w;
BEQ(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
jit_unget_reg(reg);
return (w);
}
static jit_word_t
_bler_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
SLTU(rn(reg), r1, r0);
w = _jit->pc.w;
BEQ(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
jit_unget_reg(reg);
return (w);
}
static jit_word_t
_blei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t reg;
if (i1 == 0) {
w = _jit->pc.w;
BLEZ(r0, ((i0 - w) >> 2) - 1);
NOP(1);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i1);
w = bler(i0, r0, rn(reg));
jit_unget_reg(reg);
}
return (w);
}
static jit_word_t
_blei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t reg;
if (i1 == 0) {
w = _jit->pc.w;
BEQ(r0, _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i1);
w = bler_u(i0, r0, rn(reg));
jit_unget_reg(reg);
}
return (w);
}
static jit_word_t
_beqr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
w = _jit->pc.w;
BEQ(r0, r1, ((i0 - w) >> 2) - 1);
NOP(1);
return (w);
}
static jit_word_t
_beqi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t reg;
if (i1 == 0) {
w = _jit->pc.w;
BEQ(r0, _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i1);
w = beqr(i0, r0, rn(reg));
jit_unget_reg(reg);
}
return (w);
}
static jit_word_t
_bger(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
SLT(rn(reg), r0, r1);
w = _jit->pc.w;
BEQ(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
jit_unget_reg(reg);
return (w);
}
static jit_word_t
_bger_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
SLTU(rn(reg), r0, r1);
w = _jit->pc.w;
BEQ(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
jit_unget_reg(reg);
return (w);
}
static jit_word_t
_bgei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_word_t d;
jit_int32_t reg;
jit_bool_t zero_p;
if (!(zero_p = i1 == 0))
reg = jit_get_reg(jit_class_gpr);
if (can_sign_extend_short_p(i1)) {
if (!zero_p)
SLTI(rn(reg), r0, i1);
w = _jit->pc.w;
d = ((i0 - w) >> 2) - 1;
if (!zero_p)
BEQ(rn(reg), _ZERO_REGNO, d);
else
BGEZ(r0, d);
NOP(1);
}
else {
movi(rn(reg), i1);
w = bger(i0, r0, rn(reg));
}
if (!zero_p)
jit_unget_reg(reg);
return (w);
}
static jit_word_t
_bgei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
if (can_sign_extend_short_p(i1)) {
SLTIU(rn(reg), r0, i1);
w = _jit->pc.w;
BEQ(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
}
else {
movi(rn(reg), i1);
w = bger_u(i0, r0, rn(reg));
}
jit_unget_reg(reg);
return (w);
}
static jit_word_t
_bgtr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
SLT(rn(reg), r1, r0);
w = _jit->pc.w;
BNE(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
jit_unget_reg(reg);
return (w);
}
static jit_word_t
_bgtr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
SLTU(rn(reg), r1, r0);
w = _jit->pc.w;
BNE(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
jit_unget_reg(reg);
return (w);
}
static jit_word_t
_bgti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t reg;
if (i1 == 0) {
w = _jit->pc.w;
BGTZ(r0, ((i0 - w) >> 2) - 1);
NOP(1);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i1);
w = bgtr(i0, r0, rn(reg));
jit_unget_reg(reg);
}
return (w);
}
static jit_word_t
_bgti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t reg;
if (i1 == 0) {
w = _jit->pc.w;
BNE(r0, _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i1);
w = bgtr_u(i0, r0, rn(reg));
jit_unget_reg(reg);
}
return (w);
}
static jit_word_t
_bner(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
w = _jit->pc.w;
BNE(r0, r1, ((i0 - w) >> 2) - 1);
NOP(1);
return (w);
}
static jit_word_t
_bnei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t reg;
if (i1 == 0) {
w = _jit->pc.w;
BNE(r0, _ZERO_REGNO, ((i0 - w) >> 2) - 1);
NOP(1);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i1);
w = bner(i0, r0, rn(reg));
jit_unget_reg(reg);
}
return (w);
}
static void
_jmpr(jit_state_t *_jit, jit_int32_t r0)
{
JR(r0);
NOP(1);
}
static jit_word_t
_jmpi(jit_state_t *_jit, jit_word_t i0)
{
jit_word_t w;
jit_int32_t reg;
w = _jit->pc.w;
if (((w + sizeof(jit_int32_t)) & 0xf0000000) == (i0 & 0xf0000000)) {
J((i0 & ~0xf0000000) >> 2);
NOP(1);
}
else {
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
movi_p(rn(reg), i0);
jmpr(rn(reg));
jit_unget_reg(reg);
}
return (w);
}
static jit_word_t
_boaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
jit_int32_t t2;
/* t1 = r0 + r1; overflow = r1 < 0 ? r0 < t1 : t1 < r0 */
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr);
SLT(rn(t0), r1, _ZERO_REGNO); /* t0 = r1 < 0 */
ADDU(rn(t1), r0, r1); /* t1 = r0 + r1 */
SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */
SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */
MOVZ(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */
w = _jit->pc.w;
BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */
ADDU(r0, r0, r1);
jit_unget_reg(t2);
jit_unget_reg(t1);
jit_unget_reg(t0);
return (w);
}
static jit_word_t
_boaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
jit_int32_t t2;
if (can_sign_extend_short_p(i1)) {
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr);
SLTI(rn(t0), _ZERO_REGNO, i1);
ADDIU(rn(t1), r0, i1);
SLT(rn(t2), r0, rn(t1));
SLT(rn(t1), rn(t1), r0);
MOVZ(rn(t1), rn(t2), rn(t0));
w = _jit->pc.w;
BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */
ADDIU(r0, r0, i1);
jit_unget_reg(t2);
jit_unget_reg(t1);
jit_unget_reg(t0);
}
else {
t0 = jit_get_reg(jit_class_gpr);
movi(rn(t0), i1);
w = boaddr(i0, r0, rn(t0));
jit_unget_reg(t0);
}
return (w);
}
static jit_word_t
_boaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
ADDU(rn(t0), r0, r1);
SLTU(rn(t1), rn(t0), r0);
w = _jit->pc.w;
BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
/* delay slot */
movr(r0, rn(t0));
jit_unget_reg(t1);
jit_unget_reg(t0);
return (w);
}
static jit_word_t
_boaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
if (can_sign_extend_short_p(i0)) {
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
ADDIU(rn(t0), r0, i1);
SLTU(rn(t1), rn(t0), r0);
w = _jit->pc.w;
BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
/* delay slot */
movr(r0, rn(t0));
jit_unget_reg(t1);
jit_unget_reg(t0);
}
else {
t0 = jit_get_reg(jit_class_gpr);
movi(rn(t0), i1);
w = boaddr_u(i0, r0, rn(t0));
jit_unget_reg(t0);
}
return (w);
}
static jit_word_t
_bxaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
jit_int32_t t2;
/* t1 = r0 + r1; overflow = r1 < 0 ? r0 < t1 : t1 < r0 */
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr);
SLT(rn(t0), r1, _ZERO_REGNO); /* t0 = r1 < 0 */
ADDU(rn(t1), r0, r1); /* t1 = r0 + r1 */
SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */
SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */
MOVZ(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */
w = _jit->pc.w;
BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */
ADDU(r0, r0, r1);
jit_unget_reg(t2);
jit_unget_reg(t1);
jit_unget_reg(t0);
return (w);
}
static jit_word_t
_bxaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
jit_int32_t t2;
if (can_sign_extend_short_p(i1)) {
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr);
SLTI(rn(t0), _ZERO_REGNO, i1);
ADDIU(rn(t1), r0, i1);
SLT(rn(t2), r0, rn(t1));
SLT(rn(t1), rn(t1), r0);
MOVZ(rn(t1), rn(t2), rn(t0));
w = _jit->pc.w;
BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */
ADDIU(r0, r0, i1);
jit_unget_reg(t2);
jit_unget_reg(t1);
jit_unget_reg(t0);
}
else {
t0 = jit_get_reg(jit_class_gpr);
movi(rn(t0), i1);
w = bxaddr(i0, r0, rn(t0));
jit_unget_reg(t0);
}
return (w);
}
static jit_word_t
_bxaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
ADDU(rn(t0), r0, r1);
SLTU(rn(t1), rn(t0), r0);
w = _jit->pc.w;
BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
/* delay slot */
movr(r0, rn(t0));
jit_unget_reg(t1);
jit_unget_reg(t0);
return (w);
}
static jit_word_t
_bxaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
if (can_sign_extend_short_p(i0)) {
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
ADDIU(rn(t0), r0, i1);
SLTU(rn(t1), rn(t0), r0);
w = _jit->pc.w;
BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
/* delay slot */
movr(r0, rn(t0));
jit_unget_reg(t1);
jit_unget_reg(t0);
}
else {
t0 = jit_get_reg(jit_class_gpr);
movi(rn(t0), i1);
w = bxaddr_u(i0, r0, rn(t0));
jit_unget_reg(t0);
}
return (w);
}
static jit_word_t
_bosubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
jit_int32_t t2;
/* t1 = r0 - r1; overflow = 0 < r1 ? r0 < t1 : t1 < r0 */
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr);
SLT(rn(t0), _ZERO_REGNO, r1); /* t0 = 0 < r1 */
SUBU(rn(t1), r0, r1); /* t1 = r0 - r1 */
SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */
SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */
MOVZ(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */
w = _jit->pc.w;
BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */
SUBU(r0, r0, r1);
jit_unget_reg(t2);
jit_unget_reg(t1);
jit_unget_reg(t0);
return (w);
}
static jit_word_t
_bosubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
jit_int32_t t2;
if (can_sign_extend_short_p(i1) && (i1 & 0xffff) != 0x8000) {
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr);
SLTI(rn(t0), _ZERO_REGNO, i1);
ADDIU(rn(t1), r0, -i1);
SLT(rn(t2), rn(t1), r0);
SLT(rn(t1), r0, rn(t1));
MOVZ(rn(t1), rn(t2), rn(t0));
w = _jit->pc.w;
BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */
ADDIU(r0, r0, -i1);
jit_unget_reg(t2);
jit_unget_reg(t1);
jit_unget_reg(t0);
}
else {
t0 = jit_get_reg(jit_class_gpr);
movi(rn(t0), i1);
w = bosubr(i0, r0, rn(t0));
jit_unget_reg(t0);
}
return (w);
}
static jit_word_t
_bosubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
SUBU(rn(t0), r0, r1);
SLTU(rn(t1), r0, rn(t0));
w = _jit->pc.w;
BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
/* delay slot */
movr(r0, rn(t0));
jit_unget_reg(t1);
jit_unget_reg(t0);
return (w);
}
static jit_word_t
_bosubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) {
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
ADDIU(rn(t0), r0, -i1);
SLTU(rn(t1), r0, rn(t0));
w = _jit->pc.w;
BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
/* delay slot */
movr(r0, rn(t0));
jit_unget_reg(t1);
jit_unget_reg(t0);
}
else {
t0 = jit_get_reg(jit_class_gpr);
movi(rn(t0), i1);
w = bosubr_u(i0, r0, rn(t0));
jit_unget_reg(t0);
}
return (w);
}
static jit_word_t
_bxsubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
jit_int32_t t2;
/* t1 = r0 - r1; overflow = 0 < r1 ? r0 < t1 : t1 < r0 */
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr);
SLT(rn(t0), _ZERO_REGNO, r1); /* t0 = 0 < r1 */
SUBU(rn(t1), r0, r1); /* t1 = r0 - r1 */
SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */
SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */
MOVZ(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */
w = _jit->pc.w;
BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */
SUBU(r0, r0, r1);
jit_unget_reg(t2);
jit_unget_reg(t1);
jit_unget_reg(t0);
return (w);
}
static jit_word_t
_bxsubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
jit_int32_t t2;
if (can_sign_extend_short_p(i1) && (i1 & 0xffff) != 0x8000) {
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr);
SLTI(rn(t0), _ZERO_REGNO, i1);
ADDIU(rn(t1), r0, -i1);
SLT(rn(t2), rn(t1), r0);
SLT(rn(t1), r0, rn(t1));
MOVZ(rn(t1), rn(t2), rn(t0));
w = _jit->pc.w;
BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1);
/* delay slot */
ADDIU(r0, r0, -i1);
jit_unget_reg(t2);
jit_unget_reg(t1);
jit_unget_reg(t0);
}
else {
t0 = jit_get_reg(jit_class_gpr);
movi(rn(t0), i1);
w = bxsubr(i0, r0, rn(t0));
jit_unget_reg(t0);
}
return (w);
}
static jit_word_t
_bxsubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
SUBU(rn(t0), r0, r1);
SLTU(rn(t1), r0, rn(t0));
w = _jit->pc.w;
BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
/* delay slot */
movr(r0, rn(t0));
jit_unget_reg(t1);
jit_unget_reg(t0);
return (w);
}
static jit_word_t
_bxsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t t0;
jit_int32_t t1;
if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) {
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
ADDIU(rn(t0), r0, -i1);
SLTU(rn(t1), r0, rn(t0));
w = _jit->pc.w;
BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1);
/* delay slot */
movr(r0, rn(t0));
jit_unget_reg(t1);
jit_unget_reg(t0);
}
else {
t0 = jit_get_reg(jit_class_gpr);
movi(rn(t0), i1);
w = bxsubr_u(i0, r0, rn(t0));
jit_unget_reg(t0);
}
return (w);
}
static jit_word_t
_bmsr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t t0;
t0 = jit_get_reg(jit_class_gpr);
AND(rn(r0), r0, r1);
w = _jit->pc.w;
BNE(_ZERO_REGNO, rn(t0), ((i0 - w) >> 2) - 1);
NOP(1);
jit_unget_reg(t0);
return (w);
}
static jit_word_t
_bmsi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t t0;
t0 = jit_get_reg(jit_class_gpr);
if (can_zero_extend_short_p(i1)) {
ANDI(rn(t0), r0, i1);
w = _jit->pc.w;
BNE(_ZERO_REGNO, rn(t0), ((i0 - w) >> 2) - 1);
NOP(1);
}
else {
movi(rn(t0), i1);
w = bmsr(i0, r0, rn(t0));
}
jit_unget_reg(t0);
return (w);
}
static jit_word_t
_bmcr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t w;
jit_int32_t t0;
t0 = jit_get_reg(jit_class_gpr);
AND(rn(t0), r0, r1);
w = _jit->pc.w;
BEQ(_ZERO_REGNO, rn(t0), ((i0 - w) >> 2) - 1);
NOP(1);
jit_unget_reg(t0);
return (w);
}
static jit_word_t
_bmci(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
{
jit_word_t w;
jit_int32_t t0;
t0 = jit_get_reg(jit_class_gpr);
if (can_zero_extend_short_p(i1)) {
ANDI(rn(t0), r0, i1);
w = _jit->pc.w;
BEQ(_ZERO_REGNO, rn(t0), ((i0 - w) >> 2) - 1);
NOP(1);
}
else {
movi(rn(t0), i1);
w = bmcr(i0, r0, rn(t0));
}
jit_unget_reg(t0);
return (w);
}
static void
_callr(jit_state_t *_jit, jit_int32_t r0)
{
if (r0 != _T9_REGNO)
movr(_T9_REGNO, r0);
JALR(r0);
NOP(1);
}
static void
_calli(jit_state_t *_jit, jit_word_t i0)
{
movi(_T9_REGNO, i0);
JALR(_T9_REGNO);
NOP(1);
}
static jit_word_t
_calli_p(jit_state_t *_jit, jit_word_t i0)
{
jit_word_t word;
word = _jit->pc.w;
movi_p(_T9_REGNO, i0);
JALR(_T9_REGNO);
NOP(1);
return (word);
}
static void
_prolog(jit_state_t *_jit, jit_node_t *node)
{
_jit->function->stack = ((/* first 16 bytes must be allocated */
(_jit->function->self.alen > 16 ?
_jit->function->self.alen : 16) -
/* align stack at 8 bytes */
_jit->function->self.aoff) + 7) & -8;
/* callee save registers */
subi(_SP_REGNO, _SP_REGNO, stack_framesize);
#if __WORDSIZE == 32
if (jit_regset_tstbit(_jit->function->regset, _F30))
stxi_d(96, _SP_REGNO, _F30_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F28))
stxi_d(88, _SP_REGNO, _F28_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F26))
stxi_d(80, _SP_REGNO, _F26_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F24))
stxi_d(72, _SP_REGNO, _F24_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F22))
stxi_d(64, _SP_REGNO, _F22_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F20))
stxi_d(56, _SP_REGNO, _F20_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F18))
stxi_d(48, _SP_REGNO, _F18_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F16))
stxi_d(40, _SP_REGNO, _F16_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S7))
stxi(36, _SP_REGNO, _S7_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S6))
stxi(32, _SP_REGNO, _S6_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S5))
stxi(28, _SP_REGNO, _S5_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S4))
stxi(24, _SP_REGNO, _S4_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S3))
stxi(20, _SP_REGNO, _S3_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S2))
stxi(16, _SP_REGNO, _S2_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S1))
stxi(12, _SP_REGNO, _S1_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S0))
stxi( 8, _SP_REGNO, _S0_REGNO);
stxi( 4, _SP_REGNO, _RA_REGNO);
#else
if (jit_regset_tstbit(_jit->function->regset, _F30))
stxi_d(136, _SP_REGNO, _F30_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F28))
stxi_d(128, _SP_REGNO, _F28_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F26))
stxi_d(120, _SP_REGNO, _F26_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F24))
stxi_d(112, _SP_REGNO, _F24_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F22))
stxi_d(104, _SP_REGNO, _F22_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F20))
stxi_d(96, _SP_REGNO, _F20_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F18))
stxi_d(88, _SP_REGNO, _F18_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _F16))
stxi_d(80, _SP_REGNO, _F16_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S7))
stxi(72, _SP_REGNO, _S7_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S6))
stxi(64, _SP_REGNO, _S6_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S5))
stxi(56, _SP_REGNO, _S5_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S4))
stxi(48, _SP_REGNO, _S4_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S3))
stxi(40, _SP_REGNO, _S3_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S2))
stxi(32, _SP_REGNO, _S2_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S1))
stxi(24, _SP_REGNO, _S1_REGNO);
if (jit_regset_tstbit(_jit->function->regset, _S0))
stxi(16, _SP_REGNO, _S0_REGNO);
stxi( 8, _SP_REGNO, _RA_REGNO);
#endif
stxi(0, _SP_REGNO, _BP_REGNO);
movr(_BP_REGNO, _SP_REGNO);
/* alloca */
subi(_SP_REGNO, _SP_REGNO, _jit->function->stack);
}
static void
_epilog(jit_state_t *_jit, jit_node_t *node)
{
/* callee save registers */
movr(_SP_REGNO, _BP_REGNO);
#if __WORDSIZE == 32
if (jit_regset_tstbit(_jit->function->regset, _F30))
ldxi_d(_F30_REGNO, _SP_REGNO, 96);
if (jit_regset_tstbit(_jit->function->regset, _F28))
ldxi_d(_F28_REGNO, _SP_REGNO, 88);
if (jit_regset_tstbit(_jit->function->regset, _F26))
ldxi_d(_F26_REGNO, _SP_REGNO, 80);
if (jit_regset_tstbit(_jit->function->regset, _F24))
ldxi_d(_F24_REGNO, _SP_REGNO, 72);
if (jit_regset_tstbit(_jit->function->regset, _F22))
ldxi_d(_F22_REGNO, _SP_REGNO, 64);
if (jit_regset_tstbit(_jit->function->regset, _F20))
ldxi_d(_F20_REGNO, _SP_REGNO, 56);
if (jit_regset_tstbit(_jit->function->regset, _F18))
ldxi_d(_F18_REGNO, _SP_REGNO, 48);
if (jit_regset_tstbit(_jit->function->regset, _F16))
ldxi_d(_F16_REGNO, _SP_REGNO, 40);
if (jit_regset_tstbit(_jit->function->regset, _S7))
ldxi(_S7_REGNO, _SP_REGNO, 36);
if (jit_regset_tstbit(_jit->function->regset, _S6))
ldxi(_S6_REGNO, _SP_REGNO, 32);
if (jit_regset_tstbit(_jit->function->regset, _S5))
ldxi(_S5_REGNO, _SP_REGNO, 28);
if (jit_regset_tstbit(_jit->function->regset, _S4))
ldxi(_S4_REGNO, _SP_REGNO, 24);
if (jit_regset_tstbit(_jit->function->regset, _S3))
ldxi(_S3_REGNO, _SP_REGNO, 20);
if (jit_regset_tstbit(_jit->function->regset, _S2))
ldxi(_S2_REGNO, _SP_REGNO, 16);
if (jit_regset_tstbit(_jit->function->regset, _S1))
ldxi(_S1_REGNO, _SP_REGNO, 12);
if (jit_regset_tstbit(_jit->function->regset, _S0))
ldxi(_S0_REGNO, _SP_REGNO, 8);
ldxi(_RA_REGNO, _SP_REGNO, 4);
#else
if (jit_regset_tstbit(_jit->function->regset, _F30))
ldxi_d(_F30_REGNO, _SP_REGNO, 136);
if (jit_regset_tstbit(_jit->function->regset, _F28))
ldxi_d(_F28_REGNO, _SP_REGNO, 128);
if (jit_regset_tstbit(_jit->function->regset, _F26))
ldxi_d(_F26_REGNO, _SP_REGNO, 120);
if (jit_regset_tstbit(_jit->function->regset, _F24))
ldxi_d(_F24_REGNO, _SP_REGNO, 112);
if (jit_regset_tstbit(_jit->function->regset, _F22))
ldxi_d(_F22_REGNO, _SP_REGNO, 104);
if (jit_regset_tstbit(_jit->function->regset, _F20))
ldxi_d(_F20_REGNO, _SP_REGNO, 96);
if (jit_regset_tstbit(_jit->function->regset, _F18))
ldxi_d(_F18_REGNO, _SP_REGNO, 88);
if (jit_regset_tstbit(_jit->function->regset, _F16))
ldxi_d(_F16_REGNO, _SP_REGNO, 80);
if (jit_regset_tstbit(_jit->function->regset, _S7))
ldxi(_S7_REGNO, _SP_REGNO, 72);
if (jit_regset_tstbit(_jit->function->regset, _S6))
ldxi(_S6_REGNO, _SP_REGNO, 64);
if (jit_regset_tstbit(_jit->function->regset, _S5))
ldxi(_S5_REGNO, _SP_REGNO, 56);
if (jit_regset_tstbit(_jit->function->regset, _S4))
ldxi(_S4_REGNO, _SP_REGNO, 48);
if (jit_regset_tstbit(_jit->function->regset, _S3))
ldxi(_S3_REGNO, _SP_REGNO, 40);
if (jit_regset_tstbit(_jit->function->regset, _S2))
ldxi(_S2_REGNO, _SP_REGNO, 32);
if (jit_regset_tstbit(_jit->function->regset, _S1))
ldxi(_S1_REGNO, _SP_REGNO, 24);
if (jit_regset_tstbit(_jit->function->regset, _S0))
ldxi(_S0_REGNO, _SP_REGNO, 16);
ldxi(_RA_REGNO, _SP_REGNO, 8);
#endif
ldxi(_BP_REGNO, _SP_REGNO, 0);
JR(_RA_REGNO);
/* delay slot */
addi(_SP_REGNO, _SP_REGNO, stack_framesize);
}
static void
_patch_abs(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
{
jit_instr_t i;
union {
jit_int32_t *i;
jit_word_t w;
} u;
u.w = instr;
i.op = u.i[0];
assert(i.hc.b == MIPS_LUI);
i.is.b = label >> 16;
u.i[0] = i.op;
i.op = u.i[1];
assert(i.hc.b == MIPS_ORI);
i.is.b = label;
u.i[1] = i.op;
}
static void
_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
{
jit_instr_t i;
union {
jit_int32_t *i;
jit_word_t w;
} u;
u.w = instr;
i.op = u.i[0];
switch (i.hc.b) {
/* 16 bit immediate opcodes */
case MIPS_REGIMM:
switch (i.rt.b) {
case MIPS_BLTZ: case MIPS_BLTZL:
case MIPS_BLTZAL: case MIPS_BLTZALL:
case MIPS_BGEZ: case MIPS_BGEZAL:
case MIPS_BGEZALL: case MIPS_BGEZL:
case MIPS_TEQI: case MIPS_TGEI:
case MIPS_TGEIU: case MIPS_TLTI:
case MIPS_TLTIU: case MIPS_TNEI:
i.is.b = ((label - instr) >> 2) - 1;
u.i[0] = i.op;
break;
default:
assert(!"unhandled branch opcode");
break;
}
break;
case MIPS_COP1: case MIPS_COP2:
assert(i.rs.b == MIPS_BC);
switch (i.rt.b) {
case MIPS_BCF: case MIPS_BCFL:
case MIPS_BCT: case MIPS_BCTL:
i.is.b = ((label - instr) >> 2) - 1;
u.i[0] = i.op;
break;
default:
assert(!"unhandled branch opcode");
break;
}
break;
case MIPS_BLEZ: case MIPS_BLEZL:
case MIPS_BEQ: case MIPS_BEQL:
case MIPS_BGTZ: case MIPS_BGTZL:
case MIPS_BNE: case MIPS_BNEL:
i.is.b = ((label - instr) >> 2) - 1;
u.i[0] = i.op;
break;
case MIPS_LUI:
patch_abs(instr, label);
break;
case MIPS_J: case MIPS_JAL:
case MIPS_JALX:
assert(((instr + sizeof(jit_int32_t)) & 0xf0000000) ==
(label & 0xf0000000));
i.ii.b = (label & ~0xf0000000) >> 2;
u.i[0] = i.op;
break;
default:
assert(!"unhandled branch opcode");
break;
}
}
#endif