mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
3029 lines
81 KiB
C
3029 lines
81 KiB
C
/*
|
|
* Copyright (C) 2012, 2013 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 (t0 == 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)
|
|
{
|
|
_jitc->function->stack = ((/* first 16 bytes must be allocated */
|
|
(_jitc->function->self.alen > 16 ?
|
|
_jitc->function->self.alen : 16) -
|
|
/* align stack at 8 bytes */
|
|
_jitc->function->self.aoff) + 7) & -8;
|
|
/* callee save registers */
|
|
subi(_SP_REGNO, _SP_REGNO, stack_framesize);
|
|
#if __WORDSIZE == 32
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F30))
|
|
stxi_d(96, _SP_REGNO, _F30_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F28))
|
|
stxi_d(88, _SP_REGNO, _F28_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F26))
|
|
stxi_d(80, _SP_REGNO, _F26_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F24))
|
|
stxi_d(72, _SP_REGNO, _F24_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F22))
|
|
stxi_d(64, _SP_REGNO, _F22_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F20))
|
|
stxi_d(56, _SP_REGNO, _F20_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F18))
|
|
stxi_d(48, _SP_REGNO, _F18_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F16))
|
|
stxi_d(40, _SP_REGNO, _F16_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S7))
|
|
stxi(36, _SP_REGNO, _S7_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S6))
|
|
stxi(32, _SP_REGNO, _S6_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S5))
|
|
stxi(28, _SP_REGNO, _S5_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S4))
|
|
stxi(24, _SP_REGNO, _S4_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S3))
|
|
stxi(20, _SP_REGNO, _S3_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S2))
|
|
stxi(16, _SP_REGNO, _S2_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S1))
|
|
stxi(12, _SP_REGNO, _S1_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S0))
|
|
stxi( 8, _SP_REGNO, _S0_REGNO);
|
|
stxi( 4, _SP_REGNO, _RA_REGNO);
|
|
#else
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F30))
|
|
stxi_d(136, _SP_REGNO, _F30_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F28))
|
|
stxi_d(128, _SP_REGNO, _F28_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F26))
|
|
stxi_d(120, _SP_REGNO, _F26_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F24))
|
|
stxi_d(112, _SP_REGNO, _F24_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F22))
|
|
stxi_d(104, _SP_REGNO, _F22_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F20))
|
|
stxi_d(96, _SP_REGNO, _F20_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F18))
|
|
stxi_d(88, _SP_REGNO, _F18_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F16))
|
|
stxi_d(80, _SP_REGNO, _F16_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S7))
|
|
stxi(72, _SP_REGNO, _S7_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S6))
|
|
stxi(64, _SP_REGNO, _S6_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S5))
|
|
stxi(56, _SP_REGNO, _S5_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S4))
|
|
stxi(48, _SP_REGNO, _S4_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S3))
|
|
stxi(40, _SP_REGNO, _S3_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S2))
|
|
stxi(32, _SP_REGNO, _S2_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S1))
|
|
stxi(24, _SP_REGNO, _S1_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->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, _jitc->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(&_jitc->function->regset, _F30))
|
|
ldxi_d(_F30_REGNO, _SP_REGNO, 96);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F28))
|
|
ldxi_d(_F28_REGNO, _SP_REGNO, 88);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F26))
|
|
ldxi_d(_F26_REGNO, _SP_REGNO, 80);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F24))
|
|
ldxi_d(_F24_REGNO, _SP_REGNO, 72);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F22))
|
|
ldxi_d(_F22_REGNO, _SP_REGNO, 64);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F20))
|
|
ldxi_d(_F20_REGNO, _SP_REGNO, 56);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F18))
|
|
ldxi_d(_F18_REGNO, _SP_REGNO, 48);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F16))
|
|
ldxi_d(_F16_REGNO, _SP_REGNO, 40);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S7))
|
|
ldxi(_S7_REGNO, _SP_REGNO, 36);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S6))
|
|
ldxi(_S6_REGNO, _SP_REGNO, 32);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S5))
|
|
ldxi(_S5_REGNO, _SP_REGNO, 28);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S4))
|
|
ldxi(_S4_REGNO, _SP_REGNO, 24);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S3))
|
|
ldxi(_S3_REGNO, _SP_REGNO, 20);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S2))
|
|
ldxi(_S2_REGNO, _SP_REGNO, 16);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S1))
|
|
ldxi(_S1_REGNO, _SP_REGNO, 12);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S0))
|
|
ldxi(_S0_REGNO, _SP_REGNO, 8);
|
|
ldxi(_RA_REGNO, _SP_REGNO, 4);
|
|
#else
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F30))
|
|
ldxi_d(_F30_REGNO, _SP_REGNO, 136);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F28))
|
|
ldxi_d(_F28_REGNO, _SP_REGNO, 128);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F26))
|
|
ldxi_d(_F26_REGNO, _SP_REGNO, 120);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F24))
|
|
ldxi_d(_F24_REGNO, _SP_REGNO, 112);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F22))
|
|
ldxi_d(_F22_REGNO, _SP_REGNO, 104);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F20))
|
|
ldxi_d(_F20_REGNO, _SP_REGNO, 96);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F18))
|
|
ldxi_d(_F18_REGNO, _SP_REGNO, 88);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _F16))
|
|
ldxi_d(_F16_REGNO, _SP_REGNO, 80);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S7))
|
|
ldxi(_S7_REGNO, _SP_REGNO, 72);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S6))
|
|
ldxi(_S6_REGNO, _SP_REGNO, 64);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S5))
|
|
ldxi(_S5_REGNO, _SP_REGNO, 56);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S4))
|
|
ldxi(_S4_REGNO, _SP_REGNO, 48);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S3))
|
|
ldxi(_S3_REGNO, _SP_REGNO, 40);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S2))
|
|
ldxi(_S2_REGNO, _SP_REGNO, 32);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _S1))
|
|
ldxi(_S1_REGNO, _SP_REGNO, 24);
|
|
if (jit_regset_tstbit(&_jitc->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
|