1/* 2 * Stack-less Just-In-Time compiler 3 * 4 * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without modification, are 7 * permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, this list of 10 * conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 * of conditions and the following disclaimer in the documentation and/or other materials 14 * provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27/* mips 64-bit arch dependent functions. */ 28 29static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm) 30{ 31 sljit_s32 shift = 32; 32 sljit_s32 shift2; 33 sljit_s32 inv = 0; 34 sljit_ins ins; 35 sljit_uw uimm; 36 37 if (!(imm & ~0xffff)) 38 return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); 39 40 if (imm < 0 && imm >= SIMM_MIN) 41 return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); 42 43 if (imm <= 0x7fffffffl && imm >= -0x80000000l) { 44 FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar)); 45 return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS; 46 } 47 48 /* Zero extended number. */ 49 uimm = imm; 50 if (imm < 0) { 51 uimm = ~imm; 52 inv = 1; 53 } 54 55 while (!(uimm & 0xff00000000000000l)) { 56 shift -= 8; 57 uimm <<= 8; 58 } 59 60 if (!(uimm & 0xf000000000000000l)) { 61 shift -= 4; 62 uimm <<= 4; 63 } 64 65 if (!(uimm & 0xc000000000000000l)) { 66 shift -= 2; 67 uimm <<= 2; 68 } 69 70 if ((sljit_sw)uimm < 0) { 71 uimm >>= 1; 72 shift += 1; 73 } 74 SLJIT_ASSERT(((uimm & 0xc000000000000000l) == 0x4000000000000000l) && (shift > 0) && (shift <= 32)); 75 76 if (inv) 77 uimm = ~uimm; 78 79 FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(uimm >> 48), dst_ar)); 80 if (uimm & 0x0000ffff00000000l) 81 FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 32), dst_ar)); 82 83 imm &= (1l << shift) - 1; 84 if (!(imm & ~0xffff)) { 85 ins = (shift == 32) ? DSLL32 : DSLL; 86 if (shift < 32) 87 ins |= SH_IMM(shift); 88 FAIL_IF(push_inst(compiler, ins | TA(dst_ar) | DA(dst_ar), dst_ar)); 89 return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar); 90 } 91 92 /* Double shifts needs to be performed. */ 93 uimm <<= 32; 94 shift2 = shift - 16; 95 96 while (!(uimm & 0xf000000000000000l)) { 97 shift2 -= 4; 98 uimm <<= 4; 99 } 100 101 if (!(uimm & 0xc000000000000000l)) { 102 shift2 -= 2; 103 uimm <<= 2; 104 } 105 106 if (!(uimm & 0x8000000000000000l)) { 107 shift2--; 108 uimm <<= 1; 109 } 110 111 SLJIT_ASSERT((uimm & 0x8000000000000000l) && (shift2 > 0) && (shift2 <= 16)); 112 113 FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift - shift2), dst_ar)); 114 FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 48), dst_ar)); 115 FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift2), dst_ar)); 116 117 imm &= (1l << shift2) - 1; 118 return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar); 119} 120 121#define SELECT_OP(a, b) \ 122 (!(op & SLJIT_I32_OP) ? a : b) 123 124#define EMIT_LOGICAL(op_imm, op_norm) \ 125 if (flags & SRC2_IMM) { \ 126 if (op & SLJIT_SET_E) \ 127 FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \ 128 if (CHECK_FLAGS(SLJIT_SET_E)) \ 129 FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \ 130 } \ 131 else { \ 132 if (op & SLJIT_SET_E) \ 133 FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ 134 if (CHECK_FLAGS(SLJIT_SET_E)) \ 135 FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \ 136 } 137 138#define EMIT_SHIFT(op_dimm, op_dimm32, op_imm, op_dv, op_v) \ 139 if (flags & SRC2_IMM) { \ 140 if (src2 >= 32) { \ 141 SLJIT_ASSERT(!(op & SLJIT_I32_OP)); \ 142 ins = op_dimm32; \ 143 src2 -= 32; \ 144 } \ 145 else \ 146 ins = (op & SLJIT_I32_OP) ? op_imm : op_dimm; \ 147 if (op & SLJIT_SET_E) \ 148 FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \ 149 if (CHECK_FLAGS(SLJIT_SET_E)) \ 150 FAIL_IF(push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \ 151 } \ 152 else { \ 153 ins = (op & SLJIT_I32_OP) ? op_v : op_dv; \ 154 if (op & SLJIT_SET_E) \ 155 FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ 156 if (CHECK_FLAGS(SLJIT_SET_E)) \ 157 FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst))); \ 158 } 159 160static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, 161 sljit_s32 dst, sljit_s32 src1, sljit_sw src2) 162{ 163 sljit_ins ins; 164 165 switch (GET_OPCODE(op)) { 166 case SLJIT_MOV: 167 case SLJIT_MOV_P: 168 SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 169 if (dst != src2) 170 return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst)); 171 return SLJIT_SUCCESS; 172 173 case SLJIT_MOV_U8: 174 case SLJIT_MOV_S8: 175 SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 176 if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { 177 if (op == SLJIT_MOV_S8) { 178 FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst))); 179 return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst)); 180 } 181 return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst)); 182 } 183 else if (dst != src2) 184 SLJIT_ASSERT_STOP(); 185 return SLJIT_SUCCESS; 186 187 case SLJIT_MOV_U16: 188 case SLJIT_MOV_S16: 189 SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 190 if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { 191 if (op == SLJIT_MOV_S16) { 192 FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst))); 193 return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst)); 194 } 195 return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst)); 196 } 197 else if (dst != src2) 198 SLJIT_ASSERT_STOP(); 199 return SLJIT_SUCCESS; 200 201 case SLJIT_MOV_U32: 202 SLJIT_ASSERT(!(op & SLJIT_I32_OP)); 203 FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst))); 204 return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)); 205 206 case SLJIT_MOV_S32: 207 SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 208 return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst)); 209 210 case SLJIT_NOT: 211 SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 212 if (op & SLJIT_SET_E) 213 FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); 214 if (CHECK_FLAGS(SLJIT_SET_E)) 215 FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst))); 216 return SLJIT_SUCCESS; 217 218 case SLJIT_CLZ: 219 SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 220#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) 221 if (op & SLJIT_SET_E) 222 FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); 223 if (CHECK_FLAGS(SLJIT_SET_E)) 224 FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst))); 225#else 226 if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { 227 FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG)); 228 return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG); 229 } 230 /* Nearly all instructions are unmovable in the following sequence. */ 231 FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); 232 /* Check zero. */ 233 FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS)); 234 FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_I32_OP) ? 32 : 64), UNMOVABLE_INS)); 235 FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(dst) | IMM(-1), DR(dst))); 236 /* Loop for searching the highest bit. */ 237 FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst))); 238 FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); 239 FAIL_IF(push_inst(compiler, SELECT_OP(DSLL, SLL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS)); 240 if (op & SLJIT_SET_E) 241 return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); 242#endif 243 return SLJIT_SUCCESS; 244 245 case SLJIT_ADD: 246 if (flags & SRC2_IMM) { 247 if (op & SLJIT_SET_O) { 248 if (src2 >= 0) 249 FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 250 else 251 FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 252 } 253 if (op & SLJIT_SET_E) 254 FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); 255 if (op & (SLJIT_SET_C | SLJIT_SET_O)) { 256 if (src2 >= 0) 257 FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); 258 else { 259 FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); 260 FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); 261 } 262 } 263 /* dst may be the same as src1 or src2. */ 264 if (CHECK_FLAGS(SLJIT_SET_E)) 265 FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst))); 266 } 267 else { 268 if (op & SLJIT_SET_O) 269 FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 270 if (op & SLJIT_SET_E) 271 FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); 272 if (op & (SLJIT_SET_C | SLJIT_SET_O)) 273 FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); 274 /* dst may be the same as src1 or src2. */ 275 if (CHECK_FLAGS(SLJIT_SET_E)) 276 FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst))); 277 } 278 279 /* a + b >= a | b (otherwise, the carry should be set to 1). */ 280 if (op & (SLJIT_SET_C | SLJIT_SET_O)) 281 FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); 282 if (!(op & SLJIT_SET_O)) 283 return SLJIT_SUCCESS; 284 FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1))); 285 FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 286 FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 287 return push_inst(compiler, SELECT_OP(DSRL32, SLL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); 288 289 case SLJIT_ADDC: 290 if (flags & SRC2_IMM) { 291 if (op & SLJIT_SET_C) { 292 if (src2 >= 0) 293 FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); 294 else { 295 FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); 296 FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 297 } 298 } 299 FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst))); 300 } else { 301 if (op & SLJIT_SET_C) 302 FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 303 /* dst may be the same as src1 or src2. */ 304 FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst))); 305 } 306 if (op & SLJIT_SET_C) 307 FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 308 309 FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); 310 if (!(op & SLJIT_SET_C)) 311 return SLJIT_SUCCESS; 312 313 /* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */ 314 FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); 315 /* Set carry flag. */ 316 return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(OVERFLOW_FLAG) | DA(ULESS_FLAG), ULESS_FLAG); 317 318 case SLJIT_SUB: 319 if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) { 320 FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); 321 src2 = TMP_REG2; 322 flags &= ~SRC2_IMM; 323 } 324 325 if (flags & SRC2_IMM) { 326 if (op & SLJIT_SET_O) { 327 if (src2 >= 0) 328 FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 329 else 330 FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 331 } 332 if (op & SLJIT_SET_E) 333 FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG)); 334 if (op & (SLJIT_SET_C | SLJIT_SET_O)) 335 FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); 336 /* dst may be the same as src1 or src2. */ 337 if (CHECK_FLAGS(SLJIT_SET_E)) 338 FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst))); 339 } 340 else { 341 if (op & SLJIT_SET_O) 342 FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 343 if (op & SLJIT_SET_E) 344 FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); 345 if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O)) 346 FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); 347 if (op & SLJIT_SET_U) 348 FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG)); 349 if (op & SLJIT_SET_S) { 350 FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG)); 351 FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG)); 352 } 353 /* dst may be the same as src1 or src2. */ 354 if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C)) 355 FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst))); 356 } 357 358 if (!(op & SLJIT_SET_O)) 359 return SLJIT_SUCCESS; 360 FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1))); 361 FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 362 FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 363 return push_inst(compiler, SELECT_OP(DSRL32, SRL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); 364 365 case SLJIT_SUBC: 366 if ((flags & SRC2_IMM) && src2 == SIMM_MIN) { 367 FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); 368 src2 = TMP_REG2; 369 flags &= ~SRC2_IMM; 370 } 371 372 if (flags & SRC2_IMM) { 373 if (op & SLJIT_SET_C) 374 FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); 375 /* dst may be the same as src1 or src2. */ 376 FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst))); 377 } 378 else { 379 if (op & SLJIT_SET_C) 380 FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 381 /* dst may be the same as src1 or src2. */ 382 FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst))); 383 } 384 385 if (op & SLJIT_SET_C) 386 FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(LESS_FLAG), LESS_FLAG)); 387 388 FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); 389 return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(OVERFLOW_FLAG) | TA(LESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS; 390 391 case SLJIT_MUL: 392 SLJIT_ASSERT(!(flags & SRC2_IMM)); 393 if (!(op & SLJIT_SET_O)) { 394#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) 395 if (op & SLJIT_I32_OP) 396 return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); 397 FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS)); 398 return push_inst(compiler, MFLO | D(dst), DR(dst)); 399#else 400 FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS)); 401 return push_inst(compiler, MFLO | D(dst), DR(dst)); 402#endif 403 } 404 FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS)); 405 FAIL_IF(push_inst(compiler, MFHI | DA(ULESS_FLAG), ULESS_FLAG)); 406 FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst))); 407 FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(UGREATER_FLAG) | SH_IMM(31), UGREATER_FLAG)); 408 return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(ULESS_FLAG) | TA(UGREATER_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); 409 410 case SLJIT_AND: 411 EMIT_LOGICAL(ANDI, AND); 412 return SLJIT_SUCCESS; 413 414 case SLJIT_OR: 415 EMIT_LOGICAL(ORI, OR); 416 return SLJIT_SUCCESS; 417 418 case SLJIT_XOR: 419 EMIT_LOGICAL(XORI, XOR); 420 return SLJIT_SUCCESS; 421 422 case SLJIT_SHL: 423 EMIT_SHIFT(DSLL, DSLL32, SLL, DSLLV, SLLV); 424 return SLJIT_SUCCESS; 425 426 case SLJIT_LSHR: 427 EMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV); 428 return SLJIT_SUCCESS; 429 430 case SLJIT_ASHR: 431 EMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV); 432 return SLJIT_SUCCESS; 433 } 434 435 SLJIT_ASSERT_STOP(); 436 return SLJIT_SUCCESS; 437} 438 439static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value) 440{ 441 FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 48), DR(dst))); 442 FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 32), DR(dst))); 443 FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst))); 444 FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 16), DR(dst))); 445 FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst))); 446 return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); 447} 448 449SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) 450{ 451 sljit_ins *inst = (sljit_ins*)addr; 452 453 inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff); 454 inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff); 455 inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff); 456 inst[5] = (inst[5] & 0xffff0000) | (new_addr & 0xffff); 457 SLJIT_CACHE_FLUSH(inst, inst + 6); 458} 459 460SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) 461{ 462 sljit_ins *inst = (sljit_ins*)addr; 463 464 inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff); 465 inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff); 466 inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff); 467 inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff); 468 SLJIT_CACHE_FLUSH(inst, inst + 6); 469} 470