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