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 >= 1)
46 
47 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
48 	return "MIPS32-R1" SLJIT_CPUINFO;
49 #else /* !SLJIT_CONFIG_MIPS_32 */
50 	return "MIPS64-R1" SLJIT_CPUINFO;
51 #endif /* SLJIT_CONFIG_MIPS_32 */
52 
53 #else /* SLJIT_MIPS_REV < 1 */
54 	return "MIPS III" SLJIT_CPUINFO;
55 #endif /* SLJIT_MIPS_REV >= 6 */
56 }
57 
58 /* Length of an instruction word
59    Both for mips-32 and mips-64 */
60 typedef sljit_u32 sljit_ins;
61 
62 #define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)
63 #define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)
64 #define TMP_REG3	(SLJIT_NUMBER_OF_REGISTERS + 4)
65 
66 /* For position independent code, t9 must contain the function address. */
67 #define PIC_ADDR_REG	TMP_REG2
68 
69 /* Floating point status register. */
70 #define FCSR_REG	31
71 /* Return address register. */
72 #define RETURN_ADDR_REG	31
73 
74 /* Flags are kept in volatile registers. */
75 #define EQUAL_FLAG	3
76 #define OTHER_FLAG	1
77 
78 #define TMP_FREG1	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
79 #define TMP_FREG2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
80 #define TMP_FREG3	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3)
81 
82 static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
83 	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
84 };
85 
86 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
87 
88 static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
89 	0, 0, 14, 2, 4, 6, 8, 18, 30, 28, 26, 24, 22, 20, 12, 10, 16
90 };
91 
92 #else
93 
94 static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
95 	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
96 };
97 
98 #endif
99 
100 /* --------------------------------------------------------------------- */
101 /*  Instrucion forms                                                     */
102 /* --------------------------------------------------------------------- */
103 
104 #define S(s)		((sljit_ins)reg_map[s] << 21)
105 #define T(t)		((sljit_ins)reg_map[t] << 16)
106 #define D(d)		((sljit_ins)reg_map[d] << 11)
107 #define FT(t)		((sljit_ins)freg_map[t] << 16)
108 #define FS(s)		((sljit_ins)freg_map[s] << 11)
109 #define FD(d)		((sljit_ins)freg_map[d] << 6)
110 /* Absolute registers. */
111 #define SA(s)		((sljit_ins)(s) << 21)
112 #define TA(t)		((sljit_ins)(t) << 16)
113 #define DA(d)		((sljit_ins)(d) << 11)
114 #define IMM(imm)	((sljit_ins)(imm) & 0xffff)
115 #define SH_IMM(imm)	((sljit_ins)(imm) << 6)
116 
117 #define DR(dr)		(reg_map[dr])
118 #define FR(dr)		(freg_map[dr])
119 #define HI(opcode)	((sljit_ins)(opcode) << 26)
120 #define LO(opcode)	((sljit_ins)(opcode))
121 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
122 /* CMP.cond.fmt */
123 /* S = (20 << 21) D = (21 << 21) */
124 #define CMP_FMT_S	(20 << 21)
125 #endif /* SLJIT_MIPS_REV >= 6 */
126 /* S = (16 << 21) D = (17 << 21) */
127 #define FMT_S		(16 << 21)
128 #define FMT_D		(17 << 21)
129 
130 #define ABS_S		(HI(17) | FMT_S | LO(5))
131 #define ADD_S		(HI(17) | FMT_S | LO(0))
132 #define ADDIU		(HI(9))
133 #define ADDU		(HI(0) | LO(33))
134 #define AND		(HI(0) | LO(36))
135 #define ANDI		(HI(12))
136 #define B		(HI(4))
137 #define BAL		(HI(1) | (17 << 16))
138 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
139 #define BC1EQZ		(HI(17) | (9 << 21) | FT(TMP_FREG3))
140 #define BC1NEZ		(HI(17) | (13 << 21) | FT(TMP_FREG3))
141 #else /* SLJIT_MIPS_REV < 6 */
142 #define BC1F		(HI(17) | (8 << 21))
143 #define BC1T		(HI(17) | (8 << 21) | (1 << 16))
144 #endif /* SLJIT_MIPS_REV >= 6 */
145 #define BEQ		(HI(4))
146 #define BGEZ		(HI(1) | (1 << 16))
147 #define BGTZ		(HI(7))
148 #define BLEZ		(HI(6))
149 #define BLTZ		(HI(1) | (0 << 16))
150 #define BNE		(HI(5))
151 #define BREAK		(HI(0) | LO(13))
152 #define CFC1		(HI(17) | (2 << 21))
153 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
154 #define C_UEQ_S		(HI(17) | CMP_FMT_S | LO(3))
155 #define C_ULE_S		(HI(17) | CMP_FMT_S | LO(7))
156 #define C_ULT_S		(HI(17) | CMP_FMT_S | LO(5))
157 #define C_UN_S		(HI(17) | CMP_FMT_S | LO(1))
158 #define C_FD		(FD(TMP_FREG3))
159 #else /* SLJIT_MIPS_REV < 6 */
160 #define C_UEQ_S		(HI(17) | FMT_S | LO(51))
161 #define C_ULE_S		(HI(17) | FMT_S | LO(55))
162 #define C_ULT_S		(HI(17) | FMT_S | LO(53))
163 #define C_UN_S		(HI(17) | FMT_S | LO(49))
164 #define C_FD		(0)
165 #endif /* SLJIT_MIPS_REV >= 6 */
166 #define CVT_S_S		(HI(17) | FMT_S | LO(32))
167 #define DADDIU		(HI(25))
168 #define DADDU		(HI(0) | LO(45))
169 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
170 #define DDIV		(HI(0) | (2 << 6) | LO(30))
171 #define DDIVU		(HI(0) | (2 << 6) | LO(31))
172 #define DMOD		(HI(0) | (3 << 6) | LO(30))
173 #define DMODU		(HI(0) | (3 << 6) | LO(31))
174 #define DIV		(HI(0) | (2 << 6) | LO(26))
175 #define DIVU		(HI(0) | (2 << 6) | LO(27))
176 #define DMUH		(HI(0) | (3 << 6) | LO(28))
177 #define DMUHU		(HI(0) | (3 << 6) | LO(29))
178 #define DMUL		(HI(0) | (2 << 6) | LO(28))
179 #define DMULU		(HI(0) | (2 << 6) | LO(29))
180 #else /* SLJIT_MIPS_REV < 6 */
181 #define DDIV		(HI(0) | LO(30))
182 #define DDIVU		(HI(0) | LO(31))
183 #define DIV		(HI(0) | LO(26))
184 #define DIVU		(HI(0) | LO(27))
185 #define DMULT		(HI(0) | LO(28))
186 #define DMULTU		(HI(0) | LO(29))
187 #endif /* SLJIT_MIPS_REV >= 6 */
188 #define DIV_S		(HI(17) | FMT_S | LO(3))
189 #define DINSU		(HI(31) | LO(6))
190 #define DSLL		(HI(0) | LO(56))
191 #define DSLL32		(HI(0) | LO(60))
192 #define DSLLV		(HI(0) | LO(20))
193 #define DSRA		(HI(0) | LO(59))
194 #define DSRA32		(HI(0) | LO(63))
195 #define DSRAV		(HI(0) | LO(23))
196 #define DSRL		(HI(0) | LO(58))
197 #define DSRL32		(HI(0) | LO(62))
198 #define DSRLV		(HI(0) | LO(22))
199 #define DSUBU		(HI(0) | LO(47))
200 #define J		(HI(2))
201 #define JAL		(HI(3))
202 #define JALR		(HI(0) | LO(9))
203 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
204 #define JR		(HI(0) | LO(9))
205 #else /* SLJIT_MIPS_REV < 6 */
206 #define JR		(HI(0) | LO(8))
207 #endif /* SLJIT_MIPS_REV >= 6 */
208 #define LD		(HI(55))
209 #define LDC1		(HI(53))
210 #define LUI		(HI(15))
211 #define LW		(HI(35))
212 #define LWC1		(HI(49))
213 #define MFC1		(HI(17))
214 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
215 #define MOD		(HI(0) | (3 << 6) | LO(26))
216 #define MODU		(HI(0) | (3 << 6) | LO(27))
217 #else /* SLJIT_MIPS_REV < 6 */
218 #define MFHI		(HI(0) | LO(16))
219 #define MFLO		(HI(0) | LO(18))
220 #endif /* SLJIT_MIPS_REV >= 6 */
221 #define MOV_S		(HI(17) | FMT_S | LO(6))
222 #define MTC1		(HI(17) | (4 << 21))
223 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
224 #define MUH		(HI(0) | (3 << 6) | LO(24))
225 #define MUHU		(HI(0) | (3 << 6) | LO(25))
226 #define MUL		(HI(0) | (2 << 6) | LO(24))
227 #define MULU		(HI(0) | (2 << 6) | LO(25))
228 #else /* SLJIT_MIPS_REV < 6 */
229 #define MULT		(HI(0) | LO(24))
230 #define MULTU		(HI(0) | LO(25))
231 #endif /* SLJIT_MIPS_REV >= 6 */
232 #define MUL_S		(HI(17) | FMT_S | LO(2))
233 #define NEG_S		(HI(17) | FMT_S | LO(7))
234 #define NOP		(HI(0) | LO(0))
235 #define NOR		(HI(0) | LO(39))
236 #define OR		(HI(0) | LO(37))
237 #define ORI		(HI(13))
238 #define SD		(HI(63))
239 #define SDC1		(HI(61))
240 #define SLT		(HI(0) | LO(42))
241 #define SLTI		(HI(10))
242 #define SLTIU		(HI(11))
243 #define SLTU		(HI(0) | LO(43))
244 #define SLL		(HI(0) | LO(0))
245 #define SLLV		(HI(0) | LO(4))
246 #define SRL		(HI(0) | LO(2))
247 #define SRLV		(HI(0) | LO(6))
248 #define SRA		(HI(0) | LO(3))
249 #define SRAV		(HI(0) | LO(7))
250 #define SUB_S		(HI(17) | FMT_S | LO(1))
251 #define SUBU		(HI(0) | LO(35))
252 #define SW		(HI(43))
253 #define SWC1		(HI(57))
254 #define TRUNC_W_S	(HI(17) | FMT_S | LO(13))
255 #define XOR		(HI(0) | LO(38))
256 #define XORI		(HI(14))
257 
258 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
259 #define CLZ		(HI(28) | LO(32))
260 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
261 #define DCLZ		(LO(18))
262 #else /* SLJIT_MIPS_REV < 6 */
263 #define DCLZ		(HI(28) | LO(36))
264 #define MOVF		(HI(0) | (0 << 16) | LO(1))
265 #define MOVN		(HI(0) | LO(11))
266 #define MOVT		(HI(0) | (1 << 16) | LO(1))
267 #define MOVZ		(HI(0) | LO(10))
268 #define MUL		(HI(28) | LO(2))
269 #endif /* SLJIT_MIPS_REV >= 6 */
270 #define PREF		(HI(51))
271 #define PREFX		(HI(19) | LO(15))
272 #define SEB		(HI(31) | (16 << 6) | LO(32))
273 #define SEH		(HI(31) | (24 << 6) | LO(32))
274 #endif /* SLJIT_MIPS_REV >= 1 */
275 
276 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
277 #define ADDU_W		ADDU
278 #define ADDIU_W		ADDIU
279 #define SLL_W		SLL
280 #define SUBU_W		SUBU
281 #else
282 #define ADDU_W		DADDU
283 #define ADDIU_W		DADDIU
284 #define SLL_W		DSLL
285 #define SUBU_W		DSUBU
286 #endif
287 
288 #define SIMM_MAX	(0x7fff)
289 #define SIMM_MIN	(-0x8000)
290 #define UIMM_MAX	(0xffff)
291 
292 /* dest_reg is the absolute name of the register
293    Useful for reordering instructions in the delay slot. */
push_inst(struct sljit_compiler * compiler,sljit_ins ins,sljit_s32 delay_slot)294 static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)
295 {
296 	sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
297 	SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS
298 		|| (sljit_ins)delay_slot == ((ins >> 11) & 0x1f)
299 		|| (sljit_ins)delay_slot == ((ins >> 16) & 0x1f));
300 	FAIL_IF(!ptr);
301 	*ptr = ins;
302 	compiler->size++;
303 	compiler->delay_slot = delay_slot;
304 	return SLJIT_SUCCESS;
305 }
306 
invert_branch(sljit_uw flags)307 static SLJIT_INLINE sljit_ins invert_branch(sljit_uw flags)
308 {
309 	if (flags & IS_BIT26_COND)
310 		return (1 << 26);
311 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
312 	if (flags & IS_BIT23_COND)
313 		return (1 << 23);
314 #endif /* SLJIT_MIPS_REV >= 6 */
315 	return (1 << 16);
316 }
317 
detect_jump_type(struct sljit_jump * jump,sljit_ins * code_ptr,sljit_ins * code,sljit_sw executable_offset)318 static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
319 {
320 	sljit_sw diff;
321 	sljit_uw target_addr;
322 	sljit_ins *inst;
323 	sljit_ins saved_inst;
324 
325 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
326 	if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))
327 		return code_ptr;
328 #else
329 	if (jump->flags & SLJIT_REWRITABLE_JUMP)
330 		return code_ptr;
331 #endif
332 
333 	if (jump->flags & JUMP_ADDR)
334 		target_addr = jump->u.target;
335 	else {
336 		SLJIT_ASSERT(jump->flags & JUMP_LABEL);
337 		target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
338 	}
339 
340 	inst = (sljit_ins *)jump->addr;
341 	if (jump->flags & IS_COND)
342 		inst--;
343 
344 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
345 	if (jump->flags & IS_CALL)
346 		goto keep_address;
347 #endif
348 
349 	/* B instructions. */
350 	if (jump->flags & IS_MOVABLE) {
351 		diff = ((sljit_sw)target_addr - (sljit_sw)inst - executable_offset) >> 2;
352 		if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
353 			jump->flags |= PATCH_B;
354 
355 			if (!(jump->flags & IS_COND)) {
356 				inst[0] = inst[-1];
357 				inst[-1] = (jump->flags & IS_JAL) ? BAL : B;
358 				jump->addr -= sizeof(sljit_ins);
359 				return inst;
360 			}
361 			saved_inst = inst[0];
362 			inst[0] = inst[-1];
363 			inst[-1] = saved_inst ^ invert_branch(jump->flags);
364 			jump->addr -= 2 * sizeof(sljit_ins);
365 			return inst;
366 		}
367 	}
368 	else {
369 		diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1) - executable_offset) >> 2;
370 		if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
371 			jump->flags |= PATCH_B;
372 
373 			if (!(jump->flags & IS_COND)) {
374 				inst[0] = (jump->flags & IS_JAL) ? BAL : B;
375 				inst[1] = NOP;
376 				return inst + 1;
377 			}
378 			inst[0] ^= invert_branch(jump->flags);
379 			inst[1] = NOP;
380 			jump->addr -= sizeof(sljit_ins);
381 			return inst + 1;
382 		}
383 	}
384 
385 	if (jump->flags & IS_COND) {
386 		if ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 2 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
387 			jump->flags |= PATCH_J;
388 			saved_inst = inst[0];
389 			inst[0] = inst[-1];
390 			inst[-1] = (saved_inst & 0xffff0000) | 3;
391 			inst[1] = J;
392 			inst[2] = NOP;
393 			return inst + 2;
394 		}
395 		else if ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
396 			jump->flags |= PATCH_J;
397 			inst[0] = (inst[0] & 0xffff0000) | 3;
398 			inst[1] = NOP;
399 			inst[2] = J;
400 			inst[3] = NOP;
401 			jump->addr += sizeof(sljit_ins);
402 			return inst + 3;
403 		}
404 	}
405 	else {
406 		/* J instuctions. */
407 		if ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == (jump->addr & ~(sljit_uw)0xfffffff)) {
408 			jump->flags |= PATCH_J;
409 			inst[0] = inst[-1];
410 			inst[-1] = (jump->flags & IS_JAL) ? JAL : J;
411 			jump->addr -= sizeof(sljit_ins);
412 			return inst;
413 		}
414 
415 		if ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
416 			jump->flags |= PATCH_J;
417 			inst[0] = (jump->flags & IS_JAL) ? JAL : J;
418 			inst[1] = NOP;
419 			return inst + 1;
420 		}
421 	}
422 
423 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
424 keep_address:
425 	if (target_addr <= 0x7fffffff) {
426 		jump->flags |= PATCH_ABS32;
427 		if (jump->flags & IS_COND) {
428 			inst[0] -= 4;
429 			inst++;
430 		}
431 		inst[2] = inst[6];
432 		inst[3] = inst[7];
433 		return inst + 3;
434 	}
435 	if (target_addr <= 0x7fffffffffffl) {
436 		jump->flags |= PATCH_ABS48;
437 		if (jump->flags & IS_COND) {
438 			inst[0] -= 2;
439 			inst++;
440 		}
441 		inst[4] = inst[6];
442 		inst[5] = inst[7];
443 		return inst + 5;
444 	}
445 #endif
446 
447 	return code_ptr;
448 }
449 
450 #ifdef __GNUC__
sljit_cache_flush(void * code,void * code_ptr)451 static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr)
452 {
453 	SLJIT_CACHE_FLUSH(code, code_ptr);
454 }
455 #endif
456 
457 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
458 
put_label_get_length(struct sljit_put_label * put_label,sljit_uw max_label)459 static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
460 {
461 	if (max_label < 0x80000000l) {
462 		put_label->flags = 0;
463 		return 1;
464 	}
465 
466 	if (max_label < 0x800000000000l) {
467 		put_label->flags = 1;
468 		return 3;
469 	}
470 
471 	put_label->flags = 2;
472 	return 5;
473 }
474 
put_label_set(struct sljit_put_label * put_label)475 static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label)
476 {
477 	sljit_uw addr = put_label->label->addr;
478 	sljit_ins *inst = (sljit_ins *)put_label->addr;
479 	sljit_u32 reg = *inst;
480 
481 	if (put_label->flags == 0) {
482 		SLJIT_ASSERT(addr < 0x80000000l);
483 		inst[0] = LUI | T(reg) | IMM(addr >> 16);
484 	}
485 	else if (put_label->flags == 1) {
486 		SLJIT_ASSERT(addr < 0x800000000000l);
487 		inst[0] = LUI | T(reg) | IMM(addr >> 32);
488 		inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
489 		inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
490 		inst += 2;
491 	}
492 	else {
493 		inst[0] = LUI | T(reg) | IMM(addr >> 48);
494 		inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff);
495 		inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
496 		inst[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
497 		inst[4] = DSLL | T(reg) | D(reg) | SH_IMM(16);
498 		inst += 4;
499 	}
500 
501 	inst[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff);
502 }
503 
504 #endif
505 
sljit_generate_code(struct sljit_compiler * compiler)506 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
507 {
508 	struct sljit_memory_fragment *buf;
509 	sljit_ins *code;
510 	sljit_ins *code_ptr;
511 	sljit_ins *buf_ptr;
512 	sljit_ins *buf_end;
513 	sljit_uw word_count;
514 	sljit_uw next_addr;
515 	sljit_sw executable_offset;
516 	sljit_uw addr;
517 
518 	struct sljit_label *label;
519 	struct sljit_jump *jump;
520 	struct sljit_const *const_;
521 	struct sljit_put_label *put_label;
522 
523 	CHECK_ERROR_PTR();
524 	CHECK_PTR(check_sljit_generate_code(compiler));
525 	reverse_buf(compiler);
526 
527 	code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
528 	PTR_FAIL_WITH_EXEC_IF(code);
529 	buf = compiler->buf;
530 
531 	code_ptr = code;
532 	word_count = 0;
533 	next_addr = 0;
534 	executable_offset = SLJIT_EXEC_OFFSET(code);
535 
536 	label = compiler->labels;
537 	jump = compiler->jumps;
538 	const_ = compiler->consts;
539 	put_label = compiler->put_labels;
540 
541 	do {
542 		buf_ptr = (sljit_ins*)buf->memory;
543 		buf_end = buf_ptr + (buf->used_size >> 2);
544 		do {
545 			*code_ptr = *buf_ptr++;
546 			if (next_addr == word_count) {
547 				SLJIT_ASSERT(!label || label->size >= word_count);
548 				SLJIT_ASSERT(!jump || jump->addr >= word_count);
549 				SLJIT_ASSERT(!const_ || const_->addr >= word_count);
550 				SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
551 
552 				/* These structures are ordered by their address. */
553 				if (label && label->size == word_count) {
554 					label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
555 					label->size = (sljit_uw)(code_ptr - code);
556 					label = label->next;
557 				}
558 				if (jump && jump->addr == word_count) {
559 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
560 					jump->addr = (sljit_uw)(code_ptr - 3);
561 #else
562 					jump->addr = (sljit_uw)(code_ptr - 7);
563 #endif
564 					code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
565 					jump = jump->next;
566 				}
567 				if (const_ && const_->addr == word_count) {
568 					const_->addr = (sljit_uw)code_ptr;
569 					const_ = const_->next;
570 				}
571 				if (put_label && put_label->addr == word_count) {
572 					SLJIT_ASSERT(put_label->label);
573 					put_label->addr = (sljit_uw)code_ptr;
574 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
575 					code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
576 					word_count += 5;
577 #endif
578 					put_label = put_label->next;
579 				}
580 				next_addr = compute_next_addr(label, jump, const_, put_label);
581 			}
582 			code_ptr ++;
583 			word_count ++;
584 		} while (buf_ptr < buf_end);
585 
586 		buf = buf->next;
587 	} while (buf);
588 
589 	if (label && label->size == word_count) {
590 		label->addr = (sljit_uw)code_ptr;
591 		label->size = (sljit_uw)(code_ptr - code);
592 		label = label->next;
593 	}
594 
595 	SLJIT_ASSERT(!label);
596 	SLJIT_ASSERT(!jump);
597 	SLJIT_ASSERT(!const_);
598 	SLJIT_ASSERT(!put_label);
599 	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
600 
601 	jump = compiler->jumps;
602 	while (jump) {
603 		do {
604 			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
605 			buf_ptr = (sljit_ins *)jump->addr;
606 
607 			if (jump->flags & PATCH_B) {
608 				addr = (sljit_uw)((sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) - sizeof(sljit_ins)) >> 2);
609 				SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN);
610 				buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((sljit_ins)addr & 0xffff);
611 				break;
612 			}
613 			if (jump->flags & PATCH_J) {
614 				SLJIT_ASSERT((addr & ~(sljit_uw)0xfffffff)
615 					== (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff));
616 				buf_ptr[0] |= (sljit_ins)(addr >> 2) & 0x03ffffff;
617 				break;
618 			}
619 
620 			/* Set the fields of immediate loads. */
621 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
622 			SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1]) & 0xffff) == 0);
623 			buf_ptr[0] |= (sljit_ins)(addr >> 16) & 0xffff;
624 			buf_ptr[1] |= (sljit_ins)addr & 0xffff;
625 #else
626 			if (jump->flags & PATCH_ABS32) {
627 				SLJIT_ASSERT(addr <= 0x7fffffff);
628 				SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1]) & 0xffff) == 0);
629 				buf_ptr[0] |= (sljit_ins)(addr >> 16) & 0xffff;
630 				buf_ptr[1] |= (sljit_ins)addr & 0xffff;
631 				break;
632 			}
633 
634 			if (jump->flags & PATCH_ABS48) {
635 				SLJIT_ASSERT(addr <= 0x7fffffffffffl);
636 				SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1] | buf_ptr[3]) & 0xffff) == 0);
637 				buf_ptr[0] |= (sljit_ins)(addr >> 32) & 0xffff;
638 				buf_ptr[1] |= (sljit_ins)(addr >> 16) & 0xffff;
639 				buf_ptr[3] |= (sljit_ins)addr & 0xffff;
640 				break;
641 			}
642 
643 			SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1] | buf_ptr[3] | buf_ptr[5]) & 0xffff) == 0);
644 			buf_ptr[0] |= (sljit_ins)(addr >> 48) & 0xffff;
645 			buf_ptr[1] |= (sljit_ins)(addr >> 32) & 0xffff;
646 			buf_ptr[3] |= (sljit_ins)(addr >> 16) & 0xffff;
647 			buf_ptr[5] |= (sljit_ins)addr & 0xffff;
648 #endif
649 		} while (0);
650 		jump = jump->next;
651 	}
652 
653 	put_label = compiler->put_labels;
654 	while (put_label) {
655 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
656 		addr = put_label->label->addr;
657 		buf_ptr = (sljit_ins *)put_label->addr;
658 
659 		SLJIT_ASSERT((buf_ptr[0] & 0xffe00000) == LUI && (buf_ptr[1] & 0xfc000000) == ORI);
660 		buf_ptr[0] |= (addr >> 16) & 0xffff;
661 		buf_ptr[1] |= addr & 0xffff;
662 #else
663 		put_label_set(put_label);
664 #endif
665 		put_label = put_label->next;
666 	}
667 
668 	compiler->error = SLJIT_ERR_COMPILED;
669 	compiler->executable_offset = executable_offset;
670 	compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
671 
672 	code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
673 	code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
674 
675 #ifndef __GNUC__
676 	SLJIT_CACHE_FLUSH(code, code_ptr);
677 #else
678 	/* GCC workaround for invalid code generation with -O2. */
679 	sljit_cache_flush(code, code_ptr);
680 #endif
681 	SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
682 	return code;
683 }
684 
sljit_has_cpu_feature(sljit_s32 feature_type)685 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
686 {
687 #if defined(__GNUC__) && !defined(SLJIT_IS_FPU_AVAILABLE)
688 	sljit_sw fir = 0;
689 #endif /* __GNUC__ && !SLJIT_IS_FPU_AVAILABLE */
690 
691 	switch (feature_type) {
692 	case SLJIT_HAS_FPU:
693 #ifdef SLJIT_IS_FPU_AVAILABLE
694 		return SLJIT_IS_FPU_AVAILABLE;
695 #elif defined(__GNUC__)
696 		__asm__ ("cfc1 %0, $0" : "=r"(fir));
697 		return (fir >> 22) & 0x1;
698 #else
699 #error "FIR check is not implemented for this architecture"
700 #endif
701 	case SLJIT_HAS_ZERO_REGISTER:
702 		return 1;
703 
704 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
705 	case SLJIT_HAS_CLZ:
706 	case SLJIT_HAS_CMOV:
707 	case SLJIT_HAS_PREFETCH:
708 		return 1;
709 #endif /* SLJIT_MIPS_REV >= 1 */
710 
711 	default:
712 		return 0;
713 	}
714 }
715 
716 /* --------------------------------------------------------------------- */
717 /*  Entry, exit                                                          */
718 /* --------------------------------------------------------------------- */
719 
720 /* Creates an index in data_transfer_insts array. */
721 #define LOAD_DATA	0x01
722 #define WORD_DATA	0x00
723 #define BYTE_DATA	0x02
724 #define HALF_DATA	0x04
725 #define INT_DATA	0x06
726 #define SIGNED_DATA	0x08
727 /* Separates integer and floating point registers */
728 #define GPR_REG		0x0f
729 #define DOUBLE_DATA	0x10
730 #define SINGLE_DATA	0x12
731 
732 #define MEM_MASK	0x1f
733 
734 #define ARG_TEST	0x00020
735 #define ALT_KEEP_CACHE	0x00040
736 #define CUMULATIVE_OP	0x00080
737 #define LOGICAL_OP	0x00100
738 #define IMM_OP		0x00200
739 #define MOVE_OP		0x00400
740 #define SRC2_IMM	0x00800
741 
742 #define UNUSED_DEST	0x01000
743 #define REG_DEST	0x02000
744 #define REG1_SOURCE	0x04000
745 #define REG2_SOURCE	0x08000
746 #define SLOW_SRC1	0x10000
747 #define SLOW_SRC2	0x20000
748 #define SLOW_DEST	0x40000
749 
750 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
751 #define STACK_STORE	SW
752 #define STACK_LOAD	LW
753 #else
754 #define STACK_STORE	SD
755 #define STACK_LOAD	LD
756 #endif
757 
758 static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw);
759 static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr);
760 
761 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
762 #include "sljitNativeMIPS_32.c"
763 #else
764 #include "sljitNativeMIPS_64.c"
765 #endif
766 
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)767 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
768 	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
769 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
770 {
771 	sljit_ins base;
772 	sljit_s32 i, tmp, offset;
773 	sljit_s32 arg_count, word_arg_count, saved_arg_count, float_arg_count;
774 
775 	CHECK_ERROR();
776 	CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
777 	set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
778 
779 	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
780 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
781 	if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
782 		if ((local_size & SSIZE_OF(sw)) != 0)
783 			local_size += SSIZE_OF(sw);
784 		local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
785 	}
786 
787 	local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
788 #else
789 	local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
790 	local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
791 #endif
792 	compiler->local_size = local_size;
793 
794 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
795 	tmp = arg_types >> SLJIT_ARG_SHIFT;
796 	arg_count = 0;
797 	offset = 0;
798 
799 	while (tmp) {
800 		offset = arg_count;
801 		if ((tmp & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F64) {
802 			if ((arg_count & 0x1) != 0)
803 				arg_count++;
804 			arg_count++;
805 		}
806 
807 		arg_count++;
808 		tmp >>= SLJIT_ARG_SHIFT;
809 	}
810 
811 	compiler->args_size = (sljit_uw)arg_count << 2;
812 	offset = (offset >= 4) ? (offset << 2) : 0;
813 #else /* !SLJIT_CONFIG_MIPS_32 */
814 	offset = 0;
815 #endif /* SLJIT_CONFIG_MIPS_32 */
816 
817 	if (local_size + offset <= -SIMM_MIN) {
818 		/* Frequent case. */
819 		FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP)));
820 		base = S(SLJIT_SP);
821 		offset = local_size - SSIZE_OF(sw);
822 	} else {
823 		FAIL_IF(load_immediate(compiler, DR(OTHER_FLAG), local_size));
824 		FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
825 		FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | T(OTHER_FLAG) | D(SLJIT_SP), DR(SLJIT_SP)));
826 		base = S(TMP_REG2);
827 		offset = -SSIZE_OF(sw);
828 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
829 		local_size = 0;
830 #endif
831 	}
832 
833 	FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(offset), MOVABLE_INS));
834 
835 	tmp = SLJIT_S0 - saveds;
836 	for (i = SLJIT_S0; i > tmp; i--) {
837 		offset -= SSIZE_OF(sw);
838 		FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offset), MOVABLE_INS));
839 	}
840 
841 	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
842 		offset -= SSIZE_OF(sw);
843 		FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offset), MOVABLE_INS));
844 	}
845 
846 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
847 	/* This alignment is valid because offset is not used after storing FPU regs. */
848 	if ((offset & SSIZE_OF(sw)) != 0)
849 		offset -= SSIZE_OF(sw);
850 #endif
851 
852 	tmp = SLJIT_FS0 - fsaveds;
853 	for (i = SLJIT_FS0; i > tmp; i--) {
854 		offset -= SSIZE_OF(f64);
855 		FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
856 	}
857 
858 	for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
859 		offset -= SSIZE_OF(f64);
860 		FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
861 	}
862 
863 	arg_types >>= SLJIT_ARG_SHIFT;
864 	arg_count = 0;
865 	word_arg_count = 0;
866 	saved_arg_count = 0;
867 	float_arg_count = 0;
868 
869 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
870 	/* The first maximum two floating point arguments are passed in floating point
871 	   registers if no integer argument precedes them. The first 16 byte data is
872 	   passed in four integer registers, the rest is placed onto the stack.
873 	   The floating point registers are also part of the first 16 byte data, so
874 	   their corresponding integer registers are not used when they are present. */
875 
876 	while (arg_types) {
877 		switch (arg_types & SLJIT_ARG_MASK) {
878 		case SLJIT_ARG_TYPE_F64:
879 			float_arg_count++;
880 			if ((arg_count & 0x1) != 0)
881 				arg_count++;
882 
883 			if (word_arg_count == 0 && float_arg_count <= 2) {
884 				if (float_arg_count == 1)
885 					FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
886 			} else if (arg_count < 4) {
887 				FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
888 				FAIL_IF(push_inst(compiler, MTC1 | TA(5 + arg_count) | FS(float_arg_count) | (1 << 11), MOVABLE_INS));
889 			} else
890 				FAIL_IF(push_inst(compiler, LDC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
891 			arg_count++;
892 			break;
893 		case SLJIT_ARG_TYPE_F32:
894 			float_arg_count++;
895 
896 			if (word_arg_count == 0 && float_arg_count <= 2) {
897 				if (float_arg_count == 1)
898 					FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
899 			} else if (arg_count < 4)
900 				FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
901 			else
902 				FAIL_IF(push_inst(compiler, LWC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
903 			break;
904 		default:
905 			word_arg_count++;
906 
907 			if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
908 				tmp = SLJIT_S0 - saved_arg_count;
909 				saved_arg_count++;
910 			} else if (word_arg_count != arg_count + 1 || arg_count == 0)
911 				tmp = word_arg_count;
912 			else
913 				break;
914 
915 			if (arg_count < 4)
916 				FAIL_IF(push_inst(compiler, ADDU_W | SA(4 + arg_count) | TA(0) | D(tmp), DR(tmp)));
917 			else
918 				FAIL_IF(push_inst(compiler, LW | base | T(tmp) | IMM(local_size + (arg_count << 2)), DR(tmp)));
919 			break;
920 		}
921 		arg_count++;
922 		arg_types >>= SLJIT_ARG_SHIFT;
923 	}
924 
925 	SLJIT_ASSERT(compiler->args_size == (sljit_uw)arg_count << 2);
926 #else /* !SLJIT_CONFIG_MIPS_32 */
927 	while (arg_types) {
928 		arg_count++;
929 		switch (arg_types & SLJIT_ARG_MASK) {
930 		case SLJIT_ARG_TYPE_F64:
931 			float_arg_count++;
932 			if (arg_count != float_arg_count)
933 				FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
934 			else if (arg_count == 1)
935 				FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
936 			break;
937 		case SLJIT_ARG_TYPE_F32:
938 			float_arg_count++;
939 			if (arg_count != float_arg_count)
940 				FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
941 			else if (arg_count == 1)
942 				FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
943 			break;
944 		default:
945 			word_arg_count++;
946 
947 			if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
948 				tmp = SLJIT_S0 - saved_arg_count;
949 				saved_arg_count++;
950 			} else if (word_arg_count != arg_count || word_arg_count <= 1)
951 				tmp = word_arg_count;
952 			else
953 				break;
954 
955 			FAIL_IF(push_inst(compiler, ADDU_W | SA(3 + arg_count) | TA(0) | D(tmp), DR(tmp)));
956 			break;
957 		}
958 		arg_types >>= SLJIT_ARG_SHIFT;
959 	}
960 #endif /* SLJIT_CONFIG_MIPS_32 */
961 
962 	return SLJIT_SUCCESS;
963 }
964 
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)965 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
966 	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
967 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
968 {
969 	CHECK_ERROR();
970 	CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
971 	set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
972 
973 	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
974 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
975 	if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
976 		if ((local_size & SSIZE_OF(sw)) != 0)
977 			local_size += SSIZE_OF(sw);
978 		local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
979 	}
980 
981 	compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
982 #else
983 	local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
984 	compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
985 #endif
986 	return SLJIT_SUCCESS;
987 }
988 
emit_stack_frame_release(struct sljit_compiler * compiler,sljit_s32 frame_size,sljit_ins * ins_ptr)989 static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr)
990 {
991 	sljit_s32 local_size, i, tmp, offset;
992 	sljit_s32 scratches = compiler->scratches;
993 	sljit_s32 saveds = compiler->saveds;
994 	sljit_s32 fsaveds = compiler->fsaveds;
995 	sljit_s32 fscratches = compiler->fscratches;
996 
997 	local_size = compiler->local_size;
998 
999 	tmp = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
1000 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1001 	if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
1002 		if ((tmp & SSIZE_OF(sw)) != 0)
1003 			tmp += SSIZE_OF(sw);
1004 		tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
1005 	}
1006 #else
1007 	tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
1008 #endif
1009 
1010 	if (local_size <= SIMM_MAX) {
1011 		if (local_size < frame_size) {
1012 			FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size), DR(SLJIT_SP)));
1013 			local_size = frame_size;
1014 		}
1015 	} else {
1016 		if (tmp < frame_size)
1017 			tmp = frame_size;
1018 
1019 		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size - tmp));
1020 		FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG1) | D(SLJIT_SP), DR(SLJIT_SP)));
1021 		local_size = tmp;
1022 	}
1023 
1024 	SLJIT_ASSERT(local_size >= frame_size);
1025 
1026 	offset = local_size - SSIZE_OF(sw);
1027 	if (frame_size == 0)
1028 		FAIL_IF(push_inst(compiler, STACK_LOAD | S(SLJIT_SP) | TA(RETURN_ADDR_REG) | IMM(offset), RETURN_ADDR_REG));
1029 
1030 	tmp = SLJIT_S0 - saveds;
1031 	for (i = SLJIT_S0; i > tmp; i--) {
1032 		offset -= SSIZE_OF(sw);
1033 		FAIL_IF(push_inst(compiler, STACK_LOAD | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
1034 	}
1035 
1036 	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
1037 		offset -= SSIZE_OF(sw);
1038 		FAIL_IF(push_inst(compiler, STACK_LOAD | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
1039 	}
1040 
1041 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1042 	/* This alignment is valid because offset is not used after storing FPU regs. */
1043 	if ((offset & SSIZE_OF(sw)) != 0)
1044 		offset -= SSIZE_OF(sw);
1045 #endif
1046 
1047 	tmp = SLJIT_FS0 - fsaveds;
1048 	for (i = SLJIT_FS0; i > tmp; i--) {
1049 		offset -= SSIZE_OF(f64);
1050 		FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
1051 	}
1052 
1053 	for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
1054 		offset -= SSIZE_OF(f64);
1055 		FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
1056 	}
1057 
1058 	if (local_size > frame_size)
1059 		*ins_ptr = ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size);
1060 	else
1061 		*ins_ptr = NOP;
1062 
1063 	return SLJIT_SUCCESS;
1064 }
1065 
sljit_emit_return_void(struct sljit_compiler * compiler)1066 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
1067 {
1068 	sljit_ins ins;
1069 
1070 	CHECK_ERROR();
1071 	CHECK(check_sljit_emit_return_void(compiler));
1072 
1073 	emit_stack_frame_release(compiler, 0, &ins);
1074 
1075 	FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
1076 	return push_inst(compiler, ins, UNMOVABLE_INS);
1077 }
1078 
1079 #undef STACK_STORE
1080 #undef STACK_LOAD
1081 
1082 /* --------------------------------------------------------------------- */
1083 /*  Operators                                                            */
1084 /* --------------------------------------------------------------------- */
1085 
1086 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1087 #define ARCH_32_64(a, b)	a
1088 #else
1089 #define ARCH_32_64(a, b)	b
1090 #endif
1091 
1092 static const sljit_ins data_transfer_insts[16 + 4] = {
1093 /* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
1094 /* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
1095 /* u b s */ HI(40) /* sb */,
1096 /* u b l */ HI(36) /* lbu */,
1097 /* u h s */ HI(41) /* sh */,
1098 /* u h l */ HI(37) /* lhu */,
1099 /* u i s */ HI(43) /* sw */,
1100 /* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */),
1101 
1102 /* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
1103 /* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
1104 /* s b s */ HI(40) /* sb */,
1105 /* s b l */ HI(32) /* lb */,
1106 /* s h s */ HI(41) /* sh */,
1107 /* s h l */ HI(33) /* lh */,
1108 /* s i s */ HI(43) /* sw */,
1109 /* s i l */ HI(35) /* lw */,
1110 
1111 /* d   s */ HI(61) /* sdc1 */,
1112 /* d   l */ HI(53) /* ldc1 */,
1113 /* s   s */ HI(57) /* swc1 */,
1114 /* s   l */ HI(49) /* lwc1 */,
1115 };
1116 
1117 #undef ARCH_32_64
1118 
1119 /* reg_ar is an absoulute register! */
1120 
1121 /* 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)1122 static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
1123 {
1124 	SLJIT_ASSERT(arg & SLJIT_MEM);
1125 
1126 	if (!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
1127 		/* Works for both absoulte and relative addresses. */
1128 		if (SLJIT_UNLIKELY(flags & ARG_TEST))
1129 			return 1;
1130 		FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & REG_MASK)
1131 			| TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS));
1132 		return -1;
1133 	}
1134 	return 0;
1135 }
1136 
1137 /* See getput_arg below.
1138    Note: can_cache is called only for binary operators. Those
1139    operators always uses word arguments without write back. */
can_cache(sljit_s32 arg,sljit_sw argw,sljit_s32 next_arg,sljit_sw next_argw)1140 static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
1141 {
1142 	SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
1143 
1144 	/* Simple operation except for updates. */
1145 	if (arg & OFFS_REG_MASK) {
1146 		argw &= 0x3;
1147 		next_argw &= 0x3;
1148 		if (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))
1149 			return 1;
1150 		return 0;
1151 	}
1152 
1153 	if (arg == next_arg) {
1154 		if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN))
1155 			return 1;
1156 		return 0;
1157 	}
1158 
1159 	return 0;
1160 }
1161 
1162 /* 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)1163 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)
1164 {
1165 	sljit_s32 tmp_ar, base, delay_slot;
1166 
1167 	SLJIT_ASSERT(arg & SLJIT_MEM);
1168 	if (!(next_arg & SLJIT_MEM)) {
1169 		next_arg = 0;
1170 		next_argw = 0;
1171 	}
1172 
1173 	if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
1174 		tmp_ar = reg_ar;
1175 		delay_slot = reg_ar;
1176 	}
1177 	else {
1178 		tmp_ar = DR(TMP_REG1);
1179 		delay_slot = MOVABLE_INS;
1180 	}
1181 	base = arg & REG_MASK;
1182 
1183 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
1184 		argw &= 0x3;
1185 
1186 		/* Using the cache. */
1187 		if (argw == compiler->cache_argw) {
1188 			if (arg == compiler->cache_arg)
1189 				return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
1190 
1191 			if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
1192 				if (arg == next_arg && argw == (next_argw & 0x3)) {
1193 					compiler->cache_arg = arg;
1194 					compiler->cache_argw = argw;
1195 					FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
1196 					return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
1197 				}
1198 				FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar));
1199 				return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1200 			}
1201 		}
1202 
1203 		if (SLJIT_UNLIKELY(argw)) {
1204 			compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
1205 			compiler->cache_argw = argw;
1206 			FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3)));
1207 		}
1208 
1209 		if (arg == next_arg && argw == (next_argw & 0x3)) {
1210 			compiler->cache_arg = arg;
1211 			compiler->cache_argw = argw;
1212 			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
1213 			tmp_ar = DR(TMP_REG3);
1214 		}
1215 		else
1216 			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | DA(tmp_ar), tmp_ar));
1217 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1218 	}
1219 
1220 	if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
1221 		if (argw != compiler->cache_argw) {
1222 			FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
1223 			compiler->cache_argw = argw;
1224 		}
1225 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
1226 	}
1227 
1228 	if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
1229 		if (argw != compiler->cache_argw)
1230 			FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
1231 	}
1232 	else {
1233 		compiler->cache_arg = SLJIT_MEM;
1234 		FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
1235 	}
1236 	compiler->cache_argw = argw;
1237 
1238 	if (!base)
1239 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
1240 
1241 	if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) {
1242 		compiler->cache_arg = arg;
1243 		FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3)));
1244 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
1245 	}
1246 
1247 	FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar));
1248 	return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1249 }
1250 
emit_op_mem(struct sljit_compiler * compiler,sljit_s32 flags,sljit_s32 reg_ar,sljit_s32 arg,sljit_sw argw)1251 static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
1252 {
1253 	sljit_s32 tmp_ar, base, delay_slot;
1254 
1255 	if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
1256 		return compiler->error;
1257 
1258 	if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
1259 		tmp_ar = reg_ar;
1260 		delay_slot = reg_ar;
1261 	}
1262 	else {
1263 		tmp_ar = DR(TMP_REG1);
1264 		delay_slot = MOVABLE_INS;
1265 	}
1266 	base = arg & REG_MASK;
1267 
1268 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
1269 		argw &= 0x3;
1270 
1271 		if (SLJIT_UNLIKELY(argw)) {
1272 			FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | DA(tmp_ar) | SH_IMM(argw), tmp_ar));
1273 			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | TA(tmp_ar) | DA(tmp_ar), tmp_ar));
1274 		}
1275 		else
1276 			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(OFFS_REG(arg)) | DA(tmp_ar), tmp_ar));
1277 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1278 	}
1279 
1280 	FAIL_IF(load_immediate(compiler, tmp_ar, argw));
1281 
1282 	if (base != 0)
1283 		FAIL_IF(push_inst(compiler, ADDU_W | S(base) | TA(tmp_ar) | DA(tmp_ar), tmp_ar));
1284 
1285 	return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1286 }
1287 
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)1288 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)
1289 {
1290 	if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
1291 		return compiler->error;
1292 	return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
1293 }
1294 
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)1295 static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
1296 	sljit_s32 dst, sljit_sw dstw,
1297 	sljit_s32 src1, sljit_sw src1w,
1298 	sljit_s32 src2, sljit_sw src2w)
1299 {
1300 	/* arg1 goes to TMP_REG1 or src reg
1301 	   arg2 goes to TMP_REG2, imm or src reg
1302 	   TMP_REG3 can be used for caching
1303 	   result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
1304 	sljit_s32 dst_r = TMP_REG2;
1305 	sljit_s32 src1_r;
1306 	sljit_sw src2_r = 0;
1307 	sljit_s32 sugg_src2_r = TMP_REG2;
1308 
1309 	if (!(flags & ALT_KEEP_CACHE)) {
1310 		compiler->cache_arg = 0;
1311 		compiler->cache_argw = 0;
1312 	}
1313 
1314 	if (dst == TMP_REG2) {
1315 		SLJIT_ASSERT(HAS_FLAGS(op));
1316 		flags |= UNUSED_DEST;
1317 	}
1318 	else if (FAST_IS_REG(dst)) {
1319 		dst_r = dst;
1320 		flags |= REG_DEST;
1321 		if (flags & MOVE_OP)
1322 			sugg_src2_r = dst_r;
1323 	}
1324 	else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))
1325 		flags |= SLOW_DEST;
1326 
1327 	if (flags & IMM_OP) {
1328 		if ((src2 & SLJIT_IMM) && src2w) {
1329 			if ((!(flags & LOGICAL_OP) && (src2w <= SIMM_MAX && src2w >= SIMM_MIN))
1330 				|| ((flags & LOGICAL_OP) && !(src2w & ~UIMM_MAX))) {
1331 				flags |= SRC2_IMM;
1332 				src2_r = src2w;
1333 			}
1334 		}
1335 		if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {
1336 			if ((!(flags & LOGICAL_OP) && (src1w <= SIMM_MAX && src1w >= SIMM_MIN))
1337 				|| ((flags & LOGICAL_OP) && !(src1w & ~UIMM_MAX))) {
1338 				flags |= SRC2_IMM;
1339 				src2_r = src1w;
1340 
1341 				/* And swap arguments. */
1342 				src1 = src2;
1343 				src1w = src2w;
1344 				src2 = SLJIT_IMM;
1345 				/* src2w = src2_r unneeded. */
1346 			}
1347 		}
1348 	}
1349 
1350 	/* Source 1. */
1351 	if (FAST_IS_REG(src1)) {
1352 		src1_r = src1;
1353 		flags |= REG1_SOURCE;
1354 	}
1355 	else if (src1 & SLJIT_IMM) {
1356 		if (src1w) {
1357 			FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
1358 			src1_r = TMP_REG1;
1359 		}
1360 		else
1361 			src1_r = 0;
1362 	}
1363 	else {
1364 		if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w))
1365 			FAIL_IF(compiler->error);
1366 		else
1367 			flags |= SLOW_SRC1;
1368 		src1_r = TMP_REG1;
1369 	}
1370 
1371 	/* Source 2. */
1372 	if (FAST_IS_REG(src2)) {
1373 		src2_r = src2;
1374 		flags |= REG2_SOURCE;
1375 		if ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP)
1376 			dst_r = (sljit_s32)src2_r;
1377 	}
1378 	else if (src2 & SLJIT_IMM) {
1379 		if (!(flags & SRC2_IMM)) {
1380 			if (src2w) {
1381 				FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w));
1382 				src2_r = sugg_src2_r;
1383 			}
1384 			else {
1385 				src2_r = 0;
1386 				if (flags & MOVE_OP) {
1387 					if (dst & SLJIT_MEM)
1388 						dst_r = 0;
1389 					else
1390 						op = SLJIT_MOV;
1391 				}
1392 			}
1393 		}
1394 	}
1395 	else {
1396 		if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w))
1397 			FAIL_IF(compiler->error);
1398 		else
1399 			flags |= SLOW_SRC2;
1400 		src2_r = sugg_src2_r;
1401 	}
1402 
1403 	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
1404 		SLJIT_ASSERT(src2_r == TMP_REG2);
1405 		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
1406 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));
1407 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
1408 		}
1409 		else {
1410 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w));
1411 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw));
1412 		}
1413 	}
1414 	else if (flags & SLOW_SRC1)
1415 		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
1416 	else if (flags & SLOW_SRC2)
1417 		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w, dst, dstw));
1418 
1419 	FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
1420 
1421 	if (dst & SLJIT_MEM) {
1422 		if (!(flags & SLOW_DEST)) {
1423 			getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw);
1424 			return compiler->error;
1425 		}
1426 		return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0);
1427 	}
1428 
1429 	return SLJIT_SUCCESS;
1430 }
1431 
sljit_emit_op0(struct sljit_compiler * compiler,sljit_s32 op)1432 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
1433 {
1434 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1435 	sljit_s32 int_op = op & SLJIT_32;
1436 #endif
1437 
1438 	CHECK_ERROR();
1439 	CHECK(check_sljit_emit_op0(compiler, op));
1440 
1441 	op = GET_OPCODE(op);
1442 	switch (op) {
1443 	case SLJIT_BREAKPOINT:
1444 		return push_inst(compiler, BREAK, UNMOVABLE_INS);
1445 	case SLJIT_NOP:
1446 		return push_inst(compiler, NOP, UNMOVABLE_INS);
1447 	case SLJIT_LMUL_UW:
1448 	case SLJIT_LMUL_SW:
1449 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1450 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1451 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULU : DMUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
1452 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMUHU : DMUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
1453 #else /* !SLJIT_CONFIG_MIPS_64 */
1454 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULU : MUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
1455 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MUHU : MUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
1456 #endif /* SLJIT_CONFIG_MIPS_64 */
1457 		FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
1458 		return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
1459 #else /* SLJIT_MIPS_REV < 6 */
1460 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1461 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
1462 #else /* !SLJIT_CONFIG_MIPS_64 */
1463 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
1464 #endif /* SLJIT_CONFIG_MIPS_64 */
1465 		FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
1466 		return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
1467 #endif /* SLJIT_MIPS_REV >= 6 */
1468 	case SLJIT_DIVMOD_UW:
1469 	case SLJIT_DIVMOD_SW:
1470 	case SLJIT_DIV_UW:
1471 	case SLJIT_DIV_SW:
1472 		SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
1473 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1474 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1475 		if (int_op) {
1476 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
1477 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
1478 		}
1479 		else {
1480 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
1481 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DMODU : DMOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
1482 		}
1483 #else /* !SLJIT_CONFIG_MIPS_64 */
1484 		FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
1485 		FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
1486 #endif /* SLJIT_CONFIG_MIPS_64 */
1487 		FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
1488 		return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
1489 #else /* SLJIT_MIPS_REV < 6 */
1490 #if !(defined SLJIT_MIPS_REV)
1491 		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
1492 		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
1493 #endif /* !SLJIT_MIPS_REV */
1494 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1495 		if (int_op)
1496 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
1497 		else
1498 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
1499 #else /* !SLJIT_CONFIG_MIPS_64 */
1500 		FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
1501 #endif /* SLJIT_CONFIG_MIPS_64 */
1502 		FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
1503 		return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
1504 #endif /* SLJIT_MIPS_REV >= 6 */
1505 	case SLJIT_ENDBR:
1506 	case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
1507 		return SLJIT_SUCCESS;
1508 	}
1509 
1510 	return SLJIT_SUCCESS;
1511 }
1512 
1513 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
emit_prefetch(struct sljit_compiler * compiler,sljit_s32 src,sljit_sw srcw)1514 static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
1515         sljit_s32 src, sljit_sw srcw)
1516 {
1517 	if (!(src & OFFS_REG_MASK)) {
1518 		if (srcw <= SIMM_MAX && srcw >= SIMM_MIN)
1519 			return push_inst(compiler, PREF | S(src & REG_MASK) | IMM(srcw), MOVABLE_INS);
1520 
1521 		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
1522 		return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
1523 	}
1524 
1525 	srcw &= 0x3;
1526 
1527 	if (SLJIT_UNLIKELY(srcw != 0)) {
1528 		FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(src)) | D(TMP_REG1) | SH_IMM(srcw), DR(TMP_REG1)));
1529 		return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
1530 	}
1531 
1532 	return push_inst(compiler, PREFX | S(src & REG_MASK) | T(OFFS_REG(src)), MOVABLE_INS);
1533 }
1534 #endif /* SLJIT_MIPS_REV >= 1 */
1535 
sljit_emit_op1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1536 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
1537 	sljit_s32 dst, sljit_sw dstw,
1538 	sljit_s32 src, sljit_sw srcw)
1539 {
1540 	sljit_s32 flags = 0;
1541 
1542 	CHECK_ERROR();
1543 	CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
1544 	ADJUST_LOCAL_OFFSET(dst, dstw);
1545 	ADJUST_LOCAL_OFFSET(src, srcw);
1546 
1547 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1548 	if (op & SLJIT_32)
1549 		flags = INT_DATA | SIGNED_DATA;
1550 #endif
1551 
1552 	switch (GET_OPCODE(op)) {
1553 	case SLJIT_MOV:
1554 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1555 	case SLJIT_MOV_U32:
1556 	case SLJIT_MOV_S32:
1557 	case SLJIT_MOV32:
1558 #endif
1559 	case SLJIT_MOV_P:
1560 		return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, srcw);
1561 
1562 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1563 	case SLJIT_MOV_U32:
1564 		return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw);
1565 
1566 	case SLJIT_MOV_S32:
1567 	case SLJIT_MOV32:
1568 		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);
1569 #endif
1570 
1571 	case SLJIT_MOV_U8:
1572 		return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
1573 
1574 	case SLJIT_MOV_S8:
1575 		return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
1576 
1577 	case SLJIT_MOV_U16:
1578 		return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
1579 
1580 	case SLJIT_MOV_S16:
1581 		return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
1582 
1583 	case SLJIT_NOT:
1584 		return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
1585 
1586 	case SLJIT_CLZ:
1587 		return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
1588 	}
1589 
1590 	SLJIT_UNREACHABLE();
1591 	return SLJIT_SUCCESS;
1592 }
1593 
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)1594 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
1595 	sljit_s32 dst, sljit_sw dstw,
1596 	sljit_s32 src1, sljit_sw src1w,
1597 	sljit_s32 src2, sljit_sw src2w)
1598 {
1599 	sljit_s32 flags = 0;
1600 
1601 	CHECK_ERROR();
1602 	CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
1603 	ADJUST_LOCAL_OFFSET(dst, dstw);
1604 	ADJUST_LOCAL_OFFSET(src1, src1w);
1605 	ADJUST_LOCAL_OFFSET(src2, src2w);
1606 
1607 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1608 	if (op & SLJIT_32) {
1609 		flags |= INT_DATA | SIGNED_DATA;
1610 		if (src1 & SLJIT_IMM)
1611 			src1w = (sljit_s32)src1w;
1612 		if (src2 & SLJIT_IMM)
1613 			src2w = (sljit_s32)src2w;
1614 	}
1615 #endif
1616 
1617 	switch (GET_OPCODE(op)) {
1618 	case SLJIT_ADD:
1619 	case SLJIT_ADDC:
1620 		compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
1621 		return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
1622 
1623 	case SLJIT_SUB:
1624 	case SLJIT_SUBC:
1625 		compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
1626 		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
1627 
1628 	case SLJIT_MUL:
1629 		compiler->status_flags_state = 0;
1630 		return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
1631 
1632 	case SLJIT_AND:
1633 	case SLJIT_OR:
1634 	case SLJIT_XOR:
1635 		return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
1636 
1637 	case SLJIT_SHL:
1638 	case SLJIT_LSHR:
1639 	case SLJIT_ASHR:
1640 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1641 		if (src2 & SLJIT_IMM)
1642 			src2w &= 0x1f;
1643 #else
1644 		if (src2 & SLJIT_IMM) {
1645 			if (op & SLJIT_32)
1646 				src2w &= 0x1f;
1647 			else
1648 				src2w &= 0x3f;
1649 		}
1650 #endif
1651 		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
1652 	}
1653 
1654 	SLJIT_UNREACHABLE();
1655 	return SLJIT_SUCCESS;
1656 }
1657 
sljit_emit_op2u(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)1658 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
1659 	sljit_s32 src1, sljit_sw src1w,
1660 	sljit_s32 src2, sljit_sw src2w)
1661 {
1662 	CHECK_ERROR();
1663 	CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
1664 
1665 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
1666 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1667 	compiler->skip_checks = 1;
1668 #endif
1669 	return sljit_emit_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w);
1670 }
1671 
sljit_emit_op_src(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)1672 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
1673 	sljit_s32 src, sljit_sw srcw)
1674 {
1675 	CHECK_ERROR();
1676 	CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
1677 	ADJUST_LOCAL_OFFSET(src, srcw);
1678 
1679 	switch (op) {
1680 	case SLJIT_FAST_RETURN:
1681 		if (FAST_IS_REG(src))
1682 			FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
1683 		else
1684 			FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
1685 
1686 		FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
1687 		return push_inst(compiler, NOP, UNMOVABLE_INS);
1688 	case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
1689 		return SLJIT_SUCCESS;
1690 	case SLJIT_PREFETCH_L1:
1691 	case SLJIT_PREFETCH_L2:
1692 	case SLJIT_PREFETCH_L3:
1693 	case SLJIT_PREFETCH_ONCE:
1694 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1695 		return emit_prefetch(compiler, src, srcw);
1696 #else /* SLJIT_MIPS_REV < 1 */
1697 		return SLJIT_SUCCESS;
1698 #endif /* SLJIT_MIPS_REV >= 1 */
1699 	}
1700 
1701 	return SLJIT_SUCCESS;
1702 }
1703 
sljit_get_register_index(sljit_s32 reg)1704 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
1705 {
1706 	CHECK_REG_INDEX(check_sljit_get_register_index(reg));
1707 	return reg_map[reg];
1708 }
1709 
sljit_get_float_register_index(sljit_s32 reg)1710 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
1711 {
1712 	CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
1713 	return FR(reg);
1714 }
1715 
sljit_emit_op_custom(struct sljit_compiler * compiler,void * instruction,sljit_u32 size)1716 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
1717 	void *instruction, sljit_u32 size)
1718 {
1719 	CHECK_ERROR();
1720 	CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
1721 
1722 	return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
1723 }
1724 
1725 /* --------------------------------------------------------------------- */
1726 /*  Floating point operators                                             */
1727 /* --------------------------------------------------------------------- */
1728 
1729 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7))
1730 #define FMT(op) ((((sljit_ins)op & SLJIT_32) ^ SLJIT_32) << (21 - 8))
1731 
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)1732 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
1733 	sljit_s32 dst, sljit_sw dstw,
1734 	sljit_s32 src, sljit_sw srcw)
1735 {
1736 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1737 #	define flags (sljit_u32)0
1738 #else
1739 	sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)) << 21;
1740 #endif
1741 
1742 	if (src & SLJIT_MEM) {
1743 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
1744 		src = TMP_FREG1;
1745 	}
1746 
1747 	FAIL_IF(push_inst(compiler, (TRUNC_W_S ^ (flags >> 19)) | FMT(op) | FS(src) | FD(TMP_FREG1), MOVABLE_INS));
1748 
1749 	if (FAST_IS_REG(dst))
1750 		return push_inst(compiler, MFC1 | flags | T(dst) | FS(TMP_FREG1), MOVABLE_INS);
1751 
1752 	/* Store the integer value from a VFP register. */
1753 	return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, FR(TMP_FREG1), dst, dstw, 0, 0);
1754 
1755 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1756 #	undef is_long
1757 #endif
1758 }
1759 
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)1760 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
1761 	sljit_s32 dst, sljit_sw dstw,
1762 	sljit_s32 src, sljit_sw srcw)
1763 {
1764 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1765 #	define flags (sljit_u32)0
1766 #else
1767 	sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)) << 21;
1768 #endif
1769 
1770 	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1771 
1772 	if (FAST_IS_REG(src))
1773 		FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS));
1774 	else if (src & SLJIT_MEM) {
1775 		/* Load the integer value into a VFP register. */
1776 		FAIL_IF(emit_op_mem2(compiler, ((flags) ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
1777 	}
1778 	else {
1779 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1780 		if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
1781 			srcw = (sljit_s32)srcw;
1782 #endif
1783 		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
1784 		FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS));
1785 	}
1786 
1787 	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));
1788 
1789 	if (dst & SLJIT_MEM)
1790 		return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
1791 	return SLJIT_SUCCESS;
1792 
1793 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1794 #	undef flags
1795 #endif
1796 }
1797 
sljit_emit_fop1_cmp(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)1798 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
1799 	sljit_s32 src1, sljit_sw src1w,
1800 	sljit_s32 src2, sljit_sw src2w)
1801 {
1802 	sljit_ins inst;
1803 
1804 	if (src1 & SLJIT_MEM) {
1805 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
1806 		src1 = TMP_FREG1;
1807 	}
1808 
1809 	if (src2 & SLJIT_MEM) {
1810 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, 0, 0));
1811 		src2 = TMP_FREG2;
1812 	}
1813 
1814 	switch (GET_FLAG_TYPE(op)) {
1815 	case SLJIT_EQUAL_F64:
1816 	case SLJIT_NOT_EQUAL_F64:
1817 		inst = C_UEQ_S;
1818 		break;
1819 	case SLJIT_LESS_F64:
1820 	case SLJIT_GREATER_EQUAL_F64:
1821 		inst = C_ULT_S;
1822 		break;
1823 	case SLJIT_GREATER_F64:
1824 	case SLJIT_LESS_EQUAL_F64:
1825 		inst = C_ULE_S;
1826 		break;
1827 	default:
1828 		SLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_UNORDERED_F64 || GET_FLAG_TYPE(op) == SLJIT_ORDERED_F64);
1829 		inst = C_UN_S;
1830 		break;
1831 	}
1832 	return push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1) | C_FD, UNMOVABLE_INS);
1833 }
1834 
sljit_emit_fop1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1835 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
1836 	sljit_s32 dst, sljit_sw dstw,
1837 	sljit_s32 src, sljit_sw srcw)
1838 {
1839 	sljit_s32 dst_r;
1840 
1841 	CHECK_ERROR();
1842 	compiler->cache_arg = 0;
1843 	compiler->cache_argw = 0;
1844 
1845 	SLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
1846 	SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
1847 
1848 	if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
1849 		op ^= SLJIT_32;
1850 
1851 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1852 
1853 	if (src & SLJIT_MEM) {
1854 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(dst_r), src, srcw, dst, dstw));
1855 		src = dst_r;
1856 	}
1857 
1858 	switch (GET_OPCODE(op)) {
1859 	case SLJIT_MOV_F64:
1860 		if (src != dst_r) {
1861 			if (dst_r != TMP_FREG1)
1862 				FAIL_IF(push_inst(compiler, MOV_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
1863 			else
1864 				dst_r = src;
1865 		}
1866 		break;
1867 	case SLJIT_NEG_F64:
1868 		FAIL_IF(push_inst(compiler, NEG_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
1869 		break;
1870 	case SLJIT_ABS_F64:
1871 		FAIL_IF(push_inst(compiler, ABS_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
1872 		break;
1873 	case SLJIT_CONV_F64_FROM_F32:
1874 		FAIL_IF(push_inst(compiler, CVT_S_S | (sljit_ins)((op & SLJIT_32) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS));
1875 		op ^= SLJIT_32;
1876 		break;
1877 	}
1878 
1879 	if (dst & SLJIT_MEM)
1880 		return emit_op_mem2(compiler, FLOAT_DATA(op), FR(dst_r), dst, dstw, 0, 0);
1881 	return SLJIT_SUCCESS;
1882 }
1883 
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)1884 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
1885 	sljit_s32 dst, sljit_sw dstw,
1886 	sljit_s32 src1, sljit_sw src1w,
1887 	sljit_s32 src2, sljit_sw src2w)
1888 {
1889 	sljit_s32 dst_r, flags = 0;
1890 
1891 	CHECK_ERROR();
1892 	CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
1893 	ADJUST_LOCAL_OFFSET(dst, dstw);
1894 	ADJUST_LOCAL_OFFSET(src1, src1w);
1895 	ADJUST_LOCAL_OFFSET(src2, src2w);
1896 
1897 	compiler->cache_arg = 0;
1898 	compiler->cache_argw = 0;
1899 
1900 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
1901 
1902 	if (src1 & SLJIT_MEM) {
1903 		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w)) {
1904 			FAIL_IF(compiler->error);
1905 			src1 = TMP_FREG1;
1906 		} else
1907 			flags |= SLOW_SRC1;
1908 	}
1909 
1910 	if (src2 & SLJIT_MEM) {
1911 		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w)) {
1912 			FAIL_IF(compiler->error);
1913 			src2 = TMP_FREG2;
1914 		} else
1915 			flags |= SLOW_SRC2;
1916 	}
1917 
1918 	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
1919 		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
1920 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, src1, src1w));
1921 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
1922 		}
1923 		else {
1924 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
1925 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
1926 		}
1927 	}
1928 	else if (flags & SLOW_SRC1)
1929 		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
1930 	else if (flags & SLOW_SRC2)
1931 		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
1932 
1933 	if (flags & SLOW_SRC1)
1934 		src1 = TMP_FREG1;
1935 	if (flags & SLOW_SRC2)
1936 		src2 = TMP_FREG2;
1937 
1938 	switch (GET_OPCODE(op)) {
1939 	case SLJIT_ADD_F64:
1940 		FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
1941 		break;
1942 
1943 	case SLJIT_SUB_F64:
1944 		FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
1945 		break;
1946 
1947 	case SLJIT_MUL_F64:
1948 		FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
1949 		break;
1950 
1951 	case SLJIT_DIV_F64:
1952 		FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
1953 		break;
1954 	}
1955 
1956 	if (dst_r == TMP_FREG2)
1957 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG2), dst, dstw, 0, 0));
1958 
1959 	return SLJIT_SUCCESS;
1960 }
1961 
1962 /* --------------------------------------------------------------------- */
1963 /*  Other instructions                                                   */
1964 /* --------------------------------------------------------------------- */
1965 
sljit_emit_fast_enter(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)1966 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
1967 {
1968 	CHECK_ERROR();
1969 	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
1970 	ADJUST_LOCAL_OFFSET(dst, dstw);
1971 
1972 	if (FAST_IS_REG(dst))
1973 		return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS);
1974 
1975 	/* Memory. */
1976 	FAIL_IF(emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw));
1977 	compiler->delay_slot = UNMOVABLE_INS;
1978 	return SLJIT_SUCCESS;
1979 }
1980 
1981 /* --------------------------------------------------------------------- */
1982 /*  Conditional instructions                                             */
1983 /* --------------------------------------------------------------------- */
1984 
sljit_emit_label(struct sljit_compiler * compiler)1985 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
1986 {
1987 	struct sljit_label *label;
1988 
1989 	CHECK_ERROR_PTR();
1990 	CHECK_PTR(check_sljit_emit_label(compiler));
1991 
1992 	if (compiler->last_label && compiler->last_label->size == compiler->size)
1993 		return compiler->last_label;
1994 
1995 	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
1996 	PTR_FAIL_IF(!label);
1997 	set_label(label, compiler);
1998 	compiler->delay_slot = UNMOVABLE_INS;
1999 	return label;
2000 }
2001 
2002 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2003 #define JUMP_LENGTH	4
2004 #else
2005 #define JUMP_LENGTH	8
2006 #endif
2007 
2008 #define BR_Z(src) \
2009 	inst = BEQ | SA(src) | TA(0) | JUMP_LENGTH; \
2010 	flags = IS_BIT26_COND; \
2011 	delay_check = src;
2012 
2013 #define BR_NZ(src) \
2014 	inst = BNE | SA(src) | TA(0) | JUMP_LENGTH; \
2015 	flags = IS_BIT26_COND; \
2016 	delay_check = src;
2017 
2018 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2019 
2020 #define BR_T() \
2021 	inst = BC1NEZ; \
2022 	flags = IS_BIT23_COND; \
2023 	delay_check = FCSR_FCC;
2024 #define BR_F() \
2025 	inst = BC1EQZ; \
2026 	flags = IS_BIT23_COND; \
2027 	delay_check = FCSR_FCC;
2028 
2029 #else /* SLJIT_MIPS_REV < 6 */
2030 
2031 #define BR_T() \
2032 	inst = BC1T | JUMP_LENGTH; \
2033 	flags = IS_BIT16_COND; \
2034 	delay_check = FCSR_FCC;
2035 #define BR_F() \
2036 	inst = BC1F | JUMP_LENGTH; \
2037 	flags = IS_BIT16_COND; \
2038 	delay_check = FCSR_FCC;
2039 
2040 #endif /* SLJIT_MIPS_REV >= 6 */
2041 
sljit_emit_jump(struct sljit_compiler * compiler,sljit_s32 type)2042 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
2043 {
2044 	struct sljit_jump *jump;
2045 	sljit_ins inst;
2046 	sljit_u32 flags = 0;
2047 	sljit_s32 delay_check = UNMOVABLE_INS;
2048 
2049 	CHECK_ERROR_PTR();
2050 	CHECK_PTR(check_sljit_emit_jump(compiler, type));
2051 
2052 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2053 	PTR_FAIL_IF(!jump);
2054 	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
2055 	type &= 0xff;
2056 
2057 	switch (type) {
2058 	case SLJIT_EQUAL:
2059 		BR_NZ(EQUAL_FLAG);
2060 		break;
2061 	case SLJIT_NOT_EQUAL:
2062 		BR_Z(EQUAL_FLAG);
2063 		break;
2064 	case SLJIT_LESS:
2065 	case SLJIT_GREATER:
2066 	case SLJIT_SIG_LESS:
2067 	case SLJIT_SIG_GREATER:
2068 	case SLJIT_OVERFLOW:
2069 	case SLJIT_CARRY:
2070 		BR_Z(OTHER_FLAG);
2071 		break;
2072 	case SLJIT_GREATER_EQUAL:
2073 	case SLJIT_LESS_EQUAL:
2074 	case SLJIT_SIG_GREATER_EQUAL:
2075 	case SLJIT_SIG_LESS_EQUAL:
2076 	case SLJIT_NOT_OVERFLOW:
2077 	case SLJIT_NOT_CARRY:
2078 		BR_NZ(OTHER_FLAG);
2079 		break;
2080 	case SLJIT_NOT_EQUAL_F64:
2081 	case SLJIT_GREATER_EQUAL_F64:
2082 	case SLJIT_GREATER_F64:
2083 	case SLJIT_ORDERED_F64:
2084 		BR_T();
2085 		break;
2086 	case SLJIT_EQUAL_F64:
2087 	case SLJIT_LESS_F64:
2088 	case SLJIT_LESS_EQUAL_F64:
2089 	case SLJIT_UNORDERED_F64:
2090 		BR_F();
2091 		break;
2092 	default:
2093 		/* Not conditional branch. */
2094 		inst = 0;
2095 		break;
2096 	}
2097 
2098 	jump->flags |= flags;
2099 	if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check))
2100 		jump->flags |= IS_MOVABLE;
2101 
2102 	if (inst)
2103 		PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));
2104 
2105 	PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
2106 
2107 	if (type <= SLJIT_JUMP)
2108 		PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
2109 	else {
2110 		jump->flags |= IS_JAL;
2111 		PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
2112 	}
2113 
2114 	jump->addr = compiler->size;
2115 	PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2116 	return jump;
2117 }
2118 
2119 #define RESOLVE_IMM1() \
2120 	if (src1 & SLJIT_IMM) { \
2121 		if (src1w) { \
2122 			PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \
2123 			src1 = TMP_REG1; \
2124 		} \
2125 		else \
2126 			src1 = 0; \
2127 	}
2128 
2129 #define RESOLVE_IMM2() \
2130 	if (src2 & SLJIT_IMM) { \
2131 		if (src2w) { \
2132 			PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \
2133 			src2 = TMP_REG2; \
2134 		} \
2135 		else \
2136 			src2 = 0; \
2137 	}
2138 
sljit_emit_cmp(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2139 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
2140 	sljit_s32 src1, sljit_sw src1w,
2141 	sljit_s32 src2, sljit_sw src2w)
2142 {
2143 	struct sljit_jump *jump;
2144 	sljit_s32 flags;
2145 	sljit_ins inst;
2146 
2147 	CHECK_ERROR_PTR();
2148 	CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
2149 	ADJUST_LOCAL_OFFSET(src1, src1w);
2150 	ADJUST_LOCAL_OFFSET(src2, src2w);
2151 
2152 	compiler->cache_arg = 0;
2153 	compiler->cache_argw = 0;
2154 	flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
2155 	if (src1 & SLJIT_MEM) {
2156 		PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w));
2157 		src1 = TMP_REG1;
2158 	}
2159 	if (src2 & SLJIT_MEM) {
2160 		PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0));
2161 		src2 = TMP_REG2;
2162 	}
2163 
2164 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2165 	PTR_FAIL_IF(!jump);
2166 	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
2167 	type &= 0xff;
2168 
2169 	if (type <= SLJIT_NOT_EQUAL) {
2170 		RESOLVE_IMM1();
2171 		RESOLVE_IMM2();
2172 		jump->flags |= IS_BIT26_COND;
2173 		if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2)))
2174 			jump->flags |= IS_MOVABLE;
2175 		PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | JUMP_LENGTH, UNMOVABLE_INS));
2176 	}
2177 	else if (type >= SLJIT_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) {
2178 		inst = NOP;
2179 		if ((src1 & SLJIT_IMM) && (src1w == 0)) {
2180 			RESOLVE_IMM2();
2181 			switch (type) {
2182 			case SLJIT_SIG_LESS:
2183 				inst = BLEZ;
2184 				jump->flags |= IS_BIT26_COND;
2185 				break;
2186 			case SLJIT_SIG_GREATER_EQUAL:
2187 				inst = BGTZ;
2188 				jump->flags |= IS_BIT26_COND;
2189 				break;
2190 			case SLJIT_SIG_GREATER:
2191 				inst = BGEZ;
2192 				jump->flags |= IS_BIT16_COND;
2193 				break;
2194 			case SLJIT_SIG_LESS_EQUAL:
2195 				inst = BLTZ;
2196 				jump->flags |= IS_BIT16_COND;
2197 				break;
2198 			}
2199 			src1 = src2;
2200 		}
2201 		else {
2202 			RESOLVE_IMM1();
2203 			switch (type) {
2204 			case SLJIT_SIG_LESS:
2205 				inst = BGEZ;
2206 				jump->flags |= IS_BIT16_COND;
2207 				break;
2208 			case SLJIT_SIG_GREATER_EQUAL:
2209 				inst = BLTZ;
2210 				jump->flags |= IS_BIT16_COND;
2211 				break;
2212 			case SLJIT_SIG_GREATER:
2213 				inst = BLEZ;
2214 				jump->flags |= IS_BIT26_COND;
2215 				break;
2216 			case SLJIT_SIG_LESS_EQUAL:
2217 				inst = BGTZ;
2218 				jump->flags |= IS_BIT26_COND;
2219 				break;
2220 			}
2221 		}
2222 		PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | JUMP_LENGTH, UNMOVABLE_INS));
2223 	}
2224 	else {
2225 		if (type == SLJIT_LESS || type == SLJIT_GREATER_EQUAL || type == SLJIT_SIG_LESS || type == SLJIT_SIG_GREATER_EQUAL) {
2226 			RESOLVE_IMM1();
2227 			if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN)
2228 				PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1)));
2229 			else {
2230 				RESOLVE_IMM2();
2231 				PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));
2232 			}
2233 			type = (type == SLJIT_LESS || type == SLJIT_SIG_LESS) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
2234 		}
2235 		else {
2236 			RESOLVE_IMM2();
2237 			if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN)
2238 				PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1)));
2239 			else {
2240 				RESOLVE_IMM1();
2241 				PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1)));
2242 			}
2243 			type = (type == SLJIT_GREATER || type == SLJIT_SIG_GREATER) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
2244 		}
2245 
2246 		jump->flags |= IS_BIT26_COND;
2247 		PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | JUMP_LENGTH, UNMOVABLE_INS));
2248 	}
2249 
2250 	PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
2251 	PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
2252 	jump->addr = compiler->size;
2253 	PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2254 	return jump;
2255 }
2256 
2257 #undef RESOLVE_IMM1
2258 #undef RESOLVE_IMM2
2259 
2260 #undef JUMP_LENGTH
2261 #undef BR_Z
2262 #undef BR_NZ
2263 #undef BR_T
2264 #undef BR_F
2265 
2266 #undef FLOAT_DATA
2267 #undef FMT
2268 
sljit_emit_ijump(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src,sljit_sw srcw)2269 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
2270 {
2271 	struct sljit_jump *jump = NULL;
2272 
2273 	CHECK_ERROR();
2274 	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
2275 	ADJUST_LOCAL_OFFSET(src, srcw);
2276 
2277 	if (src & SLJIT_IMM) {
2278 		jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2279 		FAIL_IF(!jump);
2280 		set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
2281 		jump->u.target = (sljit_uw)srcw;
2282 
2283 		if (compiler->delay_slot != UNMOVABLE_INS)
2284 			jump->flags |= IS_MOVABLE;
2285 
2286 		FAIL_IF(emit_const(compiler, TMP_REG2, 0));
2287 		src = TMP_REG2;
2288 	}
2289 	else if (src & SLJIT_MEM) {
2290 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG2), src, srcw));
2291 		src = TMP_REG2;
2292 	}
2293 
2294 	FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));
2295 	if (jump)
2296 		jump->addr = compiler->size;
2297 	FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2298 	return SLJIT_SUCCESS;
2299 }
2300 
sljit_emit_op_flags(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 type)2301 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
2302 	sljit_s32 dst, sljit_sw dstw,
2303 	sljit_s32 type)
2304 {
2305 	sljit_s32 src_ar, dst_ar;
2306 	sljit_s32 saved_op = op;
2307 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2308 	sljit_s32 mem_type = WORD_DATA;
2309 #else
2310 	sljit_s32 mem_type = ((op & SLJIT_32) || op == SLJIT_MOV32) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
2311 #endif
2312 
2313 	CHECK_ERROR();
2314 	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
2315 	ADJUST_LOCAL_OFFSET(dst, dstw);
2316 
2317 	op = GET_OPCODE(op);
2318 	dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2);
2319 
2320 	compiler->cache_arg = 0;
2321 	compiler->cache_argw = 0;
2322 
2323 	if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
2324 		FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, DR(TMP_REG1), dst, dstw, dst, dstw));
2325 
2326 	switch (type & 0xff) {
2327 	case SLJIT_EQUAL:
2328 	case SLJIT_NOT_EQUAL:
2329 		FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(dst_ar) | IMM(1), dst_ar));
2330 		src_ar = dst_ar;
2331 		break;
2332 	case SLJIT_OVERFLOW:
2333 	case SLJIT_NOT_OVERFLOW:
2334 		if (compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)) {
2335 			src_ar = OTHER_FLAG;
2336 			break;
2337 		}
2338 		FAIL_IF(push_inst(compiler, SLTIU | SA(OTHER_FLAG) | TA(dst_ar) | IMM(1), dst_ar));
2339 		src_ar = dst_ar;
2340 		type ^= 0x1; /* Flip type bit for the XORI below. */
2341 		break;
2342 	case SLJIT_GREATER_F64:
2343 	case SLJIT_LESS_EQUAL_F64:
2344 		type ^= 0x1; /* Flip type bit for the XORI below. */
2345 		/* fallthrough */
2346 	case SLJIT_EQUAL_F64:
2347 	case SLJIT_NOT_EQUAL_F64:
2348 	case SLJIT_LESS_F64:
2349 	case SLJIT_GREATER_EQUAL_F64:
2350 	case SLJIT_UNORDERED_F64:
2351 	case SLJIT_ORDERED_F64:
2352 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2353 		FAIL_IF(push_inst(compiler, MFC1 | TA(dst_ar) | FS(TMP_FREG3), dst_ar));
2354 #else /* SLJIT_MIPS_REV < 6 */
2355 		FAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar));
2356 #endif /* SLJIT_MIPS_REV >= 6 */
2357 		FAIL_IF(push_inst(compiler, SRL | TA(dst_ar) | DA(dst_ar) | SH_IMM(23), dst_ar));
2358 		FAIL_IF(push_inst(compiler, ANDI | SA(dst_ar) | TA(dst_ar) | IMM(1), dst_ar));
2359 		src_ar = dst_ar;
2360 		break;
2361 
2362 	default:
2363 		src_ar = OTHER_FLAG;
2364 		break;
2365 	}
2366 
2367 	if (type & 0x1) {
2368 		FAIL_IF(push_inst(compiler, XORI | SA(src_ar) | TA(dst_ar) | IMM(1), dst_ar));
2369 		src_ar = dst_ar;
2370 	}
2371 
2372 	if (op < SLJIT_ADD) {
2373 		if (dst & SLJIT_MEM)
2374 			return emit_op_mem(compiler, mem_type, src_ar, dst, dstw);
2375 
2376 		if (src_ar != dst_ar)
2377 			return push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | DA(dst_ar), dst_ar);
2378 		return SLJIT_SUCCESS;
2379 	}
2380 
2381 	/* OTHER_FLAG cannot be specified as src2 argument at the moment. */
2382 	if (DR(TMP_REG2) != src_ar)
2383 		FAIL_IF(push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
2384 
2385 	mem_type |= CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE;
2386 
2387 	if (dst & SLJIT_MEM)
2388 		return emit_op(compiler, saved_op, mem_type, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
2389 	return emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, TMP_REG2, 0);
2390 }
2391 
sljit_emit_cmov(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_reg,sljit_s32 src,sljit_sw srcw)2392 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
2393 	sljit_s32 dst_reg,
2394 	sljit_s32 src, sljit_sw srcw)
2395 {
2396 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
2397 	sljit_ins ins;
2398 #endif /* SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6 */
2399 
2400 	CHECK_ERROR();
2401 	CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
2402 
2403 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
2404 
2405 	if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
2406 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2407 		if (dst_reg & SLJIT_32)
2408 			srcw = (sljit_s32)srcw;
2409 #endif
2410 		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
2411 		src = TMP_REG1;
2412 		srcw = 0;
2413 	}
2414 
2415 	dst_reg &= ~SLJIT_32;
2416 
2417 	switch (type & 0xff) {
2418 	case SLJIT_EQUAL:
2419 		ins = MOVZ | TA(EQUAL_FLAG);
2420 		break;
2421 	case SLJIT_NOT_EQUAL:
2422 		ins = MOVN | TA(EQUAL_FLAG);
2423 		break;
2424 	case SLJIT_LESS:
2425 	case SLJIT_GREATER:
2426 	case SLJIT_SIG_LESS:
2427 	case SLJIT_SIG_GREATER:
2428 	case SLJIT_OVERFLOW:
2429 		ins = MOVN | TA(OTHER_FLAG);
2430 		break;
2431 	case SLJIT_GREATER_EQUAL:
2432 	case SLJIT_LESS_EQUAL:
2433 	case SLJIT_SIG_GREATER_EQUAL:
2434 	case SLJIT_SIG_LESS_EQUAL:
2435 	case SLJIT_NOT_OVERFLOW:
2436 		ins = MOVZ | TA(OTHER_FLAG);
2437 		break;
2438 	case SLJIT_EQUAL_F64:
2439 	case SLJIT_LESS_F64:
2440 	case SLJIT_LESS_EQUAL_F64:
2441 	case SLJIT_UNORDERED_F64:
2442 		ins = MOVT;
2443 		break;
2444 	case SLJIT_NOT_EQUAL_F64:
2445 	case SLJIT_GREATER_EQUAL_F64:
2446 	case SLJIT_GREATER_F64:
2447 	case SLJIT_ORDERED_F64:
2448 		ins = MOVF;
2449 		break;
2450 	default:
2451 		ins = MOVZ | TA(OTHER_FLAG);
2452 		SLJIT_UNREACHABLE();
2453 		break;
2454 	}
2455 
2456 	return push_inst(compiler, ins | S(src) | D(dst_reg), DR(dst_reg));
2457 
2458 #else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */
2459 	return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);
2460 #endif /* SLJIT_MIPS_REV >= 1 */
2461 }
2462 
sljit_emit_const(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw init_value)2463 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
2464 {
2465 	struct sljit_const *const_;
2466 	sljit_s32 dst_r;
2467 
2468 	CHECK_ERROR_PTR();
2469 	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
2470 	ADJUST_LOCAL_OFFSET(dst, dstw);
2471 
2472 	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
2473 	PTR_FAIL_IF(!const_);
2474 	set_const(const_, compiler);
2475 
2476 	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
2477 	PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
2478 
2479 	if (dst & SLJIT_MEM)
2480 		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
2481 
2482 	return const_;
2483 }
2484 
sljit_emit_put_label(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)2485 SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
2486 {
2487 	struct sljit_put_label *put_label;
2488 	sljit_s32 dst_r;
2489 
2490 	CHECK_ERROR_PTR();
2491 	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
2492 	ADJUST_LOCAL_OFFSET(dst, dstw);
2493 
2494 	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
2495 	PTR_FAIL_IF(!put_label);
2496 	set_put_label(put_label, compiler, 0);
2497 
2498 	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
2499 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2500 	PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
2501 #else
2502 	PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r, UNMOVABLE_INS));
2503 	compiler->size += 5;
2504 #endif
2505 
2506 	if (dst & SLJIT_MEM)
2507 		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
2508 
2509 	return put_label;
2510 }
2511