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 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) 28 { 29 return "SPARC" SLJIT_CPUINFO; 30 } 31 32 /* Length of an instruction word 33 Both for sparc-32 and sparc-64 */ 34 typedef sljit_ui sljit_ins; 35 36 static void sparc_cache_flush(sljit_ins *from, sljit_ins *to) 37 { 38 if (SLJIT_UNLIKELY(from == to)) 39 return; 40 41 do { 42 __asm__ volatile ( 43 "flush %0\n" 44 : : "r"(from) 45 ); 46 /* Operates at least on doubleword. */ 47 from += 2; 48 } while (from < to); 49 50 if (from == to) { 51 /* Flush the last word. */ 52 to --; 53 __asm__ volatile ( 54 "flush %0\n" 55 : : "r"(to) 56 ); 57 } 58 } 59 60 /* TMP_REG2 is not used by getput_arg */ 61 #define TMP_REG1 (SLJIT_NO_REGISTERS + 1) 62 #define TMP_REG2 (SLJIT_NO_REGISTERS + 2) 63 #define TMP_REG3 (SLJIT_NO_REGISTERS + 3) 64 #define TMP_REG4 (SLJIT_NO_REGISTERS + 4) 65 #define LINK_REG (SLJIT_NO_REGISTERS + 5) 66 67 #define TMP_FREG1 ((SLJIT_FLOAT_REG4 + 1) << 1) 68 #define TMP_FREG2 ((SLJIT_FLOAT_REG4 + 2) << 1) 69 70 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 7] = { 71 0, 8, 9, 10, 11, 12, 16, 17, 18, 19, 20, 14, 1, 24, 25, 26, 15 72 }; 73 74 /* --------------------------------------------------------------------- */ 75 /* Instrucion forms */ 76 /* --------------------------------------------------------------------- */ 77 78 #define D(d) (reg_map[d] << 25) 79 #define DA(d) ((d) << 25) 80 #define S1(s1) (reg_map[s1] << 14) 81 #define S2(s2) (reg_map[s2]) 82 #define S1A(s1) ((s1) << 14) 83 #define S2A(s2) (s2) 84 #define IMM_ARG 0x2000 85 #define DOP(op) ((op) << 5) 86 #define IMM(imm) (((imm) & 0x1fff) | IMM_ARG) 87 88 #define DR(dr) (reg_map[dr]) 89 #define OPC1(opcode) ((opcode) << 30) 90 #define OPC2(opcode) ((opcode) << 22) 91 #define OPC3(opcode) ((opcode) << 19) 92 #define SET_FLAGS OPC3(0x10) 93 94 #define ADD (OPC1(0x2) | OPC3(0x00)) 95 #define ADDC (OPC1(0x2) | OPC3(0x08)) 96 #define AND (OPC1(0x2) | OPC3(0x01)) 97 #define ANDN (OPC1(0x2) | OPC3(0x05)) 98 #define CALL (OPC1(0x1)) 99 #define FABSS (OPC1(0x2) | OPC3(0x34) | DOP(0x09)) 100 #define FADDD (OPC1(0x2) | OPC3(0x34) | DOP(0x42)) 101 #define FCMPD (OPC1(0x2) | OPC3(0x35) | DOP(0x52)) 102 #define FDIVD (OPC1(0x2) | OPC3(0x34) | DOP(0x4e)) 103 #define FMOVS (OPC1(0x2) | OPC3(0x34) | DOP(0x01)) 104 #define FMULD (OPC1(0x2) | OPC3(0x34) | DOP(0x4a)) 105 #define FNEGS (OPC1(0x2) | OPC3(0x34) | DOP(0x05)) 106 #define FSUBD (OPC1(0x2) | OPC3(0x34) | DOP(0x46)) 107 #define JMPL (OPC1(0x2) | OPC3(0x38)) 108 #define NOP (OPC1(0x0) | OPC2(0x04)) 109 #define OR (OPC1(0x2) | OPC3(0x02)) 110 #define ORN (OPC1(0x2) | OPC3(0x06)) 111 #define RDY (OPC1(0x2) | OPC3(0x28) | S1A(0)) 112 #define RESTORE (OPC1(0x2) | OPC3(0x3d)) 113 #define SAVE (OPC1(0x2) | OPC3(0x3c)) 114 #define SETHI (OPC1(0x0) | OPC2(0x04)) 115 #define SLL (OPC1(0x2) | OPC3(0x25)) 116 #define SLLX (OPC1(0x2) | OPC3(0x25) | (1 << 12)) 117 #define SRA (OPC1(0x2) | OPC3(0x27)) 118 #define SRAX (OPC1(0x2) | OPC3(0x27) | (1 << 12)) 119 #define SRL (OPC1(0x2) | OPC3(0x26)) 120 #define SRLX (OPC1(0x2) | OPC3(0x26) | (1 << 12)) 121 #define SUB (OPC1(0x2) | OPC3(0x04)) 122 #define SUBC (OPC1(0x2) | OPC3(0x0c)) 123 #define TA (OPC1(0x2) | OPC3(0x3a) | (8 << 25)) 124 #define WRY (OPC1(0x2) | OPC3(0x30) | DA(0)) 125 #define XOR (OPC1(0x2) | OPC3(0x03)) 126 #define XNOR (OPC1(0x2) | OPC3(0x07)) 127 128 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 129 #define MAX_DISP (0x1fffff) 130 #define MIN_DISP (-0x200000) 131 #define DISP_MASK (0x3fffff) 132 133 #define BICC (OPC1(0x0) | OPC2(0x2)) 134 #define FBFCC (OPC1(0x0) | OPC2(0x6)) 135 #define SLL_W SLL 136 #define SDIV (OPC1(0x2) | OPC3(0x0f)) 137 #define SMUL (OPC1(0x2) | OPC3(0x0b)) 138 #define UDIV (OPC1(0x2) | OPC3(0x0e)) 139 #define UMUL (OPC1(0x2) | OPC3(0x0a)) 140 #else 141 #define SLL_W SLLX 142 #endif 143 144 #define SIMM_MAX (0x0fff) 145 #define SIMM_MIN (-0x1000) 146 147 /* dest_reg is the absolute name of the register 148 Useful for reordering instructions in the delay slot. */ 149 static int push_inst(struct sljit_compiler *compiler, sljit_ins ins, int delay_slot) 150 { 151 SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS 152 || (delay_slot & DST_INS_MASK) == MOVABLE_INS 153 || (delay_slot & DST_INS_MASK) == ((ins >> 25) & 0x1f)); 154 sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); 155 FAIL_IF(!ptr); 156 *ptr = ins; 157 compiler->size++; 158 compiler->delay_slot = delay_slot; 159 return SLJIT_SUCCESS; 160 } 161 162 static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) 163 { 164 sljit_w diff; 165 sljit_uw target_addr; 166 sljit_ins *inst; 167 sljit_ins saved_inst; 168 169 if (jump->flags & SLJIT_REWRITABLE_JUMP) 170 return code_ptr; 171 172 if (jump->flags & JUMP_ADDR) 173 target_addr = jump->u.target; 174 else { 175 SLJIT_ASSERT(jump->flags & JUMP_LABEL); 176 target_addr = (sljit_uw)(code + jump->u.label->size); 177 } 178 inst = (sljit_ins*)jump->addr; 179 180 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 181 if (jump->flags & IS_CALL) { 182 /* Call is always patchable on sparc 32. */ 183 jump->flags |= PATCH_CALL; 184 if (jump->flags & IS_MOVABLE) { 185 inst[0] = inst[-1]; 186 inst[-1] = CALL; 187 jump->addr -= sizeof(sljit_ins); 188 return inst; 189 } 190 inst[0] = CALL; 191 inst[1] = NOP; 192 return inst + 1; 193 } 194 #else 195 /* Both calls and BPr instructions shall not pass this point. */ 196 #error "Implementation required" 197 #endif 198 199 if (jump->flags & IS_COND) 200 inst--; 201 202 if (jump->flags & IS_MOVABLE) { 203 diff = ((sljit_w)target_addr - (sljit_w)(inst - 1)) >> 2; 204 if (diff <= MAX_DISP && diff >= MIN_DISP) { 205 jump->flags |= PATCH_B; 206 inst--; 207 if (jump->flags & IS_COND) { 208 saved_inst = inst[0]; 209 inst[0] = inst[1] ^ (1 << 28); 210 inst[1] = saved_inst; 211 } else { 212 inst[1] = inst[0]; 213 inst[0] = BICC | DA(0x8); 214 } 215 jump->addr = (sljit_uw)inst; 216 return inst + 1; 217 } 218 } 219 220 diff = ((sljit_w)target_addr - (sljit_w)(inst)) >> 2; 221 if (diff <= MAX_DISP && diff >= MIN_DISP) { 222 jump->flags |= PATCH_B; 223 if (jump->flags & IS_COND) 224 inst[0] ^= (1 << 28); 225 else 226 inst[0] = BICC | DA(0x8); 227 inst[1] = NOP; 228 jump->addr = (sljit_uw)inst; 229 return inst + 1; 230 } 231 232 return code_ptr; 233 } 234 235 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) 236 { 237 struct sljit_memory_fragment *buf; 238 sljit_ins *code; 239 sljit_ins *code_ptr; 240 sljit_ins *buf_ptr; 241 sljit_ins *buf_end; 242 sljit_uw word_count; 243 sljit_uw addr; 244 245 struct sljit_label *label; 246 struct sljit_jump *jump; 247 struct sljit_const *const_; 248 249 CHECK_ERROR_PTR(); 250 check_sljit_generate_code(compiler); 251 reverse_buf(compiler); 252 253 code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); 254 PTR_FAIL_WITH_EXEC_IF(code); 255 buf = compiler->buf; 256 257 code_ptr = code; 258 word_count = 0; 259 label = compiler->labels; 260 jump = compiler->jumps; 261 const_ = compiler->consts; 262 do { 263 buf_ptr = (sljit_ins*)buf->memory; 264 buf_end = buf_ptr + (buf->used_size >> 2); 265 do { 266 *code_ptr = *buf_ptr++; 267 SLJIT_ASSERT(!label || label->size >= word_count); 268 SLJIT_ASSERT(!jump || jump->addr >= word_count); 269 SLJIT_ASSERT(!const_ || const_->addr >= word_count); 270 /* These structures are ordered by their address. */ 271 if (label && label->size == word_count) { 272 /* Just recording the address. */ 273 label->addr = (sljit_uw)code_ptr; 274 label->size = code_ptr - code; 275 label = label->next; 276 } 277 if (jump && jump->addr == word_count) { 278 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 279 jump->addr = (sljit_uw)(code_ptr - 3); 280 #else 281 jump->addr = (sljit_uw)(code_ptr - 6); 282 #endif 283 code_ptr = optimize_jump(jump, code_ptr, code); 284 jump = jump->next; 285 } 286 if (const_ && const_->addr == word_count) { 287 /* Just recording the address. */ 288 const_->addr = (sljit_uw)code_ptr; 289 const_ = const_->next; 290 } 291 code_ptr ++; 292 word_count ++; 293 } while (buf_ptr < buf_end); 294 295 buf = buf->next; 296 } while (buf); 297 298 if (label && label->size == word_count) { 299 label->addr = (sljit_uw)code_ptr; 300 label->size = code_ptr - code; 301 label = label->next; 302 } 303 304 SLJIT_ASSERT(!label); 305 SLJIT_ASSERT(!jump); 306 SLJIT_ASSERT(!const_); 307 SLJIT_ASSERT(code_ptr - code <= (int)compiler->size); 308 309 jump = compiler->jumps; 310 while (jump) { 311 do { 312 addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; 313 buf_ptr = (sljit_ins*)jump->addr; 314 315 if (jump->flags & PATCH_CALL) { 316 addr = (sljit_w)(addr - jump->addr) >> 2; 317 SLJIT_ASSERT((sljit_w)addr <= 0x1fffffff && (sljit_w)addr >= -0x20000000); 318 buf_ptr[0] = CALL | (addr & 0x3fffffff); 319 break; 320 } 321 if (jump->flags & PATCH_B) { 322 addr = (sljit_w)(addr - jump->addr) >> 2; 323 SLJIT_ASSERT((sljit_w)addr <= MAX_DISP && (sljit_w)addr >= MIN_DISP); 324 buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK); 325 break; 326 } 327 328 /* Set the fields of immediate loads. */ 329 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 330 buf_ptr[0] = (buf_ptr[0] & 0xffc00000) | ((addr >> 10) & 0x3fffff); 331 buf_ptr[1] = (buf_ptr[1] & 0xfffffc00) | (addr & 0x3ff); 332 #else 333 #error "Implementation required" 334 #endif 335 } while (0); 336 jump = jump->next; 337 } 338 339 340 compiler->error = SLJIT_ERR_COMPILED; 341 compiler->executable_size = compiler->size * sizeof(sljit_ins); 342 SLJIT_CACHE_FLUSH(code, code_ptr); 343 return code; 344 } 345 346 /* --------------------------------------------------------------------- */ 347 /* Entry, exit */ 348 /* --------------------------------------------------------------------- */ 349 350 /* Creates an index in data_transfer_insts array. */ 351 #define LOAD_DATA 0x01 352 #define WORD_DATA 0x00 353 #define BYTE_DATA 0x02 354 #define HALF_DATA 0x04 355 #define INT_DATA 0x06 356 #define SIGNED_DATA 0x08 357 /* Separates integer and floating point registers */ 358 #define GPR_REG 0x0f 359 #define DOUBLE_DATA 0x10 360 361 #define MEM_MASK 0x1f 362 363 #define WRITE_BACK 0x00020 364 #define ARG_TEST 0x00040 365 #define CUMULATIVE_OP 0x00080 366 #define IMM_OP 0x00100 367 #define SRC2_IMM 0x00200 368 369 #define REG_DEST 0x00400 370 #define REG2_SOURCE 0x00800 371 #define SLOW_SRC1 0x01000 372 #define SLOW_SRC2 0x02000 373 #define SLOW_DEST 0x04000 374 /* SET_FLAGS (0x10 << 19) also belong here! */ 375 376 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 377 #include "sljitNativeSPARC_32.c" 378 #else 379 #include "sljitNativeSPARC_64.c" 380 #endif 381 382 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) 383 { 384 CHECK_ERROR(); 385 check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); 386 387 compiler->temporaries = temporaries; 388 compiler->saveds = saveds; 389 #if (defined SLJIT_DEBUG && SLJIT_DEBUG) 390 compiler->logical_local_size = local_size; 391 #endif 392 393 local_size += 23 * sizeof(sljit_w); 394 local_size = (local_size + 7) & ~0x7; 395 compiler->local_size = local_size; 396 397 if (local_size <= SIMM_MAX) { 398 FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_LOCALS_REG) | S1(SLJIT_LOCALS_REG) | IMM(-local_size), UNMOVABLE_INS)); 399 } 400 else { 401 FAIL_IF(load_immediate(compiler, TMP_REG1, -local_size)); 402 FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_LOCALS_REG) | S1(SLJIT_LOCALS_REG) | S2(TMP_REG1), UNMOVABLE_INS)); 403 } 404 405 if (args >= 1) 406 FAIL_IF(push_inst(compiler, OR | D(SLJIT_SAVED_REG1) | S1(0) | S2A(24), DR(SLJIT_SAVED_REG1))); 407 if (args >= 2) 408 FAIL_IF(push_inst(compiler, OR | D(SLJIT_SAVED_REG2) | S1(0) | S2A(25), DR(SLJIT_SAVED_REG2))); 409 if (args >= 3) 410 FAIL_IF(push_inst(compiler, OR | D(SLJIT_SAVED_REG3) | S1(0) | S2A(26), DR(SLJIT_SAVED_REG3))); 411 412 return SLJIT_SUCCESS; 413 } 414 415 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) 416 { 417 CHECK_ERROR_VOID(); 418 check_sljit_set_context(compiler, args, temporaries, saveds, local_size); 419 420 compiler->temporaries = temporaries; 421 compiler->saveds = saveds; 422 #if (defined SLJIT_DEBUG && SLJIT_DEBUG) 423 compiler->logical_local_size = local_size; 424 #endif 425 426 local_size += 23 * sizeof(sljit_w); 427 compiler->local_size = (local_size + 7) & ~0x7; 428 } 429 430 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) 431 { 432 CHECK_ERROR(); 433 check_sljit_emit_return(compiler, op, src, srcw); 434 435 if (op != SLJIT_MOV || !(src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)) { 436 FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); 437 src = SLJIT_TEMPORARY_REG1; 438 } 439 440 FAIL_IF(push_inst(compiler, JMPL | D(0) | S1A(31) | IMM(8), UNMOVABLE_INS)); 441 return push_inst(compiler, RESTORE | D(SLJIT_TEMPORARY_REG1) | S1(src) | S2(0), UNMOVABLE_INS); 442 } 443 444 /* --------------------------------------------------------------------- */ 445 /* Operators */ 446 /* --------------------------------------------------------------------- */ 447 448 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 449 #define ARCH_32_64(a, b) a 450 #else 451 #define ARCH_32_64(a, b) b 452 #endif 453 454 static SLJIT_CONST sljit_ins data_transfer_insts[16 + 2] = { 455 /* u w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */), 456 /* u w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */), 457 /* u b s */ OPC1(3) | OPC3(0x05) /* stb */, 458 /* u b l */ OPC1(3) | OPC3(0x01) /* ldub */, 459 /* u h s */ OPC1(3) | OPC3(0x06) /* sth */, 460 /* u h l */ OPC1(3) | OPC3(0x02) /* lduh */, 461 /* u i s */ OPC1(3) | OPC3(0x04) /* stw */, 462 /* u i l */ OPC1(3) | OPC3(0x00) /* lduw */, 463 464 /* s w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */), 465 /* s w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */), 466 /* s b s */ OPC1(3) | OPC3(0x05) /* stb */, 467 /* s b l */ OPC1(3) | OPC3(0x09) /* ldsb */, 468 /* s h s */ OPC1(3) | OPC3(0x06) /* sth */, 469 /* s h l */ OPC1(3) | OPC3(0x0a) /* ldsh */, 470 /* s i s */ OPC1(3) | OPC3(0x04) /* stw */, 471 /* s i l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x08) /* ldsw */), 472 473 /* d s */ OPC1(3) | OPC3(0x27), 474 /* d l */ OPC1(3) | OPC3(0x23), 475 }; 476 477 #undef ARCH_32_64 478 479 /* Can perform an operation using at most 1 instruction. */ 480 static int getput_arg_fast(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw) 481 { 482 SLJIT_ASSERT(arg & SLJIT_MEM); 483 484 if (!(flags & WRITE_BACK)) { 485 if ((!(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) 486 || ((arg & 0xf0) && (argw & 0x3) == 0)) { 487 /* Works for both absoulte and relative addresses (immediate case). */ 488 if (SLJIT_UNLIKELY(flags & ARG_TEST)) 489 return 1; 490 FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] 491 | ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg)) 492 | S1(arg & 0xf) | ((arg & 0xf0) ? S2((arg >> 4) & 0xf) : IMM(argw)), 493 ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS)); 494 return -1; 495 } 496 } 497 return 0; 498 } 499 500 /* See getput_arg below. 501 Note: can_cache is called only for binary operators. Those 502 operators always uses word arguments without write back. */ 503 static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) 504 { 505 SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); 506 507 /* Simple operation except for updates. */ 508 if (arg & 0xf0) { 509 argw &= 0x3; 510 SLJIT_ASSERT(argw); 511 next_argw &= 0x3; 512 if ((arg & 0xf0) == (next_arg & 0xf0) && argw == next_argw) 513 return 1; 514 return 0; 515 } 516 517 if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)) 518 return 1; 519 return 0; 520 } 521 522 /* Emit the necessary instructions. See can_cache above. */ 523 static int getput_arg(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw) 524 { 525 int base, arg2, delay_slot; 526 sljit_ins dest; 527 528 SLJIT_ASSERT(arg & SLJIT_MEM); 529 if (!(next_arg & SLJIT_MEM)) { 530 next_arg = 0; 531 next_argw = 0; 532 } 533 534 base = arg & 0xf; 535 if (SLJIT_UNLIKELY(arg & 0xf0)) { 536 argw &= 0x3; 537 SLJIT_ASSERT(argw != 0); 538 539 /* Using the cache. */ 540 if (((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) && (argw == compiler->cache_argw)) 541 arg2 = TMP_REG3; 542 else { 543 if ((arg & 0xf0) == (next_arg & 0xf0) && argw == (next_argw & 0x3)) { 544 compiler->cache_arg = SLJIT_MEM | (arg & 0xf0); 545 compiler->cache_argw = argw; 546 arg2 = TMP_REG3; 547 } 548 else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base && (reg << 4) != (arg & 0xf0)) 549 arg2 = reg; 550 else /* It must be a mov operation, so tmp1 must be free to use. */ 551 arg2 = TMP_REG1; 552 FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1((arg >> 4) & 0xf) | IMM_ARG | argw, DR(arg2))); 553 } 554 } 555 else { 556 /* Using the cache. */ 557 if ((compiler->cache_arg == SLJIT_MEM) && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) { 558 if (argw != compiler->cache_argw) { 559 FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | S1(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); 560 compiler->cache_argw = argw; 561 } 562 arg2 = TMP_REG3; 563 } else { 564 if ((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN) { 565 compiler->cache_arg = SLJIT_MEM; 566 compiler->cache_argw = argw; 567 arg2 = TMP_REG3; 568 } 569 else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base) 570 arg2 = reg; 571 else /* It must be a mov operation, so tmp1 must be free to use. */ 572 arg2 = TMP_REG1; 573 FAIL_IF(load_immediate(compiler, arg2, argw)); 574 } 575 } 576 577 dest = ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg)); 578 delay_slot = ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS; 579 if (!base) 580 return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(arg2) | IMM(0), delay_slot); 581 if (!(flags & WRITE_BACK)) 582 return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot); 583 FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot)); 584 return push_inst(compiler, ADD | D(base) | S1(base) | S2(arg2), DR(base)); 585 } 586 587 static SLJIT_INLINE int emit_op_mem(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw) 588 { 589 if (getput_arg_fast(compiler, flags, reg, arg, argw)) 590 return compiler->error; 591 compiler->cache_arg = 0; 592 compiler->cache_argw = 0; 593 return getput_arg(compiler, flags, reg, arg, argw, 0, 0); 594 } 595 596 static SLJIT_INLINE int emit_op_mem2(struct sljit_compiler *compiler, int flags, int reg, int arg1, sljit_w arg1w, int arg2, sljit_w arg2w) 597 { 598 if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) 599 return compiler->error; 600 return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); 601 } 602 603 static int emit_op(struct sljit_compiler *compiler, int op, int flags, 604 int dst, sljit_w dstw, 605 int src1, sljit_w src1w, 606 int src2, sljit_w src2w) 607 { 608 /* arg1 goes to TMP_REG1 or src reg 609 arg2 goes to TMP_REG2, imm or src reg 610 TMP_REG3 can be used for caching 611 result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ 612 int dst_r = TMP_REG2; 613 int src1_r; 614 sljit_w src2_r = 0; 615 int sugg_src2_r = TMP_REG2; 616 617 compiler->cache_arg = 0; 618 compiler->cache_argw = 0; 619 620 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) { 621 dst_r = dst; 622 flags |= REG_DEST; 623 if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) 624 sugg_src2_r = dst_r; 625 } 626 else if (dst == SLJIT_UNUSED) { 627 if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) 628 return SLJIT_SUCCESS; 629 } 630 else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw)) 631 flags |= SLOW_DEST; 632 633 if (flags & IMM_OP) { 634 if ((src2 & SLJIT_IMM) && src2w) { 635 if (src2w <= SIMM_MAX && src2w >= SIMM_MIN) { 636 flags |= SRC2_IMM; 637 src2_r = src2w; 638 } 639 } 640 if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) { 641 if (src1w <= SIMM_MAX && src1w >= SIMM_MIN) { 642 flags |= SRC2_IMM; 643 src2_r = src1w; 644 645 /* And swap arguments. */ 646 src1 = src2; 647 src1w = src2w; 648 src2 = SLJIT_IMM; 649 /* src2w = src2_r unneeded. */ 650 } 651 } 652 } 653 654 /* Source 1. */ 655 if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3) 656 src1_r = src1; 657 else if (src1 & SLJIT_IMM) { 658 if (src1w) { 659 FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); 660 src1_r = TMP_REG1; 661 } 662 else 663 src1_r = 0; 664 } 665 else { 666 if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w)) 667 FAIL_IF(compiler->error); 668 else 669 flags |= SLOW_SRC1; 670 src1_r = TMP_REG1; 671 } 672 673 /* Source 2. */ 674 if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { 675 src2_r = src2; 676 flags |= REG2_SOURCE; 677 if (!(flags & REG_DEST) && GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) 678 dst_r = src2_r; 679 } 680 else if (src2 & SLJIT_IMM) { 681 if (!(flags & SRC2_IMM)) { 682 if (src2w || (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI)) { 683 FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); 684 src2_r = sugg_src2_r; 685 } 686 else 687 src2_r = 0; 688 } 689 } 690 else { 691 if (getput_arg_fast(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w)) 692 FAIL_IF(compiler->error); 693 else 694 flags |= SLOW_SRC2; 695 src2_r = sugg_src2_r; 696 } 697 698 if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { 699 SLJIT_ASSERT(src2_r == TMP_REG2); 700 if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { 701 FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w)); 702 FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); 703 } 704 else { 705 FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); 706 FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); 707 } 708 } 709 else if (flags & SLOW_SRC1) 710 FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); 711 else if (flags & SLOW_SRC2) 712 FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); 713 714 FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); 715 716 if (dst & SLJIT_MEM) { 717 if (!(flags & SLOW_DEST)) { 718 getput_arg_fast(compiler, flags, dst_r, dst, dstw); 719 return compiler->error; 720 } 721 return getput_arg(compiler, flags, dst_r, dst, dstw, 0, 0); 722 } 723 724 return SLJIT_SUCCESS; 725 } 726 727 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) 728 { 729 CHECK_ERROR(); 730 check_sljit_emit_op0(compiler, op); 731 732 op = GET_OPCODE(op); 733 switch (op) { 734 case SLJIT_BREAKPOINT: 735 return push_inst(compiler, TA, UNMOVABLE_INS); 736 case SLJIT_NOP: 737 return push_inst(compiler, NOP, UNMOVABLE_INS); 738 case SLJIT_UMUL: 739 case SLJIT_SMUL: 740 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 741 FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? UMUL : SMUL) | D(SLJIT_TEMPORARY_REG1) | S1(SLJIT_TEMPORARY_REG1) | S2(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG1))); 742 return push_inst(compiler, RDY | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2)); 743 #else 744 #error "Implementation required" 745 #endif 746 case SLJIT_UDIV: 747 case SLJIT_SDIV: 748 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 749 if (op == SLJIT_UDIV) 750 FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS)); 751 else { 752 FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_TEMPORARY_REG1) | IMM(31), DR(TMP_REG1))); 753 FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS)); 754 } 755 FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_TEMPORARY_REG1), DR(TMP_REG2))); 756 FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? UDIV : SDIV) | D(SLJIT_TEMPORARY_REG1) | S1(SLJIT_TEMPORARY_REG1) | S2(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG1))); 757 FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_TEMPORARY_REG2) | S1(SLJIT_TEMPORARY_REG1) | S2(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2))); 758 FAIL_IF(push_inst(compiler, SUB | D(SLJIT_TEMPORARY_REG2) | S1(TMP_REG2) | S2(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2))); 759 return SLJIT_SUCCESS; 760 #else 761 #error "Implementation required" 762 #endif 763 } 764 765 return SLJIT_SUCCESS; 766 } 767 768 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, 769 int dst, sljit_w dstw, 770 int src, sljit_w srcw) 771 { 772 int flags = GET_FLAGS(op) ? SET_FLAGS : 0; 773 774 CHECK_ERROR(); 775 check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); 776 ADJUST_LOCAL_OFFSET(dst, dstw); 777 ADJUST_LOCAL_OFFSET(src, srcw); 778 779 SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset); 780 781 op = GET_OPCODE(op); 782 switch (op) { 783 case SLJIT_MOV: 784 return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); 785 786 case SLJIT_MOV_UI: 787 return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); 788 789 case SLJIT_MOV_SI: 790 return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); 791 792 case SLJIT_MOV_UB: 793 return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); 794 795 case SLJIT_MOV_SB: 796 return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); 797 798 case SLJIT_MOV_UH: 799 return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); 800 801 case SLJIT_MOV_SH: 802 return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); 803 804 case SLJIT_MOVU: 805 return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); 806 807 case SLJIT_MOVU_UI: 808 return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); 809 810 case SLJIT_MOVU_SI: 811 return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); 812 813 case SLJIT_MOVU_UB: 814 return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); 815 816 case SLJIT_MOVU_SB: 817 return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); 818 819 case SLJIT_MOVU_UH: 820 return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); 821 822 case SLJIT_MOVU_SH: 823 return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); 824 825 case SLJIT_NOT: 826 case SLJIT_CLZ: 827 return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); 828 829 case SLJIT_NEG: 830 return emit_op(compiler, SLJIT_SUB, flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); 831 } 832 833 return SLJIT_SUCCESS; 834 } 835 836 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, 837 int dst, sljit_w dstw, 838 int src1, sljit_w src1w, 839 int src2, sljit_w src2w) 840 { 841 int flags = GET_FLAGS(op) ? SET_FLAGS : 0; 842 843 CHECK_ERROR(); 844 check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); 845 ADJUST_LOCAL_OFFSET(dst, dstw); 846 ADJUST_LOCAL_OFFSET(src1, src1w); 847 ADJUST_LOCAL_OFFSET(src2, src2w); 848 849 op = GET_OPCODE(op); 850 switch (op) { 851 case SLJIT_ADD: 852 case SLJIT_ADDC: 853 case SLJIT_MUL: 854 case SLJIT_AND: 855 case SLJIT_OR: 856 case SLJIT_XOR: 857 return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); 858 859 case SLJIT_SUB: 860 case SLJIT_SUBC: 861 return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); 862 863 case SLJIT_SHL: 864 case SLJIT_LSHR: 865 case SLJIT_ASHR: 866 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 867 if (src2 & SLJIT_IMM) 868 src2w &= 0x1f; 869 #else 870 SLJIT_ASSERT_STOP(); 871 #endif 872 return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); 873 } 874 875 return SLJIT_SUCCESS; 876 } 877 878 SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) 879 { 880 check_sljit_get_register_index(reg); 881 return reg_map[reg]; 882 } 883 884 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, 885 void *instruction, int size) 886 { 887 CHECK_ERROR(); 888 check_sljit_emit_op_custom(compiler, instruction, size); 889 SLJIT_ASSERT(size == 4); 890 891 return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS); 892 } 893 894 /* --------------------------------------------------------------------- */ 895 /* Floating point operators */ 896 /* --------------------------------------------------------------------- */ 897 898 SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) 899 { 900 return 1; 901 } 902 903 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, 904 int dst, sljit_w dstw, 905 int src, sljit_w srcw) 906 { 907 int dst_fr; 908 909 CHECK_ERROR(); 910 check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); 911 912 compiler->cache_arg = 0; 913 compiler->cache_argw = 0; 914 915 if (GET_OPCODE(op) == SLJIT_FCMP) { 916 if (dst > SLJIT_FLOAT_REG4) { 917 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw)); 918 dst = TMP_FREG1; 919 } 920 else 921 dst <<= 1; 922 923 if (src > SLJIT_FLOAT_REG4) { 924 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0)); 925 src = TMP_FREG2; 926 } 927 else 928 src <<= 1; 929 930 return push_inst(compiler, FCMPD | S1A(dst) | S2A(src), FCC_IS_SET | MOVABLE_INS); 931 } 932 933 dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : (dst << 1); 934 935 if (src > SLJIT_FLOAT_REG4) { 936 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, dst_fr, src, srcw, dst, dstw)); 937 src = dst_fr; 938 } 939 else 940 src <<= 1; 941 942 switch (op) { 943 case SLJIT_FMOV: 944 if (src != dst_fr && dst_fr != TMP_FREG1) { 945 FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr) | S2A(src), MOVABLE_INS)); 946 FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr | 1) | S2A(src | 1), MOVABLE_INS)); 947 } 948 break; 949 case SLJIT_FNEG: 950 FAIL_IF(push_inst(compiler, FNEGS | DA(dst_fr) | S2A(src), MOVABLE_INS)); 951 if (dst_fr != src) 952 FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr | 1) | S2A(src | 1), MOVABLE_INS)); 953 break; 954 case SLJIT_FABS: 955 FAIL_IF(push_inst(compiler, FABSS | DA(dst_fr) | S2A(src), MOVABLE_INS)); 956 if (dst_fr != src) 957 FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr | 1) | S2A(src | 1), MOVABLE_INS)); 958 break; 959 } 960 961 if (dst_fr == TMP_FREG1) { 962 if (op == SLJIT_FMOV) 963 dst_fr = src; 964 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, dst_fr, dst, dstw, 0, 0)); 965 } 966 967 return SLJIT_SUCCESS; 968 } 969 970 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, 971 int dst, sljit_w dstw, 972 int src1, sljit_w src1w, 973 int src2, sljit_w src2w) 974 { 975 int dst_fr, flags = 0; 976 977 CHECK_ERROR(); 978 check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); 979 980 compiler->cache_arg = 0; 981 compiler->cache_argw = 0; 982 983 dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG2 : (dst << 1); 984 985 if (src1 > SLJIT_FLOAT_REG4) { 986 if (getput_arg_fast(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src1, src1w)) { 987 FAIL_IF(compiler->error); 988 src1 = TMP_FREG1; 989 } else 990 flags |= SLOW_SRC1; 991 } 992 else 993 src1 <<= 1; 994 995 if (src2 > SLJIT_FLOAT_REG4) { 996 if (getput_arg_fast(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, src2, src2w)) { 997 FAIL_IF(compiler->error); 998 src2 = TMP_FREG2; 999 } else 1000 flags |= SLOW_SRC2; 1001 } 1002 else 1003 src2 <<= 1; 1004 1005 if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { 1006 if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { 1007 FAIL_IF(getput_arg(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w)); 1008 FAIL_IF(getput_arg(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); 1009 } 1010 else { 1011 FAIL_IF(getput_arg(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); 1012 FAIL_IF(getput_arg(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); 1013 } 1014 } 1015 else if (flags & SLOW_SRC1) 1016 FAIL_IF(getput_arg(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); 1017 else if (flags & SLOW_SRC2) 1018 FAIL_IF(getput_arg(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); 1019 1020 if (flags & SLOW_SRC1) 1021 src1 = TMP_FREG1; 1022 if (flags & SLOW_SRC2) 1023 src2 = TMP_FREG2; 1024 1025 switch (op) { 1026 case SLJIT_FADD: 1027 FAIL_IF(push_inst(compiler, FADDD | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS)); 1028 break; 1029 1030 case SLJIT_FSUB: 1031 FAIL_IF(push_inst(compiler, FSUBD | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS)); 1032 break; 1033 1034 case SLJIT_FMUL: 1035 FAIL_IF(push_inst(compiler, FMULD | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS)); 1036 break; 1037 1038 case SLJIT_FDIV: 1039 FAIL_IF(push_inst(compiler, FDIVD | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS)); 1040 break; 1041 } 1042 1043 if (dst_fr == TMP_FREG2) 1044 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG2, dst, dstw, 0, 0)); 1045 1046 return SLJIT_SUCCESS; 1047 } 1048 1049 /* --------------------------------------------------------------------- */ 1050 /* Other instructions */ 1051 /* --------------------------------------------------------------------- */ 1052 1053 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) 1054 { 1055 CHECK_ERROR(); 1056 check_sljit_emit_fast_enter(compiler, dst, dstw); 1057 ADJUST_LOCAL_OFFSET(dst, dstw); 1058 1059 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) 1060 return push_inst(compiler, OR | D(dst) | S1(0) | S2(LINK_REG), DR(dst)); 1061 else if (dst & SLJIT_MEM) 1062 return emit_op_mem(compiler, WORD_DATA, LINK_REG, dst, dstw); 1063 1064 /* SLJIT_UNUSED is also possible, although highly unlikely. */ 1065 return SLJIT_SUCCESS; 1066 } 1067 1068 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) 1069 { 1070 CHECK_ERROR(); 1071 check_sljit_emit_fast_return(compiler, src, srcw); 1072 ADJUST_LOCAL_OFFSET(src, srcw); 1073 1074 if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) 1075 FAIL_IF(push_inst(compiler, OR | D(LINK_REG) | S1(0) | S2(src), DR(LINK_REG))); 1076 else if (src & SLJIT_MEM) 1077 FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, LINK_REG, src, srcw)); 1078 else if (src & SLJIT_IMM) 1079 FAIL_IF(load_immediate(compiler, LINK_REG, srcw)); 1080 1081 FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(LINK_REG) | IMM(8), UNMOVABLE_INS)); 1082 return push_inst(compiler, NOP, UNMOVABLE_INS); 1083 } 1084 1085 /* --------------------------------------------------------------------- */ 1086 /* Conditional instructions */ 1087 /* --------------------------------------------------------------------- */ 1088 1089 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) 1090 { 1091 struct sljit_label *label; 1092 1093 CHECK_ERROR_PTR(); 1094 check_sljit_emit_label(compiler); 1095 1096 if (compiler->last_label && compiler->last_label->size == compiler->size) 1097 return compiler->last_label; 1098 1099 label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); 1100 PTR_FAIL_IF(!label); 1101 set_label(label, compiler); 1102 compiler->delay_slot = UNMOVABLE_INS; 1103 return label; 1104 } 1105 1106 static sljit_ins get_cc(int type) 1107 { 1108 switch (type) { 1109 case SLJIT_C_EQUAL: 1110 case SLJIT_C_MUL_NOT_OVERFLOW: 1111 return DA(0x1); 1112 1113 case SLJIT_C_NOT_EQUAL: 1114 case SLJIT_C_MUL_OVERFLOW: 1115 return DA(0x9); 1116 1117 case SLJIT_C_LESS: 1118 return DA(0x5); 1119 1120 case SLJIT_C_GREATER_EQUAL: 1121 return DA(0xd); 1122 1123 case SLJIT_C_GREATER: 1124 return DA(0xc); 1125 1126 case SLJIT_C_LESS_EQUAL: 1127 return DA(0x4); 1128 1129 case SLJIT_C_SIG_LESS: 1130 return DA(0x3); 1131 1132 case SLJIT_C_SIG_GREATER_EQUAL: 1133 return DA(0xb); 1134 1135 case SLJIT_C_SIG_GREATER: 1136 return DA(0xa); 1137 1138 case SLJIT_C_SIG_LESS_EQUAL: 1139 return DA(0x2); 1140 1141 case SLJIT_C_OVERFLOW: 1142 return DA(0x7); 1143 1144 case SLJIT_C_NOT_OVERFLOW: 1145 return DA(0xf); 1146 1147 case SLJIT_C_FLOAT_EQUAL: 1148 return DA(0x9); 1149 1150 case SLJIT_C_FLOAT_NOT_EQUAL: /* Unordered. */ 1151 return DA(0x1); 1152 1153 case SLJIT_C_FLOAT_LESS: 1154 return DA(0x4); 1155 1156 case SLJIT_C_FLOAT_GREATER_EQUAL: /* Unordered. */ 1157 return DA(0xc); 1158 1159 case SLJIT_C_FLOAT_LESS_EQUAL: 1160 return DA(0xd); 1161 1162 case SLJIT_C_FLOAT_GREATER: /* Unordered. */ 1163 return DA(0x5); 1164 1165 case SLJIT_C_FLOAT_UNORDERED: 1166 return DA(0x7); 1167 1168 case SLJIT_C_FLOAT_ORDERED: 1169 return DA(0xf); 1170 1171 default: 1172 SLJIT_ASSERT_STOP(); 1173 return DA(0x8); 1174 } 1175 } 1176 1177 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) 1178 { 1179 struct sljit_jump *jump; 1180 1181 CHECK_ERROR_PTR(); 1182 check_sljit_emit_jump(compiler, type); 1183 1184 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); 1185 PTR_FAIL_IF(!jump); 1186 set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); 1187 type &= 0xff; 1188 1189 if (type < SLJIT_C_FLOAT_EQUAL) { 1190 jump->flags |= IS_COND; 1191 if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET)) 1192 jump->flags |= IS_MOVABLE; 1193 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 1194 PTR_FAIL_IF(push_inst(compiler, BICC | get_cc(type ^ 1) | 5, UNMOVABLE_INS)); 1195 #else 1196 #error "Implementation required" 1197 #endif 1198 } 1199 else if (type < SLJIT_JUMP) { 1200 jump->flags |= IS_COND; 1201 if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & FCC_IS_SET)) 1202 jump->flags |= IS_MOVABLE; 1203 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 1204 PTR_FAIL_IF(push_inst(compiler, FBFCC | get_cc(type ^ 1) | 5, UNMOVABLE_INS)); 1205 #else 1206 #error "Implementation required" 1207 #endif 1208 } else { 1209 if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) 1210 jump->flags |= IS_MOVABLE; 1211 if (type >= SLJIT_FAST_CALL) 1212 jump->flags |= IS_CALL; 1213 } 1214 1215 PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); 1216 PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? LINK_REG : 0) | S1(TMP_REG2) | IMM(0), UNMOVABLE_INS)); 1217 jump->addr = compiler->size; 1218 PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); 1219 1220 return jump; 1221 } 1222 1223 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) 1224 { 1225 struct sljit_jump *jump = NULL; 1226 int src_r; 1227 1228 CHECK_ERROR(); 1229 check_sljit_emit_ijump(compiler, type, src, srcw); 1230 ADJUST_LOCAL_OFFSET(src, srcw); 1231 1232 if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) 1233 src_r = src; 1234 else if (src & SLJIT_IMM) { 1235 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); 1236 FAIL_IF(!jump); 1237 set_jump(jump, compiler, JUMP_ADDR); 1238 jump->u.target = srcw; 1239 if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) 1240 jump->flags |= IS_MOVABLE; 1241 if (type >= SLJIT_FAST_CALL) 1242 jump->flags |= IS_CALL; 1243 1244 FAIL_IF(emit_const(compiler, TMP_REG2, 0)); 1245 src_r = TMP_REG2; 1246 } 1247 else { 1248 FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw)); 1249 src_r = TMP_REG2; 1250 } 1251 1252 FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? LINK_REG : 0) | S1(src_r) | IMM(0), UNMOVABLE_INS)); 1253 if (jump) 1254 jump->addr = compiler->size; 1255 return push_inst(compiler, NOP, UNMOVABLE_INS); 1256 } 1257 1258 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) 1259 { 1260 int reg; 1261 1262 CHECK_ERROR(); 1263 check_sljit_emit_cond_value(compiler, op, dst, dstw, type); 1264 ADJUST_LOCAL_OFFSET(dst, dstw); 1265 1266 if (dst == SLJIT_UNUSED) 1267 return SLJIT_SUCCESS; 1268 1269 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 1270 reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; 1271 1272 if (type < SLJIT_C_FLOAT_EQUAL) 1273 FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS)); 1274 else 1275 FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS)); 1276 1277 FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(1), UNMOVABLE_INS)); 1278 FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(0), UNMOVABLE_INS)); 1279 1280 if (GET_OPCODE(op) == SLJIT_OR) 1281 return emit_op(compiler, SLJIT_OR, (GET_FLAGS(op) ? SET_FLAGS : 0) | CUMULATIVE_OP | IMM_OP, dst, dstw, dst, dstw, TMP_REG2, 0); 1282 1283 return (reg == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; 1284 #else 1285 #error "Implementation required" 1286 #endif 1287 } 1288 1289 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) 1290 { 1291 int reg; 1292 struct sljit_const *const_; 1293 1294 CHECK_ERROR_PTR(); 1295 check_sljit_emit_const(compiler, dst, dstw, init_value); 1296 ADJUST_LOCAL_OFFSET(dst, dstw); 1297 1298 const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); 1299 PTR_FAIL_IF(!const_); 1300 set_const(const_, compiler); 1301 1302 reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; 1303 1304 PTR_FAIL_IF(emit_const(compiler, reg, init_value)); 1305 1306 if (dst & SLJIT_MEM) 1307 PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw)); 1308 1309 return const_; 1310 } 1311