2 * Stack-less Just-In-Time compiler
4 * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
6 * Redistribution and use in source and binary forms, with or without modification, are
7 * permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice, this list of
10 * conditions and the following disclaimer.
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.
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.
27 /* Latest MIPS architecture. */
29 #ifndef __mips_hard_float
30 /* Disable automatic detection, covers both -msoft-float and -mno-float */
31 #undef SLJIT_IS_FPU_AVAILABLE
32 #define SLJIT_IS_FPU_AVAILABLE 0
35 SLJIT_API_FUNC_ATTRIBUTE
const char* sljit_get_platform_name(void)
37 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
39 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
40 return "MIPS32-R6" SLJIT_CPUINFO
;
41 #else /* !SLJIT_CONFIG_MIPS_32 */
42 return "MIPS64-R6" SLJIT_CPUINFO
;
43 #endif /* SLJIT_CONFIG_MIPS_32 */
45 #elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
47 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
48 return "MIPS32-R1" SLJIT_CPUINFO
;
49 #else /* !SLJIT_CONFIG_MIPS_32 */
50 return "MIPS64-R1" SLJIT_CPUINFO
;
51 #endif /* SLJIT_CONFIG_MIPS_32 */
53 #else /* SLJIT_MIPS_REV < 1 */
54 return "MIPS III" SLJIT_CPUINFO
;
55 #endif /* SLJIT_MIPS_REV >= 6 */
58 /* Length of an instruction word
59 Both for mips-32 and mips-64 */
60 typedef sljit_u32 sljit_ins
;
62 #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
63 #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
64 #define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
66 /* For position independent code, t9 must contain the function address. */
67 #define PIC_ADDR_REG TMP_REG2
69 /* Floating point status register. */
71 /* Return address register. */
72 #define RETURN_ADDR_REG 31
74 /* Flags are kept in volatile registers. */
78 #define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
79 #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
80 #define TMP_FREG3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3)
82 static const sljit_u8 reg_map
[SLJIT_NUMBER_OF_REGISTERS
+ 5] = {
83 0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31
86 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
88 static const sljit_u8 freg_map
[SLJIT_NUMBER_OF_FLOAT_REGISTERS
+ 4] = {
89 0, 0, 14, 2, 4, 6, 8, 18, 30, 28, 26, 24, 22, 20, 12, 10, 16
94 static const sljit_u8 freg_map
[SLJIT_NUMBER_OF_FLOAT_REGISTERS
+ 4] = {
95 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 31, 30, 29, 28, 27, 26, 25, 24, 12, 11, 10
100 /* --------------------------------------------------------------------- */
101 /* Instrucion forms */
102 /* --------------------------------------------------------------------- */
104 #define S(s) ((sljit_ins)reg_map[s] << 21)
105 #define T(t) ((sljit_ins)reg_map[t] << 16)
106 #define D(d) ((sljit_ins)reg_map[d] << 11)
107 #define FT(t) ((sljit_ins)freg_map[t] << 16)
108 #define FS(s) ((sljit_ins)freg_map[s] << 11)
109 #define FD(d) ((sljit_ins)freg_map[d] << 6)
110 /* Absolute registers. */
111 #define SA(s) ((sljit_ins)(s) << 21)
112 #define TA(t) ((sljit_ins)(t) << 16)
113 #define DA(d) ((sljit_ins)(d) << 11)
114 #define IMM(imm) ((sljit_ins)(imm) & 0xffff)
115 #define SH_IMM(imm) ((sljit_ins)(imm) << 6)
117 #define DR(dr) (reg_map[dr])
118 #define FR(dr) (freg_map[dr])
119 #define HI(opcode) ((sljit_ins)(opcode) << 26)
120 #define LO(opcode) ((sljit_ins)(opcode))
121 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
123 /* S = (20 << 21) D = (21 << 21) */
124 #define CMP_FMT_S (20 << 21)
125 #endif /* SLJIT_MIPS_REV >= 6 */
126 /* S = (16 << 21) D = (17 << 21) */
127 #define FMT_S (16 << 21)
128 #define FMT_D (17 << 21)
130 #define ABS_S (HI(17) | FMT_S | LO(5))
131 #define ADD_S (HI(17) | FMT_S | LO(0))
132 #define ADDIU (HI(9))
133 #define ADDU (HI(0) | LO(33))
134 #define AND (HI(0) | LO(36))
135 #define ANDI (HI(12))
137 #define BAL (HI(1) | (17 << 16))
138 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
139 #define BC1EQZ (HI(17) | (9 << 21) | FT(TMP_FREG3))
140 #define BC1NEZ (HI(17) | (13 << 21) | FT(TMP_FREG3))
141 #else /* SLJIT_MIPS_REV < 6 */
142 #define BC1F (HI(17) | (8 << 21))
143 #define BC1T (HI(17) | (8 << 21) | (1 << 16))
144 #endif /* SLJIT_MIPS_REV >= 6 */
146 #define BGEZ (HI(1) | (1 << 16))
149 #define BLTZ (HI(1) | (0 << 16))
151 #define BREAK (HI(0) | LO(13))
152 #define CFC1 (HI(17) | (2 << 21))
153 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
154 #define C_EQ_S (HI(17) | CMP_FMT_S | LO(2))
155 #define C_OLE_S (HI(17) | CMP_FMT_S | LO(6))
156 #define C_OLT_S (HI(17) | CMP_FMT_S | LO(4))
157 #define C_UEQ_S (HI(17) | CMP_FMT_S | LO(3))
158 #define C_ULE_S (HI(17) | CMP_FMT_S | LO(7))
159 #define C_ULT_S (HI(17) | CMP_FMT_S | LO(5))
160 #define C_UN_S (HI(17) | CMP_FMT_S | LO(1))
161 #define C_FD (FD(TMP_FREG3))
162 #else /* SLJIT_MIPS_REV < 6 */
163 #define C_EQ_S (HI(17) | FMT_S | LO(50))
164 #define C_OLE_S (HI(17) | FMT_S | LO(54))
165 #define C_OLT_S (HI(17) | FMT_S | LO(52))
166 #define C_UEQ_S (HI(17) | FMT_S | LO(51))
167 #define C_ULE_S (HI(17) | FMT_S | LO(55))
168 #define C_ULT_S (HI(17) | FMT_S | LO(53))
169 #define C_UN_S (HI(17) | FMT_S | LO(49))
171 #endif /* SLJIT_MIPS_REV >= 6 */
172 #define CVT_S_S (HI(17) | FMT_S | LO(32))
173 #define DADDIU (HI(25))
174 #define DADDU (HI(0) | LO(45))
175 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
176 #define DDIV (HI(0) | (2 << 6) | LO(30))
177 #define DDIVU (HI(0) | (2 << 6) | LO(31))
178 #define DMOD (HI(0) | (3 << 6) | LO(30))
179 #define DMODU (HI(0) | (3 << 6) | LO(31))
180 #define DIV (HI(0) | (2 << 6) | LO(26))
181 #define DIVU (HI(0) | (2 << 6) | LO(27))
182 #define DMUH (HI(0) | (3 << 6) | LO(28))
183 #define DMUHU (HI(0) | (3 << 6) | LO(29))
184 #define DMUL (HI(0) | (2 << 6) | LO(28))
185 #define DMULU (HI(0) | (2 << 6) | LO(29))
186 #else /* SLJIT_MIPS_REV < 6 */
187 #define DDIV (HI(0) | LO(30))
188 #define DDIVU (HI(0) | LO(31))
189 #define DIV (HI(0) | LO(26))
190 #define DIVU (HI(0) | LO(27))
191 #define DMULT (HI(0) | LO(28))
192 #define DMULTU (HI(0) | LO(29))
193 #endif /* SLJIT_MIPS_REV >= 6 */
194 #define DIV_S (HI(17) | FMT_S | LO(3))
195 #define DINSU (HI(31) | LO(6))
196 #define DSLL (HI(0) | LO(56))
197 #define DSLL32 (HI(0) | LO(60))
198 #define DSLLV (HI(0) | LO(20))
199 #define DSRA (HI(0) | LO(59))
200 #define DSRA32 (HI(0) | LO(63))
201 #define DSRAV (HI(0) | LO(23))
202 #define DSRL (HI(0) | LO(58))
203 #define DSRL32 (HI(0) | LO(62))
204 #define DSRLV (HI(0) | LO(22))
205 #define DSUBU (HI(0) | LO(47))
208 #define JALR (HI(0) | LO(9))
209 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
210 #define JR (HI(0) | LO(9))
211 #else /* SLJIT_MIPS_REV < 6 */
212 #define JR (HI(0) | LO(8))
213 #endif /* SLJIT_MIPS_REV >= 6 */
217 #define LDC1 (HI(53))
222 #define LWC1 (HI(49))
223 #define MFC1 (HI(17))
224 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
225 #define MOD (HI(0) | (3 << 6) | LO(26))
226 #define MODU (HI(0) | (3 << 6) | LO(27))
227 #else /* SLJIT_MIPS_REV < 6 */
228 #define MFHI (HI(0) | LO(16))
229 #define MFLO (HI(0) | LO(18))
230 #endif /* SLJIT_MIPS_REV >= 6 */
231 #define MOV_S (HI(17) | FMT_S | LO(6))
232 #define MTC1 (HI(17) | (4 << 21))
233 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
234 #define MUH (HI(0) | (3 << 6) | LO(24))
235 #define MUHU (HI(0) | (3 << 6) | LO(25))
236 #define MUL (HI(0) | (2 << 6) | LO(24))
237 #define MULU (HI(0) | (2 << 6) | LO(25))
238 #else /* SLJIT_MIPS_REV < 6 */
239 #define MULT (HI(0) | LO(24))
240 #define MULTU (HI(0) | LO(25))
241 #endif /* SLJIT_MIPS_REV >= 6 */
242 #define MUL_S (HI(17) | FMT_S | LO(2))
243 #define NEG_S (HI(17) | FMT_S | LO(7))
244 #define NOP (HI(0) | LO(0))
245 #define NOR (HI(0) | LO(39))
246 #define OR (HI(0) | LO(37))
251 #define SDC1 (HI(61))
252 #define SLT (HI(0) | LO(42))
253 #define SLTI (HI(10))
254 #define SLTIU (HI(11))
255 #define SLTU (HI(0) | LO(43))
256 #define SLL (HI(0) | LO(0))
257 #define SLLV (HI(0) | LO(4))
258 #define SRL (HI(0) | LO(2))
259 #define SRLV (HI(0) | LO(6))
260 #define SRA (HI(0) | LO(3))
261 #define SRAV (HI(0) | LO(7))
262 #define SUB_S (HI(17) | FMT_S | LO(1))
263 #define SUBU (HI(0) | LO(35))
267 #define SWC1 (HI(57))
268 #define TRUNC_W_S (HI(17) | FMT_S | LO(13))
269 #define XOR (HI(0) | LO(38))
270 #define XORI (HI(14))
272 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
273 #define CLZ (HI(28) | LO(32))
274 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
275 #define DCLZ (LO(18))
276 #else /* SLJIT_MIPS_REV < 6 */
277 #define DCLZ (HI(28) | LO(36))
278 #define MOVF (HI(0) | (0 << 16) | LO(1))
279 #define MOVN (HI(0) | LO(11))
280 #define MOVT (HI(0) | (1 << 16) | LO(1))
281 #define MOVZ (HI(0) | LO(10))
282 #define MUL (HI(28) | LO(2))
283 #endif /* SLJIT_MIPS_REV >= 6 */
284 #define PREF (HI(51))
285 #define PREFX (HI(19) | LO(15))
286 #define SEB (HI(31) | (16 << 6) | LO(32))
287 #define SEH (HI(31) | (24 << 6) | LO(32))
288 #endif /* SLJIT_MIPS_REV >= 1 */
290 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
292 #define ADDIU_W ADDIU
298 #define ADDIU_W DADDIU
304 #define SIMM_MAX (0x7fff)
305 #define SIMM_MIN (-0x8000)
306 #define UIMM_MAX (0xffff)
308 /* dest_reg is the absolute name of the register
309 Useful for reordering instructions in the delay slot. */
310 static sljit_s32
push_inst(struct sljit_compiler
*compiler
, sljit_ins ins
, sljit_s32 delay_slot
)
312 sljit_ins
*ptr
= (sljit_ins
*)ensure_buf(compiler
, sizeof(sljit_ins
));
313 SLJIT_ASSERT(delay_slot
== MOVABLE_INS
|| delay_slot
>= UNMOVABLE_INS
314 || (sljit_ins
)delay_slot
== ((ins
>> 11) & 0x1f)
315 || (sljit_ins
)delay_slot
== ((ins
>> 16) & 0x1f));
319 compiler
->delay_slot
= delay_slot
;
320 return SLJIT_SUCCESS
;
323 static SLJIT_INLINE sljit_ins
invert_branch(sljit_uw flags
)
325 if (flags
& IS_BIT26_COND
)
327 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
328 if (flags
& IS_BIT23_COND
)
330 #endif /* SLJIT_MIPS_REV >= 6 */
334 static SLJIT_INLINE sljit_ins
* detect_jump_type(struct sljit_jump
*jump
, sljit_ins
*code
, sljit_sw executable_offset
)
337 sljit_uw target_addr
;
339 sljit_ins saved_inst
;
341 inst
= (sljit_ins
*)jump
->addr
;
343 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
344 if (jump
->flags
& (SLJIT_REWRITABLE_JUMP
| IS_CALL
))
347 if (jump
->flags
& SLJIT_REWRITABLE_JUMP
)
351 if (jump
->flags
& JUMP_ADDR
)
352 target_addr
= jump
->u
.target
;
354 SLJIT_ASSERT(jump
->flags
& JUMP_LABEL
);
355 target_addr
= (sljit_uw
)(code
+ jump
->u
.label
->size
) + (sljit_uw
)executable_offset
;
358 if (jump
->flags
& IS_COND
)
361 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
362 if (jump
->flags
& IS_CALL
)
366 /* B instructions. */
367 if (jump
->flags
& IS_MOVABLE
) {
368 diff
= ((sljit_sw
)target_addr
- (sljit_sw
)inst
- executable_offset
) >> 2;
369 if (diff
<= SIMM_MAX
&& diff
>= SIMM_MIN
) {
370 jump
->flags
|= PATCH_B
;
372 if (!(jump
->flags
& IS_COND
)) {
374 inst
[-1] = (jump
->flags
& IS_JAL
) ? BAL
: B
;
375 jump
->addr
-= sizeof(sljit_ins
);
378 saved_inst
= inst
[0];
380 inst
[-1] = saved_inst
^ invert_branch(jump
->flags
);
381 jump
->addr
-= 2 * sizeof(sljit_ins
);
386 diff
= ((sljit_sw
)target_addr
- (sljit_sw
)(inst
+ 1) - executable_offset
) >> 2;
387 if (diff
<= SIMM_MAX
&& diff
>= SIMM_MIN
) {
388 jump
->flags
|= PATCH_B
;
390 if (!(jump
->flags
& IS_COND
)) {
391 inst
[0] = (jump
->flags
& IS_JAL
) ? BAL
: B
;
395 inst
[0] ^= invert_branch(jump
->flags
);
397 jump
->addr
-= sizeof(sljit_ins
);
402 if (jump
->flags
& IS_COND
) {
403 if ((jump
->flags
& IS_MOVABLE
) && (target_addr
& ~(sljit_uw
)0xfffffff) == ((jump
->addr
+ 2 * sizeof(sljit_ins
)) & ~(sljit_uw
)0xfffffff)) {
404 jump
->flags
|= PATCH_J
;
405 saved_inst
= inst
[0];
407 inst
[-1] = (saved_inst
& 0xffff0000) | 3;
412 else if ((target_addr
& ~(sljit_uw
)0xfffffff) == ((jump
->addr
+ 3 * sizeof(sljit_ins
)) & ~(sljit_uw
)0xfffffff)) {
413 jump
->flags
|= PATCH_J
;
414 inst
[0] = (inst
[0] & 0xffff0000) | 3;
418 jump
->addr
+= sizeof(sljit_ins
);
424 if ((jump
->flags
& IS_MOVABLE
) && (target_addr
& ~(sljit_uw
)0xfffffff) == (jump
->addr
& ~(sljit_uw
)0xfffffff)) {
425 jump
->flags
|= PATCH_J
;
427 inst
[-1] = (jump
->flags
& IS_JAL
) ? JAL
: J
;
428 jump
->addr
-= sizeof(sljit_ins
);
432 if ((target_addr
& ~(sljit_uw
)0xfffffff) == ((jump
->addr
+ sizeof(sljit_ins
)) & ~(sljit_uw
)0xfffffff)) {
433 jump
->flags
|= PATCH_J
;
434 inst
[0] = (jump
->flags
& IS_JAL
) ? JAL
: J
;
440 if (jump
->flags
& IS_COND
)
443 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
445 if (target_addr
<= 0x7fffffff) {
446 jump
->flags
|= PATCH_ABS32
;
447 if (jump
->flags
& IS_COND
)
454 if (target_addr
<= 0x7fffffffffffl
) {
455 jump
->flags
|= PATCH_ABS48
;
456 if (jump
->flags
& IS_COND
)
466 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
478 static __attribute__ ((noinline
)) void sljit_cache_flush(void* code
, void* code_ptr
)
480 SLJIT_CACHE_FLUSH(code
, code_ptr
);
484 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
486 static SLJIT_INLINE sljit_sw
put_label_get_length(struct sljit_put_label
*put_label
, sljit_uw max_label
)
488 if (max_label
< 0x80000000l
) {
489 put_label
->flags
= PATCH_ABS32
;
493 if (max_label
< 0x800000000000l
) {
494 put_label
->flags
= PATCH_ABS48
;
498 put_label
->flags
= 0;
502 #endif /* SLJIT_CONFIG_MIPS_64 */
504 static SLJIT_INLINE
void load_addr_to_reg(void *dst
, sljit_u32 reg
)
506 struct sljit_jump
*jump
;
507 struct sljit_put_label
*put_label
;
513 jump
= (struct sljit_jump
*)dst
;
515 inst
= (sljit_ins
*)jump
->addr
;
516 addr
= (flags
& JUMP_LABEL
) ? jump
->u
.label
->addr
: jump
->u
.target
;
518 put_label
= (struct sljit_put_label
*)dst
;
519 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
520 flags
= put_label
->flags
;
522 inst
= (sljit_ins
*)put_label
->addr
;
523 addr
= put_label
->label
->addr
;
527 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
528 inst
[0] = LUI
| T(reg
) | IMM(addr
>> 16);
529 #else /* !SLJIT_CONFIG_MIPS_32 */
530 if (flags
& PATCH_ABS32
) {
531 SLJIT_ASSERT(addr
< 0x80000000l
);
532 inst
[0] = LUI
| T(reg
) | IMM(addr
>> 16);
534 else if (flags
& PATCH_ABS48
) {
535 SLJIT_ASSERT(addr
< 0x800000000000l
);
536 inst
[0] = LUI
| T(reg
) | IMM(addr
>> 32);
537 inst
[1] = ORI
| S(reg
) | T(reg
) | IMM((addr
>> 16) & 0xffff);
538 inst
[2] = DSLL
| T(reg
) | D(reg
) | SH_IMM(16);
542 inst
[0] = LUI
| T(reg
) | IMM(addr
>> 48);
543 inst
[1] = ORI
| S(reg
) | T(reg
) | IMM((addr
>> 32) & 0xffff);
544 inst
[2] = DSLL
| T(reg
) | D(reg
) | SH_IMM(16);
545 inst
[3] = ORI
| S(reg
) | T(reg
) | IMM((addr
>> 16) & 0xffff);
546 inst
[4] = DSLL
| T(reg
) | D(reg
) | SH_IMM(16);
549 #endif /* SLJIT_CONFIG_MIPS_32 */
551 inst
[1] = ORI
| S(reg
) | T(reg
) | IMM(addr
& 0xffff);
554 SLJIT_API_FUNC_ATTRIBUTE
void* sljit_generate_code(struct sljit_compiler
*compiler
)
556 struct sljit_memory_fragment
*buf
;
563 sljit_sw executable_offset
;
566 struct sljit_label
*label
;
567 struct sljit_jump
*jump
;
568 struct sljit_const
*const_
;
569 struct sljit_put_label
*put_label
;
572 CHECK_PTR(check_sljit_generate_code(compiler
));
573 reverse_buf(compiler
);
575 code
= (sljit_ins
*)SLJIT_MALLOC_EXEC(compiler
->size
* sizeof(sljit_ins
), compiler
->exec_allocator_data
);
576 PTR_FAIL_WITH_EXEC_IF(code
);
582 executable_offset
= SLJIT_EXEC_OFFSET(code
);
584 label
= compiler
->labels
;
585 jump
= compiler
->jumps
;
586 const_
= compiler
->consts
;
587 put_label
= compiler
->put_labels
;
590 buf_ptr
= (sljit_ins
*)buf
->memory
;
591 buf_end
= buf_ptr
+ (buf
->used_size
>> 2);
593 *code_ptr
= *buf_ptr
++;
594 if (next_addr
== word_count
) {
595 SLJIT_ASSERT(!label
|| label
->size
>= word_count
);
596 SLJIT_ASSERT(!jump
|| jump
->addr
>= word_count
);
597 SLJIT_ASSERT(!const_
|| const_
->addr
>= word_count
);
598 SLJIT_ASSERT(!put_label
|| put_label
->addr
>= word_count
);
600 /* These structures are ordered by their address. */
601 if (label
&& label
->size
== word_count
) {
602 label
->addr
= (sljit_uw
)SLJIT_ADD_EXEC_OFFSET(code_ptr
, executable_offset
);
603 label
->size
= (sljit_uw
)(code_ptr
- code
);
606 if (jump
&& jump
->addr
== word_count
) {
607 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
612 jump
->addr
= (sljit_uw
)(code_ptr
- 1);
613 code_ptr
= detect_jump_type(jump
, code
, executable_offset
);
616 if (const_
&& const_
->addr
== word_count
) {
617 const_
->addr
= (sljit_uw
)code_ptr
;
618 const_
= const_
->next
;
620 if (put_label
&& put_label
->addr
== word_count
) {
621 SLJIT_ASSERT(put_label
->label
);
622 put_label
->addr
= (sljit_uw
)code_ptr
;
623 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
627 code_ptr
+= put_label_get_length(put_label
, (sljit_uw
)(SLJIT_ADD_EXEC_OFFSET(code
, executable_offset
) + put_label
->label
->size
));
630 put_label
= put_label
->next
;
632 next_addr
= compute_next_addr(label
, jump
, const_
, put_label
);
636 } while (buf_ptr
< buf_end
);
641 if (label
&& label
->size
== word_count
) {
642 label
->addr
= (sljit_uw
)code_ptr
;
643 label
->size
= (sljit_uw
)(code_ptr
- code
);
647 SLJIT_ASSERT(!label
);
649 SLJIT_ASSERT(!const_
);
650 SLJIT_ASSERT(!put_label
);
651 SLJIT_ASSERT(code_ptr
- code
<= (sljit_sw
)compiler
->size
);
653 jump
= compiler
->jumps
;
656 addr
= (jump
->flags
& JUMP_LABEL
) ? jump
->u
.label
->addr
: jump
->u
.target
;
657 buf_ptr
= (sljit_ins
*)jump
->addr
;
659 if (jump
->flags
& PATCH_B
) {
660 addr
= (sljit_uw
)((sljit_sw
)(addr
- (sljit_uw
)SLJIT_ADD_EXEC_OFFSET(buf_ptr
, executable_offset
) - sizeof(sljit_ins
)) >> 2);
661 SLJIT_ASSERT((sljit_sw
)addr
<= SIMM_MAX
&& (sljit_sw
)addr
>= SIMM_MIN
);
662 buf_ptr
[0] = (buf_ptr
[0] & 0xffff0000) | ((sljit_ins
)addr
& 0xffff);
665 if (jump
->flags
& PATCH_J
) {
666 SLJIT_ASSERT((addr
& ~(sljit_uw
)0xfffffff)
667 == (((sljit_uw
)SLJIT_ADD_EXEC_OFFSET(buf_ptr
, executable_offset
) + sizeof(sljit_ins
)) & ~(sljit_uw
)0xfffffff));
668 buf_ptr
[0] |= (sljit_ins
)(addr
>> 2) & 0x03ffffff;
672 load_addr_to_reg(jump
, PIC_ADDR_REG
);
677 put_label
= compiler
->put_labels
;
679 load_addr_to_reg(put_label
, 0);
680 put_label
= put_label
->next
;
683 compiler
->error
= SLJIT_ERR_COMPILED
;
684 compiler
->executable_offset
= executable_offset
;
685 compiler
->executable_size
= (sljit_uw
)(code_ptr
- code
) * sizeof(sljit_ins
);
687 code
= (sljit_ins
*)SLJIT_ADD_EXEC_OFFSET(code
, executable_offset
);
688 code_ptr
= (sljit_ins
*)SLJIT_ADD_EXEC_OFFSET(code_ptr
, executable_offset
);
691 SLJIT_CACHE_FLUSH(code
, code_ptr
);
693 /* GCC workaround for invalid code generation with -O2. */
694 sljit_cache_flush(code
, code_ptr
);
696 SLJIT_UPDATE_WX_FLAGS(code
, code_ptr
, 1);
700 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_has_cpu_feature(sljit_s32 feature_type
)
702 #if defined(__GNUC__) && !defined(SLJIT_IS_FPU_AVAILABLE)
704 #endif /* __GNUC__ && !SLJIT_IS_FPU_AVAILABLE */
706 switch (feature_type
) {
708 #ifdef SLJIT_IS_FPU_AVAILABLE
709 return SLJIT_IS_FPU_AVAILABLE
;
710 #elif defined(__GNUC__)
711 __asm__ ("cfc1 %0, $0" : "=r"(fir
));
712 return (fir
>> 22) & 0x1;
714 #error "FIR check is not implemented for this architecture"
716 case SLJIT_HAS_ZERO_REGISTER
:
719 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
722 case SLJIT_HAS_PREFETCH
:
724 #endif /* SLJIT_MIPS_REV >= 1 */
731 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_cmp_info(sljit_s32 type
)
733 return (type
>= SLJIT_ORDERED_EQUAL
&& type
<= SLJIT_ORDERED_LESS_EQUAL
);
736 /* --------------------------------------------------------------------- */
738 /* --------------------------------------------------------------------- */
740 /* Creates an index in data_transfer_insts array. */
741 #define LOAD_DATA 0x01
742 #define WORD_DATA 0x00
743 #define BYTE_DATA 0x02
744 #define HALF_DATA 0x04
745 #define INT_DATA 0x06
746 #define SIGNED_DATA 0x08
747 /* Separates integer and floating point registers */
749 #define DOUBLE_DATA 0x10
750 #define SINGLE_DATA 0x12
752 #define MEM_MASK 0x1f
754 #define ARG_TEST 0x00020
755 #define ALT_KEEP_CACHE 0x00040
756 #define CUMULATIVE_OP 0x00080
757 #define LOGICAL_OP 0x00100
758 #define IMM_OP 0x00200
759 #define MOVE_OP 0x00400
760 #define SRC2_IMM 0x00800
762 #define UNUSED_DEST 0x01000
763 #define REG_DEST 0x02000
764 #define REG1_SOURCE 0x04000
765 #define REG2_SOURCE 0x08000
766 #define SLOW_SRC1 0x10000
767 #define SLOW_SRC2 0x20000
768 #define SLOW_DEST 0x40000
770 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
771 #define STACK_STORE SW
772 #define STACK_LOAD LW
774 #define STACK_STORE SD
775 #define STACK_LOAD LD
778 static sljit_s32
emit_op_mem(struct sljit_compiler
*compiler
, sljit_s32 flags
, sljit_s32 reg_ar
, sljit_s32 arg
, sljit_sw argw
);
779 static sljit_s32
emit_stack_frame_release(struct sljit_compiler
*compiler
, sljit_s32 frame_size
, sljit_ins
*ins_ptr
);
781 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
782 #include "sljitNativeMIPS_32.c"
784 #include "sljitNativeMIPS_64.c"
787 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_enter(struct sljit_compiler
*compiler
,
788 sljit_s32 options
, sljit_s32 arg_types
, sljit_s32 scratches
, sljit_s32 saveds
,
789 sljit_s32 fscratches
, sljit_s32 fsaveds
, sljit_s32 local_size
)
792 sljit_s32 i
, tmp
, offset
;
793 sljit_s32 arg_count
, word_arg_count
, float_arg_count
;
794 sljit_s32 saved_arg_count
= SLJIT_KEPT_SAVEDS_COUNT(options
);
797 CHECK(check_sljit_emit_enter(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
));
798 set_emit_enter(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
);
800 local_size
+= GET_SAVED_REGISTERS_SIZE(scratches
, saveds
- saved_arg_count
, 1);
801 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
802 if (fsaveds
> 0 || fscratches
>= SLJIT_FIRST_SAVED_FLOAT_REG
) {
803 if ((local_size
& SSIZE_OF(sw
)) != 0)
804 local_size
+= SSIZE_OF(sw
);
805 local_size
+= GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches
, fsaveds
, sizeof(sljit_f64
));
808 local_size
= (local_size
+ SLJIT_LOCALS_OFFSET
+ 15) & ~0xf;
810 local_size
+= GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches
, fsaveds
, sizeof(sljit_f64
));
811 local_size
= (local_size
+ SLJIT_LOCALS_OFFSET
+ 31) & ~0x1f;
813 compiler
->local_size
= local_size
;
815 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
816 tmp
= arg_types
>> SLJIT_ARG_SHIFT
;
822 if ((tmp
& SLJIT_ARG_MASK
) == SLJIT_ARG_TYPE_F64
) {
823 if ((arg_count
& 0x1) != 0)
829 tmp
>>= SLJIT_ARG_SHIFT
;
832 compiler
->args_size
= (sljit_uw
)arg_count
<< 2;
833 offset
= (offset
>= 4) ? (offset
<< 2) : 0;
834 #else /* !SLJIT_CONFIG_MIPS_32 */
836 #endif /* SLJIT_CONFIG_MIPS_32 */
838 if (local_size
+ offset
<= -SIMM_MIN
) {
840 FAIL_IF(push_inst(compiler
, ADDIU_W
| S(SLJIT_SP
) | T(SLJIT_SP
) | IMM(-local_size
), DR(SLJIT_SP
)));
842 offset
= local_size
- SSIZE_OF(sw
);
844 FAIL_IF(load_immediate(compiler
, DR(OTHER_FLAG
), local_size
));
845 FAIL_IF(push_inst(compiler
, ADDU_W
| S(SLJIT_SP
) | TA(0) | D(TMP_REG2
), DR(TMP_REG2
)));
846 FAIL_IF(push_inst(compiler
, SUBU_W
| S(SLJIT_SP
) | T(OTHER_FLAG
) | D(SLJIT_SP
), DR(SLJIT_SP
)));
848 offset
= -SSIZE_OF(sw
);
849 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
854 FAIL_IF(push_inst(compiler
, STACK_STORE
| base
| TA(RETURN_ADDR_REG
) | IMM(offset
), MOVABLE_INS
));
856 tmp
= SLJIT_S0
- saveds
;
857 for (i
= SLJIT_S0
- saved_arg_count
; i
> tmp
; i
--) {
858 offset
-= SSIZE_OF(sw
);
859 FAIL_IF(push_inst(compiler
, STACK_STORE
| base
| T(i
) | IMM(offset
), MOVABLE_INS
));
862 for (i
= scratches
; i
>= SLJIT_FIRST_SAVED_REG
; i
--) {
863 offset
-= SSIZE_OF(sw
);
864 FAIL_IF(push_inst(compiler
, STACK_STORE
| base
| T(i
) | IMM(offset
), MOVABLE_INS
));
867 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
868 /* This alignment is valid because offset is not used after storing FPU regs. */
869 if ((offset
& SSIZE_OF(sw
)) != 0)
870 offset
-= SSIZE_OF(sw
);
873 tmp
= SLJIT_FS0
- fsaveds
;
874 for (i
= SLJIT_FS0
; i
> tmp
; i
--) {
875 offset
-= SSIZE_OF(f64
);
876 FAIL_IF(push_inst(compiler
, SDC1
| base
| FT(i
) | IMM(offset
), MOVABLE_INS
));
879 for (i
= fscratches
; i
>= SLJIT_FIRST_SAVED_FLOAT_REG
; i
--) {
880 offset
-= SSIZE_OF(f64
);
881 FAIL_IF(push_inst(compiler
, SDC1
| base
| FT(i
) | IMM(offset
), MOVABLE_INS
));
884 arg_types
>>= SLJIT_ARG_SHIFT
;
889 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
890 /* The first maximum two floating point arguments are passed in floating point
891 registers if no integer argument precedes them. The first 16 byte data is
892 passed in four integer registers, the rest is placed onto the stack.
893 The floating point registers are also part of the first 16 byte data, so
894 their corresponding integer registers are not used when they are present. */
897 switch (arg_types
& SLJIT_ARG_MASK
) {
898 case SLJIT_ARG_TYPE_F64
:
900 if ((arg_count
& 0x1) != 0)
903 if (word_arg_count
== 0 && float_arg_count
<= 2) {
904 if (float_arg_count
== 1)
905 FAIL_IF(push_inst(compiler
, MOV_S
| FMT_D
| FS(TMP_FREG1
) | FD(SLJIT_FR0
), MOVABLE_INS
));
906 } else if (arg_count
< 4) {
907 FAIL_IF(push_inst(compiler
, MTC1
| TA(4 + arg_count
) | FS(float_arg_count
), MOVABLE_INS
));
908 FAIL_IF(push_inst(compiler
, MTC1
| TA(5 + arg_count
) | FS(float_arg_count
) | (1 << 11), MOVABLE_INS
));
910 FAIL_IF(push_inst(compiler
, LDC1
| base
| FT(float_arg_count
) | IMM(local_size
+ (arg_count
<< 2)), MOVABLE_INS
));
913 case SLJIT_ARG_TYPE_F32
:
916 if (word_arg_count
== 0 && float_arg_count
<= 2) {
917 if (float_arg_count
== 1)
918 FAIL_IF(push_inst(compiler
, MOV_S
| FMT_S
| FS(TMP_FREG1
) | FD(SLJIT_FR0
), MOVABLE_INS
));
919 } else if (arg_count
< 4)
920 FAIL_IF(push_inst(compiler
, MTC1
| TA(4 + arg_count
) | FS(float_arg_count
), MOVABLE_INS
));
922 FAIL_IF(push_inst(compiler
, LWC1
| base
| FT(float_arg_count
) | IMM(local_size
+ (arg_count
<< 2)), MOVABLE_INS
));
927 if (!(arg_types
& SLJIT_ARG_TYPE_SCRATCH_REG
)) {
928 tmp
= SLJIT_S0
- saved_arg_count
;
930 } else if (word_arg_count
!= arg_count
+ 1 || arg_count
== 0)
931 tmp
= word_arg_count
;
936 FAIL_IF(push_inst(compiler
, ADDU_W
| SA(4 + arg_count
) | TA(0) | D(tmp
), DR(tmp
)));
938 FAIL_IF(push_inst(compiler
, LW
| base
| T(tmp
) | IMM(local_size
+ (arg_count
<< 2)), DR(tmp
)));
942 arg_types
>>= SLJIT_ARG_SHIFT
;
945 SLJIT_ASSERT(compiler
->args_size
== (sljit_uw
)arg_count
<< 2);
946 #else /* !SLJIT_CONFIG_MIPS_32 */
949 switch (arg_types
& SLJIT_ARG_MASK
) {
950 case SLJIT_ARG_TYPE_F64
:
952 if (arg_count
!= float_arg_count
)
953 FAIL_IF(push_inst(compiler
, MOV_S
| FMT_D
| FS(arg_count
) | FD(float_arg_count
), MOVABLE_INS
));
954 else if (arg_count
== 1)
955 FAIL_IF(push_inst(compiler
, MOV_S
| FMT_D
| FS(TMP_FREG1
) | FD(SLJIT_FR0
), MOVABLE_INS
));
957 case SLJIT_ARG_TYPE_F32
:
959 if (arg_count
!= float_arg_count
)
960 FAIL_IF(push_inst(compiler
, MOV_S
| FMT_S
| FS(arg_count
) | FD(float_arg_count
), MOVABLE_INS
));
961 else if (arg_count
== 1)
962 FAIL_IF(push_inst(compiler
, MOV_S
| FMT_S
| FS(TMP_FREG1
) | FD(SLJIT_FR0
), MOVABLE_INS
));
967 if (!(arg_types
& SLJIT_ARG_TYPE_SCRATCH_REG
)) {
968 tmp
= SLJIT_S0
- saved_arg_count
;
970 } else if (word_arg_count
!= arg_count
|| word_arg_count
<= 1)
971 tmp
= word_arg_count
;
975 FAIL_IF(push_inst(compiler
, ADDU_W
| SA(3 + arg_count
) | TA(0) | D(tmp
), DR(tmp
)));
978 arg_types
>>= SLJIT_ARG_SHIFT
;
980 #endif /* SLJIT_CONFIG_MIPS_32 */
982 return SLJIT_SUCCESS
;
985 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_set_context(struct sljit_compiler
*compiler
,
986 sljit_s32 options
, sljit_s32 arg_types
, sljit_s32 scratches
, sljit_s32 saveds
,
987 sljit_s32 fscratches
, sljit_s32 fsaveds
, sljit_s32 local_size
)
990 CHECK(check_sljit_set_context(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
));
991 set_set_context(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
);
993 local_size
+= GET_SAVED_REGISTERS_SIZE(scratches
, saveds
- SLJIT_KEPT_SAVEDS_COUNT(options
), 1);
994 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
995 if (fsaveds
> 0 || fscratches
>= SLJIT_FIRST_SAVED_FLOAT_REG
) {
996 if ((local_size
& SSIZE_OF(sw
)) != 0)
997 local_size
+= SSIZE_OF(sw
);
998 local_size
+= GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches
, fsaveds
, sizeof(sljit_f64
));
1001 compiler
->local_size
= (local_size
+ SLJIT_LOCALS_OFFSET
+ 15) & ~0xf;
1003 local_size
+= GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches
, fsaveds
, sizeof(sljit_f64
));
1004 compiler
->local_size
= (local_size
+ SLJIT_LOCALS_OFFSET
+ 31) & ~0x1f;
1006 return SLJIT_SUCCESS
;
1009 static sljit_s32
emit_stack_frame_release(struct sljit_compiler
*compiler
, sljit_s32 frame_size
, sljit_ins
*ins_ptr
)
1011 sljit_s32 local_size
, i
, tmp
, offset
;
1012 sljit_s32 scratches
= compiler
->scratches
;
1013 sljit_s32 saveds
= compiler
->saveds
;
1014 sljit_s32 fsaveds
= compiler
->fsaveds
;
1015 sljit_s32 fscratches
= compiler
->fscratches
;
1016 sljit_s32 kept_saveds_count
= SLJIT_KEPT_SAVEDS_COUNT(compiler
->options
);
1018 local_size
= compiler
->local_size
;
1020 tmp
= GET_SAVED_REGISTERS_SIZE(scratches
, saveds
- kept_saveds_count
, 1);
1021 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1022 if (fsaveds
> 0 || fscratches
>= SLJIT_FIRST_SAVED_FLOAT_REG
) {
1023 if ((tmp
& SSIZE_OF(sw
)) != 0)
1024 tmp
+= SSIZE_OF(sw
);
1025 tmp
+= GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches
, fsaveds
, sizeof(sljit_f64
));
1028 tmp
+= GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches
, fsaveds
, sizeof(sljit_f64
));
1031 if (local_size
<= SIMM_MAX
) {
1032 if (local_size
< frame_size
) {
1033 FAIL_IF(push_inst(compiler
, ADDIU_W
| S(SLJIT_SP
) | T(SLJIT_SP
) | IMM(local_size
- frame_size
), DR(SLJIT_SP
)));
1034 local_size
= frame_size
;
1037 if (tmp
< frame_size
)
1040 FAIL_IF(load_immediate(compiler
, DR(TMP_REG1
), local_size
- tmp
));
1041 FAIL_IF(push_inst(compiler
, ADDU_W
| S(SLJIT_SP
) | T(TMP_REG1
) | D(SLJIT_SP
), DR(SLJIT_SP
)));
1045 SLJIT_ASSERT(local_size
>= frame_size
);
1047 offset
= local_size
- SSIZE_OF(sw
);
1048 if (frame_size
== 0)
1049 FAIL_IF(push_inst(compiler
, STACK_LOAD
| S(SLJIT_SP
) | TA(RETURN_ADDR_REG
) | IMM(offset
), RETURN_ADDR_REG
));
1051 tmp
= SLJIT_S0
- saveds
;
1052 for (i
= SLJIT_S0
- kept_saveds_count
; i
> tmp
; i
--) {
1053 offset
-= SSIZE_OF(sw
);
1054 FAIL_IF(push_inst(compiler
, STACK_LOAD
| S(SLJIT_SP
) | T(i
) | IMM(offset
), MOVABLE_INS
));
1057 for (i
= scratches
; i
>= SLJIT_FIRST_SAVED_REG
; i
--) {
1058 offset
-= SSIZE_OF(sw
);
1059 FAIL_IF(push_inst(compiler
, STACK_LOAD
| S(SLJIT_SP
) | T(i
) | IMM(offset
), MOVABLE_INS
));
1062 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1063 /* This alignment is valid because offset is not used after storing FPU regs. */
1064 if ((offset
& SSIZE_OF(sw
)) != 0)
1065 offset
-= SSIZE_OF(sw
);
1068 tmp
= SLJIT_FS0
- fsaveds
;
1069 for (i
= SLJIT_FS0
; i
> tmp
; i
--) {
1070 offset
-= SSIZE_OF(f64
);
1071 FAIL_IF(push_inst(compiler
, LDC1
| S(SLJIT_SP
) | FT(i
) | IMM(offset
), MOVABLE_INS
));
1074 for (i
= fscratches
; i
>= SLJIT_FIRST_SAVED_FLOAT_REG
; i
--) {
1075 offset
-= SSIZE_OF(f64
);
1076 FAIL_IF(push_inst(compiler
, LDC1
| S(SLJIT_SP
) | FT(i
) | IMM(offset
), MOVABLE_INS
));
1079 if (local_size
> frame_size
)
1080 *ins_ptr
= ADDIU_W
| S(SLJIT_SP
) | T(SLJIT_SP
) | IMM(local_size
- frame_size
);
1084 return SLJIT_SUCCESS
;
1087 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_return_void(struct sljit_compiler
*compiler
)
1092 CHECK(check_sljit_emit_return_void(compiler
));
1094 emit_stack_frame_release(compiler
, 0, &ins
);
1096 FAIL_IF(push_inst(compiler
, JR
| SA(RETURN_ADDR_REG
), UNMOVABLE_INS
));
1097 return push_inst(compiler
, ins
, UNMOVABLE_INS
);
1103 /* --------------------------------------------------------------------- */
1105 /* --------------------------------------------------------------------- */
1107 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1108 #define ARCH_32_64(a, b) a
1110 #define ARCH_32_64(a, b) b
1113 static const sljit_ins data_transfer_insts
[16 + 4] = {
1114 /* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
1115 /* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
1116 /* u b s */ HI(40) /* sb */,
1117 /* u b l */ HI(36) /* lbu */,
1118 /* u h s */ HI(41) /* sh */,
1119 /* u h l */ HI(37) /* lhu */,
1120 /* u i s */ HI(43) /* sw */,
1121 /* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */),
1123 /* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
1124 /* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
1125 /* s b s */ HI(40) /* sb */,
1126 /* s b l */ HI(32) /* lb */,
1127 /* s h s */ HI(41) /* sh */,
1128 /* s h l */ HI(33) /* lh */,
1129 /* s i s */ HI(43) /* sw */,
1130 /* s i l */ HI(35) /* lw */,
1132 /* d s */ HI(61) /* sdc1 */,
1133 /* d l */ HI(53) /* ldc1 */,
1134 /* s s */ HI(57) /* swc1 */,
1135 /* s l */ HI(49) /* lwc1 */,
1140 /* reg_ar is an absoulute register! */
1142 /* Can perform an operation using at most 1 instruction. */
1143 static sljit_s32
getput_arg_fast(struct sljit_compiler
*compiler
, sljit_s32 flags
, sljit_s32 reg_ar
, sljit_s32 arg
, sljit_sw argw
)
1145 SLJIT_ASSERT(arg
& SLJIT_MEM
);
1147 if (!(arg
& OFFS_REG_MASK
) && argw
<= SIMM_MAX
&& argw
>= SIMM_MIN
) {
1148 /* Works for both absoulte and relative addresses. */
1149 if (SLJIT_UNLIKELY(flags
& ARG_TEST
))
1151 FAIL_IF(push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | S(arg
& REG_MASK
)
1152 | TA(reg_ar
) | IMM(argw
), ((flags
& MEM_MASK
) <= GPR_REG
&& (flags
& LOAD_DATA
)) ? reg_ar
: MOVABLE_INS
));
1158 #define TO_ARGW_HI(argw) (((argw) & ~0xffff) + (((argw) & 0x8000) ? 0x10000 : 0))
1160 /* See getput_arg below.
1161 Note: can_cache is called only for binary operators. */
1162 static sljit_s32
can_cache(sljit_s32 arg
, sljit_sw argw
, sljit_s32 next_arg
, sljit_sw next_argw
)
1164 SLJIT_ASSERT((arg
& SLJIT_MEM
) && (next_arg
& SLJIT_MEM
));
1166 /* Simple operation except for updates. */
1167 if (arg
& OFFS_REG_MASK
) {
1170 if (argw
&& argw
== next_argw
&& (arg
== next_arg
|| (arg
& OFFS_REG_MASK
) == (next_arg
& OFFS_REG_MASK
)))
1175 if (arg
== next_arg
) {
1176 if (((next_argw
- argw
) <= SIMM_MAX
&& (next_argw
- argw
) >= SIMM_MIN
)
1177 || TO_ARGW_HI(argw
) == TO_ARGW_HI(next_argw
))
1185 /* Emit the necessary instructions. See can_cache above. */
1186 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
)
1188 sljit_s32 tmp_ar
, base
, delay_slot
;
1189 sljit_sw offset
, argw_hi
;
1191 SLJIT_ASSERT(arg
& SLJIT_MEM
);
1192 if (!(next_arg
& SLJIT_MEM
)) {
1197 /* Since tmp can be the same as base or offset registers,
1198 * these might be unavailable after modifying tmp. */
1199 if ((flags
& MEM_MASK
) <= GPR_REG
&& (flags
& LOAD_DATA
)) {
1201 delay_slot
= reg_ar
;
1204 tmp_ar
= DR(TMP_REG1
);
1205 delay_slot
= MOVABLE_INS
;
1207 base
= arg
& REG_MASK
;
1209 if (SLJIT_UNLIKELY(arg
& OFFS_REG_MASK
)) {
1212 /* Using the cache. */
1213 if (argw
== compiler
->cache_argw
) {
1214 if (arg
== compiler
->cache_arg
)
1215 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | S(TMP_REG3
) | TA(reg_ar
), delay_slot
);
1217 if ((SLJIT_MEM
| (arg
& OFFS_REG_MASK
)) == compiler
->cache_arg
) {
1218 if (arg
== next_arg
&& argw
== (next_argw
& 0x3)) {
1219 compiler
->cache_arg
= arg
;
1220 compiler
->cache_argw
= argw
;
1221 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | T(TMP_REG3
) | D(TMP_REG3
), DR(TMP_REG3
)));
1222 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | S(TMP_REG3
) | TA(reg_ar
), delay_slot
);
1224 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | T(TMP_REG3
) | DA(tmp_ar
), tmp_ar
));
1225 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | SA(tmp_ar
) | TA(reg_ar
), delay_slot
);
1229 if (SLJIT_UNLIKELY(argw
)) {
1230 compiler
->cache_arg
= SLJIT_MEM
| (arg
& OFFS_REG_MASK
);
1231 compiler
->cache_argw
= argw
;
1232 FAIL_IF(push_inst(compiler
, SLL_W
| T(OFFS_REG(arg
)) | D(TMP_REG3
) | SH_IMM(argw
), DR(TMP_REG3
)));
1235 if (arg
== next_arg
&& argw
== (next_argw
& 0x3)) {
1236 compiler
->cache_arg
= arg
;
1237 compiler
->cache_argw
= argw
;
1238 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | T(!argw
? OFFS_REG(arg
) : TMP_REG3
) | D(TMP_REG3
), DR(TMP_REG3
)));
1239 tmp_ar
= DR(TMP_REG3
);
1242 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | T(!argw
? OFFS_REG(arg
) : TMP_REG3
) | DA(tmp_ar
), tmp_ar
));
1243 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | SA(tmp_ar
) | TA(reg_ar
), delay_slot
);
1246 if (compiler
->cache_arg
== arg
&& argw
- compiler
->cache_argw
<= SIMM_MAX
&& argw
- compiler
->cache_argw
>= SIMM_MIN
)
1247 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | S(TMP_REG3
) | TA(reg_ar
) | IMM(argw
- compiler
->cache_argw
), delay_slot
);
1249 if (compiler
->cache_arg
== SLJIT_MEM
&& (argw
- compiler
->cache_argw
) <= SIMM_MAX
&& (argw
- compiler
->cache_argw
) >= SIMM_MIN
) {
1250 offset
= argw
- compiler
->cache_argw
;
1252 compiler
->cache_arg
= SLJIT_MEM
;
1254 argw_hi
= TO_ARGW_HI(argw
);
1256 if (next_arg
&& next_argw
- argw
<= SIMM_MAX
&& next_argw
- argw
>= SIMM_MIN
&& argw_hi
!= TO_ARGW_HI(next_argw
)) {
1257 FAIL_IF(load_immediate(compiler
, DR(TMP_REG3
), argw
));
1258 compiler
->cache_argw
= argw
;
1261 FAIL_IF(load_immediate(compiler
, DR(TMP_REG3
), argw_hi
));
1262 compiler
->cache_argw
= argw_hi
;
1263 offset
= argw
& 0xffff;
1269 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | S(TMP_REG3
) | TA(reg_ar
) | IMM(offset
), delay_slot
);
1271 if (arg
== next_arg
&& next_argw
- argw
<= SIMM_MAX
&& next_argw
- argw
>= SIMM_MIN
) {
1272 compiler
->cache_arg
= arg
;
1273 FAIL_IF(push_inst(compiler
, ADDU_W
| S(TMP_REG3
) | T(base
) | D(TMP_REG3
), DR(TMP_REG3
)));
1274 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | S(TMP_REG3
) | TA(reg_ar
) | IMM(offset
), delay_slot
);
1277 FAIL_IF(push_inst(compiler
, ADDU_W
| S(TMP_REG3
) | T(base
) | DA(tmp_ar
), tmp_ar
));
1278 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | SA(tmp_ar
) | TA(reg_ar
) | IMM(offset
), delay_slot
);
1281 static sljit_s32
emit_op_mem(struct sljit_compiler
*compiler
, sljit_s32 flags
, sljit_s32 reg_ar
, sljit_s32 arg
, sljit_sw argw
)
1283 sljit_s32 tmp_ar
, base
, delay_slot
;
1285 if (getput_arg_fast(compiler
, flags
, reg_ar
, arg
, argw
))
1286 return compiler
->error
;
1288 if ((flags
& MEM_MASK
) <= GPR_REG
&& (flags
& LOAD_DATA
)) {
1290 delay_slot
= reg_ar
;
1293 tmp_ar
= DR(TMP_REG1
);
1294 delay_slot
= MOVABLE_INS
;
1296 base
= arg
& REG_MASK
;
1298 if (SLJIT_UNLIKELY(arg
& OFFS_REG_MASK
)) {
1301 if (SLJIT_UNLIKELY(argw
)) {
1302 FAIL_IF(push_inst(compiler
, SLL_W
| T(OFFS_REG(arg
)) | DA(tmp_ar
) | SH_IMM(argw
), tmp_ar
));
1303 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | TA(tmp_ar
) | DA(tmp_ar
), tmp_ar
));
1306 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | T(OFFS_REG(arg
)) | DA(tmp_ar
), tmp_ar
));
1307 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | SA(tmp_ar
) | TA(reg_ar
), delay_slot
);
1310 FAIL_IF(load_immediate(compiler
, tmp_ar
, TO_ARGW_HI(argw
)));
1313 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | TA(tmp_ar
) | DA(tmp_ar
), tmp_ar
));
1315 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | SA(tmp_ar
) | TA(reg_ar
) | IMM(argw
), delay_slot
);
1318 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
)
1320 if (getput_arg_fast(compiler
, flags
, reg
, arg1
, arg1w
))
1321 return compiler
->error
;
1322 return getput_arg(compiler
, flags
, reg
, arg1
, arg1w
, arg2
, arg2w
);
1325 #define EMIT_LOGICAL(op_imm, op_reg) \
1326 if (flags & SRC2_IMM) { \
1327 if (op & SLJIT_SET_Z) \
1328 FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
1329 if (!(flags & UNUSED_DEST)) \
1330 FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
1333 if (op & SLJIT_SET_Z) \
1334 FAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
1335 if (!(flags & UNUSED_DEST)) \
1336 FAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | D(dst), DR(dst))); \
1339 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1341 #define SELECT_OP(a, b) (b)
1343 #define EMIT_SHIFT(op_dimm, op_dimm32, op_imm, op_dv, op_v) \
1344 if (flags & SRC2_IMM) { \
1345 if (op & SLJIT_SET_Z) \
1346 FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
1347 if (!(flags & UNUSED_DEST)) \
1348 FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \
1351 if (op & SLJIT_SET_Z) \
1352 FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
1353 if (!(flags & UNUSED_DEST)) \
1354 FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst))); \
1357 #else /* !SLJIT_CONFIG_MIPS_32 */
1359 #define SELECT_OP(a, b) \
1360 (!(op & SLJIT_32) ? a : b)
1362 #define EMIT_SHIFT(op_dimm, op_dimm32, op_imm, op_dv, op_v) \
1363 if (flags & SRC2_IMM) { \
1365 SLJIT_ASSERT(!(op & SLJIT_32)); \
1370 ins = (op & SLJIT_32) ? op_imm : op_dimm; \
1371 if (op & SLJIT_SET_Z) \
1372 FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
1373 if (!(flags & UNUSED_DEST)) \
1374 FAIL_IF(push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \
1377 ins = (op & SLJIT_32) ? op_v : op_dv; \
1378 if (op & SLJIT_SET_Z) \
1379 FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
1380 if (!(flags & UNUSED_DEST)) \
1381 FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst))); \
1384 #endif /* SLJIT_CONFIG_MIPS_32 */
1386 static SLJIT_INLINE sljit_s32
emit_single_op(struct sljit_compiler
*compiler
, sljit_s32 op
, sljit_s32 flags
,
1387 sljit_s32 dst
, sljit_s32 src1
, sljit_sw src2
)
1389 sljit_s32 is_overflow
, is_carry
, carry_src_ar
, is_handled
;
1390 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1394 switch (GET_OPCODE(op
)) {
1396 SLJIT_ASSERT(src1
== TMP_REG1
&& !(flags
& SRC2_IMM
));
1398 return push_inst(compiler
, SELECT_OP(DADDU
, ADDU
) | S(src2
) | TA(0) | D(dst
), DR(dst
));
1399 return SLJIT_SUCCESS
;
1402 SLJIT_ASSERT(src1
== TMP_REG1
&& !(flags
& SRC2_IMM
));
1403 if ((flags
& (REG_DEST
| REG2_SOURCE
)) == (REG_DEST
| REG2_SOURCE
))
1404 return push_inst(compiler
, ANDI
| S(src2
) | T(dst
) | IMM(0xff), DR(dst
));
1405 SLJIT_ASSERT(dst
== src2
);
1406 return SLJIT_SUCCESS
;
1409 SLJIT_ASSERT(src1
== TMP_REG1
&& !(flags
& SRC2_IMM
));
1410 if ((flags
& (REG_DEST
| REG2_SOURCE
)) == (REG_DEST
| REG2_SOURCE
)) {
1411 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1412 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1413 return push_inst(compiler
, SEB
| T(src2
) | D(dst
), DR(dst
));
1414 #else /* SLJIT_MIPS_REV < 1 */
1415 FAIL_IF(push_inst(compiler
, SLL
| T(src2
) | D(dst
) | SH_IMM(24), DR(dst
)));
1416 return push_inst(compiler
, SRA
| T(dst
) | D(dst
) | SH_IMM(24), DR(dst
));
1417 #endif /* SLJIT_MIPS_REV >= 1 */
1418 #else /* !SLJIT_CONFIG_MIPS_32 */
1419 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1421 return push_inst(compiler
, SEB
| T(src2
) | D(dst
), DR(dst
));
1422 #endif /* SLJIT_MIPS_REV >= 1 */
1423 FAIL_IF(push_inst(compiler
, DSLL32
| T(src2
) | D(dst
) | SH_IMM(24), DR(dst
)));
1424 return push_inst(compiler
, DSRA32
| T(dst
) | D(dst
) | SH_IMM(24), DR(dst
));
1425 #endif /* SLJIT_CONFIG_MIPS_32 */
1427 SLJIT_ASSERT(dst
== src2
);
1428 return SLJIT_SUCCESS
;
1431 SLJIT_ASSERT(src1
== TMP_REG1
&& !(flags
& SRC2_IMM
));
1432 if ((flags
& (REG_DEST
| REG2_SOURCE
)) == (REG_DEST
| REG2_SOURCE
))
1433 return push_inst(compiler
, ANDI
| S(src2
) | T(dst
) | IMM(0xffff), DR(dst
));
1434 SLJIT_ASSERT(dst
== src2
);
1435 return SLJIT_SUCCESS
;
1438 SLJIT_ASSERT(src1
== TMP_REG1
&& !(flags
& SRC2_IMM
));
1439 if ((flags
& (REG_DEST
| REG2_SOURCE
)) == (REG_DEST
| REG2_SOURCE
)) {
1440 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1441 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1442 return push_inst(compiler
, SEH
| T(src2
) | D(dst
), DR(dst
));
1443 #else /* SLJIT_MIPS_REV < 1 */
1444 FAIL_IF(push_inst(compiler
, SLL
| T(src2
) | D(dst
) | SH_IMM(16), DR(dst
)));
1445 return push_inst(compiler
, SRA
| T(dst
) | D(dst
) | SH_IMM(16), DR(dst
));
1446 #endif /* SLJIT_MIPS_REV >= 1 */
1447 #else /* !SLJIT_CONFIG_MIPS_32 */
1448 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1450 return push_inst(compiler
, SEH
| T(src2
) | D(dst
), DR(dst
));
1451 #endif /* SLJIT_MIPS_REV >= 1 */
1452 FAIL_IF(push_inst(compiler
, DSLL32
| T(src2
) | D(dst
) | SH_IMM(16), DR(dst
)));
1453 return push_inst(compiler
, DSRA32
| T(dst
) | D(dst
) | SH_IMM(16), DR(dst
));
1454 #endif /* SLJIT_CONFIG_MIPS_32 */
1456 SLJIT_ASSERT(dst
== src2
);
1457 return SLJIT_SUCCESS
;
1459 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1461 SLJIT_ASSERT(src1
== TMP_REG1
&& !(flags
& SRC2_IMM
) && !(op
& SLJIT_32
));
1462 if ((flags
& (REG_DEST
| REG2_SOURCE
)) == (REG_DEST
| REG2_SOURCE
)) {
1463 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1465 return push_inst(compiler
, DINSU
| T(src2
) | SA(0) | (31 << 11) | (0 << 11), DR(dst
));
1466 #endif /* SLJIT_MIPS_REV >= 2 */
1467 FAIL_IF(push_inst(compiler
, DSLL32
| T(src2
) | D(dst
) | SH_IMM(0), DR(dst
)));
1468 return push_inst(compiler
, DSRL32
| T(dst
) | D(dst
) | SH_IMM(0), DR(dst
));
1470 SLJIT_ASSERT(dst
== src2
);
1471 return SLJIT_SUCCESS
;
1474 SLJIT_ASSERT(src1
== TMP_REG1
&& !(flags
& SRC2_IMM
) && !(op
& SLJIT_32
));
1475 if ((flags
& (REG_DEST
| REG2_SOURCE
)) == (REG_DEST
| REG2_SOURCE
)) {
1476 return push_inst(compiler
, SLL
| T(src2
) | D(dst
) | SH_IMM(0), DR(dst
));
1478 SLJIT_ASSERT(dst
== src2
);
1479 return SLJIT_SUCCESS
;
1480 #endif /* SLJIT_CONFIG_MIPS_64 */
1483 SLJIT_ASSERT(src1
== TMP_REG1
&& !(flags
& SRC2_IMM
));
1484 if (op
& SLJIT_SET_Z
)
1485 FAIL_IF(push_inst(compiler
, NOR
| S(src2
) | T(src2
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1486 if (!(flags
& UNUSED_DEST
))
1487 FAIL_IF(push_inst(compiler
, NOR
| S(src2
) | T(src2
) | D(dst
), DR(dst
)));
1488 return SLJIT_SUCCESS
;
1491 SLJIT_ASSERT(src1
== TMP_REG1
&& !(flags
& SRC2_IMM
));
1492 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1493 if (op
& SLJIT_SET_Z
)
1494 FAIL_IF(push_inst(compiler
, SELECT_OP(DCLZ
, CLZ
) | S(src2
) | TA(EQUAL_FLAG
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1495 if (!(flags
& UNUSED_DEST
))
1496 FAIL_IF(push_inst(compiler
, SELECT_OP(DCLZ
, CLZ
) | S(src2
) | T(dst
) | D(dst
), DR(dst
)));
1497 #else /* SLJIT_MIPS_REV < 1 */
1498 /* Nearly all instructions are unmovable in the following sequence. */
1499 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDU
, ADDU
) | S(src2
) | TA(0) | D(TMP_REG1
), DR(TMP_REG1
)));
1501 FAIL_IF(push_inst(compiler
, BEQ
| S(TMP_REG1
) | TA(0) | IMM(5), UNMOVABLE_INS
));
1502 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1503 FAIL_IF(push_inst(compiler
, ORI
| SA(0) | T(dst
) | IMM(32), UNMOVABLE_INS
));
1504 #else /* !SLJIT_CONFIG_MIPS_32 */
1505 FAIL_IF(push_inst(compiler
, ORI
| SA(0) | T(dst
) | IMM((op
& SLJIT_32
) ? 32 : 64), UNMOVABLE_INS
));
1506 #endif /* SLJIT_CONFIG_MIPS_32 */
1507 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDIU
, ADDIU
) | SA(0) | T(dst
) | IMM(-1), DR(dst
)));
1508 /* Loop for searching the highest bit. */
1509 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDIU
, ADDIU
) | S(dst
) | T(dst
) | IMM(1), DR(dst
)));
1510 FAIL_IF(push_inst(compiler
, BGEZ
| S(TMP_REG1
) | IMM(-2), UNMOVABLE_INS
));
1511 FAIL_IF(push_inst(compiler
, SELECT_OP(DSLL
, SLL
) | T(TMP_REG1
) | D(TMP_REG1
) | SH_IMM(1), UNMOVABLE_INS
));
1512 #endif /* SLJIT_MIPS_REV >= 1 */
1513 return SLJIT_SUCCESS
;
1516 /* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */
1517 is_overflow
= GET_FLAG_TYPE(op
) == SLJIT_OVERFLOW
;
1518 carry_src_ar
= GET_FLAG_TYPE(op
) == GET_FLAG_TYPE(SLJIT_SET_CARRY
);
1520 if (flags
& SRC2_IMM
) {
1523 FAIL_IF(push_inst(compiler
, OR
| S(src1
) | T(src1
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1525 FAIL_IF(push_inst(compiler
, NOR
| S(src1
) | T(src1
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1527 else if (op
& SLJIT_SET_Z
)
1528 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDIU
, ADDIU
) | S(src1
) | TA(EQUAL_FLAG
) | IMM(src2
), EQUAL_FLAG
));
1530 /* Only the zero flag is needed. */
1531 if (!(flags
& UNUSED_DEST
) || (op
& VARIABLE_FLAG_MASK
))
1532 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDIU
, ADDIU
) | S(src1
) | T(dst
) | IMM(src2
), DR(dst
)));
1536 FAIL_IF(push_inst(compiler
, XOR
| S(src1
) | T(src2
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1537 else if (op
& SLJIT_SET_Z
)
1538 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDU
, ADDU
) | S(src1
) | T(src2
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1540 if (is_overflow
|| carry_src_ar
!= 0) {
1542 carry_src_ar
= DR(src1
);
1543 else if (src2
!= dst
)
1544 carry_src_ar
= DR(src2
);
1546 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDU
, ADDU
) | S(src1
) | TA(0) | DA(OTHER_FLAG
), OTHER_FLAG
));
1547 carry_src_ar
= OTHER_FLAG
;
1551 /* Only the zero flag is needed. */
1552 if (!(flags
& UNUSED_DEST
) || (op
& VARIABLE_FLAG_MASK
))
1553 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDU
, ADDU
) | S(src1
) | T(src2
) | D(dst
), DR(dst
)));
1556 /* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
1557 if (is_overflow
|| carry_src_ar
!= 0) {
1558 if (flags
& SRC2_IMM
)
1559 FAIL_IF(push_inst(compiler
, SLTIU
| S(dst
) | TA(OTHER_FLAG
) | IMM(src2
), OTHER_FLAG
));
1561 FAIL_IF(push_inst(compiler
, SLTU
| S(dst
) | TA(carry_src_ar
) | DA(OTHER_FLAG
), OTHER_FLAG
));
1565 return SLJIT_SUCCESS
;
1567 FAIL_IF(push_inst(compiler
, XOR
| S(dst
) | TA(EQUAL_FLAG
) | D(TMP_REG1
), DR(TMP_REG1
)));
1568 if (op
& SLJIT_SET_Z
)
1569 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDU
, ADDU
) | S(dst
) | TA(0) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1570 FAIL_IF(push_inst(compiler
, SELECT_OP(DSRL32
, SRL
) | T(TMP_REG1
) | D(TMP_REG1
) | SH_IMM(31), DR(TMP_REG1
)));
1571 return push_inst(compiler
, XOR
| S(TMP_REG1
) | TA(OTHER_FLAG
) | DA(OTHER_FLAG
), OTHER_FLAG
);
1574 carry_src_ar
= GET_FLAG_TYPE(op
) == GET_FLAG_TYPE(SLJIT_SET_CARRY
);
1576 if (flags
& SRC2_IMM
) {
1577 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDIU
, ADDIU
) | S(src1
) | T(dst
) | IMM(src2
), DR(dst
)));
1579 if (carry_src_ar
!= 0) {
1581 carry_src_ar
= DR(src1
);
1582 else if (src2
!= dst
)
1583 carry_src_ar
= DR(src2
);
1585 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDU
, ADDU
) | S(src1
) | TA(0) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1586 carry_src_ar
= EQUAL_FLAG
;
1590 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDU
, ADDU
) | S(src1
) | T(src2
) | D(dst
), DR(dst
)));
1593 /* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
1594 if (carry_src_ar
!= 0) {
1595 if (flags
& SRC2_IMM
)
1596 FAIL_IF(push_inst(compiler
, SLTIU
| S(dst
) | TA(EQUAL_FLAG
) | IMM(src2
), EQUAL_FLAG
));
1598 FAIL_IF(push_inst(compiler
, SLTU
| S(dst
) | TA(carry_src_ar
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1601 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDU
, ADDU
) | S(dst
) | TA(OTHER_FLAG
) | D(dst
), DR(dst
)));
1603 if (carry_src_ar
== 0)
1604 return SLJIT_SUCCESS
;
1606 /* Set ULESS_FLAG (dst == 0) && (OTHER_FLAG == 1). */
1607 FAIL_IF(push_inst(compiler
, SLTU
| S(dst
) | TA(OTHER_FLAG
) | DA(OTHER_FLAG
), OTHER_FLAG
));
1608 /* Set carry flag. */
1609 return push_inst(compiler
, OR
| SA(OTHER_FLAG
) | TA(EQUAL_FLAG
) | DA(OTHER_FLAG
), OTHER_FLAG
);
1612 if ((flags
& SRC2_IMM
) && src2
== SIMM_MIN
) {
1613 FAIL_IF(push_inst(compiler
, ADDIU
| SA(0) | T(TMP_REG2
) | IMM(src2
), DR(TMP_REG2
)));
1620 if (flags
& SRC2_IMM
) {
1621 if (GET_FLAG_TYPE(op
) == SLJIT_LESS
|| GET_FLAG_TYPE(op
) == SLJIT_GREATER_EQUAL
) {
1622 FAIL_IF(push_inst(compiler
, SLTIU
| S(src1
) | TA(OTHER_FLAG
) | IMM(src2
), OTHER_FLAG
));
1625 else if (GET_FLAG_TYPE(op
) == SLJIT_SIG_LESS
|| GET_FLAG_TYPE(op
) == SLJIT_SIG_GREATER_EQUAL
) {
1626 FAIL_IF(push_inst(compiler
, SLTI
| S(src1
) | TA(OTHER_FLAG
) | IMM(src2
), OTHER_FLAG
));
1631 if (!is_handled
&& GET_FLAG_TYPE(op
) >= SLJIT_LESS
&& GET_FLAG_TYPE(op
) <= SLJIT_SIG_LESS_EQUAL
) {
1634 if (flags
& SRC2_IMM
) {
1635 FAIL_IF(push_inst(compiler
, ADDIU
| SA(0) | T(TMP_REG2
) | IMM(src2
), DR(TMP_REG2
)));
1640 switch (GET_FLAG_TYPE(op
)) {
1642 case SLJIT_GREATER_EQUAL
:
1643 FAIL_IF(push_inst(compiler
, SLTU
| S(src1
) | T(src2
) | DA(OTHER_FLAG
), OTHER_FLAG
));
1646 case SLJIT_LESS_EQUAL
:
1647 FAIL_IF(push_inst(compiler
, SLTU
| S(src2
) | T(src1
) | DA(OTHER_FLAG
), OTHER_FLAG
));
1649 case SLJIT_SIG_LESS
:
1650 case SLJIT_SIG_GREATER_EQUAL
:
1651 FAIL_IF(push_inst(compiler
, SLT
| S(src1
) | T(src2
) | DA(OTHER_FLAG
), OTHER_FLAG
));
1653 case SLJIT_SIG_GREATER
:
1654 case SLJIT_SIG_LESS_EQUAL
:
1655 FAIL_IF(push_inst(compiler
, SLT
| S(src2
) | T(src1
) | DA(OTHER_FLAG
), OTHER_FLAG
));
1661 if (flags
& SRC2_IMM
) {
1662 if (op
& SLJIT_SET_Z
)
1663 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDIU
, ADDIU
) | S(src1
) | TA(EQUAL_FLAG
) | IMM(-src2
), EQUAL_FLAG
));
1664 if (!(flags
& UNUSED_DEST
))
1665 return push_inst(compiler
, SELECT_OP(DADDIU
, ADDIU
) | S(src1
) | T(dst
) | IMM(-src2
), DR(dst
));
1668 if (op
& SLJIT_SET_Z
)
1669 FAIL_IF(push_inst(compiler
, SELECT_OP(DSUBU
, SUBU
) | S(src1
) | T(src2
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1670 if (!(flags
& UNUSED_DEST
))
1671 return push_inst(compiler
, SELECT_OP(DSUBU
, SUBU
) | S(src1
) | T(src2
) | D(dst
), DR(dst
));
1673 return SLJIT_SUCCESS
;
1676 is_overflow
= GET_FLAG_TYPE(op
) == SLJIT_OVERFLOW
;
1677 is_carry
= GET_FLAG_TYPE(op
) == GET_FLAG_TYPE(SLJIT_SET_CARRY
);
1679 if (flags
& SRC2_IMM
) {
1682 FAIL_IF(push_inst(compiler
, OR
| S(src1
) | T(src1
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1684 FAIL_IF(push_inst(compiler
, NOR
| S(src1
) | T(src1
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1686 else if (op
& SLJIT_SET_Z
)
1687 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDIU
, ADDIU
) | S(src1
) | TA(EQUAL_FLAG
) | IMM(-src2
), EQUAL_FLAG
));
1689 if (is_overflow
|| is_carry
)
1690 FAIL_IF(push_inst(compiler
, SLTIU
| S(src1
) | TA(OTHER_FLAG
) | IMM(src2
), OTHER_FLAG
));
1692 /* Only the zero flag is needed. */
1693 if (!(flags
& UNUSED_DEST
) || (op
& VARIABLE_FLAG_MASK
))
1694 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDIU
, ADDIU
) | S(src1
) | T(dst
) | IMM(-src2
), DR(dst
)));
1698 FAIL_IF(push_inst(compiler
, XOR
| S(src1
) | T(src2
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1699 else if (op
& SLJIT_SET_Z
)
1700 FAIL_IF(push_inst(compiler
, SELECT_OP(DSUBU
, SUBU
) | S(src1
) | T(src2
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1702 if (is_overflow
|| is_carry
)
1703 FAIL_IF(push_inst(compiler
, SLTU
| S(src1
) | T(src2
) | DA(OTHER_FLAG
), OTHER_FLAG
));
1705 /* Only the zero flag is needed. */
1706 if (!(flags
& UNUSED_DEST
) || (op
& VARIABLE_FLAG_MASK
))
1707 FAIL_IF(push_inst(compiler
, SELECT_OP(DSUBU
, SUBU
) | S(src1
) | T(src2
) | D(dst
), DR(dst
)));
1711 return SLJIT_SUCCESS
;
1713 FAIL_IF(push_inst(compiler
, XOR
| S(dst
) | TA(EQUAL_FLAG
) | D(TMP_REG1
), DR(TMP_REG1
)));
1714 if (op
& SLJIT_SET_Z
)
1715 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDU
, ADDU
) | S(dst
) | TA(0) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1716 FAIL_IF(push_inst(compiler
, SELECT_OP(DSRL32
, SRL
) | T(TMP_REG1
) | D(TMP_REG1
) | SH_IMM(31), DR(TMP_REG1
)));
1717 return push_inst(compiler
, XOR
| S(TMP_REG1
) | TA(OTHER_FLAG
) | DA(OTHER_FLAG
), OTHER_FLAG
);
1720 if ((flags
& SRC2_IMM
) && src2
== SIMM_MIN
) {
1721 FAIL_IF(push_inst(compiler
, ADDIU
| SA(0) | T(TMP_REG2
) | IMM(src2
), DR(TMP_REG2
)));
1726 is_carry
= GET_FLAG_TYPE(op
) == GET_FLAG_TYPE(SLJIT_SET_CARRY
);
1728 if (flags
& SRC2_IMM
) {
1730 FAIL_IF(push_inst(compiler
, SLTIU
| S(src1
) | TA(EQUAL_FLAG
) | IMM(src2
), EQUAL_FLAG
));
1732 FAIL_IF(push_inst(compiler
, SELECT_OP(DADDIU
, ADDIU
) | S(src1
) | T(dst
) | IMM(-src2
), DR(dst
)));
1736 FAIL_IF(push_inst(compiler
, SLTU
| S(src1
) | T(src2
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1738 FAIL_IF(push_inst(compiler
, SELECT_OP(DSUBU
, SUBU
) | S(src1
) | T(src2
) | D(dst
), DR(dst
)));
1742 FAIL_IF(push_inst(compiler
, SLTU
| S(dst
) | TA(OTHER_FLAG
) | D(TMP_REG1
), DR(TMP_REG1
)));
1744 FAIL_IF(push_inst(compiler
, SELECT_OP(DSUBU
, SUBU
) | S(dst
) | TA(OTHER_FLAG
) | D(dst
), DR(dst
)));
1747 return SLJIT_SUCCESS
;
1749 return push_inst(compiler
, OR
| SA(EQUAL_FLAG
) | T(TMP_REG1
) | DA(OTHER_FLAG
), OTHER_FLAG
);
1752 SLJIT_ASSERT(!(flags
& SRC2_IMM
));
1754 if (GET_FLAG_TYPE(op
) != SLJIT_OVERFLOW
) {
1755 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1756 return push_inst(compiler
, SELECT_OP(DMUL
, MUL
) | S(src1
) | T(src2
) | D(dst
), DR(dst
));
1757 #elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1758 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1759 return push_inst(compiler
, MUL
| S(src1
) | T(src2
) | D(dst
), DR(dst
));
1760 #else /* !SLJIT_CONFIG_MIPS_32 */
1762 return push_inst(compiler
, MUL
| S(src1
) | T(src2
) | D(dst
), DR(dst
));
1763 FAIL_IF(push_inst(compiler
, DMULT
| S(src1
) | T(src2
), MOVABLE_INS
));
1764 return push_inst(compiler
, MFLO
| D(dst
), DR(dst
));
1765 #endif /* SLJIT_CONFIG_MIPS_32 */
1766 #else /* SLJIT_MIPS_REV < 1 */
1767 FAIL_IF(push_inst(compiler
, SELECT_OP(DMULT
, MULT
) | S(src1
) | T(src2
), MOVABLE_INS
));
1768 return push_inst(compiler
, MFLO
| D(dst
), DR(dst
));
1769 #endif /* SLJIT_MIPS_REV >= 6 */
1772 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1773 FAIL_IF(push_inst(compiler
, SELECT_OP(DMUL
, MUL
) | S(src1
) | T(src2
) | D(dst
), DR(dst
)));
1774 FAIL_IF(push_inst(compiler
, SELECT_OP(DMUH
, MUH
) | S(src1
) | T(src2
) | DA(EQUAL_FLAG
), EQUAL_FLAG
));
1775 #else /* SLJIT_MIPS_REV < 6 */
1776 FAIL_IF(push_inst(compiler
, SELECT_OP(DMULT
, MULT
) | S(src1
) | T(src2
), MOVABLE_INS
));
1777 FAIL_IF(push_inst(compiler
, MFHI
| DA(EQUAL_FLAG
), EQUAL_FLAG
));
1778 FAIL_IF(push_inst(compiler
, MFLO
| D(dst
), DR(dst
)));
1779 #endif /* SLJIT_MIPS_REV >= 6 */
1780 FAIL_IF(push_inst(compiler
, SELECT_OP(DSRA32
, SRA
) | T(dst
) | DA(OTHER_FLAG
) | SH_IMM(31), OTHER_FLAG
));
1781 return push_inst(compiler
, SELECT_OP(DSUBU
, SUBU
) | SA(EQUAL_FLAG
) | TA(OTHER_FLAG
) | DA(OTHER_FLAG
), OTHER_FLAG
);
1784 EMIT_LOGICAL(ANDI
, AND
);
1785 return SLJIT_SUCCESS
;
1788 EMIT_LOGICAL(ORI
, OR
);
1789 return SLJIT_SUCCESS
;
1792 EMIT_LOGICAL(XORI
, XOR
);
1793 return SLJIT_SUCCESS
;
1796 EMIT_SHIFT(DSLL
, DSLL32
, SLL
, DSLLV
, SLLV
);
1797 return SLJIT_SUCCESS
;
1800 EMIT_SHIFT(DSRL
, DSRL32
, SRL
, DSRLV
, SRLV
);
1801 return SLJIT_SUCCESS
;
1804 EMIT_SHIFT(DSRA
, DSRA32
, SRA
, DSRAV
, SRAV
);
1805 return SLJIT_SUCCESS
;
1808 SLJIT_UNREACHABLE();
1809 return SLJIT_SUCCESS
;
1812 #define CHECK_IMM(flags, srcw) \
1813 ((!((flags) & LOGICAL_OP) && ((srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)) \
1814 || (((flags) & LOGICAL_OP) && !((srcw) & ~UIMM_MAX)))
1816 static sljit_s32
emit_op(struct sljit_compiler
*compiler
, sljit_s32 op
, sljit_s32 flags
,
1817 sljit_s32 dst
, sljit_sw dstw
,
1818 sljit_s32 src1
, sljit_sw src1w
,
1819 sljit_s32 src2
, sljit_sw src2w
)
1821 /* arg1 goes to TMP_REG1 or src reg
1822 arg2 goes to TMP_REG2, imm or src reg
1823 TMP_REG3 can be used for caching
1824 result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
1825 sljit_s32 dst_r
= TMP_REG2
;
1827 sljit_sw src2_r
= 0;
1828 sljit_s32 sugg_src2_r
= TMP_REG2
;
1830 if (!(flags
& ALT_KEEP_CACHE
)) {
1831 compiler
->cache_arg
= 0;
1832 compiler
->cache_argw
= 0;
1835 if (dst
== TMP_REG2
) {
1836 SLJIT_ASSERT(HAS_FLAGS(op
));
1837 flags
|= UNUSED_DEST
;
1839 else if (FAST_IS_REG(dst
)) {
1842 if (flags
& MOVE_OP
)
1843 sugg_src2_r
= dst_r
;
1845 else if ((dst
& SLJIT_MEM
) && !getput_arg_fast(compiler
, flags
| ARG_TEST
, DR(TMP_REG1
), dst
, dstw
))
1848 if (flags
& IMM_OP
) {
1849 if ((src2
& SLJIT_IMM
) && src2w
!= 0 && CHECK_IMM(flags
, src2w
)) {
1852 } else if ((flags
& CUMULATIVE_OP
) && (src1
& SLJIT_IMM
) && src1w
!= 0 && CHECK_IMM(flags
, src1w
)) {
1856 /* And swap arguments. */
1860 /* src2w = src2_r unneeded. */
1865 if (FAST_IS_REG(src1
)) {
1867 flags
|= REG1_SOURCE
;
1869 else if (src1
& SLJIT_IMM
) {
1871 FAIL_IF(load_immediate(compiler
, DR(TMP_REG1
), src1w
));
1878 if (getput_arg_fast(compiler
, flags
| LOAD_DATA
, DR(TMP_REG1
), src1
, src1w
))
1879 FAIL_IF(compiler
->error
);
1886 if (FAST_IS_REG(src2
)) {
1888 flags
|= REG2_SOURCE
;
1889 if ((flags
& (REG_DEST
| MOVE_OP
)) == MOVE_OP
)
1890 dst_r
= (sljit_s32
)src2_r
;
1892 else if (src2
& SLJIT_IMM
) {
1893 if (!(flags
& SRC2_IMM
)) {
1895 FAIL_IF(load_immediate(compiler
, DR(sugg_src2_r
), src2w
));
1896 src2_r
= sugg_src2_r
;
1900 if (flags
& MOVE_OP
) {
1901 if (dst
& SLJIT_MEM
)
1910 if (getput_arg_fast(compiler
, flags
| LOAD_DATA
, DR(sugg_src2_r
), src2
, src2w
))
1911 FAIL_IF(compiler
->error
);
1914 src2_r
= sugg_src2_r
;
1917 if ((flags
& (SLOW_SRC1
| SLOW_SRC2
)) == (SLOW_SRC1
| SLOW_SRC2
)) {
1918 SLJIT_ASSERT(src2_r
== TMP_REG2
);
1919 if (!can_cache(src1
, src1w
, src2
, src2w
) && can_cache(src1
, src1w
, dst
, dstw
)) {
1920 FAIL_IF(getput_arg(compiler
, flags
| LOAD_DATA
, DR(TMP_REG2
), src2
, src2w
, src1
, src1w
));
1921 FAIL_IF(getput_arg(compiler
, flags
| LOAD_DATA
, DR(TMP_REG1
), src1
, src1w
, dst
, dstw
));
1924 FAIL_IF(getput_arg(compiler
, flags
| LOAD_DATA
, DR(TMP_REG1
), src1
, src1w
, src2
, src2w
));
1925 FAIL_IF(getput_arg(compiler
, flags
| LOAD_DATA
, DR(TMP_REG2
), src2
, src2w
, dst
, dstw
));
1928 else if (flags
& SLOW_SRC1
)
1929 FAIL_IF(getput_arg(compiler
, flags
| LOAD_DATA
, DR(TMP_REG1
), src1
, src1w
, dst
, dstw
));
1930 else if (flags
& SLOW_SRC2
)
1931 FAIL_IF(getput_arg(compiler
, flags
| LOAD_DATA
, DR(sugg_src2_r
), src2
, src2w
, dst
, dstw
));
1933 FAIL_IF(emit_single_op(compiler
, op
, flags
, dst_r
, src1_r
, src2_r
));
1935 if (dst
& SLJIT_MEM
) {
1936 if (!(flags
& SLOW_DEST
)) {
1937 getput_arg_fast(compiler
, flags
, DR(dst_r
), dst
, dstw
);
1938 return compiler
->error
;
1940 return getput_arg(compiler
, flags
, DR(dst_r
), dst
, dstw
, 0, 0);
1943 return SLJIT_SUCCESS
;
1948 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op0(struct sljit_compiler
*compiler
, sljit_s32 op
)
1950 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1951 sljit_s32 int_op
= op
& SLJIT_32
;
1955 CHECK(check_sljit_emit_op0(compiler
, op
));
1957 op
= GET_OPCODE(op
);
1959 case SLJIT_BREAKPOINT
:
1960 return push_inst(compiler
, BREAK
, UNMOVABLE_INS
);
1962 return push_inst(compiler
, NOP
, UNMOVABLE_INS
);
1965 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1966 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1967 FAIL_IF(push_inst(compiler
, (op
== SLJIT_LMUL_UW
? DMULU
: DMUL
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG3
), DR(TMP_REG3
)));
1968 FAIL_IF(push_inst(compiler
, (op
== SLJIT_LMUL_UW
? DMUHU
: DMUH
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG1
), DR(TMP_REG1
)));
1969 #else /* !SLJIT_CONFIG_MIPS_64 */
1970 FAIL_IF(push_inst(compiler
, (op
== SLJIT_LMUL_UW
? MULU
: MUL
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG3
), DR(TMP_REG3
)));
1971 FAIL_IF(push_inst(compiler
, (op
== SLJIT_LMUL_UW
? MUHU
: MUH
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG1
), DR(TMP_REG1
)));
1972 #endif /* SLJIT_CONFIG_MIPS_64 */
1973 FAIL_IF(push_inst(compiler
, ADDU_W
| S(TMP_REG3
) | TA(0) | D(SLJIT_R0
), DR(SLJIT_R0
)));
1974 return push_inst(compiler
, ADDU_W
| S(TMP_REG1
) | TA(0) | D(SLJIT_R1
), DR(SLJIT_R1
));
1975 #else /* SLJIT_MIPS_REV < 6 */
1976 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1977 FAIL_IF(push_inst(compiler
, (op
== SLJIT_LMUL_UW
? DMULTU
: DMULT
) | S(SLJIT_R0
) | T(SLJIT_R1
), MOVABLE_INS
));
1978 #else /* !SLJIT_CONFIG_MIPS_64 */
1979 FAIL_IF(push_inst(compiler
, (op
== SLJIT_LMUL_UW
? MULTU
: MULT
) | S(SLJIT_R0
) | T(SLJIT_R1
), MOVABLE_INS
));
1980 #endif /* SLJIT_CONFIG_MIPS_64 */
1981 FAIL_IF(push_inst(compiler
, MFLO
| D(SLJIT_R0
), DR(SLJIT_R0
)));
1982 return push_inst(compiler
, MFHI
| D(SLJIT_R1
), DR(SLJIT_R1
));
1983 #endif /* SLJIT_MIPS_REV >= 6 */
1984 case SLJIT_DIVMOD_UW
:
1985 case SLJIT_DIVMOD_SW
:
1988 SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW
& 0x2) == 0 && SLJIT_DIV_UW
- 0x2 == SLJIT_DIVMOD_UW
, bad_div_opcode_assignments
);
1989 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1990 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1992 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DIVU
: DIV
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG3
), DR(TMP_REG3
)));
1993 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? MODU
: MOD
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG1
), DR(TMP_REG1
)));
1996 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DDIVU
: DDIV
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG3
), DR(TMP_REG3
)));
1997 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DMODU
: DMOD
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG1
), DR(TMP_REG1
)));
1999 #else /* !SLJIT_CONFIG_MIPS_64 */
2000 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DIVU
: DIV
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG3
), DR(TMP_REG3
)));
2001 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? MODU
: MOD
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG1
), DR(TMP_REG1
)));
2002 #endif /* SLJIT_CONFIG_MIPS_64 */
2003 FAIL_IF(push_inst(compiler
, ADDU_W
| S(TMP_REG3
) | TA(0) | D(SLJIT_R0
), DR(SLJIT_R0
)));
2004 return (op
>= SLJIT_DIV_UW
) ? SLJIT_SUCCESS
: push_inst(compiler
, ADDU_W
| S(TMP_REG1
) | TA(0) | D(SLJIT_R1
), DR(SLJIT_R1
));
2005 #else /* SLJIT_MIPS_REV < 6 */
2006 #if !(defined SLJIT_MIPS_REV)
2007 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
2008 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
2009 #endif /* !SLJIT_MIPS_REV */
2010 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2012 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DIVU
: DIV
) | S(SLJIT_R0
) | T(SLJIT_R1
), MOVABLE_INS
));
2014 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DDIVU
: DDIV
) | S(SLJIT_R0
) | T(SLJIT_R1
), MOVABLE_INS
));
2015 #else /* !SLJIT_CONFIG_MIPS_64 */
2016 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DIVU
: DIV
) | S(SLJIT_R0
) | T(SLJIT_R1
), MOVABLE_INS
));
2017 #endif /* SLJIT_CONFIG_MIPS_64 */
2018 FAIL_IF(push_inst(compiler
, MFLO
| D(SLJIT_R0
), DR(SLJIT_R0
)));
2019 return (op
>= SLJIT_DIV_UW
) ? SLJIT_SUCCESS
: push_inst(compiler
, MFHI
| D(SLJIT_R1
), DR(SLJIT_R1
));
2020 #endif /* SLJIT_MIPS_REV >= 6 */
2022 case SLJIT_SKIP_FRAMES_BEFORE_RETURN
:
2023 return SLJIT_SUCCESS
;
2026 return SLJIT_SUCCESS
;
2029 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
2030 static sljit_s32
emit_prefetch(struct sljit_compiler
*compiler
,
2031 sljit_s32 src
, sljit_sw srcw
)
2033 if (!(src
& OFFS_REG_MASK
)) {
2034 if (srcw
<= SIMM_MAX
&& srcw
>= SIMM_MIN
)
2035 return push_inst(compiler
, PREF
| S(src
& REG_MASK
) | IMM(srcw
), MOVABLE_INS
);
2037 FAIL_IF(load_immediate(compiler
, DR(TMP_REG1
), srcw
));
2038 return push_inst(compiler
, PREFX
| S(src
& REG_MASK
) | T(TMP_REG1
), MOVABLE_INS
);
2043 if (SLJIT_UNLIKELY(srcw
!= 0)) {
2044 FAIL_IF(push_inst(compiler
, SLL_W
| T(OFFS_REG(src
)) | D(TMP_REG1
) | SH_IMM(srcw
), DR(TMP_REG1
)));
2045 return push_inst(compiler
, PREFX
| S(src
& REG_MASK
) | T(TMP_REG1
), MOVABLE_INS
);
2048 return push_inst(compiler
, PREFX
| S(src
& REG_MASK
) | T(OFFS_REG(src
)), MOVABLE_INS
);
2050 #endif /* SLJIT_MIPS_REV >= 1 */
2052 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op1(struct sljit_compiler
*compiler
, sljit_s32 op
,
2053 sljit_s32 dst
, sljit_sw dstw
,
2054 sljit_s32 src
, sljit_sw srcw
)
2056 sljit_s32 flags
= 0;
2059 CHECK(check_sljit_emit_op1(compiler
, op
, dst
, dstw
, src
, srcw
));
2060 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2061 ADJUST_LOCAL_OFFSET(src
, srcw
);
2063 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2065 flags
= INT_DATA
| SIGNED_DATA
;
2068 switch (GET_OPCODE(op
)) {
2070 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2076 return emit_op(compiler
, SLJIT_MOV
, WORD_DATA
| MOVE_OP
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
2078 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2080 return emit_op(compiler
, SLJIT_MOV_U32
, INT_DATA
| MOVE_OP
, dst
, dstw
, TMP_REG1
, 0, src
, (src
& SLJIT_IMM
) ? (sljit_u32
)srcw
: srcw
);
2084 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
);
2088 return emit_op(compiler
, op
, BYTE_DATA
| MOVE_OP
, dst
, dstw
, TMP_REG1
, 0, src
, (src
& SLJIT_IMM
) ? (sljit_u8
)srcw
: srcw
);
2091 return emit_op(compiler
, op
, BYTE_DATA
| SIGNED_DATA
| MOVE_OP
, dst
, dstw
, TMP_REG1
, 0, src
, (src
& SLJIT_IMM
) ? (sljit_s8
)srcw
: srcw
);
2094 return emit_op(compiler
, op
, HALF_DATA
| MOVE_OP
, dst
, dstw
, TMP_REG1
, 0, src
, (src
& SLJIT_IMM
) ? (sljit_u16
)srcw
: srcw
);
2097 return emit_op(compiler
, op
, HALF_DATA
| SIGNED_DATA
| MOVE_OP
, dst
, dstw
, TMP_REG1
, 0, src
, (src
& SLJIT_IMM
) ? (sljit_s16
)srcw
: srcw
);
2100 return emit_op(compiler
, op
, flags
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
2103 return emit_op(compiler
, op
, flags
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
2106 SLJIT_UNREACHABLE();
2107 return SLJIT_SUCCESS
;
2110 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op2(struct sljit_compiler
*compiler
, sljit_s32 op
,
2111 sljit_s32 dst
, sljit_sw dstw
,
2112 sljit_s32 src1
, sljit_sw src1w
,
2113 sljit_s32 src2
, sljit_sw src2w
)
2115 sljit_s32 flags
= 0;
2118 CHECK(check_sljit_emit_op2(compiler
, op
, 0, dst
, dstw
, src1
, src1w
, src2
, src2w
));
2119 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2120 ADJUST_LOCAL_OFFSET(src1
, src1w
);
2121 ADJUST_LOCAL_OFFSET(src2
, src2w
);
2123 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2124 if (op
& SLJIT_32
) {
2125 flags
|= INT_DATA
| SIGNED_DATA
;
2126 if (src1
& SLJIT_IMM
)
2127 src1w
= (sljit_s32
)src1w
;
2128 if (src2
& SLJIT_IMM
)
2129 src2w
= (sljit_s32
)src2w
;
2133 switch (GET_OPCODE(op
)) {
2136 compiler
->status_flags_state
= SLJIT_CURRENT_FLAGS_ADD
;
2137 return emit_op(compiler
, op
, flags
| CUMULATIVE_OP
| IMM_OP
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
2141 compiler
->status_flags_state
= SLJIT_CURRENT_FLAGS_SUB
;
2142 return emit_op(compiler
, op
, flags
| IMM_OP
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
2145 compiler
->status_flags_state
= 0;
2146 return emit_op(compiler
, op
, flags
| CUMULATIVE_OP
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
2151 return emit_op(compiler
, op
, flags
| CUMULATIVE_OP
| LOGICAL_OP
| IMM_OP
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
2156 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2157 if (src2
& SLJIT_IMM
)
2160 if (src2
& SLJIT_IMM
) {
2167 return emit_op(compiler
, op
, flags
| IMM_OP
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
2170 SLJIT_UNREACHABLE();
2171 return SLJIT_SUCCESS
;
2174 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op2u(struct sljit_compiler
*compiler
, sljit_s32 op
,
2175 sljit_s32 src1
, sljit_sw src1w
,
2176 sljit_s32 src2
, sljit_sw src2w
)
2179 CHECK(check_sljit_emit_op2(compiler
, op
, 1, 0, 0, src1
, src1w
, src2
, src2w
));
2181 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2182 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2183 compiler
->skip_checks
= 1;
2185 return sljit_emit_op2(compiler
, op
, TMP_REG2
, 0, src1
, src1w
, src2
, src2w
);
2188 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_src(struct sljit_compiler
*compiler
, sljit_s32 op
,
2189 sljit_s32 src
, sljit_sw srcw
)
2192 CHECK(check_sljit_emit_op_src(compiler
, op
, src
, srcw
));
2193 ADJUST_LOCAL_OFFSET(src
, srcw
);
2196 case SLJIT_FAST_RETURN
:
2197 if (FAST_IS_REG(src
))
2198 FAIL_IF(push_inst(compiler
, ADDU_W
| S(src
) | TA(0) | DA(RETURN_ADDR_REG
), RETURN_ADDR_REG
));
2200 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
| LOAD_DATA
, RETURN_ADDR_REG
, src
, srcw
));
2202 FAIL_IF(push_inst(compiler
, JR
| SA(RETURN_ADDR_REG
), UNMOVABLE_INS
));
2203 return push_inst(compiler
, NOP
, UNMOVABLE_INS
);
2204 case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN
:
2205 return SLJIT_SUCCESS
;
2206 case SLJIT_PREFETCH_L1
:
2207 case SLJIT_PREFETCH_L2
:
2208 case SLJIT_PREFETCH_L3
:
2209 case SLJIT_PREFETCH_ONCE
:
2210 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
2211 return emit_prefetch(compiler
, src
, srcw
);
2212 #else /* SLJIT_MIPS_REV < 1 */
2213 return SLJIT_SUCCESS
;
2214 #endif /* SLJIT_MIPS_REV >= 1 */
2217 return SLJIT_SUCCESS
;
2220 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_get_register_index(sljit_s32 reg
)
2222 CHECK_REG_INDEX(check_sljit_get_register_index(reg
));
2223 return reg_map
[reg
];
2226 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_get_float_register_index(sljit_s32 reg
)
2228 CHECK_REG_INDEX(check_sljit_get_float_register_index(reg
));
2232 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_custom(struct sljit_compiler
*compiler
,
2233 void *instruction
, sljit_u32 size
)
2236 CHECK(check_sljit_emit_op_custom(compiler
, instruction
, size
));
2238 return push_inst(compiler
, *(sljit_ins
*)instruction
, UNMOVABLE_INS
);
2241 /* --------------------------------------------------------------------- */
2242 /* Floating point operators */
2243 /* --------------------------------------------------------------------- */
2245 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7))
2246 #define FMT(op) ((((sljit_ins)op & SLJIT_32) ^ SLJIT_32) << (21 - 8))
2248 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler
*compiler
, sljit_s32 op
,
2249 sljit_s32 dst
, sljit_sw dstw
,
2250 sljit_s32 src
, sljit_sw srcw
)
2252 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2253 # define flags (sljit_u32)0
2255 sljit_u32 flags
= ((sljit_u32
)(GET_OPCODE(op
) == SLJIT_CONV_SW_FROM_F64
)) << 21;
2258 if (src
& SLJIT_MEM
) {
2259 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG1
), src
, srcw
, dst
, dstw
));
2263 FAIL_IF(push_inst(compiler
, (TRUNC_W_S
^ (flags
>> 19)) | FMT(op
) | FS(src
) | FD(TMP_FREG1
), MOVABLE_INS
));
2265 if (FAST_IS_REG(dst
)) {
2266 FAIL_IF(push_inst(compiler
, MFC1
| flags
| T(dst
) | FS(TMP_FREG1
), MOVABLE_INS
));
2267 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
2268 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
2270 return SLJIT_SUCCESS
;
2273 /* Store the integer value from a VFP register. */
2274 return emit_op_mem2(compiler
, flags
? DOUBLE_DATA
: SINGLE_DATA
, FR(TMP_FREG1
), dst
, dstw
, 0, 0);
2276 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2281 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler
*compiler
, sljit_s32 op
,
2282 sljit_s32 dst
, sljit_sw dstw
,
2283 sljit_s32 src
, sljit_sw srcw
)
2285 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2286 # define flags (sljit_u32)0
2288 sljit_u32 flags
= ((sljit_u32
)(GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_SW
)) << 21;
2291 sljit_s32 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG1
;
2293 if (FAST_IS_REG(src
)) {
2294 FAIL_IF(push_inst(compiler
, MTC1
| flags
| T(src
) | FS(TMP_FREG1
), MOVABLE_INS
));
2295 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
2296 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
2298 } else if (src
& SLJIT_MEM
) {
2299 /* Load the integer value into a VFP register. */
2300 FAIL_IF(emit_op_mem2(compiler
, (flags
? DOUBLE_DATA
: SINGLE_DATA
) | LOAD_DATA
, FR(TMP_FREG1
), src
, srcw
, dst
, dstw
));
2303 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2304 if (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_S32
)
2305 srcw
= (sljit_s32
)srcw
;
2307 FAIL_IF(load_immediate(compiler
, DR(TMP_REG1
), srcw
));
2308 FAIL_IF(push_inst(compiler
, MTC1
| flags
| T(TMP_REG1
) | FS(TMP_FREG1
), MOVABLE_INS
));
2309 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
2310 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
2314 FAIL_IF(push_inst(compiler
, CVT_S_S
| flags
| (4 << 21) | ((((sljit_ins
)op
& SLJIT_32
) ^ SLJIT_32
) >> 8) | FS(TMP_FREG1
) | FD(dst_r
), MOVABLE_INS
));
2316 if (dst
& SLJIT_MEM
)
2317 return emit_op_mem2(compiler
, FLOAT_DATA(op
), FR(TMP_FREG1
), dst
, dstw
, 0, 0);
2318 return SLJIT_SUCCESS
;
2320 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2325 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_cmp(struct sljit_compiler
*compiler
, sljit_s32 op
,
2326 sljit_s32 src1
, sljit_sw src1w
,
2327 sljit_s32 src2
, sljit_sw src2w
)
2331 if (src1
& SLJIT_MEM
) {
2332 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG1
), src1
, src1w
, src2
, src2w
));
2336 if (src2
& SLJIT_MEM
) {
2337 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG2
), src2
, src2w
, 0, 0));
2341 switch (GET_FLAG_TYPE(op
)) {
2343 case SLJIT_ORDERED_EQUAL
:
2344 case SLJIT_UNORDERED_OR_NOT_EQUAL
:
2347 case SLJIT_F_NOT_EQUAL
:
2348 case SLJIT_UNORDERED_OR_EQUAL
:
2349 case SLJIT_ORDERED_NOT_EQUAL
:
2353 case SLJIT_ORDERED_LESS
:
2354 case SLJIT_UNORDERED_OR_GREATER_EQUAL
:
2357 case SLJIT_F_GREATER_EQUAL
:
2358 case SLJIT_UNORDERED_OR_LESS
:
2359 case SLJIT_ORDERED_GREATER_EQUAL
:
2362 case SLJIT_F_GREATER
:
2363 case SLJIT_ORDERED_GREATER
:
2364 case SLJIT_UNORDERED_OR_LESS_EQUAL
:
2367 case SLJIT_F_LESS_EQUAL
:
2368 case SLJIT_UNORDERED_OR_GREATER
:
2369 case SLJIT_ORDERED_LESS_EQUAL
:
2373 SLJIT_ASSERT(GET_FLAG_TYPE(op
) == SLJIT_UNORDERED
|| GET_FLAG_TYPE(op
) == SLJIT_ORDERED
);
2377 return push_inst(compiler
, inst
| FMT(op
) | FT(src2
) | FS(src1
) | C_FD
, UNMOVABLE_INS
);
2380 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fop1(struct sljit_compiler
*compiler
, sljit_s32 op
,
2381 sljit_s32 dst
, sljit_sw dstw
,
2382 sljit_s32 src
, sljit_sw srcw
)
2387 compiler
->cache_arg
= 0;
2388 compiler
->cache_argw
= 0;
2390 SLJIT_COMPILE_ASSERT((SLJIT_32
== 0x100) && !(DOUBLE_DATA
& 0x2), float_transfer_bit_error
);
2391 SELECT_FOP1_OPERATION_WITH_CHECKS(compiler
, op
, dst
, dstw
, src
, srcw
);
2393 if (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_F32
)
2396 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG1
;
2398 if (src
& SLJIT_MEM
) {
2399 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(dst_r
), src
, srcw
, dst
, dstw
));
2403 switch (GET_OPCODE(op
)) {
2406 if (dst_r
!= TMP_FREG1
)
2407 FAIL_IF(push_inst(compiler
, MOV_S
| FMT(op
) | FS(src
) | FD(dst_r
), MOVABLE_INS
));
2413 FAIL_IF(push_inst(compiler
, NEG_S
| FMT(op
) | FS(src
) | FD(dst_r
), MOVABLE_INS
));
2416 FAIL_IF(push_inst(compiler
, ABS_S
| FMT(op
) | FS(src
) | FD(dst_r
), MOVABLE_INS
));
2418 case SLJIT_CONV_F64_FROM_F32
:
2419 /* The SLJIT_32 bit is inverted because sljit_f32 needs to be loaded from the memory. */
2420 FAIL_IF(push_inst(compiler
, CVT_S_S
| (sljit_ins
)((op
& SLJIT_32
) ? 1 : (1 << 21)) | FS(src
) | FD(dst_r
), MOVABLE_INS
));
2425 if (dst
& SLJIT_MEM
)
2426 return emit_op_mem2(compiler
, FLOAT_DATA(op
), FR(dst_r
), dst
, dstw
, 0, 0);
2427 return SLJIT_SUCCESS
;
2430 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fop2(struct sljit_compiler
*compiler
, sljit_s32 op
,
2431 sljit_s32 dst
, sljit_sw dstw
,
2432 sljit_s32 src1
, sljit_sw src1w
,
2433 sljit_s32 src2
, sljit_sw src2w
)
2435 sljit_s32 dst_r
, flags
= 0;
2438 CHECK(check_sljit_emit_fop2(compiler
, op
, dst
, dstw
, src1
, src1w
, src2
, src2w
));
2439 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2440 ADJUST_LOCAL_OFFSET(src1
, src1w
);
2441 ADJUST_LOCAL_OFFSET(src2
, src2w
);
2443 compiler
->cache_arg
= 0;
2444 compiler
->cache_argw
= 0;
2446 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG2
;
2448 if (src1
& SLJIT_MEM
) {
2449 if (getput_arg_fast(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG1
), src1
, src1w
)) {
2450 FAIL_IF(compiler
->error
);
2456 if (src2
& SLJIT_MEM
) {
2457 if (getput_arg_fast(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG2
), src2
, src2w
)) {
2458 FAIL_IF(compiler
->error
);
2464 if ((flags
& (SLOW_SRC1
| SLOW_SRC2
)) == (SLOW_SRC1
| SLOW_SRC2
)) {
2465 if (!can_cache(src1
, src1w
, src2
, src2w
) && can_cache(src1
, src1w
, dst
, dstw
)) {
2466 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG2
), src2
, src2w
, src1
, src1w
));
2467 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG1
), src1
, src1w
, dst
, dstw
));
2470 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG1
), src1
, src1w
, src2
, src2w
));
2471 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG2
), src2
, src2w
, dst
, dstw
));
2474 else if (flags
& SLOW_SRC1
)
2475 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG1
), src1
, src1w
, dst
, dstw
));
2476 else if (flags
& SLOW_SRC2
)
2477 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG2
), src2
, src2w
, dst
, dstw
));
2479 if (flags
& SLOW_SRC1
)
2481 if (flags
& SLOW_SRC2
)
2484 switch (GET_OPCODE(op
)) {
2486 FAIL_IF(push_inst(compiler
, ADD_S
| FMT(op
) | FT(src2
) | FS(src1
) | FD(dst_r
), MOVABLE_INS
));
2490 FAIL_IF(push_inst(compiler
, SUB_S
| FMT(op
) | FT(src2
) | FS(src1
) | FD(dst_r
), MOVABLE_INS
));
2494 FAIL_IF(push_inst(compiler
, MUL_S
| FMT(op
) | FT(src2
) | FS(src1
) | FD(dst_r
), MOVABLE_INS
));
2498 FAIL_IF(push_inst(compiler
, DIV_S
| FMT(op
) | FT(src2
) | FS(src1
) | FD(dst_r
), MOVABLE_INS
));
2502 if (dst_r
== TMP_FREG2
)
2503 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
), FR(TMP_FREG2
), dst
, dstw
, 0, 0));
2505 return SLJIT_SUCCESS
;
2511 /* --------------------------------------------------------------------- */
2512 /* Other instructions */
2513 /* --------------------------------------------------------------------- */
2515 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fast_enter(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
)
2518 CHECK(check_sljit_emit_fast_enter(compiler
, dst
, dstw
));
2519 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2521 if (FAST_IS_REG(dst
))
2522 return push_inst(compiler
, ADDU_W
| SA(RETURN_ADDR_REG
) | TA(0) | D(dst
), UNMOVABLE_INS
);
2525 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, RETURN_ADDR_REG
, dst
, dstw
));
2526 compiler
->delay_slot
= UNMOVABLE_INS
;
2527 return SLJIT_SUCCESS
;
2530 /* --------------------------------------------------------------------- */
2531 /* Conditional instructions */
2532 /* --------------------------------------------------------------------- */
2534 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_label
* sljit_emit_label(struct sljit_compiler
*compiler
)
2536 struct sljit_label
*label
;
2539 CHECK_PTR(check_sljit_emit_label(compiler
));
2541 if (compiler
->last_label
&& compiler
->last_label
->size
== compiler
->size
)
2542 return compiler
->last_label
;
2544 label
= (struct sljit_label
*)ensure_abuf(compiler
, sizeof(struct sljit_label
));
2545 PTR_FAIL_IF(!label
);
2546 set_label(label
, compiler
);
2547 compiler
->delay_slot
= UNMOVABLE_INS
;
2551 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2552 #define BRANCH_LENGTH 4
2554 #define BRANCH_LENGTH 8
2558 inst = BEQ | SA(src) | TA(0) | BRANCH_LENGTH; \
2559 flags = IS_BIT26_COND; \
2562 #define BR_NZ(src) \
2563 inst = BNE | SA(src) | TA(0) | BRANCH_LENGTH; \
2564 flags = IS_BIT26_COND; \
2567 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2571 flags = IS_BIT23_COND; \
2572 delay_check = FCSR_FCC;
2575 flags = IS_BIT23_COND; \
2576 delay_check = FCSR_FCC;
2578 #else /* SLJIT_MIPS_REV < 6 */
2581 inst = BC1T | BRANCH_LENGTH; \
2582 flags = IS_BIT16_COND; \
2583 delay_check = FCSR_FCC;
2585 inst = BC1F | BRANCH_LENGTH; \
2586 flags = IS_BIT16_COND; \
2587 delay_check = FCSR_FCC;
2589 #endif /* SLJIT_MIPS_REV >= 6 */
2591 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_jump(struct sljit_compiler
*compiler
, sljit_s32 type
)
2593 struct sljit_jump
*jump
;
2595 sljit_u32 flags
= 0;
2596 sljit_s32 delay_check
= UNMOVABLE_INS
;
2599 CHECK_PTR(check_sljit_emit_jump(compiler
, type
));
2601 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
2603 set_jump(jump
, compiler
, type
& SLJIT_REWRITABLE_JUMP
);
2610 case SLJIT_NOT_EQUAL
:
2615 case SLJIT_SIG_LESS
:
2616 case SLJIT_SIG_GREATER
:
2617 case SLJIT_OVERFLOW
:
2621 case SLJIT_GREATER_EQUAL
:
2622 case SLJIT_LESS_EQUAL
:
2623 case SLJIT_SIG_GREATER_EQUAL
:
2624 case SLJIT_SIG_LESS_EQUAL
:
2625 case SLJIT_NOT_OVERFLOW
:
2626 case SLJIT_NOT_CARRY
:
2629 case SLJIT_F_NOT_EQUAL
:
2630 case SLJIT_F_GREATER_EQUAL
:
2631 case SLJIT_F_GREATER
:
2632 case SLJIT_UNORDERED_OR_NOT_EQUAL
:
2633 case SLJIT_ORDERED_NOT_EQUAL
:
2634 case SLJIT_UNORDERED_OR_GREATER_EQUAL
:
2635 case SLJIT_ORDERED_GREATER_EQUAL
:
2636 case SLJIT_ORDERED_GREATER
:
2637 case SLJIT_UNORDERED_OR_GREATER
:
2643 case SLJIT_F_LESS_EQUAL
:
2644 case SLJIT_ORDERED_EQUAL
:
2645 case SLJIT_UNORDERED_OR_EQUAL
:
2646 case SLJIT_ORDERED_LESS
:
2647 case SLJIT_UNORDERED_OR_LESS
:
2648 case SLJIT_UNORDERED_OR_LESS_EQUAL
:
2649 case SLJIT_ORDERED_LESS_EQUAL
:
2650 case SLJIT_UNORDERED
:
2654 /* Not conditional branch. */
2659 jump
->flags
|= flags
;
2660 if (compiler
->delay_slot
== MOVABLE_INS
|| (compiler
->delay_slot
!= UNMOVABLE_INS
&& compiler
->delay_slot
!= delay_check
))
2661 jump
->flags
|= IS_MOVABLE
;
2664 PTR_FAIL_IF(push_inst(compiler
, inst
, UNMOVABLE_INS
));
2666 if (type
<= SLJIT_JUMP
)
2667 PTR_FAIL_IF(push_inst(compiler
, JR
| S(TMP_REG2
), UNMOVABLE_INS
));
2669 jump
->flags
|= IS_JAL
;
2670 PTR_FAIL_IF(push_inst(compiler
, JALR
| S(TMP_REG2
) | DA(RETURN_ADDR_REG
), UNMOVABLE_INS
));
2673 jump
->addr
= compiler
->size
;
2674 PTR_FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
2676 /* Maximum number of instructions required for generating a constant. */
2677 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2678 compiler
->size
+= 2;
2680 compiler
->size
+= 6;
2685 #define RESOLVE_IMM1() \
2686 if (src1 & SLJIT_IMM) { \
2688 PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \
2695 #define RESOLVE_IMM2() \
2696 if (src2 & SLJIT_IMM) { \
2698 PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \
2705 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_cmp(struct sljit_compiler
*compiler
, sljit_s32 type
,
2706 sljit_s32 src1
, sljit_sw src1w
,
2707 sljit_s32 src2
, sljit_sw src2w
)
2709 struct sljit_jump
*jump
;
2714 CHECK_PTR(check_sljit_emit_cmp(compiler
, type
, src1
, src1w
, src2
, src2w
));
2715 ADJUST_LOCAL_OFFSET(src1
, src1w
);
2716 ADJUST_LOCAL_OFFSET(src2
, src2w
);
2718 compiler
->cache_arg
= 0;
2719 compiler
->cache_argw
= 0;
2720 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2721 flags
= WORD_DATA
| LOAD_DATA
;
2722 #else /* !SLJIT_CONFIG_MIPS_32 */
2723 flags
= ((type
& SLJIT_32
) ? INT_DATA
: WORD_DATA
) | LOAD_DATA
;
2724 #endif /* SLJIT_CONFIG_MIPS_32 */
2726 if (src1
& SLJIT_MEM
) {
2727 PTR_FAIL_IF(emit_op_mem2(compiler
, flags
, DR(TMP_REG1
), src1
, src1w
, src2
, src2w
));
2731 if (src2
& SLJIT_MEM
) {
2732 PTR_FAIL_IF(emit_op_mem2(compiler
, flags
, DR(TMP_REG2
), src2
, src2w
, 0, 0));
2736 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
2738 set_jump(jump
, compiler
, type
& SLJIT_REWRITABLE_JUMP
);
2741 if (type
<= SLJIT_NOT_EQUAL
) {
2744 jump
->flags
|= IS_BIT26_COND
;
2745 if (compiler
->delay_slot
== MOVABLE_INS
|| (compiler
->delay_slot
!= UNMOVABLE_INS
&& compiler
->delay_slot
!= DR(src1
) && compiler
->delay_slot
!= DR(src2
)))
2746 jump
->flags
|= IS_MOVABLE
;
2747 PTR_FAIL_IF(push_inst(compiler
, (type
== SLJIT_EQUAL
? BNE
: BEQ
) | S(src1
) | T(src2
) | BRANCH_LENGTH
, UNMOVABLE_INS
));
2749 else if (type
>= SLJIT_SIG_LESS
&& (((src1
& SLJIT_IMM
) && (src1w
== 0)) || ((src2
& SLJIT_IMM
) && (src2w
== 0)))) {
2751 if ((src1
& SLJIT_IMM
) && (src1w
== 0)) {
2754 case SLJIT_SIG_LESS
:
2756 jump
->flags
|= IS_BIT26_COND
;
2758 case SLJIT_SIG_GREATER_EQUAL
:
2760 jump
->flags
|= IS_BIT26_COND
;
2762 case SLJIT_SIG_GREATER
:
2764 jump
->flags
|= IS_BIT16_COND
;
2766 case SLJIT_SIG_LESS_EQUAL
:
2768 jump
->flags
|= IS_BIT16_COND
;
2776 case SLJIT_SIG_LESS
:
2778 jump
->flags
|= IS_BIT16_COND
;
2780 case SLJIT_SIG_GREATER_EQUAL
:
2782 jump
->flags
|= IS_BIT16_COND
;
2784 case SLJIT_SIG_GREATER
:
2786 jump
->flags
|= IS_BIT26_COND
;
2788 case SLJIT_SIG_LESS_EQUAL
:
2790 jump
->flags
|= IS_BIT26_COND
;
2794 PTR_FAIL_IF(push_inst(compiler
, inst
| S(src1
) | BRANCH_LENGTH
, UNMOVABLE_INS
));
2797 if (type
== SLJIT_LESS
|| type
== SLJIT_GREATER_EQUAL
|| type
== SLJIT_SIG_LESS
|| type
== SLJIT_SIG_GREATER_EQUAL
) {
2799 if ((src2
& SLJIT_IMM
) && src2w
<= SIMM_MAX
&& src2w
>= SIMM_MIN
)
2800 PTR_FAIL_IF(push_inst(compiler
, (type
<= SLJIT_LESS_EQUAL
? SLTIU
: SLTI
) | S(src1
) | T(TMP_REG1
) | IMM(src2w
), DR(TMP_REG1
)));
2803 PTR_FAIL_IF(push_inst(compiler
, (type
<= SLJIT_LESS_EQUAL
? SLTU
: SLT
) | S(src1
) | T(src2
) | D(TMP_REG1
), DR(TMP_REG1
)));
2805 type
= (type
== SLJIT_LESS
|| type
== SLJIT_SIG_LESS
) ? SLJIT_NOT_EQUAL
: SLJIT_EQUAL
;
2809 if ((src1
& SLJIT_IMM
) && src1w
<= SIMM_MAX
&& src1w
>= SIMM_MIN
)
2810 PTR_FAIL_IF(push_inst(compiler
, (type
<= SLJIT_LESS_EQUAL
? SLTIU
: SLTI
) | S(src2
) | T(TMP_REG1
) | IMM(src1w
), DR(TMP_REG1
)));
2813 PTR_FAIL_IF(push_inst(compiler
, (type
<= SLJIT_LESS_EQUAL
? SLTU
: SLT
) | S(src2
) | T(src1
) | D(TMP_REG1
), DR(TMP_REG1
)));
2815 type
= (type
== SLJIT_GREATER
|| type
== SLJIT_SIG_GREATER
) ? SLJIT_NOT_EQUAL
: SLJIT_EQUAL
;
2818 jump
->flags
|= IS_BIT26_COND
;
2819 PTR_FAIL_IF(push_inst(compiler
, (type
== SLJIT_EQUAL
? BNE
: BEQ
) | S(TMP_REG1
) | TA(0) | BRANCH_LENGTH
, UNMOVABLE_INS
));
2822 PTR_FAIL_IF(push_inst(compiler
, JR
| S(TMP_REG2
), UNMOVABLE_INS
));
2823 jump
->addr
= compiler
->size
;
2824 PTR_FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
2826 /* Maximum number of instructions required for generating a constant. */
2827 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2828 compiler
->size
+= 2;
2830 compiler
->size
+= 6;
2838 #undef BRANCH_LENGTH
2847 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_ijump(struct sljit_compiler
*compiler
, sljit_s32 type
, sljit_s32 src
, sljit_sw srcw
)
2849 struct sljit_jump
*jump
= NULL
;
2852 CHECK(check_sljit_emit_ijump(compiler
, type
, src
, srcw
));
2853 ADJUST_LOCAL_OFFSET(src
, srcw
);
2855 if (src
& SLJIT_IMM
) {
2856 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
2858 set_jump(jump
, compiler
, JUMP_ADDR
| ((type
>= SLJIT_FAST_CALL
) ? IS_JAL
: 0));
2859 jump
->u
.target
= (sljit_uw
)srcw
;
2861 if (compiler
->delay_slot
!= UNMOVABLE_INS
)
2862 jump
->flags
|= IS_MOVABLE
;
2866 else if (src
& SLJIT_MEM
) {
2867 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
| LOAD_DATA
, DR(TMP_REG2
), src
, srcw
));
2871 if (type
<= SLJIT_JUMP
)
2872 FAIL_IF(push_inst(compiler
, JR
| S(src
), UNMOVABLE_INS
));
2874 FAIL_IF(push_inst(compiler
, JALR
| S(src
) | DA(RETURN_ADDR_REG
), UNMOVABLE_INS
));
2877 jump
->addr
= compiler
->size
;
2879 /* Maximum number of instructions required for generating a constant. */
2880 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2881 compiler
->size
+= 2;
2883 compiler
->size
+= 6;
2886 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
2887 return SLJIT_SUCCESS
;
2890 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_flags(struct sljit_compiler
*compiler
, sljit_s32 op
,
2891 sljit_s32 dst
, sljit_sw dstw
,
2894 sljit_s32 src_ar
, dst_ar
, invert
;
2895 sljit_s32 saved_op
= op
;
2896 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2897 sljit_s32 mem_type
= WORD_DATA
;
2899 sljit_s32 mem_type
= ((op
& SLJIT_32
) || op
== SLJIT_MOV32
) ? (INT_DATA
| SIGNED_DATA
) : WORD_DATA
;
2903 CHECK(check_sljit_emit_op_flags(compiler
, op
, dst
, dstw
, type
));
2904 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2906 op
= GET_OPCODE(op
);
2907 dst_ar
= DR((op
< SLJIT_ADD
&& FAST_IS_REG(dst
)) ? dst
: TMP_REG2
);
2909 compiler
->cache_arg
= 0;
2910 compiler
->cache_argw
= 0;
2912 if (op
>= SLJIT_ADD
&& (dst
& SLJIT_MEM
))
2913 FAIL_IF(emit_op_mem2(compiler
, mem_type
| LOAD_DATA
, DR(TMP_REG1
), dst
, dstw
, dst
, dstw
));
2915 if (type
< SLJIT_F_EQUAL
) {
2916 src_ar
= OTHER_FLAG
;
2917 invert
= type
& 0x1;
2921 case SLJIT_NOT_EQUAL
:
2922 FAIL_IF(push_inst(compiler
, SLTIU
| SA(EQUAL_FLAG
) | TA(dst_ar
) | IMM(1), dst_ar
));
2925 case SLJIT_OVERFLOW
:
2926 case SLJIT_NOT_OVERFLOW
:
2927 if (compiler
->status_flags_state
& (SLJIT_CURRENT_FLAGS_ADD
| SLJIT_CURRENT_FLAGS_SUB
)) {
2928 src_ar
= OTHER_FLAG
;
2931 FAIL_IF(push_inst(compiler
, SLTIU
| SA(OTHER_FLAG
) | TA(dst_ar
) | IMM(1), dst_ar
));
2940 case SLJIT_F_NOT_EQUAL
:
2941 case SLJIT_F_GREATER_EQUAL
:
2942 case SLJIT_F_GREATER
:
2943 case SLJIT_UNORDERED_OR_NOT_EQUAL
:
2944 case SLJIT_ORDERED_NOT_EQUAL
:
2945 case SLJIT_UNORDERED_OR_GREATER_EQUAL
:
2946 case SLJIT_ORDERED_GREATER_EQUAL
:
2947 case SLJIT_ORDERED_GREATER
:
2948 case SLJIT_UNORDERED_OR_GREATER
:
2954 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2955 FAIL_IF(push_inst(compiler
, MFC1
| TA(dst_ar
) | FS(TMP_FREG3
), dst_ar
));
2956 #else /* SLJIT_MIPS_REV < 6 */
2957 FAIL_IF(push_inst(compiler
, CFC1
| TA(dst_ar
) | DA(FCSR_REG
), dst_ar
));
2958 #endif /* SLJIT_MIPS_REV >= 6 */
2959 FAIL_IF(push_inst(compiler
, SRL
| TA(dst_ar
) | DA(dst_ar
) | SH_IMM(23), dst_ar
));
2960 FAIL_IF(push_inst(compiler
, ANDI
| SA(dst_ar
) | TA(dst_ar
) | IMM(1), dst_ar
));
2965 FAIL_IF(push_inst(compiler
, XORI
| SA(src_ar
) | TA(dst_ar
) | IMM(1), dst_ar
));
2969 if (op
< SLJIT_ADD
) {
2970 if (dst
& SLJIT_MEM
)
2971 return emit_op_mem(compiler
, mem_type
, src_ar
, dst
, dstw
);
2973 if (src_ar
!= dst_ar
)
2974 return push_inst(compiler
, ADDU_W
| SA(src_ar
) | TA(0) | DA(dst_ar
), dst_ar
);
2975 return SLJIT_SUCCESS
;
2978 /* OTHER_FLAG cannot be specified as src2 argument at the moment. */
2979 if (DR(TMP_REG2
) != src_ar
)
2980 FAIL_IF(push_inst(compiler
, ADDU_W
| SA(src_ar
) | TA(0) | D(TMP_REG2
), DR(TMP_REG2
)));
2982 mem_type
|= CUMULATIVE_OP
| LOGICAL_OP
| IMM_OP
| ALT_KEEP_CACHE
;
2984 if (dst
& SLJIT_MEM
)
2985 return emit_op(compiler
, saved_op
, mem_type
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0);
2986 return emit_op(compiler
, saved_op
, mem_type
, dst
, dstw
, dst
, dstw
, TMP_REG2
, 0);
2989 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_cmov(struct sljit_compiler
*compiler
, sljit_s32 type
,
2991 sljit_s32 src
, sljit_sw srcw
)
2993 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
2995 #endif /* SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6 */
2998 CHECK(check_sljit_emit_cmov(compiler
, type
, dst_reg
, src
, srcw
));
3000 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
3002 if (SLJIT_UNLIKELY(src
& SLJIT_IMM
)) {
3003 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
3004 if (dst_reg
& SLJIT_32
)
3005 srcw
= (sljit_s32
)srcw
;
3007 FAIL_IF(load_immediate(compiler
, DR(TMP_REG1
), srcw
));
3012 dst_reg
&= ~SLJIT_32
;
3016 ins
= MOVZ
| TA(EQUAL_FLAG
);
3018 case SLJIT_NOT_EQUAL
:
3019 ins
= MOVN
| TA(EQUAL_FLAG
);
3023 case SLJIT_SIG_LESS
:
3024 case SLJIT_SIG_GREATER
:
3025 case SLJIT_OVERFLOW
:
3026 ins
= MOVN
| TA(OTHER_FLAG
);
3028 case SLJIT_GREATER_EQUAL
:
3029 case SLJIT_LESS_EQUAL
:
3030 case SLJIT_SIG_GREATER_EQUAL
:
3031 case SLJIT_SIG_LESS_EQUAL
:
3032 case SLJIT_NOT_OVERFLOW
:
3033 ins
= MOVZ
| TA(OTHER_FLAG
);
3037 case SLJIT_F_LESS_EQUAL
:
3038 case SLJIT_ORDERED_EQUAL
:
3039 case SLJIT_UNORDERED_OR_EQUAL
:
3040 case SLJIT_ORDERED_LESS
:
3041 case SLJIT_UNORDERED_OR_LESS
:
3042 case SLJIT_UNORDERED_OR_LESS_EQUAL
:
3043 case SLJIT_ORDERED_LESS_EQUAL
:
3044 case SLJIT_UNORDERED
:
3047 case SLJIT_F_NOT_EQUAL
:
3048 case SLJIT_F_GREATER_EQUAL
:
3049 case SLJIT_F_GREATER
:
3050 case SLJIT_UNORDERED_OR_NOT_EQUAL
:
3051 case SLJIT_ORDERED_NOT_EQUAL
:
3052 case SLJIT_UNORDERED_OR_GREATER_EQUAL
:
3053 case SLJIT_ORDERED_GREATER_EQUAL
:
3054 case SLJIT_ORDERED_GREATER
:
3055 case SLJIT_UNORDERED_OR_GREATER
:
3060 ins
= MOVZ
| TA(OTHER_FLAG
);
3061 SLJIT_UNREACHABLE();
3065 return push_inst(compiler
, ins
| S(src
) | D(dst_reg
), DR(dst_reg
));
3067 #else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */
3068 return sljit_emit_cmov_generic(compiler
, type
, dst_reg
, src
, srcw
);
3069 #endif /* SLJIT_MIPS_REV >= 1 */
3072 #if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
3074 static sljit_s32
update_mem_addr(struct sljit_compiler
*compiler
, sljit_s32
*mem
, sljit_sw
*memw
, sljit_s16 max_offset
)
3076 sljit_s32 arg
= *mem
;
3077 sljit_sw argw
= *memw
;
3079 if (SLJIT_UNLIKELY(arg
& OFFS_REG_MASK
)) {
3082 if (SLJIT_UNLIKELY(argw
)) {
3083 FAIL_IF(push_inst(compiler
, SLL_W
| T(OFFS_REG(arg
)) | D(TMP_REG1
) | SH_IMM(argw
), DR(TMP_REG1
)));
3084 FAIL_IF(push_inst(compiler
, ADDU_W
| S(arg
& REG_MASK
) | T(TMP_REG1
) | D(TMP_REG1
), DR(TMP_REG1
)));
3086 FAIL_IF(push_inst(compiler
, ADDU_W
| S(arg
& REG_MASK
) | T(OFFS_REG(arg
)) | D(TMP_REG1
), DR(TMP_REG1
)));
3091 return SLJIT_SUCCESS
;
3094 if (argw
<= max_offset
&& argw
>= SIMM_MIN
) {
3095 *mem
= arg
& REG_MASK
;
3096 return SLJIT_SUCCESS
;
3101 if ((sljit_s16
)argw
> max_offset
) {
3102 FAIL_IF(load_immediate(compiler
, DR(TMP_REG1
), argw
));
3105 FAIL_IF(load_immediate(compiler
, DR(TMP_REG1
), TO_ARGW_HI(argw
)));
3106 *memw
= (sljit_s16
)argw
;
3109 if ((arg
& REG_MASK
) == 0)
3110 return SLJIT_SUCCESS
;
3112 return push_inst(compiler
, ADDU_W
| S(arg
& REG_MASK
) | T(TMP_REG1
) | D(TMP_REG1
), DR(TMP_REG1
));
3115 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
3116 #define MEM16_IMM_FIRST(memw) IMM((memw) + 1)
3117 #define MEM16_IMM_SECOND(memw) IMM(memw)
3118 #define MEMF64_FS_FIRST(freg) FS(freg)
3119 #define MEMF64_FS_SECOND(freg) (FS(freg) | ((sljit_ins)1 << 11))
3120 #else /* !SLJIT_LITTLE_ENDIAN */
3121 #define MEM16_IMM_FIRST(memw) IMM(memw)
3122 #define MEM16_IMM_SECOND(memw) IMM((memw) + 1)
3123 #define MEMF64_FS_FIRST(freg) (FS(freg) | ((sljit_ins)1 << 11))
3124 #define MEMF64_FS_SECOND(freg) FS(freg)
3125 #endif /* SLJIT_LITTLE_ENDIAN */
3127 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_mem(struct sljit_compiler
*compiler
, sljit_s32 type
,
3129 sljit_s32 mem
, sljit_sw memw
)
3131 sljit_s32 op
= type
& 0xff;
3132 sljit_s32 flags
= 0;
3135 CHECK(check_sljit_emit_mem(compiler
, type
, reg
, mem
, memw
));
3137 if (type
& (SLJIT_MEM_PRE
| SLJIT_MEM_POST
))
3138 return SLJIT_ERR_UNSUPPORTED
;
3144 if (!(type
& SLJIT_MEM_STORE
))
3147 if (op
== SLJIT_MOV_S8
)
3148 flags
|= SIGNED_DATA
;
3150 return emit_op_mem(compiler
, flags
, DR(reg
), mem
, memw
);
3154 FAIL_IF(update_mem_addr(compiler
, &mem
, &memw
, SIMM_MAX
- 1));
3155 SLJIT_ASSERT(FAST_IS_REG(mem
) && mem
!= TMP_REG2
);
3157 if (type
& SLJIT_MEM_STORE
) {
3158 FAIL_IF(push_inst(compiler
, SRA_W
| T(reg
) | D(TMP_REG2
) | SH_IMM(8), DR(TMP_REG2
)));
3159 FAIL_IF(push_inst(compiler
, data_transfer_insts
[BYTE_DATA
] | S(mem
) | T(TMP_REG2
) | MEM16_IMM_FIRST(memw
), MOVABLE_INS
));
3160 return push_inst(compiler
, data_transfer_insts
[BYTE_DATA
] | S(mem
) | T(reg
) | MEM16_IMM_SECOND(memw
), MOVABLE_INS
);
3163 flags
= BYTE_DATA
| LOAD_DATA
;
3165 if (op
== SLJIT_MOV_S16
)
3166 flags
|= SIGNED_DATA
;
3168 FAIL_IF(push_inst(compiler
, data_transfer_insts
[flags
] | S(mem
) | T(TMP_REG2
) | MEM16_IMM_FIRST(memw
), DR(TMP_REG2
)));
3169 FAIL_IF(push_inst(compiler
, data_transfer_insts
[BYTE_DATA
| LOAD_DATA
] | S(mem
) | T(reg
) | MEM16_IMM_SECOND(memw
), DR(reg
)));
3170 FAIL_IF(push_inst(compiler
, SLL_W
| T(TMP_REG2
) | D(TMP_REG2
) | SH_IMM(8), DR(TMP_REG2
)));
3171 return push_inst(compiler
, OR
| S(reg
) | T(TMP_REG2
) | D(reg
), DR(reg
));
3175 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3176 if (type
& SLJIT_MEM_ALIGNED_32
) {
3178 if (!(type
& SLJIT_MEM_STORE
))
3181 return emit_op_mem(compiler
, flags
, DR(reg
), mem
, memw
);
3183 #else /* !SLJIT_CONFIG_MIPS_32 */
3184 FAIL_IF(update_mem_addr(compiler
, &mem
, &memw
, SIMM_MAX
- 7));
3185 SLJIT_ASSERT(FAST_IS_REG(mem
) && mem
!= TMP_REG2
);
3187 if (type
& SLJIT_MEM_STORE
) {
3188 FAIL_IF(push_inst(compiler
, SDL
| S(mem
) | T(reg
) | IMM(memw
), MOVABLE_INS
));
3189 return push_inst(compiler
, SDR
| S(mem
) | T(reg
) | IMM(memw
+ 7), MOVABLE_INS
);
3193 FAIL_IF(push_inst(compiler
, DADDU
| S(mem
) | TA(0) | D(TMP_REG1
), DR(TMP_REG1
)));
3197 FAIL_IF(push_inst(compiler
, LDL
| S(mem
) | T(reg
) | IMM(memw
), DR(reg
)));
3198 return push_inst(compiler
, LDR
| S(mem
) | T(reg
) | IMM(memw
+ 7), DR(reg
));
3199 #endif /* SLJIT_CONFIG_MIPS_32 */
3202 FAIL_IF(update_mem_addr(compiler
, &mem
, &memw
, SIMM_MAX
- 3));
3203 SLJIT_ASSERT(FAST_IS_REG(mem
) && mem
!= TMP_REG2
);
3205 if (type
& SLJIT_MEM_STORE
) {
3206 FAIL_IF(push_inst(compiler
, SWL
| S(mem
) | T(reg
) | IMM(memw
), MOVABLE_INS
));
3207 return push_inst(compiler
, SWR
| S(mem
) | T(reg
) | IMM(memw
+ 3), MOVABLE_INS
);
3210 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3212 FAIL_IF(push_inst(compiler
, ADDU
| S(mem
) | TA(0) | D(TMP_REG1
), DR(TMP_REG1
)));
3216 FAIL_IF(push_inst(compiler
, LWL
| S(mem
) | T(reg
) | IMM(memw
), DR(reg
)));
3217 return push_inst(compiler
, LWR
| S(mem
) | T(reg
) | IMM(memw
+ 3), DR(reg
));
3219 #else /* !SLJIT_CONFIG_MIPS_32 */
3221 FAIL_IF(push_inst(compiler
, DADDU
| S(mem
) | TA(0) | D(TMP_REG1
), DR(TMP_REG1
)));
3225 FAIL_IF(push_inst(compiler
, LWL
| S(mem
) | T(reg
) | IMM(memw
), DR(reg
)));
3226 FAIL_IF(push_inst(compiler
, LWR
| S(mem
) | T(reg
) | IMM(memw
+ 3), DR(reg
)));
3228 if (op
== SLJIT_MOV_U32
) {
3229 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
3230 return push_inst(compiler
, DINSU
| T(reg
) | SA(0) | (31 << 11) | (0 << 11), DR(reg
));
3231 #else /* SLJIT_MIPS_REV < 1 */
3232 FAIL_IF(push_inst(compiler
, DSLL32
| T(reg
) | D(reg
) | SH_IMM(0), DR(reg
)));
3233 return push_inst(compiler
, DSRL32
| T(reg
) | D(reg
) | SH_IMM(0), DR(reg
));
3234 #endif /* SLJIT_MIPS_REV >= 2 */
3237 return SLJIT_SUCCESS
;
3238 #endif /* SLJIT_CONFIG_MIPS_32 */
3241 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fmem(struct sljit_compiler
*compiler
, sljit_s32 type
,
3243 sljit_s32 mem
, sljit_sw memw
)
3246 CHECK(check_sljit_emit_fmem(compiler
, type
, freg
, mem
, memw
));
3248 if (type
& (SLJIT_MEM_PRE
| SLJIT_MEM_POST
))
3249 return SLJIT_ERR_UNSUPPORTED
;
3251 FAIL_IF(update_mem_addr(compiler
, &mem
, &memw
, SIMM_MAX
- (type
& SLJIT_32
) ? 3 : 7));
3252 SLJIT_ASSERT(FAST_IS_REG(mem
) && mem
!= TMP_REG2
);
3254 if (type
& SLJIT_MEM_STORE
) {
3255 if (type
& SLJIT_32
) {
3256 FAIL_IF(push_inst(compiler
, MFC1
| T(TMP_REG2
) | FS(freg
), DR(TMP_REG2
)));
3257 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3258 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
3260 FAIL_IF(push_inst(compiler
, SWL
| S(mem
) | T(TMP_REG2
) | IMM(memw
), MOVABLE_INS
));
3261 return push_inst(compiler
, SWR
| S(mem
) | T(TMP_REG2
) | IMM(memw
+ 3), MOVABLE_INS
);
3264 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3265 FAIL_IF(push_inst(compiler
, MFC1
| T(TMP_REG2
) | MEMF64_FS_FIRST(freg
), DR(TMP_REG2
)));
3266 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3267 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
3269 FAIL_IF(push_inst(compiler
, SWL
| S(mem
) | T(TMP_REG2
) | IMM(memw
), MOVABLE_INS
));
3270 FAIL_IF(push_inst(compiler
, SWR
| S(mem
) | T(TMP_REG2
) | IMM(memw
+ 3), MOVABLE_INS
));
3272 FAIL_IF(push_inst(compiler
, MFC1
| T(TMP_REG2
) | MEMF64_FS_SECOND(freg
), DR(TMP_REG2
)));
3273 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3274 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
3276 FAIL_IF(push_inst(compiler
, SWL
| S(mem
) | T(TMP_REG2
) | IMM(memw
+ 4), MOVABLE_INS
));
3277 return push_inst(compiler
, SWR
| S(mem
) | T(TMP_REG2
) | IMM(memw
+ 7), MOVABLE_INS
);
3278 #else /* !SLJIT_CONFIG_MIPS_32 */
3279 FAIL_IF(push_inst(compiler
, MFC1
| (1 << 21) | T(TMP_REG2
) | FS(freg
), DR(TMP_REG2
)));
3280 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3281 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
3283 FAIL_IF(push_inst(compiler
, SDL
| S(mem
) | T(TMP_REG2
) | IMM(memw
), MOVABLE_INS
));
3284 return push_inst(compiler
, SDR
| S(mem
) | T(TMP_REG2
) | IMM(memw
+ 7), MOVABLE_INS
);
3285 #endif /* SLJIT_CONFIG_MIPS_32 */
3288 if (type
& SLJIT_32
) {
3289 FAIL_IF(push_inst(compiler
, LWL
| S(mem
) | T(TMP_REG2
) | IMM(memw
), DR(TMP_REG2
)));
3290 FAIL_IF(push_inst(compiler
, LWR
| S(mem
) | T(TMP_REG2
) | IMM(memw
+ 3), DR(TMP_REG2
)));
3292 FAIL_IF(push_inst(compiler
, MTC1
| T(TMP_REG2
) | FS(freg
), MOVABLE_INS
));
3293 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3294 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
3296 return SLJIT_SUCCESS
;
3299 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3300 FAIL_IF(push_inst(compiler
, LWL
| S(mem
) | T(TMP_REG2
) | IMM(memw
), DR(TMP_REG2
)));
3301 FAIL_IF(push_inst(compiler
, LWR
| S(mem
) | T(TMP_REG2
) | IMM(memw
+ 3), DR(TMP_REG2
)));
3302 FAIL_IF(push_inst(compiler
, MTC1
| T(TMP_REG2
) | MEMF64_FS_FIRST(freg
), MOVABLE_INS
));
3304 FAIL_IF(push_inst(compiler
, LWL
| S(mem
) | T(TMP_REG2
) | IMM(memw
+ 4), DR(TMP_REG2
)));
3305 FAIL_IF(push_inst(compiler
, LWR
| S(mem
) | T(TMP_REG2
) | IMM(memw
+ 7), DR(TMP_REG2
)));
3306 FAIL_IF(push_inst(compiler
, MTC1
| T(TMP_REG2
) | MEMF64_FS_SECOND(freg
), MOVABLE_INS
));
3307 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3308 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
3310 #else /* !SLJIT_CONFIG_MIPS_32 */
3311 FAIL_IF(push_inst(compiler
, LDL
| S(mem
) | T(TMP_REG2
) | IMM(memw
), DR(TMP_REG2
)));
3312 FAIL_IF(push_inst(compiler
, LDR
| S(mem
) | T(TMP_REG2
) | IMM(memw
+ 7), DR(TMP_REG2
)));
3314 FAIL_IF(push_inst(compiler
, MTC1
| (1 << 21) | T(TMP_REG2
) | FS(freg
), MOVABLE_INS
));
3315 #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
3316 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
3318 #endif /* SLJIT_CONFIG_MIPS_32 */
3319 return SLJIT_SUCCESS
;
3322 #undef MEM16_IMM_FIRST
3323 #undef MEM16_IMM_SECOND
3324 #undef MEMF64_FS_FIRST
3325 #undef MEMF64_FS_SECOND
3327 #endif /* !SLJIT_MIPS_REV || SLJIT_MIPS_REV < 6 */
3331 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_const
* sljit_emit_const(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
, sljit_sw init_value
)
3333 struct sljit_const
*const_
;
3337 CHECK_PTR(check_sljit_emit_const(compiler
, dst
, dstw
, init_value
));
3338 ADJUST_LOCAL_OFFSET(dst
, dstw
);
3340 const_
= (struct sljit_const
*)ensure_abuf(compiler
, sizeof(struct sljit_const
));
3341 PTR_FAIL_IF(!const_
);
3342 set_const(const_
, compiler
);
3344 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_REG2
;
3345 PTR_FAIL_IF(emit_const(compiler
, dst_r
, init_value
));
3347 if (dst
& SLJIT_MEM
)
3348 PTR_FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, DR(TMP_REG2
), dst
, dstw
));
3353 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_put_label
* sljit_emit_put_label(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
)
3355 struct sljit_put_label
*put_label
;
3359 CHECK_PTR(check_sljit_emit_put_label(compiler
, dst
, dstw
));
3360 ADJUST_LOCAL_OFFSET(dst
, dstw
);
3362 put_label
= (struct sljit_put_label
*)ensure_abuf(compiler
, sizeof(struct sljit_put_label
));
3363 PTR_FAIL_IF(!put_label
);
3364 set_put_label(put_label
, compiler
, 0);
3366 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_REG2
;
3367 PTR_FAIL_IF(push_inst(compiler
, (sljit_ins
)dst_r
, UNMOVABLE_INS
));
3368 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3369 compiler
->size
+= 1;
3371 compiler
->size
+= 5;
3374 if (dst
& SLJIT_MEM
)
3375 PTR_FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, DR(TMP_REG2
), dst
, dstw
));