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