| 33 |
#endif |
#endif |
| 34 |
} |
} |
| 35 |
|
|
| 36 |
|
/* Latest MIPS architecture. */ |
| 37 |
|
/* Detect SLJIT_MIPS_32_64 */ |
| 38 |
|
|
| 39 |
/* Length of an instruction word |
/* Length of an instruction word |
| 40 |
Both for mips-32 and mips-64 */ |
Both for mips-32 and mips-64 */ |
| 41 |
typedef sljit_ui sljit_ins; |
typedef sljit_ui sljit_ins; |
| 45 |
#define TMP_REG3 (SLJIT_NO_REGISTERS + 3) |
#define TMP_REG3 (SLJIT_NO_REGISTERS + 3) |
| 46 |
#define REAL_STACK_PTR (SLJIT_NO_REGISTERS + 4) |
#define REAL_STACK_PTR (SLJIT_NO_REGISTERS + 4) |
| 47 |
|
|
| 48 |
|
/* For position independent code, t9 must contain the function address. */ |
| 49 |
|
#define PIC_ADDR_REG TMP_REG2 |
| 50 |
|
|
| 51 |
/* TMP_EREG1 is used mainly for literal encoding on 64 bit. */ |
/* TMP_EREG1 is used mainly for literal encoding on 64 bit. */ |
| 52 |
#define TMP_EREG1 24 |
#define TMP_EREG1 15 |
| 53 |
#define TMP_EREG2 25 |
#define TMP_EREG2 24 |
| 54 |
|
/* Floating point status register. */ |
| 55 |
|
#define FCSR_REG 31 |
| 56 |
|
/* Return address register. */ |
| 57 |
|
#define RETURN_ADDR_REG 31 |
| 58 |
|
|
| 59 |
/* Flags are keept in volatile registers. */ |
/* Flags are keept in volatile registers. */ |
| 60 |
#define EQUAL_FLAG 7 |
#define EQUAL_FLAG 7 |
| 61 |
/* And carry flag as well. */ |
/* And carry flag as well. */ |
| 62 |
#define ULESS_FLAG 11 |
#define ULESS_FLAG 10 |
| 63 |
#define UGREATER_FLAG 12 |
#define UGREATER_FLAG 11 |
| 64 |
#define LESS_FLAG 13 |
#define LESS_FLAG 12 |
| 65 |
#define GREATER_FLAG 14 |
#define GREATER_FLAG 13 |
| 66 |
#define OVERFLOW_FLAG 15 |
#define OVERFLOW_FLAG 14 |
|
|
|
|
#define UNORD_BIT 1 |
|
|
#define EQUAL_BIT 2 |
|
|
#define LESS_BIT 3 |
|
|
#define GREATER_BIT 4 |
|
| 67 |
|
|
| 68 |
#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) |
#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) |
| 69 |
#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) |
#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) |
| 97 |
#define AND (HI(0) | LO(36)) |
#define AND (HI(0) | LO(36)) |
| 98 |
#define ANDI (HI(12)) |
#define ANDI (HI(12)) |
| 99 |
#define B (HI(4)) |
#define B (HI(4)) |
|
#define BAL (HI(1) | (17 << 16)) |
|
| 100 |
#define BC1F (HI(17) | (8 << 21)) |
#define BC1F (HI(17) | (8 << 21)) |
| 101 |
#define BC1T (HI(17) | (8 << 21) | (1 << 16)) |
#define BC1T (HI(17) | (8 << 21) | (1 << 16)) |
| 102 |
#define BEQ (HI(4)) |
#define BEQ (HI(4)) |
| 109 |
#define C_UN_D (HI(17) | FMT_D | LO(49)) |
#define C_UN_D (HI(17) | FMT_D | LO(49)) |
| 110 |
#define C_UEQ_D (HI(17) | FMT_D | LO(51)) |
#define C_UEQ_D (HI(17) | FMT_D | LO(51)) |
| 111 |
#define C_ULT_D (HI(17) | FMT_D | LO(53)) |
#define C_ULT_D (HI(17) | FMT_D | LO(53)) |
|
#define CLZ (HI(28) | LO(32)) |
|
| 112 |
#define DIV_D (HI(17) | FMT_D | LO(3)) |
#define DIV_D (HI(17) | FMT_D | LO(3)) |
|
#define EXT (HI(31) | LO(0)) |
|
| 113 |
#define J (HI(2)) |
#define J (HI(2)) |
|
#define JAL (HI(3)) |
|
| 114 |
#define JALR (HI(0) | LO(9)) |
#define JALR (HI(0) | LO(9)) |
| 115 |
#define JR (HI(0) | LO(8)) |
#define JR (HI(0) | LO(8)) |
| 116 |
#define LD (HI(55)) |
#define LD (HI(55)) |
| 124 |
#define CFC1 (HI(17) | (2 << 21)) |
#define CFC1 (HI(17) | (2 << 21)) |
| 125 |
#define MOVN (HI(0) | LO(11)) |
#define MOVN (HI(0) | LO(11)) |
| 126 |
#define MOVZ (HI(0) | LO(10)) |
#define MOVZ (HI(0) | LO(10)) |
|
#define MUL (HI(28) | LO(2)) |
|
| 127 |
#define MUL_D (HI(17) | FMT_D | LO(2)) |
#define MUL_D (HI(17) | FMT_D | LO(2)) |
| 128 |
#define MULT (HI(0) | LO(24)) |
#define MULT (HI(0) | LO(24)) |
| 129 |
#define NOP (HI(0) | LO(0)) |
#define NOP (HI(0) | LO(0)) |
| 132 |
#define ORI (HI(13)) |
#define ORI (HI(13)) |
| 133 |
#define SD (HI(63)) |
#define SD (HI(63)) |
| 134 |
#define SDC1 (HI(61)) |
#define SDC1 (HI(61)) |
|
#define SEB (HI(31) | (16 << 6) | LO(32)) |
|
|
#define SEH (HI(31) | (24 << 6) | LO(32)) |
|
| 135 |
#define SLT (HI(0) | LO(42)) |
#define SLT (HI(0) | LO(42)) |
| 136 |
#define SLTI (HI(10)) |
#define SLTI (HI(10)) |
| 137 |
#define SLTIU (HI(11)) |
#define SLTIU (HI(11)) |
| 148 |
#define XOR (HI(0) | LO(38)) |
#define XOR (HI(0) | LO(38)) |
| 149 |
#define XORI (HI(14)) |
#define XORI (HI(14)) |
| 150 |
|
|
| 151 |
|
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) |
| 152 |
|
#define CLZ (HI(28) | LO(32)) |
| 153 |
|
#define MUL (HI(28) | LO(2)) |
| 154 |
|
#define SEB (HI(31) | (16 << 6) | LO(32)) |
| 155 |
|
#define SEH (HI(31) | (24 << 6) | LO(32)) |
| 156 |
|
#endif |
| 157 |
|
|
| 158 |
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) |
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) |
| 159 |
#define ADDU_W ADDU |
#define ADDU_W ADDU |
| 160 |
#define ADDIU_W ADDIU |
#define ADDIU_W ADDIU |
|
#define EXT_W EXT |
|
| 161 |
#define SLL_W SLL |
#define SLL_W SLL |
| 162 |
#define SUBU_W SUBU |
#define SUBU_W SUBU |
| 163 |
#else |
#else |
| 164 |
#define ADDU_W DADDU |
#define ADDU_W DADDU |
| 165 |
#define ADDIU_W DADDIU |
#define ADDIU_W DADDIU |
|
#define EXT_W DEXT |
|
| 166 |
#define SLL_W DSLL |
#define SLL_W DSLL |
| 167 |
#define SUBU_W DSUBU |
#define SUBU_W DSUBU |
| 168 |
#endif |
#endif |
| 172 |
#define UIMM_MAX (0xffff) |
#define UIMM_MAX (0xffff) |
| 173 |
|
|
| 174 |
static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = { |
static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = { |
| 175 |
0, 2, 5, 6, 3, 4, 17, 18, 19, 20, 21, 16, 8, 9, 10, 29 |
0, 2, 5, 6, 3, 8, 17, 18, 19, 20, 21, 16, 4, 25, 9, 29 |
| 176 |
}; |
}; |
| 177 |
|
|
| 178 |
/* dest_reg is the absolute name of the register |
/* dest_reg is the absolute name of the register |
| 199 |
sljit_ins *inst; |
sljit_ins *inst; |
| 200 |
sljit_ins saved_inst; |
sljit_ins saved_inst; |
| 201 |
|
|
| 202 |
if (jump->flags & SLJIT_REWRITABLE_JUMP) |
if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_JAL)) |
| 203 |
return code_ptr; |
return code_ptr; |
| 204 |
|
|
| 205 |
if (jump->flags & JUMP_ADDR) |
if (jump->flags & JUMP_ADDR) |
| 220 |
|
|
| 221 |
if (!(jump->flags & IS_COND)) { |
if (!(jump->flags & IS_COND)) { |
| 222 |
inst[0] = inst[-1]; |
inst[0] = inst[-1]; |
| 223 |
inst[-1] = (jump->flags & IS_JAL) ? BAL : B; |
inst[-1] = B; |
| 224 |
jump->addr -= sizeof(sljit_ins); |
jump->addr -= sizeof(sljit_ins); |
| 225 |
return inst; |
return inst; |
| 226 |
} |
} |
| 237 |
jump->flags |= PATCH_B; |
jump->flags |= PATCH_B; |
| 238 |
|
|
| 239 |
if (!(jump->flags & IS_COND)) { |
if (!(jump->flags & IS_COND)) { |
| 240 |
inst[0] = (jump->flags & IS_JAL) ? BAL : B; |
inst[0] = B; |
| 241 |
inst[1] = NOP; |
inst[1] = NOP; |
| 242 |
return inst + 1; |
return inst + 1; |
| 243 |
} |
} |
| 265 |
if ((target_addr & ~0xfffffff) == (jump->addr & ~0xfffffff)) { |
if ((target_addr & ~0xfffffff) == (jump->addr & ~0xfffffff)) { |
| 266 |
jump->flags |= PATCH_J; |
jump->flags |= PATCH_J; |
| 267 |
inst[0] = inst[-1]; |
inst[0] = inst[-1]; |
| 268 |
inst[-1] = (jump->flags & IS_JAL) ? JAL : J; |
inst[-1] = J; |
| 269 |
jump->addr -= sizeof(sljit_ins); |
jump->addr -= sizeof(sljit_ins); |
| 270 |
return inst; |
return inst; |
| 271 |
} |
} |
| 273 |
|
|
| 274 |
if ((target_addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)) { |
if ((target_addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)) { |
| 275 |
jump->flags |= PATCH_J; |
jump->flags |= PATCH_J; |
| 276 |
inst[0] = (jump->flags & IS_JAL) ? JAL : J; |
inst[0] = J; |
| 277 |
inst[1] = NOP; |
inst[1] = NOP; |
| 278 |
return inst + 1; |
return inst + 1; |
| 279 |
} |
} |
| 480 |
local_size = 0; |
local_size = 0; |
| 481 |
} |
} |
| 482 |
|
|
| 483 |
FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(31) | IMM(local_size - 1 * (int)sizeof(sljit_w)), MOVABLE_INS)); |
FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), MOVABLE_INS)); |
| 484 |
if (compiler->has_locals) |
if (compiler->has_locals) |
| 485 |
FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_LOCALS_REG) | IMM(local_size - 2 * (int)sizeof(sljit_w)), MOVABLE_INS)); |
FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_LOCALS_REG) | IMM(local_size - 2 * (int)sizeof(sljit_w)), MOVABLE_INS)); |
| 486 |
if (generals >= 1) |
if (generals >= 1) |
| 542 |
local_size = 0; |
local_size = 0; |
| 543 |
} |
} |
| 544 |
|
|
| 545 |
FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(31) | IMM(local_size - 1 * (int)sizeof(sljit_w)), 31)); |
FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), RETURN_ADDR_REG)); |
| 546 |
if (compiler->generals >= 5) |
if (compiler->generals >= 5) |
| 547 |
FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_GENERAL_EREG2) | IMM(local_size - 7 * (int)sizeof(sljit_w)), DR(SLJIT_GENERAL_EREG2))); |
FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_GENERAL_EREG2) | IMM(local_size - 7 * (int)sizeof(sljit_w)), DR(SLJIT_GENERAL_EREG2))); |
| 548 |
if (compiler->generals >= 4) |
if (compiler->generals >= 4) |
| 556 |
if (compiler->has_locals) |
if (compiler->has_locals) |
| 557 |
FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_LOCALS_REG) | IMM(local_size - 2 * (int)sizeof(sljit_w)), DR(SLJIT_LOCALS_REG))); |
FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_LOCALS_REG) | IMM(local_size - 2 * (int)sizeof(sljit_w)), DR(SLJIT_LOCALS_REG))); |
| 558 |
|
|
| 559 |
FAIL_IF(push_inst(compiler, JR | SA(31), UNMOVABLE_INS)); |
FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); |
| 560 |
if (compiler->local_size <= SIMM_MAX) |
if (compiler->local_size <= SIMM_MAX) |
| 561 |
return push_inst(compiler, ADDIU_W | S(REAL_STACK_PTR) | T(REAL_STACK_PTR) | IMM(compiler->local_size), UNMOVABLE_INS); |
return push_inst(compiler, ADDIU_W | S(REAL_STACK_PTR) | T(REAL_STACK_PTR) | IMM(compiler->local_size), UNMOVABLE_INS); |
| 562 |
else |
else |
| 1057 |
|
|
| 1058 |
int sljit_is_fpu_available(void) |
int sljit_is_fpu_available(void) |
| 1059 |
{ |
{ |
| 1060 |
#if 0 |
#if (defined SLJIT_QEMU && SLJIT_QEMU) |
| 1061 |
|
/* Qemu says fir is 0 by default. */ |
| 1062 |
|
return 1; |
| 1063 |
|
#elif defined(__GNUC__) |
| 1064 |
sljit_w fir; |
sljit_w fir; |
| 1065 |
asm ("cfc1 %0, $0" : "=r"(fir)); |
asm ("cfc1 %0, $0" : "=r"(fir)); |
| 1066 |
return (fir >> 22) & 0x1; |
return (fir >> 22) & 0x1; |
| 1067 |
|
#else |
| 1068 |
|
#error "FIR check is not implemented for this architecture" |
| 1069 |
#endif |
#endif |
|
/* Qemu says fir is 0 by default. */ |
|
|
return 1; |
|
| 1070 |
} |
} |
| 1071 |
|
|
| 1072 |
static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw) |
static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw) |
| 1130 |
} |
} |
| 1131 |
|
|
| 1132 |
/* src and dst are swapped. */ |
/* src and dst are swapped. */ |
| 1133 |
if (op & SLJIT_SET_E) |
if (op & SLJIT_SET_E) { |
| 1134 |
FAIL_IF(push_inst(compiler, C_UEQ_D | FT(src) | FS(dst) | (EQUAL_BIT << 8), FCSR_FCC + EQUAL_BIT)); |
FAIL_IF(push_inst(compiler, C_UEQ_D | FT(src) | FS(dst), UNMOVABLE_INS)); |
| 1135 |
|
FAIL_IF(push_inst(compiler, CFC1 | TA(EQUAL_FLAG) | DA(FCSR_REG), EQUAL_FLAG)); |
| 1136 |
|
FAIL_IF(push_inst(compiler, SRL | TA(EQUAL_FLAG) | DA(EQUAL_FLAG) | SH_IMM(23), EQUAL_FLAG)); |
| 1137 |
|
FAIL_IF(push_inst(compiler, ANDI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG)); |
| 1138 |
|
} |
| 1139 |
if (op & SLJIT_SET_S) { |
if (op & SLJIT_SET_S) { |
| 1140 |
FAIL_IF(push_inst(compiler, C_ULT_D | FT(src) | FS(dst) | (LESS_BIT << 8), FCSR_FCC + LESS_BIT)); |
/* Mixing the instructions for the two checks. */ |
| 1141 |
FAIL_IF(push_inst(compiler, C_ULT_D | FT(dst) | FS(src) | (GREATER_BIT << 8), FCSR_FCC + GREATER_BIT)); |
FAIL_IF(push_inst(compiler, C_ULT_D | FT(src) | FS(dst), UNMOVABLE_INS)); |
| 1142 |
|
FAIL_IF(push_inst(compiler, CFC1 | TA(ULESS_FLAG) | DA(FCSR_REG), ULESS_FLAG)); |
| 1143 |
|
FAIL_IF(push_inst(compiler, C_ULT_D | FT(dst) | FS(src), UNMOVABLE_INS)); |
| 1144 |
|
FAIL_IF(push_inst(compiler, SRL | TA(ULESS_FLAG) | DA(ULESS_FLAG) | SH_IMM(23), ULESS_FLAG)); |
| 1145 |
|
FAIL_IF(push_inst(compiler, ANDI | SA(ULESS_FLAG) | TA(ULESS_FLAG) | IMM(1), ULESS_FLAG)); |
| 1146 |
|
FAIL_IF(push_inst(compiler, CFC1 | TA(UGREATER_FLAG) | DA(FCSR_REG), UGREATER_FLAG)); |
| 1147 |
|
FAIL_IF(push_inst(compiler, SRL | TA(UGREATER_FLAG) | DA(UGREATER_FLAG) | SH_IMM(23), UGREATER_FLAG)); |
| 1148 |
|
FAIL_IF(push_inst(compiler, ANDI | SA(UGREATER_FLAG) | TA(UGREATER_FLAG) | IMM(1), UGREATER_FLAG)); |
| 1149 |
} |
} |
| 1150 |
return push_inst(compiler, C_UN_D | FT(src) | FS(dst) | (UNORD_BIT << 8), FCSR_FCC + UNORD_BIT); |
return push_inst(compiler, C_UN_D | FT(src) | FS(dst), FCSR_FCC); |
| 1151 |
} |
} |
| 1152 |
|
|
| 1153 |
dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; |
dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; |
| 1242 |
compiler->local_size = (local_size + 15) & ~0xf; |
compiler->local_size = (local_size + 15) & ~0xf; |
| 1243 |
|
|
| 1244 |
if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) |
if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) |
| 1245 |
return push_inst(compiler, ADDU_W | SA(31) | TA(0) | D(dst), DR(dst)); |
return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst)); |
| 1246 |
else if (dst & SLJIT_MEM) |
else if (dst & SLJIT_MEM) |
| 1247 |
return emit_op_mem(compiler, WORD_DATA, 31, dst, dstw); |
return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); |
| 1248 |
return SLJIT_SUCCESS; |
return SLJIT_SUCCESS; |
| 1249 |
} |
} |
| 1250 |
|
|
| 1254 |
check_sljit_emit_fast_return(compiler, src, srcw); |
check_sljit_emit_fast_return(compiler, src, srcw); |
| 1255 |
|
|
| 1256 |
if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) |
if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) |
| 1257 |
FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(31), 31)); |
FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG)); |
| 1258 |
else if (src & SLJIT_MEM) |
else if (src & SLJIT_MEM) |
| 1259 |
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, 31, src, srcw)); |
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw)); |
| 1260 |
else if (src & SLJIT_IMM) |
else if (src & SLJIT_IMM) |
| 1261 |
FAIL_IF(load_immediate(compiler, 31, srcw)); |
FAIL_IF(load_immediate(compiler, RETURN_ADDR_REG, srcw)); |
| 1262 |
|
|
| 1263 |
FAIL_IF(push_inst(compiler, JR | SA(31), UNMOVABLE_INS)); |
FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); |
| 1264 |
return push_inst(compiler, NOP, UNMOVABLE_INS); |
return push_inst(compiler, NOP, UNMOVABLE_INS); |
| 1265 |
} |
} |
| 1266 |
|
|
| 1301 |
flags = IS_BIT26_COND; \ |
flags = IS_BIT26_COND; \ |
| 1302 |
delay_check = src; |
delay_check = src; |
| 1303 |
|
|
| 1304 |
#define BR_T(bit) \ |
#define BR_T() \ |
| 1305 |
inst = BC1T | (bit << 18) | JUMP_LENGTH; \ |
inst = BC1T | JUMP_LENGTH; \ |
| 1306 |
flags = IS_BIT16_COND; \ |
flags = IS_BIT16_COND; \ |
| 1307 |
delay_check = FCSR_FCC + bit; |
delay_check = FCSR_FCC; |
| 1308 |
|
|
| 1309 |
#define BR_F(bit) \ |
#define BR_F() \ |
| 1310 |
inst = BC1F | (bit << 18) | JUMP_LENGTH; \ |
inst = BC1F | JUMP_LENGTH; \ |
| 1311 |
flags = IS_BIT16_COND; \ |
flags = IS_BIT16_COND; \ |
| 1312 |
delay_check = FCSR_FCC + bit; |
delay_check = FCSR_FCC; |
| 1313 |
|
|
| 1314 |
struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) |
struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) |
| 1315 |
{ |
{ |
| 1328 |
|
|
| 1329 |
switch (type) { |
switch (type) { |
| 1330 |
case SLJIT_C_EQUAL: |
case SLJIT_C_EQUAL: |
| 1331 |
|
case SLJIT_C_FLOAT_NOT_EQUAL: |
| 1332 |
BR_NZ(EQUAL_FLAG); |
BR_NZ(EQUAL_FLAG); |
| 1333 |
break; |
break; |
| 1334 |
case SLJIT_C_NOT_EQUAL: |
case SLJIT_C_NOT_EQUAL: |
| 1335 |
|
case SLJIT_C_FLOAT_EQUAL: |
| 1336 |
BR_Z(EQUAL_FLAG); |
BR_Z(EQUAL_FLAG); |
| 1337 |
break; |
break; |
| 1338 |
case SLJIT_C_LESS: |
case SLJIT_C_LESS: |
| 1339 |
|
case SLJIT_C_FLOAT_LESS: |
| 1340 |
BR_Z(ULESS_FLAG); |
BR_Z(ULESS_FLAG); |
| 1341 |
break; |
break; |
| 1342 |
case SLJIT_C_GREATER_EQUAL: |
case SLJIT_C_GREATER_EQUAL: |
| 1343 |
|
case SLJIT_C_FLOAT_GREATER_EQUAL: |
| 1344 |
BR_NZ(ULESS_FLAG); |
BR_NZ(ULESS_FLAG); |
| 1345 |
break; |
break; |
| 1346 |
case SLJIT_C_GREATER: |
case SLJIT_C_GREATER: |
| 1347 |
|
case SLJIT_C_FLOAT_GREATER: |
| 1348 |
BR_Z(UGREATER_FLAG); |
BR_Z(UGREATER_FLAG); |
| 1349 |
break; |
break; |
| 1350 |
case SLJIT_C_LESS_EQUAL: |
case SLJIT_C_LESS_EQUAL: |
| 1351 |
|
case SLJIT_C_FLOAT_LESS_EQUAL: |
| 1352 |
BR_NZ(UGREATER_FLAG); |
BR_NZ(UGREATER_FLAG); |
| 1353 |
break; |
break; |
| 1354 |
case SLJIT_C_SIG_LESS: |
case SLJIT_C_SIG_LESS: |
| 1371 |
case SLJIT_C_MUL_NOT_OVERFLOW: |
case SLJIT_C_MUL_NOT_OVERFLOW: |
| 1372 |
BR_NZ(OVERFLOW_FLAG); |
BR_NZ(OVERFLOW_FLAG); |
| 1373 |
break; |
break; |
|
case SLJIT_C_FLOAT_EQUAL: |
|
|
BR_F(EQUAL_BIT); |
|
|
break; |
|
|
case SLJIT_C_FLOAT_NOT_EQUAL: |
|
|
BR_T(EQUAL_BIT); |
|
|
break; |
|
|
case SLJIT_C_FLOAT_LESS: |
|
|
BR_F(LESS_BIT); |
|
|
break; |
|
|
case SLJIT_C_FLOAT_GREATER_EQUAL: |
|
|
BR_T(LESS_BIT); |
|
|
break; |
|
|
case SLJIT_C_FLOAT_GREATER: |
|
|
BR_F(GREATER_BIT); |
|
|
break; |
|
|
case SLJIT_C_FLOAT_LESS_EQUAL: |
|
|
BR_T(GREATER_BIT); |
|
|
break; |
|
| 1374 |
case SLJIT_C_FLOAT_NAN: |
case SLJIT_C_FLOAT_NAN: |
| 1375 |
BR_F(UNORD_BIT); |
BR_F(); |
| 1376 |
break; |
break; |
| 1377 |
case SLJIT_C_FLOAT_NOT_NAN: |
case SLJIT_C_FLOAT_NOT_NAN: |
| 1378 |
BR_T(UNORD_BIT); |
BR_T(); |
| 1379 |
break; |
break; |
| 1380 |
default: |
default: |
| 1381 |
/* Not conditional branch. */ |
/* Not conditional branch. */ |
| 1390 |
if (inst) |
if (inst) |
| 1391 |
PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS)); |
PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS)); |
| 1392 |
|
|
|
if (type >= SLJIT_CALL1) |
|
|
PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), 4)); |
|
|
|
|
| 1393 |
PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); |
PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); |
| 1394 |
if (type <= SLJIT_JUMP) |
if (type <= SLJIT_JUMP) { |
| 1395 |
PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); |
PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); |
| 1396 |
else { |
jump->addr = compiler->size; |
| 1397 |
|
PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); |
| 1398 |
|
} else { |
| 1399 |
|
/* Cannot be optimized out. */ |
| 1400 |
|
SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); |
| 1401 |
jump->flags |= IS_JAL; |
jump->flags |= IS_JAL; |
| 1402 |
PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(31), UNMOVABLE_INS)); |
PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); |
| 1403 |
|
jump->addr = compiler->size; |
| 1404 |
|
PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS)); |
| 1405 |
} |
} |
|
jump->addr = compiler->size; |
|
|
PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); |
|
| 1406 |
return jump; |
return jump; |
| 1407 |
} |
} |
| 1408 |
|
|
| 1573 |
} |
} |
| 1574 |
|
|
| 1575 |
if (type >= SLJIT_CALL0) { |
if (type >= SLJIT_CALL0) { |
| 1576 |
if (src & SLJIT_IMM) { |
SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); |
| 1577 |
FAIL_IF(load_immediate(compiler, 25, srcw)); |
if (src & (SLJIT_IMM | SLJIT_MEM)) { |
| 1578 |
FAIL_IF(push_inst(compiler, JALR | SA(25) | DA(31), UNMOVABLE_INS)); |
if (src & SLJIT_IMM) |
| 1579 |
|
FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw)); |
| 1580 |
|
else { |
| 1581 |
|
SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM)); |
| 1582 |
|
FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); |
| 1583 |
|
} |
| 1584 |
|
FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); |
| 1585 |
/* We need an extra instruction in any case. */ |
/* We need an extra instruction in any case. */ |
| 1586 |
return push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS); |
return push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS); |
| 1587 |
} |
} |
|
if (src & SLJIT_MEM) |
|
|
FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); |
|
| 1588 |
|
|
| 1589 |
|
/* Register input. */ |
| 1590 |
if (type >= SLJIT_CALL1) |
if (type >= SLJIT_CALL1) |
| 1591 |
FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), 4)); |
FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), 4)); |
| 1592 |
FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(31), UNMOVABLE_INS)); |
FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); |
| 1593 |
return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | DA(25), UNMOVABLE_INS); |
return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | D(PIC_ADDR_REG), UNMOVABLE_INS); |
| 1594 |
} |
} |
| 1595 |
|
|
| 1596 |
if (src & SLJIT_IMM) { |
if (src & SLJIT_IMM) { |
| 1597 |
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); |
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); |
| 1598 |
FAIL_IF(!jump); |
FAIL_IF(!jump); |
| 1599 |
set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_CALL0) ? IS_JAL : 0)); |
set_jump(jump, compiler, JUMP_ADDR); |
| 1600 |
jump->u.target = srcw; |
jump->u.target = srcw; |
| 1601 |
|
|
| 1602 |
if (compiler->delay_slot != UNMOVABLE_INS) |
if (compiler->delay_slot != UNMOVABLE_INS) |
| 1634 |
break; |
break; |
| 1635 |
case SLJIT_C_LESS: |
case SLJIT_C_LESS: |
| 1636 |
case SLJIT_C_GREATER_EQUAL: |
case SLJIT_C_GREATER_EQUAL: |
| 1637 |
|
case SLJIT_C_FLOAT_LESS: |
| 1638 |
|
case SLJIT_C_FLOAT_GREATER_EQUAL: |
| 1639 |
dst_ar = ULESS_FLAG; |
dst_ar = ULESS_FLAG; |
| 1640 |
break; |
break; |
| 1641 |
case SLJIT_C_GREATER: |
case SLJIT_C_GREATER: |
| 1642 |
case SLJIT_C_LESS_EQUAL: |
case SLJIT_C_LESS_EQUAL: |
| 1643 |
|
case SLJIT_C_FLOAT_GREATER: |
| 1644 |
|
case SLJIT_C_FLOAT_LESS_EQUAL: |
| 1645 |
dst_ar = UGREATER_FLAG; |
dst_ar = UGREATER_FLAG; |
| 1646 |
break; |
break; |
| 1647 |
case SLJIT_C_SIG_LESS: |
case SLJIT_C_SIG_LESS: |
| 1662 |
dst_ar = sugg_dst_ar; |
dst_ar = sugg_dst_ar; |
| 1663 |
type ^= 0x1; /* Flip type bit for the XORI below. */ |
type ^= 0x1; /* Flip type bit for the XORI below. */ |
| 1664 |
break; |
break; |
| 1665 |
|
case SLJIT_C_FLOAT_EQUAL: |
| 1666 |
|
case SLJIT_C_FLOAT_NOT_EQUAL: |
| 1667 |
|
dst_ar = EQUAL_FLAG; |
| 1668 |
|
break; |
| 1669 |
|
|
| 1670 |
|
case SLJIT_C_FLOAT_NAN: |
| 1671 |
|
case SLJIT_C_FLOAT_NOT_NAN: |
| 1672 |
|
FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(FCSR_REG), sugg_dst_ar)); |
| 1673 |
|
FAIL_IF(push_inst(compiler, SRL | TA(sugg_dst_ar) | DA(sugg_dst_ar) | SH_IMM(23), sugg_dst_ar)); |
| 1674 |
|
FAIL_IF(push_inst(compiler, ANDI | SA(sugg_dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); |
| 1675 |
|
dst_ar = sugg_dst_ar; |
| 1676 |
|
break; |
| 1677 |
|
|
| 1678 |
default: |
default: |
| 1679 |
if (type >= SLJIT_C_FLOAT_EQUAL && type <= SLJIT_C_FLOAT_NOT_NAN) { |
SLJIT_ASSERT_STOP(); |
|
FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(31), sugg_dst_ar)); |
|
|
switch (type) { |
|
|
case SLJIT_C_FLOAT_EQUAL: |
|
|
case SLJIT_C_FLOAT_NOT_EQUAL: |
|
|
dst_ar = EQUAL_BIT + 24; |
|
|
break; |
|
|
case SLJIT_C_FLOAT_LESS: |
|
|
case SLJIT_C_FLOAT_GREATER_EQUAL: |
|
|
dst_ar = LESS_BIT + 24; |
|
|
break; |
|
|
case SLJIT_C_FLOAT_GREATER: |
|
|
case SLJIT_C_FLOAT_LESS_EQUAL: |
|
|
dst_ar = GREATER_BIT + 24; |
|
|
break; |
|
|
case SLJIT_C_FLOAT_NAN: |
|
|
case SLJIT_C_FLOAT_NOT_NAN: |
|
|
dst_ar = UNORD_BIT + 24; |
|
|
break; |
|
|
} |
|
|
FAIL_IF(push_inst(compiler, EXT_W | SA(sugg_dst_ar) | TA(sugg_dst_ar) | (dst_ar << 6), sugg_dst_ar)); |
|
|
} |
|
| 1680 |
dst_ar = sugg_dst_ar; |
dst_ar = sugg_dst_ar; |
| 1681 |
break; |
break; |
| 1682 |
} |
} |