NCBI C++ ToolKit
sljitNativeMIPS_common.c
Go to the documentation of this file.

Go to the SVN repository for this file.

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 
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 */
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 
372 
373 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
374  && (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
375 
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 
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. */
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 
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 
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__
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 
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 
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 
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);
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 
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);
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 
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)
842  if (!cpu_feature_list)
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)
850 
851  return (cpu_feature_list & CPU_FEATURE_FPU) != 0;
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 
876 {
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 
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)));
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 
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 
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)
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 
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 
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. */
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. */
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. */
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 
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 
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 
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. */
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 
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)));
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)));
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 
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 
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:
2118  break;
2119 
2120  case SLJIT_LSHR:
2121  case SLJIT_MLSHR:
2123  break;
2124 
2125  case SLJIT_ASHR:
2126  case SLJIT_MASHR:
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:
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 
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 
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:
2467  return SLJIT_SUCCESS;
2468  }
2469 
2470  return SLJIT_SUCCESS;
2471 }
2472 
2473 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
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 
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)
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 
2558  return SLJIT_SUCCESS;
2559 }
2560 
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 
2631  return SLJIT_SUCCESS;
2632 }
2633 
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 
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 
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 
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);
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 
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;
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 
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 
2827  void *instruction, sljit_u32 size)
2828 {
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 
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 
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 
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 
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:
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:
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:
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 
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;
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 
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 
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 
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 
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:
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:
3332  case SLJIT_ORDERED_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:
3342  case SLJIT_ORDERED_LESS:
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 
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)
3419 #else /* !SLJIT_CONFIG_MIPS_32 */
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;
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;
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 {
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  }
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  }
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 
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 
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:
3639  case SLJIT_ORDERED_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 
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:
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:
3709  case SLJIT_ORDERED_LESS:
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:
3722  case SLJIT_ORDERED_GREATER:
3724  case SLJIT_ORDERED:
3725  return is_float ? MOVF_S : MOVF;
3726  default:
3728  return (is_float ? MOVZ_S : MOVZ) | TA(OTHER_FLAG);
3729  }
3730 }
3731 
3732 #endif /* SLJIT_MIPS_REV >= 1 */
3733 
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 
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