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