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_REG1
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, 25, 4, 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->u.label != NULL);
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 
mov_addr_get_length(struct sljit_jump * jump,sljit_ins * code,sljit_sw executable_offset)638 static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset)
639 {
640 	sljit_uw addr;
641 	SLJIT_UNUSED_ARG(executable_offset);
642 
643 	if (jump->flags & JUMP_ADDR)
644 		addr = jump->u.target;
645 	else
646 		addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);
647 
648 	if (addr < 0x80000000l) {
649 		jump->flags |= PATCH_ABS32;
650 		return 1;
651 	}
652 
653 	if (addr < 0x800000000000l) {
654 		jump->flags |= PATCH_ABS48;
655 		return 3;
656 	}
657 
658 	return 5;
659 }
660 
661 #endif /* SLJIT_CONFIG_MIPS_64 */
662 
load_addr_to_reg(struct sljit_jump * jump)663 static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump)
664 {
665 	sljit_uw flags = jump->flags;
666 	sljit_ins *ins = (sljit_ins*)jump->addr;
667 	sljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
668 	sljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *ins : PIC_ADDR_REG;
669 
670 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
671 	ins[0] = LUI | T(reg) | IMM(addr >> 16);
672 #else /* !SLJIT_CONFIG_MIPS_32 */
673 	if (flags & PATCH_ABS32) {
674 		SLJIT_ASSERT(addr < 0x80000000l);
675 		ins[0] = LUI | T(reg) | IMM(addr >> 16);
676 	}
677 	else if (flags & PATCH_ABS48) {
678 		SLJIT_ASSERT(addr < 0x800000000000l);
679 		ins[0] = LUI | T(reg) | IMM(addr >> 32);
680 		ins[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
681 		ins[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
682 		ins += 2;
683 	}
684 	else {
685 		ins[0] = LUI | T(reg) | IMM(addr >> 48);
686 		ins[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff);
687 		ins[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
688 		ins[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
689 		ins[4] = DSLL | T(reg) | D(reg) | SH_IMM(16);
690 		ins += 4;
691 	}
692 #endif /* SLJIT_CONFIG_MIPS_32 */
693 
694 	ins[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff);
695 }
696 
sljit_generate_code(struct sljit_compiler * compiler,sljit_s32 options,void * exec_allocator_data)697 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
698 {
699 	struct sljit_memory_fragment *buf;
700 	sljit_ins *code;
701 	sljit_ins *code_ptr;
702 	sljit_ins *buf_ptr;
703 	sljit_ins *buf_end;
704 	sljit_uw word_count;
705 	SLJIT_NEXT_DEFINE_TYPES;
706 	sljit_sw executable_offset;
707 	sljit_uw addr;
708 	struct sljit_label *label;
709 	struct sljit_jump *jump;
710 	struct sljit_const *const_;
711 
712 	CHECK_ERROR_PTR();
713 	CHECK_PTR(check_sljit_generate_code(compiler));
714 	reverse_buf(compiler);
715 
716 	code = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);
717 	PTR_FAIL_WITH_EXEC_IF(code);
718 	buf = compiler->buf;
719 
720 	code_ptr = code;
721 	word_count = 0;
722 	label = compiler->labels;
723 	jump = compiler->jumps;
724 	const_ = compiler->consts;
725 	SLJIT_NEXT_INIT_TYPES();
726 	SLJIT_GET_NEXT_MIN();
727 
728 	do {
729 		buf_ptr = (sljit_ins*)buf->memory;
730 		buf_end = buf_ptr + (buf->used_size >> 2);
731 		do {
732 			*code_ptr = *buf_ptr++;
733 			if (next_min_addr == word_count) {
734 				SLJIT_ASSERT(!label || label->size >= word_count);
735 				SLJIT_ASSERT(!jump || jump->addr >= word_count);
736 				SLJIT_ASSERT(!const_ || const_->addr >= word_count);
737 
738 				/* These structures are ordered by their address. */
739 				if (next_min_addr == next_label_size) {
740 					label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
741 					label->size = (sljit_uw)(code_ptr - code);
742 					label = label->next;
743 					next_label_size = SLJIT_GET_NEXT_SIZE(label);
744 				}
745 
746 				if (next_min_addr == next_jump_addr) {
747 					if (!(jump->flags & JUMP_MOV_ADDR)) {
748 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
749 						word_count += 2;
750 #else /* !SLJIT_CONFIG_MIPS_32 */
751 						word_count += 6;
752 #endif /* SLJIT_CONFIG_MIPS_32 */
753 						jump->addr = (sljit_uw)(code_ptr - 1);
754 						code_ptr = detect_jump_type(jump, code, executable_offset);
755 					} else {
756 						jump->addr = (sljit_uw)code_ptr;
757 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
758 						code_ptr += 1;
759 						word_count += 1;
760 #else /* !SLJIT_CONFIG_MIPS_32 */
761 						code_ptr += mov_addr_get_length(jump, code, executable_offset);
762 						word_count += 5;
763 #endif /* SLJIT_CONFIG_MIPS_32 */
764 					}
765 
766 					jump = jump->next;
767 					next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
768 				} else if (next_min_addr == next_const_addr) {
769 					const_->addr = (sljit_uw)code_ptr;
770 					const_ = const_->next;
771 					next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
772 				}
773 
774 				SLJIT_GET_NEXT_MIN();
775 			}
776 			code_ptr++;
777 			word_count++;
778 		} while (buf_ptr < buf_end);
779 
780 		buf = buf->next;
781 	} while (buf);
782 
783 	if (label && label->size == word_count) {
784 		label->u.addr = (sljit_uw)code_ptr;
785 		label->size = (sljit_uw)(code_ptr - code);
786 		label = label->next;
787 	}
788 
789 	SLJIT_ASSERT(!label);
790 	SLJIT_ASSERT(!jump);
791 	SLJIT_ASSERT(!const_);
792 	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
793 
794 	jump = compiler->jumps;
795 	while (jump) {
796 		do {
797 			addr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
798 			buf_ptr = (sljit_ins *)jump->addr;
799 
800 			if (jump->flags & PATCH_B) {
801 				addr = (sljit_uw)((sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) - sizeof(sljit_ins)) >> 2);
802 				SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN);
803 				buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((sljit_ins)addr & 0xffff);
804 				break;
805 			}
806 			if (jump->flags & PATCH_J) {
807 				SLJIT_ASSERT((addr & ~(sljit_uw)0xfffffff)
808 					== (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff));
809 				buf_ptr[0] |= (sljit_ins)(addr >> 2) & 0x03ffffff;
810 				break;
811 			}
812 
813 			load_addr_to_reg(jump);
814 		} while (0);
815 
816 		jump = jump->next;
817 	}
818 
819 	compiler->error = SLJIT_ERR_COMPILED;
820 	compiler->executable_offset = executable_offset;
821 	compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
822 
823 	code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
824 	code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
825 
826 #ifndef __GNUC__
827 	SLJIT_CACHE_FLUSH(code, code_ptr);
828 #else
829 	/* GCC workaround for invalid code generation with -O2. */
830 	sljit_cache_flush(code, code_ptr);
831 #endif
832 	SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
833 	return code;
834 }
835 
sljit_has_cpu_feature(sljit_s32 feature_type)836 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
837 {
838 	switch (feature_type) {
839 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
840 		&& (!defined(SLJIT_IS_FPU_AVAILABLE) || SLJIT_IS_FPU_AVAILABLE)
841 	case SLJIT_HAS_F64_AS_F32_PAIR:
842 		if (!cpu_feature_list)
843 			get_cpu_features();
844 
845 		return (cpu_feature_list & CPU_FEATURE_FR) != 0;
846 #endif /* SLJIT_CONFIG_MIPS_32 && SLJIT_IS_FPU_AVAILABLE */
847 	case SLJIT_HAS_FPU:
848 		if (!cpu_feature_list)
849 			get_cpu_features();
850 
851 		return (cpu_feature_list & CPU_FEATURE_FPU) != 0;
852 	case SLJIT_HAS_ZERO_REGISTER:
853 	case SLJIT_HAS_COPY_F32:
854 	case SLJIT_HAS_COPY_F64:
855 		return 1;
856 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
857 	case SLJIT_HAS_CLZ:
858 	case SLJIT_HAS_CMOV:
859 	case SLJIT_HAS_PREFETCH:
860 		return 1;
861 
862 	case SLJIT_HAS_CTZ:
863 		return 2;
864 #endif /* SLJIT_MIPS_REV >= 1 */
865 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
866 	case SLJIT_HAS_REV:
867 	case SLJIT_HAS_ROT:
868 		return 1;
869 #endif /* SLJIT_MIPS_REV >= 2 */
870 	default:
871 		return 0;
872 	}
873 }
874 
sljit_cmp_info(sljit_s32 type)875 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
876 {
877 	SLJIT_UNUSED_ARG(type);
878 	return 0;
879 }
880 
881 /* --------------------------------------------------------------------- */
882 /*  Entry, exit                                                          */
883 /* --------------------------------------------------------------------- */
884 
885 /* Creates an index in data_transfer_insts array. */
886 #define LOAD_DATA	0x01
887 #define WORD_DATA	0x00
888 #define BYTE_DATA	0x02
889 #define HALF_DATA	0x04
890 #define INT_DATA	0x06
891 #define SIGNED_DATA	0x08
892 /* Separates integer and floating point registers */
893 #define GPR_REG		0x0f
894 #define DOUBLE_DATA	0x10
895 #define SINGLE_DATA	0x12
896 
897 #define MEM_MASK	0x1f
898 
899 #define ARG_TEST	0x00020
900 #define ALT_KEEP_CACHE	0x00040
901 #define CUMULATIVE_OP	0x00080
902 #define LOGICAL_OP	0x00100
903 #define IMM_OP		0x00200
904 #define MOVE_OP		0x00400
905 #define SRC2_IMM	0x00800
906 
907 #define UNUSED_DEST	0x01000
908 #define REG_DEST	0x02000
909 #define REG1_SOURCE	0x04000
910 #define REG2_SOURCE	0x08000
911 #define SLOW_SRC1	0x10000
912 #define SLOW_SRC2	0x20000
913 #define SLOW_DEST	0x40000
914 
915 static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw);
916 static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr);
917 
918 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
919 #define SELECT_OP(d, w)	(w)
920 #else
921 #define SELECT_OP(d, w)	(!(op & SLJIT_32) ? (d) : (w))
922 #endif
923 
924 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
925 #include "sljitNativeMIPS_32.c"
926 #else
927 #include "sljitNativeMIPS_64.c"
928 #endif
929 
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)930 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
931 	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
932 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
933 {
934 	sljit_ins base;
935 	sljit_s32 i, tmp, offset;
936 	sljit_s32 arg_count, word_arg_count, float_arg_count;
937 	sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);
938 
939 	CHECK_ERROR();
940 	CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
941 	set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
942 
943 	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);
944 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
945 	if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
946 		if ((local_size & SSIZE_OF(sw)) != 0)
947 			local_size += SSIZE_OF(sw);
948 		local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
949 	}
950 
951 	local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
952 #else
953 	local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
954 	local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
955 #endif
956 	compiler->local_size = local_size;
957 
958 	offset = 0;
959 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
960 	if (!(options & SLJIT_ENTER_REG_ARG)) {
961 		tmp = arg_types >> SLJIT_ARG_SHIFT;
962 		arg_count = 0;
963 
964 		while (tmp) {
965 			offset = arg_count;
966 			if ((tmp & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F64) {
967 				if ((arg_count & 0x1) != 0)
968 					arg_count++;
969 				arg_count++;
970 			}
971 
972 			arg_count++;
973 			tmp >>= SLJIT_ARG_SHIFT;
974 		}
975 
976 		compiler->args_size = (sljit_uw)arg_count << 2;
977 		offset = (offset >= 4) ? (offset << 2) : 0;
978 	}
979 #endif /* SLJIT_CONFIG_MIPS_32 */
980 
981 	if (local_size + offset <= -SIMM_MIN) {
982 		/* Frequent case. */
983 		FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP)));
984 		base = S(SLJIT_SP);
985 		offset = local_size - SSIZE_OF(sw);
986 	} else {
987 		FAIL_IF(load_immediate(compiler, OTHER_FLAG, local_size));
988 		FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
989 		FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | TA(OTHER_FLAG) | D(SLJIT_SP), DR(SLJIT_SP)));
990 		base = S(TMP_REG1);
991 		offset = -SSIZE_OF(sw);
992 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
993 		local_size = 0;
994 #endif
995 	}
996 
997 	FAIL_IF(push_inst(compiler, STORE_W | base | TA(RETURN_ADDR_REG) | IMM(offset), UNMOVABLE_INS));
998 
999 	tmp = SLJIT_S0 - saveds;
1000 	for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {
1001 		offset -= SSIZE_OF(sw);
1002 		FAIL_IF(push_inst(compiler, STORE_W | base | T(i) | IMM(offset), MOVABLE_INS));
1003 	}
1004 
1005 	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
1006 		offset -= SSIZE_OF(sw);
1007 		FAIL_IF(push_inst(compiler, STORE_W | base | T(i) | IMM(offset), MOVABLE_INS));
1008 	}
1009 
1010 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1011 	/* This alignment is valid because offset is not used after storing FPU regs. */
1012 	if ((offset & SSIZE_OF(sw)) != 0)
1013 		offset -= SSIZE_OF(sw);
1014 #endif
1015 
1016 	tmp = SLJIT_FS0 - fsaveds;
1017 	for (i = SLJIT_FS0; i > tmp; i--) {
1018 		offset -= SSIZE_OF(f64);
1019 		FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
1020 	}
1021 
1022 	for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
1023 		offset -= SSIZE_OF(f64);
1024 		FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
1025 	}
1026 
1027 	if (options & SLJIT_ENTER_REG_ARG)
1028 		return SLJIT_SUCCESS;
1029 
1030 	arg_types >>= SLJIT_ARG_SHIFT;
1031 	arg_count = 0;
1032 	word_arg_count = 0;
1033 	float_arg_count = 0;
1034 
1035 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1036 	/* The first maximum two floating point arguments are passed in floating point
1037 	   registers if no integer argument precedes them. The first 16 byte data is
1038 	   passed in four integer registers, the rest is placed onto the stack.
1039 	   The floating point registers are also part of the first 16 byte data, so
1040 	   their corresponding integer registers are not used when they are present. */
1041 
1042 	while (arg_types) {
1043 		switch (arg_types & SLJIT_ARG_MASK) {
1044 		case SLJIT_ARG_TYPE_F64:
1045 			float_arg_count++;
1046 			if ((arg_count & 0x1) != 0)
1047 				arg_count++;
1048 
1049 			if (word_arg_count == 0 && float_arg_count <= 2) {
1050 				if (float_arg_count == 1)
1051 					FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
1052 			} else if (arg_count < 4) {
1053 				FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
1054 				switch (cpu_feature_list & CPU_FEATURE_FR) {
1055 #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
1056 				case CPU_FEATURE_FR:
1057 					FAIL_IF(push_inst(compiler, MTHC1 | TA(5 + arg_count) | FS(float_arg_count), MOVABLE_INS));
1058 					break;
1059 #endif /* SLJIT_MIPS_REV >= 2 */
1060 				default:
1061 					FAIL_IF(push_inst(compiler, MTC1 | TA(5 + arg_count) | FS(float_arg_count) | (1 << 11), MOVABLE_INS));
1062 					break;
1063 				}
1064 			} else
1065 				FAIL_IF(push_inst(compiler, LDC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
1066 			arg_count++;
1067 			break;
1068 		case SLJIT_ARG_TYPE_F32:
1069 			float_arg_count++;
1070 
1071 			if (word_arg_count == 0 && float_arg_count <= 2) {
1072 				if (float_arg_count == 1)
1073 					FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
1074 			} else if (arg_count < 4)
1075 				FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
1076 			else
1077 				FAIL_IF(push_inst(compiler, LWC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
1078 			break;
1079 		default:
1080 			word_arg_count++;
1081 
1082 			if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
1083 				tmp = SLJIT_S0 - saved_arg_count;
1084 				saved_arg_count++;
1085 			} else if (word_arg_count != arg_count + 1 || arg_count == 0)
1086 				tmp = word_arg_count;
1087 			else
1088 				break;
1089 
1090 			if (arg_count < 4)
1091 				FAIL_IF(push_inst(compiler, ADDU_W | SA(4 + arg_count) | TA(0) | D(tmp), DR(tmp)));
1092 			else
1093 				FAIL_IF(push_inst(compiler, LW | base | T(tmp) | IMM(local_size + (arg_count << 2)), DR(tmp)));
1094 			break;
1095 		}
1096 		arg_count++;
1097 		arg_types >>= SLJIT_ARG_SHIFT;
1098 	}
1099 
1100 	SLJIT_ASSERT(compiler->args_size == (sljit_uw)arg_count << 2);
1101 #else /* !SLJIT_CONFIG_MIPS_32 */
1102 	while (arg_types) {
1103 		arg_count++;
1104 		switch (arg_types & SLJIT_ARG_MASK) {
1105 		case SLJIT_ARG_TYPE_F64:
1106 			float_arg_count++;
1107 			if (arg_count != float_arg_count)
1108 				FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
1109 			else if (arg_count == 1)
1110 				FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
1111 			break;
1112 		case SLJIT_ARG_TYPE_F32:
1113 			float_arg_count++;
1114 			if (arg_count != float_arg_count)
1115 				FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
1116 			else if (arg_count == 1)
1117 				FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
1118 			break;
1119 		default:
1120 			word_arg_count++;
1121 
1122 			if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
1123 				tmp = SLJIT_S0 - saved_arg_count;
1124 				saved_arg_count++;
1125 			} else if (word_arg_count != arg_count || word_arg_count <= 1)
1126 				tmp = word_arg_count;
1127 			else
1128 				break;
1129 
1130 			FAIL_IF(push_inst(compiler, ADDU_W | SA(3 + arg_count) | TA(0) | D(tmp), DR(tmp)));
1131 			break;
1132 		}
1133 		arg_types >>= SLJIT_ARG_SHIFT;
1134 	}
1135 #endif /* SLJIT_CONFIG_MIPS_32 */
1136 
1137 	return SLJIT_SUCCESS;
1138 }
1139 
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)1140 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
1141 	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
1142 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
1143 {
1144 	CHECK_ERROR();
1145 	CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
1146 	set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
1147 
1148 	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);
1149 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1150 	if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
1151 		if ((local_size & SSIZE_OF(sw)) != 0)
1152 			local_size += SSIZE_OF(sw);
1153 		local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
1154 	}
1155 
1156 	compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
1157 #else
1158 	local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
1159 	compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
1160 #endif
1161 	return SLJIT_SUCCESS;
1162 }
1163 
emit_stack_frame_release(struct sljit_compiler * compiler,sljit_s32 frame_size,sljit_ins * ins_ptr)1164 static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr)
1165 {
1166 	sljit_s32 local_size, i, tmp, offset;
1167 	sljit_s32 load_return_addr = (frame_size == 0);
1168 	sljit_s32 scratches = compiler->scratches;
1169 	sljit_s32 saveds = compiler->saveds;
1170 	sljit_s32 fsaveds = compiler->fsaveds;
1171 	sljit_s32 fscratches = compiler->fscratches;
1172 	sljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);
1173 
1174 	SLJIT_ASSERT(frame_size == 1 || (frame_size & 0xf) == 0);
1175 	frame_size &= ~0xf;
1176 
1177 	local_size = compiler->local_size;
1178 
1179 	tmp = GET_SAVED_REGISTERS_SIZE(scratches, saveds - kept_saveds_count, 1);
1180 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1181 	if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
1182 		if ((tmp & SSIZE_OF(sw)) != 0)
1183 			tmp += SSIZE_OF(sw);
1184 		tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
1185 	}
1186 #else
1187 	tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
1188 #endif
1189 
1190 	if (local_size <= SIMM_MAX) {
1191 		if (local_size < frame_size) {
1192 			FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size), DR(SLJIT_SP)));
1193 			local_size = frame_size;
1194 		}
1195 	} else {
1196 		if (tmp < frame_size)
1197 			tmp = frame_size;
1198 
1199 		FAIL_IF(load_immediate(compiler, DR(TMP_REG2), local_size - tmp));
1200 		FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG2) | D(SLJIT_SP), DR(SLJIT_SP)));
1201 		local_size = tmp;
1202 	}
1203 
1204 	SLJIT_ASSERT(local_size >= frame_size);
1205 
1206 	offset = local_size - SSIZE_OF(sw);
1207 	if (load_return_addr)
1208 		FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | TA(RETURN_ADDR_REG) | IMM(offset), RETURN_ADDR_REG));
1209 
1210 	tmp = SLJIT_S0 - saveds;
1211 	for (i = SLJIT_S0 - kept_saveds_count; i > tmp; i--) {
1212 		offset -= SSIZE_OF(sw);
1213 		FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
1214 	}
1215 
1216 	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
1217 		offset -= SSIZE_OF(sw);
1218 		FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
1219 	}
1220 
1221 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1222 	/* This alignment is valid because offset is not used after storing FPU regs. */
1223 	if ((offset & SSIZE_OF(sw)) != 0)
1224 		offset -= SSIZE_OF(sw);
1225 #endif
1226 
1227 	tmp = SLJIT_FS0 - fsaveds;
1228 	for (i = SLJIT_FS0; i > tmp; i--) {
1229 		offset -= SSIZE_OF(f64);
1230 		FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
1231 	}
1232 
1233 	for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
1234 		offset -= SSIZE_OF(f64);
1235 		FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
1236 	}
1237 
1238 	if (local_size > frame_size)
1239 		*ins_ptr = ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size);
1240 	else
1241 		*ins_ptr = NOP;
1242 
1243 	return SLJIT_SUCCESS;
1244 }
1245 
sljit_emit_return_void(struct sljit_compiler * compiler)1246 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
1247 {
1248 	sljit_ins ins;
1249 
1250 	CHECK_ERROR();
1251 	CHECK(check_sljit_emit_return_void(compiler));
1252 
1253 	emit_stack_frame_release(compiler, 0, &ins);
1254 
1255 	FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
1256 	return push_inst(compiler, ins, UNMOVABLE_INS);
1257 }
1258 
sljit_emit_return_to(struct sljit_compiler * compiler,sljit_s32 src,sljit_sw srcw)1259 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
1260 	sljit_s32 src, sljit_sw srcw)
1261 {
1262 	sljit_ins ins;
1263 
1264 	CHECK_ERROR();
1265 	CHECK(check_sljit_emit_return_to(compiler, src, srcw));
1266 
1267 	if (src & SLJIT_MEM) {
1268 		ADJUST_LOCAL_OFFSET(src, srcw);
1269 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
1270 		src = PIC_ADDR_REG;
1271 		srcw = 0;
1272 	} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
1273 		FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
1274 		src = PIC_ADDR_REG;
1275 		srcw = 0;
1276 	}
1277 
1278 	FAIL_IF(emit_stack_frame_release(compiler, 1, &ins));
1279 
1280 	if (src != SLJIT_IMM) {
1281 		FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));
1282 		return push_inst(compiler, ins, UNMOVABLE_INS);
1283 	}
1284 
1285 	if (ins != NOP)
1286 		FAIL_IF(push_inst(compiler, ins, MOVABLE_INS));
1287 
1288 	SLJIT_SKIP_CHECKS(compiler);
1289 	return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
1290 }
1291 
1292 /* --------------------------------------------------------------------- */
1293 /*  Operators                                                            */
1294 /* --------------------------------------------------------------------- */
1295 
1296 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1297 #define ARCH_32_64(a, b)	a
1298 #else
1299 #define ARCH_32_64(a, b)	b
1300 #endif
1301 
1302 static const sljit_ins data_transfer_insts[16 + 4] = {
1303 /* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
1304 /* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
1305 /* u b s */ HI(40) /* sb */,
1306 /* u b l */ HI(36) /* lbu */,
1307 /* u h s */ HI(41) /* sh */,
1308 /* u h l */ HI(37) /* lhu */,
1309 /* u i s */ HI(43) /* sw */,
1310 /* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */),
1311 
1312 /* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
1313 /* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
1314 /* s b s */ HI(40) /* sb */,
1315 /* s b l */ HI(32) /* lb */,
1316 /* s h s */ HI(41) /* sh */,
1317 /* s h l */ HI(33) /* lh */,
1318 /* s i s */ HI(43) /* sw */,
1319 /* s i l */ HI(35) /* lw */,
1320 
1321 /* d   s */ HI(61) /* sdc1 */,
1322 /* d   l */ HI(53) /* ldc1 */,
1323 /* s   s */ HI(57) /* swc1 */,
1324 /* s   l */ HI(49) /* lwc1 */,
1325 };
1326 
1327 #undef ARCH_32_64
1328 
1329 /* reg_ar is an absoulute register! */
1330 
1331 /* 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)1332 static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
1333 {
1334 	SLJIT_ASSERT(arg & SLJIT_MEM);
1335 
1336 	if (!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
1337 		/* Works for both absoulte and relative addresses. */
1338 		if (SLJIT_UNLIKELY(flags & ARG_TEST))
1339 			return 1;
1340 		FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & REG_MASK)
1341 			| TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS));
1342 		return -1;
1343 	}
1344 	return 0;
1345 }
1346 
1347 #define TO_ARGW_HI(argw) (((argw) & ~0xffff) + (((argw) & 0x8000) ? 0x10000 : 0))
1348 
1349 /* See getput_arg below.
1350    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)1351 static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
1352 {
1353 	SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
1354 
1355 	/* Simple operation except for updates. */
1356 	if (arg & OFFS_REG_MASK) {
1357 		argw &= 0x3;
1358 		next_argw &= 0x3;
1359 		if (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))
1360 			return 1;
1361 		return 0;
1362 	}
1363 
1364 	if (arg == next_arg) {
1365 		if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)
1366 				|| TO_ARGW_HI(argw) == TO_ARGW_HI(next_argw))
1367 			return 1;
1368 		return 0;
1369 	}
1370 
1371 	return 0;
1372 }
1373 
1374 /* 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)1375 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)
1376 {
1377 	sljit_s32 tmp_ar, base, delay_slot;
1378 	sljit_sw offset, argw_hi;
1379 
1380 	SLJIT_ASSERT(arg & SLJIT_MEM);
1381 	if (!(next_arg & SLJIT_MEM)) {
1382 		next_arg = 0;
1383 		next_argw = 0;
1384 	}
1385 
1386 	/* Since tmp can be the same as base or offset registers,
1387 	 * these might be unavailable after modifying tmp. */
1388 	if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
1389 		tmp_ar = reg_ar;
1390 		delay_slot = reg_ar;
1391 	}
1392 	else {
1393 		tmp_ar = DR(TMP_REG1);
1394 		delay_slot = MOVABLE_INS;
1395 	}
1396 	base = arg & REG_MASK;
1397 
1398 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
1399 		argw &= 0x3;
1400 
1401 		/* Using the cache. */
1402 		if (argw == compiler->cache_argw) {
1403 			if (arg == compiler->cache_arg)
1404 				return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
1405 
1406 			if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
1407 				if (arg == next_arg && argw == (next_argw & 0x3)) {
1408 					compiler->cache_arg = arg;
1409 					compiler->cache_argw = argw;
1410 					FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
1411 					return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
1412 				}
1413 				FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar));
1414 				return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1415 			}
1416 		}
1417 
1418 		if (SLJIT_UNLIKELY(argw)) {
1419 			compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
1420 			compiler->cache_argw = argw;
1421 			FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3)));
1422 		}
1423 
1424 		if (arg == next_arg && argw == (next_argw & 0x3)) {
1425 			compiler->cache_arg = arg;
1426 			compiler->cache_argw = argw;
1427 			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
1428 			tmp_ar = DR(TMP_REG3);
1429 		}
1430 		else
1431 			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | DA(tmp_ar), tmp_ar));
1432 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1433 	}
1434 
1435 	if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN)
1436 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(argw - compiler->cache_argw), delay_slot);
1437 
1438 	if (compiler->cache_arg == SLJIT_MEM && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) {
1439 		offset = argw - compiler->cache_argw;
1440 	} else {
1441 		compiler->cache_arg = SLJIT_MEM;
1442 
1443 		argw_hi = TO_ARGW_HI(argw);
1444 
1445 		if (next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN && argw_hi != TO_ARGW_HI(next_argw)) {
1446 			FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
1447 			compiler->cache_argw = argw;
1448 			offset = 0;
1449 		} else {
1450 			FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw_hi));
1451 			compiler->cache_argw = argw_hi;
1452 			offset = argw & 0xffff;
1453 			argw = argw_hi;
1454 		}
1455 	}
1456 
1457 	if (!base)
1458 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(offset), delay_slot);
1459 
1460 	if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) {
1461 		compiler->cache_arg = arg;
1462 		FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3)));
1463 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(offset), delay_slot);
1464 	}
1465 
1466 	FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar));
1467 	return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar) | IMM(offset), delay_slot);
1468 }
1469 
emit_op_mem(struct sljit_compiler * compiler,sljit_s32 flags,sljit_s32 reg_ar,sljit_s32 arg,sljit_sw argw)1470 static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
1471 {
1472 	sljit_s32 tmp_ar, base, delay_slot;
1473 
1474 	if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
1475 		return compiler->error;
1476 
1477 	if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
1478 		tmp_ar = reg_ar;
1479 		delay_slot = reg_ar;
1480 	}
1481 	else {
1482 		tmp_ar = DR(TMP_REG1);
1483 		delay_slot = MOVABLE_INS;
1484 	}
1485 	base = arg & REG_MASK;
1486 
1487 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
1488 		argw &= 0x3;
1489 
1490 		if (SLJIT_UNLIKELY(argw)) {
1491 			FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | DA(tmp_ar) | SH_IMM(argw), tmp_ar));
1492 			FAIL_IF(push_inst(compiler, ADDU_W | SA(tmp_ar) | T(base) | DA(tmp_ar), tmp_ar));
1493 		}
1494 		else
1495 			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(OFFS_REG(arg)) | DA(tmp_ar), tmp_ar));
1496 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1497 	}
1498 
1499 	FAIL_IF(load_immediate(compiler, tmp_ar, TO_ARGW_HI(argw)));
1500 
1501 	if (base != 0)
1502 		FAIL_IF(push_inst(compiler, ADDU_W | SA(tmp_ar) | T(base) | DA(tmp_ar), tmp_ar));
1503 
1504 	return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar) | IMM(argw), delay_slot);
1505 }
1506 
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)1507 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)
1508 {
1509 	if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
1510 		return compiler->error;
1511 	return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
1512 }
1513 
1514 #define EMIT_LOGICAL(op_imm, op_reg) \
1515 	if (flags & SRC2_IMM) { \
1516 		if (op & SLJIT_SET_Z) \
1517 			FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
1518 		if (!(flags & UNUSED_DEST)) \
1519 			FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
1520 	} \
1521 	else { \
1522 		if (op & SLJIT_SET_Z) \
1523 			FAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
1524 		if (!(flags & UNUSED_DEST)) \
1525 			FAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | D(dst), DR(dst))); \
1526 	}
1527 
1528 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1529 
1530 #define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \
1531 	op_imm = (imm); \
1532 	op_v = (v);
1533 
1534 #else /* !SLJIT_CONFIG_MIPS_32 */
1535 
1536 
1537 #define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \
1538 	op_dimm = (dimm); \
1539 	op_dimm32 = (dimm32); \
1540 	op_imm = (imm); \
1541 	op_dv = (dv); \
1542 	op_v = (v);
1543 
1544 #endif /* SLJIT_CONFIG_MIPS_32 */
1545 
1546 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV < 1)
1547 
emit_clz_ctz(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw src)1548 static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)
1549 {
1550 	sljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ);
1551 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1552 	sljit_ins word_size = (op & SLJIT_32) ? 32 : 64;
1553 #else /* !SLJIT_CONFIG_MIPS_64 */
1554 	sljit_ins word_size = 32;
1555 #endif /* SLJIT_CONFIG_MIPS_64 */
1556 
1557 	/* The TMP_REG2 is the next value. */
1558 	if (src != TMP_REG2)
1559 		FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
1560 
1561 	FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(is_clz ? 13 : 14), UNMOVABLE_INS));
1562 	/* The OTHER_FLAG is the counter. Delay slot. */
1563 	FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(word_size), OTHER_FLAG));
1564 
1565 	if (!is_clz) {
1566 		FAIL_IF(push_inst(compiler, ANDI | S(TMP_REG2) | T(TMP_REG1) | IMM(1), DR(TMP_REG1)));
1567 		FAIL_IF(push_inst(compiler, BNE | S(TMP_REG1) | TA(0) | IMM(11), UNMOVABLE_INS));
1568 	} else
1569 		FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG2) | TA(0) | IMM(11), UNMOVABLE_INS));
1570 
1571 	/* Delay slot. */
1572 	FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(0), OTHER_FLAG));
1573 
1574 	/* The TMP_REG1 is the next shift. */
1575 	FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(TMP_REG1) | IMM(word_size), DR(TMP_REG1)));
1576 
1577 	FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(TMP_REG2) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
1578 	FAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));
1579 
1580 	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)));
1581 	FAIL_IF(push_inst(compiler, BNE | S(TMP_REG2) | TA(0) | IMM(-4), UNMOVABLE_INS));
1582 	/* Delay slot. */
1583 	FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
1584 
1585 	FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(TMP_REG1) | T(TMP_REG2) | IMM(-1), DR(TMP_REG2)));
1586 	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)));
1587 
1588 	FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(-7), UNMOVABLE_INS));
1589 	/* Delay slot. */
1590 	FAIL_IF(push_inst(compiler, OR | SA(OTHER_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG));
1591 
1592 	return push_inst(compiler, SELECT_OP(DADDU, ADDU) | SA(OTHER_FLAG) | TA(0) | D(dst), DR(dst));
1593 }
1594 
1595 #endif /* SLJIT_MIPS_REV < 1 */
1596 
emit_rev(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw src)1597 static sljit_s32 emit_rev(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)
1598 {
1599 #if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64
1600 	int is_32 = (op & SLJIT_32);
1601 #endif /* SLJIT_CONFIG_MIPS_64 */
1602 
1603 	op = GET_OPCODE(op);
1604 #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
1605 #if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64
1606 	if (!is_32 && (op == SLJIT_REV)) {
1607 		FAIL_IF(push_inst(compiler, DSBH | T(src) | D(dst), DR(dst)));
1608 		return push_inst(compiler, DSHD | T(dst) | D(dst), DR(dst));
1609 	}
1610 	if (op != SLJIT_REV && src != TMP_REG2) {
1611 		FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG1), DR(TMP_REG1)));
1612 		src = TMP_REG1;
1613 	}
1614 #endif /* SLJIT_CONFIG_MIPS_64 */
1615 	FAIL_IF(push_inst(compiler, WSBH | T(src) | D(dst), DR(dst)));
1616 	FAIL_IF(push_inst(compiler, ROTR | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
1617 #if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64
1618 	if (op == SLJIT_REV_U32 && dst != TMP_REG2 && dst != TMP_REG3)
1619 		FAIL_IF(push_inst(compiler, DINSU | T(dst) | SA(0) | (31 << 11), DR(dst)));
1620 #endif /* SLJIT_CONFIG_MIPS_64 */
1621 #else /* SLJIT_MIPS_REV < 2 */
1622 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1623 	if (!is_32) {
1624 		FAIL_IF(push_inst(compiler, DSRL32 | T(src) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1)));
1625 		FAIL_IF(push_inst(compiler, ORI | SA(0) | TA(OTHER_FLAG) | 0xffff, OTHER_FLAG));
1626 		FAIL_IF(push_inst(compiler, DSLL32 | T(src) | D(dst) | SH_IMM(0), DR(dst)));
1627 		FAIL_IF(push_inst(compiler, DSLL32 | TA(OTHER_FLAG) | DA(OTHER_FLAG) | SH_IMM(0), OTHER_FLAG));
1628 		FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));
1629 
1630 		FAIL_IF(push_inst(compiler, DSRL | T(dst) | D(TMP_REG1) | SH_IMM(16), DR(TMP_REG1)));
1631 		FAIL_IF(push_inst(compiler, ORI | SA(OTHER_FLAG) | TA(OTHER_FLAG) | 0xffff, OTHER_FLAG));
1632 		FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1633 		FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1634 		FAIL_IF(push_inst(compiler, DSLL | TA(OTHER_FLAG) | DA(EQUAL_FLAG) | SH_IMM(8), EQUAL_FLAG));
1635 		FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
1636 		FAIL_IF(push_inst(compiler, XOR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
1637 		FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));
1638 
1639 		FAIL_IF(push_inst(compiler, DSRL | T(dst) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1)));
1640 		FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1641 		FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1642 		FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(8), DR(dst)));
1643 		return push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));
1644 	}
1645 
1646 	if (op != SLJIT_REV && src != TMP_REG2) {
1647 		FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG2) | SH_IMM(0), DR(TMP_REG2)));
1648 		src = TMP_REG2;
1649 	}
1650 #endif /* SLJIT_CONFIG_MIPS_64 */
1651 
1652 	FAIL_IF(push_inst(compiler, SRL | T(src) | D(TMP_REG1) | SH_IMM(16), DR(TMP_REG1)));
1653 	FAIL_IF(push_inst(compiler, LUI | TA(OTHER_FLAG) | 0xff, OTHER_FLAG));
1654 	FAIL_IF(push_inst(compiler, SLL | T(src) | D(dst) | SH_IMM(16), DR(dst)));
1655 	FAIL_IF(push_inst(compiler, ORI | SA(OTHER_FLAG) | TA(OTHER_FLAG) | 0xff, OTHER_FLAG));
1656 	FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));
1657 
1658 	FAIL_IF(push_inst(compiler, SRL | T(dst) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1)));
1659 	FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1660 	FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1661 	FAIL_IF(push_inst(compiler, SLL | T(dst) | D(dst) | SH_IMM(8), DR(dst)));
1662 	FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));
1663 
1664 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1665 	if (op == SLJIT_REV_U32 && dst != TMP_REG2 && dst != TMP_REG3) {
1666 		FAIL_IF(push_inst(compiler, DSLL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)));
1667 		FAIL_IF(push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)));
1668 	}
1669 #endif /* SLJIT_CONFIG_MIPS_64 */
1670 #endif /* SLJIT_MIPR_REV >= 2 */
1671 	return SLJIT_SUCCESS;
1672 }
1673 
emit_rev16(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw src)1674 static sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)
1675 {
1676 #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
1677 #if defined(SLJIT_CONFIG_MIPS_32) && SLJIT_CONFIG_MIPS_32
1678 	FAIL_IF(push_inst(compiler, WSBH | T(src) | D(dst), DR(dst)));
1679 #else /* !SLJIT_CONFIG_MIPS_32 */
1680 	FAIL_IF(push_inst(compiler, DSBH | T(src) | D(dst), DR(dst)));
1681 #endif /* SLJIT_CONFIG_MIPS_32 */
1682 	if (GET_OPCODE(op) == SLJIT_REV_U16)
1683 		return push_inst(compiler, ANDI | S(dst) | T(dst) | 0xffff, DR(dst));
1684 	else
1685 		return push_inst(compiler, SEH | T(dst) | D(dst), DR(dst));
1686 #else /* SLJIT_MIPS_REV < 2 */
1687 	FAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(src) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1)));
1688 	FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | T(src) | D(dst) | SH_IMM(24), DR(dst)));
1689 	FAIL_IF(push_inst(compiler, ANDI | S(TMP_REG1) | T(TMP_REG1) | 0xff, DR(TMP_REG1)));
1690 	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)));
1691 	return push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));
1692 #endif /* SLJIT_MIPS_REV >= 2 */
1693 }
1694 
emit_single_op(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 flags,sljit_s32 dst,sljit_s32 src1,sljit_sw src2)1695 static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
1696 	sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
1697 {
1698 	sljit_s32 is_overflow, is_carry, carry_src_ar, is_handled, reg;
1699 	sljit_ins op_imm, op_v;
1700 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1701 	sljit_ins ins, op_dimm, op_dimm32, op_dv;
1702 #endif
1703 
1704 	switch (GET_OPCODE(op)) {
1705 	case SLJIT_MOV:
1706 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1707 		if (dst != src2)
1708 			return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst));
1709 		return SLJIT_SUCCESS;
1710 
1711 	case SLJIT_MOV_U8:
1712 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1713 		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
1714 			return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
1715 		SLJIT_ASSERT(dst == src2);
1716 		return SLJIT_SUCCESS;
1717 
1718 	case SLJIT_MOV_S8:
1719 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1720 		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1721 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1722 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1723 			return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
1724 #else /* SLJIT_MIPS_REV < 2 */
1725 			FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
1726 			return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
1727 #endif /* SLJIT_MIPS_REV >= 2 */
1728 #else /* !SLJIT_CONFIG_MIPS_32 */
1729 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1730 			if (op & SLJIT_32)
1731 				return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
1732 #endif /* SLJIT_MIPS_REV >= 2 */
1733 			FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
1734 			return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst));
1735 #endif /* SLJIT_CONFIG_MIPS_32 */
1736 		}
1737 		SLJIT_ASSERT(dst == src2);
1738 		return SLJIT_SUCCESS;
1739 
1740 	case SLJIT_MOV_U16:
1741 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1742 		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
1743 			return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
1744 		SLJIT_ASSERT(dst == src2);
1745 		return SLJIT_SUCCESS;
1746 
1747 	case SLJIT_MOV_S16:
1748 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1749 		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1750 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1751 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1752 			return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
1753 #else /* SLJIT_MIPS_REV < 2 */
1754 			FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
1755 			return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
1756 #endif /* SLJIT_MIPS_REV >= 2 */
1757 #else /* !SLJIT_CONFIG_MIPS_32 */
1758 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1759 			if (op & SLJIT_32)
1760 				return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
1761 #endif /* SLJIT_MIPS_REV >= 2 */
1762 			FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
1763 			return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst));
1764 #endif /* SLJIT_CONFIG_MIPS_32 */
1765 		}
1766 		SLJIT_ASSERT(dst == src2);
1767 		return SLJIT_SUCCESS;
1768 
1769 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1770 	case SLJIT_MOV_U32:
1771 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));
1772 		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1773 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1774 			if (dst == src2)
1775 				return push_inst(compiler, DINSU | T(src2) | SA(0) | (31 << 11), DR(dst));
1776 #endif /* SLJIT_MIPS_REV >= 2 */
1777 			FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst)));
1778 			return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst));
1779 		}
1780 		SLJIT_ASSERT(dst == src2);
1781 		return SLJIT_SUCCESS;
1782 
1783 	case SLJIT_MOV_S32:
1784 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));
1785 		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1786 			return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst));
1787 		}
1788 		SLJIT_ASSERT(dst == src2);
1789 		return SLJIT_SUCCESS;
1790 #endif /* SLJIT_CONFIG_MIPS_64 */
1791 
1792 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1793 	case SLJIT_CLZ:
1794 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1795 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1796 		return push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | D(dst), DR(dst));
1797 #else /* SLJIT_MIPS_REV < 6 */
1798 		return push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst));
1799 #endif /* SLJIT_MIPS_REV >= 6 */
1800 	case SLJIT_CTZ:
1801 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1802 		FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));
1803 		FAIL_IF(push_inst(compiler, AND | S(src2) | T(TMP_REG1) | D(dst), DR(dst)));
1804 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1805 		FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(dst) | D(dst), DR(dst)));
1806 #else /* SLJIT_MIPS_REV < 6 */
1807 		FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(dst) | T(dst) | D(dst), DR(dst)));
1808 #endif /* SLJIT_MIPS_REV >= 6 */
1809 		FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(TMP_REG1) | IMM(SELECT_OP(-64, -32)), DR(TMP_REG1)));
1810 		FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(SELECT_OP(26, 27)), DR(TMP_REG1)));
1811 		return push_inst(compiler, XOR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));
1812 #else /* SLJIT_MIPS_REV < 1 */
1813 	case SLJIT_CLZ:
1814 	case SLJIT_CTZ:
1815 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1816 		return emit_clz_ctz(compiler, op, dst, src2);
1817 #endif /* SLJIT_MIPS_REV >= 1 */
1818 
1819 	case SLJIT_REV:
1820 	case SLJIT_REV_U32:
1821 	case SLJIT_REV_S32:
1822 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && src2 != TMP_REG1 && dst != TMP_REG1);
1823 		return emit_rev(compiler, op, dst, src2);
1824 
1825 	case SLJIT_REV_U16:
1826 	case SLJIT_REV_S16:
1827 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1828 		return emit_rev16(compiler, op, dst, src2);
1829 
1830 	case SLJIT_ADD:
1831 		/* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */
1832 		is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
1833 		carry_src_ar = GET_FLAG_TYPE(op) == SLJIT_CARRY;
1834 
1835 		if (flags & SRC2_IMM) {
1836 			if (is_overflow) {
1837 				if (src2 >= 0)
1838 					FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1839 				else
1840 					FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1841 			}
1842 			else if (op & SLJIT_SET_Z)
1843 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
1844 
1845 			/* Only the zero flag is needed. */
1846 			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
1847 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
1848 		}
1849 		else {
1850 			if (is_overflow)
1851 				FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1852 			else if (op & SLJIT_SET_Z)
1853 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1854 
1855 			if (is_overflow || carry_src_ar != 0) {
1856 				if (src1 != dst)
1857 					carry_src_ar = DR(src1);
1858 				else if (src2 != dst)
1859 					carry_src_ar = DR(src2);
1860 				else {
1861 					FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | DA(OTHER_FLAG), OTHER_FLAG));
1862 					carry_src_ar = OTHER_FLAG;
1863 				}
1864 			}
1865 
1866 			/* Only the zero flag is needed. */
1867 			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
1868 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
1869 		}
1870 
1871 		/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
1872 		if (is_overflow || carry_src_ar != 0) {
1873 			if (flags & SRC2_IMM)
1874 				FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
1875 			else
1876 				FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(carry_src_ar) | DA(OTHER_FLAG), OTHER_FLAG));
1877 		}
1878 
1879 		if (!is_overflow)
1880 			return SLJIT_SUCCESS;
1881 
1882 		FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1883 		if (op & SLJIT_SET_Z)
1884 			FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
1885 		FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
1886 		return push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
1887 
1888 	case SLJIT_ADDC:
1889 		carry_src_ar = GET_FLAG_TYPE(op) == SLJIT_CARRY;
1890 
1891 		if (flags & SRC2_IMM) {
1892 			FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
1893 		} else {
1894 			if (carry_src_ar != 0) {
1895 				if (src1 != dst)
1896 					carry_src_ar = DR(src1);
1897 				else if (src2 != dst)
1898 					carry_src_ar = DR(src2);
1899 				else {
1900 					FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
1901 					carry_src_ar = EQUAL_FLAG;
1902 				}
1903 			}
1904 
1905 			FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
1906 		}
1907 
1908 		/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
1909 		if (carry_src_ar != 0) {
1910 			if (flags & SRC2_IMM)
1911 				FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
1912 			else
1913 				FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(carry_src_ar) | DA(EQUAL_FLAG), EQUAL_FLAG));
1914 		}
1915 
1916 		FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1917 
1918 		if (carry_src_ar == 0)
1919 			return SLJIT_SUCCESS;
1920 
1921 		/* Set ULESS_FLAG (dst == 0) && (OTHER_FLAG == 1). */
1922 		FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
1923 		/* Set carry flag. */
1924 		return push_inst(compiler, OR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
1925 
1926 	case SLJIT_SUB:
1927 		if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
1928 			FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
1929 			src2 = TMP_REG2;
1930 			flags &= ~SRC2_IMM;
1931 		}
1932 
1933 		is_handled = 0;
1934 
1935 		if (flags & SRC2_IMM) {
1936 			if (GET_FLAG_TYPE(op) == SLJIT_LESS) {
1937 				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
1938 				is_handled = 1;
1939 			}
1940 			else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) {
1941 				FAIL_IF(push_inst(compiler, SLTI | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
1942 				is_handled = 1;
1943 			}
1944 		}
1945 
1946 		if (!is_handled && GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {
1947 			is_handled = 1;
1948 
1949 			if (flags & SRC2_IMM) {
1950 				reg = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
1951 				FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(reg) | IMM(src2), DR(reg)));
1952 				src2 = reg;
1953 				flags &= ~SRC2_IMM;
1954 			}
1955 
1956 			switch (GET_FLAG_TYPE(op)) {
1957 			case SLJIT_LESS:
1958 				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
1959 				break;
1960 			case SLJIT_GREATER:
1961 				FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
1962 				break;
1963 			case SLJIT_SIG_LESS:
1964 				FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
1965 				break;
1966 			case SLJIT_SIG_GREATER:
1967 				FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
1968 				break;
1969 			}
1970 		}
1971 
1972 		if (is_handled) {
1973 			if (flags & SRC2_IMM) {
1974 				if (op & SLJIT_SET_Z)
1975 					FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
1976 				if (!(flags & UNUSED_DEST))
1977 					return push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst));
1978 			}
1979 			else {
1980 				if (op & SLJIT_SET_Z)
1981 					FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1982 				if (!(flags & UNUSED_DEST))
1983 					return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst));
1984 			}
1985 			return SLJIT_SUCCESS;
1986 		}
1987 
1988 		is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
1989 		is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY;
1990 
1991 		if (flags & SRC2_IMM) {
1992 			if (is_overflow) {
1993 				if (src2 >= 0)
1994 					FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1995 				else
1996 					FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1997 			}
1998 			else if (op & SLJIT_SET_Z)
1999 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
2000 
2001 			if (is_overflow || is_carry)
2002 				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
2003 
2004 			/* Only the zero flag is needed. */
2005 			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
2006 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
2007 		}
2008 		else {
2009 			if (is_overflow)
2010 				FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2011 			else if (op & SLJIT_SET_Z)
2012 				FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2013 
2014 			if (is_overflow || is_carry)
2015 				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
2016 
2017 			/* Only the zero flag is needed. */
2018 			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
2019 				FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
2020 		}
2021 
2022 		if (!is_overflow)
2023 			return SLJIT_SUCCESS;
2024 
2025 		FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
2026 		if (op & SLJIT_SET_Z)
2027 			FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
2028 		FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
2029 		return push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
2030 
2031 	case SLJIT_SUBC:
2032 		if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
2033 			FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
2034 			src2 = TMP_REG2;
2035 			flags &= ~SRC2_IMM;
2036 		}
2037 
2038 		is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY;
2039 
2040 		if (flags & SRC2_IMM) {
2041 			if (is_carry)
2042 				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
2043 
2044 			FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
2045 		}
2046 		else {
2047 			if (is_carry)
2048 				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2049 
2050 			FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
2051 		}
2052 
2053 		if (is_carry)
2054 			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
2055 
2056 		FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
2057 
2058 		if (!is_carry)
2059 			return SLJIT_SUCCESS;
2060 
2061 		return push_inst(compiler, OR | SA(EQUAL_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG);
2062 
2063 	case SLJIT_MUL:
2064 		SLJIT_ASSERT(!(flags & SRC2_IMM));
2065 
2066 		if (GET_FLAG_TYPE(op) != SLJIT_OVERFLOW) {
2067 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2068 			return push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst));
2069 #elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
2070 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2071 			return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
2072 #else /* !SLJIT_CONFIG_MIPS_32 */
2073 			if (op & SLJIT_32)
2074 				return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
2075 			FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
2076 			return push_inst(compiler, MFLO | D(dst), DR(dst));
2077 #endif /* SLJIT_CONFIG_MIPS_32 */
2078 #else /* SLJIT_MIPS_REV < 1 */
2079 			FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
2080 			return push_inst(compiler, MFLO | D(dst), DR(dst));
2081 #endif /* SLJIT_MIPS_REV >= 6 */
2082 		}
2083 
2084 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2085 		FAIL_IF(push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst)));
2086 		FAIL_IF(push_inst(compiler, SELECT_OP(DMUH, MUH) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2087 #else /* SLJIT_MIPS_REV < 6 */
2088 		FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
2089 		FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
2090 		FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
2091 #endif /* SLJIT_MIPS_REV >= 6 */
2092 		FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
2093 		return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
2094 
2095 	case SLJIT_AND:
2096 		EMIT_LOGICAL(ANDI, AND);
2097 		return SLJIT_SUCCESS;
2098 
2099 	case SLJIT_OR:
2100 		EMIT_LOGICAL(ORI, OR);
2101 		return SLJIT_SUCCESS;
2102 
2103 	case SLJIT_XOR:
2104 		if (!(flags & LOGICAL_OP)) {
2105 			SLJIT_ASSERT((flags & SRC2_IMM) && src2 == -1);
2106 			if (op & SLJIT_SET_Z)
2107 				FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
2108 			if (!(flags & UNUSED_DEST))
2109 				FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | D(dst), DR(dst)));
2110 			return SLJIT_SUCCESS;
2111 		}
2112 		EMIT_LOGICAL(XORI, XOR);
2113 		return SLJIT_SUCCESS;
2114 
2115 	case SLJIT_SHL:
2116 	case SLJIT_MSHL:
2117 		EMIT_SHIFT(DSLL, DSLL32, SLL, DSLLV, SLLV);
2118 		break;
2119 
2120 	case SLJIT_LSHR:
2121 	case SLJIT_MLSHR:
2122 		EMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV);
2123 		break;
2124 
2125 	case SLJIT_ASHR:
2126 	case SLJIT_MASHR:
2127 		EMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV);
2128 		break;
2129 
2130 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
2131 	case SLJIT_ROTL:
2132 		if ((flags & SRC2_IMM) || src2 == 0) {
2133 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2134 			src2 = -src2 & 0x1f;
2135 #else /* !SLJIT_CONFIG_MIPS_32 */
2136 			src2 = -src2 & ((op & SLJIT_32) ? 0x1f : 0x3f);
2137 #endif /* SLJIT_CONFIG_MIPS_32 */
2138 		} else {
2139 			FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG2), DR(TMP_REG2)));
2140 			src2 = TMP_REG2;
2141 		}
2142 		/* fallthrough */
2143 
2144 	case SLJIT_ROTR:
2145 		EMIT_SHIFT(DROTR, DROTR32, ROTR, DROTRV, ROTRV);
2146 		break;
2147 #else /* SLJIT_MIPS_REV < 1 */
2148 	case SLJIT_ROTL:
2149 	case SLJIT_ROTR:
2150 		if (flags & SRC2_IMM) {
2151 			SLJIT_ASSERT(src2 != 0);
2152 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2153 			if (!(op & SLJIT_32)) {
2154 				if (GET_OPCODE(op) == SLJIT_ROTL)
2155 					op_imm = ((src2 < 32) ? DSLL : DSLL32);
2156 				else
2157 					op_imm = ((src2 < 32) ? DSRL : DSRL32);
2158 
2159 				FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(OTHER_FLAG) | (((sljit_ins)src2 & 0x1f) << 6), OTHER_FLAG));
2160 
2161 				src2 = 64 - src2;
2162 				if (GET_OPCODE(op) == SLJIT_ROTL)
2163 					op_imm = ((src2 < 32) ? DSRL : DSRL32);
2164 				else
2165 					op_imm = ((src2 < 32) ? DSLL : DSLL32);
2166 
2167 				FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | (((sljit_ins)src2 & 0x1f) << 6), DR(dst)));
2168 				return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
2169 			}
2170 #endif /* SLJIT_CONFIG_MIPS_64 */
2171 
2172 			op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SLL : SRL;
2173 			FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(OTHER_FLAG) | ((sljit_ins)src2 << 6), OTHER_FLAG));
2174 
2175 			src2 = 32 - src2;
2176 			op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SRL : SLL;
2177 			FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | (((sljit_ins)src2 & 0x1f) << 6), DR(dst)));
2178 			return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
2179 		}
2180 
2181 		if (src2 == 0) {
2182 			if (dst != src1)
2183 				return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | D(dst), DR(dst));
2184 			return SLJIT_SUCCESS;
2185 		}
2186 
2187 		FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2188 
2189 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2190 		if (!(op & SLJIT_32)) {
2191 			op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? DSLLV : DSRLV;
2192 			FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
2193 			op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? DSRLV : DSLLV;
2194 			FAIL_IF(push_inst(compiler, op_v | SA(EQUAL_FLAG) | T(src1) | D(dst), DR(dst)));
2195 			return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
2196 		}
2197 #endif /* SLJIT_CONFIG_MIPS_64 */
2198 
2199 		op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? SLLV : SRLV;
2200 		FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
2201 		op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? SRLV : SLLV;
2202 		FAIL_IF(push_inst(compiler, op_v | SA(EQUAL_FLAG) | T(src1) | D(dst), DR(dst)));
2203 		return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
2204 #endif /* SLJIT_MIPS_REV >= 2 */
2205 
2206 	default:
2207 		SLJIT_UNREACHABLE();
2208 		return SLJIT_SUCCESS;
2209 	}
2210 
2211 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2212 	if ((flags & SRC2_IMM) || src2 == 0) {
2213 		if (op & SLJIT_SET_Z)
2214 			FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG));
2215 
2216 		if (flags & UNUSED_DEST)
2217 			return SLJIT_SUCCESS;
2218 		return push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst));
2219 	}
2220 
2221 	if (op & SLJIT_SET_Z)
2222 		FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
2223 
2224 	if (flags & UNUSED_DEST)
2225 		return SLJIT_SUCCESS;
2226 	return push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst));
2227 #else /* !SLJIT_CONFIG_MIPS_32 */
2228 	if ((flags & SRC2_IMM) || src2 == 0) {
2229 		if (src2 >= 32) {
2230 			SLJIT_ASSERT(!(op & SLJIT_32));
2231 			ins = op_dimm32;
2232 			src2 -= 32;
2233 		}
2234 		else
2235 			ins = (op & SLJIT_32) ? op_imm : op_dimm;
2236 
2237 		if (op & SLJIT_SET_Z)
2238 			FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG));
2239 
2240 		if (flags & UNUSED_DEST)
2241 			return SLJIT_SUCCESS;
2242 		return push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst));
2243 	}
2244 
2245 	ins = (op & SLJIT_32) ? op_v : op_dv;
2246 	if (op & SLJIT_SET_Z)
2247 		FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
2248 
2249 	if (flags & UNUSED_DEST)
2250 		return SLJIT_SUCCESS;
2251 	return push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst));
2252 #endif /* SLJIT_CONFIG_MIPS_32 */
2253 }
2254 
2255 #define CHECK_IMM(flags, srcw) \
2256 	((!((flags) & LOGICAL_OP) && ((srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)) \
2257 		|| (((flags) & LOGICAL_OP) && !((srcw) & ~UIMM_MAX)))
2258 
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)2259 static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
2260 	sljit_s32 dst, sljit_sw dstw,
2261 	sljit_s32 src1, sljit_sw src1w,
2262 	sljit_s32 src2, sljit_sw src2w)
2263 {
2264 	/* arg1 goes to TMP_REG1 or src reg
2265 	   arg2 goes to TMP_REG2, imm or src reg
2266 	   TMP_REG3 can be used for caching
2267 	   result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
2268 	sljit_s32 dst_r = TMP_REG2;
2269 	sljit_s32 src1_r;
2270 	sljit_sw src2_r = 0;
2271 	sljit_s32 src2_tmp_reg = (GET_OPCODE(op) >= SLJIT_OP2_BASE && FAST_IS_REG(src1)) ? TMP_REG1 : TMP_REG2;
2272 
2273 	if (!(flags & ALT_KEEP_CACHE)) {
2274 		compiler->cache_arg = 0;
2275 		compiler->cache_argw = 0;
2276 	}
2277 
2278 	if (dst == 0) {
2279 		SLJIT_ASSERT(HAS_FLAGS(op));
2280 		flags |= UNUSED_DEST;
2281 		dst = TMP_REG2;
2282 	}
2283 	else if (FAST_IS_REG(dst)) {
2284 		dst_r = dst;
2285 		flags |= REG_DEST;
2286 		if (flags & MOVE_OP)
2287 			src2_tmp_reg = dst_r;
2288 	}
2289 	else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))
2290 		flags |= SLOW_DEST;
2291 
2292 	if (flags & IMM_OP) {
2293 		if (src2 == SLJIT_IMM && src2w != 0 && CHECK_IMM(flags, src2w)) {
2294 			flags |= SRC2_IMM;
2295 			src2_r = src2w;
2296 		} else if ((flags & CUMULATIVE_OP) && src1 == SLJIT_IMM && src1w != 0 && CHECK_IMM(flags, src1w)) {
2297 			flags |= SRC2_IMM;
2298 			src2_r = src1w;
2299 
2300 			/* And swap arguments. */
2301 			src1 = src2;
2302 			src1w = src2w;
2303 			src2 = SLJIT_IMM;
2304 			/* src2w = src2_r unneeded. */
2305 		}
2306 	}
2307 
2308 	/* Source 1. */
2309 	if (FAST_IS_REG(src1)) {
2310 		src1_r = src1;
2311 		flags |= REG1_SOURCE;
2312 	}
2313 	else if (src1 == SLJIT_IMM) {
2314 		if (src1w) {
2315 			FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
2316 			src1_r = TMP_REG1;
2317 		}
2318 		else
2319 			src1_r = 0;
2320 	}
2321 	else {
2322 		if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w))
2323 			FAIL_IF(compiler->error);
2324 		else
2325 			flags |= SLOW_SRC1;
2326 		src1_r = TMP_REG1;
2327 	}
2328 
2329 	/* Source 2. */
2330 	if (FAST_IS_REG(src2)) {
2331 		src2_r = src2;
2332 		flags |= REG2_SOURCE;
2333 		if ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP)
2334 			dst_r = (sljit_s32)src2_r;
2335 	}
2336 	else if (src2 == SLJIT_IMM) {
2337 		if (!(flags & SRC2_IMM)) {
2338 			if (src2w) {
2339 				FAIL_IF(load_immediate(compiler, DR(src2_tmp_reg), src2w));
2340 				src2_r = src2_tmp_reg;
2341 			}
2342 			else {
2343 				src2_r = 0;
2344 				if (flags & MOVE_OP) {
2345 					if (dst & SLJIT_MEM)
2346 						dst_r = 0;
2347 					else
2348 						op = SLJIT_MOV;
2349 				}
2350 			}
2351 		}
2352 	}
2353 	else {
2354 		if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(src2_tmp_reg), src2, src2w))
2355 			FAIL_IF(compiler->error);
2356 		else
2357 			flags |= SLOW_SRC2;
2358 		src2_r = src2_tmp_reg;
2359 	}
2360 
2361 	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
2362 		SLJIT_ASSERT(src2_r == TMP_REG2);
2363 		if ((flags & SLOW_DEST) && !can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
2364 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));
2365 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
2366 		}
2367 		else {
2368 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w));
2369 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw));
2370 		}
2371 	}
2372 	else if (flags & SLOW_SRC1)
2373 		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
2374 	else if (flags & SLOW_SRC2)
2375 		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(src2_tmp_reg), src2, src2w, dst, dstw));
2376 
2377 	FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
2378 
2379 	if (dst & SLJIT_MEM) {
2380 		if (!(flags & SLOW_DEST)) {
2381 			getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw);
2382 			return compiler->error;
2383 		}
2384 		return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0);
2385 	}
2386 
2387 	return SLJIT_SUCCESS;
2388 }
2389 
2390 #undef CHECK_IMM
2391 
sljit_emit_op0(struct sljit_compiler * compiler,sljit_s32 op)2392 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
2393 {
2394 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2395 	sljit_s32 int_op = op & SLJIT_32;
2396 #endif
2397 
2398 	CHECK_ERROR();
2399 	CHECK(check_sljit_emit_op0(compiler, op));
2400 
2401 	op = GET_OPCODE(op);
2402 	switch (op) {
2403 	case SLJIT_BREAKPOINT:
2404 		return push_inst(compiler, BREAK, UNMOVABLE_INS);
2405 	case SLJIT_NOP:
2406 		return push_inst(compiler, NOP, UNMOVABLE_INS);
2407 	case SLJIT_LMUL_UW:
2408 	case SLJIT_LMUL_SW:
2409 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2410 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2411 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULU : DMUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2412 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMUHU : DMUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2413 #else /* !SLJIT_CONFIG_MIPS_64 */
2414 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULU : MUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2415 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MUHU : MUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2416 #endif /* SLJIT_CONFIG_MIPS_64 */
2417 		FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
2418 		return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
2419 #else /* SLJIT_MIPS_REV < 6 */
2420 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2421 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2422 #else /* !SLJIT_CONFIG_MIPS_64 */
2423 		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2424 #endif /* SLJIT_CONFIG_MIPS_64 */
2425 		FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
2426 		return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
2427 #endif /* SLJIT_MIPS_REV >= 6 */
2428 	case SLJIT_DIVMOD_UW:
2429 	case SLJIT_DIVMOD_SW:
2430 	case SLJIT_DIV_UW:
2431 	case SLJIT_DIV_SW:
2432 		SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
2433 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2434 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2435 		if (int_op) {
2436 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2437 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2438 		}
2439 		else {
2440 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2441 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DMODU : DMOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2442 		}
2443 #else /* !SLJIT_CONFIG_MIPS_64 */
2444 		FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2445 		FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2446 #endif /* SLJIT_CONFIG_MIPS_64 */
2447 		FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
2448 		return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
2449 #else /* SLJIT_MIPS_REV < 6 */
2450 #if !(defined SLJIT_MIPS_REV)
2451 		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2452 		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2453 #endif /* !SLJIT_MIPS_REV */
2454 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2455 		if (int_op)
2456 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2457 		else
2458 			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2459 #else /* !SLJIT_CONFIG_MIPS_64 */
2460 		FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2461 #endif /* SLJIT_CONFIG_MIPS_64 */
2462 		FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
2463 		return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
2464 #endif /* SLJIT_MIPS_REV >= 6 */
2465 	case SLJIT_ENDBR:
2466 	case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
2467 		return SLJIT_SUCCESS;
2468 	}
2469 
2470 	return SLJIT_SUCCESS;
2471 }
2472 
2473 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
emit_prefetch(struct sljit_compiler * compiler,sljit_s32 src,sljit_sw srcw)2474 static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
2475         sljit_s32 src, sljit_sw srcw)
2476 {
2477 	if (!(src & OFFS_REG_MASK)) {
2478 		if (srcw <= SIMM_MAX && srcw >= SIMM_MIN)
2479 			return push_inst(compiler, PREF | S(src & REG_MASK) | IMM(srcw), MOVABLE_INS);
2480 
2481 		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
2482 		return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
2483 	}
2484 
2485 	srcw &= 0x3;
2486 
2487 	if (SLJIT_UNLIKELY(srcw != 0)) {
2488 		FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(src)) | D(TMP_REG1) | SH_IMM(srcw), DR(TMP_REG1)));
2489 		return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
2490 	}
2491 
2492 	return push_inst(compiler, PREFX | S(src & REG_MASK) | T(OFFS_REG(src)), MOVABLE_INS);
2493 }
2494 #endif /* SLJIT_MIPS_REV >= 1 */
2495 
sljit_emit_op1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)2496 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
2497 	sljit_s32 dst, sljit_sw dstw,
2498 	sljit_s32 src, sljit_sw srcw)
2499 {
2500 	sljit_s32 flags = 0;
2501 
2502 	CHECK_ERROR();
2503 	CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
2504 	ADJUST_LOCAL_OFFSET(dst, dstw);
2505 	ADJUST_LOCAL_OFFSET(src, srcw);
2506 
2507 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2508 	if (op & SLJIT_32)
2509 		flags = INT_DATA | SIGNED_DATA;
2510 #endif
2511 
2512 	switch (GET_OPCODE(op)) {
2513 	case SLJIT_MOV:
2514 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2515 	case SLJIT_MOV_U32:
2516 	case SLJIT_MOV_S32:
2517 	case SLJIT_MOV32:
2518 #endif
2519 	case SLJIT_MOV_P:
2520 		return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, srcw);
2521 
2522 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2523 	case SLJIT_MOV_U32:
2524 		return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u32)srcw : srcw);
2525 
2526 	case SLJIT_MOV_S32:
2527 	case SLJIT_MOV32:
2528 		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);
2529 #endif
2530 
2531 	case SLJIT_MOV_U8:
2532 		return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw);
2533 
2534 	case SLJIT_MOV_S8:
2535 		return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s8)srcw : srcw);
2536 
2537 	case SLJIT_MOV_U16:
2538 		return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u16)srcw : srcw);
2539 
2540 	case SLJIT_MOV_S16:
2541 		return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s16)srcw : srcw);
2542 
2543 	case SLJIT_CLZ:
2544 	case SLJIT_CTZ:
2545 	case SLJIT_REV:
2546 		return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
2547 
2548 	case SLJIT_REV_U16:
2549 	case SLJIT_REV_S16:
2550 		return emit_op(compiler, op, HALF_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
2551 
2552 	case SLJIT_REV_U32:
2553 	case SLJIT_REV_S32:
2554 		return emit_op(compiler, op | SLJIT_32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
2555 	}
2556 
2557 	SLJIT_UNREACHABLE();
2558 	return SLJIT_SUCCESS;
2559 }
2560 
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)2561 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
2562 	sljit_s32 dst, sljit_sw dstw,
2563 	sljit_s32 src1, sljit_sw src1w,
2564 	sljit_s32 src2, sljit_sw src2w)
2565 {
2566 	sljit_s32 flags = 0;
2567 
2568 	CHECK_ERROR();
2569 	CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
2570 	ADJUST_LOCAL_OFFSET(dst, dstw);
2571 	ADJUST_LOCAL_OFFSET(src1, src1w);
2572 	ADJUST_LOCAL_OFFSET(src2, src2w);
2573 
2574 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2575 	if (op & SLJIT_32) {
2576 		flags |= INT_DATA | SIGNED_DATA;
2577 		if (src1 == SLJIT_IMM)
2578 			src1w = (sljit_s32)src1w;
2579 		if (src2 == SLJIT_IMM)
2580 			src2w = (sljit_s32)src2w;
2581 	}
2582 #endif
2583 
2584 	switch (GET_OPCODE(op)) {
2585 	case SLJIT_ADD:
2586 	case SLJIT_ADDC:
2587 		compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
2588 		return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2589 
2590 	case SLJIT_SUB:
2591 	case SLJIT_SUBC:
2592 		compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
2593 		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2594 
2595 	case SLJIT_MUL:
2596 		compiler->status_flags_state = 0;
2597 		return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
2598 
2599 	case SLJIT_XOR:
2600 		if ((src1 == SLJIT_IMM && src1w == -1) || (src2 == SLJIT_IMM && src2w == -1)) {
2601 			return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2602 		}
2603 		/* fallthrough */
2604 	case SLJIT_AND:
2605 	case SLJIT_OR:
2606 		return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2607 
2608 	case SLJIT_SHL:
2609 	case SLJIT_MSHL:
2610 	case SLJIT_LSHR:
2611 	case SLJIT_MLSHR:
2612 	case SLJIT_ASHR:
2613 	case SLJIT_MASHR:
2614 	case SLJIT_ROTL:
2615 	case SLJIT_ROTR:
2616 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2617 		if (src2 == SLJIT_IMM)
2618 			src2w &= 0x1f;
2619 #else
2620 		if (src2 == SLJIT_IMM) {
2621 			if (op & SLJIT_32)
2622 				src2w &= 0x1f;
2623 			else
2624 				src2w &= 0x3f;
2625 		}
2626 #endif
2627 		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2628 	}
2629 
2630 	SLJIT_UNREACHABLE();
2631 	return SLJIT_SUCCESS;
2632 }
2633 
sljit_emit_op2u(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2634 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
2635 	sljit_s32 src1, sljit_sw src1w,
2636 	sljit_s32 src2, sljit_sw src2w)
2637 {
2638 	CHECK_ERROR();
2639 	CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
2640 
2641 	SLJIT_SKIP_CHECKS(compiler);
2642 	return sljit_emit_op2(compiler, op, 0, 0, src1, src1w, src2, src2w);
2643 }
2644 
2645 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2646 #define SELECT_OP3(op, src2w, D, D32, W) (((op & SLJIT_32) ? (W) : ((src2w) < 32) ? (D) : (D32)) | (((sljit_ins)src2w & 0x1f) << 6))
2647 #else /* !SLJIT_CONFIG_MIPS_64 */
2648 #define SELECT_OP3(op, src2w, D, D32, W) ((W) | ((sljit_ins)(src2w) << 6))
2649 #endif /* SLJIT_CONFIG_MIPS_64 */
2650 
sljit_emit_op2r(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst_reg,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2651 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
2652 	sljit_s32 dst_reg,
2653 	sljit_s32 src1, sljit_sw src1w,
2654 	sljit_s32 src2, sljit_sw src2w)
2655 {
2656 	CHECK_ERROR();
2657 	CHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));
2658 
2659 	switch (GET_OPCODE(op)) {
2660 	case SLJIT_MULADD:
2661 		SLJIT_SKIP_CHECKS(compiler);
2662 		FAIL_IF(sljit_emit_op2(compiler, SLJIT_MUL | (op & SLJIT_32), TMP_REG2, 0, src1, src1w, src2, src2w));
2663 		return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst_reg) | T(TMP_REG2) | D(dst_reg), DR(dst_reg));
2664 	}
2665 
2666 	return SLJIT_SUCCESS;
2667 }
2668 
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)2669 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
2670 	sljit_s32 dst_reg,
2671 	sljit_s32 src1_reg,
2672 	sljit_s32 src2_reg,
2673 	sljit_s32 src3, sljit_sw src3w)
2674 {
2675 	sljit_s32 is_left;
2676 	sljit_ins ins1, ins2, ins3;
2677 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2678 	sljit_s32 inp_flags = ((op & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
2679 	sljit_sw bit_length = (op & SLJIT_32) ? 32 : 64;
2680 #else /* !SLJIT_CONFIG_MIPS_64 */
2681 	sljit_s32 inp_flags = WORD_DATA | LOAD_DATA;
2682 	sljit_sw bit_length = 32;
2683 #endif /* SLJIT_CONFIG_MIPS_64 */
2684 
2685 	CHECK_ERROR();
2686 	CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w));
2687 
2688 	is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL);
2689 
2690 	if (src1_reg == src2_reg) {
2691 		SLJIT_SKIP_CHECKS(compiler);
2692 		return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w);
2693 	}
2694 
2695 	ADJUST_LOCAL_OFFSET(src3, src3w);
2696 
2697 	if (src3 == SLJIT_IMM) {
2698 		src3w &= bit_length - 1;
2699 
2700 		if (src3w == 0)
2701 			return SLJIT_SUCCESS;
2702 
2703 		if (is_left) {
2704 			ins1 = SELECT_OP3(op, src3w, DSLL, DSLL32, SLL);
2705 			src3w = bit_length - src3w;
2706 			ins2 = SELECT_OP3(op, src3w, DSRL, DSRL32, SRL);
2707 		} else {
2708 			ins1 = SELECT_OP3(op, src3w, DSRL, DSRL32, SRL);
2709 			src3w = bit_length - src3w;
2710 			ins2 = SELECT_OP3(op, src3w, DSLL, DSLL32, SLL);
2711 		}
2712 
2713 		FAIL_IF(push_inst(compiler, ins1 | T(src1_reg) | D(dst_reg), DR(dst_reg)));
2714 		FAIL_IF(push_inst(compiler, ins2 | T(src2_reg) | D(TMP_REG1), DR(TMP_REG1)));
2715 		return push_inst(compiler, OR | S(dst_reg) | T(TMP_REG1) | D(dst_reg), DR(dst_reg));
2716 	}
2717 
2718 	if (src3 & SLJIT_MEM) {
2719 		FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG2), src3, src3w));
2720 		src3 = TMP_REG2;
2721 	} else if (dst_reg == src3) {
2722 		FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src3) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
2723 		src3 = TMP_REG2;
2724 	}
2725 
2726 	if (is_left) {
2727 		ins1 = SELECT_OP(DSRL, SRL);
2728 		ins2 = SELECT_OP(DSLLV, SLLV);
2729 		ins3 = SELECT_OP(DSRLV, SRLV);
2730 	} else {
2731 		ins1 = SELECT_OP(DSLL, SLL);
2732 		ins2 = SELECT_OP(DSRLV, SRLV);
2733 		ins3 = SELECT_OP(DSLLV, SLLV);
2734 	}
2735 
2736 	FAIL_IF(push_inst(compiler, ins2 | S(src3) | T(src1_reg) | D(dst_reg), DR(dst_reg)));
2737 
2738 	if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) {
2739 		FAIL_IF(push_inst(compiler, ins1 | T(src2_reg) | D(TMP_REG1) | (1 << 6), DR(TMP_REG1)));
2740 		FAIL_IF(push_inst(compiler, XORI | S(src3) | T(TMP_REG2) | ((sljit_ins)bit_length - 1), DR(TMP_REG2)));
2741 		src2_reg = TMP_REG1;
2742 	} else
2743 		FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src3) | D(TMP_REG2), DR(TMP_REG2)));
2744 
2745 	FAIL_IF(push_inst(compiler, ins3 | S(TMP_REG2) | T(src2_reg) | D(TMP_REG1), DR(TMP_REG1)));
2746 	return push_inst(compiler, OR | S(dst_reg) | T(TMP_REG1) | D(dst_reg), DR(dst_reg));
2747 }
2748 
2749 #undef SELECT_OP3
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 & SLJIT_MEM))
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 ((dst & SLJIT_MEM) && !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 		} else {
3169 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
3170 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
3171 		}
3172 	}
3173 	else if (flags & SLOW_SRC1)
3174 		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
3175 	else if (flags & SLOW_SRC2)
3176 		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
3177 
3178 	if (flags & SLOW_SRC1)
3179 		src1 = TMP_FREG1;
3180 	if (flags & SLOW_SRC2)
3181 		src2 = TMP_FREG2;
3182 
3183 	switch (GET_OPCODE(op)) {
3184 	case SLJIT_ADD_F64:
3185 		FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
3186 		break;
3187 	case SLJIT_SUB_F64:
3188 		FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
3189 		break;
3190 	case SLJIT_MUL_F64:
3191 		FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
3192 		break;
3193 	case SLJIT_DIV_F64:
3194 		FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
3195 		break;
3196 	case SLJIT_COPYSIGN_F64:
3197 		return emit_copysign(compiler, op, src1, src2, dst_r);
3198 	}
3199 
3200 	if (dst_r == TMP_FREG2)
3201 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG2), dst, dstw, 0, 0));
3202 
3203 	return SLJIT_SUCCESS;
3204 }
3205 
sljit_emit_fset32(struct sljit_compiler * compiler,sljit_s32 freg,sljit_f32 value)3206 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,
3207 	sljit_s32 freg, sljit_f32 value)
3208 {
3209 	union {
3210 		sljit_s32 imm;
3211 		sljit_f32 value;
3212 	} u;
3213 
3214 	CHECK_ERROR();
3215 	CHECK(check_sljit_emit_fset32(compiler, freg, value));
3216 
3217 	u.value = value;
3218 
3219 	if (u.imm == 0)
3220 		return push_inst(compiler, MTC1 | TA(0) | FS(freg), MOVABLE_INS);
3221 
3222 	FAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.imm));
3223 	return push_inst(compiler, MTC1 | T(TMP_REG1) | FS(freg), MOVABLE_INS);
3224 }
3225 
3226 /* --------------------------------------------------------------------- */
3227 /*  Conditional instructions                                             */
3228 /* --------------------------------------------------------------------- */
3229 
sljit_emit_label(struct sljit_compiler * compiler)3230 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
3231 {
3232 	struct sljit_label *label;
3233 
3234 	CHECK_ERROR_PTR();
3235 	CHECK_PTR(check_sljit_emit_label(compiler));
3236 
3237 	if (compiler->last_label && compiler->last_label->size == compiler->size)
3238 		return compiler->last_label;
3239 
3240 	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
3241 	PTR_FAIL_IF(!label);
3242 	set_label(label, compiler);
3243 	compiler->delay_slot = UNMOVABLE_INS;
3244 	return label;
3245 }
3246 
3247 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3248 #define BRANCH_LENGTH	4
3249 #else
3250 #define BRANCH_LENGTH	8
3251 #endif
3252 
3253 #define BR_Z(src) \
3254 	inst = BEQ | SA(src) | TA(0) | BRANCH_LENGTH; \
3255 	flags = IS_BIT26_COND; \
3256 	delay_check = src;
3257 
3258 #define BR_NZ(src) \
3259 	inst = BNE | SA(src) | TA(0) | BRANCH_LENGTH; \
3260 	flags = IS_BIT26_COND; \
3261 	delay_check = src;
3262 
3263 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
3264 
3265 #define BR_T() \
3266 	inst = BC1NEZ; \
3267 	flags = IS_BIT23_COND; \
3268 	delay_check = FCSR_FCC;
3269 #define BR_F() \
3270 	inst = BC1EQZ; \
3271 	flags = IS_BIT23_COND; \
3272 	delay_check = FCSR_FCC;
3273 
3274 #else /* SLJIT_MIPS_REV < 6 */
3275 
3276 #define BR_T() \
3277 	inst = BC1T | BRANCH_LENGTH; \
3278 	flags = IS_BIT16_COND; \
3279 	delay_check = FCSR_FCC;
3280 #define BR_F() \
3281 	inst = BC1F | BRANCH_LENGTH; \
3282 	flags = IS_BIT16_COND; \
3283 	delay_check = FCSR_FCC;
3284 
3285 #endif /* SLJIT_MIPS_REV >= 6 */
3286 
sljit_emit_jump(struct sljit_compiler * compiler,sljit_s32 type)3287 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
3288 {
3289 	struct sljit_jump *jump;
3290 	sljit_ins inst;
3291 	sljit_u32 flags = 0;
3292 	sljit_s32 delay_check = UNMOVABLE_INS;
3293 
3294 	CHECK_ERROR_PTR();
3295 	CHECK_PTR(check_sljit_emit_jump(compiler, type));
3296 
3297 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
3298 	PTR_FAIL_IF(!jump);
3299 	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
3300 	type &= 0xff;
3301 
3302 	switch (type) {
3303 	case SLJIT_EQUAL:
3304 		BR_NZ(EQUAL_FLAG);
3305 		break;
3306 	case SLJIT_NOT_EQUAL:
3307 		BR_Z(EQUAL_FLAG);
3308 		break;
3309 	case SLJIT_LESS:
3310 	case SLJIT_GREATER:
3311 	case SLJIT_SIG_LESS:
3312 	case SLJIT_SIG_GREATER:
3313 	case SLJIT_OVERFLOW:
3314 	case SLJIT_CARRY:
3315 		BR_Z(OTHER_FLAG);
3316 		break;
3317 	case SLJIT_GREATER_EQUAL:
3318 	case SLJIT_LESS_EQUAL:
3319 	case SLJIT_SIG_GREATER_EQUAL:
3320 	case SLJIT_SIG_LESS_EQUAL:
3321 	case SLJIT_NOT_OVERFLOW:
3322 	case SLJIT_NOT_CARRY:
3323 		BR_NZ(OTHER_FLAG);
3324 		break;
3325 	case SLJIT_F_NOT_EQUAL:
3326 	case SLJIT_F_GREATER_EQUAL:
3327 	case SLJIT_F_GREATER:
3328 	case SLJIT_UNORDERED_OR_NOT_EQUAL:
3329 	case SLJIT_ORDERED_NOT_EQUAL:
3330 	case SLJIT_UNORDERED_OR_GREATER_EQUAL:
3331 	case SLJIT_ORDERED_GREATER_EQUAL:
3332 	case SLJIT_ORDERED_GREATER:
3333 	case SLJIT_UNORDERED_OR_GREATER:
3334 	case SLJIT_ORDERED:
3335 		BR_T();
3336 		break;
3337 	case SLJIT_F_EQUAL:
3338 	case SLJIT_F_LESS:
3339 	case SLJIT_F_LESS_EQUAL:
3340 	case SLJIT_ORDERED_EQUAL:
3341 	case SLJIT_UNORDERED_OR_EQUAL:
3342 	case SLJIT_ORDERED_LESS:
3343 	case SLJIT_UNORDERED_OR_LESS:
3344 	case SLJIT_UNORDERED_OR_LESS_EQUAL:
3345 	case SLJIT_ORDERED_LESS_EQUAL:
3346 	case SLJIT_UNORDERED:
3347 		BR_F();
3348 		break;
3349 	default:
3350 		/* Not conditional branch. */
3351 		inst = 0;
3352 		break;
3353 	}
3354 
3355 	jump->flags |= flags;
3356 	if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check))
3357 		jump->flags |= IS_MOVABLE;
3358 
3359 	if (inst)
3360 		PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));
3361 
3362 	if (type <= SLJIT_JUMP)
3363 		PTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
3364 	else {
3365 		jump->flags |= IS_JAL;
3366 		PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
3367 	}
3368 
3369 	jump->addr = compiler->size;
3370 	PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3371 
3372 	/* Maximum number of instructions required for generating a constant. */
3373 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3374 	compiler->size += 2;
3375 #else
3376 	compiler->size += 6;
3377 #endif
3378 	return jump;
3379 }
3380 
3381 #define RESOLVE_IMM1() \
3382 	if (src1 == SLJIT_IMM) { \
3383 		if (src1w) { \
3384 			PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \
3385 			src1 = TMP_REG1; \
3386 		} \
3387 		else \
3388 			src1 = 0; \
3389 	}
3390 
3391 #define RESOLVE_IMM2() \
3392 	if (src2 == SLJIT_IMM) { \
3393 		if (src2w) { \
3394 			PTR_FAIL_IF(load_immediate(compiler, DR(src2_tmp_reg), src2w)); \
3395 			src2 = src2_tmp_reg; \
3396 		} \
3397 		else \
3398 			src2 = 0; \
3399 	}
3400 
sljit_emit_cmp(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)3401 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
3402 	sljit_s32 src1, sljit_sw src1w,
3403 	sljit_s32 src2, sljit_sw src2w)
3404 {
3405 	struct sljit_jump *jump;
3406 	sljit_s32 flags;
3407 	sljit_ins inst;
3408 	sljit_s32 src2_tmp_reg = FAST_IS_REG(src1) ? TMP_REG1 : TMP_REG2;
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(src2_tmp_reg), src2, src2w, 0, 0));
3430 		src2 = src2_tmp_reg;
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(PIC_ADDR_REG), 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 = PIC_ADDR_REG;
3557 	} else if (src & SLJIT_MEM) {
3558 		ADJUST_LOCAL_OFFSET(src, srcw);
3559 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
3560 		src = PIC_ADDR_REG;
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_REG1), src1, src1w));
3759 		src1 = TMP_REG1;
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_REG1), DR(TMP_REG1)));
3788 
3789 				if ((src1 & REG_MASK) == dst_reg)
3790 					src1 = (src1 & ~REG_MASK) | TMP_REG1;
3791 
3792 				if (OFFS_REG(src1) == dst_reg)
3793 					src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);
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_FREG2), src1, src1w));
3851 		src1 = TMP_FREG2;
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_mov_addr(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)4234 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
4235 {
4236 	struct sljit_jump *jump;
4237 	sljit_s32 dst_r;
4238 
4239 	CHECK_ERROR_PTR();
4240 	CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
4241 	ADJUST_LOCAL_OFFSET(dst, dstw);
4242 
4243 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
4244 	PTR_FAIL_IF(!jump);
4245 	set_mov_addr(jump, 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 jump;
4259 }
4260