root/ext/pcre/pcrelib/sljit/sljitNativeARM_64.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sljit_get_platform_name
  2. push_inst
  3. emit_imm64_const
  4. modify_imm64_const
  5. detect_jump_type
  6. sljit_generate_code
  7. logical_imm
  8. load_immediate
  9. emit_op_imm
  10. emit_set_delta
  11. getput_arg_fast
  12. can_cache
  13. getput_arg
  14. emit_op_mem
  15. emit_op_mem2
  16. sljit_emit_enter
  17. sljit_set_context
  18. sljit_emit_return
  19. sljit_emit_op0
  20. sljit_emit_op1
  21. sljit_emit_op2
  22. sljit_get_register_index
  23. sljit_get_float_register_index
  24. sljit_emit_op_custom
  25. sljit_is_fpu_available
  26. emit_fop_mem
  27. sljit_emit_fop1_convw_fromd
  28. sljit_emit_fop1_convd_fromw
  29. sljit_emit_fop1_cmp
  30. sljit_emit_fop1
  31. sljit_emit_fop2
  32. sljit_emit_fast_enter
  33. sljit_emit_fast_return
  34. get_cc
  35. sljit_emit_label
  36. sljit_emit_jump
  37. emit_cmp_to0
  38. sljit_emit_ijump
  39. sljit_emit_op_flags
  40. sljit_emit_const
  41. sljit_set_jump_addr
  42. sljit_set_const

   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 "ARM-64" SLJIT_CPUINFO;
  30 }
  31 
  32 /* Length of an instruction word */
  33 typedef sljit_ui sljit_ins;
  34 
  35 #define TMP_ZERO        (0)
  36 
  37 #define TMP_REG1        (SLJIT_NUMBER_OF_REGISTERS + 2)
  38 #define TMP_REG2        (SLJIT_NUMBER_OF_REGISTERS + 3)
  39 #define TMP_REG3        (SLJIT_NUMBER_OF_REGISTERS + 4)
  40 #define TMP_LR          (SLJIT_NUMBER_OF_REGISTERS + 5)
  41 #define TMP_SP          (SLJIT_NUMBER_OF_REGISTERS + 6)
  42 
  43 #define TMP_FREG1       (0)
  44 #define TMP_FREG2       (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
  45 
  46 static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = {
  47   31, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 29, 9, 10, 11, 30, 31
  48 };
  49 
  50 #define W_OP (1 << 31)
  51 #define RD(rd) (reg_map[rd])
  52 #define RT(rt) (reg_map[rt])
  53 #define RN(rn) (reg_map[rn] << 5)
  54 #define RT2(rt2) (reg_map[rt2] << 10)
  55 #define RM(rm) (reg_map[rm] << 16)
  56 #define VD(vd) (vd)
  57 #define VT(vt) (vt)
  58 #define VN(vn) ((vn) << 5)
  59 #define VM(vm) ((vm) << 16)
  60 
  61 /* --------------------------------------------------------------------- */
  62 /*  Instrucion forms                                                     */
  63 /* --------------------------------------------------------------------- */
  64 
  65 #define ADC 0x9a000000
  66 #define ADD 0x8b000000
  67 #define ADDI 0x91000000
  68 #define AND 0x8a000000
  69 #define ANDI 0x92000000
  70 #define ASRV 0x9ac02800
  71 #define B 0x14000000
  72 #define B_CC 0x54000000
  73 #define BL 0x94000000
  74 #define BLR 0xd63f0000
  75 #define BR 0xd61f0000
  76 #define BRK 0xd4200000
  77 #define CBZ 0xb4000000
  78 #define CLZ 0xdac01000
  79 #define CSINC 0x9a800400
  80 #define EOR 0xca000000
  81 #define EORI 0xd2000000
  82 #define FABS 0x1e60c000
  83 #define FADD 0x1e602800
  84 #define FCMP 0x1e602000
  85 #define FCVT 0x1e224000
  86 #define FCVTZS 0x9e780000
  87 #define FDIV 0x1e601800
  88 #define FMOV 0x1e604000
  89 #define FMUL 0x1e600800
  90 #define FNEG 0x1e614000
  91 #define FSUB 0x1e603800
  92 #define LDRI 0xf9400000
  93 #define LDP 0xa9400000
  94 #define LDP_PST 0xa8c00000
  95 #define LSLV 0x9ac02000
  96 #define LSRV 0x9ac02400
  97 #define MADD 0x9b000000
  98 #define MOVK 0xf2800000
  99 #define MOVN 0x92800000
 100 #define MOVZ 0xd2800000
 101 #define NOP 0xd503201f
 102 #define ORN 0xaa200000
 103 #define ORR 0xaa000000
 104 #define ORRI 0xb2000000
 105 #define RET 0xd65f0000
 106 #define SBC 0xda000000
 107 #define SBFM 0x93000000
 108 #define SCVTF 0x9e620000
 109 #define SDIV 0x9ac00c00
 110 #define SMADDL 0x9b200000
 111 #define SMULH 0x9b403c00
 112 #define STP 0xa9000000
 113 #define STP_PRE 0xa9800000
 114 #define STRI 0xf9000000
 115 #define STR_FI 0x3d000000
 116 #define STR_FR 0x3c206800
 117 #define STUR_FI 0x3c000000
 118 #define SUB 0xcb000000
 119 #define SUBI 0xd1000000
 120 #define SUBS 0xeb000000
 121 #define UBFM 0xd3000000
 122 #define UDIV 0x9ac00800
 123 #define UMULH 0x9bc03c00
 124 
 125 /* dest_reg is the absolute name of the register
 126    Useful for reordering instructions in the delay slot. */
 127 static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins)
 128 {
 129         sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
 130         FAIL_IF(!ptr);
 131         *ptr = ins;
 132         compiler->size++;
 133         return SLJIT_SUCCESS;
 134 }
 135 
 136 static SLJIT_INLINE sljit_si emit_imm64_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm)
 137 {
 138         FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5)));
 139         FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 16) & 0xffff) << 5) | (1 << 21)));
 140         FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 32) & 0xffff) << 5) | (2 << 21)));
 141         return push_inst(compiler, MOVK | RD(dst) | ((imm >> 48) << 5) | (3 << 21));
 142 }
 143 
 144 static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm)
 145 {
 146         sljit_si dst = inst[0] & 0x1f;
 147         SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));
 148         inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5);
 149         inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21);
 150         inst[2] = MOVK | dst | (((new_imm >> 32) & 0xffff) << 5) | (2 << 21);
 151         inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21);
 152 }
 153 
 154 static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
 155 {
 156         sljit_sw diff;
 157         sljit_uw target_addr;
 158 
 159         if (jump->flags & SLJIT_REWRITABLE_JUMP) {
 160                 jump->flags |= PATCH_ABS64;
 161                 return 0;
 162         }
 163 
 164         if (jump->flags & JUMP_ADDR)
 165                 target_addr = jump->u.target;
 166         else {
 167                 SLJIT_ASSERT(jump->flags & JUMP_LABEL);
 168                 target_addr = (sljit_uw)(code + jump->u.label->size);
 169         }
 170         diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4);
 171 
 172         if (jump->flags & IS_COND) {
 173                 diff += sizeof(sljit_ins);
 174                 if (diff <= 0xfffff && diff >= -0x100000) {
 175                         code_ptr[-5] ^= (jump->flags & IS_CBZ) ? (0x1 << 24) : 0x1;
 176                         jump->addr -= sizeof(sljit_ins);
 177                         jump->flags |= PATCH_COND;
 178                         return 5;
 179                 }
 180                 diff -= sizeof(sljit_ins);
 181         }
 182 
 183         if (diff <= 0x7ffffff && diff >= -0x8000000) {
 184                 jump->flags |= PATCH_B;
 185                 return 4;
 186         }
 187 
 188         if (target_addr <= 0xffffffffl) {
 189                 if (jump->flags & IS_COND)
 190                         code_ptr[-5] -= (2 << 5);
 191                 code_ptr[-2] = code_ptr[0];
 192                 return 2;
 193         }
 194         if (target_addr <= 0xffffffffffffl) {
 195                 if (jump->flags & IS_COND)
 196                         code_ptr[-5] -= (1 << 5);
 197                 jump->flags |= PATCH_ABS48;
 198                 code_ptr[-1] = code_ptr[0];
 199                 return 1;
 200         }
 201 
 202         jump->flags |= PATCH_ABS64;
 203         return 0;
 204 }
 205 
 206 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
 207 {
 208         struct sljit_memory_fragment *buf;
 209         sljit_ins *code;
 210         sljit_ins *code_ptr;
 211         sljit_ins *buf_ptr;
 212         sljit_ins *buf_end;
 213         sljit_uw word_count;
 214         sljit_uw addr;
 215         sljit_si dst;
 216 
 217         struct sljit_label *label;
 218         struct sljit_jump *jump;
 219         struct sljit_const *const_;
 220 
 221         CHECK_ERROR_PTR();
 222         CHECK_PTR(check_sljit_generate_code(compiler));
 223         reverse_buf(compiler);
 224 
 225         code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
 226         PTR_FAIL_WITH_EXEC_IF(code);
 227         buf = compiler->buf;
 228 
 229         code_ptr = code;
 230         word_count = 0;
 231         label = compiler->labels;
 232         jump = compiler->jumps;
 233         const_ = compiler->consts;
 234 
 235         do {
 236                 buf_ptr = (sljit_ins*)buf->memory;
 237                 buf_end = buf_ptr + (buf->used_size >> 2);
 238                 do {
 239                         *code_ptr = *buf_ptr++;
 240                         /* These structures are ordered by their address. */
 241                         SLJIT_ASSERT(!label || label->size >= word_count);
 242                         SLJIT_ASSERT(!jump || jump->addr >= word_count);
 243                         SLJIT_ASSERT(!const_ || const_->addr >= word_count);
 244                         if (label && label->size == word_count) {
 245                                 label->addr = (sljit_uw)code_ptr;
 246                                 label->size = code_ptr - code;
 247                                 label = label->next;
 248                         }
 249                         if (jump && jump->addr == word_count) {
 250                                         jump->addr = (sljit_uw)(code_ptr - 4);
 251                                         code_ptr -= detect_jump_type(jump, code_ptr, code);
 252                                         jump = jump->next;
 253                         }
 254                         if (const_ && const_->addr == word_count) {
 255                                 const_->addr = (sljit_uw)code_ptr;
 256                                 const_ = const_->next;
 257                         }
 258                         code_ptr ++;
 259                         word_count ++;
 260                 } while (buf_ptr < buf_end);
 261 
 262                 buf = buf->next;
 263         } while (buf);
 264 
 265         if (label && label->size == word_count) {
 266                 label->addr = (sljit_uw)code_ptr;
 267                 label->size = code_ptr - code;
 268                 label = label->next;
 269         }
 270 
 271         SLJIT_ASSERT(!label);
 272         SLJIT_ASSERT(!jump);
 273         SLJIT_ASSERT(!const_);
 274         SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
 275 
 276         jump = compiler->jumps;
 277         while (jump) {
 278                 do {
 279                         addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
 280                         buf_ptr = (sljit_ins*)jump->addr;
 281                         if (jump->flags & PATCH_B) {
 282                                 addr = (sljit_sw)(addr - jump->addr) >> 2;
 283                                 SLJIT_ASSERT((sljit_sw)addr <= 0x1ffffff && (sljit_sw)addr >= -0x2000000);
 284                                 buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (addr & 0x3ffffff);
 285                                 if (jump->flags & IS_COND)
 286                                         buf_ptr[-1] -= (4 << 5);
 287                                 break;
 288                         }
 289                         if (jump->flags & PATCH_COND) {
 290                                 addr = (sljit_sw)(addr - jump->addr) >> 2;
 291                                 SLJIT_ASSERT((sljit_sw)addr <= 0x3ffff && (sljit_sw)addr >= -0x40000);
 292                                 buf_ptr[0] = (buf_ptr[0] & ~0xffffe0) | ((addr & 0x7ffff) << 5);
 293                                 break;
 294                         }
 295 
 296                         SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || addr <= 0xffffffffl);
 297                         SLJIT_ASSERT((jump->flags & PATCH_ABS64) || addr <= 0xffffffffffffl);
 298 
 299                         dst = buf_ptr[0] & 0x1f;
 300                         buf_ptr[0] = MOVZ | dst | ((addr & 0xffff) << 5);
 301                         buf_ptr[1] = MOVK | dst | (((addr >> 16) & 0xffff) << 5) | (1 << 21);
 302                         if (jump->flags & (PATCH_ABS48 | PATCH_ABS64))
 303                                 buf_ptr[2] = MOVK | dst | (((addr >> 32) & 0xffff) << 5) | (2 << 21);
 304                         if (jump->flags & PATCH_ABS64)
 305                                 buf_ptr[3] = MOVK | dst | (((addr >> 48) & 0xffff) << 5) | (3 << 21);
 306                 } while (0);
 307                 jump = jump->next;
 308         }
 309 
 310         compiler->error = SLJIT_ERR_COMPILED;
 311         compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
 312         SLJIT_CACHE_FLUSH(code, code_ptr);
 313         return code;
 314 }
 315 
 316 /* --------------------------------------------------------------------- */
 317 /*  Core code generator functions.                                       */
 318 /* --------------------------------------------------------------------- */
 319 
 320 #define COUNT_TRAILING_ZERO(value, result) \
 321         result = 0; \
 322         if (!(value & 0xffffffff)) { \
 323                 result += 32; \
 324                 value >>= 32; \
 325         } \
 326         if (!(value & 0xffff)) { \
 327                 result += 16; \
 328                 value >>= 16; \
 329         } \
 330         if (!(value & 0xff)) { \
 331                 result += 8; \
 332                 value >>= 8; \
 333         } \
 334         if (!(value & 0xf)) { \
 335                 result += 4; \
 336                 value >>= 4; \
 337         } \
 338         if (!(value & 0x3)) { \
 339                 result += 2; \
 340                 value >>= 2; \
 341         } \
 342         if (!(value & 0x1)) { \
 343                 result += 1; \
 344                 value >>= 1; \
 345         }
 346 
 347 #define LOGICAL_IMM_CHECK 0x100
 348 
 349 static sljit_ins logical_imm(sljit_sw imm, sljit_si len)
 350 {
 351         sljit_si negated, ones, right;
 352         sljit_uw mask, uimm;
 353         sljit_ins ins;
 354 
 355         if (len & LOGICAL_IMM_CHECK) {
 356                 len &= ~LOGICAL_IMM_CHECK;
 357                 if (len == 32 && (imm == 0 || imm == -1))
 358                         return 0;
 359                 if (len == 16 && ((sljit_si)imm == 0 || (sljit_si)imm == -1))
 360                         return 0;
 361         }
 362 
 363         SLJIT_ASSERT((len == 32 && imm != 0 && imm != -1)
 364                 || (len == 16 && (sljit_si)imm != 0 && (sljit_si)imm != -1));
 365         uimm = (sljit_uw)imm;
 366         while (1) {
 367                 if (len <= 0) {
 368                         SLJIT_ASSERT_STOP();
 369                         return 0;
 370                 }
 371                 mask = ((sljit_uw)1 << len) - 1;
 372                 if ((uimm & mask) != ((uimm >> len) & mask))
 373                         break;
 374                 len >>= 1;
 375         }
 376 
 377         len <<= 1;
 378 
 379         negated = 0;
 380         if (uimm & 0x1) {
 381                 negated = 1;
 382                 uimm = ~uimm;
 383         }
 384 
 385         if (len < 64)
 386                 uimm &= ((sljit_uw)1 << len) - 1;
 387 
 388         /* Unsigned right shift. */
 389         COUNT_TRAILING_ZERO(uimm, right);
 390 
 391         /* Signed shift. We also know that the highest bit is set. */
 392         imm = (sljit_sw)~uimm;
 393         SLJIT_ASSERT(imm < 0);
 394 
 395         COUNT_TRAILING_ZERO(imm, ones);
 396 
 397         if (~imm)
 398                 return 0;
 399 
 400         if (len == 64)
 401                 ins = 1 << 22;
 402         else
 403                 ins = (0x3f - ((len << 1) - 1)) << 10;
 404 
 405         if (negated)
 406                 return ins | ((len - ones - 1) << 10) | ((len - ones - right) << 16);
 407 
 408         return ins | ((ones - 1) << 10) | ((len - right) << 16);
 409 }
 410 
 411 #undef COUNT_TRAILING_ZERO
 412 
 413 static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw simm)
 414 {
 415         sljit_uw imm = (sljit_uw)simm;
 416         sljit_si i, zeros, ones, first;
 417         sljit_ins bitmask;
 418 
 419         if (imm <= 0xffff)
 420                 return push_inst(compiler, MOVZ | RD(dst) | (imm << 5));
 421 
 422         if (simm >= -0x10000 && simm < 0)
 423                 return push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5));
 424 
 425         if (imm <= 0xffffffffl) {
 426                 if ((imm & 0xffff0000l) == 0xffff0000)
 427                         return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff) << 5));
 428                 if ((imm & 0xffff) == 0xffff)
 429                         return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));
 430                 bitmask = logical_imm(simm, 16);
 431                 if (bitmask != 0)
 432                         return push_inst(compiler, (ORRI ^ W_OP) | RD(dst) | RN(TMP_ZERO) | bitmask);
 433         }
 434         else {
 435                 bitmask = logical_imm(simm, 32);
 436                 if (bitmask != 0)
 437                         return push_inst(compiler, ORRI | RD(dst) | RN(TMP_ZERO) | bitmask);
 438         }
 439 
 440         if (imm <= 0xffffffffl) {
 441                 FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5)));
 442                 return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));
 443         }
 444 
 445         if (simm >= -0x100000000l && simm < 0) {
 446                 FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5)));
 447                 return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));
 448         }
 449 
 450         /* A large amount of number can be constructed from ORR and MOVx,
 451         but computing them is costly. We don't  */
 452 
 453         zeros = 0;
 454         ones = 0;
 455         for (i = 4; i > 0; i--) {
 456                 if ((simm & 0xffff) == 0)
 457                         zeros++;
 458                 if ((simm & 0xffff) == 0xffff)
 459                         ones++;
 460                 simm >>= 16;
 461         }
 462 
 463         simm = (sljit_sw)imm;
 464         first = 1;
 465         if (ones > zeros) {
 466                 simm = ~simm;
 467                 for (i = 0; i < 4; i++) {
 468                         if (!(simm & 0xffff)) {
 469                                 simm >>= 16;
 470                                 continue;
 471                         }
 472                         if (first) {
 473                                 first = 0;
 474                                 FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((simm & 0xffff) << 5) | (i << 21)));
 475                         }
 476                         else
 477                                 FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((~simm & 0xffff) << 5) | (i << 21)));
 478                         simm >>= 16;
 479                 }
 480                 return SLJIT_SUCCESS;
 481         }
 482 
 483         for (i = 0; i < 4; i++) {
 484                 if (!(simm & 0xffff)) {
 485                         simm >>= 16;
 486                         continue;
 487                 }
 488                 if (first) {
 489                         first = 0;
 490                         FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((simm & 0xffff) << 5) | (i << 21)));
 491                 }
 492                 else
 493                         FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((simm & 0xffff) << 5) | (i << 21)));
 494                 simm >>= 16;
 495         }
 496         return SLJIT_SUCCESS;
 497 }
 498 
 499 #define ARG1_IMM        0x0010000
 500 #define ARG2_IMM        0x0020000
 501 #define INT_OP          0x0040000
 502 #define SET_FLAGS       0x0080000
 503 #define UNUSED_RETURN   0x0100000
 504 #define SLOW_DEST       0x0200000
 505 #define SLOW_SRC1       0x0400000
 506 #define SLOW_SRC2       0x0800000
 507 
 508 #define CHECK_FLAGS(flag_bits) \
 509         if (flags & SET_FLAGS) { \
 510                 inv_bits |= flag_bits; \
 511                 if (flags & UNUSED_RETURN) \
 512                         dst = TMP_ZERO; \
 513         }
 514 
 515 static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_sw arg1, sljit_sw arg2)
 516 {
 517         /* dst must be register, TMP_REG1
 518            arg1 must be register, TMP_REG1, imm
 519            arg2 must be register, TMP_REG2, imm */
 520         sljit_ins inv_bits = (flags & INT_OP) ? (1 << 31) : 0;
 521         sljit_ins inst_bits;
 522         sljit_si op = (flags & 0xffff);
 523         sljit_si reg;
 524         sljit_sw imm, nimm;
 525 
 526         if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {
 527                 /* Both are immediates. */
 528                 flags &= ~ARG1_IMM;
 529                 if (arg1 == 0 && op != SLJIT_ADD && op != SLJIT_SUB)
 530                         arg1 = TMP_ZERO;
 531                 else {
 532                         FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
 533                         arg1 = TMP_REG1;
 534                 }
 535         }
 536 
 537         if (flags & (ARG1_IMM | ARG2_IMM)) {
 538                 reg = (flags & ARG2_IMM) ? arg1 : arg2;
 539                 imm = (flags & ARG2_IMM) ? arg2 : arg1;
 540 
 541                 switch (op) {
 542                 case SLJIT_MUL:
 543                 case SLJIT_NEG:
 544                 case SLJIT_CLZ:
 545                 case SLJIT_ADDC:
 546                 case SLJIT_SUBC:
 547                         /* No form with immediate operand (except imm 0, which
 548                         is represented by a ZERO register). */
 549                         break;
 550                 case SLJIT_MOV:
 551                         SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1);
 552                         return load_immediate(compiler, dst, imm);
 553                 case SLJIT_NOT:
 554                         SLJIT_ASSERT(flags & ARG2_IMM);
 555                         FAIL_IF(load_immediate(compiler, dst, (flags & INT_OP) ? (~imm & 0xffffffff) : ~imm));
 556                         goto set_flags;
 557                 case SLJIT_SUB:
 558                         if (flags & ARG1_IMM)
 559                                 break;
 560                         imm = -imm;
 561                         /* Fall through. */
 562                 case SLJIT_ADD:
 563                         if (imm == 0) {
 564                                 CHECK_FLAGS(1 << 29);
 565                                 return push_inst(compiler, ((op == SLJIT_ADD ? ADDI : SUBI) ^ inv_bits) | RD(dst) | RN(reg));
 566                         }
 567                         if (imm > 0 && imm <= 0xfff) {
 568                                 CHECK_FLAGS(1 << 29);
 569                                 return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | (imm << 10));
 570                         }
 571                         nimm = -imm;
 572                         if (nimm > 0 && nimm <= 0xfff) {
 573                                 CHECK_FLAGS(1 << 29);
 574                                 return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | (nimm << 10));
 575                         }
 576                         if (imm > 0 && imm <= 0xffffff && !(imm & 0xfff)) {
 577                                 CHECK_FLAGS(1 << 29);
 578                                 return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22));
 579                         }
 580                         if (nimm > 0 && nimm <= 0xffffff && !(nimm & 0xfff)) {
 581                                 CHECK_FLAGS(1 << 29);
 582                                 return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22));
 583                         }
 584                         if (imm > 0 && imm <= 0xffffff && !(flags & SET_FLAGS)) {
 585                                 FAIL_IF(push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22)));
 586                                 return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(dst) | ((imm & 0xfff) << 10));
 587                         }
 588                         if (nimm > 0 && nimm <= 0xffffff && !(flags & SET_FLAGS)) {
 589                                 FAIL_IF(push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22)));
 590                                 return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(dst) | ((nimm & 0xfff) << 10));
 591                         }
 592                         break;
 593                 case SLJIT_AND:
 594                         inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32));
 595                         if (!inst_bits)
 596                                 break;
 597                         CHECK_FLAGS(3 << 29);
 598                         return push_inst(compiler, (ANDI ^ inv_bits) | RD(dst) | RN(reg) | inst_bits);
 599                 case SLJIT_OR:
 600                 case SLJIT_XOR:
 601                         inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32));
 602                         if (!inst_bits)
 603                                 break;
 604                         if (op == SLJIT_OR)
 605                                 inst_bits |= ORRI;
 606                         else
 607                                 inst_bits |= EORI;
 608                         FAIL_IF(push_inst(compiler, (inst_bits ^ inv_bits) | RD(dst) | RN(reg)));
 609                         goto set_flags;
 610                 case SLJIT_SHL:
 611                         if (flags & ARG1_IMM)
 612                                 break;
 613                         if (flags & INT_OP) {
 614                                 imm &= 0x1f;
 615                                 FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | ((-imm & 0x1f) << 16) | ((31 - imm) << 10)));
 616                         }
 617                         else {
 618                                 imm &= 0x3f;
 619                                 FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | ((-imm & 0x3f) << 16) | ((63 - imm) << 10)));
 620                         }
 621                         goto set_flags;
 622                 case SLJIT_LSHR:
 623                 case SLJIT_ASHR:
 624                         if (flags & ARG1_IMM)
 625                                 break;
 626                         if (op == SLJIT_ASHR)
 627                                 inv_bits |= 1 << 30;
 628                         if (flags & INT_OP) {
 629                                 imm &= 0x1f;
 630                                 FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (imm << 16) | (31 << 10)));
 631                         }
 632                         else {
 633                                 imm &= 0x3f;
 634                                 FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | (imm << 16) | (63 << 10)));
 635                         }
 636                         goto set_flags;
 637                 default:
 638                         SLJIT_ASSERT_STOP();
 639                         break;
 640                 }
 641 
 642                 if (flags & ARG2_IMM) {
 643                         if (arg2 == 0)
 644                                 arg2 = TMP_ZERO;
 645                         else {
 646                                 FAIL_IF(load_immediate(compiler, TMP_REG2, arg2));
 647                                 arg2 = TMP_REG2;
 648                         }
 649                 }
 650                 else {
 651                         if (arg1 == 0)
 652                                 arg1 = TMP_ZERO;
 653                         else {
 654                                 FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
 655                                 arg1 = TMP_REG1;
 656                         }
 657                 }
 658         }
 659 
 660         /* Both arguments are registers. */
 661         switch (op) {
 662         case SLJIT_MOV:
 663         case SLJIT_MOV_P:
 664         case SLJIT_MOVU:
 665         case SLJIT_MOVU_P:
 666                 SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 667                 if (dst == arg2)
 668                         return SLJIT_SUCCESS;
 669                 return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2));
 670         case SLJIT_MOV_UB:
 671         case SLJIT_MOVU_UB:
 672                 SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 673                 return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (7 << 10));
 674         case SLJIT_MOV_SB:
 675         case SLJIT_MOVU_SB:
 676                 SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 677                 if (!(flags & INT_OP))
 678                         inv_bits |= 1 << 22;
 679                 return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10));
 680         case SLJIT_MOV_UH:
 681         case SLJIT_MOVU_UH:
 682                 SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 683                 return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (15 << 10));
 684         case SLJIT_MOV_SH:
 685         case SLJIT_MOVU_SH:
 686                 SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 687                 if (!(flags & INT_OP))
 688                         inv_bits |= 1 << 22;
 689                 return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10));
 690         case SLJIT_MOV_UI:
 691         case SLJIT_MOVU_UI:
 692                 SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 693                 if ((flags & INT_OP) && dst == arg2)
 694                         return SLJIT_SUCCESS;
 695                 return push_inst(compiler, (ORR ^ (1 << 31)) | RD(dst) | RN(TMP_ZERO) | RM(arg2));
 696         case SLJIT_MOV_SI:
 697         case SLJIT_MOVU_SI:
 698                 SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 699                 if ((flags & INT_OP) && dst == arg2)
 700                         return SLJIT_SUCCESS;
 701                 return push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(arg2) | (31 << 10));
 702         case SLJIT_NOT:
 703                 SLJIT_ASSERT(arg1 == TMP_REG1);
 704                 FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2)));
 705                 goto set_flags;
 706         case SLJIT_NEG:
 707                 SLJIT_ASSERT(arg1 == TMP_REG1);
 708                 if (flags & SET_FLAGS)
 709                         inv_bits |= 1 << 29;
 710                 return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2));
 711         case SLJIT_CLZ:
 712                 SLJIT_ASSERT(arg1 == TMP_REG1);
 713                 FAIL_IF(push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(arg2)));
 714                 goto set_flags;
 715         case SLJIT_ADD:
 716                 CHECK_FLAGS(1 << 29);
 717                 return push_inst(compiler, (ADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
 718         case SLJIT_ADDC:
 719                 CHECK_FLAGS(1 << 29);
 720                 return push_inst(compiler, (ADC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
 721         case SLJIT_SUB:
 722                 CHECK_FLAGS(1 << 29);
 723                 return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
 724         case SLJIT_SUBC:
 725                 CHECK_FLAGS(1 << 29);
 726                 return push_inst(compiler, (SBC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
 727         case SLJIT_MUL:
 728                 if (!(flags & SET_FLAGS))
 729                         return push_inst(compiler, (MADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO));
 730                 if (flags & INT_OP) {
 731                         FAIL_IF(push_inst(compiler, SMADDL | RD(dst) | RN(arg1) | RM(arg2) | (31 << 10)));
 732                         FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(TMP_ZERO) | RM(dst) | (2 << 22) | (31 << 10)));
 733                         return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));
 734                 }
 735                 FAIL_IF(push_inst(compiler, SMULH | RD(TMP_LR) | RN(arg1) | RM(arg2)));
 736                 FAIL_IF(push_inst(compiler, MADD | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO)));
 737                 return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));
 738         case SLJIT_AND:
 739                 CHECK_FLAGS(3 << 29);
 740                 return push_inst(compiler, (AND ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
 741         case SLJIT_OR:
 742                 FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
 743                 goto set_flags;
 744         case SLJIT_XOR:
 745                 FAIL_IF(push_inst(compiler, (EOR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
 746                 goto set_flags;
 747         case SLJIT_SHL:
 748                 FAIL_IF(push_inst(compiler, (LSLV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
 749                 goto set_flags;
 750         case SLJIT_LSHR:
 751                 FAIL_IF(push_inst(compiler, (LSRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
 752                 goto set_flags;
 753         case SLJIT_ASHR:
 754                 FAIL_IF(push_inst(compiler, (ASRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
 755                 goto set_flags;
 756         }
 757 
 758         SLJIT_ASSERT_STOP();
 759         return SLJIT_SUCCESS;
 760 
 761 set_flags:
 762         if (flags & SET_FLAGS)
 763                 return push_inst(compiler, (SUBS ^ inv_bits) | RD(TMP_ZERO) | RN(dst) | RM(TMP_ZERO));
 764         return SLJIT_SUCCESS;
 765 }
 766 
 767 #define STORE           0x01
 768 #define SIGNED          0x02
 769 
 770 #define UPDATE          0x04
 771 #define ARG_TEST        0x08
 772 
 773 #define BYTE_SIZE       0x000
 774 #define HALF_SIZE       0x100
 775 #define INT_SIZE        0x200
 776 #define WORD_SIZE       0x300
 777 
 778 #define MEM_SIZE_SHIFT(flags) ((flags) >> 8)
 779 
 780 static SLJIT_CONST sljit_ins sljit_mem_imm[4] = {
 781 /* u l */ 0x39400000 /* ldrb [reg,imm] */,
 782 /* u s */ 0x39000000 /* strb [reg,imm] */,
 783 /* s l */ 0x39800000 /* ldrsb [reg,imm] */,
 784 /* s s */ 0x39000000 /* strb [reg,imm] */,
 785 };
 786 
 787 static SLJIT_CONST sljit_ins sljit_mem_simm[4] = {
 788 /* u l */ 0x38400000 /* ldurb [reg,imm] */,
 789 /* u s */ 0x38000000 /* sturb [reg,imm] */,
 790 /* s l */ 0x38800000 /* ldursb [reg,imm] */,
 791 /* s s */ 0x38000000 /* sturb [reg,imm] */,
 792 };
 793 
 794 static SLJIT_CONST sljit_ins sljit_mem_pre_simm[4] = {
 795 /* u l */ 0x38400c00 /* ldrb [reg,imm]! */,
 796 /* u s */ 0x38000c00 /* strb [reg,imm]! */,
 797 /* s l */ 0x38800c00 /* ldrsb [reg,imm]! */,
 798 /* s s */ 0x38000c00 /* strb [reg,imm]! */,
 799 };
 800 
 801 static SLJIT_CONST sljit_ins sljit_mem_reg[4] = {
 802 /* u l */ 0x38606800 /* ldrb [reg,reg] */,
 803 /* u s */ 0x38206800 /* strb [reg,reg] */,
 804 /* s l */ 0x38a06800 /* ldrsb [reg,reg] */,
 805 /* s s */ 0x38206800 /* strb [reg,reg] */,
 806 };
 807 
 808 /* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
 809 static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value)
 810 {
 811         if (value >= 0) {
 812                 if (value <= 0xfff)
 813                         return push_inst(compiler, ADDI | RD(dst) | RN(reg) | (value << 10));
 814                 if (value <= 0xffffff && !(value & 0xfff))
 815                         return push_inst(compiler, ADDI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2));
 816         }
 817         else {
 818                 value = -value;
 819                 if (value <= 0xfff)
 820                         return push_inst(compiler, SUBI | RD(dst) | RN(reg) | (value << 10));
 821                 if (value <= 0xffffff && !(value & 0xfff))
 822                         return push_inst(compiler, SUBI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2));
 823         }
 824         return SLJIT_ERR_UNSUPPORTED;
 825 }
 826 
 827 /* Can perform an operation using at most 1 instruction. */
 828 static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
 829 {
 830         sljit_ui shift = MEM_SIZE_SHIFT(flags);
 831 
 832         SLJIT_ASSERT(arg & SLJIT_MEM);
 833 
 834         if (SLJIT_UNLIKELY(flags & UPDATE)) {
 835                 if ((arg & REG_MASK) && !(arg & OFFS_REG_MASK) && argw <= 255 && argw >= -256) {
 836                         if (SLJIT_UNLIKELY(flags & ARG_TEST))
 837                                 return 1;
 838 
 839                         arg &= REG_MASK;
 840                         argw &= 0x1ff;
 841                         FAIL_IF(push_inst(compiler, sljit_mem_pre_simm[flags & 0x3]
 842                                 | (shift << 30) | RT(reg) | RN(arg) | (argw << 12)));
 843                         return -1;
 844                 }
 845                 return 0;
 846         }
 847 
 848         if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
 849                 argw &= 0x3;
 850                 if (argw && argw != shift)
 851                         return 0;
 852 
 853                 if (SLJIT_UNLIKELY(flags & ARG_TEST))
 854                         return 1;
 855 
 856                 FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg)
 857                         | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0)));
 858                 return -1;
 859         }
 860 
 861         arg &= REG_MASK;
 862         if (argw >= 0 && (argw >> shift) <= 0xfff && (argw & ((1 << shift) - 1)) == 0) {
 863                 if (SLJIT_UNLIKELY(flags & ARG_TEST))
 864                         return 1;
 865 
 866                 FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30)
 867                         | RT(reg) | RN(arg) | (argw << (10 - shift))));
 868                 return -1;
 869         }
 870 
 871         if (argw > 255 || argw < -256)
 872                 return 0;
 873 
 874         if (SLJIT_UNLIKELY(flags & ARG_TEST))
 875                 return 1;
 876 
 877         FAIL_IF(push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30)
 878                 | RT(reg) | RN(arg) | ((argw & 0x1ff) << 12)));
 879         return -1;
 880 }
 881 
 882 /* see getput_arg below.
 883    Note: can_cache is called only for binary operators. Those
 884    operators always uses word arguments without write back. */
 885 static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
 886 {
 887         sljit_sw diff;
 888         if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM))
 889                 return 0;
 890 
 891         if (!(arg & REG_MASK)) {
 892                 diff = argw - next_argw;
 893                 if (diff <= 0xfff && diff >= -0xfff)
 894                         return 1;
 895                 return 0;
 896         }
 897 
 898         if (argw == next_argw)
 899                 return 1;
 900 
 901         diff = argw - next_argw;
 902         if (arg == next_arg && diff <= 0xfff && diff >= -0xfff)
 903                 return 1;
 904 
 905         return 0;
 906 }
 907 
 908 /* Emit the necessary instructions. See can_cache above. */
 909 static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg,
 910         sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
 911 {
 912         sljit_ui shift = MEM_SIZE_SHIFT(flags);
 913         sljit_si tmp_r, other_r;
 914         sljit_sw diff;
 915 
 916         SLJIT_ASSERT(arg & SLJIT_MEM);
 917         if (!(next_arg & SLJIT_MEM)) {
 918                 next_arg = 0;
 919                 next_argw = 0;
 920         }
 921 
 922         tmp_r = (flags & STORE) ? TMP_REG3 : reg;
 923 
 924         if (SLJIT_UNLIKELY((flags & UPDATE) && (arg & REG_MASK))) {
 925                 /* Update only applies if a base register exists. */
 926                 other_r = OFFS_REG(arg);
 927                 if (!other_r) {
 928                         other_r = arg & REG_MASK;
 929                         if (other_r != reg && argw >= 0 && argw <= 0xffffff) {
 930                                 if ((argw & 0xfff) != 0)
 931                                         FAIL_IF(push_inst(compiler, ADDI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10)));
 932                                 if (argw >> 12)
 933                                         FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10)));
 934                                 return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r));
 935                         }
 936                         else if (other_r != reg && argw < 0 && argw >= -0xffffff) {
 937                                 argw = -argw;
 938                                 if ((argw & 0xfff) != 0)
 939                                         FAIL_IF(push_inst(compiler, SUBI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10)));
 940                                 if (argw >> 12)
 941                                         FAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10)));
 942                                 return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r));
 943                         }
 944 
 945                         if (compiler->cache_arg == SLJIT_MEM) {
 946                                 if (argw == compiler->cache_argw) {
 947                                         other_r = TMP_REG3;
 948                                         argw = 0;
 949                                 }
 950                                 else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
 951                                         FAIL_IF(compiler->error);
 952                                         compiler->cache_argw = argw;
 953                                         other_r = TMP_REG3;
 954                                         argw = 0;
 955                                 }
 956                         }
 957 
 958                         if (argw) {
 959                                 FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
 960                                 compiler->cache_arg = SLJIT_MEM;
 961                                 compiler->cache_argw = argw;
 962                                 other_r = TMP_REG3;
 963                                 argw = 0;
 964                         }
 965                 }
 966 
 967                 /* No caching here. */
 968                 arg &= REG_MASK;
 969                 argw &= 0x3;
 970                 if (!argw || argw == shift) {
 971                         FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(other_r) | (argw ? (1 << 12) : 0)));
 972                         return push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10));
 973                 }
 974                 if (arg != reg) {
 975                         FAIL_IF(push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10)));
 976                         return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg));
 977                 }
 978                 FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(arg) | RM(other_r) | (argw << 10)));
 979                 FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_LR)));
 980                 return push_inst(compiler, ORR | RD(arg) | RN(TMP_ZERO) | RM(TMP_LR));
 981         }
 982 
 983         if (arg & OFFS_REG_MASK) {
 984                 other_r = OFFS_REG(arg);
 985                 arg &= REG_MASK;
 986                 FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RN(arg) | RM(other_r) | ((argw & 0x3) << 10)));
 987                 return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(tmp_r));
 988         }
 989 
 990         if (compiler->cache_arg == arg) {
 991                 diff = argw - compiler->cache_argw;
 992                 if (diff <= 255 && diff >= -256)
 993                         return push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30)
 994                                 | RT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12));
 995                 if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, diff) != SLJIT_ERR_UNSUPPORTED) {
 996                         FAIL_IF(compiler->error);
 997                         return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg));
 998                 }
 999         }
