1f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* 2f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * Stack-less Just-In-Time compiler 3f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 4f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 6f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * Redistribution and use in source and binary forms, with or without modification, are 7f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * permitted provided that the following conditions are met: 8f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 9f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 1. Redistributions of source code must retain the above copyright notice, this list of 10f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * conditions and the following disclaimer. 11f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 12f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * of conditions and the following disclaimer in the documentation and/or other materials 14f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * provided with the distribution. 15f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 16f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich */ 26f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 278b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) 28f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 29f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return "ARM-64" SLJIT_CPUINFO; 30f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 31f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 32f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Length of an instruction word */ 338b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskistypedef sljit_u32 sljit_ins; 34f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 358366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes#define TMP_ZERO (0) 36f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 37f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) 38f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) 39f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) 408366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes#define TMP_LR (SLJIT_NUMBER_OF_REGISTERS + 5) 418366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes#define TMP_SP (SLJIT_NUMBER_OF_REGISTERS + 6) 42f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 43f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define TMP_FREG1 (0) 44f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) 45f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 468b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = { 478366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes 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 48f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}; 49f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 50f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define W_OP (1 << 31) 51f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define RD(rd) (reg_map[rd]) 52f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define RT(rt) (reg_map[rt]) 53f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define RN(rn) (reg_map[rn] << 5) 54f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define RT2(rt2) (reg_map[rt2] << 10) 55f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define RM(rm) (reg_map[rm] << 16) 56f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define VD(vd) (vd) 57f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define VT(vt) (vt) 58f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define VN(vn) ((vn) << 5) 59f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define VM(vm) ((vm) << 16) 60f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 61f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 62f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Instrucion forms */ 63f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 64f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 65f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define ADC 0x9a000000 66f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define ADD 0x8b000000 67f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define ADDI 0x91000000 68f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define AND 0x8a000000 69f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define ANDI 0x92000000 70f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define ASRV 0x9ac02800 71f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define B 0x14000000 72f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define B_CC 0x54000000 73f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define BL 0x94000000 74f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define BLR 0xd63f0000 75f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define BR 0xd61f0000 76f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define BRK 0xd4200000 77f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define CBZ 0xb4000000 78f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define CLZ 0xdac01000 79f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define CSINC 0x9a800400 80f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define EOR 0xca000000 81f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define EORI 0xd2000000 82f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FABS 0x1e60c000 83f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FADD 0x1e602800 84f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FCMP 0x1e602000 85f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FCVT 0x1e224000 86f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FCVTZS 0x9e780000 87f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FDIV 0x1e601800 88f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FMOV 0x1e604000 89f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FMUL 0x1e600800 90f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FNEG 0x1e614000 91f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FSUB 0x1e603800 92f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define LDRI 0xf9400000 93f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define LDP 0xa9400000 94f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define LDP_PST 0xa8c00000 95f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define LSLV 0x9ac02000 96f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define LSRV 0x9ac02400 97f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define MADD 0x9b000000 98f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define MOVK 0xf2800000 99f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define MOVN 0x92800000 100f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define MOVZ 0xd2800000 101f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define NOP 0xd503201f 102f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define ORN 0xaa200000 103f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define ORR 0xaa000000 104f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define ORRI 0xb2000000 105f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define RET 0xd65f0000 106f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SBC 0xda000000 107f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SBFM 0x93000000 108f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SCVTF 0x9e620000 109f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SDIV 0x9ac00c00 110f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SMADDL 0x9b200000 111f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SMULH 0x9b403c00 112f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define STP 0xa9000000 113f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define STP_PRE 0xa9800000 114f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define STRI 0xf9000000 115f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define STR_FI 0x3d000000 116f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define STR_FR 0x3c206800 117f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define STUR_FI 0x3c000000 118f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SUB 0xcb000000 119f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SUBI 0xd1000000 120f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SUBS 0xeb000000 121f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define UBFM 0xd3000000 122f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define UDIV 0x9ac00800 123f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define UMULH 0x9bc03c00 124f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 125f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* dest_reg is the absolute name of the register 126f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich Useful for reordering instructions in the delay slot. */ 1278b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) 128f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 129f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); 130f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(!ptr); 131f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich *ptr = ins; 132f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->size++; 133f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 134f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 135f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1368b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic SLJIT_INLINE sljit_s32 emit_imm64_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm) 137f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 138f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5))); 139f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 16) & 0xffff) << 5) | (1 << 21))); 140f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 32) & 0xffff) << 5) | (2 << 21))); 141f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, MOVK | RD(dst) | ((imm >> 48) << 5) | (3 << 21)); 142f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 143f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 144f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm) 145f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 1468b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst = inst[0] & 0x1f; 147f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21))); 148f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5); 149f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21); 150f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst[2] = MOVK | dst | (((new_imm >> 32) & 0xffff) << 5) | (2 << 21); 151f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21); 152f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 153f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1548b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) 155f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 156f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_sw diff; 157f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_uw target_addr; 158f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 159f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (jump->flags & SLJIT_REWRITABLE_JUMP) { 160f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->flags |= PATCH_ABS64; 161f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 162f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 163f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 164f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (jump->flags & JUMP_ADDR) 165f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich target_addr = jump->u.target; 166f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 167f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(jump->flags & JUMP_LABEL); 168f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich target_addr = (sljit_uw)(code + jump->u.label->size); 169f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 170f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4); 171f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 172f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (jump->flags & IS_COND) { 173f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich diff += sizeof(sljit_ins); 174f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (diff <= 0xfffff && diff >= -0x100000) { 175f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich code_ptr[-5] ^= (jump->flags & IS_CBZ) ? (0x1 << 24) : 0x1; 176f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->addr -= sizeof(sljit_ins); 177f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->flags |= PATCH_COND; 178f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 5; 179f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 180f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich diff -= sizeof(sljit_ins); 181f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 182f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 183f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (diff <= 0x7ffffff && diff >= -0x8000000) { 184f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->flags |= PATCH_B; 185f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 4; 186f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 187f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 188f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (target_addr <= 0xffffffffl) { 189f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (jump->flags & IS_COND) 190f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich code_ptr[-5] -= (2 << 5); 191f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich code_ptr[-2] = code_ptr[0]; 192f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 2; 193f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 194f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (target_addr <= 0xffffffffffffl) { 195f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (jump->flags & IS_COND) 196f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich code_ptr[-5] -= (1 << 5); 197f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->flags |= PATCH_ABS48; 198f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich code_ptr[-1] = code_ptr[0]; 199f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 1; 200f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 201f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 202f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->flags |= PATCH_ABS64; 203f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 204f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 205f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 206f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) 207f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 208f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich struct sljit_memory_fragment *buf; 209f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins *code; 210f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins *code_ptr; 211f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins *buf_ptr; 212f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins *buf_end; 213f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_uw word_count; 214f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_uw addr; 2158b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst; 216f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 217f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich struct sljit_label *label; 218f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich struct sljit_jump *jump; 219f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich struct sljit_const *const_; 220f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 221f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR_PTR(); 2228366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK_PTR(check_sljit_generate_code(compiler)); 223f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich reverse_buf(compiler); 224f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 225f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); 226f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_WITH_EXEC_IF(code); 227f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich buf = compiler->buf; 228f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 229f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich code_ptr = code; 230f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich word_count = 0; 231f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich label = compiler->labels; 232f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump = compiler->jumps; 233f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich const_ = compiler->consts; 234f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 235f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich do { 236f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich buf_ptr = (sljit_ins*)buf->memory; 237f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich buf_end = buf_ptr + (buf->used_size >> 2); 238f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich do { 239f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich *code_ptr = *buf_ptr++; 240f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* These structures are ordered by their address. */ 241f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!label || label->size >= word_count); 242f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!jump || jump->addr >= word_count); 243f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!const_ || const_->addr >= word_count); 244f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (label && label->size == word_count) { 245f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich label->addr = (sljit_uw)code_ptr; 246f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich label->size = code_ptr - code; 247f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich label = label->next; 248f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 249f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (jump && jump->addr == word_count) { 250f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->addr = (sljit_uw)(code_ptr - 4); 251f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich code_ptr -= detect_jump_type(jump, code_ptr, code); 252f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump = jump->next; 253f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 254f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (const_ && const_->addr == word_count) { 255f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich const_->addr = (sljit_uw)code_ptr; 256f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich const_ = const_->next; 257f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 258f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich code_ptr ++; 259f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich word_count ++; 260f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } while (buf_ptr < buf_end); 261f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 262f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich buf = buf->next; 263f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } while (buf); 264f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 265f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (label && label->size == word_count) { 266f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich label->addr = (sljit_uw)code_ptr; 267f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich label->size = code_ptr - code; 268f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich label = label->next; 269f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 270f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 271f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!label); 272f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!jump); 273f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!const_); 274f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); 275f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 276f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump = compiler->jumps; 277f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich while (jump) { 278f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich do { 279f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; 280f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich buf_ptr = (sljit_ins*)jump->addr; 281f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (jump->flags & PATCH_B) { 282f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich addr = (sljit_sw)(addr - jump->addr) >> 2; 283f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT((sljit_sw)addr <= 0x1ffffff && (sljit_sw)addr >= -0x2000000); 284f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (addr & 0x3ffffff); 285f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (jump->flags & IS_COND) 286f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich buf_ptr[-1] -= (4 << 5); 287f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 288f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 289f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (jump->flags & PATCH_COND) { 290f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich addr = (sljit_sw)(addr - jump->addr) >> 2; 291f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT((sljit_sw)addr <= 0x3ffff && (sljit_sw)addr >= -0x40000); 292f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich buf_ptr[0] = (buf_ptr[0] & ~0xffffe0) | ((addr & 0x7ffff) << 5); 293f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 294f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 295f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 296f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || addr <= 0xffffffffl); 297f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT((jump->flags & PATCH_ABS64) || addr <= 0xffffffffffffl); 298f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 299f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich dst = buf_ptr[0] & 0x1f; 300f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich buf_ptr[0] = MOVZ | dst | ((addr & 0xffff) << 5); 301f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich buf_ptr[1] = MOVK | dst | (((addr >> 16) & 0xffff) << 5) | (1 << 21); 302f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (jump->flags & (PATCH_ABS48 | PATCH_ABS64)) 303f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich buf_ptr[2] = MOVK | dst | (((addr >> 32) & 0xffff) << 5) | (2 << 21); 304f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (jump->flags & PATCH_ABS64) 305f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich buf_ptr[3] = MOVK | dst | (((addr >> 48) & 0xffff) << 5) | (3 << 21); 306f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } while (0); 307f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump = jump->next; 308f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 309f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 310f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->error = SLJIT_ERR_COMPILED; 311f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); 312f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_CACHE_FLUSH(code, code_ptr); 313f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return code; 314f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 315f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 316f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 317f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Core code generator functions. */ 318f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 319f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 320f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define COUNT_TRAILING_ZERO(value, result) \ 321f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich result = 0; \ 322f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(value & 0xffffffff)) { \ 323f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich result += 32; \ 324f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich value >>= 32; \ 325f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } \ 326f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(value & 0xffff)) { \ 327f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich result += 16; \ 328f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich value >>= 16; \ 329f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } \ 330f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(value & 0xff)) { \ 331f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich result += 8; \ 332f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich value >>= 8; \ 333f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } \ 334f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(value & 0xf)) { \ 335f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich result += 4; \ 336f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich value >>= 4; \ 337f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } \ 338f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(value & 0x3)) { \ 339f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich result += 2; \ 340f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich value >>= 2; \ 341f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } \ 342f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(value & 0x1)) { \ 343f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich result += 1; \ 344f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich value >>= 1; \ 345f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 346f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 347f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define LOGICAL_IMM_CHECK 0x100 348f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 3498b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic sljit_ins logical_imm(sljit_sw imm, sljit_s32 len) 350f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 3518b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 negated, ones, right; 352f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_uw mask, uimm; 353f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins ins; 354f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 355f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (len & LOGICAL_IMM_CHECK) { 356f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich len &= ~LOGICAL_IMM_CHECK; 357f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (len == 32 && (imm == 0 || imm == -1)) 358f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 3598b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis if (len == 16 && ((sljit_s32)imm == 0 || (sljit_s32)imm == -1)) 360f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 361f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 362f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 363f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT((len == 32 && imm != 0 && imm != -1) 3648b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis || (len == 16 && (sljit_s32)imm != 0 && (sljit_s32)imm != -1)); 365f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm = (sljit_uw)imm; 366f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich while (1) { 367f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (len <= 0) { 368f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT_STOP(); 369f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 370f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 371f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich mask = ((sljit_uw)1 << len) - 1; 372f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((uimm & mask) != ((uimm >> len) & mask)) 373f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 374f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich len >>= 1; 375f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 376f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 377f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich len <<= 1; 378f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 379f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich negated = 0; 380f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (uimm & 0x1) { 381f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich negated = 1; 382f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm = ~uimm; 383f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 384f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 385f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (len < 64) 386f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm &= ((sljit_uw)1 << len) - 1; 387f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 388f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Unsigned right shift. */ 389f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich COUNT_TRAILING_ZERO(uimm, right); 390f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 391f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Signed shift. We also know that the highest bit is set. */ 392f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich imm = (sljit_sw)~uimm; 393f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(imm < 0); 394f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 395f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich COUNT_TRAILING_ZERO(imm, ones); 396f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 397f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (~imm) 398f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 399f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 400f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (len == 64) 401f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ins = 1 << 22; 402f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 403f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ins = (0x3f - ((len << 1) - 1)) << 10; 404f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 405f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (negated) 406f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return ins | ((len - ones - 1) << 10) | ((len - ones - right) << 16); 407f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 408f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return ins | ((ones - 1) << 10) | ((len - right) << 16); 409f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 410f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 411f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#undef COUNT_TRAILING_ZERO 412f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 4138b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw simm) 414f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 415f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_uw imm = (sljit_uw)simm; 4168b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 i, zeros, ones, first; 417f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins bitmask; 418f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 419f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (imm <= 0xffff) 420f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, MOVZ | RD(dst) | (imm << 5)); 421f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 422f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (simm >= -0x10000 && simm < 0) 423f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5)); 424f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 425f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (imm <= 0xffffffffl) { 426f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((imm & 0xffff0000l) == 0xffff0000) 427f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff) << 5)); 428f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((imm & 0xffff) == 0xffff) 429f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff0000l) >> (16 - 5)) | (1 << 21)); 430f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich bitmask = logical_imm(simm, 16); 431f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (bitmask != 0) 432f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (ORRI ^ W_OP) | RD(dst) | RN(TMP_ZERO) | bitmask); 433f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 434f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 435f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich bitmask = logical_imm(simm, 32); 436f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (bitmask != 0) 437f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ORRI | RD(dst) | RN(TMP_ZERO) | bitmask); 438f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 439f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 440f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (imm <= 0xffffffffl) { 441f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5))); 442f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21)); 443f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 444f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 445f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (simm >= -0x100000000l && simm < 0) { 446f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5))); 447f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21)); 448f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 449f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 450f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* A large amount of number can be constructed from ORR and MOVx, 451f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich but computing them is costly. We don't */ 452f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 453f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich zeros = 0; 454f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ones = 0; 455f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich for (i = 4; i > 0; i--) { 456f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((simm & 0xffff) == 0) 457f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich zeros++; 458f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((simm & 0xffff) == 0xffff) 459f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ones++; 460f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich simm >>= 16; 461f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 462f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 463f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich simm = (sljit_sw)imm; 464f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich first = 1; 465f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (ones > zeros) { 466f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich simm = ~simm; 467f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich for (i = 0; i < 4; i++) { 468f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(simm & 0xffff)) { 469f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich simm >>= 16; 470f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich continue; 471f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 472f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (first) { 473f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich first = 0; 474f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((simm & 0xffff) << 5) | (i << 21))); 475f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 476f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 477f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((~simm & 0xffff) << 5) | (i << 21))); 478f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich simm >>= 16; 479f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 480f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 481f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 482f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 483f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich for (i = 0; i < 4; i++) { 484f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(simm & 0xffff)) { 485f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich simm >>= 16; 486f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich continue; 487f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 488f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (first) { 489f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich first = 0; 490f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((simm & 0xffff) << 5) | (i << 21))); 491f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 492f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 493f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((simm & 0xffff) << 5) | (i << 21))); 494f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich simm >>= 16; 495f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 496f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 497f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 498f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 499f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define ARG1_IMM 0x0010000 500f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define ARG2_IMM 0x0020000 501f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define INT_OP 0x0040000 502f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SET_FLAGS 0x0080000 503f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define UNUSED_RETURN 0x0100000 504f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SLOW_DEST 0x0200000 505f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SLOW_SRC1 0x0400000 506f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SLOW_SRC2 0x0800000 507f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 508f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define CHECK_FLAGS(flag_bits) \ 509f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & SET_FLAGS) { \ 510f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inv_bits |= flag_bits; \ 511f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & UNUSED_RETURN) \ 512f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich dst = TMP_ZERO; \ 513f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 514f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 5158b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_sw arg1, sljit_sw arg2) 516f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 517f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* dst must be register, TMP_REG1 518f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg1 must be register, TMP_REG1, imm 519f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg2 must be register, TMP_REG2, imm */ 520f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins inv_bits = (flags & INT_OP) ? (1 << 31) : 0; 521f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins inst_bits; 5228b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 op = (flags & 0xffff); 5238b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 reg; 524f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_sw imm, nimm; 525f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 526f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) { 527f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Both are immediates. */ 528f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags &= ~ARG1_IMM; 529f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (arg1 == 0 && op != SLJIT_ADD && op != SLJIT_SUB) 530f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg1 = TMP_ZERO; 531f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 532f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); 533f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg1 = TMP_REG1; 534f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 535f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 536f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 537f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & (ARG1_IMM | ARG2_IMM)) { 538f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich reg = (flags & ARG2_IMM) ? arg1 : arg2; 539f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich imm = (flags & ARG2_IMM) ? arg2 : arg1; 540f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 541f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich switch (op) { 542f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MUL: 543f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_NEG: 544f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_CLZ: 545f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_ADDC: 546f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_SUBC: 547f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* No form with immediate operand (except imm 0, which 548f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich is represented by a ZERO register). */ 549f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 550f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOV: 551f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1); 552f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return load_immediate(compiler, dst, imm); 553f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_NOT: 554f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(flags & ARG2_IMM); 555f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(load_immediate(compiler, dst, (flags & INT_OP) ? (~imm & 0xffffffff) : ~imm)); 556f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich goto set_flags; 557f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_SUB: 558f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & ARG1_IMM) 559f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 560f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich imm = -imm; 561f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Fall through. */ 562f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_ADD: 563f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (imm == 0) { 564f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_FLAGS(1 << 29); 565f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ((op == SLJIT_ADD ? ADDI : SUBI) ^ inv_bits) | RD(dst) | RN(reg)); 566f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 567f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (imm > 0 && imm <= 0xfff) { 568f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_FLAGS(1 << 29); 569f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | (imm << 10)); 570f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 571f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich nimm = -imm; 572f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (nimm > 0 && nimm <= 0xfff) { 573f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_FLAGS(1 << 29); 574f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | (nimm << 10)); 575f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 576f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (imm > 0 && imm <= 0xffffff && !(imm & 0xfff)) { 577f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_FLAGS(1 << 29); 578f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22)); 579f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 580f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (nimm > 0 && nimm <= 0xffffff && !(nimm & 0xfff)) { 581f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_FLAGS(1 << 29); 582f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22)); 583f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 584f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (imm > 0 && imm <= 0xffffff && !(flags & SET_FLAGS)) { 585f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22))); 586f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(dst) | ((imm & 0xfff) << 10)); 587f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 588f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (nimm > 0 && nimm <= 0xffffff && !(flags & SET_FLAGS)) { 589f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22))); 590f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(dst) | ((nimm & 0xfff) << 10)); 591f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 592f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 593f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_AND: 594f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32)); 595f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!inst_bits) 596f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 597f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_FLAGS(3 << 29); 598f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (ANDI ^ inv_bits) | RD(dst) | RN(reg) | inst_bits); 599f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_OR: 600f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_XOR: 601f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32)); 602f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!inst_bits) 603f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 604f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op == SLJIT_OR) 605f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst_bits |= ORRI; 606f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 607f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst_bits |= EORI; 608f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (inst_bits ^ inv_bits) | RD(dst) | RN(reg))); 609f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich goto set_flags; 610f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_SHL: 611f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & ARG1_IMM) 612f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 613f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & INT_OP) { 614f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich imm &= 0x1f; 615f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | ((-imm & 0x1f) << 16) | ((31 - imm) << 10))); 616f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 617f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 618f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich imm &= 0x3f; 619f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | ((-imm & 0x3f) << 16) | ((63 - imm) << 10))); 620f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 621f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich goto set_flags; 622f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_LSHR: 623f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_ASHR: 624f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & ARG1_IMM) 625f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 626f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op == SLJIT_ASHR) 627f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inv_bits |= 1 << 30; 628f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & INT_OP) { 629f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich imm &= 0x1f; 630f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (imm << 16) | (31 << 10))); 631f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 632f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 633f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich imm &= 0x3f; 634f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | (imm << 16) | (63 << 10))); 635f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 636f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich goto set_flags; 637f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich default: 638f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT_STOP(); 639f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 640f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 641f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 642f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & ARG2_IMM) { 643f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (arg2 == 0) 644f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg2 = TMP_ZERO; 645f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 646f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(load_immediate(compiler, TMP_REG2, arg2)); 647f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg2 = TMP_REG2; 648f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 649f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 650f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 651f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (arg1 == 0) 652f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg1 = TMP_ZERO; 653f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 654f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); 655f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg1 = TMP_REG1; 656f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 657f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 658f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 659f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 660f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Both arguments are registers. */ 661f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich switch (op) { 662f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOV: 663f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOV_P: 664f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOVU: 665f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOVU_P: 666f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); 667f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst == arg2) 668f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 669f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2)); 6708b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOV_U8: 6718b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOVU_U8: 672f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); 673f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (7 << 10)); 6748b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOV_S8: 6758b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOVU_S8: 676f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); 677f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(flags & INT_OP)) 678f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inv_bits |= 1 << 22; 679f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10)); 6808b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOV_U16: 6818b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOVU_U16: 682f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); 683f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (15 << 10)); 6848b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOV_S16: 6858b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOVU_S16: 686f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); 687f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(flags & INT_OP)) 688f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inv_bits |= 1 << 22; 689f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10)); 6908b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOV_U32: 6918b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOVU_U32: 692f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); 693f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((flags & INT_OP) && dst == arg2) 694f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 695f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (ORR ^ (1 << 31)) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); 6968b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOV_S32: 6978b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOVU_S32: 698f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); 699f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((flags & INT_OP) && dst == arg2) 700f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 701f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(arg2) | (31 << 10)); 702f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_NOT: 703f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(arg1 == TMP_REG1); 704f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2))); 705f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich goto set_flags; 706f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_NEG: 707f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(arg1 == TMP_REG1); 708f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & SET_FLAGS) 709f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inv_bits |= 1 << 29; 710f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); 711f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_CLZ: 712f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(arg1 == TMP_REG1); 713f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(arg2))); 714f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich goto set_flags; 715f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_ADD: 716f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_FLAGS(1 << 29); 717f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (ADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); 718f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_ADDC: 719f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_FLAGS(1 << 29); 720f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (ADC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); 721f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_SUB: 722f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_FLAGS(1 << 29); 723f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); 724f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_SUBC: 725f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_FLAGS(1 << 29); 726f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (SBC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); 727f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MUL: 728f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(flags & SET_FLAGS)) 729f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (MADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO)); 730f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & INT_OP) { 731f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SMADDL | RD(dst) | RN(arg1) | RM(arg2) | (31 << 10))); 7328366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(TMP_ZERO) | RM(dst) | (2 << 22) | (31 << 10))); 7338366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10)); 734f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 7358366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes FAIL_IF(push_inst(compiler, SMULH | RD(TMP_LR) | RN(arg1) | RM(arg2))); 736f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, MADD | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO))); 7378366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10)); 738f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_AND: 739f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_FLAGS(3 << 29); 740f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (AND ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); 741f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_OR: 742f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); 743f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich goto set_flags; 744f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_XOR: 745f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (EOR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); 746f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich goto set_flags; 747f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_SHL: 748f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (LSLV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); 749f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich goto set_flags; 750f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_LSHR: 751f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (LSRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); 752f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich goto set_flags; 753f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_ASHR: 754f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (ASRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); 755f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich goto set_flags; 756f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 757f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 758f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT_STOP(); 759f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 760f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 761f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichset_flags: 762f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & SET_FLAGS) 763f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (SUBS ^ inv_bits) | RD(TMP_ZERO) | RN(dst) | RM(TMP_ZERO)); 764f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 765f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 766f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 767f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define STORE 0x01 768f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SIGNED 0x02 769f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 770f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define UPDATE 0x04 771f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define ARG_TEST 0x08 772f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 773f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define BYTE_SIZE 0x000 774f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define HALF_SIZE 0x100 775f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define INT_SIZE 0x200 776f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define WORD_SIZE 0x300 777f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 778f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define MEM_SIZE_SHIFT(flags) ((flags) >> 8) 779f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 7808b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic const sljit_ins sljit_mem_imm[4] = { 781f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* u l */ 0x39400000 /* ldrb [reg,imm] */, 782f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* u s */ 0x39000000 /* strb [reg,imm] */, 783f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* s l */ 0x39800000 /* ldrsb [reg,imm] */, 784f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* s s */ 0x39000000 /* strb [reg,imm] */, 785f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}; 786f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 7878b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic const sljit_ins sljit_mem_simm[4] = { 788f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* u l */ 0x38400000 /* ldurb [reg,imm] */, 789f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* u s */ 0x38000000 /* sturb [reg,imm] */, 790f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* s l */ 0x38800000 /* ldursb [reg,imm] */, 791f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* s s */ 0x38000000 /* sturb [reg,imm] */, 792f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}; 793f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 7948b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic const sljit_ins sljit_mem_pre_simm[4] = { 795f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* u l */ 0x38400c00 /* ldrb [reg,imm]! */, 796f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* u s */ 0x38000c00 /* strb [reg,imm]! */, 797f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* s l */ 0x38800c00 /* ldrsb [reg,imm]! */, 798f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* s s */ 0x38000c00 /* strb [reg,imm]! */, 799f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}; 800f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 8018b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic const sljit_ins sljit_mem_reg[4] = { 802f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* u l */ 0x38606800 /* ldrb [reg,reg] */, 803f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* u s */ 0x38206800 /* strb [reg,reg] */, 804f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* s l */ 0x38a06800 /* ldrsb [reg,reg] */, 805f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* s s */ 0x38206800 /* strb [reg,reg] */, 806f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}; 807f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 808f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ 8098b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value) 810f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 811f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (value >= 0) { 812f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (value <= 0xfff) 813f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ADDI | RD(dst) | RN(reg) | (value << 10)); 814f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (value <= 0xffffff && !(value & 0xfff)) 815f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ADDI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2)); 816f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 817f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 818f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich value = -value; 819f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (value <= 0xfff) 820f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, SUBI | RD(dst) | RN(reg) | (value << 10)); 821f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (value <= 0xffffff && !(value & 0xfff)) 822f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, SUBI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2)); 823f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 824f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_ERR_UNSUPPORTED; 825f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 826f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 827f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Can perform an operation using at most 1 instruction. */ 8288b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) 829f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 8308b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_u32 shift = MEM_SIZE_SHIFT(flags); 831f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 832f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(arg & SLJIT_MEM); 833f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 834f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (SLJIT_UNLIKELY(flags & UPDATE)) { 835f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((arg & REG_MASK) && !(arg & OFFS_REG_MASK) && argw <= 255 && argw >= -256) { 836f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (SLJIT_UNLIKELY(flags & ARG_TEST)) 837f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 1; 838f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 839f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg &= REG_MASK; 840f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich argw &= 0x1ff; 841f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, sljit_mem_pre_simm[flags & 0x3] 842f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich | (shift << 30) | RT(reg) | RN(arg) | (argw << 12))); 843f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return -1; 844f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 845f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 846f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 847f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 848f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { 849f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich argw &= 0x3; 850f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (argw && argw != shift) 851f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 852f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 853f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (SLJIT_UNLIKELY(flags & ARG_TEST)) 854f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 1; 855f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 856f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) 857f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0))); 858f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return -1; 859f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 860f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 861f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg &= REG_MASK; 862f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (argw >= 0 && (argw >> shift) <= 0xfff && (argw & ((1 << shift) - 1)) == 0) { 863f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (SLJIT_UNLIKELY(flags & ARG_TEST)) 864f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 1; 865f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 866f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) 867f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich | RT(reg) | RN(arg) | (argw << (10 - shift)))); 868f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return -1; 869f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 870f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 871f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (argw > 255 || argw < -256) 872f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 873f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 874f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (SLJIT_UNLIKELY(flags & ARG_TEST)) 875f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 1; 876f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 877f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30) 878f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich | RT(reg) | RN(arg) | ((argw & 0x1ff) << 12))); 879f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return -1; 880f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 881f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 882f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* see getput_arg below. 883f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich Note: can_cache is called only for binary operators. Those 884f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich operators always uses word arguments without write back. */ 8858b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) 886f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 887f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_sw diff; 888f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM)) 889f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 890f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 891f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(arg & REG_MASK)) { 892f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich diff = argw - next_argw; 893f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (diff <= 0xfff && diff >= -0xfff) 894f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 1; 895f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 896f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 897f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 898f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (argw == next_argw) 899f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 1; 900f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 901f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich diff = argw - next_argw; 902f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (arg == next_arg && diff <= 0xfff && diff >= -0xfff) 903f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 1; 904f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 905f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0; 906f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 907f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 908f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Emit the necessary instructions. See can_cache above. */ 9098b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, 9108b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) 911f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 9128b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_u32 shift = MEM_SIZE_SHIFT(flags); 9138b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 tmp_r, other_r; 914f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_sw diff; 915f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 916f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(arg & SLJIT_MEM); 917f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(next_arg & SLJIT_MEM)) { 918f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich next_arg = 0; 919f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich next_argw = 0; 920f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 921f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 922f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich tmp_r = (flags & STORE) ? TMP_REG3 : reg; 923f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 924f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (SLJIT_UNLIKELY((flags & UPDATE) && (arg & REG_MASK))) { 925f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Update only applies if a base register exists. */ 926f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich other_r = OFFS_REG(arg); 927f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!other_r) { 928f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich other_r = arg & REG_MASK; 929f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (other_r != reg && argw >= 0 && argw <= 0xffffff) { 930f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((argw & 0xfff) != 0) 931f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ADDI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10))); 932f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (argw >> 12) 933f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10))); 934f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r)); 935f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 936f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else if (other_r != reg && argw < 0 && argw >= -0xffffff) { 937f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich argw = -argw; 938f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((argw & 0xfff) != 0) 939f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SUBI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10))); 940f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (argw >> 12) 941f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10))); 942f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r)); 943f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 944f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 945f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (compiler->cache_arg == SLJIT_MEM) { 946f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (argw == compiler->cache_argw) { 947f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich other_r = TMP_REG3; 948f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich argw = 0; 949f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 950f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { 951f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(compiler->error); 952f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_argw = argw; 953f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich other_r = TMP_REG3; 954f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich argw = 0; 955f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 956f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 957f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 958f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (argw) { 959f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); 960f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_arg = SLJIT_MEM; 961f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_argw = argw; 962f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich other_r = TMP_REG3; 963f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich argw = 0; 964f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 965f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 966f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 967f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* No caching here. */ 968f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg &= REG_MASK; 969f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich argw &= 0x3; 970f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!argw || argw == shift) { 971f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(other_r) | (argw ? (1 << 12) : 0))); 972f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10)); 973f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 974f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (arg != reg) { 975f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10))); 976f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg)); 977f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 9788366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(arg) | RM(other_r) | (argw << 10))); 9798366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_LR))); 9808366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes return push_inst(compiler, ORR | RD(arg) | RN(TMP_ZERO) | RM(TMP_LR)); 981f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 982f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 983f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (arg & OFFS_REG_MASK) { 984f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich other_r = OFFS_REG(arg); 985f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg &= REG_MASK; 986f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RN(arg) | RM(other_r) | ((argw & 0x3) << 10))); 987f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(tmp_r)); 988f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 989f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 990f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (compiler->cache_arg == arg) { 991f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich diff = argw - compiler->cache_argw; 992f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (diff <= 255 && diff >= -256) 993f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30) 994f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich | RT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12)); 995f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, diff) != SLJIT_ERR_UNSUPPORTED) { 996f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(compiler->error); 997f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg)); 998f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 999f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1000f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1001f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (argw >= 0 && argw <= 0xffffff && (argw & ((1 << shift) - 1)) == 0) { 1002f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_r) | RN(arg & REG_MASK) | ((argw >> 12) << 10))); 1003f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) 1004f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich | RT(reg) | RN(tmp_r) | ((argw & 0xfff) << (10 - shift))); 1005f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1006f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1007f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich diff = argw - next_argw; 1008f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich next_arg = (arg & REG_MASK) && (arg == next_arg) && diff <= 0xfff && diff >= -0xfff && diff != 0; 1009f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg &= REG_MASK; 1010f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1011f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (arg && compiler->cache_arg == SLJIT_MEM) { 1012f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (compiler->cache_argw == argw) 1013f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3)); 1014f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { 1015f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(compiler->error); 1016f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_argw = argw; 1017f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3)); 1018f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1019f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1020f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1021f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_argw = argw; 1022f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) { 1023f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(compiler->error); 1024f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_arg = SLJIT_MEM | arg; 1025f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg = 0; 1026f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1027f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 1028f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); 1029f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_arg = SLJIT_MEM; 1030f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1031f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (next_arg) { 1032f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG3) | RN(TMP_REG3) | RM(arg))); 1033f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_arg = SLJIT_MEM | arg; 1034f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg = 0; 1035f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1036f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1037f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1038f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (arg) 1039f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3)); 1040f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_REG3)); 1041f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1042f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 10438b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) 1044f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 1045f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (getput_arg_fast(compiler, flags, reg, arg, argw)) 1046f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return compiler->error; 1047f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_arg = 0; 1048f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_argw = 0; 1049f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return getput_arg(compiler, flags, reg, arg, argw, 0, 0); 1050f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1051f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 10528b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) 1053f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 1054f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) 1055f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return compiler->error; 1056f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); 1057f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1058f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1059f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 1060f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Entry, exit */ 1061f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 1062f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 10638b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, 10648b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, 10658b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) 1066f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 10678b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 i, tmp, offs, prev, saved_regs_size; 1068f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1069f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR(); 10708366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); 10718366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); 10728366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes 10738366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0); 10748366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes local_size += saved_regs_size + SLJIT_LOCALS_OFFSET; 10758366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes local_size = (local_size + 15) & ~0xf; 1076f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->local_size = local_size; 1077f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 10788366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes if (local_size <= (63 * sizeof(sljit_sw))) { 1079f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) 1080f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich | RN(TMP_SP) | ((-(local_size >> 3) & 0x7f) << 15))); 10818366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); 10828366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes offs = (local_size - saved_regs_size) << (15 - 3); 10838366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes } else { 10848366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes offs = 0 << 15; 10858366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes if (saved_regs_size & 0x8) { 10868366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes offs = 1 << 15; 10878366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes saved_regs_size += sizeof(sljit_sw); 1088f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 10898366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; 10900ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes if (saved_regs_size > 0) 10910ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); 1092f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1093f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1094f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; 1095f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich prev = -1; 1096f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich for (i = SLJIT_S0; i >= tmp; i--) { 1097f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (prev == -1) { 10980ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes if (!(offs & (1 << 15))) { 10990ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes prev = i; 11000ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes continue; 11010ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes } 11020ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5))); 11030ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes offs += 1 << 15; 1104f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich continue; 1105f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1106f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); 1107f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich offs += 2 << 15; 1108f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich prev = -1; 1109f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1110f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1111f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { 1112f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (prev == -1) { 11130ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes if (!(offs & (1 << 15))) { 11140ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes prev = i; 11150ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes continue; 11160ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes } 11170ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5))); 11180ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes offs += 1 << 15; 1119f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich continue; 1120f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1121f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); 1122f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich offs += 2 << 15; 1123f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich prev = -1; 1124f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1125f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 11260ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes SLJIT_ASSERT(prev == -1); 1127f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 11288366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes if (compiler->local_size > (63 * sizeof(sljit_sw))) { 11298366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes /* The local_size is already adjusted by the saved registers. */ 11308366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes if (local_size > 0xfff) { 11318366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); 11328366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes local_size &= 0xfff; 11338366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes } 11348366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes if (local_size) 11358366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); 11368366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) 11378366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes | RN(TMP_SP) | ((-(16 >> 3) & 0x7f) << 15))); 11388366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); 11398366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes } 11408366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes 1141f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (args >= 1) 1142f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S0) | RN(TMP_ZERO) | RM(SLJIT_R0))); 1143f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (args >= 2) 1144f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S1) | RN(TMP_ZERO) | RM(SLJIT_R1))); 1145f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (args >= 3) 1146f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S2) | RN(TMP_ZERO) | RM(SLJIT_R2))); 1147f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1148f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 1149f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1150f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 11518b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, 11528b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, 11538b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) 1154f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 11558366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK_ERROR(); 11568366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); 11578366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); 11588366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes 11598366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0) + SLJIT_LOCALS_OFFSET; 11608366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes local_size = (local_size + 15) & ~0xf; 11618366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes compiler->local_size = local_size; 11628366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes return SLJIT_SUCCESS; 1163f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1164f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 11658b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) 1166f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 11678b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 local_size; 11688b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 i, tmp, offs, prev, saved_regs_size; 1169f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1170f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR(); 11718366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK(check_sljit_emit_return(compiler, op, src, srcw)); 1172f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1173f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); 1174f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 11758366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes local_size = compiler->local_size; 11768366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes 11778366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 0); 11788366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes if (local_size <= (63 * sizeof(sljit_sw))) 11798366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes offs = (local_size - saved_regs_size) << (15 - 3); 11808366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes else { 11818366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) 11828366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes | RN(TMP_SP) | (((16 >> 3) & 0x7f) << 15))); 11838366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes offs = 0 << 15; 11848366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes if (saved_regs_size & 0x8) { 11858366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes offs = 1 << 15; 11868366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes saved_regs_size += sizeof(sljit_sw); 11878366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes } 11888366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; 11898366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes if (local_size > 0xfff) { 11908366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); 11918366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes local_size &= 0xfff; 11928366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes } 11938366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes if (local_size) 11948366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); 11958366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes } 11968366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes 1197f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; 1198f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich prev = -1; 1199f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich for (i = SLJIT_S0; i >= tmp; i--) { 1200f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (prev == -1) { 12010ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes if (!(offs & (1 << 15))) { 12020ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes prev = i; 12030ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes continue; 12040ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes } 12050ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5))); 12060ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes offs += 1 << 15; 1207f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich continue; 1208f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1209f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); 1210f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich offs += 2 << 15; 1211f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich prev = -1; 1212f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1213f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1214f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { 1215f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (prev == -1) { 12160ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes if (!(offs & (1 << 15))) { 12170ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes prev = i; 12180ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes continue; 12190ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes } 12200ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5))); 12210ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes offs += 1 << 15; 1222f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich continue; 1223f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1224f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); 1225f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich offs += 2 << 15; 1226f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich prev = -1; 1227f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1228f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 12290ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes SLJIT_ASSERT(prev == -1); 1230f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 12318366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes if (compiler->local_size <= (63 * sizeof(sljit_sw))) { 1232f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) 1233f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15))); 12340ea9883633b5d1fcfc777d57427bbf9b0098397eElliott Hughes } else if (saved_regs_size > 0) { 12358366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); 1236f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1237f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1238f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, RET | RN(TMP_LR))); 1239f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 1240f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1241f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1242f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 1243f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Operators */ 1244f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 1245f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 12468b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) 1247f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 12488b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_ins inv_bits = (op & SLJIT_I32_OP) ? (1 << 31) : 0; 1249f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1250f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR(); 12518366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK(check_sljit_emit_op0(compiler, op)); 1252f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1253f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich op = GET_OPCODE(op); 1254f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich switch (op) { 1255f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_BREAKPOINT: 1256f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, BRK); 1257f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_NOP: 1258f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, NOP); 12598b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_LMUL_UW: 12608b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_LMUL_SW: 1261f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); 1262f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); 12638b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); 12648b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_DIVMOD_UW: 12658b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_DIVMOD_SW: 1266f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); 12678b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis FAIL_IF(push_inst(compiler, ((op == SLJIT_DIVMOD_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1))); 1268f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); 1269f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); 12708b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_DIV_UW: 12718b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_DIV_SW: 12728b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis return push_inst(compiler, ((op == SLJIT_DIV_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)); 1273f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1274f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1275f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 1276f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1277f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 12788b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, 12798b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst, sljit_sw dstw, 12808b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 src, sljit_sw srcw) 1281f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 12828b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst_r, flags, mem_flags; 12838b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 op_flags = GET_ALL_FLAGS(op); 1284f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1285f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR(); 12868366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); 1287f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(dst, dstw); 1288f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(src, srcw); 1289f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1290f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_arg = 0; 1291f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_argw = 0; 1292f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1293f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; 1294f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1295f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich op = GET_OPCODE(op); 1296f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { 1297f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich switch (op) { 1298f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOV: 1299f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOV_P: 1300f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = WORD_SIZE; 1301f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 13028b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOV_U8: 1303f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = BYTE_SIZE; 1304f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) 13058b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_u8)srcw; 1306f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 13078b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOV_S8: 1308f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = BYTE_SIZE | SIGNED; 1309f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) 13108b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_s8)srcw; 1311f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 13128b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOV_U16: 1313f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = HALF_SIZE; 1314f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) 13158b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_u16)srcw; 1316f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 13178b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOV_S16: 1318f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = HALF_SIZE | SIGNED; 1319f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) 13208b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_s16)srcw; 1321f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 13228b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOV_U32: 1323f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = INT_SIZE; 1324f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) 13258b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_u32)srcw; 1326f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 13278b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOV_S32: 1328f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = INT_SIZE | SIGNED; 1329f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) 13308b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_s32)srcw; 1331f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 1332f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOVU: 1333f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOVU_P: 1334f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = WORD_SIZE | UPDATE; 1335f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 13368b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOVU_U8: 1337f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = BYTE_SIZE | UPDATE; 1338f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) 13398b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_u8)srcw; 1340f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 13418b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOVU_S8: 1342f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = BYTE_SIZE | SIGNED | UPDATE; 1343f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) 13448b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_s8)srcw; 1345f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 13468b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOVU_U16: 1347f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = HALF_SIZE | UPDATE; 1348f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) 13498b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_u16)srcw; 1350f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 13518b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOVU_S16: 1352f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = HALF_SIZE | SIGNED | UPDATE; 1353f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) 13548b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_s16)srcw; 1355f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 13568b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOVU_U32: 1357f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = INT_SIZE | UPDATE; 1358f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) 13598b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_u32)srcw; 1360f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 13618b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOVU_S32: 1362f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = INT_SIZE | SIGNED | UPDATE; 1363f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) 13648b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_s32)srcw; 1365f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 1366f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich default: 1367f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT_STOP(); 1368f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = 0; 1369f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 1370f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1371f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1372f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) 1373f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw)); 1374f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else if (src & SLJIT_MEM) { 1375f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (getput_arg_fast(compiler, flags, dst_r, src, srcw)) 1376f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(compiler->error); 1377f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 1378f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw)); 1379f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } else { 1380f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst_r != TMP_REG1) 13818b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis return emit_op_imm(compiler, op | ((op_flags & SLJIT_I32_OP) ? INT_OP : 0), dst_r, TMP_REG1, src); 1382f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich dst_r = src; 1383f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1384f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1385f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst & SLJIT_MEM) { 1386f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw)) 1387f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return compiler->error; 1388f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 1389f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0); 1390f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1391f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 1392f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1393f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1394f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = GET_FLAGS(op_flags) ? SET_FLAGS : 0; 1395f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich mem_flags = WORD_SIZE; 13968b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis if (op_flags & SLJIT_I32_OP) { 1397f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags |= INT_OP; 1398f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich mem_flags = INT_SIZE; 1399f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1400f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1401f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst == SLJIT_UNUSED) 1402f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags |= UNUSED_RETURN; 1403f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1404f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_MEM) { 1405f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src, srcw)) 1406f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(compiler->error); 1407f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 1408f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src, srcw, dst, dstw)); 1409f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src = TMP_REG2; 1410f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1411f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1412f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_IMM) { 1413f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags |= ARG2_IMM; 14148b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis if (op_flags & SLJIT_I32_OP) 14158b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_s32)srcw; 1416f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } else 1417f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich srcw = src; 1418f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1419f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw); 1420f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1421f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst & SLJIT_MEM) { 1422f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw)) 1423f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return compiler->error; 1424f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 1425f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return getput_arg(compiler, mem_flags | STORE, dst_r, dst, dstw, 0, 0); 1426f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1427f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 1428f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1429f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 14308b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, 14318b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst, sljit_sw dstw, 14328b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 src1, sljit_sw src1w, 14338b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 src2, sljit_sw src2w) 1434f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 14358b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst_r, flags, mem_flags; 1436f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1437f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR(); 14388366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); 1439f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(dst, dstw); 1440f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(src1, src1w); 1441f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(src2, src2w); 1442f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1443f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_arg = 0; 1444f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_argw = 0; 1445f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1446f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; 1447f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = GET_FLAGS(op) ? SET_FLAGS : 0; 1448f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich mem_flags = WORD_SIZE; 14498b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis if (op & SLJIT_I32_OP) { 1450f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags |= INT_OP; 1451f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich mem_flags = INT_SIZE; 1452f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1453f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1454f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst == SLJIT_UNUSED) 1455f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags |= UNUSED_RETURN; 1456f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1457f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, mem_flags | STORE | ARG_TEST, TMP_REG1, dst, dstw)) 1458f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags |= SLOW_DEST; 1459f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1460f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src1 & SLJIT_MEM) { 1461f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (getput_arg_fast(compiler, mem_flags, TMP_REG1, src1, src1w)) 1462f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(compiler->error); 1463f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 1464f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags |= SLOW_SRC1; 1465f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1466f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src2 & SLJIT_MEM) { 1467f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src2, src2w)) 1468f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(compiler->error); 1469f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 1470f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags |= SLOW_SRC2; 1471f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1472f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1473f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { 1474f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { 1475f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, src1, src1w)); 1476f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw)); 1477f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1478f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 1479f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, src2, src2w)); 1480f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw)); 1481f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1482f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1483f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else if (flags & SLOW_SRC1) 1484f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw)); 1485f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else if (flags & SLOW_SRC2) 1486f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw)); 1487f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1488f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src1 & SLJIT_MEM) 1489f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src1 = TMP_REG1; 1490f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src2 & SLJIT_MEM) 1491f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src2 = TMP_REG2; 1492f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1493f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src1 & SLJIT_IMM) 1494f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags |= ARG1_IMM; 1495f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 1496f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src1w = src1; 1497f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src2 & SLJIT_IMM) 1498f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags |= ARG2_IMM; 1499f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 1500f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src2w = src2; 1501f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1502f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w); 1503f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1504f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst & SLJIT_MEM) { 1505f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(flags & SLOW_DEST)) { 1506f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw); 1507f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return compiler->error; 1508f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1509f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return getput_arg(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0); 1510f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1511f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1512f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 1513f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1514f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 15158b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) 1516f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 15178366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK_REG_INDEX(check_sljit_get_register_index(reg)); 1518f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return reg_map[reg]; 1519f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1520f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 15218b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) 1522f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 15238366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); 1524f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return reg; 1525f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1526f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 15278b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, 15288b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis void *instruction, sljit_s32 size) 1529f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 1530f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR(); 15318366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); 1532f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1533f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, *(sljit_ins*)instruction); 1534f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1535f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1536f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 1537f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Floating point operators */ 1538f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 1539f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 15408b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) 1541f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 1542f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SLJIT_IS_FPU_AVAILABLE 1543f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_IS_FPU_AVAILABLE; 1544f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else 1545f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Available by default. */ 1546f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 1; 1547f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 1548f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1549f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 15508b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) 1551f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 15528b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_u32 shift = MEM_SIZE_SHIFT(flags); 1553f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins ins_bits = (shift << 30); 15548b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 other_r; 1555f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_sw diff; 1556f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1557f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(arg & SLJIT_MEM); 1558f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1559f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(flags & STORE)) 1560f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ins_bits |= 1 << 22; 1561f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1562f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (arg & OFFS_REG_MASK) { 1563f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich argw &= 3; 1564f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!argw || argw == shift) 1565f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, STR_FR | ins_bits | VT(reg) 1566f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0)); 1567f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich other_r = OFFS_REG(arg); 1568f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg &= REG_MASK; 1569f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg) | RM(other_r) | (argw << 10))); 1570f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg = TMP_REG1; 1571f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich argw = 0; 1572f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1573f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1574f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich arg &= REG_MASK; 1575f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (arg && argw >= 0 && ((argw >> shift) <= 0xfff) && (argw & ((1 << shift) - 1)) == 0) 1576f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(arg) | (argw << (10 - shift))); 1577f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1578f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (arg && argw <= 255 && argw >= -256) 1579f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(arg) | ((argw & 0x1ff) << 12)); 1580f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1581f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Slow cases */ 1582f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (compiler->cache_arg == SLJIT_MEM && argw != compiler->cache_argw) { 1583f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich diff = argw - compiler->cache_argw; 1584f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!arg && diff <= 255 && diff >= -256) 1585f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12)); 1586f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { 1587f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(compiler->error); 1588f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_argw = argw; 1589f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1590f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1591f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1592f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (compiler->cache_arg != SLJIT_MEM || argw != compiler->cache_argw) { 1593f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_arg = SLJIT_MEM; 1594f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_argw = argw; 1595f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); 1596f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1597f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1598f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (arg & REG_MASK) 1599f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, STR_FR | ins_bits | VT(reg) | RN(arg) | RM(TMP_REG3)); 1600f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(TMP_REG3)); 1601f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1602f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 16038b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, 16048b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst, sljit_sw dstw, 16058b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 src, sljit_sw srcw) 1606f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 16078b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; 16088b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; 1609f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 16108b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis if (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) 1611f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inv_bits |= (1 << 31); 1612f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1613f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_MEM) { 16148b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis emit_fop_mem(compiler, (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw); 1615f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src = TMP_FREG1; 1616f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1617f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1618f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src))); 1619f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1620f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED) 16218b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw); 1622f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 1623f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1624f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 16258b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, 16268b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst, sljit_sw dstw, 16278b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 src, sljit_sw srcw) 1628f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 16298b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; 16308b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; 1631f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 16328b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) 1633f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inv_bits |= (1 << 31); 1634f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1635f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_MEM) { 16368b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw); 1637f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src = TMP_REG1; 1638f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } else if (src & SLJIT_IMM) { 1639f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) 16408b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) 16418b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis srcw = (sljit_s32)srcw; 1642f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 1643f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); 1644f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src = TMP_REG1; 1645f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1646f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1647f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src))); 1648f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1649f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst & SLJIT_MEM) 16508b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis return emit_fop_mem(compiler, ((op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw); 1651f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 1652f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1653f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 16548b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, 16558b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 src1, sljit_sw src1w, 16568b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 src2, sljit_sw src2w) 1657f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 16588b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE; 16598b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; 1660f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1661f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src1 & SLJIT_MEM) { 1662f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w); 1663f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src1 = TMP_FREG1; 1664f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1665f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1666f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src2 & SLJIT_MEM) { 1667f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w); 1668f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src2 = TMP_FREG2; 1669f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1670f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1671f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2)); 1672f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1673f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 16748b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, 16758b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst, sljit_sw dstw, 16768b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 src, sljit_sw srcw) 1677f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 16788b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst_r, mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE; 1679f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins inv_bits; 1680f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1681f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR(); 1682f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_arg = 0; 1683f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_argw = 0; 1684f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1685f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x100) == WORD_SIZE, must_be_one_bit_difference); 1686f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); 1687f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 16888b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; 1689f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; 1690f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1691f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_MEM) { 16928b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw); 1693f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src = dst_r; 1694f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1695f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1696f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich switch (GET_OPCODE(op)) { 16978b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MOV_F64: 1698f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src != dst_r) { 1699f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst_r != TMP_FREG1) 1700f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src))); 1701f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 1702f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich dst_r = src; 1703f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1704f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 17058b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_NEG_F64: 1706f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src))); 1707f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 17088b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_ABS_F64: 1709f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src))); 1710f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 17118b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_CONV_F64_FROM_F32: 17128b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_F32_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src))); 1713f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 1714f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1715f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1716f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst & SLJIT_MEM) 1717f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return emit_fop_mem(compiler, mem_flags | STORE, dst_r, dst, dstw); 1718f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 1719f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1720f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 17218b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, 17228b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst, sljit_sw dstw, 17238b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 src1, sljit_sw src1w, 17248b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 src2, sljit_sw src2w) 1725f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 17268b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst_r, mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE; 17278b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; 1728f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1729f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR(); 17308366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); 1731f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(dst, dstw); 1732f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(src1, src1w); 1733f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(src2, src2w); 1734f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1735f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_arg = 0; 1736f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_argw = 0; 1737f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1738f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; 1739f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src1 & SLJIT_MEM) { 1740f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w); 1741f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src1 = TMP_FREG1; 1742f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1743f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src2 & SLJIT_MEM) { 1744f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w); 1745f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src2 = TMP_FREG2; 1746f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1747f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1748f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich switch (GET_OPCODE(op)) { 17498b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_ADD_F64: 1750f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); 1751f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 17528b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_SUB_F64: 1753f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); 1754f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 17558b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_MUL_F64: 1756f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); 1757f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 17588b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_DIV_F64: 1759f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); 1760f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich break; 1761f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1762f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1763f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(dst & SLJIT_MEM)) 1764f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 1765f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw); 1766f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1767f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1768f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 1769f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Other instructions */ 1770f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 1771f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 17728b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) 1773f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 1774f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR(); 17758366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); 1776f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(dst, dstw); 1777f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1778f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* For UNUSED dst. Uncommon, but possible. */ 1779f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst == SLJIT_UNUSED) 1780f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 1781f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1782f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (FAST_IS_REG(dst)) 1783f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(TMP_LR)); 1784f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1785f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Memory. */ 1786f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw); 1787f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1788f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 17898b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) 1790f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 1791f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR(); 17928366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); 1793f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(src, srcw); 1794f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1795f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (FAST_IS_REG(src)) 1796f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src))); 1797f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else if (src & SLJIT_MEM) 1798f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw)); 1799f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else if (src & SLJIT_IMM) 1800f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(load_immediate(compiler, TMP_LR, srcw)); 1801f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1802f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, RET | RN(TMP_LR)); 1803f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1804f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1805f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 1806f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Conditional instructions */ 1807f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* --------------------------------------------------------------------- */ 1808f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 18098b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic sljit_uw get_cc(sljit_s32 type) 1810f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 1811f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich switch (type) { 18128366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_EQUAL: 18138366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_MUL_NOT_OVERFLOW: 18148b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_EQUAL_F64: 1815f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0x1; 1816f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 18178366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_NOT_EQUAL: 18188366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_MUL_OVERFLOW: 18198b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_NOT_EQUAL_F64: 1820f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0x0; 1821f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 18228366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_LESS: 18238b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_LESS_F64: 1824f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0x2; 1825f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 18268366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_GREATER_EQUAL: 18278b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_GREATER_EQUAL_F64: 1828f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0x3; 1829f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 18308366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_GREATER: 18318b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_GREATER_F64: 1832f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0x9; 1833f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 18348366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_LESS_EQUAL: 18358b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_LESS_EQUAL_F64: 1836f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0x8; 1837f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 18388366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_SIG_LESS: 1839f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0xa; 1840f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 18418366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_SIG_GREATER_EQUAL: 1842f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0xb; 1843f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 18448366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_SIG_GREATER: 1845f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0xd; 1846f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 18478366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_SIG_LESS_EQUAL: 1848f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0xc; 1849f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 18508366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_OVERFLOW: 18518b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_UNORDERED_F64: 1852f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0x7; 1853f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 18548366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes case SLJIT_NOT_OVERFLOW: 18558b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis case SLJIT_ORDERED_F64: 1856f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0x6; 1857f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1858f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich default: 1859f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT_STOP(); 1860f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return 0xe; 1861f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1862f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1863f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1864f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) 1865f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 1866f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich struct sljit_label *label; 1867f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1868f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR_PTR(); 18698366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK_PTR(check_sljit_emit_label(compiler)); 1870f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1871f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (compiler->last_label && compiler->last_label->size == compiler->size) 1872f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return compiler->last_label; 1873f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1874f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); 1875f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(!label); 1876f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich set_label(label, compiler); 1877f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return label; 1878f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1879f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 18808b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) 1881f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 1882f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich struct sljit_jump *jump; 1883f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1884f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR_PTR(); 18858366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK_PTR(check_sljit_emit_jump(compiler, type)); 1886f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1887f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); 1888f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(!jump); 1889f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); 1890f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich type &= 0xff; 1891f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1892f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (type < SLJIT_JUMP) { 1893f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->flags |= IS_COND; 1894f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(push_inst(compiler, B_CC | (6 << 5) | get_cc(type))); 1895f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1896f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else if (type >= SLJIT_FAST_CALL) 1897f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->flags |= IS_BL; 1898f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1899f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0)); 1900f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->addr = compiler->size; 1901f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1))); 1902f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1903f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return jump; 1904f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1905f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 19068b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskisstatic SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_s32 type, 19078b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 src, sljit_sw srcw) 1908f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 1909f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich struct sljit_jump *jump; 19108b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_ins inv_bits = (type & SLJIT_I32_OP) ? (1 << 31) : 0; 1911f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 19128366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes SLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL); 1913f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(src, srcw); 1914f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1915f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); 1916f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(!jump); 1917f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); 1918f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->flags |= IS_CBZ | IS_COND; 1919f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1920f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_MEM) { 1921f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src, srcw)); 1922f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src = TMP_REG1; 1923f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1924f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else if (src & SLJIT_IMM) { 1925f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); 1926f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src = TMP_REG1; 1927f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1928f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(FAST_IS_REG(src)); 1929f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 19308366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes if ((type & 0xff) == SLJIT_EQUAL) 1931f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inv_bits |= 1 << 24; 1932f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1933f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(push_inst(compiler, (CBZ ^ inv_bits) | (6 << 5) | RT(src))); 1934f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0)); 1935f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->addr = compiler->size; 1936f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(push_inst(compiler, BR | RN(TMP_REG1))); 1937f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return jump; 1938f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1939f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 19408b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) 1941f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 1942f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich struct sljit_jump *jump; 1943f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1944f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR(); 19458366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); 1946f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(src, srcw); 1947f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1948f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* In ARM, we don't need to touch the arguments. */ 1949f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(src & SLJIT_IMM)) { 1950f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_MEM) { 1951f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw)); 1952f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src = TMP_REG1; 1953f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1954f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(src)); 1955f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1956f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1957f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); 1958f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(!jump); 1959f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0)); 1960f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->u.target = srcw; 1961f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1962f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0)); 1963f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich jump->addr = compiler->size; 1964f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1)); 1965f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 1966f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 19678b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, 19688b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst, sljit_sw dstw, 19698b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 src, sljit_sw srcw, 19708b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 type) 1971f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 19728b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst_r, flags, mem_flags; 1973f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins cc; 1974f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1975f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR(); 19768366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); 1977f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(dst, dstw); 1978f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(src, srcw); 1979f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1980f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst == SLJIT_UNUSED) 1981f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 1982f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 19838366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes cc = get_cc(type & 0xff); 1984f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; 1985f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1986f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (GET_OPCODE(op) < SLJIT_ADD) { 1987f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(dst_r) | RN(TMP_ZERO) | RM(TMP_ZERO))); 1988f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst_r != TMP_REG1) 1989f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 1990f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return emit_op_mem(compiler, (GET_OPCODE(op) == SLJIT_MOV ? WORD_SIZE : INT_SIZE) | STORE, TMP_REG1, dst, dstw); 1991f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 1992f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 1993f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_arg = 0; 1994f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich compiler->cache_argw = 0; 1995f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags = GET_FLAGS(op) ? SET_FLAGS : 0; 1996f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich mem_flags = WORD_SIZE; 19978b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis if (op & SLJIT_I32_OP) { 1998f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags |= INT_OP; 1999f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich mem_flags = INT_SIZE; 2000f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 2001f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 2002f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src & SLJIT_MEM) { 2003f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(emit_op_mem2(compiler, mem_flags, TMP_REG1, src, srcw, dst, dstw)); 2004f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src = TMP_REG1; 2005f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich srcw = 0; 2006f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } else if (src & SLJIT_IMM) 2007f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags |= ARG1_IMM; 2008f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 2009f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(TMP_ZERO))); 2010f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src, TMP_REG2); 2011f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 2012f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst_r != TMP_REG1) 2013f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 2014f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return emit_op_mem2(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0); 2015f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 2016f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 20178b979b2abae173bb836d8e85a842cfd00447d4beJanis DanisevskisSLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) 2018f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 2019f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich struct sljit_const *const_; 20208b979b2abae173bb836d8e85a842cfd00447d4beJanis Danisevskis sljit_s32 dst_r; 2021f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 2022f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich CHECK_ERROR_PTR(); 20238366e8beecf85b8e61b5c1a1369666db7a292eaeElliott Hughes CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); 2024f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ADJUST_LOCAL_OFFSET(dst, dstw); 2025f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 2026f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); 2027f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(!const_); 2028f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich set_const(const_, compiler); 2029f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 2030f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; 2031f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, init_value)); 2032f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 2033f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst & SLJIT_MEM) 2034f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw)); 2035f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return const_; 2036f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 2037f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 2038f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) 2039f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 2040f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins* inst = (sljit_ins*)addr; 2041f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich modify_imm64_const(inst, new_addr); 2042f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_CACHE_FLUSH(inst, inst + 4); 2043f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 2044f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 2045f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) 2046f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 2047f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins* inst = (sljit_ins*)addr; 2048f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich modify_imm64_const(inst, new_constant); 2049f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_CACHE_FLUSH(inst, inst + 4); 2050f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 2051