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