1000 
1001         if (argw >= 0 && argw <= 0xffffff && (argw & ((1 << shift) - 1)) == 0) {
1002                 FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_r) | RN(arg & REG_MASK) | ((argw >> 12) << 10)));
1003                 return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30)
1004                         | RT(reg) | RN(tmp_r) | ((argw & 0xfff) << (10 - shift)));
1005         }
1006 
1007         diff = argw - next_argw;
1008         next_arg = (arg & REG_MASK) && (arg == next_arg) && diff <= 0xfff && diff >= -0xfff && diff != 0;
1009         arg &= REG_MASK;
1010 
1011         if (arg && compiler->cache_arg == SLJIT_MEM) {
1012                 if (compiler->cache_argw == argw)
1013                         return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3));
1014                 if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
1015                         FAIL_IF(compiler->error);
1016                         compiler->cache_argw = argw;
1017                         return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3));
1018                 }
1019         }
1020 
1021         compiler->cache_argw = argw;
1022         if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) {
1023                 FAIL_IF(compiler->error);
1024                 compiler->cache_arg = SLJIT_MEM | arg;
1025                 arg = 0;
1026         }
1027         else {
1028                 FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
1029                 compiler->cache_arg = SLJIT_MEM;
1030 
1031                 if (next_arg) {
1032                         FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG3) | RN(TMP_REG3) | RM(arg)));
1033                         compiler->cache_arg = SLJIT_MEM | arg;
1034                         arg = 0;
1035                 }
1036         }
1037 
1038         if (arg)
1039                 return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3));
1040         return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_REG3));
1041 }
1042 
1043 static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
1044 {
1045         if (getput_arg_fast(compiler, flags, reg, arg, argw))
1046                 return compiler->error;
1047         compiler->cache_arg = 0;
1048         compiler->cache_argw = 0;
1049         return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
1050 }
1051 
1052 static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w)
1053 {
1054         if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
1055                 return compiler->error;
1056         return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
1057 }
1058 
1059 /* --------------------------------------------------------------------- */
1060 /*  Entry, exit                                                          */
1061 /* --------------------------------------------------------------------- */
1062 
1063 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
1064         sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
1065         sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
1066 {
1067         sljit_si i, tmp, offs, prev, saved_regs_size;
1068 
1069         CHECK_ERROR();
1070         CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
1071         set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
1072 
1073         saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0);
1074         local_size += saved_regs_size + SLJIT_LOCALS_OFFSET;
1075         local_size = (local_size + 15) & ~0xf;
1076         compiler->local_size = local_size;
1077 
1078         if (local_size <= (63 * sizeof(sljit_sw))) {
1079                 FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR)
1080                         | RN(TMP_SP) | ((-(local_size >> 3) & 0x7f) << 15)));
1081                 FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10)));
1082                 offs = (local_size - saved_regs_size) << (15 - 3);
1083         } else {
1084                 offs = 0 << 15;
1085                 if (saved_regs_size & 0x8) {
1086                         offs = 1 << 15;
1087                         saved_regs_size += sizeof(sljit_sw);
1088                 }
1089                 local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET;
1090                 if (saved_regs_size > 0)
1091                         FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
1092         }
1093 
1094         tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
1095         prev = -1;
1096         for (i = SLJIT_S0; i >= tmp; i--) {
1097                 if (prev == -1) {
1098                         if (!(offs & (1 << 15))) {
1099                                 prev = i;
1100                                 continue;
1101                         }
1102                         FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
1103                         offs += 1 << 15;
1104                         continue;
1105                 }
1106                 FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
1107                 offs += 2 << 15;
1108                 prev = -1;
1109         }
1110 
1111         for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
1112                 if (prev == -1) {
1113                         if (!(offs & (1 << 15))) {
1114                                 prev = i;
1115                                 continue;
1116                         }
1117                         FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
1118                         offs += 1 << 15;
1119                         continue;
1120                 }
1121                 FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
1122                 offs += 2 << 15;
1123                 prev = -1;
1124         }
1125 
1126         SLJIT_ASSERT(prev == -1);
1127 
1128         if (compiler->local_size > (63 * sizeof(sljit_sw))) {
1129                 /* The local_size is already adjusted by the saved registers. */
1130                 if (local_size > 0xfff) {
1131                         FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22)));
1132                         local_size &= 0xfff;
1133                 }
1134                 if (local_size)
1135                         FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10)));
1136                 FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR)
1137                         | RN(TMP_SP) | ((-(16 >> 3) & 0x7f) << 15)));
1138                 FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10)));
1139         }
1140 
1141         if (args >= 1)
1142                 FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S0) | RN(TMP_ZERO) | RM(SLJIT_R0)));
1143         if (args >= 2)
1144                 FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S1) | RN(TMP_ZERO) | RM(SLJIT_R1)));
1145         if (args >= 3)
1146                 FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S2) | RN(TMP_ZERO) | RM(SLJIT_R2)));
1147 
1148         return SLJIT_SUCCESS;
1149 }
1150 
1151 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
1152         sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
1153         sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
1154 {
1155         CHECK_ERROR();
1156         CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
1157         set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
1158 
1159         local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0) + SLJIT_LOCALS_OFFSET;
1160         local_size = (local_size + 15) & ~0xf;
1161         compiler->local_size = local_size;
1162         return SLJIT_SUCCESS;
1163 }
1164 
1165 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
1166 {
1167         sljit_si local_size;
1168         sljit_si i, tmp, offs, prev, saved_regs_size;
1169 
1170         CHECK_ERROR();
1171         CHECK(check_sljit_emit_return(compiler, op, src, srcw));
1172 
1173         FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
1174 
1175         local_size = compiler->local_size;
1176 
1177         saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 0);
1178         if (local_size <= (63 * sizeof(sljit_sw)))
1179                 offs = (local_size - saved_regs_size) << (15 - 3);
1180         else {
1181                 FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
1182                         | RN(TMP_SP) | (((16 >> 3) & 0x7f) << 15)));
1183                 offs = 0 << 15;
1184                 if (saved_regs_size & 0x8) {
1185                         offs = 1 << 15;
1186                         saved_regs_size += sizeof(sljit_sw);
1187                 }
1188                 local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET;
1189                 if (local_size > 0xfff) {
1190                         FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22)));
1191                         local_size &= 0xfff;
1192                 }
1193                 if (local_size)
1194                         FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10)));
1195         }
1196 
1197         tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
1198         prev = -1;
1199         for (i = SLJIT_S0; i >= tmp; i--) {
1200                 if (prev == -1) {
1201                         if (!(offs & (1 << 15))) {
1202                                 prev = i;
1203                                 continue;
1204                         }
1205                         FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
1206                         offs += 1 << 15;
1207                         continue;
1208                 }
1209                 FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
1210                 offs += 2 << 15;
1211                 prev = -1;
1212         }
1213 
1214         for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
1215                 if (prev == -1) {
1216                         if (!(offs & (1 << 15))) {
1217                                 prev = i;
1218                                 continue;
1219                         }
1220                         FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
1221                         offs += 1 << 15;
1222                         continue;
1223                 }
1224                 FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
1225                 offs += 2 << 15;
1226                 prev = -1;
1227         }
1228 
1229         SLJIT_ASSERT(prev == -1);
1230 
1231         if (compiler->local_size <= (63 * sizeof(sljit_sw))) {
1232                 FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
1233                         | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15)));
1234         } else if (saved_regs_size > 0) {
1235                 FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
1236         }
1237 
1238         FAIL_IF(push_inst(compiler, RET | RN(TMP_LR)));
1239         return SLJIT_SUCCESS;
1240 }
1241 
1242 /* --------------------------------------------------------------------- */
1243 /*  Operators                                                            */
1244 /* --------------------------------------------------------------------- */
1245 
1246 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
1247 {
1248         sljit_ins inv_bits = (op & SLJIT_INT_OP) ? (1 << 31) : 0;
1249 
1250         CHECK_ERROR();
1251         CHECK(check_sljit_emit_op0(compiler, op));
1252 
1253         op = GET_OPCODE(op);
1254         switch (op) {
1255         case SLJIT_BREAKPOINT:
1256                 return push_inst(compiler, BRK);
1257         case SLJIT_NOP:
1258                 return push_inst(compiler, NOP);
1259         case SLJIT_LUMUL:
1260         case SLJIT_LSMUL:
1261                 FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
1262                 FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
1263                 return push_inst(compiler, (op == SLJIT_LUMUL ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
1264         case SLJIT_UDIVMOD:
1265         case SLJIT_SDIVMOD:
1266                 FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
1267                 FAIL_IF(push_inst(compiler, ((op == SLJIT_UDIVMOD ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));
1268                 FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
1269                 return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
1270         case SLJIT_UDIVI:
1271         case SLJIT_SDIVI:
1272                 return push_inst(compiler, ((op == SLJIT_UDIVI ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1));
1273         }
1274 
1275         return SLJIT_SUCCESS;
1276 }
1277 
1278 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
1279         sljit_si dst, sljit_sw dstw,
1280         sljit_si src, sljit_sw srcw)
1281 {
1282         sljit_si dst_r, flags, mem_flags;
1283         sljit_si op_flags = GET_ALL_FLAGS(op);
1284 
1285         CHECK_ERROR();
1286         CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
1287         ADJUST_LOCAL_OFFSET(dst, dstw);
1288         ADJUST_LOCAL_OFFSET(src, srcw);
1289 
1290         compiler->cache_arg = 0;
1291         compiler->cache_argw = 0;
1292 
1293         dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
1294 
1295         op = GET_OPCODE(op);
1296         if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
1297                 switch (op) {
1298                 case SLJIT_MOV:
1299                 case SLJIT_MOV_P:
1300                         flags = WORD_SIZE;
1301                         break;
1302                 case SLJIT_MOV_UB:
1303                         flags = BYTE_SIZE;
1304                         if (src & SLJIT_IMM)
1305                                 srcw = (sljit_ub)srcw;
1306                         break;
1307                 case SLJIT_MOV_SB:
1308                         flags = BYTE_SIZE | SIGNED;
1309                         if (src & SLJIT_IMM)
1310                                 srcw = (sljit_sb)srcw;
1311                         break;
1312                 case SLJIT_MOV_UH:
1313                         flags = HALF_SIZE;
1314                         if (src & SLJIT_IMM)
1315                                 srcw = (sljit_uh)srcw;
1316                         break;
1317                 case SLJIT_MOV_SH:
1318                         flags = HALF_SIZE | SIGNED;
1319                         if (src & SLJIT_IMM)
1320                                 srcw = (sljit_sh)srcw;
1321                         break;
1322                 case SLJIT_MOV_UI:
1323                         flags = INT_SIZE;
1324                         if (src & SLJIT_IMM)
1325                                 srcw = (sljit_ui)srcw;
1326                         break;
1327                 case SLJIT_MOV_SI:
1328                         flags = INT_SIZE | SIGNED;
1329                         if (src & SLJIT_IMM)
1330                                 srcw = (sljit_si)srcw;
1331                         break;
1332                 case SLJIT_MOVU:
1333                 case SLJIT_MOVU_P:
1334                         flags = WORD_SIZE | UPDATE;
1335                         break;
1336                 case SLJIT_MOVU_UB:
1337                         flags = BYTE_SIZE | UPDATE;
1338                         if (src & SLJIT_IMM)
1339                                 srcw = (sljit_ub)srcw;
1340                         break;
1341                 case SLJIT_MOVU_SB:
1342                         flags = BYTE_SIZE | SIGNED | UPDATE;
1343                         if (src & SLJIT_IMM)
1344                                 srcw = (sljit_sb)srcw;
1345                         break;
1346                 case SLJIT_MOVU_UH:
1347                         flags = HALF_SIZE | UPDATE;
1348                         if (src & SLJIT_IMM)
1349                                 srcw = (sljit_uh)srcw;
1350                         break;
1351                 case SLJIT_MOVU_SH:
1352                         flags = HALF_SIZE | SIGNED | UPDATE;
1353                         if (src & SLJIT_IMM)
1354                                 srcw = (sljit_sh)srcw;
1355                         break;
1356                 case SLJIT_MOVU_UI:
1357                         flags = INT_SIZE | UPDATE;
1358                         if (src & SLJIT_IMM)
1359                                 srcw = (sljit_ui)srcw;
1360                         break;
1361                 case SLJIT_MOVU_SI:
1362                         flags = INT_SIZE | SIGNED | UPDATE;
1363                         if (src & SLJIT_IMM)
1364                                 srcw = (sljit_si)srcw;
1365                         break;
1366                 default:
1367                         SLJIT_ASSERT_STOP();
1368                         flags = 0;
1369                         break;
1370                 }
1371 
1372                 if (src & SLJIT_IMM)
1373                         FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw));
1374                 else if (src & SLJIT_MEM) {
1375                         if (getput_arg_fast(compiler, flags, dst_r, src, srcw))
1376                                 FAIL_IF(compiler->error);
1377                         else
1378                                 FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw));
1379                 } else {
1380                         if (dst_r != TMP_REG1)
1381                                 return emit_op_imm(compiler, op | ((op_flags & SLJIT_INT_OP) ? INT_OP : 0), dst_r, TMP_REG1, src);
1382                         dst_r = src;
1383                 }
1384 
1385                 if (dst & SLJIT_MEM) {
1386                         if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw))
1387                                 return compiler->error;
1388                         else
1389                                 return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0);
1390                 }
1391                 return SLJIT_SUCCESS;
1392         }
1393 
1394         flags = GET_FLAGS(op_flags) ? SET_FLAGS : 0;
1395         mem_flags = WORD_SIZE;
1396         if (op_flags & SLJIT_INT_OP) {
1397                 flags |= INT_OP;
1398                 mem_flags = INT_SIZE;
1399         }
1400 
1401         if (dst == SLJIT_UNUSED)
1402                 flags |= UNUSED_RETURN;
1403 
1404         if (src & SLJIT_MEM) {
1405                 if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src, srcw))
1406                         FAIL_IF(compiler->error);
1407                 else
1408                         FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src, srcw, dst, dstw));
1409                 src = TMP_REG2;
1410         }
1411 
1412         if (src & SLJIT_IMM) {
1413                 flags |= ARG2_IMM;
1414                 if (op_flags & SLJIT_INT_OP)
1415                         srcw = (sljit_si)srcw;
1416         } else
1417                 srcw = src;
1418 
1419         emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw);
1420 
1421         if (dst & SLJIT_MEM) {
1422                 if (getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw))
1423                         return compiler->error;
1424                 else
1425                         return getput_arg(compiler, mem_flags | STORE, dst_r, dst, dstw, 0, 0);
1426         }
1427         return SLJIT_SUCCESS;
1428 }
1429 
1430 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
1431         sljit_si dst, sljit_sw dstw,
1432         sljit_si src1, sljit_sw src1w,
1433         sljit_si src2, sljit_sw src2w)
1434 {
1435         sljit_si dst_r, flags, mem_flags;
1436 
1437         CHECK_ERROR();
1438         CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
1439         ADJUST_LOCAL_OFFSET(dst, dstw);
1440         ADJUST_LOCAL_OFFSET(src1, src1w);
1441         ADJUST_LOCAL_OFFSET(src2, src2w);
1442 
1443         compiler->cache_arg = 0;
1444         compiler->cache_argw = 0;
1445 
1446         dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
1447         flags = GET_FLAGS(op) ? SET_FLAGS : 0;
1448         mem_flags = WORD_SIZE;
1449         if (op & SLJIT_INT_OP) {
1450                 flags |= INT_OP;
1451                 mem_flags = INT_SIZE;
1452         }
1453 
1454         if (dst == SLJIT_UNUSED)
1455                 flags |= UNUSED_RETURN;
1456 
1457         if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, mem_flags | STORE | ARG_TEST, TMP_REG1, dst, dstw))
1458                 flags |= SLOW_DEST;
1459 
1460         if (src1 & SLJIT_MEM) {
1461                 if (getput_arg_fast(compiler, mem_flags, TMP_REG1, src1, src1w))
1462                         FAIL_IF(compiler->error);
1463                 else
1464                         flags |= SLOW_SRC1;
1465         }
1466         if (src2 & SLJIT_MEM) {
1467                 if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src2, src2w))
1468                         FAIL_IF(compiler->error);
1469                 else
1470                         flags |= SLOW_SRC2;
1471         }
1472 
1473         if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
1474                 if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
1475                         FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, src1, src1w));
1476                         FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw));
1477                 }
1478                 else {
1479                         FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, src2, src2w));
1480                         FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw));
1481                 }
1482         }
1483         else if (flags & SLOW_SRC1)
1484                 FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw));
1485         else if (flags & SLOW_SRC2)
1486                 FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw));
1487 
1488         if (src1 & SLJIT_MEM)
1489                 src1 = TMP_REG1;
1490         if (src2 & SLJIT_MEM)
1491                 src2 = TMP_REG2;
1492 
1493         if (src1 & SLJIT_IMM)
1494                 flags |= ARG1_IMM;
1495         else
1496                 src1w = src1;
1497         if (src2 & SLJIT_IMM)
1498                 flags |= ARG2_IMM;
1499         else
1500                 src2w = src2;
1501 
1502         emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w);
1503 
1504         if (dst & SLJIT_MEM) {
1505                 if (!(flags & SLOW_DEST)) {
1506                         getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw);
1507                         return compiler->error;
1508                 }
1509                 return getput_arg(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0);
1510         }
1511 
1512         return SLJIT_SUCCESS;
1513 }
1514 
1515 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
1516 {
1517         CHECK_REG_INDEX(check_sljit_get_register_index(reg));
1518         return reg_map[reg];
1519 }
1520 
1521 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
1522 {
1523         CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
1524         return reg;
1525 }
1526 
1527 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
1528         void *instruction, sljit_si size)
1529 {
1530         CHECK_ERROR();
1531         CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
1532 
1533         return push_inst(compiler, *(sljit_ins*)instruction);
1534 }
1535 
1536 /* --------------------------------------------------------------------- */
1537 /*  Floating point operators                                             */
1538 /* --------------------------------------------------------------------- */
1539 
1540 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
1541 {
1542 #ifdef SLJIT_IS_FPU_AVAILABLE
1543         return SLJIT_IS_FPU_AVAILABLE;
1544 #else
1545         /* Available by default. */
1546         return 1;
1547 #endif
1548 }
1549 
1550 static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
1551 {
1552         sljit_ui shift = MEM_SIZE_SHIFT(flags);
1553         sljit_ins ins_bits = (shift << 30);
1554         sljit_si other_r;
1555         sljit_sw diff;
1556 
1557         SLJIT_ASSERT(arg & SLJIT_MEM);
1558 
1559         if (!(flags & STORE))
1560                 ins_bits |= 1 << 22;
1561 
1562         if (arg & OFFS_REG_MASK) {
1563                 argw &= 3;
1564                 if (!argw || argw == shift)
1565                         return push_inst(compiler, STR_FR | ins_bits | VT(reg)
1566                                 | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0));
1567                 other_r = OFFS_REG(arg);
1568                 arg &= REG_MASK;
1569                 FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg) | RM(other_r) | (argw << 10)));
1570                 arg = TMP_REG1;
1571                 argw = 0;
1572         }
1573 
1574         arg &= REG_MASK;
1575         if (arg && argw >= 0 && ((argw >> shift) <= 0xfff) && (argw & ((1 << shift) - 1)) == 0)
1576                 return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(arg) | (argw << (10 - shift)));
1577 
1578         if (arg && argw <= 255 && argw >= -256)
1579                 return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(arg) | ((argw & 0x1ff) << 12));
1580 
1581         /* Slow cases */
1582         if (compiler->cache_arg == SLJIT_MEM && argw != compiler->cache_argw) {
1583                 diff = argw - compiler->cache_argw;
1584                 if (!arg && diff <= 255 && diff >= -256)
1585                         return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12));
1586                 if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
1587                         FAIL_IF(compiler->error);
1588                         compiler->cache_argw = argw;
1589                 }
1590         }
1591 
1592         if (compiler->cache_arg != SLJIT_MEM || argw != compiler->cache_argw) {
1593                 compiler->cache_arg = SLJIT_MEM;
1594                 compiler->cache_argw = argw;
1595                 FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
1596         }
1597 
1598         if (arg & REG_MASK)
1599                 return push_inst(compiler, STR_FR | ins_bits | VT(reg) | RN(arg) | RM(TMP_REG3));
1600         return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(TMP_REG3));
1601 }
1602 
1603 static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
1604         sljit_si dst, sljit_sw dstw,
1605         sljit_si src, sljit_sw srcw)
1606 {
1607         sljit_si dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
1608         sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
1609 
1610         if (GET_OPCODE(op) == SLJIT_CONVI_FROMD)
1611                 inv_bits |= (1 << 31);
1612 
1613         if (src & SLJIT_MEM) {
1614                 emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw);
1615                 src = TMP_FREG1;
1616         }
1617 
1618         FAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src)));
1619 
1620         if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED)
1621                 return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVI_FROMD) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw);
1622         return SLJIT_SUCCESS;
1623 }
1624 
1625 static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
1626         sljit_si dst, sljit_sw dstw,
1627         sljit_si src, sljit_sw srcw)
1628 {
1629         sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1630         sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
1631 
1632         if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
1633                 inv_bits |= (1 << 31);
1634 
1635         if (src & SLJIT_MEM) {
1636                 emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVD_FROMI) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw);
1637                 src = TMP_REG1;
1638         } else if (src & SLJIT_IMM) {
1639 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1640                 if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
1641                         srcw = (sljit_si)srcw;
1642 #endif
1643                 FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
1644                 src = TMP_REG1;
1645         }
1646 
1647         FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src)));
1648 
1649         if (dst & SLJIT_MEM)
1650                 return emit_fop_mem(compiler, ((op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw);
1651         return SLJIT_SUCCESS;
1652 }
1653 
1654 static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
1655         sljit_si src1, sljit_sw src1w,
1656         sljit_si src2, sljit_sw src2w)
1657 {
1658         sljit_si mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE;
1659         sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
1660 
1661         if (src1 & SLJIT_MEM) {
1662                 emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);
1663                 src1 = TMP_FREG1;
1664         }
1665 
1666         if (src2 & SLJIT_MEM) {
1667                 emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w);
1668                 src2 = TMP_FREG2;
1669         }
1670 
1671         return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2));
1672 }
1673 
1674 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
1675         sljit_si dst, sljit_sw dstw,
1676         sljit_si src, sljit_sw srcw)
1677 {
1678         sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE;
1679         sljit_ins inv_bits;
1680 
1681         CHECK_ERROR();
1682         compiler->cache_arg = 0;
1683         compiler->cache_argw = 0;
1684 
1685         SLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x100) == WORD_SIZE, must_be_one_bit_difference);
1686         SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
1687 
1688         inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
1689         dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1690 
1691         if (src & SLJIT_MEM) {
1692                 emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONVD_FROMS) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw);
1693                 src = dst_r;
1694         }
1695 
1696         switch (GET_OPCODE(op)) {
1697         case SLJIT_DMOV:
1698                 if (src != dst_r) {
1699                         if (dst_r != TMP_FREG1)
1700                                 FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src)));
1701                         else
1702                                 dst_r = src;
1703                 }
1704                 break;
1705         case SLJIT_DNEG:
1706                 FAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src)));
1707                 break;
1708         case SLJIT_DABS:
1709                 FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src)));
1710                 break;
1711         case SLJIT_CONVD_FROMS:
1712                 FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_SINGLE_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src)));
1713                 break;
1714         }
1715 
1716         if (dst & SLJIT_MEM)
1717                 return emit_fop_mem(compiler, mem_flags | STORE, dst_r, dst, dstw);
1718         return SLJIT_SUCCESS;
1719 }
1720 
1721 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
1722         sljit_si dst, sljit_sw dstw,
1723         sljit_si src1, sljit_sw src1w,
1724         sljit_si src2, sljit_sw src2w)
1725 {
1726         sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE;
1727         sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
1728 
1729         CHECK_ERROR();
1730         CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
1731         ADJUST_LOCAL_OFFSET(dst, dstw);
1732         ADJUST_LOCAL_OFFSET(src1, src1w);
1733         ADJUST_LOCAL_OFFSET(src2, src2w);
1734 
1735         compiler->cache_arg = 0;
1736         compiler->cache_argw = 0;
1737 
1738         dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1739         if (src1 & SLJIT_MEM) {
1740                 emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);
1741                 src1 = TMP_FREG1;
1742         }
1743         if (src2 & SLJIT_MEM) {
1744                 emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w);
1745                 src2 = TMP_FREG2;
1746         }
1747 
1748         switch (GET_OPCODE(op)) {
1749         case SLJIT_DADD:
1750                 FAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
1751                 break;
1752         case SLJIT_DSUB:
1753                 FAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
1754                 break;
1755         case SLJIT_DMUL:
1756                 FAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
1757                 break;
1758         case SLJIT_DDIV:
1759                 FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
1760                 break;
1761         }
1762 
1763         if (!(dst & SLJIT_MEM))
1764                 return SLJIT_SUCCESS;
1765         return emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw);
1766 }
1767 
1768 /* --------------------------------------------------------------------- */
1769 /*  Other instructions                                                   */
1770 /* --------------------------------------------------------------------- */
1771 
1772 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
1773 {
1774         CHECK_ERROR();
1775         CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
1776         ADJUST_LOCAL_OFFSET(dst, dstw);
1777 
1778         /* For UNUSED dst. Uncommon, but possible. */
1779         if (dst == SLJIT_UNUSED)
1780                 return SLJIT_SUCCESS;
1781 
1782         if (FAST_IS_REG(dst))
1783                 return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(TMP_LR));
1784 
1785         /* Memory. */
1786         return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw);
1787 }
1788 
1789 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
1790 {
1791         CHECK_ERROR();
1792         CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
1793         ADJUST_LOCAL_OFFSET(src, srcw);
1794 
1795         if (FAST_IS_REG(src))
1796                 FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src)));
1797         else if (src & SLJIT_MEM)
1798                 FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw));
1799         else if (src & SLJIT_IMM)
1800                 FAIL_IF(load_immediate(compiler, TMP_LR, srcw));
1801 
1802         return push_inst(compiler, RET | RN(TMP_LR));
1803 }
1804 
1805 /* --------------------------------------------------------------------- */
1806 /*  Conditional instructions                                             */
1807 /* --------------------------------------------------------------------- */
1808 
1809 static sljit_uw get_cc(sljit_si type)
1810 {
1811         switch (type) {
1812         case SLJIT_EQUAL:
1813         case SLJIT_MUL_NOT_OVERFLOW:
1814         case SLJIT_D_EQUAL:
1815                 return 0x1;
1816 
1817         case SLJIT_NOT_EQUAL:
1818         case SLJIT_MUL_OVERFLOW:
1819         case SLJIT_D_NOT_EQUAL:
1820                 return 0x0;
1821 
1822         case SLJIT_LESS:
1823         case SLJIT_D_LESS:
1824                 return 0x2;
1825 
1826         case SLJIT_GREATER_EQUAL:
1827         case SLJIT_D_GREATER_EQUAL:
1828                 return 0x3;
1829 
1830         case SLJIT_GREATER:
1831         case SLJIT_D_GREATER:
1832                 return 0x9;
1833 
1834         case SLJIT_LESS_EQUAL:
1835         case SLJIT_D_LESS_EQUAL:
1836                 return 0x8;
1837 
1838         case SLJIT_SIG_LESS:
1839                 return 0xa;
1840 
1841         case SLJIT_SIG_GREATER_EQUAL:
1842                 return 0xb;
1843 
1844         case SLJIT_SIG_GREATER:
1845                 return 0xd;
1846 
1847         case SLJIT_SIG_LESS_EQUAL:
1848                 return 0xc;
1849 
1850         case SLJIT_OVERFLOW:
1851         case SLJIT_D_UNORDERED:
1852                 return 0x7;
1853 
1854         case SLJIT_NOT_OVERFLOW:
1855         case SLJIT_D_ORDERED:
1856                 return 0x6;
1857 
1858         default:
1859                 SLJIT_ASSERT_STOP();
1860                 return 0xe;
1861         }
1862 }
1863 
1864 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
1865 {
1866         struct sljit_label *label;
1867 
1868         CHECK_ERROR_PTR();
1869         CHECK_PTR(check_sljit_emit_label(compiler));
1870 
1871         if (compiler->last_label && compiler->last_label->size == compiler->size)
1872                 return compiler->last_label;
1873 
1874         label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
1875         PTR_FAIL_IF(!label);
1876         set_label(label, compiler);
1877         return label;
1878 }
1879 
1880 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
1881 {
1882         struct sljit_jump *jump;
1883 
1884         CHECK_ERROR_PTR();
1885         CHECK_PTR(check_sljit_emit_jump(compiler, type));
1886 
1887         jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
1888         PTR_FAIL_IF(!jump);
1889         set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
1890         type &= 0xff;
1891 
1892         if (type < SLJIT_JUMP) {
1893                 jump->flags |= IS_COND;
1894                 PTR_FAIL_IF(push_inst(compiler, B_CC | (6 << 5) | get_cc(type)));
1895         }
1896         else if (type >= SLJIT_FAST_CALL)
1897                 jump->flags |= IS_BL;
1898 
1899         PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
1900         jump->addr = compiler->size;
1901         PTR_FAIL_IF(push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1)));
1902 
1903         return jump;
1904 }
1905 
1906 static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_si type,
1907         sljit_si src, sljit_sw srcw)
1908 {
1909         struct sljit_jump *jump;
1910         sljit_ins inv_bits = (type & SLJIT_INT_OP) ? (1 << 31) : 0;
1911 
1912         SLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL);
1913         ADJUST_LOCAL_OFFSET(src, srcw);
1914 
1915         jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
1916         PTR_FAIL_IF(!jump);
1917         set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
1918         jump->flags |= IS_CBZ | IS_COND;
1919 
1920         if (src & SLJIT_MEM) {
1921                 PTR_FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src, srcw));
1922                 src = TMP_REG1;
1923         }
1924         else if (src & SLJIT_IMM) {
1925                 PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
1926                 src = TMP_REG1;
1927         }
1928         SLJIT_ASSERT(FAST_IS_REG(src));
1929 
1930         if ((type & 0xff) == SLJIT_EQUAL)
1931                 inv_bits |= 1 << 24;
1932 
1933         PTR_FAIL_IF(push_inst(compiler, (CBZ ^ inv_bits) | (6 << 5) | RT(src)));
1934         PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
1935         jump->addr = compiler->size;
1936         PTR_FAIL_IF(push_inst(compiler, BR | RN(TMP_REG1)));
1937         return jump;
1938 }
1939 
1940 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
1941 {
1942         struct sljit_jump *jump;
1943 
1944         CHECK_ERROR();
1945         CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
1946         ADJUST_LOCAL_OFFSET(src, srcw);
1947 
1948         /* In ARM, we don't need to touch the arguments. */
1949         if (!(src & SLJIT_IMM)) {
1950                 if (src & SLJIT_MEM) {
1951                         FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw));
1952                         src = TMP_REG1;
1953                 }
1954                 return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(src));
1955         }
1956 
1957         jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
1958         FAIL_IF(!jump);
1959         set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
1960         jump->u.target = srcw;
1961 
1962         FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
1963         jump->addr = compiler->size;
1964         return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1));
1965 }
1966 
1967 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
1968         sljit_si dst, sljit_sw dstw,
1969         sljit_si src, sljit_sw srcw,
1970         sljit_si type)
1971 {
1972         sljit_si dst_r, flags, mem_flags;
1973         sljit_ins cc;
1974 
1975         CHECK_ERROR();
1976         CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
1977         ADJUST_LOCAL_OFFSET(dst, dstw);
1978         ADJUST_LOCAL_OFFSET(src, srcw);
1979 
1980         if (dst == SLJIT_UNUSED)
1981                 return SLJIT_SUCCESS;
1982 
1983         cc = get_cc(type & 0xff);
1984         dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
1985 
1986         if (GET_OPCODE(op) < SLJIT_ADD) {
1987                 FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(dst_r) | RN(TMP_ZERO) | RM(TMP_ZERO)));
1988                 if (dst_r != TMP_REG1)
1989                         return SLJIT_SUCCESS;
1990                 return emit_op_mem(compiler, (GET_OPCODE(op) == SLJIT_MOV ? WORD_SIZE : INT_SIZE) | STORE, TMP_REG1, dst, dstw);
1991         }
1992 
1993         compiler->cache_arg = 0;
1994         compiler->cache_argw = 0;
1995         flags = GET_FLAGS(op) ? SET_FLAGS : 0;
1996         mem_flags = WORD_SIZE;
1997         if (op & SLJIT_INT_OP) {
1998                 flags |= INT_OP;
1999                 mem_flags = INT_SIZE;
2000         }
2001 
2002         if (src & SLJIT_MEM) {
2003                 FAIL_IF(emit_op_mem2(compiler, mem_flags, TMP_REG1, src, srcw, dst, dstw));
2004                 src = TMP_REG1;
2005                 srcw = 0;
2006         } else if (src & SLJIT_IMM)
2007                 flags |= ARG1_IMM;
2008 
2009         FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(TMP_ZERO)));
2010         emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src, TMP_REG2);
2011 
2012         if (dst_r != TMP_REG1)
2013                 return SLJIT_SUCCESS;
2014         return emit_op_mem2(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0);
2015 }
2016 
2017 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
2018 {
2019         struct sljit_const *const_;
2020         sljit_si dst_r;
2021 
2022         CHECK_ERROR_PTR();
2023         CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
2024         ADJUST_LOCAL_OFFSET(dst, dstw);
2025 
2026         const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
2027         PTR_FAIL_IF(!const_);
2028         set_const(const_, compiler);
2029 
2030         dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
2031         PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, init_value));
2032 
2033         if (dst & SLJIT_MEM)
2034                 PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw));
2035         return const_;
2036 }
2037 
2038 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
2039 {
2040         sljit_ins* inst = (sljit_ins*)addr;
2041         modify_imm64_const(inst, new_addr);
2042         SLJIT_CACHE_FLUSH(inst, inst + 4);
2043 }
2044 
2045 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
2046 {
2047         sljit_ins* inst = (sljit_ins*)addr;
2048         modify_imm64_const(inst, new_constant);
2049         SLJIT_CACHE_FLUSH(inst, inst + 4);
2050 }

/* [<][>][^][v][top][bottom][index][help] */