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 "MIPS" SLJIT_CPUINFO; 30 } 31 32 /* Latest MIPS architecture. */ 33 /* Detect SLJIT_MIPS_32_64 */ 34 35 /* Length of an instruction word 36 Both for mips-32 and mips-64 */ 37 typedef sljit_ui sljit_ins; 38 39 #define TMP_REG1 (SLJIT_NO_REGISTERS + 1) 40 #define TMP_REG2 (SLJIT_NO_REGISTERS + 2) 41 #define TMP_REG3 (SLJIT_NO_REGISTERS + 3) 42 43 /* For position independent code, t9 must contain the function address. */ 44 #define PIC_ADDR_REG TMP_REG2 45 46 /* TMP_EREG1 is used mainly for literal encoding on 64 bit. */ 47 #define TMP_EREG1 15 48 #define TMP_EREG2 24 49 /* Floating point status register. */ 50 #define FCSR_REG 31 51 /* Return address register. */ 52 #define RETURN_ADDR_REG 31 53 54 /* Flags are keept in volatile registers. */ 55 #define EQUAL_FLAG 7 56 /* And carry flag as well. */ 57 #define ULESS_FLAG 10 58 #define UGREATER_FLAG 11 59 #define LESS_FLAG 12 60 #define GREATER_FLAG 13 61 #define OVERFLOW_FLAG 14 62 63 #define TMP_FREG1 ((SLJIT_FLOAT_REG4 + 1) << 1) 64 #define TMP_FREG2 ((SLJIT_FLOAT_REG4 + 2) << 1) 65 66 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { 67 0, 2, 5, 6, 3, 8, 16, 17, 18, 19, 20, 29, 4, 25, 9 68 }; 69 70 /* --------------------------------------------------------------------- */ 71 /* Instrucion forms */ 72 /* --------------------------------------------------------------------- */ 73 74 #define S(s) (reg_map[s] << 21) 75 #define T(t) (reg_map[t] << 16) 76 #define D(d) (reg_map[d] << 11) 77 /* Absolute registers. */ 78 #define SA(s) ((s) << 21) 79 #define TA(t) ((t) << 16) 80 #define DA(d) ((d) << 11) 81 #define FT(t) ((t) << 16) 82 #define FS(s) ((s) << 11) 83 #define FD(d) ((d) << 6) 84 #define IMM(imm) ((imm) & 0xffff) 85 #define SH_IMM(imm) ((imm & 0x1f) << 6) 86 87 #define DR(dr) (reg_map[dr]) 88 #define HI(opcode) ((opcode) << 26) 89 #define LO(opcode) (opcode) 90 #define FMT_D (17 << 21) 91 92 #define ABS_D (HI(17) | FMT_D | LO(5)) 93 #define ADD_D (HI(17) | FMT_D | LO(0)) 94 #define ADDU (HI(0) | LO(33)) 95 #define ADDIU (HI(9)) 96 #define AND (HI(0) | LO(36)) 97 #define ANDI (HI(12)) 98 #define B (HI(4)) 99 #define BAL (HI(1) | (17 << 16)) 100 #define BC1F (HI(17) | (8 << 21)) 101 #define BC1T (HI(17) | (8 << 21) | (1 << 16)) 102 #define BEQ (HI(4)) 103 #define BGEZ (HI(1) | (1 << 16)) 104 #define BGTZ (HI(7)) 105 #define BLEZ (HI(6)) 106 #define BLTZ (HI(1) | (0 << 16)) 107 #define BNE (HI(5)) 108 #define BREAK (HI(0) | LO(13)) 109 #define C_UN_D (HI(17) | FMT_D | LO(49)) 110 #define C_UEQ_D (HI(17) | FMT_D | LO(51)) 111 #define C_ULE_D (HI(17) | FMT_D | LO(55)) 112 #define C_ULT_D (HI(17) | FMT_D | LO(53)) 113 #define DIV (HI(0) | LO(26)) 114 #define DIVU (HI(0) | LO(27)) 115 #define DIV_D (HI(17) | FMT_D | LO(3)) 116 #define J (HI(2)) 117 #define JAL (HI(3)) 118 #define JALR (HI(0) | LO(9)) 119 #define JR (HI(0) | LO(8)) 120 #define LD (HI(55)) 121 #define LUI (HI(15)) 122 #define LW (HI(35)) 123 #define NEG_D (HI(17) | FMT_D | LO(7)) 124 #define MFHI (HI(0) | LO(16)) 125 #define MFLO (HI(0) | LO(18)) 126 #define MOV_D (HI(17) | FMT_D | LO(6)) 127 #define CFC1 (HI(17) | (2 << 21)) 128 #define MOVN (HI(0) | LO(11)) 129 #define MOVZ (HI(0) | LO(10)) 130 #define MUL_D (HI(17) | FMT_D | LO(2)) 131 #define MULT (HI(0) | LO(24)) 132 #define MULTU (HI(0) | LO(25)) 133 #define NOP (HI(0) | LO(0)) 134 #define NOR (HI(0) | LO(39)) 135 #define OR (HI(0) | LO(37)) 136 #define ORI (HI(13)) 137 #define SD (HI(63)) 138 #define SLT (HI(0) | LO(42)) 139 #define SLTI (HI(10)) 140 #define SLTIU (HI(11)) 141 #define SLTU (HI(0) | LO(43)) 142 #define SLL (HI(0) | LO(0)) 143 #define SLLV (HI(0) | LO(4)) 144 #define SRL (HI(0) | LO(2)) 145 #define SRLV (HI(0) | LO(6)) 146 #define SRA (HI(0) | LO(3)) 147 #define SRAV (HI(0) | LO(7)) 148 #define SUB_D (HI(17) | FMT_D | LO(1)) 149 #define SUBU (HI(0) | LO(35)) 150 #define SW (HI(43)) 151 #define XOR (HI(0) | LO(38)) 152 #define XORI (HI(14)) 153 154 #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) 155 #define CLZ (HI(28) | LO(32)) 156 #define MUL (HI(28) | LO(2)) 157 #define SEB (HI(31) | (16 << 6) | LO(32)) 158 #define SEH (HI(31) | (24 << 6) | LO(32)) 159 #endif 160 161 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) 162 #define ADDU_W ADDU 163 #define ADDIU_W ADDIU 164 #define SLL_W SLL 165 #define SUBU_W SUBU 166 #else 167 #define ADDU_W DADDU 168 #define ADDIU_W DADDIU 169 #define SLL_W DSLL 170 #define SUBU_W DSUBU 171 #endif 172 173 #define SIMM_MAX (0x7fff) 174 #define SIMM_MIN (-0x8000) 175 #define UIMM_MAX (0xffff) 176 177 /* dest_reg is the absolute name of the register 178 Useful for reordering instructions in the delay slot. */ 179 static int push_inst(struct sljit_compiler *compiler, sljit_ins ins, int delay_slot) 180 { 181 SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS 182 || delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f)); 183 sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); 184 FAIL_IF(!ptr); 185 *ptr = ins; 186 compiler->size++; 187 compiler->delay_slot = delay_slot; 188 return SLJIT_SUCCESS; 189 } 190 191 static SLJIT_INLINE sljit_ins invert_branch(int flags) 192 { 193 return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16); 194 } 195 196 static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) 197 { 198 sljit_w diff; 199 sljit_uw target_addr; 200 sljit_ins *inst; 201 sljit_ins saved_inst; 202 203 if (jump->flags & SLJIT_REWRITABLE_JUMP) 204 return code_ptr; 205 206 if (jump->flags & JUMP_ADDR) 207 target_addr = jump->u.target; 208 else { 209 SLJIT_ASSERT(jump->flags & JUMP_LABEL); 210 target_addr = (sljit_uw)(code + jump->u.label->size); 211 } 212 inst = (sljit_ins*)jump->addr; 213 if (jump->flags & IS_COND) 214 inst--; 215 216 /* B instructions. */ 217 if (jump->flags & IS_MOVABLE) { 218 diff = ((sljit_w)target_addr - (sljit_w)(inst)) >> 2; 219 if (diff <= SIMM_MAX && diff >= SIMM_MIN) { 220 jump->flags |= PATCH_B; 221 222 if (!(jump->flags & IS_COND)) { 223 inst[0] = inst[-1]; 224 inst[-1] = (jump->flags & IS_JAL) ? BAL : B; 225 jump->addr -= sizeof(sljit_ins); 226 return inst; 227 } 228 saved_inst = inst[0]; 229 inst[0] = inst[-1]; 230 inst[-1] = saved_inst ^ invert_branch(jump->flags); 231 jump->addr -= 2 * sizeof(sljit_ins); 232 return inst; 233 } 234 } 235 236 diff = ((sljit_w)target_addr - (sljit_w)(inst + 1)) >> 2; 237 if (diff <= SIMM_MAX && diff >= SIMM_MIN) { 238 jump->flags |= PATCH_B; 239 240 if (!(jump->flags & IS_COND)) { 241 inst[0] = (jump->flags & IS_JAL) ? BAL : B; 242 inst[1] = NOP; 243 return inst + 1; 244 } 245 inst[0] = inst[0] ^ invert_branch(jump->flags); 246 inst[1] = NOP; 247 jump->addr -= sizeof(sljit_ins); 248 return inst + 1; 249 } 250 251 if (jump->flags & IS_COND) { 252 if ((target_addr & ~0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~0xfffffff)) { 253 jump->flags |= PATCH_J; 254 inst[0] = (inst[0] & 0xffff0000) | 3; 255 inst[1] = NOP; 256 inst[2] = J; 257 inst[3] = NOP; 258 jump->addr += sizeof(sljit_ins); 259 return inst + 3; 260 } 261 return code_ptr; 262 } 263 264 /* J instuctions. */ 265 if (jump->flags & IS_MOVABLE) { 266 if ((target_addr & ~0xfffffff) == (jump->addr & ~0xfffffff)) { 267 jump->flags |= PATCH_J; 268 inst[0] = inst[-1]; 269 inst[-1] = (jump->flags & IS_JAL) ? JAL : J; 270 jump->addr -= sizeof(sljit_ins); 271 return inst; 272 } 273 } 274 275 if ((target_addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)) { 276 jump->flags |= PATCH_J; 277 inst[0] = (jump->flags & IS_JAL) ? JAL : J; 278 inst[1] = NOP; 279 return inst + 1; 280 } 281 282 return code_ptr; 283 } 284 285 #ifdef __GNUC__ 286 static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr) 287 { 288 SLJIT_CACHE_FLUSH(code, code_ptr); 289 } 290 #endif 291 292 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) 293 { 294 struct sljit_memory_fragment *buf; 295 sljit_ins *code; 296 sljit_ins *code_ptr; 297 sljit_ins *buf_ptr; 298 sljit_ins *buf_end; 299 sljit_uw word_count; 300 sljit_uw addr; 301 302 struct sljit_label *label; 303 struct sljit_jump *jump; 304 struct sljit_const *const_; 305 306 CHECK_ERROR_PTR(); 307 check_sljit_generate_code(compiler); 308 reverse_buf(compiler); 309 310 code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); 311 PTR_FAIL_WITH_EXEC_IF(code); 312 buf = compiler->buf; 313 314 code_ptr = code; 315 word_count = 0; 316 label = compiler->labels; 317 jump = compiler->jumps; 318 const_ = compiler->consts; 319 do { 320 buf_ptr = (sljit_ins*)buf->memory; 321 buf_end = buf_ptr + (buf->used_size >> 2); 322 do { 323 *code_ptr = *buf_ptr++; 324 SLJIT_ASSERT(!label || label->size >= word_count); 325 SLJIT_ASSERT(!jump || jump->addr >= word_count); 326 SLJIT_ASSERT(!const_ || const_->addr >= word_count); 327 /* These structures are ordered by their address. */ 328 if (label && label->size == word_count) { 329 /* Just recording the address. */ 330 label->addr = (sljit_uw)code_ptr; 331 label->size = code_ptr - code; 332 label = label->next; 333 } 334 if (jump && jump->addr == word_count) { 335 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) 336 jump->addr = (sljit_uw)(code_ptr - 3); 337 #else 338 #error "Implementation required" 339 #endif 340 code_ptr = optimize_jump(jump, code_ptr, code); 341 jump = jump->next; 342 } 343 if (const_ && const_->addr == word_count) { 344 /* Just recording the address. */ 345 const_->addr = (sljit_uw)code_ptr; 346 const_ = const_->next; 347 } 348 code_ptr ++; 349 word_count ++; 350 } while (buf_ptr < buf_end); 351 352 buf = buf->next; 353 } while (buf); 354 355 if (label && label->size == word_count) { 356 label->addr = (sljit_uw)code_ptr; 357 label->size = code_ptr - code; 358 label = label->next; 359 } 360 361 SLJIT_ASSERT(!label); 362 SLJIT_ASSERT(!jump); 363 SLJIT_ASSERT(!const_); 364 SLJIT_ASSERT(code_ptr - code <= (int)compiler->size); 365 366 jump = compiler->jumps; 367 while (jump) { 368 do { 369 addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; 370 buf_ptr = (sljit_ins*)jump->addr; 371 372 if (jump->flags & PATCH_B) { 373 addr = (sljit_w)(addr - (jump->addr + sizeof(sljit_ins))) >> 2; 374 SLJIT_ASSERT((sljit_w)addr <= SIMM_MAX && (sljit_w)addr >= SIMM_MIN); 375 buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff); 376 break; 377 } 378 if (jump->flags & PATCH_J) { 379 SLJIT_ASSERT((addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)); 380 buf_ptr[0] |= (addr >> 2) & 0x03ffffff; 381 break; 382 } 383 384 /* Set the fields of immediate loads. */ 385 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) 386 buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); 387 buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); 388 #else 389 #error "Implementation required" 390 #endif 391 } while (0); 392 jump = jump->next; 393 } 394 395 compiler->error = SLJIT_ERR_COMPILED; 396 compiler->executable_size = compiler->size * sizeof(sljit_ins); 397 #ifndef __GNUC__ 398 SLJIT_CACHE_FLUSH(code, code_ptr); 399 #else 400 /* GCC workaround for invalid code generation with -O2. */ 401 sljit_cache_flush(code, code_ptr); 402 #endif 403 return code; 404 } 405 406 /* --------------------------------------------------------------------- */ 407 /* Entry, exit */ 408 /* --------------------------------------------------------------------- */ 409 410 /* Creates an index in data_transfer_insts array. */ 411 #define LOAD_DATA 0x01 412 #define WORD_DATA 0x00 413 #define BYTE_DATA 0x02 414 #define HALF_DATA 0x04 415 #define INT_DATA 0x06 416 #define SIGNED_DATA 0x08 417 /* Separates integer and floating point registers */ 418 #define GPR_REG 0x0f 419 #define DOUBLE_DATA 0x10 420 421 #define MEM_MASK 0x1f 422 423 #define WRITE_BACK 0x00020 424 #define ARG_TEST 0x00040 425 #define CUMULATIVE_OP 0x00080 426 #define LOGICAL_OP 0x00100 427 #define IMM_OP 0x00200 428 #define SRC2_IMM 0x00400 429 430 #define UNUSED_DEST 0x00800 431 #define REG_DEST 0x01000 432 #define REG1_SOURCE 0x02000 433 #define REG2_SOURCE 0x04000 434 #define SLOW_SRC1 0x08000 435 #define SLOW_SRC2 0x10000 436 #define SLOW_DEST 0x20000 437 438 /* Only these flags are set. UNUSED_DEST is not set when no flags should be set. */ 439 #define CHECK_FLAGS(list) \ 440 (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list)))) 441 442 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) 443 #define STACK_STORE SW 444 #define STACK_LOAD LW 445 #else 446 #define STACK_STORE SD 447 #define STACK_LOAD LD 448 #endif 449 450 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) 451 #include "sljitNativeMIPS_32.c" 452 #else 453 #include "sljitNativeMIPS_64.c" 454 #endif 455 456 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) 457 { 458 sljit_ins base; 459 460 CHECK_ERROR(); 461 check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); 462 463 compiler->temporaries = temporaries; 464 compiler->saveds = saveds; 465 #if (defined SLJIT_DEBUG && SLJIT_DEBUG) 466 compiler->logical_local_size = local_size; 467 #endif 468 469 local_size += (saveds + 1 + 4) * sizeof(sljit_w); 470 local_size = (local_size + 15) & ~0xf; 471 compiler->local_size = local_size; 472 473 if (local_size <= SIMM_MAX) { 474 /* Frequent case. */ 475 FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_LOCALS_REG) | T(SLJIT_LOCALS_REG) | IMM(-local_size), DR(SLJIT_LOCALS_REG))); 476 base = S(SLJIT_LOCALS_REG); 477 } 478 else { 479 FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size)); 480 FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_LOCALS_REG) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); 481 FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_LOCALS_REG) | T(TMP_REG1) | D(SLJIT_LOCALS_REG), DR(SLJIT_LOCALS_REG))); 482 base = S(TMP_REG2); 483 local_size = 0; 484 } 485 486 FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), MOVABLE_INS)); 487 if (saveds >= 1) 488 FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 2 * (int)sizeof(sljit_w)), MOVABLE_INS)); 489 if (saveds >= 2) 490 FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 3 * (int)sizeof(sljit_w)), MOVABLE_INS)); 491 if (saveds >= 3) 492 FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 4 * (int)sizeof(sljit_w)), MOVABLE_INS)); 493 if (saveds >= 4) 494 FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 5 * (int)sizeof(sljit_w)), MOVABLE_INS)); 495 if (saveds >= 5) 496 FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 6 * (int)sizeof(sljit_w)), MOVABLE_INS)); 497 498 if (args >= 1) 499 FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_SAVED_REG1), DR(SLJIT_SAVED_REG1))); 500 if (args >= 2) 501 FAIL_IF(push_inst(compiler, ADDU_W | SA(5) | TA(0) | D(SLJIT_SAVED_REG2), DR(SLJIT_SAVED_REG2))); 502 if (args >= 3) 503 FAIL_IF(push_inst(compiler, ADDU_W | SA(6) | TA(0) | D(SLJIT_SAVED_REG3), DR(SLJIT_SAVED_REG3))); 504 505 return SLJIT_SUCCESS; 506 } 507 508 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) 509 { 510 CHECK_ERROR_VOID(); 511 check_sljit_set_context(compiler, args, temporaries, saveds, local_size); 512 513 compiler->temporaries = temporaries; 514 compiler->saveds = saveds; 515 #if (defined SLJIT_DEBUG && SLJIT_DEBUG) 516 compiler->logical_local_size = local_size; 517 #endif 518 519 local_size += (saveds + 1 + 4) * sizeof(sljit_w); 520 compiler->local_size = (local_size + 15) & ~0xf; 521 } 522 523 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) 524 { 525 int local_size; 526 sljit_ins base; 527 528 CHECK_ERROR(); 529 check_sljit_emit_return(compiler, op, src, srcw); 530 531 FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); 532 533 local_size = compiler->local_size; 534 if (local_size <= SIMM_MAX) 535 base = S(SLJIT_LOCALS_REG); 536 else { 537 FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size)); 538 FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_LOCALS_REG) | T(TMP_REG1) | D(TMP_REG1), DR(TMP_REG1))); 539 base = S(TMP_REG1); 540 local_size = 0; 541 } 542 543 FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), RETURN_ADDR_REG)); 544 if (compiler->saveds >= 5) 545 FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 6 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG2))); 546 if (compiler->saveds >= 4) 547 FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 5 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG1))); 548 if (compiler->saveds >= 3) 549 FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 4 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG3))); 550 if (compiler->saveds >= 2) 551 FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 3 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG2))); 552 if (compiler->saveds >= 1) 553 FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 2 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG1))); 554 555 FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); 556 if (compiler->local_size <= SIMM_MAX) 557 return push_inst(compiler, ADDIU_W | S(SLJIT_LOCALS_REG) | T(SLJIT_LOCALS_REG) | IMM(compiler->local_size), UNMOVABLE_INS); 558 else 559 return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_LOCALS_REG), UNMOVABLE_INS); 560 } 561 562 #undef STACK_STORE 563 #undef STACK_LOAD 564 565 /* --------------------------------------------------------------------- */ 566 /* Operators */ 567 /* --------------------------------------------------------------------- */ 568 569 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) 570 #define ARCH_32_64(a, b) a 571 #else 572 #define ARCH_32_64(a, b) b 573 #endif 574 575 static SLJIT_CONST sljit_ins data_transfer_insts[16 + 2] = { 576 /* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */), 577 /* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */), 578 /* u b s */ HI(40) /* sb */, 579 /* u b l */ HI(36) /* lbu */, 580 /* u h s */ HI(41) /* sh */, 581 /* u h l */ HI(37) /* lhu */, 582 /* u i s */ HI(43) /* sw */, 583 /* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */), 584 585 /* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */), 586 /* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */), 587 /* s b s */ HI(40) /* sb */, 588 /* s b l */ HI(32) /* lb */, 589 /* s h s */ HI(41) /* sh */, 590 /* s h l */ HI(33) /* lh */, 591 /* s i s */ HI(43) /* sw */, 592 /* s i l */ HI(35) /* lw */, 593 594 /* d s */ HI(61) /* sdc1 */, 595 /* d l */ HI(53) /* ldc1 */, 596 }; 597 598 #undef ARCH_32_64 599 600 /* reg_ar is an absoulute register! */ 601 602 /* Can perform an operation using at most 1 instruction. */ 603 static int getput_arg_fast(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw) 604 { 605 SLJIT_ASSERT(arg & SLJIT_MEM); 606 607 if (!(flags & WRITE_BACK) && !(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) { 608 /* Works for both absoulte and relative addresses. */ 609 if (SLJIT_UNLIKELY(flags & ARG_TEST)) 610 return 1; 611 FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & 0xf) 612 | TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS)); 613 return -1; 614 } 615 return 0; 616 } 617 618 /* See getput_arg below. 619 Note: can_cache is called only for binary operators. Those 620 operators always uses word arguments without write back. */ 621 static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) 622 { 623 SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); 624 625 /* Simple operation except for updates. */ 626 if (arg & 0xf0) { 627 argw &= 0x3; 628 next_argw &= 0x3; 629 if (argw && argw == next_argw && (arg == next_arg || (arg & 0xf0) == (next_arg & 0xf0))) 630 return 1; 631 return 0; 632 } 633 634 if (arg == next_arg) { 635 if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)) 636 return 1; 637 return 0; 638 } 639 640 return 0; 641 } 642 643 /* Emit the necessary instructions. See can_cache above. */ 644 static int getput_arg(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw, int next_arg, sljit_w next_argw) 645 { 646 int tmp_ar, base, delay_slot; 647 648 SLJIT_ASSERT(arg & SLJIT_MEM); 649 if (!(next_arg & SLJIT_MEM)) { 650 next_arg = 0; 651 next_argw = 0; 652 } 653 654 if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) { 655 tmp_ar = reg_ar; 656 delay_slot = reg_ar; 657 } else { 658 tmp_ar = DR(TMP_REG1); 659 delay_slot = MOVABLE_INS; 660 } 661 base = arg & 0xf; 662 663 if (SLJIT_UNLIKELY(arg & 0xf0)) { 664 argw &= 0x3; 665 if ((flags & WRITE_BACK) && reg_ar == DR(base)) { 666 SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar); 667 FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); 668 reg_ar = DR(TMP_REG1); 669 } 670 671 /* Using the cache. */ 672 if (argw == compiler->cache_argw) { 673 if (!(flags & WRITE_BACK)) { 674 if (arg == compiler->cache_arg) 675 return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); 676 if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) { 677 if (arg == next_arg && argw == (next_argw & 0x3)) { 678 compiler->cache_arg = arg; 679 compiler->cache_argw = argw; 680 FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3))); 681 return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); 682 } 683 FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar)); 684 return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); 685 } 686 } 687 else { 688 if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) { 689 FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); 690 return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot); 691 } 692 } 693 } 694 695 if (SLJIT_UNLIKELY(argw)) { 696 compiler->cache_arg = SLJIT_MEM | (arg & 0xf0); 697 compiler->cache_argw = argw; 698 FAIL_IF(push_inst(compiler, SLL_W | T((arg >> 4) & 0xf) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3))); 699 } 700 701 if (!(flags & WRITE_BACK)) { 702 if (arg == next_arg && argw == (next_argw & 0x3)) { 703 compiler->cache_arg = arg; 704 compiler->cache_argw = argw; 705 FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3))); 706 tmp_ar = DR(TMP_REG3); 707 } 708 else 709 FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | DA(tmp_ar), tmp_ar)); 710 return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); 711 } 712 FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | D(base), DR(base))); 713 return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot); 714 } 715 716 if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) { 717 /* Update only applies if a base register exists. */ 718 if (reg_ar == DR(base)) { 719 SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar); 720 if (argw <= SIMM_MAX && argw >= SIMM_MIN) { 721 FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar) | IMM(argw), MOVABLE_INS)); 722 if (argw) 723 return push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base)); 724 return SLJIT_SUCCESS; 725 } 726 FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); 727 reg_ar = DR(TMP_REG1); 728 } 729 730 if (argw <= SIMM_MAX && argw >= SIMM_MIN) { 731 if (argw) 732 FAIL_IF(push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base))); 733 } 734 else { 735 if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { 736 if (argw != compiler->cache_argw) { 737 FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); 738 compiler->cache_argw = argw; 739 } 740 FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); 741 } 742 else { 743 compiler->cache_arg = SLJIT_MEM; 744 compiler->cache_argw = argw; 745 FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw)); 746 FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); 747 } 748 } 749 return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot); 750 } 751 752 if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { 753 if (argw != compiler->cache_argw) { 754 FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); 755 compiler->cache_argw = argw; 756 } 757 return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); 758 } 759 760 if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { 761 if (argw != compiler->cache_argw) 762 FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); 763 } 764 else { 765 compiler->cache_arg = SLJIT_MEM; 766 FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw)); 767 } 768 compiler->cache_argw = argw; 769 770 if (!base) 771 return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); 772 773 if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) { 774 compiler->cache_arg = arg; 775 FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3))); 776 return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); 777 } 778 779 FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar)); 780 return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); 781 } 782 783 static SLJIT_INLINE int emit_op_mem(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw) 784 { 785 if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) 786 return compiler->error; 787 compiler->cache_arg = 0; 788 compiler->cache_argw = 0; 789 return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); 790 } 791 792 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) 793 { 794 if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) 795 return compiler->error; 796 return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); 797 } 798 799 static int emit_op(struct sljit_compiler *compiler, int op, int flags, 800 int dst, sljit_w dstw, 801 int src1, sljit_w src1w, 802 int src2, sljit_w src2w) 803 { 804 /* arg1 goes to TMP_REG1 or src reg 805 arg2 goes to TMP_REG2, imm or src reg 806 TMP_REG3 can be used for caching 807 result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ 808 int dst_r = TMP_REG2; 809 int src1_r; 810 sljit_w src2_r = 0; 811 int sugg_src2_r = TMP_REG2; 812 813 compiler->cache_arg = 0; 814 compiler->cache_argw = 0; 815 816 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) { 817 dst_r = dst; 818 flags |= REG_DEST; 819 if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) 820 sugg_src2_r = dst_r; 821 } 822 else if (dst == SLJIT_UNUSED) { 823 if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) 824 return SLJIT_SUCCESS; 825 if (GET_FLAGS(op)) 826 flags |= UNUSED_DEST; 827 } 828 else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw)) 829 flags |= SLOW_DEST; 830 831 if (flags & IMM_OP) { 832 if ((src2 & SLJIT_IMM) && src2w) { 833 if ((!(flags & LOGICAL_OP) && (src2w <= SIMM_MAX && src2w >= SIMM_MIN)) 834 || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_MAX))) { 835 flags |= SRC2_IMM; 836 src2_r = src2w; 837 } 838 } 839 if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) { 840 if ((!(flags & LOGICAL_OP) && (src1w <= SIMM_MAX && src1w >= SIMM_MIN)) 841 || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_MAX))) { 842 flags |= SRC2_IMM; 843 src2_r = src1w; 844 845 /* And swap arguments. */ 846 src1 = src2; 847 src1w = src2w; 848 src2 = SLJIT_IMM; 849 /* src2w = src2_r unneeded. */ 850 } 851 } 852 } 853 854 /* Source 1. */ 855 if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3) { 856 src1_r = src1; 857 flags |= REG1_SOURCE; 858 } 859 else if (src1 & SLJIT_IMM) { 860 if (src1w) { 861 FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); 862 src1_r = TMP_REG1; 863 } 864 else 865 src1_r = 0; 866 } 867 else { 868 if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w)) 869 FAIL_IF(compiler->error); 870 else 871 flags |= SLOW_SRC1; 872 src1_r = TMP_REG1; 873 } 874 875 /* Source 2. */ 876 if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { 877 src2_r = src2; 878 flags |= REG2_SOURCE; 879 if (!(flags & REG_DEST) && GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) 880 dst_r = src2_r; 881 } 882 else if (src2 & SLJIT_IMM) { 883 if (!(flags & SRC2_IMM)) { 884 if (src2w || (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI)) { 885 FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w)); 886 src2_r = sugg_src2_r; 887 } 888 else 889 src2_r = 0; 890 } 891 } 892 else { 893 if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w)) 894 FAIL_IF(compiler->error); 895 else 896 flags |= SLOW_SRC2; 897 src2_r = sugg_src2_r; 898 } 899 900 if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { 901 SLJIT_ASSERT(src2_r == TMP_REG2); 902 if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { 903 FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w)); 904 FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw)); 905 } 906 else { 907 FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w)); 908 FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw)); 909 } 910 } 911 else if (flags & SLOW_SRC1) 912 FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw)); 913 else if (flags & SLOW_SRC2) 914 FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w, dst, dstw)); 915 916 FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); 917 918 if (dst & SLJIT_MEM) { 919 if (!(flags & SLOW_DEST)) { 920 getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw); 921 return compiler->error; 922 } 923 return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0); 924 } 925 926 return SLJIT_SUCCESS; 927 } 928 929 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) 930 { 931 CHECK_ERROR(); 932 check_sljit_emit_op0(compiler, op); 933 934 op = GET_OPCODE(op); 935 switch (op) { 936 case SLJIT_BREAKPOINT: 937 return push_inst(compiler, BREAK, UNMOVABLE_INS); 938 case SLJIT_NOP: 939 return push_inst(compiler, NOP, UNMOVABLE_INS); 940 case SLJIT_UMUL: 941 case SLJIT_SMUL: 942 FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? MULTU : MULT) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS)); 943 FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1))); 944 return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2)); 945 case SLJIT_UDIV: 946 case SLJIT_SDIV: 947 #if !(defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) 948 FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); 949 FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); 950 #endif 951 FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS)); 952 FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1))); 953 return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2)); 954 } 955 956 return SLJIT_SUCCESS; 957 } 958 959 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, 960 int dst, sljit_w dstw, 961 int src, sljit_w srcw) 962 { 963 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) 964 #define flags 0 965 #endif 966 967 CHECK_ERROR(); 968 check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); 969 ADJUST_LOCAL_OFFSET(dst, dstw); 970 ADJUST_LOCAL_OFFSET(src, srcw); 971 972 SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset); 973 974 switch (GET_OPCODE(op)) { 975 case SLJIT_MOV: 976 return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); 977 978 case SLJIT_MOV_UI: 979 return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); 980 981 case SLJIT_MOV_SI: 982 return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); 983 984 case SLJIT_MOV_UB: 985 return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); 986 987 case SLJIT_MOV_SB: 988 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); 989 990 case SLJIT_MOV_UH: 991 return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); 992 993 case SLJIT_MOV_SH: 994 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); 995 996 case SLJIT_MOVU: 997 return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); 998 999 case SLJIT_MOVU_UI: 1000 return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); 1001 1002 case SLJIT_MOVU_SI: 1003 return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); 1004 1005 case SLJIT_MOVU_UB: 1006 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); 1007 1008 case SLJIT_MOVU_SB: 1009 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); 1010 1011 case SLJIT_MOVU_UH: 1012 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); 1013 1014 case SLJIT_MOVU_SH: 1015 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); 1016 1017 case SLJIT_NOT: 1018 return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); 1019 1020 case SLJIT_NEG: 1021 return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); 1022 1023 case SLJIT_CLZ: 1024 return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); 1025 } 1026 1027 return SLJIT_SUCCESS; 1028 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) 1029 #undef flags 1030 #endif 1031 } 1032 1033 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, 1034 int dst, sljit_w dstw, 1035 int src1, sljit_w src1w, 1036 int src2, sljit_w src2w) 1037 { 1038 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) 1039 #define flags 0 1040 #endif 1041 1042 CHECK_ERROR(); 1043 check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); 1044 ADJUST_LOCAL_OFFSET(dst, dstw); 1045 ADJUST_LOCAL_OFFSET(src1, src1w); 1046 ADJUST_LOCAL_OFFSET(src2, src2w); 1047 1048 switch (GET_OPCODE(op)) { 1049 case SLJIT_ADD: 1050 case SLJIT_ADDC: 1051 return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); 1052 1053 case SLJIT_SUB: 1054 case SLJIT_SUBC: 1055 return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); 1056 1057 case SLJIT_MUL: 1058 return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); 1059 1060 case SLJIT_AND: 1061 case SLJIT_OR: 1062 case SLJIT_XOR: 1063 return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); 1064 1065 case SLJIT_SHL: 1066 case SLJIT_LSHR: 1067 case SLJIT_ASHR: 1068 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) 1069 if (src2 & SLJIT_IMM) 1070 src2w &= 0x1f; 1071 #else 1072 SLJIT_ASSERT_STOP(); 1073 #endif 1074 return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); 1075 } 1076 1077 return SLJIT_SUCCESS; 1078 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) 1079 #undef flags 1080 #endif 1081 } 1082 1083 SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) 1084 { 1085 check_sljit_get_register_index(reg); 1086 return reg_map[reg]; 1087 } 1088 1089 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, 1090 void *instruction, int size) 1091 { 1092 CHECK_ERROR(); 1093 check_sljit_emit_op_custom(compiler, instruction, size); 1094 SLJIT_ASSERT(size == 4); 1095 1096 return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS); 1097 } 1098 1099 /* --------------------------------------------------------------------- */ 1100 /* Floating point operators */ 1101 /* --------------------------------------------------------------------- */ 1102 1103 SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) 1104 { 1105 #if (defined SLJIT_QEMU && SLJIT_QEMU) 1106 /* Qemu says fir is 0 by default. */ 1107 return 1; 1108 #elif defined(__GNUC__) 1109 sljit_w fir; 1110 asm ("cfc1 %0, $0" : "=r"(fir)); 1111 return (fir >> 22) & 0x1; 1112 #else 1113 #error "FIR check is not implemented for this architecture" 1114 #endif 1115 } 1116 1117 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, 1118 int dst, sljit_w dstw, 1119 int src, sljit_w srcw) 1120 { 1121 int dst_fr; 1122 1123 CHECK_ERROR(); 1124 check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); 1125 1126 compiler->cache_arg = 0; 1127 compiler->cache_argw = 0; 1128 1129 if (GET_OPCODE(op) == SLJIT_FCMP) { 1130 if (dst > SLJIT_FLOAT_REG4) { 1131 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw)); 1132 dst = TMP_FREG1; 1133 } 1134 else 1135 dst <<= 1; 1136 1137 if (src > SLJIT_FLOAT_REG4) { 1138 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0)); 1139 src = TMP_FREG2; 1140 } 1141 else 1142 src <<= 1; 1143 1144 /* src and dst are swapped. */ 1145 if (op & SLJIT_SET_E) { 1146 FAIL_IF(push_inst(compiler, C_UEQ_D | FT(src) | FS(dst), UNMOVABLE_INS)); 1147 FAIL_IF(push_inst(compiler, CFC1 | TA(EQUAL_FLAG) | DA(FCSR_REG), EQUAL_FLAG)); 1148 FAIL_IF(push_inst(compiler, SRL | TA(EQUAL_FLAG) | DA(EQUAL_FLAG) | SH_IMM(23), EQUAL_FLAG)); 1149 FAIL_IF(push_inst(compiler, ANDI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG)); 1150 } 1151 if (op & SLJIT_SET_S) { 1152 /* Mixing the instructions for the two checks. */ 1153 FAIL_IF(push_inst(compiler, C_ULT_D | FT(src) | FS(dst), UNMOVABLE_INS)); 1154 FAIL_IF(push_inst(compiler, CFC1 | TA(ULESS_FLAG) | DA(FCSR_REG), ULESS_FLAG)); 1155 FAIL_IF(push_inst(compiler, C_ULT_D | FT(dst) | FS(src), UNMOVABLE_INS)); 1156 FAIL_IF(push_inst(compiler, SRL | TA(ULESS_FLAG) | DA(ULESS_FLAG) | SH_IMM(23), ULESS_FLAG)); 1157 FAIL_IF(push_inst(compiler, ANDI | SA(ULESS_FLAG) | TA(ULESS_FLAG) | IMM(1), ULESS_FLAG)); 1158 FAIL_IF(push_inst(compiler, CFC1 | TA(UGREATER_FLAG) | DA(FCSR_REG), UGREATER_FLAG)); 1159 FAIL_IF(push_inst(compiler, SRL | TA(UGREATER_FLAG) | DA(UGREATER_FLAG) | SH_IMM(23), UGREATER_FLAG)); 1160 FAIL_IF(push_inst(compiler, ANDI | SA(UGREATER_FLAG) | TA(UGREATER_FLAG) | IMM(1), UGREATER_FLAG)); 1161 } 1162 return push_inst(compiler, C_UN_D | FT(src) | FS(dst), FCSR_FCC); 1163 } 1164 1165 dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : (dst << 1); 1166 1167 if (src > SLJIT_FLOAT_REG4) { 1168 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, dst_fr, src, srcw, dst, dstw)); 1169 src = dst_fr; 1170 } 1171 else 1172 src <<= 1; 1173 1174 switch (op) { 1175 case SLJIT_FMOV: 1176 if (src != dst_fr && dst_fr != TMP_FREG1) 1177 FAIL_IF(push_inst(compiler, MOV_D | FS(src) | FD(dst_fr), MOVABLE_INS)); 1178 break; 1179 case SLJIT_FNEG: 1180 FAIL_IF(push_inst(compiler, NEG_D | FS(src) | FD(dst_fr), MOVABLE_INS)); 1181 break; 1182 case SLJIT_FABS: 1183 FAIL_IF(push_inst(compiler, ABS_D | FS(src) | FD(dst_fr), MOVABLE_INS)); 1184 break; 1185 } 1186 1187 if (dst_fr == TMP_FREG1) { 1188 if (op == SLJIT_FMOV) 1189 dst_fr = src; 1190 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, dst_fr, dst, dstw, 0, 0)); 1191 } 1192 1193 return SLJIT_SUCCESS; 1194 } 1195 1196 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, 1197 int dst, sljit_w dstw, 1198 int src1, sljit_w src1w, 1199 int src2, sljit_w src2w) 1200 { 1201 int dst_fr, flags = 0; 1202 1203 CHECK_ERROR(); 1204 check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); 1205 1206 compiler->cache_arg = 0; 1207 compiler->cache_argw = 0; 1208 1209 dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG2 : (dst << 1); 1210 1211 if (src1 > SLJIT_FLOAT_REG4) { 1212 if (getput_arg_fast(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src1, src1w)) { 1213 FAIL_IF(compiler->error); 1214 src1 = TMP_FREG1; 1215 } else 1216 flags |= SLOW_SRC1; 1217 } 1218 else 1219 src1 <<= 1; 1220 1221 if (src2 > SLJIT_FLOAT_REG4) { 1222 if (getput_arg_fast(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, src2, src2w)) { 1223 FAIL_IF(compiler->error); 1224 src2 = TMP_FREG2; 1225 } else 1226 flags |= SLOW_SRC2; 1227 } 1228 else 1229 src2 <<= 1; 1230 1231 if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { 1232 if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { 1233 FAIL_IF(getput_arg(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w)); 1234 FAIL_IF(getput_arg(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); 1235 } 1236 else { 1237 FAIL_IF(getput_arg(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); 1238 FAIL_IF(getput_arg(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); 1239 } 1240 } 1241 else if (flags & SLOW_SRC1) 1242 FAIL_IF(getput_arg(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); 1243 else if (flags & SLOW_SRC2) 1244 FAIL_IF(getput_arg(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); 1245 1246 if (flags & SLOW_SRC1) 1247 src1 = TMP_FREG1; 1248 if (flags & SLOW_SRC2) 1249 src2 = TMP_FREG2; 1250 1251 switch (op) { 1252 case SLJIT_FADD: 1253 FAIL_IF(push_inst(compiler, ADD_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); 1254 break; 1255 1256 case SLJIT_FSUB: 1257 FAIL_IF(push_inst(compiler, SUB_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); 1258 break; 1259 1260 case SLJIT_FMUL: 1261 FAIL_IF(push_inst(compiler, MUL_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); 1262 break; 1263 1264 case SLJIT_FDIV: 1265 FAIL_IF(push_inst(compiler, DIV_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); 1266 break; 1267 } 1268 1269 if (dst_fr == TMP_FREG2) 1270 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG2, dst, dstw, 0, 0)); 1271 1272 return SLJIT_SUCCESS; 1273 } 1274 1275 /* --------------------------------------------------------------------- */ 1276 /* Other instructions */ 1277 /* --------------------------------------------------------------------- */ 1278 1279 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) 1280 { 1281 CHECK_ERROR(); 1282 check_sljit_emit_fast_enter(compiler, dst, dstw); 1283 ADJUST_LOCAL_OFFSET(dst, dstw); 1284 1285 if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) 1286 return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst)); 1287 else if (dst & SLJIT_MEM) 1288 return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); 1289 1290 /* SLJIT_UNUSED is also possible, although highly unlikely. */ 1291 return SLJIT_SUCCESS; 1292 } 1293 1294 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) 1295 { 1296 CHECK_ERROR(); 1297 check_sljit_emit_fast_return(compiler, src, srcw); 1298 ADJUST_LOCAL_OFFSET(src, srcw); 1299 1300 if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) 1301 FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG)); 1302 else if (src & SLJIT_MEM) 1303 FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw)); 1304 else if (src & SLJIT_IMM) 1305 FAIL_IF(load_immediate(compiler, RETURN_ADDR_REG, srcw)); 1306 1307 FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); 1308 return push_inst(compiler, NOP, UNMOVABLE_INS); 1309 } 1310 1311 /* --------------------------------------------------------------------- */ 1312 /* Conditional instructions */ 1313 /* --------------------------------------------------------------------- */ 1314 1315 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) 1316 { 1317 struct sljit_label *label; 1318 1319 CHECK_ERROR_PTR(); 1320 check_sljit_emit_label(compiler); 1321 1322 if (compiler->last_label && compiler->last_label->size == compiler->size) 1323 return compiler->last_label; 1324 1325 label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); 1326 PTR_FAIL_IF(!label); 1327 set_label(label, compiler); 1328 compiler->delay_slot = UNMOVABLE_INS; 1329 return label; 1330 } 1331 1332 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) 1333 #define JUMP_LENGTH 4 1334 #else 1335 #error "Implementation required" 1336 #endif 1337 1338 #define BR_Z(src) \ 1339 inst = BEQ | SA(src) | TA(0) | JUMP_LENGTH; \ 1340 flags = IS_BIT26_COND; \ 1341 delay_check = src; 1342 1343 #define BR_NZ(src) \ 1344 inst = BNE | SA(src) | TA(0) | JUMP_LENGTH; \ 1345 flags = IS_BIT26_COND; \ 1346 delay_check = src; 1347 1348 #define BR_T() \ 1349 inst = BC1T | JUMP_LENGTH; \ 1350 flags = IS_BIT16_COND; \ 1351 delay_check = FCSR_FCC; 1352 1353 #define BR_F() \ 1354 inst = BC1F | JUMP_LENGTH; \ 1355 flags = IS_BIT16_COND; \ 1356 delay_check = FCSR_FCC; 1357 1358 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) 1359 { 1360 struct sljit_jump *jump; 1361 sljit_ins inst; 1362 int flags = 0; 1363 int delay_check = UNMOVABLE_INS; 1364 1365 CHECK_ERROR_PTR(); 1366 check_sljit_emit_jump(compiler, type); 1367 1368 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); 1369 PTR_FAIL_IF(!jump); 1370 set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); 1371 type &= 0xff; 1372 1373 switch (type) { 1374 case SLJIT_C_EQUAL: 1375 case SLJIT_C_FLOAT_NOT_EQUAL: 1376 BR_NZ(EQUAL_FLAG); 1377 break; 1378 case SLJIT_C_NOT_EQUAL: 1379 case SLJIT_C_FLOAT_EQUAL: 1380 BR_Z(EQUAL_FLAG); 1381 break; 1382 case SLJIT_C_LESS: 1383 case SLJIT_C_FLOAT_LESS: 1384 BR_Z(ULESS_FLAG); 1385 break; 1386 case SLJIT_C_GREATER_EQUAL: 1387 case SLJIT_C_FLOAT_GREATER_EQUAL: 1388 BR_NZ(ULESS_FLAG); 1389 break; 1390 case SLJIT_C_GREATER: 1391 case SLJIT_C_FLOAT_GREATER: 1392 BR_Z(UGREATER_FLAG); 1393 break; 1394 case SLJIT_C_LESS_EQUAL: 1395 case SLJIT_C_FLOAT_LESS_EQUAL: 1396 BR_NZ(UGREATER_FLAG); 1397 break; 1398 case SLJIT_C_SIG_LESS: 1399 BR_Z(LESS_FLAG); 1400 break; 1401 case SLJIT_C_SIG_GREATER_EQUAL: 1402 BR_NZ(LESS_FLAG); 1403 break; 1404 case SLJIT_C_SIG_GREATER: 1405 BR_Z(GREATER_FLAG); 1406 break; 1407 case SLJIT_C_SIG_LESS_EQUAL: 1408 BR_NZ(GREATER_FLAG); 1409 break; 1410 case SLJIT_C_OVERFLOW: 1411 case SLJIT_C_MUL_OVERFLOW: 1412 BR_Z(OVERFLOW_FLAG); 1413 break; 1414 case SLJIT_C_NOT_OVERFLOW: 1415 case SLJIT_C_MUL_NOT_OVERFLOW: 1416 BR_NZ(OVERFLOW_FLAG); 1417 break; 1418 case SLJIT_C_FLOAT_UNORDERED: 1419 BR_F(); 1420 break; 1421 case SLJIT_C_FLOAT_ORDERED: 1422 BR_T(); 1423 break; 1424 default: 1425 /* Not conditional branch. */ 1426 inst = 0; 1427 break; 1428 } 1429 1430 jump->flags |= flags; 1431 if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check)) 1432 jump->flags |= IS_MOVABLE; 1433 1434 if (inst) 1435 PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS)); 1436 1437 PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); 1438 if (type <= SLJIT_JUMP) { 1439 PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); 1440 jump->addr = compiler->size; 1441 PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); 1442 } else { 1443 SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); 1444 /* Cannot be optimized out if type is >= CALL0. */ 1445 jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0); 1446 PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); 1447 jump->addr = compiler->size; 1448 /* A NOP if type < CALL1. */ 1449 PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS)); 1450 } 1451 return jump; 1452 } 1453 1454 #define RESOLVE_IMM1() \ 1455 if (src1 & SLJIT_IMM) { \ 1456 if (src1w) { \ 1457 PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \ 1458 src1 = TMP_REG1; \ 1459 } \ 1460 else \ 1461 src1 = 0; \ 1462 } 1463 1464 #define RESOLVE_IMM2() \ 1465 if (src2 & SLJIT_IMM) { \ 1466 if (src2w) { \ 1467 PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \ 1468 src2 = TMP_REG2; \ 1469 } \ 1470 else \ 1471 src2 = 0; \ 1472 } 1473 1474 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type, 1475 int src1, sljit_w src1w, 1476 int src2, sljit_w src2w) 1477 { 1478 struct sljit_jump *jump; 1479 int flags; 1480 sljit_ins inst; 1481 1482 CHECK_ERROR_PTR(); 1483 check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w); 1484 ADJUST_LOCAL_OFFSET(src1, src1w); 1485 ADJUST_LOCAL_OFFSET(src2, src2w); 1486 1487 compiler->cache_arg = 0; 1488 compiler->cache_argw = 0; 1489 flags = ((type & SLJIT_INT_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA; 1490 if (src1 & SLJIT_MEM) { 1491 PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w)); 1492 src1 = TMP_REG1; 1493 } 1494 if (src2 & SLJIT_MEM) { 1495 PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0)); 1496 src2 = TMP_REG2; 1497 } 1498 1499 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); 1500 PTR_FAIL_IF(!jump); 1501 set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); 1502 type &= 0xff; 1503 1504 if (type <= SLJIT_C_NOT_EQUAL) { 1505 RESOLVE_IMM1(); 1506 RESOLVE_IMM2(); 1507 jump->flags |= IS_BIT26_COND; 1508 if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2))) 1509 jump->flags |= IS_MOVABLE; 1510 PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_C_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | JUMP_LENGTH, UNMOVABLE_INS)); 1511 } 1512 else if (type >= SLJIT_C_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) { 1513 inst = NOP; 1514 if ((src1 & SLJIT_IMM) && (src1w == 0)) { 1515 RESOLVE_IMM2(); 1516 switch (type) { 1517 case SLJIT_C_SIG_LESS: 1518 inst = BLEZ; 1519 jump->flags |= IS_BIT26_COND; 1520 break; 1521 case SLJIT_C_SIG_GREATER_EQUAL: 1522 inst = BGTZ; 1523 jump->flags |= IS_BIT26_COND; 1524 break; 1525 case SLJIT_C_SIG_GREATER: 1526 inst = BGEZ; 1527 jump->flags |= IS_BIT16_COND; 1528 break; 1529 case SLJIT_C_SIG_LESS_EQUAL: 1530 inst = BLTZ; 1531 jump->flags |= IS_BIT16_COND; 1532 break; 1533 } 1534 src1 = src2; 1535 } 1536 else { 1537 RESOLVE_IMM1(); 1538 switch (type) { 1539 case SLJIT_C_SIG_LESS: 1540 inst = BGEZ; 1541 jump->flags |= IS_BIT16_COND; 1542 break; 1543 case SLJIT_C_SIG_GREATER_EQUAL: 1544 inst = BLTZ; 1545 jump->flags |= IS_BIT16_COND; 1546 break; 1547 case SLJIT_C_SIG_GREATER: 1548 inst = BLEZ; 1549 jump->flags |= IS_BIT26_COND; 1550 break; 1551 case SLJIT_C_SIG_LESS_EQUAL: 1552 inst = BGTZ; 1553 jump->flags |= IS_BIT26_COND; 1554 break; 1555 } 1556 } 1557 PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | JUMP_LENGTH, UNMOVABLE_INS)); 1558 } 1559 else { 1560 if (type == SLJIT_C_LESS || type == SLJIT_C_GREATER_EQUAL || type == SLJIT_C_SIG_LESS || type == SLJIT_C_SIG_GREATER_EQUAL) { 1561 RESOLVE_IMM1(); 1562 if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN) 1563 PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1))); 1564 else { 1565 RESOLVE_IMM2(); 1566 PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1))); 1567 } 1568 type = (type == SLJIT_C_LESS || type == SLJIT_C_SIG_LESS) ? SLJIT_C_NOT_EQUAL : SLJIT_C_EQUAL; 1569 } 1570 else { 1571 RESOLVE_IMM2(); 1572 if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN) 1573 PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1))); 1574 else { 1575 RESOLVE_IMM1(); 1576 PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1))); 1577 } 1578 type = (type == SLJIT_C_GREATER || type == SLJIT_C_SIG_GREATER) ? SLJIT_C_NOT_EQUAL : SLJIT_C_EQUAL; 1579 } 1580 1581 jump->flags |= IS_BIT26_COND; 1582 PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_C_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | JUMP_LENGTH, UNMOVABLE_INS)); 1583 } 1584 1585 PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); 1586 PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); 1587 jump->addr = compiler->size; 1588 PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); 1589 return jump; 1590 } 1591 1592 #undef RESOLVE_IMM1 1593 #undef RESOLVE_IMM2 1594 1595 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type, 1596 int src1, sljit_w src1w, 1597 int src2, sljit_w src2w) 1598 { 1599 struct sljit_jump *jump; 1600 sljit_ins inst; 1601 int if_true; 1602 1603 CHECK_ERROR_PTR(); 1604 check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w); 1605 1606 compiler->cache_arg = 0; 1607 compiler->cache_argw = 0; 1608 1609 if (src1 > SLJIT_FLOAT_REG4) { 1610 PTR_FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); 1611 src1 = TMP_FREG1; 1612 } 1613 else 1614 src1 <<= 1; 1615 1616 if (src2 > SLJIT_FLOAT_REG4) { 1617 PTR_FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0)); 1618 src2 = TMP_FREG2; 1619 } 1620 else 1621 src2 <<= 1; 1622 1623 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); 1624 PTR_FAIL_IF(!jump); 1625 set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); 1626 jump->flags |= IS_BIT16_COND; 1627 type &= 0xff; 1628 1629 switch (type) { 1630 case SLJIT_C_FLOAT_EQUAL: 1631 inst = C_UEQ_D; 1632 if_true = 1; 1633 break; 1634 case SLJIT_C_FLOAT_NOT_EQUAL: 1635 inst = C_UEQ_D; 1636 if_true = 0; 1637 break; 1638 case SLJIT_C_FLOAT_LESS: 1639 inst = C_ULT_D; 1640 if_true = 1; 1641 break; 1642 case SLJIT_C_FLOAT_GREATER_EQUAL: 1643 inst = C_ULT_D; 1644 if_true = 0; 1645 break; 1646 case SLJIT_C_FLOAT_GREATER: 1647 inst = C_ULE_D; 1648 if_true = 0; 1649 break; 1650 case SLJIT_C_FLOAT_LESS_EQUAL: 1651 inst = C_ULE_D; 1652 if_true = 1; 1653 break; 1654 case SLJIT_C_FLOAT_UNORDERED: 1655 inst = C_UN_D; 1656 if_true = 1; 1657 break; 1658 case SLJIT_C_FLOAT_ORDERED: 1659 default: /* Make compilers happy. */ 1660 inst = C_UN_D; 1661 if_true = 0; 1662 break; 1663 } 1664 1665 PTR_FAIL_IF(push_inst(compiler, inst | FT(src2) | FS(src1), UNMOVABLE_INS)); 1666 /* Intentionally the other opcode. */ 1667 PTR_FAIL_IF(push_inst(compiler, (if_true ? BC1F : BC1T) | JUMP_LENGTH, UNMOVABLE_INS)); 1668 PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); 1669 PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); 1670 jump->addr = compiler->size; 1671 PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); 1672 return jump; 1673 } 1674 1675 #undef JUMP_LENGTH 1676 #undef BR_Z 1677 #undef BR_NZ 1678 #undef BR_T 1679 #undef BR_F 1680 1681 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) 1682 { 1683 int src_r = TMP_REG2; 1684 struct sljit_jump *jump = NULL; 1685 1686 CHECK_ERROR(); 1687 check_sljit_emit_ijump(compiler, type, src, srcw); 1688 ADJUST_LOCAL_OFFSET(src, srcw); 1689 1690 if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { 1691 if (DR(src) != 4) 1692 src_r = src; 1693 else 1694 FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); 1695 } 1696 1697 if (type >= SLJIT_CALL0) { 1698 SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); 1699 if (src & (SLJIT_IMM | SLJIT_MEM)) { 1700 if (src & SLJIT_IMM) 1701 FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw)); 1702 else { 1703 SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM)); 1704 FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); 1705 } 1706 FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); 1707 /* We need an extra instruction in any case. */ 1708 return push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS); 1709 } 1710 1711 /* Register input. */ 1712 if (type >= SLJIT_CALL1) 1713 FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), 4)); 1714 FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); 1715 return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | D(PIC_ADDR_REG), UNMOVABLE_INS); 1716 } 1717 1718 if (src & SLJIT_IMM) { 1719 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); 1720 FAIL_IF(!jump); 1721 set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0)); 1722 jump->u.target = srcw; 1723 1724 if (compiler->delay_slot != UNMOVABLE_INS) 1725 jump->flags |= IS_MOVABLE; 1726 1727 FAIL_IF(emit_const(compiler, TMP_REG2, 0)); 1728 } 1729 else if (src & SLJIT_MEM) 1730 FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); 1731 1732 FAIL_IF(push_inst(compiler, JR | S(src_r), UNMOVABLE_INS)); 1733 if (jump) 1734 jump->addr = compiler->size; 1735 FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); 1736 return SLJIT_SUCCESS; 1737 } 1738 1739 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) 1740 { 1741 int sugg_dst_ar, dst_ar; 1742 1743 CHECK_ERROR(); 1744 check_sljit_emit_cond_value(compiler, op, dst, dstw, type); 1745 ADJUST_LOCAL_OFFSET(dst, dstw); 1746 1747 if (dst == SLJIT_UNUSED) 1748 return SLJIT_SUCCESS; 1749 1750 sugg_dst_ar = DR((op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2); 1751 1752 switch (type) { 1753 case SLJIT_C_EQUAL: 1754 case SLJIT_C_NOT_EQUAL: 1755 FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); 1756 dst_ar = sugg_dst_ar; 1757 break; 1758 case SLJIT_C_LESS: 1759 case SLJIT_C_GREATER_EQUAL: 1760 case SLJIT_C_FLOAT_LESS: 1761 case SLJIT_C_FLOAT_GREATER_EQUAL: 1762 dst_ar = ULESS_FLAG; 1763 break; 1764 case SLJIT_C_GREATER: 1765 case SLJIT_C_LESS_EQUAL: 1766 case SLJIT_C_FLOAT_GREATER: 1767 case SLJIT_C_FLOAT_LESS_EQUAL: 1768 dst_ar = UGREATER_FLAG; 1769 break; 1770 case SLJIT_C_SIG_LESS: 1771 case SLJIT_C_SIG_GREATER_EQUAL: 1772 dst_ar = LESS_FLAG; 1773 break; 1774 case SLJIT_C_SIG_GREATER: 1775 case SLJIT_C_SIG_LESS_EQUAL: 1776 dst_ar = GREATER_FLAG; 1777 break; 1778 case SLJIT_C_OVERFLOW: 1779 case SLJIT_C_NOT_OVERFLOW: 1780 dst_ar = OVERFLOW_FLAG; 1781 break; 1782 case SLJIT_C_MUL_OVERFLOW: 1783 case SLJIT_C_MUL_NOT_OVERFLOW: 1784 FAIL_IF(push_inst(compiler, SLTIU | SA(OVERFLOW_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); 1785 dst_ar = sugg_dst_ar; 1786 type ^= 0x1; /* Flip type bit for the XORI below. */ 1787 break; 1788 case SLJIT_C_FLOAT_EQUAL: 1789 case SLJIT_C_FLOAT_NOT_EQUAL: 1790 dst_ar = EQUAL_FLAG; 1791 break; 1792 1793 case SLJIT_C_FLOAT_UNORDERED: 1794 case SLJIT_C_FLOAT_ORDERED: 1795 FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(FCSR_REG), sugg_dst_ar)); 1796 FAIL_IF(push_inst(compiler, SRL | TA(sugg_dst_ar) | DA(sugg_dst_ar) | SH_IMM(23), sugg_dst_ar)); 1797 FAIL_IF(push_inst(compiler, ANDI | SA(sugg_dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); 1798 dst_ar = sugg_dst_ar; 1799 break; 1800 1801 default: 1802 SLJIT_ASSERT_STOP(); 1803 dst_ar = sugg_dst_ar; 1804 break; 1805 } 1806 1807 if (type & 0x1) { 1808 FAIL_IF(push_inst(compiler, XORI | SA(dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); 1809 dst_ar = sugg_dst_ar; 1810 } 1811 1812 if (GET_OPCODE(op) == SLJIT_OR) { 1813 if (DR(TMP_REG2) != dst_ar) 1814 FAIL_IF(push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); 1815 return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, dst, dstw, TMP_REG2, 0); 1816 } 1817 1818 if (dst & SLJIT_MEM) 1819 return emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw); 1820 1821 if (sugg_dst_ar != dst_ar) 1822 return push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | DA(sugg_dst_ar), sugg_dst_ar); 1823 return SLJIT_SUCCESS; 1824 } 1825 1826 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) 1827 { 1828 struct sljit_const *const_; 1829 int reg; 1830 1831 CHECK_ERROR_PTR(); 1832 check_sljit_emit_const(compiler, dst, dstw, init_value); 1833 ADJUST_LOCAL_OFFSET(dst, dstw); 1834 1835 const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); 1836 PTR_FAIL_IF(!const_); 1837 set_const(const_, compiler); 1838 1839 reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; 1840 1841 PTR_FAIL_IF(emit_const(compiler, reg, init_value)); 1842 1843 if (dst & SLJIT_MEM) 1844 PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); 1845 return const_; 1846 } 1847