1 /*
2  *    Stack-less Just-In-Time compiler
3  *
4  *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without modification, are
7  * permitted provided that the following conditions are met:
8  *
9  *   1. Redistributions of source code must retain the above copyright notice, this list of
10  *      conditions and the following disclaimer.
11  *
12  *   2. Redistributions in binary form must reproduce the above copyright notice, this list
13  *      of conditions and the following disclaimer in the documentation and/or other materials
14  *      provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19  * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 /* Latest MIPS architecture. */
28 
29 #ifndef __mips_hard_float
30 /* Disable automatic detection, covers both -msoft-float and -mno-float */
31 #undef SLJIT_IS_FPU_AVAILABLE
32 #define SLJIT_IS_FPU_AVAILABLE 0
33 #endif
34 
sljit_get_platform_name(void)35 SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
36 {
37 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
38 
39 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
40 	return "MIPS32-R6" SLJIT_CPUINFO;
41 #else /* !SLJIT_CONFIG_MIPS_32 */
42 	return "MIPS64-R6" SLJIT_CPUINFO;
43 #endif /* SLJIT_CONFIG_MIPS_32 */
44 
45 #elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
46 
47 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
48 	return "MIPS32-R2" SLJIT_CPUINFO;
49 #else /* !SLJIT_CONFIG_MIPS_32 */
50 	return "MIPS64-R2" SLJIT_CPUINFO;
51 #endif /* SLJIT_CONFIG_MIPS_32 */
52 
53 #elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
54 
55 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
56 	return "MIPS32-R1" SLJIT_CPUINFO;
57 #else /* !SLJIT_CONFIG_MIPS_32 */
58 	return "MIPS64-R1" SLJIT_CPUINFO;
59 #endif /* SLJIT_CONFIG_MIPS_32 */
60 
61 #else /* SLJIT_MIPS_REV < 1 */
62 	return "MIPS III" SLJIT_CPUINFO;
63 #endif /* SLJIT_MIPS_REV >= 6 */
64 }
65 
66 /* Length of an instruction word
67    Both for mips-32 and mips-64 */
68 typedef sljit_u32 sljit_ins;
69 
70 #define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)
71 #define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)
72 #define TMP_REG3	(SLJIT_NUMBER_OF_REGISTERS + 4)
73 
74 /* For position independent code, t9 must contain the function address. */
75 #define PIC_ADDR_REG	TMP_REG2
76 
77 /* Floating point status register. */
78 #define FCSR_REG	31
79 /* Return address register. */
80 #define RETURN_ADDR_REG	31
81 
82 /* Flags are kept in volatile registers. */
83 #define EQUAL_FLAG	3
84 #define OTHER_FLAG	1
85 
86 #define TMP_FREG1	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
87 #define TMP_FREG2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
88 #define TMP_FREG3	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3)
89 
90 static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
91 	0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31
92 };
93 
94 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
95 
96 static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
97 	0, 0, 14, 2, 4, 6, 8, 18, 30, 28, 26, 24, 22, 20, 12, 10, 16
98 };
99 
100 #else
101 
102 static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
103 	0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 31, 30, 29, 28, 27, 26, 25, 24, 12, 11, 10
104 };
105 
106 #endif
107 
108 /* --------------------------------------------------------------------- */
109 /*  Instrucion forms                                                     */
110 /* --------------------------------------------------------------------- */
111 
112 #define S(s)		((sljit_ins)reg_map[s] << 21)
113 #define T(t)		((sljit_ins)reg_map[t] << 16)
114 #define D(d)		((sljit_ins)reg_map[d] << 11)
115 #define FT(t)		((sljit_ins)freg_map[t] << 16)
116 #define FS(s)		((sljit_ins)freg_map[s] << 11)
117 #define FD(d)		((sljit_ins)freg_map[d] << 6)
118 /* Absolute registers. */
119 #define SA(s)		((sljit_ins)(s) << 21)
120 #define TA(t)		((sljit_ins)(t) << 16)
121 #define DA(d)		((sljit_ins)(d) << 11)
122 #define IMM(imm)	((sljit_ins)(imm) & 0xffff)
123 #define SH_IMM(imm)	((sljit_ins)(imm) << 6)
124 
125 #define DR(dr)		(reg_map[dr])
126 #define FR(dr)		(freg_map[dr])
127 #define HI(opcode)	((sljit_ins)(opcode) << 26)
128 #define LO(opcode)	((sljit_ins)(opcode))
129 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
130 /* CMP.cond.fmt */
131 /* S = (20 << 21) D = (21 << 21) */
132 #define CMP_FMT_S	(20 << 21)
133 #endif /* SLJIT_MIPS_REV >= 6 */
134 /* S = (16 << 21) D = (17 << 21) */
135 #define FMT_S		(16 << 21)
136 #define FMT_D		(17 << 21)
137 
138 #define ABS_S		(HI(17) | FMT_S | LO(5))
139 #define ADD_S		(HI(17) | FMT_S | LO(0))
140 #define ADDIU		(HI(9))
141 #define ADDU		(HI(0) | LO(33))
142 #define AND		(HI(0) | LO(36))
143 #define ANDI		(HI(12))
144 #define B		(HI(4))
145 #define BAL		(HI(1) | (17 << 16))
146 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
147 #define BC1EQZ		(HI(17) | (9 << 21) | FT(TMP_FREG3))
148 #define BC1NEZ		(HI(17) | (13 << 21) | FT(TMP_FREG3))
149 #else /* SLJIT_MIPS_REV < 6 */
150 #define BC1F		(HI(17) | (8 << 21))
151 #define BC1T		(HI(17) | (8 << 21) | (1 << 16))
152 #endif /* SLJIT_MIPS_REV >= 6 */
153 #define BEQ		(HI(4))
154 #define BGEZ		(HI(1) | (1 << 16))
155 #define BGTZ		(HI(7))
156 #define BLEZ		(HI(6))
157 #define BLTZ		(HI(1) | (0 << 16))
158 #define BNE		(HI(5))
159 #define BREAK		(HI(0) | LO(13))
160 #define CFC1		(HI(17) | (2 << 21))
161 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
162 #define C_EQ_S		(HI(17) | CMP_FMT_S | LO(2))
163 #define C_OLE_S		(HI(17) | CMP_FMT_S | LO(6))
164 #define C_OLT_S		(HI(17) | CMP_FMT_S | LO(4))
165 #define C_UEQ_S		(HI(17) | CMP_FMT_S | LO(3))
166 #define C_ULE_S		(HI(17) | CMP_FMT_S | LO(7))
167 #define C_ULT_S		(HI(17) | CMP_FMT_S | LO(5))
168 #define C_UN_S		(HI(17) | CMP_FMT_S | LO(1))
169 #define C_FD		(FD(TMP_FREG3))
170 #else /* SLJIT_MIPS_REV < 6 */
171 #define C_EQ_S		(HI(17) | FMT_S | LO(50))
172 #define C_OLE_S		(HI(17) | FMT_S | LO(54))
173 #define C_OLT_S		(HI(17) | FMT_S | LO(52))
174 #define C_UEQ_S		(HI(17) | FMT_S | LO(51))
175 #define C_ULE_S		(HI(17) | FMT_S | LO(55))
176 #define C_ULT_S		(HI(17) | FMT_S | LO(53))
177 #define C_UN_S		(HI(17) | FMT_S | LO(49))
178 #define C_FD		(0)
179 #endif /* SLJIT_MIPS_REV >= 6 */
180 #define CVT_S_S		(HI(17) | FMT_S | LO(32))
181 #define DADDIU		(HI(25))
182 #define DADDU		(HI(0) | LO(45))
183 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
184 #define DDIV		(HI(0) | (2 << 6) | LO(30))
185 #define DDIVU		(HI(0) | (2 << 6) | LO(31))
186 #define DMOD		(HI(0) | (3 << 6) | LO(30))
187 #define DMODU		(HI(0) | (3 << 6) | LO(31))
188 #define DIV		(HI(0) | (2 << 6) | LO(26))
189 #define DIVU		(HI(0) | (2 << 6) | LO(27))
190 #define DMUH		(HI(0) | (3 << 6) | LO(28))
191 #define DMUHU		(HI(0) | (3 << 6) | LO(29))
192 #define DMUL		(HI(0) | (2 << 6) | LO(28))
193 #define DMULU		(HI(0) | (2 << 6) | LO(29))
194 #else /* SLJIT_MIPS_REV < 6 */
195 #define DDIV		(HI(0) | LO(30))
196 #define DDIVU		(HI(0) | LO(31))
197 #define DIV		(HI(0) | LO(26))
198 #define DIVU		(HI(0) | LO(27))
199 #define DMULT		(HI(0) | LO(28))
200 #define DMULTU		(HI(0) | LO(29))
201 #endif /* SLJIT_MIPS_REV >= 6 */
202 #define DIV_S		(HI(17) | FMT_S | LO(3))
203 #define DINSU		(HI(31) | LO(6))
204 #define DROTR		(HI(0) | (1 << 21) | LO(58))
205 #define DROTR32		(HI(0) | (1 << 21) | LO(62))
206 #define DROTRV		(HI(0) | (1 << 6) | LO(22))
207 #define DSLL		(HI(0) | LO(56))
208 #define DSLL32		(HI(0) | LO(60))
209 #define DSLLV		(HI(0) | LO(20))
210 #define DSRA		(HI(0) | LO(59))
211 #define DSRA32		(HI(0) | LO(63))
212 #define DSRAV		(HI(0) | LO(23))
213 #define DSRL		(HI(0) | LO(58))
214 #define DSRL32		(HI(0) | LO(62))
215 #define DSRLV		(HI(0) | LO(22))
216 #define DSUBU		(HI(0) | LO(47))
217 #define J		(HI(2))
218 #define JAL		(HI(3))
219 #define JALR		(HI(0) | LO(9))
220 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
221 #define JR		(HI(0) | LO(9))
222 #else /* SLJIT_MIPS_REV < 6 */
223 #define JR		(HI(0) | LO(8))
224 #endif /* SLJIT_MIPS_REV >= 6 */
225 #define LD		(HI(55))
226 #define LDL		(HI(26))
227 #define LDR		(HI(27))
228 #define LDC1		(HI(53))
229 #define LUI		(HI(15))
230 #define LW		(HI(35))
231 #define LWL		(HI(34))
232 #define LWR		(HI(38))
233 #define LWC1		(HI(49))
234 #define MFC1		(HI(17))
235 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
236 #define MOD		(HI(0) | (3 << 6) | LO(26))
237 #define MODU		(HI(0) | (3 << 6) | LO(27))
238 #else /* SLJIT_MIPS_REV < 6 */
239 #define MFHI		(HI(0) | LO(16))
240 #define MFLO		(HI(0) | LO(18))
241 #endif /* SLJIT_MIPS_REV >= 6 */
242 #define MOV_S		(HI(17) | FMT_S | LO(6))
243 #define MTC1		(HI(17) | (4 << 21))
244 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
245 #define MUH		(HI(0) | (3 << 6) | LO(24))
246 #define MUHU		(HI(0) | (3 << 6) | LO(25))
247 #define MUL		(HI(0) | (2 << 6) | LO(24))
248 #define MULU		(HI(0) | (2 << 6) | LO(25))
249 #else /* SLJIT_MIPS_REV < 6 */
250 #define MULT		(HI(0) | LO(24))
251 #define MULTU		(HI(0) | LO(25))
252 #endif /* SLJIT_MIPS_REV >= 6 */
253 #define MUL_S		(HI(17) | FMT_S | LO(2))
254 #define NEG_S		(HI(17) | FMT_S | LO(7))
255 #define NOP		(HI(0) | LO(0))
256 #define NOR		(HI(0) | LO(39))
257 #define OR		(HI(0) | LO(37))
258 #define ORI		(HI(13))
259 #define ROTR		(HI(0) | (1 << 21) | LO(2))
260 #define ROTRV		(HI(0) | (1 << 6) | LO(6))
261 #define SD		(HI(63))
262 #define SDL		(HI(44))
263 #define SDR		(HI(45))
264 #define SDC1		(HI(61))
265 #define SLT		(HI(0) | LO(42))
266 #define SLTI		(HI(10))
267 #define SLTIU		(HI(11))
268 #define SLTU		(HI(0) | LO(43))
269 #define SLL		(HI(0) | LO(0))
270 #define SLLV		(HI(0) | LO(4))
271 #define SRL		(HI(0) | LO(2))
272 #define SRLV		(HI(0) | LO(6))
273 #define SRA		(HI(0) | LO(3))
274 #define SRAV		(HI(0) | LO(7))
275 #define SUB_S		(HI(17) | FMT_S | LO(1))
276 #define SUBU		(HI(0) | LO(35))
277 #define SW		(HI(43))
278 #define SWL		(HI(42))
279 #define SWR		(HI(46))
280 #define SWC1		(HI(57))
281 #define TRUNC_W_S	(HI(17) | FMT_S | LO(13))
282 #define XOR		(HI(0) | LO(38))
283 #define XORI		(HI(14))
284 
285 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
286 #define CLZ		(HI(28) | LO(32))
287 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
288 #define DCLZ		(LO(18))
289 #else /* SLJIT_MIPS_REV < 6 */
290 #define DCLZ		(HI(28) | LO(36))
291 #define MOVF		(HI(0) | (0 << 16) | LO(1))
292 #define MOVN		(HI(0) | LO(11))
293 #define MOVT		(HI(0) | (1 << 16) | LO(1))
294 #define MOVZ		(HI(0) | LO(10))
295 #define MUL		(HI(28) | LO(2))
296 #endif /* SLJIT_MIPS_REV >= 6 */
297 #define PREF		(HI(51))
298 #define PREFX		(HI(19) | LO(15))
299 #define SEB		(HI(31) | (16 << 6) | LO(32))
300 #define SEH		(HI(31) | (24 << 6) | LO(32))
301 #endif /* SLJIT_MIPS_REV >= 1 */
302 
303 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
304 #define ADDU_W		ADDU
305 #define ADDIU_W		ADDIU
306 #define SLL_W		SLL
307 #define SRA_W		SRA
308 #define SUBU_W		SUBU
309 #define STORE_W		SW
310 #define LOAD_W		LW
311 #else
312 #define ADDU_W		DADDU
313 #define ADDIU_W		DADDIU
314 #define SLL_W		DSLL
315 #define SRA_W		DSRA
316 #define SUBU_W		DSUBU
317 #define STORE_W		SD
318 #define LOAD_W		LD
319 #endif
320 
321 #define SIMM_MAX	(0x7fff)
322 #define SIMM_MIN	(-0x8000)
323 #define UIMM_MAX	(0xffff)
324 
325 /* dest_reg is the absolute name of the register
326    Useful for reordering instructions in the delay slot. */
push_inst(struct sljit_compiler * compiler,sljit_ins ins,sljit_s32 delay_slot)327 static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)
328 {
329 	sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
330 	SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS
331 		|| (sljit_ins)delay_slot == ((ins >> 11) & 0x1f)
332 		|| (sljit_ins)delay_slot == ((ins >> 16) & 0x1f));
333 	FAIL_IF(!ptr);
334 	*ptr = ins;
335 	compiler->size++;
336 	compiler->delay_slot = delay_slot;
337 	return SLJIT_SUCCESS;
338 }
339 
invert_branch(sljit_uw flags)340 static SLJIT_INLINE sljit_ins invert_branch(sljit_uw flags)
341 {
342 	if (flags & IS_BIT26_COND)
343 		return (1 << 26);
344 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
345 	if (flags & IS_BIT23_COND)
346 		return (1 << 23);
347 #endif /* SLJIT_MIPS_REV >= 6 */
348 	return (1 << 16);
349 }
350 
detect_jump_type(struct sljit_jump * jump,sljit_ins * code,sljit_sw executable_offset)351 static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset)
352 {
353 	sljit_sw diff;
354 	sljit_uw target_addr;
355 	sljit_ins *inst;
356 	sljit_ins saved_inst;
357 
358 	inst = (sljit_ins *)jump->addr;
359 
360 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
361 	if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))
362 		goto exit;
363 #else
364 	if (jump->flags & SLJIT_REWRITABLE_JUMP)
365 		goto exit;
366 #endif
367 
368 	if (jump->flags & JUMP_ADDR)
369 		target_addr = jump->u.target;
370 	else {
371 		SLJIT_ASSERT(jump->flags & JUMP_LABEL);
372 		target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
373 	}
374 
375 	if (jump->flags & IS_COND)
376 		inst--;
377 
378 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
379 	if (jump->flags & IS_CALL)
380 		goto preserve_addr;
381 #endif
382 
383 	/* B instructions. */
384 	if (jump->flags & IS_MOVABLE) {
385 		diff = ((sljit_sw)target_addr - (sljit_sw)inst - executable_offset) >> 2;
386 		if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
387 			jump->flags |= PATCH_B;
388 
389 			if (!(jump->flags & IS_COND)) {
390 				inst[0] = inst[-1];
391 				inst[-1] = (jump->flags & IS_JAL) ? BAL : B;
392 				jump->addr -= sizeof(sljit_ins);
393 				return inst;
394 			}
395 			saved_inst = inst[0];
396 			inst[0] = inst[-1];
397 			inst[-1] = saved_inst ^ invert_branch(jump->flags);
398 			jump->addr -= 2 * sizeof(sljit_ins);
399 			return inst;
400 		}
401 	} else {
402 		diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1) - executable_offset) >> 2;
403 		if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
404 			jump->flags |= PATCH_B;
405 
406 			if (!(jump->flags & IS_COND)) {
407 				inst[0] = (jump->flags & IS_JAL) ? BAL : B;
408 				/* Keep inst[1] */
409 				return inst + 1;
410 			}
411 			inst[0] ^= invert_branch(jump->flags);
412 			inst[1] = NOP;
413 			jump->addr -= sizeof(sljit_ins);
414 			return inst + 1;
415 		}
416 	}
417 
418 	if (jump->flags & IS_COND) {
419 		if ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 2 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
420 			jump->flags |= PATCH_J;
421 			saved_inst = inst[0];
422 			inst[0] = inst[-1];
423 			inst[-1] = (saved_inst & 0xffff0000) | 3;
424 			inst[1] = J;
425 			inst[2] = NOP;
426 			return inst + 2;
427 		}
428 		else if ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
429 			jump->flags |= PATCH_J;
430 			inst[0] = (inst[0] & 0xffff0000) | 3;
431 			inst[1] = NOP;
432 			inst[2] = J;
433 			inst[3] = NOP;
434 			jump->addr += sizeof(sljit_ins);
435 			return inst + 3;
436 		}
437 	}
438 	else {
439 		/* J instuctions. */
440 		if ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == (jump->addr & ~(sljit_uw)0xfffffff)) {
441 			jump->flags |= PATCH_J;
442 			inst[0] = inst[-1];
443 			inst[-1] = (jump->flags & IS_JAL) ? JAL : J;
444 			jump->addr -= sizeof(sljit_ins);
445 			return inst;
446 		}
447 
448 		if ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
449 			jump->flags |= PATCH_J;
450 			inst[0] = (jump->flags & IS_JAL) ? JAL : J;
451 			/* Keep inst[1] */
452 			return inst + 1;
453 		}
454 	}
455 
456 	if (jump->flags & IS_COND)
457 		inst++;
458 
459 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
460 preserve_addr:
461 	if (target_addr <= 0x7fffffff) {
462 		jump->flags |= PATCH_ABS32;
463 		if (jump->flags & IS_COND)
464 			inst[-1] -= 4;
465 
466 		inst[2] = inst[0];
467 		inst[3] = inst[1];
468 		return inst + 3;
469 	}
470 	if (target_addr <= 0x7fffffffffffl) {
471 		jump->flags |= PATCH_ABS48;
472 		if (jump->flags & IS_COND)
473 			inst[-1] -= 2;
474 
475 		inst[4] = inst[0];
476 		inst[5] = inst[1];
477 		return inst + 5;
478 	}
479 #endif
480 
481 exit:
482 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
483 	inst[2] = inst[0];
484 	inst[3] = inst[1];
485 	return inst + 3;
486 #else
487 	inst[6] = inst[0];
488 	inst[7] = inst[1];
489 	return inst + 7;
490 #endif
491 }
492 
493 #ifdef __GNUC__
sljit_cache_flush(void * code,void * code_ptr)494 static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr)
495 {
496 	SLJIT_CACHE_FLUSH(code, code_ptr);
497 }
498 #endif
499 
500 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
501 
put_label_get_length(struct sljit_put_label * put_label,sljit_uw max_label)502 static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
503 {
504 	if (max_label < 0x80000000l) {
505 		put_label->flags = PATCH_ABS32;
506 		return 1;
507 	}
508 
509 	if (max_label < 0x800000000000l) {
510 		put_label->flags = PATCH_ABS48;
511 		return 3;
512 	}
513 
514 	put_label->flags = 0;
515 	return 5;
516 }
517 
518 #endif /* SLJIT_CONFIG_MIPS_64 */
519 
load_addr_to_reg(void * dst,sljit_u32 reg)520 static SLJIT_INLINE void load_addr_to_reg(void *dst, sljit_u32 reg)
521 {
522 	struct sljit_jump *jump;
523 	struct sljit_put_label *put_label;
524 	sljit_uw flags;
525 	sljit_ins *inst;
526 	sljit_uw addr;
527 
528 	if (reg != 0) {
529 		jump = (struct sljit_jump*)dst;
530 		flags = jump->flags;
531 		inst = (sljit_ins*)jump->addr;
532 		addr = (flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
533 	} else {
534 		put_label = (struct sljit_put_label*)dst;
535 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
536 		flags = put_label->flags;
537 #endif
538 		inst = (sljit_ins*)put_label->addr;
539 		addr = put_label->label->addr;
540 		reg = *inst;
541 	}
542 
543 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
544 	inst[0] = LUI | T(reg) | IMM(addr >> 16);
545 #else /* !SLJIT_CONFIG_MIPS_32 */
546 	if (flags & PATCH_ABS32) {
547 		SLJIT_ASSERT(addr < 0x80000000l);
548 		inst[0] = LUI | T(reg) | IMM(addr >> 16);
549 	}
550 	else if (flags & PATCH_ABS48) {
551 		SLJIT_ASSERT(addr < 0x800000000000l);
552 		inst[0] = LUI | T(reg) | IMM(addr >> 32);
553 		inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
554 		inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
555 		inst += 2;
556 	}
557 	else {
558 		inst[0] = LUI | T(reg) | IMM(addr >> 48);
559 		inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff);
560 		inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
561 		inst[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
562 		inst[4] = DSLL | T(reg) | D(reg) | SH_IMM(16);
563 		inst += 4;
564 	}
565 #endif /* SLJIT_CONFIG_MIPS_32 */
566 
567 	inst[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff);
568 }
569 
sljit_generate_code(struct sljit_compiler * compiler)570 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
571 {
572 	struct sljit_memory_fragment *buf;
573 	sljit_ins *code;
574 	sljit_ins *code_ptr;
575 	sljit_ins *buf_ptr;
576 	sljit_ins *buf_end;
577 	sljit_uw word_count;
578 	sljit_uw next_addr;
579 	sljit_sw executable_offset;
580 	sljit_uw addr;
581 
582 	struct sljit_label *label;
583 	struct sljit_jump *jump;
584 	struct sljit_const *const_;
585 	struct sljit_put_label *put_label;
586 
587 	CHECK_ERROR_PTR();
588 	CHECK_PTR(check_sljit_generate_code(compiler));
589 	reverse_buf(compiler);
590 
591 	code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
592 	PTR_FAIL_WITH_EXEC_IF(code);
593 	buf = compiler->buf;
594 
595 	code_ptr = code;
596 	word_count = 0;
597 	next_addr = 0;
598 	executable_offset = SLJIT_EXEC_OFFSET(code);
599 
600 	label = compiler->labels;
601 	jump = compiler->jumps;
602 	const_ = compiler->consts;
603 	put_label = compiler->put_labels;
604 
605 	do {
606 		buf_ptr = (sljit_ins*)buf->memory;
607 		buf_end = buf_ptr + (buf->used_size >> 2);
608 		do {
609 			*code_ptr = *buf_ptr++;
610 			if (next_addr == word_count) {
611 				SLJIT_ASSERT(!label || label->size >= word_count);
612 				SLJIT_ASSERT(!jump || jump->addr >= word_count);
613 				SLJIT_ASSERT(!const_ || const_->addr >= word_count);
614 				SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
615 
616 				/* These structures are ordered by their address. */
617 				if (label && label->size == word_count) {
618 					label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
619 					label->size = (sljit_uw)(code_ptr - code);
620 					label = label->next;
621 				}
622 				if (jump && jump->addr == word_count) {
623 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
624 					word_count += 2;
625 #else
626 					word_count += 6;
627 #endif
628 					jump->addr = (sljit_uw)(code_ptr - 1);
629 					code_ptr = detect_jump_type(jump, code, executable_offset);
630 					jump = jump->next;
631 				}
632 				if (const_ && const_->addr == word_count) {
633 					const_->addr = (sljit_uw)code_ptr;
634 					const_ = const_->next;
635 				}
636 				if (put_label && put_label->addr == word_count) {
637 					SLJIT_ASSERT(put_label->label);
638 					put_label->addr = (sljit_uw)code_ptr;
639 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
640 					code_ptr += 1;
641 					word_count += 1;
642 #else
643 					code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
644 					word_count += 5;
645 #endif
646 					put_label = put_label->next;
647 				}
648 				next_addr = compute_next_addr(label, jump, const_, put_label);
649 			}
650 			code_ptr++;
651 			word_count++;
652 		} while (buf_ptr < buf_end);
653 
654 		buf = buf->next;
655 	} while (buf);
656 
657 	if (label && label->size == word_count) {
658 		label->addr = (sljit_uw)code_ptr;
659 		label->size = (sljit_uw)(code_ptr - code);
660 		label = label->next;
661 	}
662 
663 	SLJIT_ASSERT(!label);
664 	SLJIT_ASSERT(!jump);
665 	SLJIT_ASSERT(!const_);
666 	SLJIT_ASSERT(!put_label);
667 	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
668 
669 	jump = compiler->jumps;
670 	while (jump) {
671 		do {
672 			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
673 			buf_ptr = (sljit_ins *)jump->addr;
674 
675 			if (jump->flags & PATCH_B) {
676 				addr = (sljit_uw)((sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) - sizeof(sljit_ins)) >> 2);
677 				SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN);
678 				buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((sljit_ins)addr & 0xffff);
679 				break;
680 			}
681 			if (jump->flags & PATCH_J) {
682 				SLJIT_ASSERT((addr & ~(sljit_uw)0xfffffff)
683 					== (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff));
684 				buf_ptr[0] |= (sljit_ins)(addr >> 2) & 0x03ffffff;
685 				break;
686 			}
687 
688 			load_addr_to_reg(jump, PIC_ADDR_REG);
689 		} while (0);
690 		jump = jump->next;
691 	}
692 
693 	put_label = compiler->put_labels;
694 	while (put_label) {
695 		load_addr_to_reg(put_label, 0);
696 		put_label = put_label->next;
697 	}
698 
699 	compiler->error = SLJIT_ERR_COMPILED;
700 	compiler->executable_offset = executable_offset;
701 	compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
702 
703 	code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
704 	code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
705 
706 #ifndef __GNUC__
707 	SLJIT_CACHE_FLUSH(code, code_ptr);
708 #else
709 	/* GCC workaround for invalid code generation with -O2. */
710 	sljit_cache_flush(code, code_ptr);
711 #endif
712 	SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
713 	return code;
714 }
715 
sljit_has_cpu_feature(sljit_s32 feature_type)716 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
717 {
718 #if defined(__GNUC__) && !defined(SLJIT_IS_FPU_AVAILABLE)
719 	sljit_sw fir = 0;
720 #endif /* __GNUC__ && !SLJIT_IS_FPU_AVAILABLE */
721 
722 	switch (feature_type) {
723 	case SLJIT_HAS_FPU:
724 #ifdef SLJIT_IS_FPU_AVAILABLE
725 		return SLJIT_IS_FPU_AVAILABLE;
726 #elif defined(__GNUC__)
727 		__asm__ ("cfc1 %0, $0" : "=r"(fir));
728 		return (fir >> 22) & 0x1;
729 #else
730 #error "FIR check is not implemented for this architecture"
731 #endif
732 	case SLJIT_HAS_ZERO_REGISTER:
733 		return 1;
734 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
735 	case SLJIT_HAS_CLZ:
736 	case SLJIT_HAS_CMOV:
737 	case SLJIT_HAS_PREFETCH:
738 		return 1;
739 
740 	case SLJIT_HAS_CTZ:
741 		return 2;
742 #endif /* SLJIT_MIPS_REV >= 1 */
743 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
744 	case SLJIT_HAS_ROT:
745 		return 1;
746 #endif /* SLJIT_MIPS_REV >= 2 */
747 	default:
748 		return 0;
749 	}
750 }
751 
sljit_cmp_info(sljit_s32 type)752 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
753 {
754 	return (type >= SLJIT_ORDERED_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL);
755 }
756 
757 /* --------------------------------------------------------------------- */
758 /*  Entry, exit                                                          */
759 /* --------------------------------------------------------------------- */
760 
761 /* Creates an index in data_transfer_insts array. */
762 #define LOAD_DATA	0x01
763 #define WORD_DATA	0x00
764 #define BYTE_DATA	0x02
765 #define HALF_DATA	0x04
766 #define INT_DATA	0x06
767 #define SIGNED_DATA	0x08
768 /* Separates integer and floating point registers */
769 #define GPR_REG		0x0f
770 #define DOUBLE_DATA	0x10
771 #define SINGLE_DATA	0x12
772 
773 #define MEM_MASK	0x1f
774 
775 #define ARG_TEST	0x00020
776 #define ALT_KEEP_CACHE	0x00040
777 #define CUMULATIVE_OP	0x00080
778 #define LOGICAL_OP	0x00100
779 #define IMM_OP		0x00200
780 #define MOVE_OP		0x00400
781 #define SRC2_IMM	0x00800
782 
783 #define UNUSED_DEST	0x01000
784 #define REG_DEST	0x02000
785 #define REG1_SOURCE	0x04000
786 #define REG2_SOURCE	0x08000
787 #define SLOW_SRC1	0x10000
788 #define SLOW_SRC2	0x20000
789 #define SLOW_DEST	0x40000
790 
791 static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw);
792 static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr);
793 
794 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
795 #include "sljitNativeMIPS_32.c"
796 #else
797 #include "sljitNativeMIPS_64.c"
798 #endif
799 
sljit_emit_enter(struct sljit_compiler * compiler,sljit_s32 options,sljit_s32 arg_types,sljit_s32 scratches,sljit_s32 saveds,sljit_s32 fscratches,sljit_s32 fsaveds,sljit_s32 local_size)800 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
801 	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
802 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
803 {
804 	sljit_ins base;
805 	sljit_s32 i, tmp, offset;
806 	sljit_s32 arg_count, word_arg_count, float_arg_count;
807 	sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);
808 
809 	CHECK_ERROR();
810 	CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
811 	set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
812 
813 	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);
814 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
815 	if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
816 		if ((local_size & SSIZE_OF(sw)) != 0)
817 			local_size += SSIZE_OF(sw);
818 		local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
819 	}
820 
821 	local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
822 #else
823 	local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
824 	local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
825 #endif
826 	compiler->local_size = local_size;
827 
828 	offset = 0;
829 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
830 	if (!(options & SLJIT_ENTER_REG_ARG)) {
831 		tmp = arg_types >> SLJIT_ARG_SHIFT;
832 		arg_count = 0;
833 
834 		while (tmp) {
835 			offset = arg_count;
836 			if ((tmp & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F64) {
837 				if ((arg_count & 0x1) != 0)
838 					arg_count++;
839 				arg_count++;
840 			}
841 
842 			arg_count++;
843 			tmp >>= SLJIT_ARG_SHIFT;
844 		}
845 
846 		compiler->args_size = (sljit_uw)arg_count << 2;
847 		offset = (offset >= 4) ? (offset << 2) : 0;
848 	}
849 #endif /* SLJIT_CONFIG_MIPS_32 */
850 
851 	if (local_size + offset <= -SIMM_MIN) {
852 		/* Frequent case. */
853 		FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP)));
854 		base = S(SLJIT_SP);
855 		offset = local_size - SSIZE_OF(sw);
856 	} else {
857 		FAIL_IF(load_immediate(compiler, OTHER_FLAG, local_size));
858 		FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
859 		FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | TA(OTHER_FLAG) | D(SLJIT_SP), DR(SLJIT_SP)));
860 		base = S(TMP_REG2);
861 		offset = -SSIZE_OF(sw);
862 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
863 		local_size = 0;
864 #endif
865 	}
866 
867 	FAIL_IF(push_inst(compiler, STORE_W | base | TA(RETURN_ADDR_REG) | IMM(offset), UNMOVABLE_INS));
868 
869 	tmp = SLJIT_S0 - saveds;
870 	for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {
871 		offset -= SSIZE_OF(sw);
872 		FAIL_IF(push_inst(compiler, STORE_W | base | T(i) | IMM(offset), MOVABLE_INS));
873 	}
874 
875 	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
876 		offset -= SSIZE_OF(sw);
877 		FAIL_IF(push_inst(compiler, STORE_W | base | T(i) | IMM(offset), MOVABLE_INS));
878 	}
879 
880 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
881 	/* This alignment is valid because offset is not used after storing FPU regs. */
882 	if ((offset & SSIZE_OF(sw)) != 0)
883 		offset -= SSIZE_OF(sw);
884 #endif
885 
886 	tmp = SLJIT_FS0 - fsaveds;
887 	for (i = SLJIT_FS0; i > tmp; i--) {
888 		offset -= SSIZE_OF(f64);
889 		FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
890 	}
891 
892 	for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
893 		offset -= SSIZE_OF(f64);
894 		FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
895 	}
896 
897 	if (options & SLJIT_ENTER_REG_ARG)
898 		return SLJIT_SUCCESS;
899 
900 	arg_types >>= SLJIT_ARG_SHIFT;
901 	arg_count = 0;
902 	word_arg_count = 0;
903 	float_arg_count = 0;
904 
905 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
906 	/* The first maximum two floating point arguments are passed in floating point
907 	   registers if no integer argument precedes them. The first 16 byte data is
908 	   passed in four integer registers, the rest is placed onto the stack.
909 	   The floating point registers are also part of the first 16 byte data, so
910 	   their corresponding integer registers are not used when they are present. */
911 
912 	while (arg_types) {
913 		switch (arg_types & SLJIT_ARG_MASK) {
914 		case SLJIT_ARG_TYPE_F64:
915 			float_arg_count++;
916 			if ((arg_count & 0x1) != 0)
917 				arg_count++;
918 
919 			if (word_arg_count == 0 && float_arg_count <= 2) {
920 				if (float_arg_count == 1)
921 					FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
922 			} else if (arg_count < 4) {
923 				FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
924 				FAIL_IF(push_inst(compiler, MTC1 | TA(5 + arg_count) | FS(float_arg_count) | (1 << 11), MOVABLE_INS));
925 			} else
926 				FAIL_IF(push_inst(compiler, LDC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
927 			arg_count++;
928 			break;
929 		case SLJIT_ARG_TYPE_F32:
930 			float_arg_count++;
931 
932 			if (word_arg_count == 0 && float_arg_count <= 2) {
933 				if (float_arg_count == 1)
934 					FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
935 			} else if (arg_count < 4)
936 				FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
937 			else
938 				FAIL_IF(push_inst(compiler, LWC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
939 			break;
940 		default:
941 			word_arg_count++;
942 
943 			if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
944 				tmp = SLJIT_S0 - saved_arg_count;
945 				saved_arg_count++;
946 			} else if (word_arg_count != arg_count + 1 || arg_count == 0)
947 				tmp = word_arg_count;
948 			else
949 				break;
950 
951 			if (arg_count < 4)
952 				FAIL_IF(push_inst(compiler, ADDU_W | SA(4 + arg_count) | TA(0) | D(tmp), DR(tmp)));
953 			else
954 				FAIL_IF(push_inst(compiler, LW | base | T(tmp) | IMM(local_size + (arg_count << 2)), DR(tmp)));
955 			break;
956 		}
957 		arg_count++;
958 		arg_types >>= SLJIT_ARG_SHIFT;
959 	}
960 
961 	SLJIT_ASSERT(compiler->args_size == (sljit_uw)arg_count << 2);
962 #else /* !SLJIT_CONFIG_MIPS_32 */
963 	while (arg_types) {
964 		arg_count++;
965 		switch (arg_types & SLJIT_ARG_MASK) {
966 		case SLJIT_ARG_TYPE_F64:
967 			float_arg_count++;
968 			if (arg_count != float_arg_count)
969 				FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
970 			else if (arg_count == 1)
971 				FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
972 			break;
973 		case SLJIT_ARG_TYPE_F32:
974 			float_arg_count++;
975 			if (arg_count != float_arg_count)
976 				FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
977 			else if (arg_count == 1)
978 				FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
979 			break;
980 		default:
981 			word_arg_count++;
982 
983 			if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
984 				tmp = SLJIT_S0 - saved_arg_count;
985 				saved_arg_count++;
986 			} else if (word_arg_count != arg_count || word_arg_count <= 1)
987 				tmp = word_arg_count;
988 			else
989 				break;
990 
991 			FAIL_IF(push_inst(compiler, ADDU_W | SA(3 + arg_count) | TA(0) | D(tmp), DR(tmp)));
992 			break;
993 		}
994 		arg_types >>= SLJIT_ARG_SHIFT;
995 	}
996 #endif /* SLJIT_CONFIG_MIPS_32 */
997 
998 	return SLJIT_SUCCESS;
999 }
1000 
sljit_set_context(struct sljit_compiler * compiler,sljit_s32 options,sljit_s32 arg_types,sljit_s32 scratches,sljit_s32 saveds,sljit_s32 fscratches,sljit_s32 fsaveds,sljit_s32 local_size)1001 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
1002 	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
1003 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
1004 {
1005 	CHECK_ERROR();
1006 	CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
1007 	set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
1008 
1009 	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);
1010 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1011 	if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
1012 		if ((local_size & SSIZE_OF(sw)) != 0)
1013 			local_size += SSIZE_OF(sw);
1014 		local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
1015 	}
1016 
1017 	compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
1018 #else
1019 	local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
1020 	compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
1021 #endif
1022 	return SLJIT_SUCCESS;
1023 }
1024 
emit_stack_frame_release(struct sljit_compiler * compiler,sljit_s32 frame_size,sljit_ins * ins_ptr)1025 static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr)
1026 {
1027 	sljit_s32 local_size, i, tmp, offset;
1028 	sljit_s32 load_return_addr = (frame_size == 0);
1029 	sljit_s32 scratches = compiler->scratches;
1030 	sljit_s32 saveds = compiler->saveds;
1031 	sljit_s32 fsaveds = compiler->fsaveds;
1032 	sljit_s32 fscratches = compiler->fscratches;
1033 	sljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);
1034 
1035 	SLJIT_ASSERT(frame_size == 1 || (frame_size & 0xf) == 0);
1036 	frame_size &= ~0xf;
1037 
1038 	local_size = compiler->local_size;
1039 
1040 	tmp = GET_SAVED_REGISTERS_SIZE(scratches, saveds - kept_saveds_count, 1);
1041 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1042 	if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
1043 		if ((tmp & SSIZE_OF(sw)) != 0)
1044 			tmp += SSIZE_OF(sw);
1045 		tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
1046 	}
1047 #else
1048 	tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
1049 #endif
1050 
1051 	if (local_size <= SIMM_MAX) {
1052 		if (local_size < frame_size) {
1053 			FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size), DR(SLJIT_SP)));
1054 			local_size = frame_size;
1055 		}
1056 	} else {
1057 		if (tmp < frame_size)
1058 			tmp = frame_size;
1059 
1060 		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size - tmp));
1061 		FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG1) | D(SLJIT_SP), DR(SLJIT_SP)));
1062 		local_size = tmp;
1063 	}
1064 
1065 	SLJIT_ASSERT(local_size >= frame_size);
1066 
1067 	offset = local_size - SSIZE_OF(sw);
1068 	if (load_return_addr)
1069 		FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | TA(RETURN_ADDR_REG) | IMM(offset), RETURN_ADDR_REG));
1070 
1071 	tmp = SLJIT_S0 - saveds;
1072 	for (i = SLJIT_S0 - kept_saveds_count; i > tmp; i--) {
1073 		offset -= SSIZE_OF(sw);
1074 		FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
1075 	}
1076 
1077 	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
1078 		offset -= SSIZE_OF(sw);
1079 		FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
1080 	}
1081 
1082 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1083 	/* This alignment is valid because offset is not used after storing FPU regs. */
1084 	if ((offset & SSIZE_OF(sw)) != 0)
1085 		offset -= SSIZE_OF(sw);
1086 #endif
1087 
1088 	tmp = SLJIT_FS0 - fsaveds;
1089 	for (i = SLJIT_FS0; i > tmp; i--) {
1090 		offset -= SSIZE_OF(f64);
1091 		FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
1092 	}
1093 
1094 	for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
1095 		offset -= SSIZE_OF(f64);
1096 		FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
1097 	}
1098 
1099 	if (local_size > frame_size)
1100 		*ins_ptr = ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size);
1101 	else
1102 		*ins_ptr = NOP;
1103 
1104 	return SLJIT_SUCCESS;
1105 }
1106 
sljit_emit_return_void(struct sljit_compiler * compiler)1107 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
1108 {
1109 	sljit_ins ins;
1110 
1111 	CHECK_ERROR();
1112 	CHECK(check_sljit_emit_return_void(compiler));
1113 
1114 	emit_stack_frame_release(compiler, 0, &ins);
1115 
1116 	FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
1117 	return push_inst(compiler, ins, UNMOVABLE_INS);
1118 }
1119 
sljit_emit_return_to(struct sljit_compiler * compiler,sljit_s32 src,sljit_sw srcw)1120 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
1121 	sljit_s32 src, sljit_sw srcw)
1122 {
1123 	sljit_ins ins;
1124 
1125 	CHECK_ERROR();
1126 	CHECK(check_sljit_emit_return_to(compiler, src, srcw));
1127 
1128 	if (src & SLJIT_MEM) {
1129 		ADJUST_LOCAL_OFFSET(src, srcw);
1130 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
1131 		src = PIC_ADDR_REG;
1132 		srcw = 0;
1133 	} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
1134 		FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
1135 		src = PIC_ADDR_REG;
1136 		srcw = 0;
1137 	}
1138 
1139 	FAIL_IF(emit_stack_frame_release(compiler, 1, &ins));
1140 
1141 	if (!(src & SLJIT_IMM)) {
1142 		FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));
1143 		return push_inst(compiler, ins, UNMOVABLE_INS);
1144 	}
1145 
1146 	if (ins != NOP)
1147 		FAIL_IF(push_inst(compiler, ins, MOVABLE_INS));
1148 
1149 	SLJIT_SKIP_CHECKS(compiler);
1150 	return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
1151 }
1152 
1153 /* --------------------------------------------------------------------- */
1154 /*  Operators                                                            */
1155 /* --------------------------------------------------------------------- */
1156 
1157 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1158 #define ARCH_32_64(a, b)	a
1159 #else
1160 #define ARCH_32_64(a, b)	b
1161 #endif
1162 
1163 static const sljit_ins data_transfer_insts[16 + 4] = {
1164 /* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
1165 /* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
1166 /* u b s */ HI(40) /* sb */,
1167 /* u b l */ HI(36) /* lbu */,
1168 /* u h s */ HI(41) /* sh */,
1169 /* u h l */ HI(37) /* lhu */,
1170 /* u i s */ HI(43) /* sw */,
1171 /* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */),
1172 
1173 /* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
1174 /* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
1175 /* s b s */ HI(40) /* sb */,
1176 /* s b l */ HI(32) /* lb */,
1177 /* s h s */ HI(41) /* sh */,
1178 /* s h l */ HI(33) /* lh */,
1179 /* s i s */ HI(43) /* sw */,
1180 /* s i l */ HI(35) /* lw */,
1181 
1182 /* d   s */ HI(61) /* sdc1 */,
1183 /* d   l */ HI(53) /* ldc1 */,
1184 /* s   s */ HI(57) /* swc1 */,
1185 /* s   l */ HI(49) /* lwc1 */,
1186 };
1187 
1188 #undef ARCH_32_64
1189 
1190 /* reg_ar is an absoulute register! */
1191 
1192 /* Can perform an operation using at most 1 instruction. */
getput_arg_fast(struct sljit_compiler * compiler,sljit_s32 flags,sljit_s32 reg_ar,sljit_s32 arg,sljit_sw argw)1193 static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
1194 {
1195 	SLJIT_ASSERT(arg & SLJIT_MEM);
1196 
1197 	if (!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
1198 		/* Works for both absoulte and relative addresses. */
1199 		if (SLJIT_UNLIKELY(flags & ARG_TEST))
1200 			return 1;
1201 		FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & REG_MASK)
1202 			| TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS));
1203 		return -1;
1204 	}
1205 	return 0;
1206 }
1207 
1208 #define TO_ARGW_HI(argw) (((argw) & ~0xffff) + (((argw) & 0x8000) ? 0x10000 : 0))
1209 
1210 /* See getput_arg below.
1211    Note: can_cache is called only for binary operators. */
can_cache(sljit_s32 arg,sljit_sw argw,sljit_s32 next_arg,sljit_sw next_argw)1212 static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
1213 {
1214 	SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
1215 
1216 	/* Simple operation except for updates. */
1217 	if (arg & OFFS_REG_MASK) {
1218 		argw &= 0x3;
1219 		next_argw &= 0x3;
1220 		if (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))
1221 			return 1;
1222 		return 0;
1223 	}
1224 
1225 	if (arg == next_arg) {
1226 		if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)
1227 				|| TO_ARGW_HI(argw) == TO_ARGW_HI(next_argw))
1228 			return 1;
1229 		return 0;
1230 	}
1231 
1232 	return 0;
1233 }
1234 
1235 /* Emit the necessary instructions. See can_cache above. */
getput_arg(struct sljit_compiler * compiler,sljit_s32 flags,sljit_s32 reg_ar,sljit_s32 arg,sljit_sw argw,sljit_s32 next_arg,sljit_sw next_argw)1236 static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
1237 {
1238 	sljit_s32 tmp_ar, base, delay_slot;
1239 	sljit_sw offset, argw_hi;
1240 
1241 	SLJIT_ASSERT(arg & SLJIT_MEM);
1242 	if (!(next_arg & SLJIT_MEM)) {
1243 		next_arg = 0;
1244 		next_argw = 0;
1245 	}
1246 
1247 	/* Since tmp can be the same as base or offset registers,
1248 	 * these might be unavailable after modifying tmp. */
1249 	if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
1250 		tmp_ar = reg_ar;
1251 		delay_slot = reg_ar;
1252 	}
1253 	else {
1254 		tmp_ar = DR(TMP_REG1);
1255 		delay_slot = MOVABLE_INS;
1256 	}
1257 	base = arg & REG_MASK;
1258 
1259 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
1260 		argw &= 0x3;
1261 
1262 		/* Using the cache. */
1263 		if (argw == compiler->cache_argw) {
1264 			if (arg == compiler->cache_arg)
1265 				return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
1266 
1267 			if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
1268 				if (arg == next_arg && argw == (next_argw & 0x3)) {
1269 					compiler->cache_arg = arg;
1270 					compiler->cache_argw = argw;
1271 					FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
1272 					return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
1273 				}
1274 				FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar));
1275 				return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1276 			}
1277 		}
1278 
1279 		if (SLJIT_UNLIKELY(argw)) {
1280 			compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
1281 			compiler->cache_argw = argw;
1282 			FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3)));
1283 		}
1284 
1285 		if (arg == next_arg && argw == (next_argw & 0x3)) {
1286 			compiler->cache_arg = arg;
1287 			compiler->cache_argw = argw;
1288 			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
1289 			tmp_ar = DR(TMP_REG3);
1290 		}
1291 		else
1292 			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | DA(tmp_ar), tmp_ar));
1293 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1294 	}
1295 
1296 	if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN)
1297 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(argw - compiler->cache_argw), delay_slot);
1298 
1299 	if (compiler->cache_arg == SLJIT_MEM && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) {
1300 		offset = argw - compiler->cache_argw;
1301 	} else {
1302 		compiler->cache_arg = SLJIT_MEM;
1303 
1304 		argw_hi = TO_ARGW_HI(argw);
1305 
1306 		if (next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN && argw_hi != TO_ARGW_HI(next_argw)) {
1307 			FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
1308 			compiler->cache_argw = argw;
1309 			offset = 0;
1310 		} else {
1311 			FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw_hi));
1312 			compiler->cache_argw = argw_hi;
1313 			offset = argw & 0xffff;
1314 			argw = argw_hi;
1315 		}
1316 	}
1317 
1318 	if (!base)
1319 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(offset), delay_slot);
1320 
1321 	if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) {
1322 		compiler->cache_arg = arg;
1323 		FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3)));
1324 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(offset), delay_slot);
1325 	}
1326 
1327 	FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar));
1328 	return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar) | IMM(offset), delay_slot);
1329 }
1330 
emit_op_mem(struct sljit_compiler * compiler,sljit_s32 flags,sljit_s32 reg_ar,sljit_s32 arg,sljit_sw argw)1331 static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
1332 {
1333 	sljit_s32 tmp_ar, base, delay_slot;
1334 
1335 	if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
1336 		return compiler->error;
1337 
1338 	if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
1339 		tmp_ar = reg_ar;
1340 		delay_slot = reg_ar;
1341 	}
1342 	else {
1343 		tmp_ar = DR(TMP_REG1);
1344 		delay_slot = MOVABLE_INS;
1345 	}
1346 	base = arg & REG_MASK;
1347 
1348 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
1349 		argw &= 0x3;
1350 
1351 		if (SLJIT_UNLIKELY(argw)) {
1352 			FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | DA(tmp_ar) | SH_IMM(argw), tmp_ar));
1353 			FAIL_IF(push_inst(compiler, ADDU_W | SA(tmp_ar) | T(base) | DA(tmp_ar), tmp_ar));
1354 		}
1355 		else
1356 			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(OFFS_REG(arg)) | DA(tmp_ar), tmp_ar));
1357 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1358 	}
1359 
1360 	FAIL_IF(load_immediate(compiler, tmp_ar, TO_ARGW_HI(argw)));
1361 
1362 	if (base != 0)
1363 		FAIL_IF(push_inst(compiler, ADDU_W | SA(tmp_ar) | T(base) | DA(tmp_ar), tmp_ar));
1364 
1365 	return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar) | IMM(argw), delay_slot);
1366 }
1367 
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)1368 static 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)
1369 {
1370 	if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
1371 		return compiler->error;
1372 	return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
1373 }
1374 
1375 #define EMIT_LOGICAL(op_imm, op_reg) \
1376 	if (flags & SRC2_IMM) { \
1377 		if (op & SLJIT_SET_Z) \
1378 			FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
1379 		if (!(flags & UNUSED_DEST)) \
1380 			FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
1381 	} \
1382 	else { \
1383 		if (op & SLJIT_SET_Z) \
1384 			FAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
1385 		if (!(flags & UNUSED_DEST)) \
1386 			FAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | D(dst), DR(dst))); \
1387 	}
1388 
1389 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1390 
1391 #define SELECT_OP(a, b) (b)
1392 
1393 #define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \
1394 	op_imm = (imm); \
1395 	op_v = (v);
1396 
1397 #else /* !SLJIT_CONFIG_MIPS_32 */
1398 
1399 #define SELECT_OP(a, b) \
1400 	(!(op & SLJIT_32) ? a : b)
1401 
1402 #define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \
1403 	op_dimm = (dimm); \
1404 	op_dimm32 = (dimm32); \
1405 	op_imm = (imm); \
1406 	op_dv = (dv); \
1407 	op_v = (v);
1408 
1409 #endif /* SLJIT_CONFIG_MIPS_32 */
1410 
1411 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV < 1)
1412 
emit_clz_ctz(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw src)1413 static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)
1414 {
1415 	sljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ);
1416 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1417 	sljit_ins max = (op & SLJIT_32) ? 32 : 64;
1418 #else /* !SLJIT_CONFIG_RISCV_64 */
1419 	sljit_ins max = 32;
1420 #endif /* SLJIT_CONFIG_RISCV_64 */
1421 
1422 	/* The TMP_REG2 is the next value. */
1423 	if (src != TMP_REG2)
1424 		FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
1425 
1426 	FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(is_clz ? 13 : 14), UNMOVABLE_INS));
1427 	/* The OTHER_FLAG is the counter. Delay slot. */
1428 	FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(max), OTHER_FLAG));
1429 
1430 	if (!is_clz) {
1431 		FAIL_IF(push_inst(compiler, ANDI | S(TMP_REG2) | T(TMP_REG1) | IMM(1), DR(TMP_REG1)));
1432 		FAIL_IF(push_inst(compiler, BNE | S(TMP_REG1) | TA(0) | IMM(11), UNMOVABLE_INS));
1433 	} else
1434 		FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG2) | TA(0) | IMM(11), UNMOVABLE_INS));
1435 
1436 	/* Delay slot. */
1437 	FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(0), OTHER_FLAG));
1438 
1439 	/* The TMP_REG1 is the next shift. */
1440 	FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(TMP_REG1) | IMM(max), DR(TMP_REG1)));
1441 
1442 	FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(TMP_REG2) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
1443 	FAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));
1444 
1445 	FAIL_IF(push_inst(compiler, (is_clz ? SELECT_OP(DSRLV, SRLV) : SELECT_OP(DSLLV, SLLV)) | S(TMP_REG1) | TA(EQUAL_FLAG) | D(TMP_REG2), DR(TMP_REG2)));
1446 	FAIL_IF(push_inst(compiler, BNE | S(TMP_REG2) | TA(0) | IMM(-4), UNMOVABLE_INS));
1447 	/* Delay slot. */
1448 	FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
1449 
1450 	FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(TMP_REG1) | T(TMP_REG2) | IMM(-1), DR(TMP_REG2)));
1451 	FAIL_IF(push_inst(compiler, (is_clz ? SELECT_OP(DSRLV, SRLV) : SELECT_OP(DSLLV, SLLV)) | S(TMP_REG2) | TA(EQUAL_FLAG) | D(TMP_REG2), DR(TMP_REG2)));
1452 
1453 	FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(-7), UNMOVABLE_INS));
1454 	/* Delay slot. */
1455 	FAIL_IF(push_inst(compiler, OR | SA(OTHER_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG));
1456 
1457 	return push_inst(compiler, SELECT_OP(DADDU, ADDU) | SA(OTHER_FLAG) | TA(0) | D(dst), DR(dst));
1458 }
1459 
1460 #endif /* SLJIT_MIPS_REV < 1 */
1461 
emit_single_op(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 flags,sljit_s32 dst,sljit_s32 src1,sljit_sw src2)1462 static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
1463 	sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
1464 {
1465 	sljit_s32 is_overflow, is_carry, carry_src_ar, is_handled;
1466 	sljit_ins op_imm, op_v;
1467 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1468 	sljit_ins ins, op_dimm, op_dimm32, op_dv;
1469 #endif
1470 
1471 	switch (GET_OPCODE(op)) {
1472 	case SLJIT_MOV:
1473 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1474 		if (dst != src2)
1475 			return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst));
1476 		return SLJIT_SUCCESS;
1477 
1478 	case SLJIT_MOV_U8:
1479 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1480 		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
1481 			return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
1482 		SLJIT_ASSERT(dst == src2);
1483 		return SLJIT_SUCCESS;
1484 
1485 	case SLJIT_MOV_S8:
1486 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1487 		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1488 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1489 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1490 			return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
1491 #else /* SLJIT_MIPS_REV < 1 */
1492 			FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
1493 			return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
1494 #endif /* SLJIT_MIPS_REV >= 1 */
1495 #else /* !SLJIT_CONFIG_MIPS_32 */
1496 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1497 			if (op & SLJIT_32)
1498 				return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
1499 #endif /* SLJIT_MIPS_REV >= 1 */
1500 			FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
1501 			return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst));
1502 #endif /* SLJIT_CONFIG_MIPS_32 */
1503 		}
1504 		SLJIT_ASSERT(dst == src2);
1505 		return SLJIT_SUCCESS;
1506 
1507 	case SLJIT_MOV_U16:
1508 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1509 		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
1510 			return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
1511 		SLJIT_ASSERT(dst == src2);
1512 		return SLJIT_SUCCESS;
1513 
1514 	case SLJIT_MOV_S16:
1515 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1516 		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1517 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1518 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1519 			return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
1520 #else /* SLJIT_MIPS_REV < 1 */
1521 			FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
1522 			return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
1523 #endif /* SLJIT_MIPS_REV >= 1 */
1524 #else /* !SLJIT_CONFIG_MIPS_32 */
1525 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1526 			if (op & SLJIT_32)
1527 				return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
1528 #endif /* SLJIT_MIPS_REV >= 1 */
1529 			FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
1530 			return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst));
1531 #endif /* SLJIT_CONFIG_MIPS_32 */
1532 		}
1533 		SLJIT_ASSERT(dst == src2);
1534 		return SLJIT_SUCCESS;
1535 
1536 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1537 	case SLJIT_MOV_U32:
1538 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));
1539 		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1540 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1541 			if (dst == src2)
1542 				return push_inst(compiler, DINSU | T(src2) | SA(0) | (31 << 11) | (0 << 11), DR(dst));
1543 #endif /* SLJIT_MIPS_REV >= 2 */
1544 			FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst)));
1545 			return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst));
1546 		}
1547 		SLJIT_ASSERT(dst == src2);
1548 		return SLJIT_SUCCESS;
1549 
1550 	case SLJIT_MOV_S32:
1551 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));
1552 		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1553 			return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst));
1554 		}
1555 		SLJIT_ASSERT(dst == src2);
1556 		return SLJIT_SUCCESS;
1557 #endif /* SLJIT_CONFIG_MIPS_64 */
1558 
1559 	case SLJIT_NOT:
1560 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1561 		if (op & SLJIT_SET_Z)
1562 			FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1563 		if (!(flags & UNUSED_DEST))
1564 			FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
1565 		return SLJIT_SUCCESS;
1566 
1567 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1568 	case SLJIT_CLZ:
1569 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1570 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1571 		return push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | D(dst), DR(dst));
1572 #else /* SLJIT_MIPS_REV < 6 */
1573 		return push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst));
1574 #endif /* SLJIT_MIPS_REV >= 6 */
1575 	case SLJIT_CTZ:
1576 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1577 		FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));
1578 		FAIL_IF(push_inst(compiler, AND | S(src2) | T(TMP_REG1) | D(dst), DR(dst)));
1579 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1580 		FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(dst) | D(dst), DR(dst)));
1581 #else /* SLJIT_MIPS_REV < 6 */
1582 		FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(dst) | T(dst) | D(dst), DR(dst)));
1583 #endif /* SLJIT_MIPS_REV >= 6 */
1584 		FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(TMP_REG1) | IMM(SELECT_OP(-64, -32)), DR(TMP_REG1)));
1585 		FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(SELECT_OP(26, 27)), DR(TMP_REG1)));
1586 		return push_inst(compiler, XOR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));
1587 #else /* SLJIT_MIPS_REV < 1 */
1588 	case SLJIT_CLZ:
1589 	case SLJIT_CTZ:
1590 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1591 		return emit_clz_ctz(compiler, op, dst, src2);
1592 #endif /* SLJIT_MIPS_REV >= 1 */
1593 
1594 	case SLJIT_ADD:
1595 		/* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */
1596 		is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
1597 		carry_src_ar = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
1598 
1599 		if (flags & SRC2_IMM) {
1600 			if (is_overflow) {
1601 				if (src2 >= 0)
1602 					FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1603 				else
1604 					FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1605 			}
1606 			else if (op & SLJIT_SET_Z)
1607 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
1608 
1609 			/* Only the zero flag is needed. */
1610 			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
1611 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
1612 		}
1613 		else {
1614 			if (is_overflow)
1615 				FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1616 			else if (op & SLJIT_SET_Z)
1617 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1618 
1619 			if (is_overflow || carry_src_ar != 0) {
1620 				if (src1 != dst)
1621 					carry_src_ar = DR(src1);
1622 				else if (src2 != dst)
1623 					carry_src_ar = DR(src2);
1624 				else {
1625 					FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | DA(OTHER_FLAG), OTHER_FLAG));
1626 					carry_src_ar = OTHER_FLAG;
1627 				}
1628 			}
1629 
1630 			/* Only the zero flag is needed. */
1631 			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
1632 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
1633 		}
1634 
1635 		/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
1636 		if (is_overflow || carry_src_ar != 0) {
1637 			if (flags & SRC2_IMM)
1638 				FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
1639 			else
1640 				FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(carry_src_ar) | DA(OTHER_FLAG), OTHER_FLAG));
1641 		}
1642 
1643 		if (!is_overflow)
1644 			return SLJIT_SUCCESS;
1645 
1646 		FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1647 		if (op & SLJIT_SET_Z)
1648 			FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
1649 		FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
1650 		return push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
1651 
1652 	case SLJIT_ADDC:
1653 		carry_src_ar = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
1654 
1655 		if (flags & SRC2_IMM) {
1656 			FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
1657 		} else {
1658 			if (carry_src_ar != 0) {
1659 				if (src1 != dst)
1660 					carry_src_ar = DR(src1);
1661 				else if (src2 != dst)
1662 					carry_src_ar = DR(src2);
1663 				else {
1664 					FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
1665 					carry_src_ar = EQUAL_FLAG;
1666 				}
1667 			}
1668 
1669 			FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
1670 		}
1671 
1672 		/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
1673 		if (carry_src_ar != 0) {
1674 			if (flags & SRC2_IMM)
1675 				FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
1676 			else
1677 				FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(carry_src_ar) | DA(EQUAL_FLAG), EQUAL_FLAG));
1678 		}
1679 
1680 		FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1681 
1682 		if (carry_src_ar == 0)
1683 			return SLJIT_SUCCESS;
1684 
1685 		/* Set ULESS_FLAG (dst == 0) && (OTHER_FLAG == 1). */
1686 		FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
1687 		/* Set carry flag. */
1688 		return push_inst(compiler, OR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
1689 
1690 	case SLJIT_SUB:
1691 		if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
1692 			FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
1693 			src2 = TMP_REG2;
1694 			flags &= ~SRC2_IMM;
1695 		}
1696 
1697 		is_handled = 0;
1698 
1699 		if (flags & SRC2_IMM) {
1700 			if (GET_FLAG_TYPE(op) == SLJIT_LESS || GET_FLAG_TYPE(op) == SLJIT_GREATER_EQUAL) {
1701 				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
1702 				is_handled = 1;
1703 			}
1704 			else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS || GET_FLAG_TYPE(op) == SLJIT_SIG_GREATER_EQUAL) {
1705 				FAIL_IF(push_inst(compiler, SLTI | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
1706 				is_handled = 1;
1707 			}
1708 		}
1709 
1710 		if (!is_handled && GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {
1711 			is_handled = 1;
1712 
1713 			if (flags & SRC2_IMM) {
1714 				FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
1715 				src2 = TMP_REG2;
1716 				flags &= ~SRC2_IMM;
1717 			}
1718 
1719 			switch (GET_FLAG_TYPE(op)) {
1720 			case SLJIT_LESS:
1721 			case SLJIT_GREATER_EQUAL:
1722 				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
1723 				break;
1724 			case SLJIT_GREATER:
1725 			case SLJIT_LESS_EQUAL:
1726 				FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
1727 				break;
1728 			case SLJIT_SIG_LESS:
1729 			case SLJIT_SIG_GREATER_EQUAL:
1730 				FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
1731 				break;
1732 			case SLJIT_SIG_GREATER:
1733 			case SLJIT_SIG_LESS_EQUAL:
1734 				FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
1735 				break;
1736 			}
1737 		}
1738 
1739 		if (is_handled) {
1740 			if (flags & SRC2_IMM) {
1741 				if (op & SLJIT_SET_Z)
1742 					FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
1743 				if (!(flags & UNUSED_DEST))
1744 					return push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst));
1745 			}
1746 			else {
1747 				if (op & SLJIT_SET_Z)
1748 					FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1749 				if (!(flags & UNUSED_DEST))
1750 					return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst));
1751 			}
1752 			return SLJIT_SUCCESS;
1753 		}
1754 
1755 		is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
1756 		is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
1757 
1758 		if (flags & SRC2_IMM) {
1759 			if (is_overflow) {
1760 				if (src2 >= 0)
1761 					FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1762 				else
1763 					FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1764 			}
1765 			else if (op & SLJIT_SET_Z)
1766 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
1767 
1768 			if (is_overflow || is_carry)
1769 				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
1770 
1771 			/* Only the zero flag is needed. */
1772 			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
1773 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
1774 		}
1775 		else {
1776 			if (is_overflow)
1777 				FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1778 			else if (op & SLJIT_SET_Z)
1779 				FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1780 
1781 			if (is_overflow || is_carry)
1782 				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
1783 
1784 			/* Only the zero flag is needed. */
1785 			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
1786 				FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
1787 		}
1788 
1789 		if (!is_overflow)
1790 			return SLJIT_SUCCESS;
1791 
1792 		FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1793 		if (op & SLJIT_SET_Z)
1794 			FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
1795 		FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
1796 		return push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
1797 
1798 	case SLJIT_SUBC:
1799 		if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
1800 			FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
1801 			src2 = TMP_REG2;
1802 			flags &= ~SRC2_IMM;
1803 		}
1804 
1805 		is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
1806 
1807 		if (flags & SRC2_IMM) {
1808 			if (is_carry)
1809 				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
1810 
1811 			FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
1812 		}
1813 		else {
1814 			if (is_carry)
1815 				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1816 
1817 			FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
1818 		}
1819 
1820 		if (is_carry)
1821 			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1822 
1823 		FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1824 
1825 		if (!is_carry)
1826 			return SLJIT_SUCCESS;
1827 
1828 		return push_inst(compiler, OR | SA(EQUAL_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG);
1829 
1830 	case SLJIT_MUL:
1831 		SLJIT_ASSERT(!(flags & SRC2_IMM));
1832 
1833 		if (GET_FLAG_TYPE(op) != SLJIT_OVERFLOW) {
1834 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1835 			return push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst));
1836 #elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1837 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1838 			return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
1839 #else /* !SLJIT_CONFIG_MIPS_32 */
1840 			if (op & SLJIT_32)
1841 				return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
1842 			FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
1843 			return push_inst(compiler, MFLO | D(dst), DR(dst));
1844 #endif /* SLJIT_CONFIG_MIPS_32 */
1845 #else /* SLJIT_MIPS_REV < 1 */
1846 			FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
1847 			return push_inst(compiler, MFLO | D(dst), DR(dst));
1848 #endif /* SLJIT_MIPS_REV >= 6 */
1849 		}
1850 
1851 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1852 		FAIL_IF(push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst)));
1853 		FAIL_IF(push_inst(compiler, SELECT_OP(DMUH, MUH) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1854 #else /* SLJIT_MIPS_REV < 6 */
1855 		FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
1856 		FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
1857 		FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
1858 #endif /* SLJIT_MIPS_REV >= 6 */
1859 		FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
1860 		return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
1861 
1862 	case SLJIT_AND:
1863 		EMIT_LOGICAL(ANDI, AND);
1864 		return SLJIT_SUCCESS;
1865 
1866 	case SLJIT_OR:
1867 		EMIT_LOGICAL(ORI, OR);
1868 		return SLJIT_SUCCESS;
1869 
1870 	case SLJIT_XOR:
1871 		EMIT_LOGICAL(XORI, XOR);
1872 		return SLJIT_SUCCESS;
1873 
1874 	case SLJIT_SHL:
1875 	case SLJIT_MSHL:
1876 		EMIT_SHIFT(DSLL, DSLL32, SLL, DSLLV, SLLV);
1877 		break;
1878 
1879 	case SLJIT_LSHR:
1880 	case SLJIT_MLSHR:
1881 		EMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV);
1882 		break;
1883 
1884 	case SLJIT_ASHR:
1885 	case SLJIT_MASHR:
1886 		EMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV);
1887 		break;
1888 
1889 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1890 	case SLJIT_ROTL:
1891 		if ((flags & SRC2_IMM) || src2 == 0) {
1892 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1893 			src2 = -src2 & 0x1f;
1894 #else /* !SLJIT_CONFIG_MIPS_32 */
1895 			src2 = -src2 & ((op & SLJIT_32) ? 0x1f : 0x3f);
1896 #endif /* SLJIT_CONFIG_MIPS_32 */
1897 		} else {
1898 			FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG2), DR(TMP_REG2)));
1899 			src2 = TMP_REG2;
1900 		}
1901 		/* fallthrough */
1902 
1903 	case SLJIT_ROTR:
1904 		EMIT_SHIFT(DROTR, DROTR32, ROTR, DROTRV, ROTRV);
1905 		break;
1906 #else /* SLJIT_MIPS_REV < 1 */
1907 	case SLJIT_ROTL:
1908 	case SLJIT_ROTR:
1909 		if (flags & SRC2_IMM) {
1910 			SLJIT_ASSERT(src2 != 0);
1911 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1912 			if (!(op & SLJIT_32)) {
1913 				if (GET_OPCODE(op) == SLJIT_ROTL)
1914 					op_imm = ((src2 < 32) ? DSLL : DSLL32);
1915 				else
1916 					op_imm = ((src2 < 32) ? DSRL : DSRL32);
1917 
1918 				FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(OTHER_FLAG) | (((sljit_ins)src2 & 0x1f) << 6), OTHER_FLAG));
1919 
1920 				src2 = 64 - src2;
1921 				if (GET_OPCODE(op) == SLJIT_ROTL)
1922 					op_imm = ((src2 < 32) ? DSRL : DSRL32);
1923 				else
1924 					op_imm = ((src2 < 32) ? DSLL : DSLL32);
1925 
1926 				FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | (((sljit_ins)src2 & 0x1f) << 6), DR(dst)));
1927 				return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
1928 			}
1929 #endif /* SLJIT_CONFIG_MIPS_64 */
1930 
1931 			op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SLL : SRL;
1932 			FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(OTHER_FLAG) | ((sljit_ins)src2 << 6), OTHER_FLAG));
1933 
1934 			src2 = 32 - src2;
1935 			op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SRL : SLL;
1936 			FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | (((sljit_ins)src2 & 0x1f) << 6), DR(dst)));
1937 			return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
1938 		}
1939 
1940 		if (src2 == 0) {
1941 			if (dst != src1)
1942 				return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | D(dst), DR(dst));
1943 			return SLJIT_SUCCESS;
1944 		}
1945 
1946 		FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1947 
1948 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1949 		if (!(op & SLJIT_32)) {
1950 			op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? DSLLV : DSRLV;
1951 			FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
1952 			op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? DSRLV : DSLLV;
1953 			FAIL_IF(push_inst(compiler, op_v | SA(EQUAL_FLAG) | T(src1) | D(dst), DR(dst)));
1954 			return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
1955 		}
1956 #endif /* SLJIT_CONFIG_MIPS_64 */
1957 
1958 		op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? SLLV : SRLV;
1959 		FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
1960 		op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? SRLV : SLLV;
1961 		FAIL_IF(push_inst(compiler, op_v | SA(EQUAL_FLAG) | T(src1) | D(dst), DR(dst)));
1962 		return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
1963 #endif /* SLJIT_MIPS_REV >= 2 */
1964 
1965 	default:
1966 		SLJIT_UNREACHABLE();
1967 		return SLJIT_SUCCESS;
1968 	}
1969 
1970 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1971 	if ((flags & SRC2_IMM) || src2 == 0) {
1972 		if (op & SLJIT_SET_Z)
1973 			FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG));
1974 
1975 		if (flags & UNUSED_DEST)
1976 			return SLJIT_SUCCESS;
1977 		return push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst));
1978 	}
1979 
1980 	if (op & SLJIT_SET_Z)
1981 		FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1982 
1983 	if (flags & UNUSED_DEST)
1984 		return SLJIT_SUCCESS;
1985 	return push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst));
1986 #else /* !SLJIT_CONFIG_MIPS_32 */
1987 	if ((flags & SRC2_IMM) || src2 == 0) {
1988 		if (src2 >= 32) {
1989 			SLJIT_ASSERT(!(op & SLJIT_32));
1990 			ins = op_dimm32;
1991 			src2 -= 32;
1992 		}
1993 		else
1994 			ins = (op & SLJIT_32) ? op_imm : op_dimm;
1995 
1996 		if (op & SLJIT_SET_Z)
1997 			FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG));
1998 
1999 		if (flags & UNUSED_DEST)
2000 			return SLJIT_SUCCESS;
2001 		return push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst));
2002 	}
2003 
2004 	ins = (op & SLJIT_32) ? op_v : op_dv;
2005 	if (op & SLJIT_SET_Z)
2006 		FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
2007 
2008 	if (flags & UNUSED_DEST)
2009 		return SLJIT_SUCCESS;
2010 	return push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst));
2011 #endif /* SLJIT_CONFIG_MIPS_32 */
2012 }
2013 
2014 #define CHECK_IMM(flags, srcw) \
2015 	((!((flags) & LOGICAL_OP) && ((srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)) \
2016 		|| (((flags) & LOGICAL_OP) && !((srcw) & ~UIMM_MAX)))
2017 
emit_op(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 flags,sljit_s32 dst,sljit_sw dstw,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2018 static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
2019 	sljit_s32 dst, sljit_sw dstw,
2020 	sljit_s32 src1, sljit_sw src1w,
2021 	sljit_s32 src2, sljit_sw src2w)
2022 {
2023 	/* arg1 goes to TMP_REG1 or src reg
2024 	   arg2 goes to TMP_REG2, imm or src reg
2025 	   TMP_REG3 can be used for caching
2026 	   result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
2027 	sljit_s32 dst_r = TMP_REG2;
2028 	sljit_s32 src1_r;
2029 	sljit_sw src2_r = 0;
2030 	sljit_s32 sugg_src2_r = TMP_REG2;
2031 
2032 	if (!(flags & ALT_KEEP_CACHE)) {
2033 		compiler->cache_arg = 0;
2034 		compiler->cache_argw = 0;
2035 	}
2036 
2037 	if (dst == TMP_REG2) {
2038 		SLJIT_ASSERT(HAS_FLAGS(op));
2039 		flags |= UNUSED_DEST;
2040 	}
2041 	else if (FAST_IS_REG(dst)) {
2042 		dst_r = dst;
2043 		flags |= REG_DEST;
2044 		if (flags & MOVE_OP)
2045 			sugg_src2_r = dst_r;
2046 	}
2047 	else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))
2048 		flags |= SLOW_DEST;
2049 
2050 	if (flags & IMM_OP) {
2051 		if ((src2 & SLJIT_IMM) && src2w != 0 && CHECK_IMM(flags, src2w)) {
2052 			flags |= SRC2_IMM;
2053 			src2_r = src2w;
2054 		} else if ((flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w != 0 && CHECK_IMM(flags, src1w)) {
2055 			flags |= SRC2_IMM;
2056 			src2_r = src1w;
2057 
2058 			/* And swap arguments. */
2059 			src1 = src2;
2060 			src1w = src2w;
2061 			src2 = SLJIT_IMM;
2062 			/* src2w = src2_r unneeded. */
2063 		}
2064 	}
2065 
2066 	/* Source 1. */
2067 	if (FAST_IS_REG(src1)) {
2068 		src1_r = src1;
2069 		flags |= REG1_SOURCE;
2070 	}
2071 	else if (src1 & SLJIT_IMM) {
2072 		if (src1w) {
2073 			FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
2074 			src1_r = TMP_REG1;
2075 		}
2076 		else
2077 			src1_r = 0;
2078 	}
2079 	else {
2080 		if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w))
2081 			FAIL_IF(compiler->error);
2082 		else
2083 			flags |= SLOW_SRC1;
2084 		src1_r = TMP_REG1;
2085 	}
2086 
2087 	/* Source 2. */
2088 	if (FAST_IS_REG(src2)) {
2089 		src2_r = src2;
2090 		flags |= REG2_SOURCE;
2091 		if ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP)
2092 			dst_r = (sljit_s32)src2_r;
2093 	}
2094 	else if (src2 & SLJIT_IMM) {
2095 		if (!(flags & SRC2_IMM)) {
2096 			if (src2w) {
2097 				FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w));
2098 				src2_r = sugg_src2_r;
2099 			}
2100 			else {
2101 				src2_r = 0;
2102 				if (flags & MOVE_OP) {
2103 					if (dst & SLJIT_MEM)
2104 						dst_r = 0;
2105 					else
2106 						op = SLJIT_MOV;
2107 				}
2108 			}
2109 		}
2110 	}
2111 	else {
2112 		if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w))
2113 			FAIL_IF(compiler->error);
2114 		else
2115 			flags |= SLOW_SRC2;
2116 		src2_r = sugg_src2_r;
2117 	}
2118 
2119 	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
2120 		SLJIT_ASSERT(src2_r == TMP_REG2);
2121 		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
2122 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));
2123 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
2124 		}
2125 		else {
2126 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w));
2127 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw));
2128 		}
2129 	}
2130 	else if (flags & SLOW_SRC1)
2131 		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
2132 	else if (flags & SLOW_SRC2)
2133 		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w, dst, dstw));
2134 
2135 	FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
2136 
2137 	if (dst & SLJIT_MEM) {
2138 		if (!(flags & SLOW_DEST)) {
2139 			getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw);
2140 			return compiler->error;
2141 		}
2142 		return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0);
2143 	}
2144 
2145 	return SLJIT_SUCCESS;
2146 }
2147 
2148 #undef CHECK_IMM
2149 
sljit_emit_op0(struct sljit_compiler * compiler,sljit_s32 op)2150 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
2151 {
2152 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2153 	sljit_s32 int_op = op & SLJIT_32;
2154 #endif
2155 
2156 	CHECK_ERROR();
2157 	CHECK(check_sljit_emit_op0(compiler, op));
2158 
2159 	op = GET_OPCODE(op);
2160 	switch (op) {
2161 	case SLJIT_BREAKPOINT:
2162 		return push_inst(compiler, BREAK, UNMOVABLE_INS);
2163 	case SLJIT_NOP:
2164 		return push_inst(compiler, NOP, UNMOVABLE_INS);
2165 	case SLJIT_LMUL_UW:
2166 	case SLJIT_LMUL_SW:
2167 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2168 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2169 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULU : DMUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2170 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMUHU : DMUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2171 #else /* !SLJIT_CONFIG_MIPS_64 */
2172 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULU : MUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2173 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MUHU : MUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2174 #endif /* SLJIT_CONFIG_MIPS_64 */
2175 		FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
2176 		return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
2177 #else /* SLJIT_MIPS_REV < 6 */
2178 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2179 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2180 #else /* !SLJIT_CONFIG_MIPS_64 */
2181 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2182 #endif /* SLJIT_CONFIG_MIPS_64 */
2183 		FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
2184 		return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
2185 #endif /* SLJIT_MIPS_REV >= 6 */
2186 	case SLJIT_DIVMOD_UW:
2187 	case SLJIT_DIVMOD_SW:
2188 	case SLJIT_DIV_UW:
2189 	case SLJIT_DIV_SW:
2190 		SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
2191 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2192 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2193 		if (int_op) {
2194 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2195 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2196 		}
2197 		else {
2198 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2199 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DMODU : DMOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2200 		}
2201 #else /* !SLJIT_CONFIG_MIPS_64 */
2202 		FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2203 		FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2204 #endif /* SLJIT_CONFIG_MIPS_64 */
2205 		FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
2206 		return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
2207 #else /* SLJIT_MIPS_REV < 6 */
2208 #if !(defined SLJIT_MIPS_REV)
2209 		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2210 		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2211 #endif /* !SLJIT_MIPS_REV */
2212 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2213 		if (int_op)
2214 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2215 		else
2216 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2217 #else /* !SLJIT_CONFIG_MIPS_64 */
2218 		FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2219 #endif /* SLJIT_CONFIG_MIPS_64 */
2220 		FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
2221 		return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
2222 #endif /* SLJIT_MIPS_REV >= 6 */
2223 	case SLJIT_ENDBR:
2224 	case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
2225 		return SLJIT_SUCCESS;
2226 	}
2227 
2228 	return SLJIT_SUCCESS;
2229 }
2230 
2231 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
emit_prefetch(struct sljit_compiler * compiler,sljit_s32 src,sljit_sw srcw)2232 static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
2233         sljit_s32 src, sljit_sw srcw)
2234 {
2235 	if (!(src & OFFS_REG_MASK)) {
2236 		if (srcw <= SIMM_MAX && srcw >= SIMM_MIN)
2237 			return push_inst(compiler, PREF | S(src & REG_MASK) | IMM(srcw), MOVABLE_INS);
2238 
2239 		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
2240 		return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
2241 	}
2242 
2243 	srcw &= 0x3;
2244 
2245 	if (SLJIT_UNLIKELY(srcw != 0)) {
2246 		FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(src)) | D(TMP_REG1) | SH_IMM(srcw), DR(TMP_REG1)));
2247 		return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
2248 	}
2249 
2250 	return push_inst(compiler, PREFX | S(src & REG_MASK) | T(OFFS_REG(src)), MOVABLE_INS);
2251 }
2252 #endif /* SLJIT_MIPS_REV >= 1 */
2253 
sljit_emit_op1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)2254 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
2255 	sljit_s32 dst, sljit_sw dstw,
2256 	sljit_s32 src, sljit_sw srcw)
2257 {
2258 	sljit_s32 flags = 0;
2259 
2260 	CHECK_ERROR();
2261 	CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
2262 	ADJUST_LOCAL_OFFSET(dst, dstw);
2263 	ADJUST_LOCAL_OFFSET(src, srcw);
2264 
2265 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2266 	if (op & SLJIT_32)
2267 		flags = INT_DATA | SIGNED_DATA;
2268 #endif
2269 
2270 	switch (GET_OPCODE(op)) {
2271 	case SLJIT_MOV:
2272 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2273 	case SLJIT_MOV_U32:
2274 	case SLJIT_MOV_S32:
2275 	case SLJIT_MOV32:
2276 #endif
2277 	case SLJIT_MOV_P:
2278 		return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, srcw);
2279 
2280 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2281 	case SLJIT_MOV_U32:
2282 		return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw);
2283 
2284 	case SLJIT_MOV_S32:
2285 	case SLJIT_MOV32:
2286 		return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw);
2287 #endif
2288 
2289 	case SLJIT_MOV_U8:
2290 		return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
2291 
2292 	case SLJIT_MOV_S8:
2293 		return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
2294 
2295 	case SLJIT_MOV_U16:
2296 		return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
2297 
2298 	case SLJIT_MOV_S16:
2299 		return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
2300 
2301 	case SLJIT_NOT:
2302 		return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
2303 
2304 	case SLJIT_CLZ:
2305 	case SLJIT_CTZ:
2306 		return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
2307 	}
2308 
2309 	SLJIT_UNREACHABLE();
2310 	return SLJIT_SUCCESS;
2311 }
2312 
sljit_emit_op2(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2313 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
2314 	sljit_s32 dst, sljit_sw dstw,
2315 	sljit_s32 src1, sljit_sw src1w,
2316 	sljit_s32 src2, sljit_sw src2w)
2317 {
2318 	sljit_s32 flags = 0;
2319 
2320 	CHECK_ERROR();
2321 	CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
2322 	ADJUST_LOCAL_OFFSET(dst, dstw);
2323 	ADJUST_LOCAL_OFFSET(src1, src1w);
2324 	ADJUST_LOCAL_OFFSET(src2, src2w);
2325 
2326 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2327 	if (op & SLJIT_32) {
2328 		flags |= INT_DATA | SIGNED_DATA;
2329 		if (src1 & SLJIT_IMM)
2330 			src1w = (sljit_s32)src1w;
2331 		if (src2 & SLJIT_IMM)
2332 			src2w = (sljit_s32)src2w;
2333 	}
2334 #endif
2335 
2336 	switch (GET_OPCODE(op)) {
2337 	case SLJIT_ADD:
2338 	case SLJIT_ADDC:
2339 		compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
2340 		return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2341 
2342 	case SLJIT_SUB:
2343 	case SLJIT_SUBC:
2344 		compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
2345 		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2346 
2347 	case SLJIT_MUL:
2348 		compiler->status_flags_state = 0;
2349 		return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
2350 
2351 	case SLJIT_AND:
2352 	case SLJIT_OR:
2353 	case SLJIT_XOR:
2354 		return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2355 
2356 	case SLJIT_SHL:
2357 	case SLJIT_MSHL:
2358 	case SLJIT_LSHR:
2359 	case SLJIT_MLSHR:
2360 	case SLJIT_ASHR:
2361 	case SLJIT_MASHR:
2362 	case SLJIT_ROTL:
2363 	case SLJIT_ROTR:
2364 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2365 		if (src2 & SLJIT_IMM)
2366 			src2w &= 0x1f;
2367 #else
2368 		if (src2 & SLJIT_IMM) {
2369 			if (op & SLJIT_32)
2370 				src2w &= 0x1f;
2371 			else
2372 				src2w &= 0x3f;
2373 		}
2374 #endif
2375 		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2376 	}
2377 
2378 	SLJIT_UNREACHABLE();
2379 	return SLJIT_SUCCESS;
2380 }
2381 
sljit_emit_op2u(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2382 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
2383 	sljit_s32 src1, sljit_sw src1w,
2384 	sljit_s32 src2, sljit_sw src2w)
2385 {
2386 	CHECK_ERROR();
2387 	CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
2388 
2389 	SLJIT_SKIP_CHECKS(compiler);
2390 	return sljit_emit_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w);
2391 }
2392 
2393 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2394 #define SELECT_OP3(op, src2w, D, D32, W) (((op & SLJIT_32) ? (W) : ((src2w) < 32) ? (D) : (D32)) | (((sljit_ins)src2w & 0x1f) << 6))
2395 #define SELECT_OP2(op, D, W) ((op & SLJIT_32) ? (W) : (D))
2396 #else /* !SLJIT_CONFIG_MIPS_64 */
2397 #define SELECT_OP3(op, src2w, D, D32, W) ((W) | ((sljit_ins)(src2w) << 6))
2398 #define SELECT_OP2(op, D, W) (W)
2399 #endif /* SLJIT_CONFIG_MIPS_64 */
2400 
sljit_emit_shift_into(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src_dst,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2401 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
2402 	sljit_s32 src_dst,
2403 	sljit_s32 src1, sljit_sw src1w,
2404 	sljit_s32 src2, sljit_sw src2w)
2405 {
2406 	sljit_s32 is_left;
2407 	sljit_ins ins1, ins2, ins3;
2408 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2409 	sljit_s32 inp_flags = ((op & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
2410 	sljit_sw bit_length = (op & SLJIT_32) ? 32 : 64;
2411 #else /* !SLJIT_CONFIG_MIPS_64 */
2412 	sljit_s32 inp_flags = WORD_DATA | LOAD_DATA;
2413 	sljit_sw bit_length = 32;
2414 #endif /* SLJIT_CONFIG_MIPS_64 */
2415 
2416 	CHECK_ERROR();
2417 	CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w));
2418 
2419 	is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL);
2420 
2421 	if (src_dst == src1) {
2422 		SLJIT_SKIP_CHECKS(compiler);
2423 		return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w);
2424 	}
2425 
2426 	ADJUST_LOCAL_OFFSET(src1, src1w);
2427 	ADJUST_LOCAL_OFFSET(src2, src2w);
2428 
2429 	if (src2 & SLJIT_IMM) {
2430 		src2w &= bit_length - 1;
2431 
2432 		if (src2w == 0)
2433 			return SLJIT_SUCCESS;
2434 	} else if (src2 & SLJIT_MEM) {
2435 		FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG2), src2, src2w));
2436 		src2 = TMP_REG2;
2437 	}
2438 
2439 	if (src1 & SLJIT_MEM) {
2440 		FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG1), src1, src1w));
2441 		src1 = TMP_REG1;
2442 	} else if (src1 & SLJIT_IMM) {
2443 		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
2444 		src1 = TMP_REG1;
2445 	}
2446 
2447 	if (src2 & SLJIT_IMM) {
2448 		if (is_left) {
2449 			ins1 = SELECT_OP3(op, src2w, DSLL, DSLL32, SLL);
2450 			src2w = bit_length - src2w;
2451 			ins2 = SELECT_OP3(op, src2w, DSRL, DSRL32, SRL);
2452 		} else {
2453 			ins1 = SELECT_OP3(op, src2w, DSRL, DSRL32, SRL);
2454 			src2w = bit_length - src2w;
2455 			ins2 = SELECT_OP3(op, src2w, DSLL, DSLL32, SLL);
2456 		}
2457 
2458 		FAIL_IF(push_inst(compiler, ins1 | T(src_dst) | D(src_dst), DR(src_dst)));
2459 		FAIL_IF(push_inst(compiler, ins2 | T(src1) | D(TMP_REG1), DR(TMP_REG1)));
2460 		return push_inst(compiler, OR | S(src_dst) | T(TMP_REG1) | D(src_dst), DR(src_dst));
2461 	}
2462 
2463 	if (is_left) {
2464 		ins1 = SELECT_OP2(op, DSRL, SRL);
2465 		ins2 = SELECT_OP2(op, DSLLV, SLLV);
2466 		ins3 = SELECT_OP2(op, DSRLV, SRLV);
2467 	} else {
2468 		ins1 = SELECT_OP2(op, DSLL, SLL);
2469 		ins2 = SELECT_OP2(op, DSRLV, SRLV);
2470 		ins3 = SELECT_OP2(op, DSLLV, SLLV);
2471 	}
2472 
2473 	FAIL_IF(push_inst(compiler, ins2 | S(src2) | T(src_dst) | D(src_dst), DR(src_dst)));
2474 
2475 	if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) {
2476 		FAIL_IF(push_inst(compiler, ins1 | T(src1) | D(TMP_REG1) | (1 << 6), DR(TMP_REG1)));
2477 		FAIL_IF(push_inst(compiler, XORI | S(src2) | T(TMP_REG2) | ((sljit_ins)bit_length - 1), DR(TMP_REG2)));
2478 		src1 = TMP_REG1;
2479 	} else
2480 		FAIL_IF(push_inst(compiler, SELECT_OP2(op, DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG2), DR(TMP_REG2)));
2481 
2482 	FAIL_IF(push_inst(compiler, ins3 | S(TMP_REG2) | T(src1) | D(TMP_REG1), DR(TMP_REG1)));
2483 	return push_inst(compiler, OR | S(src_dst) | T(TMP_REG1) | D(src_dst), DR(src_dst));
2484 }
2485 
2486 #undef SELECT_OP3
2487 #undef SELECT_OP2
2488 
sljit_emit_op_src(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)2489 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
2490 	sljit_s32 src, sljit_sw srcw)
2491 {
2492 	CHECK_ERROR();
2493 	CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
2494 	ADJUST_LOCAL_OFFSET(src, srcw);
2495 
2496 	switch (op) {
2497 	case SLJIT_FAST_RETURN:
2498 		if (FAST_IS_REG(src))
2499 			FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
2500 		else
2501 			FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
2502 
2503 		FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
2504 		return push_inst(compiler, NOP, UNMOVABLE_INS);
2505 	case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
2506 		return SLJIT_SUCCESS;
2507 	case SLJIT_PREFETCH_L1:
2508 	case SLJIT_PREFETCH_L2:
2509 	case SLJIT_PREFETCH_L3:
2510 	case SLJIT_PREFETCH_ONCE:
2511 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
2512 		return emit_prefetch(compiler, src, srcw);
2513 #else /* SLJIT_MIPS_REV < 1 */
2514 		return SLJIT_SUCCESS;
2515 #endif /* SLJIT_MIPS_REV >= 1 */
2516 	}
2517 
2518 	return SLJIT_SUCCESS;
2519 }
2520 
sljit_get_register_index(sljit_s32 reg)2521 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
2522 {
2523 	CHECK_REG_INDEX(check_sljit_get_register_index(reg));
2524 	return reg_map[reg];
2525 }
2526 
sljit_get_float_register_index(sljit_s32 reg)2527 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
2528 {
2529 	CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
2530 	return FR(reg);
2531 }
2532 
sljit_emit_op_custom(struct sljit_compiler * compiler,void * instruction,sljit_u32 size)2533 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
2534 	void *instruction, sljit_u32 size)
2535 {
2536 	CHECK_ERROR();
2537 	CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
2538 
2539 	return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
2540 }
2541 
2542 /* --------------------------------------------------------------------- */
2543 /*  Floating point operators                                             */
2544 /* --------------------------------------------------------------------- */
2545 
2546 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7))
2547 #define FMT(op) ((((sljit_ins)op & SLJIT_32) ^ SLJIT_32) << (21 - 8))
2548 
sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)2549 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
2550 	sljit_s32 dst, sljit_sw dstw,
2551 	sljit_s32 src, sljit_sw srcw)
2552 {
2553 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2554 #	define flags (sljit_u32)0
2555 #else
2556 	sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)) << 21;
2557 #endif
2558 
2559 	if (src & SLJIT_MEM) {
2560 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
2561 		src = TMP_FREG1;
2562 	}
2563 
2564 	FAIL_IF(push_inst(compiler, (TRUNC_W_S ^ (flags >> 19)) | FMT(op) | FS(src) | FD(TMP_FREG1), MOVABLE_INS));
2565 
2566 	if (FAST_IS_REG(dst)) {
2567 		FAIL_IF(push_inst(compiler, MFC1 | flags | T(dst) | FS(TMP_FREG1), MOVABLE_INS));
2568 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
2569 		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2570 #endif
2571 		return SLJIT_SUCCESS;
2572 	}
2573 
2574 	/* Store the integer value from a VFP register. */
2575 	return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, FR(TMP_FREG1), dst, dstw, 0, 0);
2576 
2577 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2578 #	undef flags
2579 #endif
2580 }
2581 
sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)2582 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
2583 	sljit_s32 dst, sljit_sw dstw,
2584 	sljit_s32 src, sljit_sw srcw)
2585 {
2586 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2587 #	define flags (sljit_u32)0
2588 #else
2589 	sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)) << 21;
2590 #endif
2591 
2592 	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
2593 
2594 	if (FAST_IS_REG(src)) {
2595 		FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS));
2596 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
2597 		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2598 #endif
2599 	} else if (src & SLJIT_MEM) {
2600 		/* Load the integer value into a VFP register. */
2601 		FAIL_IF(emit_op_mem2(compiler, (flags ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
2602 	}
2603 	else {
2604 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2605 		if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
2606 			srcw = (sljit_s32)srcw;
2607 #endif
2608 		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
2609 		FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS));
2610 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
2611 		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2612 #endif
2613 	}
2614 
2615 	FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((((sljit_ins)op & SLJIT_32) ^ SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
2616 
2617 	if (dst & SLJIT_MEM)
2618 		return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
2619 	return SLJIT_SUCCESS;
2620 
2621 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2622 #	undef flags
2623 #endif
2624 }
2625 
sljit_emit_fop1_cmp(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2626 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
2627 	sljit_s32 src1, sljit_sw src1w,
2628 	sljit_s32 src2, sljit_sw src2w)
2629 {
2630 	sljit_ins inst;
2631 
2632 	if (src1 & SLJIT_MEM) {
2633 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
2634 		src1 = TMP_FREG1;
2635 	}
2636 
2637 	if (src2 & SLJIT_MEM) {
2638 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, 0, 0));
2639 		src2 = TMP_FREG2;
2640 	}
2641 
2642 	switch (GET_FLAG_TYPE(op)) {
2643 	case SLJIT_F_EQUAL:
2644 	case SLJIT_ORDERED_EQUAL:
2645 	case SLJIT_UNORDERED_OR_NOT_EQUAL:
2646 		inst = C_EQ_S;
2647 		break;
2648 	case SLJIT_F_NOT_EQUAL:
2649 	case SLJIT_UNORDERED_OR_EQUAL:
2650 	case SLJIT_ORDERED_NOT_EQUAL:
2651 		inst = C_UEQ_S;
2652 		break;
2653 	case SLJIT_F_LESS:
2654 	case SLJIT_ORDERED_LESS:
2655 	case SLJIT_UNORDERED_OR_GREATER_EQUAL:
2656 		inst = C_OLT_S;
2657 		break;
2658 	case SLJIT_F_GREATER_EQUAL:
2659 	case SLJIT_UNORDERED_OR_LESS:
2660 	case SLJIT_ORDERED_GREATER_EQUAL:
2661 		inst = C_ULT_S;
2662 		break;
2663 	case SLJIT_F_GREATER:
2664 	case SLJIT_ORDERED_GREATER:
2665 	case SLJIT_UNORDERED_OR_LESS_EQUAL:
2666 		inst = C_ULE_S;
2667 		break;
2668 	case SLJIT_F_LESS_EQUAL:
2669 	case SLJIT_UNORDERED_OR_GREATER:
2670 	case SLJIT_ORDERED_LESS_EQUAL:
2671 		inst = C_OLE_S;
2672 		break;
2673 	default:
2674 		SLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_UNORDERED || GET_FLAG_TYPE(op) == SLJIT_ORDERED);
2675 		inst = C_UN_S;
2676 		break;
2677 	}
2678 	return push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1) | C_FD, UNMOVABLE_INS);
2679 }
2680 
sljit_emit_fop1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)2681 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
2682 	sljit_s32 dst, sljit_sw dstw,
2683 	sljit_s32 src, sljit_sw srcw)
2684 {
2685 	sljit_s32 dst_r;
2686 
2687 	CHECK_ERROR();
2688 	compiler->cache_arg = 0;
2689 	compiler->cache_argw = 0;
2690 
2691 	SLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
2692 	SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
2693 
2694 	if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
2695 		op ^= SLJIT_32;
2696 
2697 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
2698 
2699 	if (src & SLJIT_MEM) {
2700 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(dst_r), src, srcw, dst, dstw));
2701 		src = dst_r;
2702 	}
2703 
2704 	switch (GET_OPCODE(op)) {
2705 	case SLJIT_MOV_F64:
2706 		if (src != dst_r) {
2707 			if (dst_r != TMP_FREG1)
2708 				FAIL_IF(push_inst(compiler, MOV_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
2709 			else
2710 				dst_r = src;
2711 		}
2712 		break;
2713 	case SLJIT_NEG_F64:
2714 		FAIL_IF(push_inst(compiler, NEG_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
2715 		break;
2716 	case SLJIT_ABS_F64:
2717 		FAIL_IF(push_inst(compiler, ABS_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
2718 		break;
2719 	case SLJIT_CONV_F64_FROM_F32:
2720 		/* The SLJIT_32 bit is inverted because sljit_f32 needs to be loaded from the memory. */
2721 		FAIL_IF(push_inst(compiler, CVT_S_S | (sljit_ins)((op & SLJIT_32) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS));
2722 		op ^= SLJIT_32;
2723 		break;
2724 	}
2725 
2726 	if (dst & SLJIT_MEM)
2727 		return emit_op_mem2(compiler, FLOAT_DATA(op), FR(dst_r), dst, dstw, 0, 0);
2728 	return SLJIT_SUCCESS;
2729 }
2730 
sljit_emit_fop2(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2731 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
2732 	sljit_s32 dst, sljit_sw dstw,
2733 	sljit_s32 src1, sljit_sw src1w,
2734 	sljit_s32 src2, sljit_sw src2w)
2735 {
2736 	sljit_s32 dst_r, flags = 0;
2737 
2738 	CHECK_ERROR();
2739 	CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
2740 	ADJUST_LOCAL_OFFSET(dst, dstw);
2741 	ADJUST_LOCAL_OFFSET(src1, src1w);
2742 	ADJUST_LOCAL_OFFSET(src2, src2w);
2743 
2744 	compiler->cache_arg = 0;
2745 	compiler->cache_argw = 0;
2746 
2747 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
2748 
2749 	if (src1 & SLJIT_MEM) {
2750 		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w)) {
2751 			FAIL_IF(compiler->error);
2752 			src1 = TMP_FREG1;
2753 		} else
2754 			flags |= SLOW_SRC1;
2755 	}
2756 
2757 	if (src2 & SLJIT_MEM) {
2758 		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w)) {
2759 			FAIL_IF(compiler->error);
2760 			src2 = TMP_FREG2;
2761 		} else
2762 			flags |= SLOW_SRC2;
2763 	}
2764 
2765 	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
2766 		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
2767 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, src1, src1w));
2768 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
2769 		}
2770 		else {
2771 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
2772 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
2773 		}
2774 	}
2775 	else if (flags & SLOW_SRC1)
2776 		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
2777 	else if (flags & SLOW_SRC2)
2778 		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
2779 
2780 	if (flags & SLOW_SRC1)
2781 		src1 = TMP_FREG1;
2782 	if (flags & SLOW_SRC2)
2783 		src2 = TMP_FREG2;
2784 
2785 	switch (GET_OPCODE(op)) {
2786 	case SLJIT_ADD_F64:
2787 		FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
2788 		break;
2789 
2790 	case SLJIT_SUB_F64:
2791 		FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
2792 		break;
2793 
2794 	case SLJIT_MUL_F64:
2795 		FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
2796 		break;
2797 
2798 	case SLJIT_DIV_F64:
2799 		FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
2800 		break;
2801 	}
2802 
2803 	if (dst_r == TMP_FREG2)
2804 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG2), dst, dstw, 0, 0));
2805 
2806 	return SLJIT_SUCCESS;
2807 }
2808 
2809 #undef FLOAT_DATA
2810 #undef FMT
2811 
2812 /* --------------------------------------------------------------------- */
2813 /*  Other instructions                                                   */
2814 /* --------------------------------------------------------------------- */
2815 
sljit_emit_fast_enter(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)2816 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
2817 {
2818 	CHECK_ERROR();
2819 	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
2820 	ADJUST_LOCAL_OFFSET(dst, dstw);
2821 
2822 	if (FAST_IS_REG(dst))
2823 		return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS);
2824 
2825 	/* Memory. */
2826 	FAIL_IF(emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw));
2827 	compiler->delay_slot = UNMOVABLE_INS;
2828 	return SLJIT_SUCCESS;
2829 }
2830 
2831 /* --------------------------------------------------------------------- */
2832 /*  Conditional instructions                                             */
2833 /* --------------------------------------------------------------------- */
2834 
sljit_emit_label(struct sljit_compiler * compiler)2835 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
2836 {
2837 	struct sljit_label *label;
2838 
2839 	CHECK_ERROR_PTR();
2840 	CHECK_PTR(check_sljit_emit_label(compiler));
2841 
2842 	if (compiler->last_label && compiler->last_label->size == compiler->size)
2843 		return compiler->last_label;
2844 
2845 	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
2846 	PTR_FAIL_IF(!label);
2847 	set_label(label, compiler);
2848 	compiler->delay_slot = UNMOVABLE_INS;
2849 	return label;
2850 }
2851 
2852 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2853 #define BRANCH_LENGTH	4
2854 #else
2855 #define BRANCH_LENGTH	8
2856 #endif
2857 
2858 #define BR_Z(src) \
2859 	inst = BEQ | SA(src) | TA(0) | BRANCH_LENGTH; \
2860 	flags = IS_BIT26_COND; \
2861 	delay_check = src;
2862 
2863 #define BR_NZ(src) \
2864 	inst = BNE | SA(src) | TA(0) | BRANCH_LENGTH; \
2865 	flags = IS_BIT26_COND; \
2866 	delay_check = src;
2867 
2868 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2869 
2870 #define BR_T() \
2871 	inst = BC1NEZ; \
2872 	flags = IS_BIT23_COND; \
2873 	delay_check = FCSR_FCC;
2874 #define BR_F() \
2875 	inst = BC1EQZ; \
2876 	flags = IS_BIT23_COND; \
2877 	delay_check = FCSR_FCC;
2878 
2879 #else /* SLJIT_MIPS_REV < 6 */
2880 
2881 #define BR_T() \
2882 	inst = BC1T | BRANCH_LENGTH; \
2883 	flags = IS_BIT16_COND; \
2884 	delay_check = FCSR_FCC;
2885 #define BR_F() \
2886 	inst = BC1F | BRANCH_LENGTH; \
2887 	flags = IS_BIT16_COND; \
2888 	delay_check = FCSR_FCC;
2889 
2890 #endif /* SLJIT_MIPS_REV >= 6 */
2891 
sljit_emit_jump(struct sljit_compiler * compiler,sljit_s32 type)2892 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
2893 {
2894 	struct sljit_jump *jump;
2895 	sljit_ins inst;
2896 	sljit_u32 flags = 0;
2897 	sljit_s32 delay_check = UNMOVABLE_INS;
2898 
2899 	CHECK_ERROR_PTR();
2900 	CHECK_PTR(check_sljit_emit_jump(compiler, type));
2901 
2902 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2903 	PTR_FAIL_IF(!jump);
2904 	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
2905 	type &= 0xff;
2906 
2907 	switch (type) {
2908 	case SLJIT_EQUAL:
2909 		BR_NZ(EQUAL_FLAG);
2910 		break;
2911 	case SLJIT_NOT_EQUAL:
2912 		BR_Z(EQUAL_FLAG);
2913 		break;
2914 	case SLJIT_LESS:
2915 	case SLJIT_GREATER:
2916 	case SLJIT_SIG_LESS:
2917 	case SLJIT_SIG_GREATER:
2918 	case SLJIT_OVERFLOW:
2919 	case SLJIT_CARRY:
2920 		BR_Z(OTHER_FLAG);
2921 		break;
2922 	case SLJIT_GREATER_EQUAL:
2923 	case SLJIT_LESS_EQUAL:
2924 	case SLJIT_SIG_GREATER_EQUAL:
2925 	case SLJIT_SIG_LESS_EQUAL:
2926 	case SLJIT_NOT_OVERFLOW:
2927 	case SLJIT_NOT_CARRY:
2928 		BR_NZ(OTHER_FLAG);
2929 		break;
2930 	case SLJIT_F_NOT_EQUAL:
2931 	case SLJIT_F_GREATER_EQUAL:
2932 	case SLJIT_F_GREATER:
2933 	case SLJIT_UNORDERED_OR_NOT_EQUAL:
2934 	case SLJIT_ORDERED_NOT_EQUAL:
2935 	case SLJIT_UNORDERED_OR_GREATER_EQUAL:
2936 	case SLJIT_ORDERED_GREATER_EQUAL:
2937 	case SLJIT_ORDERED_GREATER:
2938 	case SLJIT_UNORDERED_OR_GREATER:
2939 	case SLJIT_ORDERED:
2940 		BR_T();
2941 		break;
2942 	case SLJIT_F_EQUAL:
2943 	case SLJIT_F_LESS:
2944 	case SLJIT_F_LESS_EQUAL:
2945 	case SLJIT_ORDERED_EQUAL:
2946 	case SLJIT_UNORDERED_OR_EQUAL:
2947 	case SLJIT_ORDERED_LESS:
2948 	case SLJIT_UNORDERED_OR_LESS:
2949 	case SLJIT_UNORDERED_OR_LESS_EQUAL:
2950 	case SLJIT_ORDERED_LESS_EQUAL:
2951 	case SLJIT_UNORDERED:
2952 		BR_F();
2953 		break;
2954 	default:
2955 		/* Not conditional branch. */
2956 		inst = 0;
2957 		break;
2958 	}
2959 
2960 	jump->flags |= flags;
2961 	if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check))
2962 		jump->flags |= IS_MOVABLE;
2963 
2964 	if (inst)
2965 		PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));
2966 
2967 	if (type <= SLJIT_JUMP)
2968 		PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
2969 	else {
2970 		jump->flags |= IS_JAL;
2971 		PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
2972 	}
2973 
2974 	jump->addr = compiler->size;
2975 	PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2976 
2977 	/* Maximum number of instructions required for generating a constant. */
2978 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2979 	compiler->size += 2;
2980 #else
2981 	compiler->size += 6;
2982 #endif
2983 	return jump;
2984 }
2985 
2986 #define RESOLVE_IMM1() \
2987 	if (src1 & SLJIT_IMM) { \
2988 		if (src1w) { \
2989 			PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \
2990 			src1 = TMP_REG1; \
2991 		} \
2992 		else \
2993 			src1 = 0; \
2994 	}
2995 
2996 #define RESOLVE_IMM2() \
2997 	if (src2 & SLJIT_IMM) { \
2998 		if (src2w) { \
2999 			PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \
3000 			src2 = TMP_REG2; \
3001 		} \
3002 		else \
3003 			src2 = 0; \
3004 	}
3005 
sljit_emit_cmp(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)3006 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
3007 	sljit_s32 src1, sljit_sw src1w,
3008 	sljit_s32 src2, sljit_sw src2w)
3009 {
3010 	struct sljit_jump *jump;
3011 	sljit_s32 flags;
3012 	sljit_ins inst;
3013 
3014 	CHECK_ERROR_PTR();
3015 	CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
3016 	ADJUST_LOCAL_OFFSET(src1, src1w);
3017 	ADJUST_LOCAL_OFFSET(src2, src2w);
3018 
3019 	compiler->cache_arg = 0;
3020 	compiler->cache_argw = 0;
3021 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3022 	flags = WORD_DATA | LOAD_DATA;
3023 #else /* !SLJIT_CONFIG_MIPS_32 */
3024 	flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
3025 #endif /* SLJIT_CONFIG_MIPS_32 */
3026 
3027 	if (src1 & SLJIT_MEM) {
3028 		PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w));
3029 		src1 = TMP_REG1;
3030 	}
3031 
3032 	if (src2 & SLJIT_MEM) {
3033 		PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0));
3034 		src2 = TMP_REG2;
3035 	}
3036 
3037 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
3038 	PTR_FAIL_IF(!jump);
3039 	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
3040 	type &= 0xff;
3041 
3042 	if (type <= SLJIT_NOT_EQUAL) {
3043 		RESOLVE_IMM1();
3044 		RESOLVE_IMM2();
3045 		jump->flags |= IS_BIT26_COND;
3046 		if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2)))
3047 			jump->flags |= IS_MOVABLE;
3048 		PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | BRANCH_LENGTH, UNMOVABLE_INS));
3049 	}
3050 	else if (type >= SLJIT_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) {
3051 		inst = NOP;
3052 		if ((src1 & SLJIT_IMM) && (src1w == 0)) {
3053 			RESOLVE_IMM2();
3054 			switch (type) {
3055 			case SLJIT_SIG_LESS:
3056 				inst = BLEZ;
3057 				jump->flags |= IS_BIT26_COND;
3058 				break;
3059 			case SLJIT_SIG_GREATER_EQUAL:
3060 				inst = BGTZ;
3061 				jump->flags |= IS_BIT26_COND;
3062 				break;
3063 			case SLJIT_SIG_GREATER:
3064 				inst = BGEZ;
3065 				jump->flags |= IS_BIT16_COND;
3066 				break;
3067 			case SLJIT_SIG_LESS_EQUAL:
3068 				inst = BLTZ;
3069 				jump->flags |= IS_BIT16_COND;
3070 				break;
3071 			}
3072 			src1 = src2;
3073 		}
3074 		else {
3075 			RESOLVE_IMM1();
3076 			switch (type) {
3077 			case SLJIT_SIG_LESS:
3078 				inst = BGEZ;
3079 				jump->flags |= IS_BIT16_COND;
3080 				break;
3081 			case SLJIT_SIG_GREATER_EQUAL:
3082 				inst = BLTZ;
3083 				jump->flags |= IS_BIT16_COND;
3084 				break;
3085 			case SLJIT_SIG_GREATER:
3086 				inst = BLEZ;
3087 				jump->flags |= IS_BIT26_COND;
3088 				break;
3089 			case SLJIT_SIG_LESS_EQUAL:
3090 				inst = BGTZ;
3091 				jump->flags |= IS_BIT26_COND;
3092 				break;
3093 			}
3094 		}
3095 		PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | BRANCH_LENGTH, UNMOVABLE_INS));
3096 	}
3097 	else {
3098 		if (type == SLJIT_LESS || type == SLJIT_GREATER_EQUAL || type == SLJIT_SIG_LESS || type == SLJIT_SIG_GREATER_EQUAL) {
3099 			RESOLVE_IMM1();
3100 			if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN)
3101 				PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1)));
3102 			else {
3103 				RESOLVE_IMM2();
3104 				PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));
3105 			}
3106 			type = (type == SLJIT_LESS || type == SLJIT_SIG_LESS) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
3107 		}
3108 		else {
3109 			RESOLVE_IMM2();
3110 			if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN)
3111 				PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1)));
3112 			else {
3113 				RESOLVE_IMM1();
3114 				PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1)));
3115 			}
3116 			type = (type == SLJIT_GREATER || type == SLJIT_SIG_GREATER) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
3117 		}
3118 
3119 		jump->flags |= IS_BIT26_COND;
3120 		PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | BRANCH_LENGTH, UNMOVABLE_INS));
3121 	}
3122 
3123 	PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
3124 	jump->addr = compiler->size;
3125 	PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3126 
3127 	/* Maximum number of instructions required for generating a constant. */
3128 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3129 	compiler->size += 2;
3130 #else
3131 	compiler->size += 6;
3132 #endif
3133 	return jump;
3134 }
3135 
3136 #undef RESOLVE_IMM1
3137 #undef RESOLVE_IMM2
3138 
3139 #undef BRANCH_LENGTH
3140 #undef BR_Z
3141 #undef BR_NZ
3142 #undef BR_T
3143 #undef BR_F
3144 
3145 #undef FLOAT_DATA
3146 #undef FMT
3147 
sljit_emit_ijump(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src,sljit_sw srcw)3148 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
3149 {
3150 	struct sljit_jump *jump = NULL;
3151 
3152 	CHECK_ERROR();
3153 	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
3154 
3155 	if (src & SLJIT_IMM) {
3156 		jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
3157 		FAIL_IF(!jump);
3158 		set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
3159 		jump->u.target = (sljit_uw)srcw;
3160 
3161 		if (compiler->delay_slot != UNMOVABLE_INS)
3162 			jump->flags |= IS_MOVABLE;
3163 
3164 		src = TMP_REG2;
3165 	} else if (src & SLJIT_MEM) {
3166 		ADJUST_LOCAL_OFFSET(src, srcw);
3167 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG2), src, srcw));
3168 		src = TMP_REG2;
3169 	}
3170 
3171 	if (type <= SLJIT_JUMP)
3172 		FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));
3173 	else
3174 		FAIL_IF(push_inst(compiler, JALR | S(src) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
3175 
3176 	if (jump != NULL) {
3177 		jump->addr = compiler->size;
3178 
3179 		/* Maximum number of instructions required for generating a constant. */
3180 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3181 		compiler->size += 2;
3182 #else
3183 		compiler->size += 6;
3184 #endif
3185 	}
3186 
3187 	FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3188 	return SLJIT_SUCCESS;
3189 }
3190 
sljit_emit_op_flags(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 type)3191 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
3192 	sljit_s32 dst, sljit_sw dstw,
3193 	sljit_s32 type)
3194 {
3195 	sljit_s32 src_ar, dst_ar, invert;
3196 	sljit_s32 saved_op = op;
3197 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3198 	sljit_s32 mem_type = WORD_DATA;
3199 #else
3200 	sljit_s32 mem_type = ((op & SLJIT_32) || op == SLJIT_MOV32) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
3201 #endif
3202 
3203 	CHECK_ERROR();
3204 	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
3205 	ADJUST_LOCAL_OFFSET(dst, dstw);
3206 
3207 	op = GET_OPCODE(op);
3208 	dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2);
3209 
3210 	compiler->cache_arg = 0;
3211 	compiler->cache_argw = 0;
3212 
3213 	if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
3214 		FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, DR(TMP_REG1), dst, dstw, dst, dstw));
3215 
3216 	if (type < SLJIT_F_EQUAL) {
3217 		src_ar = OTHER_FLAG;
3218 		invert = type & 0x1;
3219 
3220 		switch (type) {
3221 		case SLJIT_EQUAL:
3222 		case SLJIT_NOT_EQUAL:
3223 			FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(dst_ar) | IMM(1), dst_ar));
3224 			src_ar = dst_ar;
3225 			break;
3226 		case SLJIT_OVERFLOW:
3227 		case SLJIT_NOT_OVERFLOW:
3228 			if (compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)) {
3229 				src_ar = OTHER_FLAG;
3230 				break;
3231 			}
3232 			FAIL_IF(push_inst(compiler, SLTIU | SA(OTHER_FLAG) | TA(dst_ar) | IMM(1), dst_ar));
3233 			src_ar = dst_ar;
3234 			invert ^= 0x1;
3235 			break;
3236 		}
3237 	} else {
3238 		invert = 0;
3239 
3240 		switch (type) {
3241 		case SLJIT_F_NOT_EQUAL:
3242 		case SLJIT_F_GREATER_EQUAL:
3243 		case SLJIT_F_GREATER:
3244 		case SLJIT_UNORDERED_OR_NOT_EQUAL:
3245 		case SLJIT_ORDERED_NOT_EQUAL:
3246 		case SLJIT_UNORDERED_OR_GREATER_EQUAL:
3247 		case SLJIT_ORDERED_GREATER_EQUAL:
3248 		case SLJIT_ORDERED_GREATER:
3249 		case SLJIT_UNORDERED_OR_GREATER:
3250 		case SLJIT_ORDERED:
3251 			invert = 1;
3252 			break;
3253 		}
3254 
3255 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
3256 		FAIL_IF(push_inst(compiler, MFC1 | TA(dst_ar) | FS(TMP_FREG3), dst_ar));
3257 #else /* SLJIT_MIPS_REV < 6 */
3258 		FAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar));
3259 #endif /* SLJIT_MIPS_REV >= 6 */
3260 		FAIL_IF(push_inst(compiler, SRL | TA(dst_ar) | DA(dst_ar) | SH_IMM(23), dst_ar));
3261 		FAIL_IF(push_inst(compiler, ANDI | SA(dst_ar) | TA(dst_ar) | IMM(1), dst_ar));
3262 		src_ar = dst_ar;
3263 	}
3264 
3265 	if (invert) {
3266 		FAIL_IF(push_inst(compiler, XORI | SA(src_ar) | TA(dst_ar) | IMM(1), dst_ar));
3267 		src_ar = dst_ar;
3268 	}
3269 
3270 	if (op < SLJIT_ADD) {
3271 		if (dst & SLJIT_MEM)
3272 			return emit_op_mem(compiler, mem_type, src_ar, dst, dstw);
3273 
3274 		if (src_ar != dst_ar)
3275 			return push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | DA(dst_ar), dst_ar);
3276 		return SLJIT_SUCCESS;
3277 	}
3278 
3279 	/* OTHER_FLAG cannot be specified as src2 argument at the moment. */
3280 	if (DR(TMP_REG2) != src_ar)
3281 		FAIL_IF(push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
3282 
3283 	mem_type |= CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE;
3284 
3285 	if (dst & SLJIT_MEM)
3286 		return emit_op(compiler, saved_op, mem_type, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
3287 	return emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, TMP_REG2, 0);
3288 }
3289 
sljit_emit_cmov(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_reg,sljit_s32 src,sljit_sw srcw)3290 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
3291 	sljit_s32 dst_reg,
3292 	sljit_s32 src, sljit_sw srcw)
3293 {
3294 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
3295 	sljit_ins ins;
3296 #endif /* SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6 */
3297 
3298 	CHECK_ERROR();
3299 	CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
3300 
3301 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
3302 
3303 	if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
3304 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
3305 		if (type & SLJIT_32)
3306 			srcw = (sljit_s32)srcw;
3307 #endif
3308 		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
3309 		src = TMP_REG1;
3310 		srcw = 0;
3311 	}
3312 
3313 	switch (type & ~SLJIT_32) {
3314 	case SLJIT_EQUAL:
3315 		ins = MOVZ | TA(EQUAL_FLAG);
3316 		break;
3317 	case SLJIT_NOT_EQUAL:
3318 		ins = MOVN | TA(EQUAL_FLAG);
3319 		break;
3320 	case SLJIT_LESS:
3321 	case SLJIT_GREATER:
3322 	case SLJIT_SIG_LESS:
3323 	case SLJIT_SIG_GREATER:
3324 	case SLJIT_OVERFLOW:
3325 		ins = MOVN | TA(OTHER_FLAG);
3326 		break;
3327 	case SLJIT_GREATER_EQUAL:
3328 	case SLJIT_LESS_EQUAL:
3329 	case SLJIT_SIG_GREATER_EQUAL:
3330 	case SLJIT_SIG_LESS_EQUAL:
3331 	case SLJIT_NOT_OVERFLOW:
3332 		ins = MOVZ | TA(OTHER_FLAG);
3333 		break;
3334 	case SLJIT_F_EQUAL:
3335 	case SLJIT_F_LESS:
3336 	case SLJIT_F_LESS_EQUAL:
3337 	case SLJIT_ORDERED_EQUAL:
3338 	case SLJIT_UNORDERED_OR_EQUAL:
3339 	case SLJIT_ORDERED_LESS:
3340 	case SLJIT_UNORDERED_OR_LESS:
3341 	case SLJIT_UNORDERED_OR_LESS_EQUAL:
3342 	case SLJIT_ORDERED_LESS_EQUAL:
3343 	case SLJIT_UNORDERED:
3344 		ins = MOVT;
3345 		break;
3346 	case SLJIT_F_NOT_EQUAL:
3347 	case SLJIT_F_GREATER_EQUAL:
3348 	case SLJIT_F_GREATER:
3349 	case SLJIT_UNORDERED_OR_NOT_EQUAL:
3350 	case SLJIT_ORDERED_NOT_EQUAL:
3351 	case SLJIT_UNORDERED_OR_GREATER_EQUAL:
3352 	case SLJIT_ORDERED_GREATER_EQUAL:
3353 	case SLJIT_ORDERED_GREATER:
3354 	case SLJIT_UNORDERED_OR_GREATER:
3355 	case SLJIT_ORDERED:
3356 		ins = MOVF;
3357 		break;
3358 	default:
3359 		ins = MOVZ | TA(OTHER_FLAG);
3360 		SLJIT_UNREACHABLE();
3361 		break;
3362 	}
3363 
3364 	return push_inst(compiler, ins | S(src) | D(dst_reg), DR(dst_reg));
3365 
3366 #else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */
3367 	return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);
3368 #endif /* SLJIT_MIPS_REV >= 1 */
3369 }
3370 
update_mem_addr(struct sljit_compiler * compiler,sljit_s32 * mem,sljit_sw * memw,sljit_s16 max_offset)3371 static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem, sljit_sw *memw, sljit_s16 max_offset)
3372 {
3373 	sljit_s32 arg = *mem;
3374 	sljit_sw argw = *memw;
3375 
3376 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
3377 		argw &= 0x3;
3378 
3379 		if (SLJIT_UNLIKELY(argw)) {
3380 			FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG1) | SH_IMM(argw), DR(TMP_REG1)));
3381 			FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG1) | T(arg & REG_MASK) | D(TMP_REG1), DR(TMP_REG1)));
3382 		} else
3383 			FAIL_IF(push_inst(compiler, ADDU_W | S(arg & REG_MASK) | T(OFFS_REG(arg)) | D(TMP_REG1), DR(TMP_REG1)));
3384 
3385 		*mem = TMP_REG1;
3386 		*memw = 0;
3387 
3388 		return SLJIT_SUCCESS;
3389 	}
3390 
3391 	if (argw <= max_offset && argw >= SIMM_MIN) {
3392 		*mem = arg & REG_MASK;
3393 		return SLJIT_SUCCESS;
3394 	}
3395 
3396 	*mem = TMP_REG1;
3397 
3398 	if ((sljit_s16)argw > max_offset) {
3399 		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), argw));
3400 		*memw = 0;
3401 	} else {
3402 		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), TO_ARGW_HI(argw)));
3403 		*memw = (sljit_s16)argw;
3404 	}
3405 
3406 	if ((arg & REG_MASK) == 0)
3407 		return SLJIT_SUCCESS;
3408 
3409 	return push_inst(compiler, ADDU_W | S(TMP_REG1) | T(arg & REG_MASK) | D(TMP_REG1), DR(TMP_REG1));
3410 }
3411 
3412 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
3413 #define MEM16_IMM_FIRST(memw) IMM((memw) + 1)
3414 #define MEM16_IMM_SECOND(memw) IMM(memw)
3415 #define MEMF64_FS_FIRST(freg) FS(freg)
3416 #define MEMF64_FS_SECOND(freg) (FS(freg) | ((sljit_ins)1 << 11))
3417 #else /* !SLJIT_LITTLE_ENDIAN */
3418 #define MEM16_IMM_FIRST(memw) IMM(memw)
3419 #define MEM16_IMM_SECOND(memw) IMM((memw) + 1)
3420 #define MEMF64_FS_FIRST(freg) (FS(freg) | ((sljit_ins)1 << 11))
3421 #define MEMF64_FS_SECOND(freg) FS(freg)
3422 #endif /* SLJIT_LITTLE_ENDIAN */
3423 
3424 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3425 #define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16))
3426 #else /* !SLJIT_CONFIG_MIPS_32 */
3427 #define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32))
3428 #endif /* SLJIT_CONFIG_MIPS_32 */
3429 
sljit_emit_mem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 reg,sljit_s32 mem,sljit_sw memw)3430 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
3431 	sljit_s32 reg,
3432 	sljit_s32 mem, sljit_sw memw)
3433 {
3434 	sljit_s32 op = type & 0xff;
3435 	sljit_s32 flags = 0;
3436 	sljit_ins ins;
3437 #if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
3438 	sljit_ins ins_right;
3439 #endif /* !(SLJIT_MIPS_REV >= 6) */
3440 
3441 	CHECK_ERROR();
3442 	CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
3443 
3444 	if (reg & REG_PAIR_MASK) {
3445 		ADJUST_LOCAL_OFFSET(mem, memw);
3446 
3447 #if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
3448 		if (MEM_CHECK_UNALIGNED(type)) {
3449 			FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - (2 * SSIZE_OF(sw) - 1)));
3450 
3451 			if (!(type & SLJIT_MEM_STORE) && (mem == REG_PAIR_FIRST(reg) || mem == REG_PAIR_SECOND(reg))) {
3452 				FAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
3453 				mem = TMP_REG1;
3454 			}
3455 
3456 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3457 			ins = ((type & SLJIT_MEM_STORE) ? SWL : LWL) | S(mem);
3458 			ins_right = ((type & SLJIT_MEM_STORE) ? SWR : LWR) | S(mem);
3459 #else /* !SLJIT_CONFIG_MIPS_32 */
3460 			ins = ((type & SLJIT_MEM_STORE) ? SDL : LDL) | S(mem);
3461 			ins_right = ((type & SLJIT_MEM_STORE) ? SDR : LDR) | S(mem);
3462 #endif /* SLJIT_CONFIG_MIPS_32 */
3463 
3464 			FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg))));
3465 			FAIL_IF(push_inst(compiler, ins_right | T(REG_PAIR_FIRST(reg)) | IMM(memw + (SSIZE_OF(sw) - 1)), DR(REG_PAIR_FIRST(reg))));
3466 			FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg))));
3467 			return push_inst(compiler, ins_right | T(REG_PAIR_SECOND(reg)) | IMM((memw + 2 * SSIZE_OF(sw) - 1)), DR(REG_PAIR_SECOND(reg)));
3468 		}
3469 #endif /* !(SLJIT_MIPS_REV >= 6) */
3470 
3471 		FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - SSIZE_OF(sw)));
3472 
3473 		ins = ((type & SLJIT_MEM_STORE) ? STORE_W : LOAD_W) | S(mem);
3474 
3475 		if (!(type & SLJIT_MEM_STORE) && mem == REG_PAIR_FIRST(reg)) {
3476 			FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg))));
3477 			return push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg)));
3478 		}
3479 
3480 		FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg))));
3481 		return push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg)));
3482 	}
3483 
3484 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
3485 	return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);
3486 #else /* !(SLJIT_MIPS_REV >= 6) */
3487 	ADJUST_LOCAL_OFFSET(mem, memw);
3488 
3489 	switch (op) {
3490 	case SLJIT_MOV_U8:
3491 	case SLJIT_MOV_S8:
3492 		flags = BYTE_DATA;
3493 		if (!(type & SLJIT_MEM_STORE))
3494 			flags |= LOAD_DATA;
3495 
3496 		if (op == SLJIT_MOV_S8)
3497 			flags |= SIGNED_DATA;
3498 
3499 		return emit_op_mem(compiler, flags, DR(reg), mem, memw);
3500 
3501 	case SLJIT_MOV_U16:
3502 	case SLJIT_MOV_S16:
3503 		FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 1));
3504 		SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
3505 
3506 		if (type & SLJIT_MEM_STORE) {
3507 			FAIL_IF(push_inst(compiler, SRA_W | T(reg) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2)));
3508 			FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(TMP_REG2) | MEM16_IMM_FIRST(memw), MOVABLE_INS));
3509 			return push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(reg) | MEM16_IMM_SECOND(memw), MOVABLE_INS);
3510 		}
3511 
3512 		flags = BYTE_DATA | LOAD_DATA;
3513 
3514 		if (op == SLJIT_MOV_S16)
3515 			flags |= SIGNED_DATA;
3516 
3517 		FAIL_IF(push_inst(compiler, data_transfer_insts[flags] | S(mem) | T(TMP_REG2) | MEM16_IMM_FIRST(memw), DR(TMP_REG2)));
3518 		FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA | LOAD_DATA] | S(mem) | T(reg) | MEM16_IMM_SECOND(memw), DR(reg)));
3519 		FAIL_IF(push_inst(compiler, SLL_W | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2)));
3520 		return push_inst(compiler, OR | S(reg) | T(TMP_REG2) | D(reg), DR(reg));
3521 
3522 	case SLJIT_MOV:
3523 	case SLJIT_MOV_P:
3524 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3525 		if (type & SLJIT_MEM_UNALIGNED_32) {
3526 			flags = WORD_DATA;
3527 			if (!(type & SLJIT_MEM_STORE))
3528 				flags |= LOAD_DATA;
3529 
3530 			return emit_op_mem(compiler, flags, DR(reg), mem, memw);
3531 		}
3532 #else /* !SLJIT_CONFIG_MIPS_32 */
3533 		FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 7));
3534 		SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
3535 
3536 		if (type & SLJIT_MEM_STORE) {
3537 			FAIL_IF(push_inst(compiler, SDL | S(mem) | T(reg) | IMM(memw), MOVABLE_INS));
3538 			return push_inst(compiler, SDR | S(mem) | T(reg) | IMM(memw + 7), MOVABLE_INS);
3539 		}
3540 
3541 		if (mem == reg) {
3542 			FAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
3543 			mem = TMP_REG1;
3544 		}
3545 
3546 		FAIL_IF(push_inst(compiler, LDL | S(mem) | T(reg) | IMM(memw), DR(reg)));
3547 		return push_inst(compiler, LDR | S(mem) | T(reg) | IMM(memw + 7), DR(reg));
3548 #endif /* SLJIT_CONFIG_MIPS_32 */
3549 	}
3550 
3551 	FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 3));
3552 	SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
3553 
3554 	if (type & SLJIT_MEM_STORE) {
3555 		FAIL_IF(push_inst(compiler, SWL | S(mem) | T(reg) | IMM(memw), MOVABLE_INS));
3556 		return push_inst(compiler, SWR | S(mem) | T(reg) | IMM(memw + 3), MOVABLE_INS);
3557 	}
3558 
3559 	if (mem == reg) {
3560 		FAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
3561 		mem = TMP_REG1;
3562 	}
3563 
3564 	FAIL_IF(push_inst(compiler, LWL | S(mem) | T(reg) | IMM(memw), DR(reg)));
3565 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3566 	return push_inst(compiler, LWR | S(mem) | T(reg) | IMM(memw + 3), DR(reg));
3567 #else /* !SLJIT_CONFIG_MIPS_32 */
3568 	FAIL_IF(push_inst(compiler, LWR | S(mem) | T(reg) | IMM(memw + 3), DR(reg)));
3569 
3570 	if (op != SLJIT_MOV_U32)
3571 		return SLJIT_SUCCESS;
3572 
3573 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
3574 	return push_inst(compiler, DINSU | T(reg) | SA(0) | (31 << 11) | (0 << 11), DR(reg));
3575 #else  /* SLJIT_MIPS_REV < 1 */
3576 	FAIL_IF(push_inst(compiler, DSLL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg)));
3577 	return push_inst(compiler, DSRL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg));
3578 #endif /* SLJIT_MIPS_REV >= 2 */
3579 #endif /* SLJIT_CONFIG_MIPS_32 */
3580 #endif /* SLJIT_MIPS_REV >= 6 */
3581 }
3582 
3583 #if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
3584 
sljit_emit_fmem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 mem,sljit_sw memw)3585 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
3586 	sljit_s32 freg,
3587 	sljit_s32 mem, sljit_sw memw)
3588 {
3589 	CHECK_ERROR();
3590 	CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
3591 
3592 	FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - (type & SLJIT_32) ? 3 : 7));
3593 	SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
3594 
3595 	if (type & SLJIT_MEM_STORE) {
3596 		if (type & SLJIT_32) {
3597 			FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));
3598 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3599 			FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3600 #endif
3601 			FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM(memw), MOVABLE_INS));
3602 			return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), MOVABLE_INS);
3603 		}
3604 
3605 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3606 		FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | MEMF64_FS_FIRST(freg), DR(TMP_REG2)));
3607 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3608 		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3609 #endif
3610 		FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM(memw), MOVABLE_INS));
3611 		FAIL_IF(push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), MOVABLE_INS));
3612 
3613 		FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | MEMF64_FS_SECOND(freg), DR(TMP_REG2)));
3614 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3615 		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3616 #endif
3617 		FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM(memw + 4), MOVABLE_INS));
3618 		return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM(memw + 7), MOVABLE_INS);
3619 #else /* !SLJIT_CONFIG_MIPS_32 */
3620 		FAIL_IF(push_inst(compiler, MFC1 | (1 << 21) | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));
3621 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3622 		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3623 #endif
3624 		FAIL_IF(push_inst(compiler, SDL | S(mem) | T(TMP_REG2) | IMM(memw), MOVABLE_INS));
3625 		return push_inst(compiler, SDR | S(mem) | T(TMP_REG2) | IMM(memw + 7), MOVABLE_INS);
3626 #endif /* SLJIT_CONFIG_MIPS_32 */
3627 	}
3628 
3629 	if (type & SLJIT_32) {
3630 		FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM(memw), DR(TMP_REG2)));
3631 		FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), DR(TMP_REG2)));
3632 
3633 		FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS));
3634 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3635 		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3636 #endif
3637 		return SLJIT_SUCCESS;
3638 	}
3639 
3640 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3641 	FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM(memw), DR(TMP_REG2)));
3642 	FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), DR(TMP_REG2)));
3643 	FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | MEMF64_FS_FIRST(freg), MOVABLE_INS));
3644 
3645 	FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM(memw + 4), DR(TMP_REG2)));
3646 	FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM(memw + 7), DR(TMP_REG2)));
3647 	FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | MEMF64_FS_SECOND(freg), MOVABLE_INS));
3648 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3649 	FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3650 #endif
3651 #else /* !SLJIT_CONFIG_MIPS_32 */
3652 	FAIL_IF(push_inst(compiler, LDL | S(mem) | T(TMP_REG2) | IMM(memw), DR(TMP_REG2)));
3653 	FAIL_IF(push_inst(compiler, LDR | S(mem) | T(TMP_REG2) | IMM(memw + 7), DR(TMP_REG2)));
3654 
3655 	FAIL_IF(push_inst(compiler, MTC1 | (1 << 21) | T(TMP_REG2) | FS(freg), MOVABLE_INS));
3656 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3657 	FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3658 #endif
3659 #endif /* SLJIT_CONFIG_MIPS_32 */
3660 	return SLJIT_SUCCESS;
3661 }
3662 
3663 #endif /* !SLJIT_MIPS_REV || SLJIT_MIPS_REV < 6 */
3664 
3665 #undef MEM16_IMM_FIRST
3666 #undef MEM16_IMM_SECOND
3667 #undef MEMF64_FS_FIRST
3668 #undef MEMF64_FS_SECOND
3669 #undef MEM_CHECK_UNALIGNED
3670 
3671 #undef TO_ARGW_HI
3672 
sljit_emit_const(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw init_value)3673 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
3674 {
3675 	struct sljit_const *const_;
3676 	sljit_s32 dst_r;
3677 
3678 	CHECK_ERROR_PTR();
3679 	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
3680 	ADJUST_LOCAL_OFFSET(dst, dstw);
3681 
3682 	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
3683 	PTR_FAIL_IF(!const_);
3684 	set_const(const_, compiler);
3685 
3686 	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
3687 	PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
3688 
3689 	if (dst & SLJIT_MEM)
3690 		PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, DR(TMP_REG2), dst, dstw));
3691 
3692 	return const_;
3693 }
3694 
sljit_emit_put_label(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)3695 SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
3696 {
3697 	struct sljit_put_label *put_label;
3698 	sljit_s32 dst_r;
3699 
3700 	CHECK_ERROR_PTR();
3701 	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
3702 	ADJUST_LOCAL_OFFSET(dst, dstw);
3703 
3704 	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
3705 	PTR_FAIL_IF(!put_label);
3706 	set_put_label(put_label, compiler, 0);
3707 
3708 	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
3709 	PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r, UNMOVABLE_INS));
3710 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3711 	compiler->size += 1;
3712 #else
3713 	compiler->size += 5;
3714 #endif
3715 
3716 	if (dst & SLJIT_MEM)
3717 		PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, DR(TMP_REG2), dst, dstw));
3718 
3719 	return put_label;
3720 }
3721