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