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 32-bit arch dependent functions. */ 28 29static int load_immediate(struct sljit_compiler *compiler, int dst_ar, sljit_w imm) 30{ 31 if (!(imm & ~0xffff)) 32 return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); 33 34 if (imm < 0 && imm >= SIMM_MIN) 35 return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); 36 37 FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar)); 38 return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS; 39} 40 41#define EMIT_LOGICAL(op_imm, op_norm) \ 42 if (flags & SRC2_IMM) { \ 43 if (op & SLJIT_SET_E) \ 44 FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \ 45 if (CHECK_FLAGS(SLJIT_SET_E)) \ 46 FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \ 47 } \ 48 else { \ 49 if (op & SLJIT_SET_E) \ 50 FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ 51 if (CHECK_FLAGS(SLJIT_SET_E)) \ 52 FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \ 53 } 54 55#define EMIT_SHIFT(op_imm, op_norm) \ 56 if (flags & SRC2_IMM) { \ 57 if (op & SLJIT_SET_E) \ 58 FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \ 59 if (CHECK_FLAGS(SLJIT_SET_E)) \ 60 FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \ 61 } \ 62 else { \ 63 if (op & SLJIT_SET_E) \ 64 FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ 65 if (CHECK_FLAGS(SLJIT_SET_E)) \ 66 FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | D(dst), DR(dst))); \ 67 } 68 69static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags, 70 int dst, int src1, sljit_w src2) 71{ 72 int overflow_ra = 0; 73 74 switch (GET_OPCODE(op)) { 75 case SLJIT_ADD: 76 if (flags & SRC2_IMM) { 77 if (op & SLJIT_SET_O) { 78 FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1)); 79 if (src2 < 0) 80 FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1)); 81 } 82 if (op & SLJIT_SET_E) 83 FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); 84 if (op & SLJIT_SET_C) { 85 if (src2 >= 0) 86 FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); 87 else { 88 FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); 89 FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); 90 } 91 } 92 /* dst may be the same as src1 or src2. */ 93 if (CHECK_FLAGS(SLJIT_SET_E)) 94 FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst))); 95 if (op & SLJIT_SET_O) { 96 FAIL_IF(push_inst(compiler, SRL | T(dst) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG)); 97 if (src2 < 0) 98 FAIL_IF(push_inst(compiler, XORI | SA(OVERFLOW_FLAG) | TA(OVERFLOW_FLAG) | IMM(1), OVERFLOW_FLAG)); 99 } 100 } 101 else { 102 if (op & SLJIT_SET_O) { 103 FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1)); 104 FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1)); 105 if (src1 != dst) 106 overflow_ra = DR(src1); 107 else if (src2 != dst) 108 overflow_ra = DR(src2); 109 else { 110 /* Rare ocasion. */ 111 FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2)); 112 overflow_ra = TMP_EREG2; 113 } 114 } 115 if (op & SLJIT_SET_E) 116 FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); 117 if (op & SLJIT_SET_C) 118 FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); 119 /* dst may be the same as src1 or src2. */ 120 if (CHECK_FLAGS(SLJIT_SET_E)) 121 FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst))); 122 if (op & SLJIT_SET_O) { 123 FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 124 FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG)); 125 } 126 } 127 128 /* a + b >= a | b (otherwise, the carry should be set to 1). */ 129 if (op & SLJIT_SET_C) 130 FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); 131 if (op & SLJIT_SET_O) 132 return push_inst(compiler, MOVN | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); 133 return SLJIT_SUCCESS; 134 135 case SLJIT_ADDC: 136 if (flags & SRC2_IMM) { 137 if (op & SLJIT_SET_C) { 138 if (src2 >= 0) 139 FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1)); 140 else { 141 FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1)); 142 FAIL_IF(push_inst(compiler, OR | S(src1) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1)); 143 } 144 } 145 FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst))); 146 } else { 147 if (op & SLJIT_SET_C) 148 FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1)); 149 /* dst may be the same as src1 or src2. */ 150 FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst))); 151 } 152 if (op & SLJIT_SET_C) 153 FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1)); 154 155 FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); 156 if (!(op & SLJIT_SET_C)) 157 return SLJIT_SUCCESS; 158 159 /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */ 160 FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(TMP_EREG2) | IMM(1), TMP_EREG2)); 161 FAIL_IF(push_inst(compiler, AND | SA(TMP_EREG2) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2)); 162 /* Set carry flag. */ 163 return push_inst(compiler, OR | SA(TMP_EREG2) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG); 164 165 case SLJIT_SUB: 166 if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_S | SLJIT_SET_U)) || src2 == SIMM_MIN)) { 167 FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); 168 src2 = TMP_REG2; 169 flags &= ~SRC2_IMM; 170 } 171 172 if (flags & SRC2_IMM) { 173 if (op & SLJIT_SET_O) { 174 FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1)); 175 if (src2 < 0) 176 FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1)); 177 if (src1 != dst) 178 overflow_ra = DR(src1); 179 else { 180 /* Rare ocasion. */ 181 FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2)); 182 overflow_ra = TMP_EREG2; 183 } 184 } 185 if (op & SLJIT_SET_E) 186 FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG)); 187 if (op & SLJIT_SET_C) 188 FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); 189 /* dst may be the same as src1 or src2. */ 190 if (CHECK_FLAGS(SLJIT_SET_E)) 191 FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst))); 192 } 193 else { 194 if (op & SLJIT_SET_O) { 195 FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1)); 196 FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1)); 197 if (src1 != dst) 198 overflow_ra = DR(src1); 199 else { 200 /* Rare ocasion. */ 201 FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2)); 202 overflow_ra = TMP_EREG2; 203 } 204 } 205 if (op & SLJIT_SET_E) 206 FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); 207 if (op & (SLJIT_SET_U | SLJIT_SET_C)) 208 FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); 209 if (op & SLJIT_SET_U) 210 FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG)); 211 if (op & SLJIT_SET_S) { 212 FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG)); 213 FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG)); 214 } 215 /* dst may be the same as src1 or src2. */ 216 if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C)) 217 FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst))); 218 } 219 220 if (op & SLJIT_SET_O) { 221 FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 222 FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG)); 223 return push_inst(compiler, MOVZ | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); 224 } 225 return SLJIT_SUCCESS; 226 227 case SLJIT_SUBC: 228 if ((flags & SRC2_IMM) && src2 == SIMM_MIN) { 229 FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); 230 src2 = TMP_REG2; 231 flags &= ~SRC2_IMM; 232 } 233 234 if (flags & SRC2_IMM) { 235 if (op & SLJIT_SET_C) 236 FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(TMP_EREG1) | IMM(-src2), TMP_EREG1)); 237 /* dst may be the same as src1 or src2. */ 238 FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst))); 239 } 240 else { 241 if (op & SLJIT_SET_C) 242 FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1)); 243 /* dst may be the same as src1 or src2. */ 244 FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst))); 245 } 246 247 if (op & SLJIT_SET_C) 248 FAIL_IF(push_inst(compiler, MOVZ | SA(ULESS_FLAG) | T(dst) | DA(TMP_EREG1), TMP_EREG1)); 249 250 FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); 251 252 if (op & SLJIT_SET_C) 253 FAIL_IF(push_inst(compiler, ADDU | SA(TMP_EREG1) | TA(0) | DA(ULESS_FLAG), ULESS_FLAG)); 254 255 return SLJIT_SUCCESS; 256 257 case SLJIT_MUL: 258 SLJIT_ASSERT(!(flags & SRC2_IMM)); 259 if (!(op & SLJIT_SET_O)) { 260#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) 261 return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); 262#else 263 FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS)); 264 return push_inst(compiler, MFLO | D(dst), DR(dst)); 265#endif 266 } 267 FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS)); 268 FAIL_IF(push_inst(compiler, MFHI | DA(TMP_EREG1), TMP_EREG1)); 269 FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst))); 270 FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(TMP_EREG2) | SH_IMM(31), TMP_EREG2)); 271 return push_inst(compiler, SUBU | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); 272 273 case SLJIT_AND: 274 EMIT_LOGICAL(ANDI, AND); 275 return SLJIT_SUCCESS; 276 277 case SLJIT_OR: 278 EMIT_LOGICAL(ORI, OR); 279 return SLJIT_SUCCESS; 280 281 case SLJIT_XOR: 282 EMIT_LOGICAL(XORI, XOR); 283 return SLJIT_SUCCESS; 284 285 case SLJIT_SHL: 286 EMIT_SHIFT(SLL, SLLV); 287 return SLJIT_SUCCESS; 288 289 case SLJIT_LSHR: 290 EMIT_SHIFT(SRL, SRLV); 291 return SLJIT_SUCCESS; 292 293 case SLJIT_ASHR: 294 EMIT_SHIFT(SRA, SRAV); 295 return SLJIT_SUCCESS; 296 297 case SLJIT_MOV: 298 case SLJIT_MOV_UI: 299 case SLJIT_MOV_SI: 300 SLJIT_ASSERT(src1 == TMP_REG1); 301 if (dst != src2) 302 return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst)); 303 return SLJIT_SUCCESS; 304 305 case SLJIT_MOV_UB: 306 case SLJIT_MOV_SB: 307 SLJIT_ASSERT(src1 == TMP_REG1); 308 if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { 309 if (op == SLJIT_MOV_SB) { 310#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) 311 return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); 312#else 313 FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst))); 314 return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst)); 315#endif 316 } 317 return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst)); 318 } 319 else if (dst != src2) 320 SLJIT_ASSERT_STOP(); 321 return SLJIT_SUCCESS; 322 323 case SLJIT_MOV_UH: 324 case SLJIT_MOV_SH: 325 SLJIT_ASSERT(src1 == TMP_REG1); 326 if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { 327 if (op == SLJIT_MOV_SH) { 328#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) 329 return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); 330#else 331 FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst))); 332 return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst)); 333#endif 334 } 335 return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst)); 336 } 337 else if (dst != src2) 338 SLJIT_ASSERT_STOP(); 339 return SLJIT_SUCCESS; 340 341 case SLJIT_NOT: 342 SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 343 if (op & SLJIT_SET_E) 344 FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); 345 if (CHECK_FLAGS(SLJIT_SET_E)) 346 FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst))); 347 return SLJIT_SUCCESS; 348 349 case SLJIT_CLZ: 350 SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 351#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) 352 if (op & SLJIT_SET_E) 353 FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); 354 if (CHECK_FLAGS(SLJIT_SET_E)) 355 FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst))); 356#else 357 if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { 358 FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG)); 359 return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG); 360 } 361 /* Nearly all instructions are unmovable in the following sequence. */ 362 FAIL_IF(push_inst(compiler, ADDU_W | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); 363 /* Check zero. */ 364 FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(6), UNMOVABLE_INS)); 365 FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS)); 366 /* Check sign bit. */ 367 FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG1) | IMM(4), UNMOVABLE_INS)); 368 FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(0), UNMOVABLE_INS)); 369 /* Loop for searching the highest bit. */ 370 FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1))); 371 FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); 372 FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), UNMOVABLE_INS)); 373 if (op & SLJIT_SET_E) 374 return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); 375#endif 376 return SLJIT_SUCCESS; 377 } 378 379 SLJIT_ASSERT_STOP(); 380 return SLJIT_SUCCESS; 381} 382 383static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value) 384{ 385 FAIL_IF(push_inst(compiler, LUI | T(reg) | IMM(init_value >> 16), DR(reg))); 386 return push_inst(compiler, ORI | S(reg) | T(reg) | IMM(init_value), DR(reg)); 387} 388 389SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) 390{ 391 sljit_ins *inst = (sljit_ins*)addr; 392 393 inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff); 394 inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff); 395 SLJIT_CACHE_FLUSH(inst, inst + 2); 396} 397 398SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) 399{ 400 sljit_ins *inst = (sljit_ins*)addr; 401 402 inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); 403 inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); 404 SLJIT_CACHE_FLUSH(inst, inst + 2); 405} 406