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, 12, 10, 16
94 static const sljit_u8 freg_map
[SLJIT_NUMBER_OF_FLOAT_REGISTERS
+ 4] = {
95 0, 0, 13, 14, 15, 16, 17, 12, 18, 10
100 /* --------------------------------------------------------------------- */
101 /* Instrucion forms */
102 /* --------------------------------------------------------------------- */
104 #define S(s) (reg_map[s] << 21)
105 #define T(t) (reg_map[t] << 16)
106 #define D(d) (reg_map[d] << 11)
107 #define FT(t) (freg_map[t] << 16)
108 #define FS(s) (freg_map[s] << 11)
109 #define FD(d) (freg_map[d] << 6)
110 /* Absolute registers. */
111 #define SA(s) ((s) << 21)
112 #define TA(t) ((t) << 16)
113 #define DA(d) ((d) << 11)
114 #define IMM(imm) ((imm) & 0xffff)
115 #define SH_IMM(imm) ((imm) << 6)
117 #define DR(dr) (reg_map[dr])
118 #define FR(dr) (freg_map[dr])
119 #define HI(opcode) ((opcode) << 26)
120 #define LO(opcode) (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_UEQ_S (HI(17) | CMP_FMT_S | LO(3))
155 #define C_ULE_S (HI(17) | CMP_FMT_S | LO(7))
156 #define C_ULT_S (HI(17) | CMP_FMT_S | LO(5))
157 #define C_UN_S (HI(17) | CMP_FMT_S | LO(1))
158 #define C_FD (FD(TMP_FREG3))
159 #else /* SLJIT_MIPS_REV < 6 */
160 #define C_UEQ_S (HI(17) | FMT_S | LO(51))
161 #define C_ULE_S (HI(17) | FMT_S | LO(55))
162 #define C_ULT_S (HI(17) | FMT_S | LO(53))
163 #define C_UN_S (HI(17) | FMT_S | LO(49))
165 #endif /* SLJIT_MIPS_REV >= 6 */
166 #define CVT_S_S (HI(17) | FMT_S | LO(32))
167 #define DADDIU (HI(25))
168 #define DADDU (HI(0) | LO(45))
169 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
170 #define DDIV (HI(0) | (2 << 6) | LO(30))
171 #define DDIVU (HI(0) | (2 << 6) | LO(31))
172 #define DMOD (HI(0) | (3 << 6) | LO(30))
173 #define DMODU (HI(0) | (3 << 6) | LO(31))
174 #define DIV (HI(0) | (2 << 6) | LO(26))
175 #define DIVU (HI(0) | (2 << 6) | LO(27))
176 #define DMUH (HI(0) | (3 << 6) | LO(28))
177 #define DMUHU (HI(0) | (3 << 6) | LO(29))
178 #define DMUL (HI(0) | (2 << 6) | LO(28))
179 #define DMULU (HI(0) | (2 << 6) | LO(29))
180 #else /* SLJIT_MIPS_REV < 6 */
181 #define DDIV (HI(0) | LO(30))
182 #define DDIVU (HI(0) | LO(31))
183 #define DIV (HI(0) | LO(26))
184 #define DIVU (HI(0) | LO(27))
185 #define DMULT (HI(0) | LO(28))
186 #define DMULTU (HI(0) | LO(29))
187 #endif /* SLJIT_MIPS_REV >= 6 */
188 #define DIV_S (HI(17) | FMT_S | LO(3))
189 #define DINSU (HI(31) | LO(6))
190 #define DSLL (HI(0) | LO(56))
191 #define DSLL32 (HI(0) | LO(60))
192 #define DSLLV (HI(0) | LO(20))
193 #define DSRA (HI(0) | LO(59))
194 #define DSRA32 (HI(0) | LO(63))
195 #define DSRAV (HI(0) | LO(23))
196 #define DSRL (HI(0) | LO(58))
197 #define DSRL32 (HI(0) | LO(62))
198 #define DSRLV (HI(0) | LO(22))
199 #define DSUBU (HI(0) | LO(47))
202 #define JALR (HI(0) | LO(9))
203 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
204 #define JR (HI(0) | LO(9))
205 #else /* SLJIT_MIPS_REV < 6 */
206 #define JR (HI(0) | LO(8))
207 #endif /* SLJIT_MIPS_REV >= 6 */
209 #define LDC1 (HI(53))
212 #define LWC1 (HI(49))
213 #define MFC1 (HI(17))
214 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
215 #define MOD (HI(0) | (3 << 6) | LO(26))
216 #define MODU (HI(0) | (3 << 6) | LO(27))
217 #else /* SLJIT_MIPS_REV < 6 */
218 #define MFHI (HI(0) | LO(16))
219 #define MFLO (HI(0) | LO(18))
220 #endif /* SLJIT_MIPS_REV >= 6 */
221 #define MOV_S (HI(17) | FMT_S | LO(6))
222 #define MTC1 (HI(17) | (4 << 21))
223 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
224 #define MUH (HI(0) | (3 << 6) | LO(24))
225 #define MUHU (HI(0) | (3 << 6) | LO(25))
226 #define MUL (HI(0) | (2 << 6) | LO(24))
227 #define MULU (HI(0) | (2 << 6) | LO(25))
228 #else /* SLJIT_MIPS_REV < 6 */
229 #define MULT (HI(0) | LO(24))
230 #define MULTU (HI(0) | LO(25))
231 #endif /* SLJIT_MIPS_REV >= 6 */
232 #define MUL_S (HI(17) | FMT_S | LO(2))
233 #define NEG_S (HI(17) | FMT_S | LO(7))
234 #define NOP (HI(0) | LO(0))
235 #define NOR (HI(0) | LO(39))
236 #define OR (HI(0) | LO(37))
239 #define SDC1 (HI(61))
240 #define SLT (HI(0) | LO(42))
241 #define SLTI (HI(10))
242 #define SLTIU (HI(11))
243 #define SLTU (HI(0) | LO(43))
244 #define SLL (HI(0) | LO(0))
245 #define SLLV (HI(0) | LO(4))
246 #define SRL (HI(0) | LO(2))
247 #define SRLV (HI(0) | LO(6))
248 #define SRA (HI(0) | LO(3))
249 #define SRAV (HI(0) | LO(7))
250 #define SUB_S (HI(17) | FMT_S | LO(1))
251 #define SUBU (HI(0) | LO(35))
253 #define SWC1 (HI(57))
254 #define TRUNC_W_S (HI(17) | FMT_S | LO(13))
255 #define XOR (HI(0) | LO(38))
256 #define XORI (HI(14))
258 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
259 #define CLZ (HI(28) | LO(32))
260 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
261 #define DCLZ (LO(18))
262 #else /* SLJIT_MIPS_REV < 6 */
263 #define DCLZ (HI(28) | LO(36))
264 #define MOVF (HI(0) | (0 << 16) | LO(1))
265 #define MOVN (HI(0) | LO(11))
266 #define MOVT (HI(0) | (1 << 16) | LO(1))
267 #define MOVZ (HI(0) | LO(10))
268 #define MUL (HI(28) | LO(2))
269 #endif /* SLJIT_MIPS_REV >= 6 */
270 #define PREF (HI(51))
271 #define PREFX (HI(19) | LO(15))
272 #define SEB (HI(31) | (16 << 6) | LO(32))
273 #define SEH (HI(31) | (24 << 6) | LO(32))
274 #endif /* SLJIT_MIPS_REV >= 1 */
276 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
278 #define ADDIU_W ADDIU
283 #define ADDIU_W DADDIU
288 #define SIMM_MAX (0x7fff)
289 #define SIMM_MIN (-0x8000)
290 #define UIMM_MAX (0xffff)
292 /* dest_reg is the absolute name of the register
293 Useful for reordering instructions in the delay slot. */
294 static sljit_s32
push_inst(struct sljit_compiler
*compiler
, sljit_ins ins
, sljit_s32 delay_slot
)
296 sljit_ins
*ptr
= (sljit_ins
*)ensure_buf(compiler
, sizeof(sljit_ins
));
297 SLJIT_ASSERT(delay_slot
== MOVABLE_INS
|| delay_slot
>= UNMOVABLE_INS
298 || delay_slot
== ((ins
>> 11) & 0x1f) || delay_slot
== ((ins
>> 16) & 0x1f));
302 compiler
->delay_slot
= delay_slot
;
303 return SLJIT_SUCCESS
;
306 static SLJIT_INLINE sljit_ins
invert_branch(sljit_s32 flags
)
308 if (flags
& IS_BIT26_COND
)
310 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
311 if (flags
& IS_BIT23_COND
)
313 #endif /* SLJIT_MIPS_REV >= 6 */
317 static SLJIT_INLINE sljit_ins
* detect_jump_type(struct sljit_jump
*jump
, sljit_ins
*code_ptr
, sljit_ins
*code
, sljit_sw executable_offset
)
320 sljit_uw target_addr
;
322 sljit_ins saved_inst
;
324 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
325 if (jump
->flags
& (SLJIT_REWRITABLE_JUMP
| IS_CALL
))
328 if (jump
->flags
& SLJIT_REWRITABLE_JUMP
)
332 if (jump
->flags
& JUMP_ADDR
)
333 target_addr
= jump
->u
.target
;
335 SLJIT_ASSERT(jump
->flags
& JUMP_LABEL
);
336 target_addr
= (sljit_uw
)(code
+ jump
->u
.label
->size
) + (sljit_uw
)executable_offset
;
339 inst
= (sljit_ins
*)jump
->addr
;
340 if (jump
->flags
& IS_COND
)
343 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
344 if (jump
->flags
& IS_CALL
)
348 /* B instructions. */
349 if (jump
->flags
& IS_MOVABLE
) {
350 diff
= ((sljit_sw
)target_addr
- (sljit_sw
)inst
- executable_offset
) >> 2;
351 if (diff
<= SIMM_MAX
&& diff
>= SIMM_MIN
) {
352 jump
->flags
|= PATCH_B
;
354 if (!(jump
->flags
& IS_COND
)) {
356 inst
[-1] = (jump
->flags
& IS_JAL
) ? BAL
: B
;
357 jump
->addr
-= sizeof(sljit_ins
);
360 saved_inst
= inst
[0];
362 inst
[-1] = saved_inst
^ invert_branch(jump
->flags
);
363 jump
->addr
-= 2 * sizeof(sljit_ins
);
368 diff
= ((sljit_sw
)target_addr
- (sljit_sw
)(inst
+ 1) - executable_offset
) >> 2;
369 if (diff
<= SIMM_MAX
&& diff
>= SIMM_MIN
) {
370 jump
->flags
|= PATCH_B
;
372 if (!(jump
->flags
& IS_COND
)) {
373 inst
[0] = (jump
->flags
& IS_JAL
) ? BAL
: B
;
377 inst
[0] = inst
[0] ^ invert_branch(jump
->flags
);
379 jump
->addr
-= sizeof(sljit_ins
);
384 if (jump
->flags
& IS_COND
) {
385 if ((jump
->flags
& IS_MOVABLE
) && (target_addr
& ~0xfffffff) == ((jump
->addr
+ 2 * sizeof(sljit_ins
)) & ~0xfffffff)) {
386 jump
->flags
|= PATCH_J
;
387 saved_inst
= inst
[0];
389 inst
[-1] = (saved_inst
& 0xffff0000) | 3;
394 else if ((target_addr
& ~0xfffffff) == ((jump
->addr
+ 3 * sizeof(sljit_ins
)) & ~0xfffffff)) {
395 jump
->flags
|= PATCH_J
;
396 inst
[0] = (inst
[0] & 0xffff0000) | 3;
400 jump
->addr
+= sizeof(sljit_ins
);
406 if ((jump
->flags
& IS_MOVABLE
) && (target_addr
& ~0xfffffff) == (jump
->addr
& ~0xfffffff)) {
407 jump
->flags
|= PATCH_J
;
409 inst
[-1] = (jump
->flags
& IS_JAL
) ? JAL
: J
;
410 jump
->addr
-= sizeof(sljit_ins
);
414 if ((target_addr
& ~0xfffffff) == ((jump
->addr
+ sizeof(sljit_ins
)) & ~0xfffffff)) {
415 jump
->flags
|= PATCH_J
;
416 inst
[0] = (jump
->flags
& IS_JAL
) ? JAL
: J
;
422 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
424 if (target_addr
<= 0x7fffffff) {
425 jump
->flags
|= PATCH_ABS32
;
426 if (jump
->flags
& IS_COND
) {
434 if (target_addr
<= 0x7fffffffffffl
) {
435 jump
->flags
|= PATCH_ABS48
;
436 if (jump
->flags
& IS_COND
) {
450 static __attribute__ ((noinline
)) void sljit_cache_flush(void* code
, void* code_ptr
)
452 SLJIT_CACHE_FLUSH(code
, code_ptr
);
456 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
458 static SLJIT_INLINE sljit_sw
put_label_get_length(struct sljit_put_label
*put_label
, sljit_uw max_label
)
460 if (max_label
< 0x80000000l
) {
461 put_label
->flags
= 0;
465 if (max_label
< 0x800000000000l
) {
466 put_label
->flags
= 1;
470 put_label
->flags
= 2;
474 static SLJIT_INLINE
void put_label_set(struct sljit_put_label
*put_label
)
476 sljit_uw addr
= put_label
->label
->addr
;
477 sljit_ins
*inst
= (sljit_ins
*)put_label
->addr
;
478 sljit_s32 reg
= *inst
;
480 if (put_label
->flags
== 0) {
481 SLJIT_ASSERT(addr
< 0x80000000l
);
482 inst
[0] = LUI
| T(reg
) | IMM(addr
>> 16);
484 else if (put_label
->flags
== 1) {
485 SLJIT_ASSERT(addr
< 0x800000000000l
);
486 inst
[0] = LUI
| T(reg
) | IMM(addr
>> 32);
487 inst
[1] = ORI
| S(reg
) | T(reg
) | IMM((addr
>> 16) & 0xffff);
488 inst
[2] = DSLL
| T(reg
) | D(reg
) | SH_IMM(16);
492 inst
[0] = LUI
| T(reg
) | IMM(addr
>> 48);
493 inst
[1] = ORI
| S(reg
) | T(reg
) | IMM((addr
>> 32) & 0xffff);
494 inst
[2] = DSLL
| T(reg
) | D(reg
) | SH_IMM(16);
495 inst
[3] = ORI
| S(reg
) | T(reg
) | IMM((addr
>> 16) & 0xffff);
496 inst
[4] = DSLL
| T(reg
) | D(reg
) | SH_IMM(16);
500 inst
[1] = ORI
| S(reg
) | T(reg
) | IMM(addr
& 0xffff);
505 SLJIT_API_FUNC_ATTRIBUTE
void* sljit_generate_code(struct sljit_compiler
*compiler
)
507 struct sljit_memory_fragment
*buf
;
514 sljit_sw executable_offset
;
517 struct sljit_label
*label
;
518 struct sljit_jump
*jump
;
519 struct sljit_const
*const_
;
520 struct sljit_put_label
*put_label
;
523 CHECK_PTR(check_sljit_generate_code(compiler
));
524 reverse_buf(compiler
);
526 code
= (sljit_ins
*)SLJIT_MALLOC_EXEC(compiler
->size
* sizeof(sljit_ins
), compiler
->exec_allocator_data
);
527 PTR_FAIL_WITH_EXEC_IF(code
);
533 executable_offset
= SLJIT_EXEC_OFFSET(code
);
535 label
= compiler
->labels
;
536 jump
= compiler
->jumps
;
537 const_
= compiler
->consts
;
538 put_label
= compiler
->put_labels
;
541 buf_ptr
= (sljit_ins
*)buf
->memory
;
542 buf_end
= buf_ptr
+ (buf
->used_size
>> 2);
544 *code_ptr
= *buf_ptr
++;
545 if (next_addr
== word_count
) {
546 SLJIT_ASSERT(!label
|| label
->size
>= word_count
);
547 SLJIT_ASSERT(!jump
|| jump
->addr
>= word_count
);
548 SLJIT_ASSERT(!const_
|| const_
->addr
>= word_count
);
549 SLJIT_ASSERT(!put_label
|| put_label
->addr
>= word_count
);
551 /* These structures are ordered by their address. */
552 if (label
&& label
->size
== word_count
) {
553 label
->addr
= (sljit_uw
)SLJIT_ADD_EXEC_OFFSET(code_ptr
, executable_offset
);
554 label
->size
= code_ptr
- code
;
557 if (jump
&& jump
->addr
== word_count
) {
558 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
559 jump
->addr
= (sljit_uw
)(code_ptr
- 3);
561 jump
->addr
= (sljit_uw
)(code_ptr
- 7);
563 code_ptr
= detect_jump_type(jump
, code_ptr
, code
, executable_offset
);
566 if (const_
&& const_
->addr
== word_count
) {
567 const_
->addr
= (sljit_uw
)code_ptr
;
568 const_
= const_
->next
;
570 if (put_label
&& put_label
->addr
== word_count
) {
571 SLJIT_ASSERT(put_label
->label
);
572 put_label
->addr
= (sljit_uw
)code_ptr
;
573 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
574 code_ptr
+= put_label_get_length(put_label
, (sljit_uw
)(SLJIT_ADD_EXEC_OFFSET(code
, executable_offset
) + put_label
->label
->size
));
577 put_label
= put_label
->next
;
579 next_addr
= compute_next_addr(label
, jump
, const_
, put_label
);
583 } while (buf_ptr
< buf_end
);
588 if (label
&& label
->size
== word_count
) {
589 label
->addr
= (sljit_uw
)code_ptr
;
590 label
->size
= code_ptr
- code
;
594 SLJIT_ASSERT(!label
);
596 SLJIT_ASSERT(!const_
);
597 SLJIT_ASSERT(!put_label
);
598 SLJIT_ASSERT(code_ptr
- code
<= (sljit_sw
)compiler
->size
);
600 jump
= compiler
->jumps
;
603 addr
= (jump
->flags
& JUMP_LABEL
) ? jump
->u
.label
->addr
: jump
->u
.target
;
604 buf_ptr
= (sljit_ins
*)jump
->addr
;
606 if (jump
->flags
& PATCH_B
) {
607 addr
= (sljit_sw
)(addr
- ((sljit_uw
)SLJIT_ADD_EXEC_OFFSET(buf_ptr
, executable_offset
) + sizeof(sljit_ins
))) >> 2;
608 SLJIT_ASSERT((sljit_sw
)addr
<= SIMM_MAX
&& (sljit_sw
)addr
>= SIMM_MIN
);
609 buf_ptr
[0] = (buf_ptr
[0] & 0xffff0000) | (addr
& 0xffff);
612 if (jump
->flags
& PATCH_J
) {
613 SLJIT_ASSERT((addr
& ~0xfffffff) == (((sljit_uw
)SLJIT_ADD_EXEC_OFFSET(buf_ptr
, executable_offset
) + sizeof(sljit_ins
)) & ~0xfffffff));
614 buf_ptr
[0] |= (addr
>> 2) & 0x03ffffff;
618 /* Set the fields of immediate loads. */
619 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
620 buf_ptr
[0] = (buf_ptr
[0] & 0xffff0000) | ((addr
>> 16) & 0xffff);
621 buf_ptr
[1] = (buf_ptr
[1] & 0xffff0000) | (addr
& 0xffff);
623 if (jump
->flags
& PATCH_ABS32
) {
624 SLJIT_ASSERT(addr
<= 0x7fffffff);
625 buf_ptr
[0] = (buf_ptr
[0] & 0xffff0000) | ((addr
>> 16) & 0xffff);
626 buf_ptr
[1] = (buf_ptr
[1] & 0xffff0000) | (addr
& 0xffff);
628 else if (jump
->flags
& PATCH_ABS48
) {
629 SLJIT_ASSERT(addr
<= 0x7fffffffffffl
);
630 buf_ptr
[0] = (buf_ptr
[0] & 0xffff0000) | ((addr
>> 32) & 0xffff);
631 buf_ptr
[1] = (buf_ptr
[1] & 0xffff0000) | ((addr
>> 16) & 0xffff);
632 buf_ptr
[3] = (buf_ptr
[3] & 0xffff0000) | (addr
& 0xffff);
635 buf_ptr
[0] = (buf_ptr
[0] & 0xffff0000) | ((addr
>> 48) & 0xffff);
636 buf_ptr
[1] = (buf_ptr
[1] & 0xffff0000) | ((addr
>> 32) & 0xffff);
637 buf_ptr
[3] = (buf_ptr
[3] & 0xffff0000) | ((addr
>> 16) & 0xffff);
638 buf_ptr
[5] = (buf_ptr
[5] & 0xffff0000) | (addr
& 0xffff);
645 put_label
= compiler
->put_labels
;
647 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
648 addr
= put_label
->label
->addr
;
649 buf_ptr
= (sljit_ins
*)put_label
->addr
;
651 SLJIT_ASSERT((buf_ptr
[0] & 0xffe00000) == LUI
&& (buf_ptr
[1] & 0xfc000000) == ORI
);
652 buf_ptr
[0] |= (addr
>> 16) & 0xffff;
653 buf_ptr
[1] |= addr
& 0xffff;
655 put_label_set(put_label
);
657 put_label
= put_label
->next
;
660 compiler
->error
= SLJIT_ERR_COMPILED
;
661 compiler
->executable_offset
= executable_offset
;
662 compiler
->executable_size
= (code_ptr
- code
) * sizeof(sljit_ins
);
664 code
= (sljit_ins
*)SLJIT_ADD_EXEC_OFFSET(code
, executable_offset
);
665 code_ptr
= (sljit_ins
*)SLJIT_ADD_EXEC_OFFSET(code_ptr
, executable_offset
);
668 SLJIT_CACHE_FLUSH(code
, code_ptr
);
670 /* GCC workaround for invalid code generation with -O2. */
671 sljit_cache_flush(code
, code_ptr
);
673 SLJIT_UPDATE_WX_FLAGS(code
, code_ptr
, 1);
677 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_has_cpu_feature(sljit_s32 feature_type
)
681 switch (feature_type
) {
683 #ifdef SLJIT_IS_FPU_AVAILABLE
684 return SLJIT_IS_FPU_AVAILABLE
;
685 #elif defined(__GNUC__)
686 __asm__ ("cfc1 %0, $0" : "=r"(fir
));
687 return (fir
>> 22) & 0x1;
689 #error "FIR check is not implemented for this architecture"
691 case SLJIT_HAS_ZERO_REGISTER
:
694 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
697 case SLJIT_HAS_PREFETCH
:
699 #endif /* SLJIT_MIPS_REV >= 1 */
706 /* --------------------------------------------------------------------- */
708 /* --------------------------------------------------------------------- */
710 /* Creates an index in data_transfer_insts array. */
711 #define LOAD_DATA 0x01
712 #define WORD_DATA 0x00
713 #define BYTE_DATA 0x02
714 #define HALF_DATA 0x04
715 #define INT_DATA 0x06
716 #define SIGNED_DATA 0x08
717 /* Separates integer and floating point registers */
719 #define DOUBLE_DATA 0x10
720 #define SINGLE_DATA 0x12
722 #define MEM_MASK 0x1f
724 #define ARG_TEST 0x00020
725 #define ALT_KEEP_CACHE 0x00040
726 #define CUMULATIVE_OP 0x00080
727 #define LOGICAL_OP 0x00100
728 #define IMM_OP 0x00200
729 #define MOVE_OP 0x00400
730 #define SRC2_IMM 0x00800
732 #define UNUSED_DEST 0x01000
733 #define REG_DEST 0x02000
734 #define REG1_SOURCE 0x04000
735 #define REG2_SOURCE 0x08000
736 #define SLOW_SRC1 0x10000
737 #define SLOW_SRC2 0x20000
738 #define SLOW_DEST 0x40000
740 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
741 #define STACK_STORE SW
742 #define STACK_LOAD LW
744 #define STACK_STORE SD
745 #define STACK_LOAD LD
748 static SLJIT_INLINE sljit_s32
emit_op_mem(struct sljit_compiler
*compiler
, sljit_s32 flags
, sljit_s32 reg_ar
, sljit_s32 arg
, sljit_sw argw
);
750 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
751 #include "sljitNativeMIPS_32.c"
753 #include "sljitNativeMIPS_64.c"
756 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_enter(struct sljit_compiler
*compiler
,
757 sljit_s32 options
, sljit_s32 arg_types
, sljit_s32 scratches
, sljit_s32 saveds
,
758 sljit_s32 fscratches
, sljit_s32 fsaveds
, sljit_s32 local_size
)
761 sljit_s32 i
, tmp
, offs
;
762 sljit_s32 arg_count
, word_arg_count
, float_arg_count
;
765 CHECK(check_sljit_emit_enter(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
));
766 set_emit_enter(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
);
768 local_size
+= GET_SAVED_REGISTERS_SIZE(scratches
, saveds
, 1) + SLJIT_LOCALS_OFFSET
;
769 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
770 local_size
= (local_size
+ 15) & ~0xf;
772 local_size
= (local_size
+ 31) & ~0x1f;
774 compiler
->local_size
= local_size
;
776 if (local_size
<= -SIMM_MIN
) {
778 FAIL_IF(push_inst(compiler
, ADDIU_W
| S(SLJIT_SP
) | T(SLJIT_SP
) | IMM(-local_size
), DR(SLJIT_SP
)));
780 offs
= local_size
- (sljit_sw
)sizeof(sljit_sw
);
783 FAIL_IF(load_immediate(compiler
, DR(OTHER_FLAG
), local_size
));
784 FAIL_IF(push_inst(compiler
, ADDU_W
| S(SLJIT_SP
) | TA(0) | D(TMP_REG2
), DR(TMP_REG2
)));
785 FAIL_IF(push_inst(compiler
, SUBU_W
| S(SLJIT_SP
) | T(OTHER_FLAG
) | D(SLJIT_SP
), DR(SLJIT_SP
)));
788 offs
= -(sljit_sw
)sizeof(sljit_sw
);
791 FAIL_IF(push_inst(compiler
, STACK_STORE
| base
| TA(RETURN_ADDR_REG
) | IMM(offs
), MOVABLE_INS
));
793 tmp
= saveds
< SLJIT_NUMBER_OF_SAVED_REGISTERS
? (SLJIT_S0
+ 1 - saveds
) : SLJIT_FIRST_SAVED_REG
;
794 for (i
= SLJIT_S0
; i
>= tmp
; i
--) {
795 offs
-= (sljit_s32
)(sizeof(sljit_sw
));
796 FAIL_IF(push_inst(compiler
, STACK_STORE
| base
| T(i
) | IMM(offs
), MOVABLE_INS
));
799 for (i
= scratches
; i
>= SLJIT_FIRST_SAVED_REG
; i
--) {
800 offs
-= (sljit_s32
)(sizeof(sljit_sw
));
801 FAIL_IF(push_inst(compiler
, STACK_STORE
| base
| T(i
) | IMM(offs
), MOVABLE_INS
));
804 arg_types
>>= SLJIT_ARG_SHIFT
;
809 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
810 /* The first maximum two floating point arguments are passed in floating point
811 registers if no integer argument precedes them. The first 16 byte data is
812 passed in four integer registers, the rest is placed onto the stack.
813 The floating point registers are also part of the first 16 byte data, so
814 their corresponding integer registers are not used when they are present. */
817 switch (arg_types
& SLJIT_ARG_MASK
) {
818 case SLJIT_ARG_TYPE_F64
:
820 if ((arg_count
& 0x1) != 0)
823 if (word_arg_count
== 0 && float_arg_count
<= 2) {
824 if (float_arg_count
== 1)
825 FAIL_IF(push_inst(compiler
, MOV_S
| FMT_D
| FS(TMP_FREG1
) | FD(SLJIT_FR0
), MOVABLE_INS
));
826 } else if (arg_count
< 4) {
827 FAIL_IF(push_inst(compiler
, MTC1
| TA(4 + arg_count
) | FS(float_arg_count
), MOVABLE_INS
));
828 FAIL_IF(push_inst(compiler
, MTC1
| TA(5 + arg_count
) | FS(float_arg_count
) | (1 << 11), MOVABLE_INS
));
830 FAIL_IF(push_inst(compiler
, LDC1
| base
| FT(float_arg_count
) | IMM(local_size
+ (arg_count
<< 2)), MOVABLE_INS
));
833 case SLJIT_ARG_TYPE_F32
:
836 if (word_arg_count
== 0 && float_arg_count
<= 2) {
837 if (float_arg_count
== 1)
838 FAIL_IF(push_inst(compiler
, MOV_S
| FMT_S
| FS(TMP_FREG1
) | FD(SLJIT_FR0
), MOVABLE_INS
));
839 } else if (arg_count
< 4)
840 FAIL_IF(push_inst(compiler
, MTC1
| TA(4 + arg_count
) | FS(float_arg_count
), MOVABLE_INS
));
842 FAIL_IF(push_inst(compiler
, LWC1
| base
| FT(float_arg_count
) | IMM(local_size
+ (arg_count
<< 2)), MOVABLE_INS
));
846 FAIL_IF(push_inst(compiler
, ADDU_W
| SA(4 + arg_count
) | TA(0) | D(SLJIT_S0
- word_arg_count
),
847 DR(SLJIT_S0
- word_arg_count
)));
849 FAIL_IF(push_inst(compiler
, LW
| base
| T(SLJIT_S0
- word_arg_count
) | IMM(local_size
+ (arg_count
<< 2)),
850 DR(SLJIT_S0
- word_arg_count
)));
855 arg_types
>>= SLJIT_ARG_SHIFT
;
857 #else /* !SLJIT_CONFIG_MIPS_32 */
860 switch (arg_types
& SLJIT_ARG_MASK
) {
861 case SLJIT_ARG_TYPE_F64
:
863 if (arg_count
!= float_arg_count
)
864 FAIL_IF(push_inst(compiler
, MOV_S
| FMT_D
| FS(arg_count
) | FD(float_arg_count
), MOVABLE_INS
));
865 else if (arg_count
== 1)
866 FAIL_IF(push_inst(compiler
, MOV_S
| FMT_D
| FS(TMP_FREG1
) | FD(SLJIT_FR0
), MOVABLE_INS
));
868 case SLJIT_ARG_TYPE_F32
:
870 if (arg_count
!= float_arg_count
)
871 FAIL_IF(push_inst(compiler
, MOV_S
| FMT_S
| FS(arg_count
) | FD(float_arg_count
), MOVABLE_INS
));
872 else if (arg_count
== 1)
873 FAIL_IF(push_inst(compiler
, MOV_S
| FMT_S
| FS(TMP_FREG1
) | FD(SLJIT_FR0
), MOVABLE_INS
));
876 FAIL_IF(push_inst(compiler
, ADDU_W
| SA(3 + arg_count
) | TA(0) | D(SLJIT_S0
- word_arg_count
), DR(SLJIT_S0
- word_arg_count
)));
880 arg_types
>>= SLJIT_ARG_SHIFT
;
882 #endif /* SLJIT_CONFIG_MIPS_32 */
884 return SLJIT_SUCCESS
;
887 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_set_context(struct sljit_compiler
*compiler
,
888 sljit_s32 options
, sljit_s32 arg_types
, sljit_s32 scratches
, sljit_s32 saveds
,
889 sljit_s32 fscratches
, sljit_s32 fsaveds
, sljit_s32 local_size
)
892 CHECK(check_sljit_set_context(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
));
893 set_set_context(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
);
895 local_size
+= GET_SAVED_REGISTERS_SIZE(scratches
, saveds
, 1) + SLJIT_LOCALS_OFFSET
;
896 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
897 compiler
->local_size
= (local_size
+ 15) & ~0xf;
899 compiler
->local_size
= (local_size
+ 31) & ~0x1f;
901 return SLJIT_SUCCESS
;
904 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_return_void(struct sljit_compiler
*compiler
)
906 sljit_s32 local_size
, i
, tmp
, offs
;
910 CHECK(check_sljit_emit_return_void(compiler
));
912 local_size
= compiler
->local_size
;
913 if (local_size
<= SIMM_MAX
)
916 FAIL_IF(load_immediate(compiler
, DR(TMP_REG1
), local_size
));
917 FAIL_IF(push_inst(compiler
, ADDU_W
| S(SLJIT_SP
) | T(TMP_REG1
) | D(TMP_REG1
), DR(TMP_REG1
)));
922 FAIL_IF(push_inst(compiler
, STACK_LOAD
| base
| TA(RETURN_ADDR_REG
) | IMM(local_size
- (sljit_s32
)sizeof(sljit_sw
)), RETURN_ADDR_REG
));
923 offs
= local_size
- (sljit_s32
)GET_SAVED_REGISTERS_SIZE(compiler
->scratches
, compiler
->saveds
, 1);
925 tmp
= compiler
->scratches
;
926 for (i
= SLJIT_FIRST_SAVED_REG
; i
<= tmp
; i
++) {
927 FAIL_IF(push_inst(compiler
, STACK_LOAD
| base
| T(i
) | IMM(offs
), DR(i
)));
928 offs
+= (sljit_s32
)(sizeof(sljit_sw
));
931 tmp
= compiler
->saveds
< SLJIT_NUMBER_OF_SAVED_REGISTERS
? (SLJIT_S0
+ 1 - compiler
->saveds
) : SLJIT_FIRST_SAVED_REG
;
932 for (i
= tmp
; i
<= SLJIT_S0
; i
++) {
933 FAIL_IF(push_inst(compiler
, STACK_LOAD
| base
| T(i
) | IMM(offs
), DR(i
)));
934 offs
+= (sljit_s32
)(sizeof(sljit_sw
));
937 SLJIT_ASSERT(offs
== local_size
- (sljit_sw
)(sizeof(sljit_sw
)));
939 FAIL_IF(push_inst(compiler
, JR
| SA(RETURN_ADDR_REG
), UNMOVABLE_INS
));
940 if (compiler
->local_size
<= SIMM_MAX
)
941 return push_inst(compiler
, ADDIU_W
| S(SLJIT_SP
) | T(SLJIT_SP
) | IMM(compiler
->local_size
), UNMOVABLE_INS
);
943 return push_inst(compiler
, ADDU_W
| S(TMP_REG1
) | TA(0) | D(SLJIT_SP
), UNMOVABLE_INS
);
949 /* --------------------------------------------------------------------- */
951 /* --------------------------------------------------------------------- */
953 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
954 #define ARCH_32_64(a, b) a
956 #define ARCH_32_64(a, b) b
959 static const sljit_ins data_transfer_insts
[16 + 4] = {
960 /* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
961 /* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
962 /* u b s */ HI(40) /* sb */,
963 /* u b l */ HI(36) /* lbu */,
964 /* u h s */ HI(41) /* sh */,
965 /* u h l */ HI(37) /* lhu */,
966 /* u i s */ HI(43) /* sw */,
967 /* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */),
969 /* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
970 /* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
971 /* s b s */ HI(40) /* sb */,
972 /* s b l */ HI(32) /* lb */,
973 /* s h s */ HI(41) /* sh */,
974 /* s h l */ HI(33) /* lh */,
975 /* s i s */ HI(43) /* sw */,
976 /* s i l */ HI(35) /* lw */,
978 /* d s */ HI(61) /* sdc1 */,
979 /* d l */ HI(53) /* ldc1 */,
980 /* s s */ HI(57) /* swc1 */,
981 /* s l */ HI(49) /* lwc1 */,
986 /* reg_ar is an absoulute register! */
988 /* Can perform an operation using at most 1 instruction. */
989 static sljit_s32
getput_arg_fast(struct sljit_compiler
*compiler
, sljit_s32 flags
, sljit_s32 reg_ar
, sljit_s32 arg
, sljit_sw argw
)
991 SLJIT_ASSERT(arg
& SLJIT_MEM
);
993 if (!(arg
& OFFS_REG_MASK
) && argw
<= SIMM_MAX
&& argw
>= SIMM_MIN
) {
994 /* Works for both absoulte and relative addresses. */
995 if (SLJIT_UNLIKELY(flags
& ARG_TEST
))
997 FAIL_IF(push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | S(arg
& REG_MASK
)
998 | TA(reg_ar
) | IMM(argw
), ((flags
& MEM_MASK
) <= GPR_REG
&& (flags
& LOAD_DATA
)) ? reg_ar
: MOVABLE_INS
));
1004 /* See getput_arg below.
1005 Note: can_cache is called only for binary operators. Those
1006 operators always uses word arguments without write back. */
1007 static sljit_s32
can_cache(sljit_s32 arg
, sljit_sw argw
, sljit_s32 next_arg
, sljit_sw next_argw
)
1009 SLJIT_ASSERT((arg
& SLJIT_MEM
) && (next_arg
& SLJIT_MEM
));
1011 /* Simple operation except for updates. */
1012 if (arg
& OFFS_REG_MASK
) {
1015 if (argw
&& argw
== next_argw
&& (arg
== next_arg
|| (arg
& OFFS_REG_MASK
) == (next_arg
& OFFS_REG_MASK
)))
1020 if (arg
== next_arg
) {
1021 if (((next_argw
- argw
) <= SIMM_MAX
&& (next_argw
- argw
) >= SIMM_MIN
))
1029 /* Emit the necessary instructions. See can_cache above. */
1030 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
)
1032 sljit_s32 tmp_ar
, base
, delay_slot
;
1034 SLJIT_ASSERT(arg
& SLJIT_MEM
);
1035 if (!(next_arg
& SLJIT_MEM
)) {
1040 if ((flags
& MEM_MASK
) <= GPR_REG
&& (flags
& LOAD_DATA
)) {
1042 delay_slot
= reg_ar
;
1045 tmp_ar
= DR(TMP_REG1
);
1046 delay_slot
= MOVABLE_INS
;
1048 base
= arg
& REG_MASK
;
1050 if (SLJIT_UNLIKELY(arg
& OFFS_REG_MASK
)) {
1053 /* Using the cache. */
1054 if (argw
== compiler
->cache_argw
) {
1055 if (arg
== compiler
->cache_arg
)
1056 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | S(TMP_REG3
) | TA(reg_ar
), delay_slot
);
1058 if ((SLJIT_MEM
| (arg
& OFFS_REG_MASK
)) == compiler
->cache_arg
) {
1059 if (arg
== next_arg
&& argw
== (next_argw
& 0x3)) {
1060 compiler
->cache_arg
= arg
;
1061 compiler
->cache_argw
= argw
;
1062 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | T(TMP_REG3
) | D(TMP_REG3
), DR(TMP_REG3
)));
1063 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | S(TMP_REG3
) | TA(reg_ar
), delay_slot
);
1065 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | T(TMP_REG3
) | DA(tmp_ar
), tmp_ar
));
1066 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | SA(tmp_ar
) | TA(reg_ar
), delay_slot
);
1070 if (SLJIT_UNLIKELY(argw
)) {
1071 compiler
->cache_arg
= SLJIT_MEM
| (arg
& OFFS_REG_MASK
);
1072 compiler
->cache_argw
= argw
;
1073 FAIL_IF(push_inst(compiler
, SLL_W
| T(OFFS_REG(arg
)) | D(TMP_REG3
) | SH_IMM(argw
), DR(TMP_REG3
)));
1076 if (arg
== next_arg
&& argw
== (next_argw
& 0x3)) {
1077 compiler
->cache_arg
= arg
;
1078 compiler
->cache_argw
= argw
;
1079 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | T(!argw
? OFFS_REG(arg
) : TMP_REG3
) | D(TMP_REG3
), DR(TMP_REG3
)));
1080 tmp_ar
= DR(TMP_REG3
);
1083 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | T(!argw
? OFFS_REG(arg
) : TMP_REG3
) | DA(tmp_ar
), tmp_ar
));
1084 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | SA(tmp_ar
) | TA(reg_ar
), delay_slot
);
1087 if (compiler
->cache_arg
== arg
&& argw
- compiler
->cache_argw
<= SIMM_MAX
&& argw
- compiler
->cache_argw
>= SIMM_MIN
) {
1088 if (argw
!= compiler
->cache_argw
) {
1089 FAIL_IF(push_inst(compiler
, ADDIU_W
| S(TMP_REG3
) | T(TMP_REG3
) | IMM(argw
- compiler
->cache_argw
), DR(TMP_REG3
)));
1090 compiler
->cache_argw
= argw
;
1092 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | S(TMP_REG3
) | TA(reg_ar
), delay_slot
);
1095 if (compiler
->cache_arg
== SLJIT_MEM
&& argw
- compiler
->cache_argw
<= SIMM_MAX
&& argw
- compiler
->cache_argw
>= SIMM_MIN
) {
1096 if (argw
!= compiler
->cache_argw
)
1097 FAIL_IF(push_inst(compiler
, ADDIU_W
| S(TMP_REG3
) | T(TMP_REG3
) | IMM(argw
- compiler
->cache_argw
), DR(TMP_REG3
)));
1100 compiler
->cache_arg
= SLJIT_MEM
;
1101 FAIL_IF(load_immediate(compiler
, DR(TMP_REG3
), argw
));
1103 compiler
->cache_argw
= argw
;
1106 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | S(TMP_REG3
) | TA(reg_ar
), delay_slot
);
1108 if (arg
== next_arg
&& next_argw
- argw
<= SIMM_MAX
&& next_argw
- argw
>= SIMM_MIN
) {
1109 compiler
->cache_arg
= arg
;
1110 FAIL_IF(push_inst(compiler
, ADDU_W
| S(TMP_REG3
) | T(base
) | D(TMP_REG3
), DR(TMP_REG3
)));
1111 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | S(TMP_REG3
) | TA(reg_ar
), delay_slot
);
1114 FAIL_IF(push_inst(compiler
, ADDU_W
| S(TMP_REG3
) | T(base
) | DA(tmp_ar
), tmp_ar
));
1115 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | SA(tmp_ar
) | TA(reg_ar
), delay_slot
);
1118 static SLJIT_INLINE sljit_s32
emit_op_mem(struct sljit_compiler
*compiler
, sljit_s32 flags
, sljit_s32 reg_ar
, sljit_s32 arg
, sljit_sw argw
)
1120 sljit_s32 tmp_ar
, base
, delay_slot
;
1122 if (getput_arg_fast(compiler
, flags
, reg_ar
, arg
, argw
))
1123 return compiler
->error
;
1125 if ((flags
& MEM_MASK
) <= GPR_REG
&& (flags
& LOAD_DATA
)) {
1127 delay_slot
= reg_ar
;
1130 tmp_ar
= DR(TMP_REG1
);
1131 delay_slot
= MOVABLE_INS
;
1133 base
= arg
& REG_MASK
;
1135 if (SLJIT_UNLIKELY(arg
& OFFS_REG_MASK
)) {
1138 if (SLJIT_UNLIKELY(argw
)) {
1139 FAIL_IF(push_inst(compiler
, SLL_W
| T(OFFS_REG(arg
)) | DA(tmp_ar
) | SH_IMM(argw
), tmp_ar
));
1140 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | TA(tmp_ar
) | DA(tmp_ar
), tmp_ar
));
1143 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | T(OFFS_REG(arg
)) | DA(tmp_ar
), tmp_ar
));
1144 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | SA(tmp_ar
) | TA(reg_ar
), delay_slot
);
1147 FAIL_IF(load_immediate(compiler
, tmp_ar
, argw
));
1150 FAIL_IF(push_inst(compiler
, ADDU_W
| S(base
) | TA(tmp_ar
) | DA(tmp_ar
), tmp_ar
));
1152 return push_inst(compiler
, data_transfer_insts
[flags
& MEM_MASK
] | SA(tmp_ar
) | TA(reg_ar
), delay_slot
);
1155 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
)
1157 if (getput_arg_fast(compiler
, flags
, reg
, arg1
, arg1w
))
1158 return compiler
->error
;
1159 return getput_arg(compiler
, flags
, reg
, arg1
, arg1w
, arg2
, arg2w
);
1162 static sljit_s32
emit_op(struct sljit_compiler
*compiler
, sljit_s32 op
, sljit_s32 flags
,
1163 sljit_s32 dst
, sljit_sw dstw
,
1164 sljit_s32 src1
, sljit_sw src1w
,
1165 sljit_s32 src2
, sljit_sw src2w
)
1167 /* arg1 goes to TMP_REG1 or src reg
1168 arg2 goes to TMP_REG2, imm or src reg
1169 TMP_REG3 can be used for caching
1170 result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
1171 sljit_s32 dst_r
= TMP_REG2
;
1173 sljit_sw src2_r
= 0;
1174 sljit_s32 sugg_src2_r
= TMP_REG2
;
1176 if (!(flags
& ALT_KEEP_CACHE
)) {
1177 compiler
->cache_arg
= 0;
1178 compiler
->cache_argw
= 0;
1181 if (dst
== TMP_REG2
) {
1182 SLJIT_ASSERT(HAS_FLAGS(op
));
1183 flags
|= UNUSED_DEST
;
1185 else if (FAST_IS_REG(dst
)) {
1188 if (flags
& MOVE_OP
)
1189 sugg_src2_r
= dst_r
;
1191 else if ((dst
& SLJIT_MEM
) && !getput_arg_fast(compiler
, flags
| ARG_TEST
, DR(TMP_REG1
), dst
, dstw
))
1194 if (flags
& IMM_OP
) {
1195 if ((src2
& SLJIT_IMM
) && src2w
) {
1196 if ((!(flags
& LOGICAL_OP
) && (src2w
<= SIMM_MAX
&& src2w
>= SIMM_MIN
))
1197 || ((flags
& LOGICAL_OP
) && !(src2w
& ~UIMM_MAX
))) {
1202 if (!(flags
& SRC2_IMM
) && (flags
& CUMULATIVE_OP
) && (src1
& SLJIT_IMM
) && src1w
) {
1203 if ((!(flags
& LOGICAL_OP
) && (src1w
<= SIMM_MAX
&& src1w
>= SIMM_MIN
))
1204 || ((flags
& LOGICAL_OP
) && !(src1w
& ~UIMM_MAX
))) {
1208 /* And swap arguments. */
1212 /* src2w = src2_r unneeded. */
1218 if (FAST_IS_REG(src1
)) {
1220 flags
|= REG1_SOURCE
;
1222 else if (src1
& SLJIT_IMM
) {
1224 FAIL_IF(load_immediate(compiler
, DR(TMP_REG1
), src1w
));
1231 if (getput_arg_fast(compiler
, flags
| LOAD_DATA
, DR(TMP_REG1
), src1
, src1w
))
1232 FAIL_IF(compiler
->error
);
1239 if (FAST_IS_REG(src2
)) {
1241 flags
|= REG2_SOURCE
;
1242 if ((flags
& (REG_DEST
| MOVE_OP
)) == MOVE_OP
)
1245 else if (src2
& SLJIT_IMM
) {
1246 if (!(flags
& SRC2_IMM
)) {
1248 FAIL_IF(load_immediate(compiler
, DR(sugg_src2_r
), src2w
));
1249 src2_r
= sugg_src2_r
;
1253 if (flags
& MOVE_OP
) {
1254 if (dst
& SLJIT_MEM
)
1263 if (getput_arg_fast(compiler
, flags
| LOAD_DATA
, DR(sugg_src2_r
), src2
, src2w
))
1264 FAIL_IF(compiler
->error
);
1267 src2_r
= sugg_src2_r
;
1270 if ((flags
& (SLOW_SRC1
| SLOW_SRC2
)) == (SLOW_SRC1
| SLOW_SRC2
)) {
1271 SLJIT_ASSERT(src2_r
== TMP_REG2
);
1272 if (!can_cache(src1
, src1w
, src2
, src2w
) && can_cache(src1
, src1w
, dst
, dstw
)) {
1273 FAIL_IF(getput_arg(compiler
, flags
| LOAD_DATA
, DR(TMP_REG2
), src2
, src2w
, src1
, src1w
));
1274 FAIL_IF(getput_arg(compiler
, flags
| LOAD_DATA
, DR(TMP_REG1
), src1
, src1w
, dst
, dstw
));
1277 FAIL_IF(getput_arg(compiler
, flags
| LOAD_DATA
, DR(TMP_REG1
), src1
, src1w
, src2
, src2w
));
1278 FAIL_IF(getput_arg(compiler
, flags
| LOAD_DATA
, DR(TMP_REG2
), src2
, src2w
, dst
, dstw
));
1281 else if (flags
& SLOW_SRC1
)
1282 FAIL_IF(getput_arg(compiler
, flags
| LOAD_DATA
, DR(TMP_REG1
), src1
, src1w
, dst
, dstw
));
1283 else if (flags
& SLOW_SRC2
)
1284 FAIL_IF(getput_arg(compiler
, flags
| LOAD_DATA
, DR(sugg_src2_r
), src2
, src2w
, dst
, dstw
));
1286 FAIL_IF(emit_single_op(compiler
, op
, flags
, dst_r
, src1_r
, src2_r
));
1288 if (dst
& SLJIT_MEM
) {
1289 if (!(flags
& SLOW_DEST
)) {
1290 getput_arg_fast(compiler
, flags
, DR(dst_r
), dst
, dstw
);
1291 return compiler
->error
;
1293 return getput_arg(compiler
, flags
, DR(dst_r
), dst
, dstw
, 0, 0);
1296 return SLJIT_SUCCESS
;
1299 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op0(struct sljit_compiler
*compiler
, sljit_s32 op
)
1301 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1302 sljit_s32 int_op
= op
& SLJIT_32
;
1306 CHECK(check_sljit_emit_op0(compiler
, op
));
1308 op
= GET_OPCODE(op
);
1310 case SLJIT_BREAKPOINT
:
1311 return push_inst(compiler
, BREAK
, UNMOVABLE_INS
);
1313 return push_inst(compiler
, NOP
, UNMOVABLE_INS
);
1316 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1317 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1318 FAIL_IF(push_inst(compiler
, (op
== SLJIT_LMUL_UW
? DMULU
: DMUL
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG3
), DR(TMP_REG3
)));
1319 FAIL_IF(push_inst(compiler
, (op
== SLJIT_LMUL_UW
? DMUHU
: DMUH
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG1
), DR(TMP_REG1
)));
1320 #else /* !SLJIT_CONFIG_MIPS_64 */
1321 FAIL_IF(push_inst(compiler
, (op
== SLJIT_LMUL_UW
? MULU
: MUL
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG3
), DR(TMP_REG3
)));
1322 FAIL_IF(push_inst(compiler
, (op
== SLJIT_LMUL_UW
? MUHU
: MUH
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG1
), DR(TMP_REG1
)));
1323 #endif /* SLJIT_CONFIG_MIPS_64 */
1324 FAIL_IF(push_inst(compiler
, ADDU_W
| S(TMP_REG3
) | TA(0) | D(SLJIT_R0
), DR(SLJIT_R0
)));
1325 return push_inst(compiler
, ADDU_W
| S(TMP_REG1
) | TA(0) | D(SLJIT_R1
), DR(SLJIT_R1
));
1326 #else /* SLJIT_MIPS_REV < 6 */
1327 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1328 FAIL_IF(push_inst(compiler
, (op
== SLJIT_LMUL_UW
? DMULTU
: DMULT
) | S(SLJIT_R0
) | T(SLJIT_R1
), MOVABLE_INS
));
1329 #else /* !SLJIT_CONFIG_MIPS_64 */
1330 FAIL_IF(push_inst(compiler
, (op
== SLJIT_LMUL_UW
? MULTU
: MULT
) | S(SLJIT_R0
) | T(SLJIT_R1
), MOVABLE_INS
));
1331 #endif /* SLJIT_CONFIG_MIPS_64 */
1332 FAIL_IF(push_inst(compiler
, MFLO
| D(SLJIT_R0
), DR(SLJIT_R0
)));
1333 return push_inst(compiler
, MFHI
| D(SLJIT_R1
), DR(SLJIT_R1
));
1334 #endif /* SLJIT_MIPS_REV >= 6 */
1335 case SLJIT_DIVMOD_UW
:
1336 case SLJIT_DIVMOD_SW
:
1339 SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW
& 0x2) == 0 && SLJIT_DIV_UW
- 0x2 == SLJIT_DIVMOD_UW
, bad_div_opcode_assignments
);
1340 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1341 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1343 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DIVU
: DIV
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG3
), DR(TMP_REG3
)));
1344 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? MODU
: MOD
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG1
), DR(TMP_REG1
)));
1347 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DDIVU
: DDIV
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG3
), DR(TMP_REG3
)));
1348 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DMODU
: DMOD
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG1
), DR(TMP_REG1
)));
1350 #else /* !SLJIT_CONFIG_MIPS_64 */
1351 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DIVU
: DIV
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG3
), DR(TMP_REG3
)));
1352 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? MODU
: MOD
) | S(SLJIT_R0
) | T(SLJIT_R1
) | D(TMP_REG1
), DR(TMP_REG1
)));
1353 #endif /* SLJIT_CONFIG_MIPS_64 */
1354 FAIL_IF(push_inst(compiler
, ADDU_W
| S(TMP_REG3
) | TA(0) | D(SLJIT_R0
), DR(SLJIT_R0
)));
1355 return (op
>= SLJIT_DIV_UW
) ? SLJIT_SUCCESS
: push_inst(compiler
, ADDU_W
| S(TMP_REG1
) | TA(0) | D(SLJIT_R1
), DR(SLJIT_R1
));
1356 #else /* SLJIT_MIPS_REV < 6 */
1357 #if !(defined SLJIT_MIPS_REV)
1358 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
1359 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
1360 #endif /* !SLJIT_MIPS_REV */
1361 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1363 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DIVU
: DIV
) | S(SLJIT_R0
) | T(SLJIT_R1
), MOVABLE_INS
));
1365 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DDIVU
: DDIV
) | S(SLJIT_R0
) | T(SLJIT_R1
), MOVABLE_INS
));
1366 #else /* !SLJIT_CONFIG_MIPS_64 */
1367 FAIL_IF(push_inst(compiler
, ((op
| 0x2) == SLJIT_DIV_UW
? DIVU
: DIV
) | S(SLJIT_R0
) | T(SLJIT_R1
), MOVABLE_INS
));
1368 #endif /* SLJIT_CONFIG_MIPS_64 */
1369 FAIL_IF(push_inst(compiler
, MFLO
| D(SLJIT_R0
), DR(SLJIT_R0
)));
1370 return (op
>= SLJIT_DIV_UW
) ? SLJIT_SUCCESS
: push_inst(compiler
, MFHI
| D(SLJIT_R1
), DR(SLJIT_R1
));
1371 #endif /* SLJIT_MIPS_REV >= 6 */
1373 case SLJIT_SKIP_FRAMES_BEFORE_RETURN
:
1374 return SLJIT_SUCCESS
;
1377 return SLJIT_SUCCESS
;
1380 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1381 static sljit_s32
emit_prefetch(struct sljit_compiler
*compiler
,
1382 sljit_s32 src
, sljit_sw srcw
)
1384 if (!(src
& OFFS_REG_MASK
)) {
1385 if (srcw
<= SIMM_MAX
&& srcw
>= SIMM_MIN
)
1386 return push_inst(compiler
, PREF
| S(src
& REG_MASK
) | IMM(srcw
), MOVABLE_INS
);
1388 FAIL_IF(load_immediate(compiler
, DR(TMP_REG1
), srcw
));
1389 return push_inst(compiler
, PREFX
| S(src
& REG_MASK
) | T(TMP_REG1
), MOVABLE_INS
);
1394 if (SLJIT_UNLIKELY(srcw
!= 0)) {
1395 FAIL_IF(push_inst(compiler
, SLL_W
| T(OFFS_REG(src
)) | D(TMP_REG1
) | SH_IMM(srcw
), DR(TMP_REG1
)));
1396 return push_inst(compiler
, PREFX
| S(src
& REG_MASK
) | T(TMP_REG1
), MOVABLE_INS
);
1399 return push_inst(compiler
, PREFX
| S(src
& REG_MASK
) | T(OFFS_REG(src
)), MOVABLE_INS
);
1401 #endif /* SLJIT_MIPS_REV >= 1 */
1403 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op1(struct sljit_compiler
*compiler
, sljit_s32 op
,
1404 sljit_s32 dst
, sljit_sw dstw
,
1405 sljit_s32 src
, sljit_sw srcw
)
1407 sljit_s32 flags
= 0;
1410 CHECK(check_sljit_emit_op1(compiler
, op
, dst
, dstw
, src
, srcw
));
1411 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1412 ADJUST_LOCAL_OFFSET(src
, srcw
);
1414 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1416 flags
= INT_DATA
| SIGNED_DATA
;
1419 switch (GET_OPCODE(op
)) {
1421 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1427 return emit_op(compiler
, SLJIT_MOV
, WORD_DATA
| MOVE_OP
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1429 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1431 return emit_op(compiler
, SLJIT_MOV_U32
, INT_DATA
| MOVE_OP
, dst
, dstw
, TMP_REG1
, 0, src
, (src
& SLJIT_IMM
) ? (sljit_u32
)srcw
: srcw
);
1435 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
);
1439 return emit_op(compiler
, op
, BYTE_DATA
| MOVE_OP
, dst
, dstw
, TMP_REG1
, 0, src
, (src
& SLJIT_IMM
) ? (sljit_u8
)srcw
: srcw
);
1442 return emit_op(compiler
, op
, BYTE_DATA
| SIGNED_DATA
| MOVE_OP
, dst
, dstw
, TMP_REG1
, 0, src
, (src
& SLJIT_IMM
) ? (sljit_s8
)srcw
: srcw
);
1445 return emit_op(compiler
, op
, HALF_DATA
| MOVE_OP
, dst
, dstw
, TMP_REG1
, 0, src
, (src
& SLJIT_IMM
) ? (sljit_u16
)srcw
: srcw
);
1448 return emit_op(compiler
, op
, HALF_DATA
| SIGNED_DATA
| MOVE_OP
, dst
, dstw
, TMP_REG1
, 0, src
, (src
& SLJIT_IMM
) ? (sljit_s16
)srcw
: srcw
);
1451 return emit_op(compiler
, op
, flags
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1454 compiler
->status_flags_state
= SLJIT_CURRENT_FLAGS_ADD_SUB
;
1455 return emit_op(compiler
, SLJIT_SUB
| GET_ALL_FLAGS(op
), flags
| IMM_OP
, dst
, dstw
, SLJIT_IMM
, 0, src
, srcw
);
1458 return emit_op(compiler
, op
, flags
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1461 SLJIT_UNREACHABLE();
1462 return SLJIT_SUCCESS
;
1465 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op2(struct sljit_compiler
*compiler
, sljit_s32 op
,
1466 sljit_s32 dst
, sljit_sw dstw
,
1467 sljit_s32 src1
, sljit_sw src1w
,
1468 sljit_s32 src2
, sljit_sw src2w
)
1470 sljit_s32 flags
= 0;
1473 CHECK(check_sljit_emit_op2(compiler
, op
, 0, dst
, dstw
, src1
, src1w
, src2
, src2w
));
1474 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1475 ADJUST_LOCAL_OFFSET(src1
, src1w
);
1476 ADJUST_LOCAL_OFFSET(src2
, src2w
);
1478 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1479 if (op
& SLJIT_32
) {
1480 flags
|= INT_DATA
| SIGNED_DATA
;
1481 if (src1
& SLJIT_IMM
)
1482 src1w
= (sljit_s32
)src1w
;
1483 if (src2
& SLJIT_IMM
)
1484 src2w
= (sljit_s32
)src2w
;
1488 switch (GET_OPCODE(op
)) {
1491 compiler
->status_flags_state
= SLJIT_CURRENT_FLAGS_ADD_SUB
;
1492 return emit_op(compiler
, op
, flags
| CUMULATIVE_OP
| IMM_OP
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1496 compiler
->status_flags_state
= SLJIT_CURRENT_FLAGS_ADD_SUB
;
1497 return emit_op(compiler
, op
, flags
| IMM_OP
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1500 compiler
->status_flags_state
= 0;
1501 return emit_op(compiler
, op
, flags
| CUMULATIVE_OP
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1506 return emit_op(compiler
, op
, flags
| CUMULATIVE_OP
| LOGICAL_OP
| IMM_OP
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1511 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1512 if (src2
& SLJIT_IMM
)
1515 if (src2
& SLJIT_IMM
) {
1522 return emit_op(compiler
, op
, flags
| IMM_OP
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1525 SLJIT_UNREACHABLE();
1526 return SLJIT_SUCCESS
;
1529 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op2u(struct sljit_compiler
*compiler
, sljit_s32 op
,
1530 sljit_s32 src1
, sljit_sw src1w
,
1531 sljit_s32 src2
, sljit_sw src2w
)
1534 CHECK(check_sljit_emit_op2(compiler
, op
, 1, 0, 0, src1
, src1w
, src2
, src2w
));
1536 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
1537 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1538 compiler
->skip_checks
= 1;
1540 return sljit_emit_op2(compiler
, op
, TMP_REG2
, 0, src1
, src1w
, src2
, src2w
);
1543 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_src(struct sljit_compiler
*compiler
, sljit_s32 op
,
1544 sljit_s32 src
, sljit_sw srcw
)
1547 CHECK(check_sljit_emit_op_src(compiler
, op
, src
, srcw
));
1548 ADJUST_LOCAL_OFFSET(src
, srcw
);
1551 case SLJIT_FAST_RETURN
:
1552 if (FAST_IS_REG(src
))
1553 FAIL_IF(push_inst(compiler
, ADDU_W
| S(src
) | TA(0) | DA(RETURN_ADDR_REG
), RETURN_ADDR_REG
));
1555 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
| LOAD_DATA
, RETURN_ADDR_REG
, src
, srcw
));
1557 FAIL_IF(push_inst(compiler
, JR
| SA(RETURN_ADDR_REG
), UNMOVABLE_INS
));
1558 return push_inst(compiler
, NOP
, UNMOVABLE_INS
);
1559 case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN
:
1560 return SLJIT_SUCCESS
;
1561 case SLJIT_PREFETCH_L1
:
1562 case SLJIT_PREFETCH_L2
:
1563 case SLJIT_PREFETCH_L3
:
1564 case SLJIT_PREFETCH_ONCE
:
1565 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1566 return emit_prefetch(compiler
, src
, srcw
);
1567 #else /* SLJIT_MIPS_REV < 1 */
1568 return SLJIT_SUCCESS
;
1569 #endif /* SLJIT_MIPS_REV >= 1 */
1572 return SLJIT_SUCCESS
;
1575 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_get_register_index(sljit_s32 reg
)
1577 CHECK_REG_INDEX(check_sljit_get_register_index(reg
));
1578 return reg_map
[reg
];
1581 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_get_float_register_index(sljit_s32 reg
)
1583 CHECK_REG_INDEX(check_sljit_get_float_register_index(reg
));
1587 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_custom(struct sljit_compiler
*compiler
,
1588 void *instruction
, sljit_s32 size
)
1591 CHECK(check_sljit_emit_op_custom(compiler
, instruction
, size
));
1593 return push_inst(compiler
, *(sljit_ins
*)instruction
, UNMOVABLE_INS
);
1596 /* --------------------------------------------------------------------- */
1597 /* Floating point operators */
1598 /* --------------------------------------------------------------------- */
1600 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7))
1601 #define FMT(op) (((op & SLJIT_32) ^ SLJIT_32) << (21 - 8))
1603 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler
*compiler
, sljit_s32 op
,
1604 sljit_s32 dst
, sljit_sw dstw
,
1605 sljit_s32 src
, sljit_sw srcw
)
1607 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1610 sljit_s32 flags
= (GET_OPCODE(op
) == SLJIT_CONV_SW_FROM_F64
) << 21;
1613 if (src
& SLJIT_MEM
) {
1614 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG1
), src
, srcw
, dst
, dstw
));
1618 FAIL_IF(push_inst(compiler
, (TRUNC_W_S
^ (flags
>> 19)) | FMT(op
) | FS(src
) | FD(TMP_FREG1
), MOVABLE_INS
));
1620 if (FAST_IS_REG(dst
))
1621 return push_inst(compiler
, MFC1
| flags
| T(dst
) | FS(TMP_FREG1
), MOVABLE_INS
);
1623 /* Store the integer value from a VFP register. */
1624 return emit_op_mem2(compiler
, flags
? DOUBLE_DATA
: SINGLE_DATA
, FR(TMP_FREG1
), dst
, dstw
, 0, 0);
1626 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1631 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler
*compiler
, sljit_s32 op
,
1632 sljit_s32 dst
, sljit_sw dstw
,
1633 sljit_s32 src
, sljit_sw srcw
)
1635 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1638 sljit_s32 flags
= (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_SW
) << 21;
1641 sljit_s32 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG1
;
1643 if (FAST_IS_REG(src
))
1644 FAIL_IF(push_inst(compiler
, MTC1
| flags
| T(src
) | FS(TMP_FREG1
), MOVABLE_INS
));
1645 else if (src
& SLJIT_MEM
) {
1646 /* Load the integer value into a VFP register. */
1647 FAIL_IF(emit_op_mem2(compiler
, ((flags
) ? DOUBLE_DATA
: SINGLE_DATA
) | LOAD_DATA
, FR(TMP_FREG1
), src
, srcw
, dst
, dstw
));
1650 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1651 if (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_S32
)
1652 srcw
= (sljit_s32
)srcw
;
1654 FAIL_IF(load_immediate(compiler
, DR(TMP_REG1
), srcw
));
1655 FAIL_IF(push_inst(compiler
, MTC1
| flags
| T(TMP_REG1
) | FS(TMP_FREG1
), MOVABLE_INS
));
1658 FAIL_IF(push_inst(compiler
, CVT_S_S
| flags
| (4 << 21) | (((op
& SLJIT_32
) ^ SLJIT_32
) >> 8) | FS(TMP_FREG1
) | FD(dst_r
), MOVABLE_INS
));
1660 if (dst
& SLJIT_MEM
)
1661 return emit_op_mem2(compiler
, FLOAT_DATA(op
), FR(TMP_FREG1
), dst
, dstw
, 0, 0);
1662 return SLJIT_SUCCESS
;
1664 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1669 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_cmp(struct sljit_compiler
*compiler
, sljit_s32 op
,
1670 sljit_s32 src1
, sljit_sw src1w
,
1671 sljit_s32 src2
, sljit_sw src2w
)
1675 if (src1
& SLJIT_MEM
) {
1676 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG1
), src1
, src1w
, src2
, src2w
));
1680 if (src2
& SLJIT_MEM
) {
1681 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG2
), src2
, src2w
, 0, 0));
1685 switch (GET_FLAG_TYPE(op
)) {
1686 case SLJIT_EQUAL_F64
:
1687 case SLJIT_NOT_EQUAL_F64
:
1690 case SLJIT_LESS_F64
:
1691 case SLJIT_GREATER_EQUAL_F64
:
1694 case SLJIT_GREATER_F64
:
1695 case SLJIT_LESS_EQUAL_F64
:
1699 SLJIT_ASSERT(GET_FLAG_TYPE(op
) == SLJIT_UNORDERED_F64
|| GET_FLAG_TYPE(op
) == SLJIT_ORDERED_F64
);
1703 return push_inst(compiler
, inst
| FMT(op
) | FT(src2
) | FS(src1
) | C_FD
, UNMOVABLE_INS
);
1706 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fop1(struct sljit_compiler
*compiler
, sljit_s32 op
,
1707 sljit_s32 dst
, sljit_sw dstw
,
1708 sljit_s32 src
, sljit_sw srcw
)
1713 compiler
->cache_arg
= 0;
1714 compiler
->cache_argw
= 0;
1716 SLJIT_COMPILE_ASSERT((SLJIT_32
== 0x100) && !(DOUBLE_DATA
& 0x2), float_transfer_bit_error
);
1717 SELECT_FOP1_OPERATION_WITH_CHECKS(compiler
, op
, dst
, dstw
, src
, srcw
);
1719 if (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_F32
)
1722 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG1
;
1724 if (src
& SLJIT_MEM
) {
1725 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(dst_r
), src
, srcw
, dst
, dstw
));
1729 switch (GET_OPCODE(op
)) {
1732 if (dst_r
!= TMP_FREG1
)
1733 FAIL_IF(push_inst(compiler
, MOV_S
| FMT(op
) | FS(src
) | FD(dst_r
), MOVABLE_INS
));
1739 FAIL_IF(push_inst(compiler
, NEG_S
| FMT(op
) | FS(src
) | FD(dst_r
), MOVABLE_INS
));
1742 FAIL_IF(push_inst(compiler
, ABS_S
| FMT(op
) | FS(src
) | FD(dst_r
), MOVABLE_INS
));
1744 case SLJIT_CONV_F64_FROM_F32
:
1745 FAIL_IF(push_inst(compiler
, CVT_S_S
| ((op
& SLJIT_32
) ? 1 : (1 << 21)) | FS(src
) | FD(dst_r
), MOVABLE_INS
));
1750 if (dst
& SLJIT_MEM
)
1751 return emit_op_mem2(compiler
, FLOAT_DATA(op
), FR(dst_r
), dst
, dstw
, 0, 0);
1752 return SLJIT_SUCCESS
;
1755 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fop2(struct sljit_compiler
*compiler
, sljit_s32 op
,
1756 sljit_s32 dst
, sljit_sw dstw
,
1757 sljit_s32 src1
, sljit_sw src1w
,
1758 sljit_s32 src2
, sljit_sw src2w
)
1760 sljit_s32 dst_r
, flags
= 0;
1763 CHECK(check_sljit_emit_fop2(compiler
, op
, dst
, dstw
, src1
, src1w
, src2
, src2w
));
1764 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1765 ADJUST_LOCAL_OFFSET(src1
, src1w
);
1766 ADJUST_LOCAL_OFFSET(src2
, src2w
);
1768 compiler
->cache_arg
= 0;
1769 compiler
->cache_argw
= 0;
1771 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG2
;
1773 if (src1
& SLJIT_MEM
) {
1774 if (getput_arg_fast(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG1
), src1
, src1w
)) {
1775 FAIL_IF(compiler
->error
);
1781 if (src2
& SLJIT_MEM
) {
1782 if (getput_arg_fast(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG2
), src2
, src2w
)) {
1783 FAIL_IF(compiler
->error
);
1789 if ((flags
& (SLOW_SRC1
| SLOW_SRC2
)) == (SLOW_SRC1
| SLOW_SRC2
)) {
1790 if (!can_cache(src1
, src1w
, src2
, src2w
) && can_cache(src1
, src1w
, dst
, dstw
)) {
1791 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG2
), src2
, src2w
, src1
, src1w
));
1792 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG1
), src1
, src1w
, dst
, dstw
));
1795 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG1
), src1
, src1w
, src2
, src2w
));
1796 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG2
), src2
, src2w
, dst
, dstw
));
1799 else if (flags
& SLOW_SRC1
)
1800 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG1
), src1
, src1w
, dst
, dstw
));
1801 else if (flags
& SLOW_SRC2
)
1802 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, FR(TMP_FREG2
), src2
, src2w
, dst
, dstw
));
1804 if (flags
& SLOW_SRC1
)
1806 if (flags
& SLOW_SRC2
)
1809 switch (GET_OPCODE(op
)) {
1811 FAIL_IF(push_inst(compiler
, ADD_S
| FMT(op
) | FT(src2
) | FS(src1
) | FD(dst_r
), MOVABLE_INS
));
1815 FAIL_IF(push_inst(compiler
, SUB_S
| FMT(op
) | FT(src2
) | FS(src1
) | FD(dst_r
), MOVABLE_INS
));
1819 FAIL_IF(push_inst(compiler
, MUL_S
| FMT(op
) | FT(src2
) | FS(src1
) | FD(dst_r
), MOVABLE_INS
));
1823 FAIL_IF(push_inst(compiler
, DIV_S
| FMT(op
) | FT(src2
) | FS(src1
) | FD(dst_r
), MOVABLE_INS
));
1827 if (dst_r
== TMP_FREG2
)
1828 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
), FR(TMP_FREG2
), dst
, dstw
, 0, 0));
1830 return SLJIT_SUCCESS
;
1833 /* --------------------------------------------------------------------- */
1834 /* Other instructions */
1835 /* --------------------------------------------------------------------- */
1837 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fast_enter(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
)
1840 CHECK(check_sljit_emit_fast_enter(compiler
, dst
, dstw
));
1841 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1843 if (FAST_IS_REG(dst
))
1844 return push_inst(compiler
, ADDU_W
| SA(RETURN_ADDR_REG
) | TA(0) | D(dst
), UNMOVABLE_INS
);
1847 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, RETURN_ADDR_REG
, dst
, dstw
));
1848 compiler
->delay_slot
= UNMOVABLE_INS
;
1849 return SLJIT_SUCCESS
;
1852 /* --------------------------------------------------------------------- */
1853 /* Conditional instructions */
1854 /* --------------------------------------------------------------------- */
1856 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_label
* sljit_emit_label(struct sljit_compiler
*compiler
)
1858 struct sljit_label
*label
;
1861 CHECK_PTR(check_sljit_emit_label(compiler
));
1863 if (compiler
->last_label
&& compiler
->last_label
->size
== compiler
->size
)
1864 return compiler
->last_label
;
1866 label
= (struct sljit_label
*)ensure_abuf(compiler
, sizeof(struct sljit_label
));
1867 PTR_FAIL_IF(!label
);
1868 set_label(label
, compiler
);
1869 compiler
->delay_slot
= UNMOVABLE_INS
;
1873 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1874 #define JUMP_LENGTH 4
1876 #define JUMP_LENGTH 8
1880 inst = BEQ | SA(src) | TA(0) | JUMP_LENGTH; \
1881 flags = IS_BIT26_COND; \
1884 #define BR_NZ(src) \
1885 inst = BNE | SA(src) | TA(0) | JUMP_LENGTH; \
1886 flags = IS_BIT26_COND; \
1889 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1893 flags = IS_BIT23_COND; \
1894 delay_check = FCSR_FCC;
1897 flags = IS_BIT23_COND; \
1898 delay_check = FCSR_FCC;
1900 #else /* SLJIT_MIPS_REV < 6 */
1903 inst = BC1T | JUMP_LENGTH; \
1904 flags = IS_BIT16_COND; \
1905 delay_check = FCSR_FCC;
1907 inst = BC1F | JUMP_LENGTH; \
1908 flags = IS_BIT16_COND; \
1909 delay_check = FCSR_FCC;
1911 #endif /* SLJIT_MIPS_REV >= 6 */
1913 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_jump(struct sljit_compiler
*compiler
, sljit_s32 type
)
1915 struct sljit_jump
*jump
;
1917 sljit_s32 flags
= 0;
1918 sljit_s32 delay_check
= UNMOVABLE_INS
;
1921 CHECK_PTR(check_sljit_emit_jump(compiler
, type
));
1923 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
1925 set_jump(jump
, compiler
, type
& SLJIT_REWRITABLE_JUMP
);
1932 case SLJIT_NOT_EQUAL
:
1937 case SLJIT_SIG_LESS
:
1938 case SLJIT_SIG_GREATER
:
1939 case SLJIT_OVERFLOW
:
1942 case SLJIT_GREATER_EQUAL
:
1943 case SLJIT_LESS_EQUAL
:
1944 case SLJIT_SIG_GREATER_EQUAL
:
1945 case SLJIT_SIG_LESS_EQUAL
:
1946 case SLJIT_NOT_OVERFLOW
:
1949 case SLJIT_NOT_EQUAL_F64
:
1950 case SLJIT_GREATER_EQUAL_F64
:
1951 case SLJIT_GREATER_F64
:
1952 case SLJIT_ORDERED_F64
:
1955 case SLJIT_EQUAL_F64
:
1956 case SLJIT_LESS_F64
:
1957 case SLJIT_LESS_EQUAL_F64
:
1958 case SLJIT_UNORDERED_F64
:
1962 /* Not conditional branch. */
1967 jump
->flags
|= flags
;
1968 if (compiler
->delay_slot
== MOVABLE_INS
|| (compiler
->delay_slot
!= UNMOVABLE_INS
&& compiler
->delay_slot
!= delay_check
))
1969 jump
->flags
|= IS_MOVABLE
;
1972 PTR_FAIL_IF(push_inst(compiler
, inst
, UNMOVABLE_INS
));
1974 PTR_FAIL_IF(emit_const(compiler
, TMP_REG2
, 0));
1976 if (type
<= SLJIT_JUMP
)
1977 PTR_FAIL_IF(push_inst(compiler
, JR
| S(TMP_REG2
), UNMOVABLE_INS
));
1979 jump
->flags
|= IS_JAL
;
1980 PTR_FAIL_IF(push_inst(compiler
, JALR
| S(TMP_REG2
) | DA(RETURN_ADDR_REG
), UNMOVABLE_INS
));
1983 jump
->addr
= compiler
->size
;
1984 PTR_FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
1988 #define RESOLVE_IMM1() \
1989 if (src1 & SLJIT_IMM) { \
1991 PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \
1998 #define RESOLVE_IMM2() \
1999 if (src2 & SLJIT_IMM) { \
2001 PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \
2008 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_cmp(struct sljit_compiler
*compiler
, sljit_s32 type
,
2009 sljit_s32 src1
, sljit_sw src1w
,
2010 sljit_s32 src2
, sljit_sw src2w
)
2012 struct sljit_jump
*jump
;
2017 CHECK_PTR(check_sljit_emit_cmp(compiler
, type
, src1
, src1w
, src2
, src2w
));
2018 ADJUST_LOCAL_OFFSET(src1
, src1w
);
2019 ADJUST_LOCAL_OFFSET(src2
, src2w
);
2021 compiler
->cache_arg
= 0;
2022 compiler
->cache_argw
= 0;
2023 flags
= ((type
& SLJIT_32
) ? INT_DATA
: WORD_DATA
) | LOAD_DATA
;
2024 if (src1
& SLJIT_MEM
) {
2025 PTR_FAIL_IF(emit_op_mem2(compiler
, flags
, DR(TMP_REG1
), src1
, src1w
, src2
, src2w
));
2028 if (src2
& SLJIT_MEM
) {
2029 PTR_FAIL_IF(emit_op_mem2(compiler
, flags
, DR(TMP_REG2
), src2
, src2w
, 0, 0));
2033 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
2035 set_jump(jump
, compiler
, type
& SLJIT_REWRITABLE_JUMP
);
2038 if (type
<= SLJIT_NOT_EQUAL
) {
2041 jump
->flags
|= IS_BIT26_COND
;
2042 if (compiler
->delay_slot
== MOVABLE_INS
|| (compiler
->delay_slot
!= UNMOVABLE_INS
&& compiler
->delay_slot
!= DR(src1
) && compiler
->delay_slot
!= DR(src2
)))
2043 jump
->flags
|= IS_MOVABLE
;
2044 PTR_FAIL_IF(push_inst(compiler
, (type
== SLJIT_EQUAL
? BNE
: BEQ
) | S(src1
) | T(src2
) | JUMP_LENGTH
, UNMOVABLE_INS
));
2046 else if (type
>= SLJIT_SIG_LESS
&& (((src1
& SLJIT_IMM
) && (src1w
== 0)) || ((src2
& SLJIT_IMM
) && (src2w
== 0)))) {
2048 if ((src1
& SLJIT_IMM
) && (src1w
== 0)) {
2051 case SLJIT_SIG_LESS
:
2053 jump
->flags
|= IS_BIT26_COND
;
2055 case SLJIT_SIG_GREATER_EQUAL
:
2057 jump
->flags
|= IS_BIT26_COND
;
2059 case SLJIT_SIG_GREATER
:
2061 jump
->flags
|= IS_BIT16_COND
;
2063 case SLJIT_SIG_LESS_EQUAL
:
2065 jump
->flags
|= IS_BIT16_COND
;
2073 case SLJIT_SIG_LESS
:
2075 jump
->flags
|= IS_BIT16_COND
;
2077 case SLJIT_SIG_GREATER_EQUAL
:
2079 jump
->flags
|= IS_BIT16_COND
;
2081 case SLJIT_SIG_GREATER
:
2083 jump
->flags
|= IS_BIT26_COND
;
2085 case SLJIT_SIG_LESS_EQUAL
:
2087 jump
->flags
|= IS_BIT26_COND
;
2091 PTR_FAIL_IF(push_inst(compiler
, inst
| S(src1
) | JUMP_LENGTH
, UNMOVABLE_INS
));
2094 if (type
== SLJIT_LESS
|| type
== SLJIT_GREATER_EQUAL
|| type
== SLJIT_SIG_LESS
|| type
== SLJIT_SIG_GREATER_EQUAL
) {
2096 if ((src2
& SLJIT_IMM
) && src2w
<= SIMM_MAX
&& src2w
>= SIMM_MIN
)
2097 PTR_FAIL_IF(push_inst(compiler
, (type
<= SLJIT_LESS_EQUAL
? SLTIU
: SLTI
) | S(src1
) | T(TMP_REG1
) | IMM(src2w
), DR(TMP_REG1
)));
2100 PTR_FAIL_IF(push_inst(compiler
, (type
<= SLJIT_LESS_EQUAL
? SLTU
: SLT
) | S(src1
) | T(src2
) | D(TMP_REG1
), DR(TMP_REG1
)));
2102 type
= (type
== SLJIT_LESS
|| type
== SLJIT_SIG_LESS
) ? SLJIT_NOT_EQUAL
: SLJIT_EQUAL
;
2106 if ((src1
& SLJIT_IMM
) && src1w
<= SIMM_MAX
&& src1w
>= SIMM_MIN
)
2107 PTR_FAIL_IF(push_inst(compiler
, (type
<= SLJIT_LESS_EQUAL
? SLTIU
: SLTI
) | S(src2
) | T(TMP_REG1
) | IMM(src1w
), DR(TMP_REG1
)));
2110 PTR_FAIL_IF(push_inst(compiler
, (type
<= SLJIT_LESS_EQUAL
? SLTU
: SLT
) | S(src2
) | T(src1
) | D(TMP_REG1
), DR(TMP_REG1
)));
2112 type
= (type
== SLJIT_GREATER
|| type
== SLJIT_SIG_GREATER
) ? SLJIT_NOT_EQUAL
: SLJIT_EQUAL
;
2115 jump
->flags
|= IS_BIT26_COND
;
2116 PTR_FAIL_IF(push_inst(compiler
, (type
== SLJIT_EQUAL
? BNE
: BEQ
) | S(TMP_REG1
) | TA(0) | JUMP_LENGTH
, UNMOVABLE_INS
));
2119 PTR_FAIL_IF(emit_const(compiler
, TMP_REG2
, 0));
2120 PTR_FAIL_IF(push_inst(compiler
, JR
| S(TMP_REG2
), UNMOVABLE_INS
));
2121 jump
->addr
= compiler
->size
;
2122 PTR_FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
2138 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_ijump(struct sljit_compiler
*compiler
, sljit_s32 type
, sljit_s32 src
, sljit_sw srcw
)
2140 struct sljit_jump
*jump
= NULL
;
2143 CHECK(check_sljit_emit_ijump(compiler
, type
, src
, srcw
));
2144 ADJUST_LOCAL_OFFSET(src
, srcw
);
2146 if (src
& SLJIT_IMM
) {
2147 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
2149 set_jump(jump
, compiler
, JUMP_ADDR
| ((type
>= SLJIT_FAST_CALL
) ? IS_JAL
: 0));
2150 jump
->u
.target
= srcw
;
2152 if (compiler
->delay_slot
!= UNMOVABLE_INS
)
2153 jump
->flags
|= IS_MOVABLE
;
2155 FAIL_IF(emit_const(compiler
, TMP_REG2
, 0));
2158 else if (src
& SLJIT_MEM
) {
2159 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
| LOAD_DATA
, DR(TMP_REG2
), src
, srcw
));
2163 FAIL_IF(push_inst(compiler
, JR
| S(src
), UNMOVABLE_INS
));
2165 jump
->addr
= compiler
->size
;
2166 FAIL_IF(push_inst(compiler
, NOP
, UNMOVABLE_INS
));
2167 return SLJIT_SUCCESS
;
2170 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_flags(struct sljit_compiler
*compiler
, sljit_s32 op
,
2171 sljit_s32 dst
, sljit_sw dstw
,
2174 sljit_s32 src_ar
, dst_ar
;
2175 sljit_s32 saved_op
= op
;
2176 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2177 sljit_s32 mem_type
= WORD_DATA
;
2179 sljit_s32 mem_type
= ((op
& SLJIT_32
) || op
== SLJIT_MOV32
) ? (INT_DATA
| SIGNED_DATA
) : WORD_DATA
;
2183 CHECK(check_sljit_emit_op_flags(compiler
, op
, dst
, dstw
, type
));
2184 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2186 op
= GET_OPCODE(op
);
2187 dst_ar
= DR((op
< SLJIT_ADD
&& FAST_IS_REG(dst
)) ? dst
: TMP_REG2
);
2189 compiler
->cache_arg
= 0;
2190 compiler
->cache_argw
= 0;
2192 if (op
>= SLJIT_ADD
&& (dst
& SLJIT_MEM
))
2193 FAIL_IF(emit_op_mem2(compiler
, mem_type
| LOAD_DATA
, DR(TMP_REG1
), dst
, dstw
, dst
, dstw
));
2195 switch (type
& 0xff) {
2197 case SLJIT_NOT_EQUAL
:
2198 FAIL_IF(push_inst(compiler
, SLTIU
| SA(EQUAL_FLAG
) | TA(dst_ar
) | IMM(1), dst_ar
));
2201 case SLJIT_OVERFLOW
:
2202 case SLJIT_NOT_OVERFLOW
:
2203 if (compiler
->status_flags_state
& SLJIT_CURRENT_FLAGS_ADD_SUB
) {
2204 src_ar
= OTHER_FLAG
;
2207 FAIL_IF(push_inst(compiler
, SLTIU
| SA(OTHER_FLAG
) | TA(dst_ar
) | IMM(1), dst_ar
));
2209 type
^= 0x1; /* Flip type bit for the XORI below. */
2211 case SLJIT_GREATER_F64
:
2212 case SLJIT_LESS_EQUAL_F64
:
2213 type
^= 0x1; /* Flip type bit for the XORI below. */
2214 case SLJIT_EQUAL_F64
:
2215 case SLJIT_NOT_EQUAL_F64
:
2216 case SLJIT_LESS_F64
:
2217 case SLJIT_GREATER_EQUAL_F64
:
2218 case SLJIT_UNORDERED_F64
:
2219 case SLJIT_ORDERED_F64
:
2220 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2221 FAIL_IF(push_inst(compiler
, MFC1
| TA(dst_ar
) | FS(TMP_FREG3
), dst_ar
));
2222 #else /* SLJIT_MIPS_REV < 6 */
2223 FAIL_IF(push_inst(compiler
, CFC1
| TA(dst_ar
) | DA(FCSR_REG
), dst_ar
));
2224 #endif /* SLJIT_MIPS_REV >= 6 */
2225 FAIL_IF(push_inst(compiler
, SRL
| TA(dst_ar
) | DA(dst_ar
) | SH_IMM(23), dst_ar
));
2226 FAIL_IF(push_inst(compiler
, ANDI
| SA(dst_ar
) | TA(dst_ar
) | IMM(1), dst_ar
));
2231 src_ar
= OTHER_FLAG
;
2236 FAIL_IF(push_inst(compiler
, XORI
| SA(src_ar
) | TA(dst_ar
) | IMM(1), dst_ar
));
2240 if (op
< SLJIT_ADD
) {
2241 if (dst
& SLJIT_MEM
)
2242 return emit_op_mem(compiler
, mem_type
, src_ar
, dst
, dstw
);
2244 if (src_ar
!= dst_ar
)
2245 return push_inst(compiler
, ADDU_W
| SA(src_ar
) | TA(0) | DA(dst_ar
), dst_ar
);
2246 return SLJIT_SUCCESS
;
2249 /* OTHER_FLAG cannot be specified as src2 argument at the moment. */
2250 if (DR(TMP_REG2
) != src_ar
)
2251 FAIL_IF(push_inst(compiler
, ADDU_W
| SA(src_ar
) | TA(0) | D(TMP_REG2
), DR(TMP_REG2
)));
2253 mem_type
|= CUMULATIVE_OP
| LOGICAL_OP
| IMM_OP
| ALT_KEEP_CACHE
;
2255 if (dst
& SLJIT_MEM
)
2256 return emit_op(compiler
, saved_op
, mem_type
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0);
2257 return emit_op(compiler
, saved_op
, mem_type
, dst
, dstw
, dst
, dstw
, TMP_REG2
, 0);
2260 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_cmov(struct sljit_compiler
*compiler
, sljit_s32 type
,
2262 sljit_s32 src
, sljit_sw srcw
)
2264 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
2266 #endif /* SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6 */
2269 CHECK(check_sljit_emit_cmov(compiler
, type
, dst_reg
, src
, srcw
));
2271 #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
2273 if (SLJIT_UNLIKELY(src
& SLJIT_IMM
)) {
2274 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2275 if (dst_reg
& SLJIT_32
)
2276 srcw
= (sljit_s32
)srcw
;
2278 FAIL_IF(load_immediate(compiler
, DR(TMP_REG1
), srcw
));
2283 dst_reg
&= ~SLJIT_32
;
2285 switch (type
& 0xff) {
2287 ins
= MOVZ
| TA(EQUAL_FLAG
);
2289 case SLJIT_NOT_EQUAL
:
2290 ins
= MOVN
| TA(EQUAL_FLAG
);
2294 case SLJIT_SIG_LESS
:
2295 case SLJIT_SIG_GREATER
:
2296 case SLJIT_OVERFLOW
:
2297 ins
= MOVN
| TA(OTHER_FLAG
);
2299 case SLJIT_GREATER_EQUAL
:
2300 case SLJIT_LESS_EQUAL
:
2301 case SLJIT_SIG_GREATER_EQUAL
:
2302 case SLJIT_SIG_LESS_EQUAL
:
2303 case SLJIT_NOT_OVERFLOW
:
2304 ins
= MOVZ
| TA(OTHER_FLAG
);
2306 case SLJIT_EQUAL_F64
:
2307 case SLJIT_LESS_F64
:
2308 case SLJIT_LESS_EQUAL_F64
:
2309 case SLJIT_UNORDERED_F64
:
2312 case SLJIT_NOT_EQUAL_F64
:
2313 case SLJIT_GREATER_EQUAL_F64
:
2314 case SLJIT_GREATER_F64
:
2315 case SLJIT_ORDERED_F64
:
2319 ins
= MOVZ
| TA(OTHER_FLAG
);
2320 SLJIT_UNREACHABLE();
2324 return push_inst(compiler
, ins
| S(src
) | D(dst_reg
), DR(dst_reg
));
2326 #else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */
2327 return sljit_emit_cmov_generic(compiler
, type
, dst_reg
, src
, srcw
);
2328 #endif /* SLJIT_MIPS_REV >= 1 */
2331 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_const
* sljit_emit_const(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
, sljit_sw init_value
)
2333 struct sljit_const
*const_
;
2337 CHECK_PTR(check_sljit_emit_const(compiler
, dst
, dstw
, init_value
));
2338 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2340 const_
= (struct sljit_const
*)ensure_abuf(compiler
, sizeof(struct sljit_const
));
2341 PTR_FAIL_IF(!const_
);
2342 set_const(const_
, compiler
);
2344 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_REG2
;
2345 PTR_FAIL_IF(emit_const(compiler
, dst_r
, init_value
));
2347 if (dst
& SLJIT_MEM
)
2348 PTR_FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0));
2353 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_put_label
* sljit_emit_put_label(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
)
2355 struct sljit_put_label
*put_label
;
2359 CHECK_PTR(check_sljit_emit_put_label(compiler
, dst
, dstw
));
2360 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2362 put_label
= (struct sljit_put_label
*)ensure_abuf(compiler
, sizeof(struct sljit_put_label
));
2363 PTR_FAIL_IF(!put_label
);
2364 set_put_label(put_label
, compiler
, 0);
2366 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_REG2
;
2367 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2368 PTR_FAIL_IF(emit_const(compiler
, dst_r
, 0));
2370 PTR_FAIL_IF(push_inst(compiler
, dst_r
, UNMOVABLE_INS
));
2371 compiler
->size
+= 5;
2374 if (dst
& SLJIT_MEM
)
2375 PTR_FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0));