2 * Stack-less Just-In-Time compiler
4 * Copyright 2009-2012 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 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST
char* sljit_get_platform_name(void)
29 return "PowerPC" SLJIT_CPUINFO
;
32 /* Length of an instruction word.
33 Both for ppc-32 and ppc-64. */
34 typedef sljit_ui sljit_ins
;
37 #include <sys/cache.h>
40 static void ppc_cache_flush(sljit_ins
*from
, sljit_ins
*to
)
43 _sync_cache_range((caddr_t
)from
, (int)((size_t)to
- (size_t)from
));
44 #elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
45 # if defined(_ARCH_PWR) || defined(_ARCH_PWR2)
46 /* Cache flush for POWER architecture. */
55 __asm__
volatile ( "ics" );
56 # elif defined(_ARCH_COM) && !defined(_ARCH_PPC)
57 # error "Cache flush is not implemented for PowerPC/POWER common mode."
59 /* Cache flush for PowerPC architecture. */
69 __asm__
volatile ( "isync" );
72 # warning "This file may fail to compile if -qfuncsect is used"
74 #elif defined(__xlc__)
75 #error "Please enable GCC syntax for inline assembly statements with -qasm=gcc"
77 #error "This platform requires a cache flush implementation."
81 #define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
82 #define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
83 #define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
84 #define ZERO_REG (SLJIT_NO_REGISTERS + 4)
87 #define TMP_FREG2 (SLJIT_FLOAT_REG6 + 1)
89 static SLJIT_CONST sljit_ub reg_map
[SLJIT_NO_REGISTERS
+ 5] = {
90 0, 3, 4, 5, 6, 7, 30, 29, 28, 27, 26, 1, 8, 9, 10, 31
93 /* --------------------------------------------------------------------- */
94 /* Instrucion forms */
95 /* --------------------------------------------------------------------- */
96 #define D(d) (reg_map[d] << 21)
97 #define S(s) (reg_map[s] << 21)
98 #define A(a) (reg_map[a] << 16)
99 #define B(b) (reg_map[b] << 11)
100 #define C(c) (reg_map[c] << 6)
101 #define FD(fd) ((fd) << 21)
102 #define FA(fa) ((fa) << 16)
103 #define FB(fb) ((fb) << 11)
104 #define FC(fc) ((fc) << 6)
105 #define IMM(imm) ((imm) & 0xffff)
106 #define CRD(d) ((d) << 21)
108 /* Instruction bit sections.
109 OE and Rc flag (see ALT_SET_FLAGS). */
110 #define OERC(flags) (((flags & ALT_SET_FLAGS) >> 10) | (flags & ALT_SET_FLAGS))
111 /* Rc flag (see ALT_SET_FLAGS). */
112 #define RC(flags) ((flags & ALT_SET_FLAGS) >> 10)
113 #define HI(opcode) ((opcode) << 26)
114 #define LO(opcode) ((opcode) << 1)
116 #define ADD (HI(31) | LO(266))
117 #define ADDC (HI(31) | LO(10))
118 #define ADDE (HI(31) | LO(138))
119 #define ADDI (HI(14))
120 #define ADDIC (HI(13))
121 #define ADDIS (HI(15))
122 #define ADDME (HI(31) | LO(234))
123 #define AND (HI(31) | LO(28))
124 #define ANDI (HI(28))
125 #define ANDIS (HI(29))
128 #define BCCTR (HI(19) | LO(528) | (3 << 11))
129 #define BLR (HI(19) | LO(16) | (0x14 << 21))
130 #define CNTLZD (HI(31) | LO(58))
131 #define CNTLZW (HI(31) | LO(26))
132 #define CMP (HI(31) | LO(0))
133 #define CMPI (HI(11))
134 #define CMPL (HI(31) | LO(32))
135 #define CMPLI (HI(10))
136 #define CROR (HI(19) | LO(449))
137 #define DIVD (HI(31) | LO(489))
138 #define DIVDU (HI(31) | LO(457))
139 #define DIVW (HI(31) | LO(491))
140 #define DIVWU (HI(31) | LO(459))
141 #define EXTSB (HI(31) | LO(954))
142 #define EXTSH (HI(31) | LO(922))
143 #define EXTSW (HI(31) | LO(986))
144 #define FABS (HI(63) | LO(264))
145 #define FADD (HI(63) | LO(21))
146 #define FADDS (HI(59) | LO(21))
147 #define FCMPU (HI(63) | LO(0))
148 #define FDIV (HI(63) | LO(18))
149 #define FDIVS (HI(59) | LO(18))
150 #define FMR (HI(63) | LO(72))
151 #define FMUL (HI(63) | LO(25))
152 #define FMULS (HI(59) | LO(25))
153 #define FNEG (HI(63) | LO(40))
154 #define FSUB (HI(63) | LO(20))
155 #define FSUBS (HI(59) | LO(20))
156 #define LD (HI(58) | 0)
158 #define MFCR (HI(31) | LO(19))
159 #define MFLR (HI(31) | LO(339) | 0x80000)
160 #define MFXER (HI(31) | LO(339) | 0x10000)
161 #define MTCTR (HI(31) | LO(467) | 0x90000)
162 #define MTLR (HI(31) | LO(467) | 0x80000)
163 #define MTXER (HI(31) | LO(467) | 0x10000)
164 #define MULHD (HI(31) | LO(73))
165 #define MULHDU (HI(31) | LO(9))
166 #define MULHW (HI(31) | LO(75))
167 #define MULHWU (HI(31) | LO(11))
168 #define MULLD (HI(31) | LO(233))
169 #define MULLI (HI(7))
170 #define MULLW (HI(31) | LO(235))
171 #define NEG (HI(31) | LO(104))
173 #define NOR (HI(31) | LO(124))
174 #define OR (HI(31) | LO(444))
176 #define ORIS (HI(25))
177 #define RLDICL (HI(30))
178 #define RLWINM (HI(21))
179 #define SLD (HI(31) | LO(27))
180 #define SLW (HI(31) | LO(24))
181 #define SRAD (HI(31) | LO(794))
182 #define SRADI (HI(31) | LO(413 << 1))
183 #define SRAW (HI(31) | LO(792))
184 #define SRAWI (HI(31) | LO(824))
185 #define SRD (HI(31) | LO(539))
186 #define SRW (HI(31) | LO(536))
187 #define STD (HI(62) | 0)
188 #define STDU (HI(62) | 1)
189 #define STDUX (HI(31) | LO(181))
191 #define STWU (HI(37))
192 #define STWUX (HI(31) | LO(183))
193 #define SUBF (HI(31) | LO(40))
194 #define SUBFC (HI(31) | LO(8))
195 #define SUBFE (HI(31) | LO(136))
196 #define SUBFIC (HI(8))
197 #define XOR (HI(31) | LO(316))
198 #define XORI (HI(26))
199 #define XORIS (HI(27))
201 #define SIMM_MAX (0x7fff)
202 #define SIMM_MIN (-0x8000)
203 #define UIMM_MAX (0xffff)
205 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
206 SLJIT_API_FUNC_ATTRIBUTE
void sljit_set_function_context(void** func_ptr
, struct sljit_function_context
* context
, sljit_sw addr
, void* func
)
210 *func_ptr
= (void*)context
;
211 ptrs
= (sljit_sw
*)func
;
212 context
->addr
= addr
? addr
: ptrs
[0];
213 context
->r2
= ptrs
[1];
214 context
->r11
= ptrs
[2];
218 static sljit_si
push_inst(struct sljit_compiler
*compiler
, sljit_ins ins
)
220 sljit_ins
*ptr
= (sljit_ins
*)ensure_buf(compiler
, sizeof(sljit_ins
));
224 return SLJIT_SUCCESS
;
227 static SLJIT_INLINE sljit_si
optimize_jump(struct sljit_jump
*jump
, sljit_ins
*code_ptr
, sljit_ins
*code
)
230 sljit_uw target_addr
;
232 if (jump
->flags
& SLJIT_REWRITABLE_JUMP
)
235 if (jump
->flags
& JUMP_ADDR
)
236 target_addr
= jump
->u
.target
;
238 SLJIT_ASSERT(jump
->flags
& JUMP_LABEL
);
239 target_addr
= (sljit_uw
)(code
+ jump
->u
.label
->size
);
241 diff
= ((sljit_sw
)target_addr
- (sljit_sw
)(code_ptr
)) & ~0x3l
;
243 if (jump
->flags
& UNCOND_B
) {
244 if (diff
<= 0x01ffffff && diff
>= -0x02000000) {
245 jump
->flags
|= PATCH_B
;
248 if (target_addr
<= 0x03ffffff) {
249 jump
->flags
|= PATCH_B
| ABSOLUTE_B
;
254 if (diff
<= 0x7fff && diff
>= -0x8000) {
255 jump
->flags
|= PATCH_B
;
258 if (target_addr
<= 0xffff) {
259 jump
->flags
|= PATCH_B
| ABSOLUTE_B
;
266 SLJIT_API_FUNC_ATTRIBUTE
void* sljit_generate_code(struct sljit_compiler
*compiler
)
268 struct sljit_memory_fragment
*buf
;
276 struct sljit_label
*label
;
277 struct sljit_jump
*jump
;
278 struct sljit_const
*const_
;
281 check_sljit_generate_code(compiler
);
282 reverse_buf(compiler
);
284 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
285 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
286 compiler
->size
+= (compiler
->size
& 0x1) + (sizeof(struct sljit_function_context
) / sizeof(sljit_ins
));
288 compiler
->size
+= (sizeof(struct sljit_function_context
) / sizeof(sljit_ins
));
291 code
= (sljit_ins
*)SLJIT_MALLOC_EXEC(compiler
->size
* sizeof(sljit_ins
));
292 PTR_FAIL_WITH_EXEC_IF(code
);
297 label
= compiler
->labels
;
298 jump
= compiler
->jumps
;
299 const_
= compiler
->consts
;
301 buf_ptr
= (sljit_ins
*)buf
->memory
;
302 buf_end
= buf_ptr
+ (buf
->used_size
>> 2);
304 *code_ptr
= *buf_ptr
++;
305 SLJIT_ASSERT(!label
|| label
->size
>= word_count
);
306 SLJIT_ASSERT(!jump
|| jump
->addr
>= word_count
);
307 SLJIT_ASSERT(!const_
|| const_
->addr
>= word_count
);
308 /* These structures are ordered by their address. */
309 if (label
&& label
->size
== word_count
) {
310 /* Just recording the address. */
311 label
->addr
= (sljit_uw
)code_ptr
;
312 label
->size
= code_ptr
- code
;
315 if (jump
&& jump
->addr
== word_count
) {
316 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
317 jump
->addr
= (sljit_uw
)(code_ptr
- 3);
319 jump
->addr
= (sljit_uw
)(code_ptr
- 6);
321 if (optimize_jump(jump
, code_ptr
, code
)) {
322 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
323 code_ptr
[-3] = code_ptr
[0];
326 code_ptr
[-6] = code_ptr
[0];
332 if (const_
&& const_
->addr
== word_count
) {
333 /* Just recording the address. */
334 const_
->addr
= (sljit_uw
)code_ptr
;
335 const_
= const_
->next
;
339 } while (buf_ptr
< buf_end
);
344 if (label
&& label
->size
== word_count
) {
345 label
->addr
= (sljit_uw
)code_ptr
;
346 label
->size
= code_ptr
- code
;
350 SLJIT_ASSERT(!label
);
352 SLJIT_ASSERT(!const_
);
353 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
354 SLJIT_ASSERT(code_ptr
- code
<= (sljit_sw
)compiler
->size
- (sizeof(struct sljit_function_context
) / sizeof(sljit_ins
)));
356 SLJIT_ASSERT(code_ptr
- code
<= (sljit_sw
)compiler
->size
);
359 jump
= compiler
->jumps
;
362 addr
= (jump
->flags
& JUMP_LABEL
) ? jump
->u
.label
->addr
: jump
->u
.target
;
363 buf_ptr
= (sljit_ins
*)jump
->addr
;
364 if (jump
->flags
& PATCH_B
) {
365 if (jump
->flags
& UNCOND_B
) {
366 if (!(jump
->flags
& ABSOLUTE_B
)) {
367 addr
= addr
- jump
->addr
;
368 SLJIT_ASSERT((sljit_sw
)addr
<= 0x01ffffff && (sljit_sw
)addr
>= -0x02000000);
369 *buf_ptr
= Bx
| (addr
& 0x03fffffc) | ((*buf_ptr
) & 0x1);
372 SLJIT_ASSERT(addr
<= 0x03ffffff);
373 *buf_ptr
= Bx
| (addr
& 0x03fffffc) | 0x2 | ((*buf_ptr
) & 0x1);
377 if (!(jump
->flags
& ABSOLUTE_B
)) {
378 addr
= addr
- jump
->addr
;
379 SLJIT_ASSERT((sljit_sw
)addr
<= 0x7fff && (sljit_sw
)addr
>= -0x8000);
380 *buf_ptr
= BCx
| (addr
& 0xfffc) | ((*buf_ptr
) & 0x03ff0001);
384 SLJIT_ASSERT(addr
<= 0xffff);
385 *buf_ptr
= BCx
| (addr
& 0xfffc) | 0x2 | ((*buf_ptr
) & 0x03ff0001);
391 /* Set the fields of immediate loads. */
392 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
393 buf_ptr
[0] = (buf_ptr
[0] & 0xffff0000) | ((addr
>> 16) & 0xffff);
394 buf_ptr
[1] = (buf_ptr
[1] & 0xffff0000) | (addr
& 0xffff);
396 buf_ptr
[0] = (buf_ptr
[0] & 0xffff0000) | ((addr
>> 48) & 0xffff);
397 buf_ptr
[1] = (buf_ptr
[1] & 0xffff0000) | ((addr
>> 32) & 0xffff);
398 buf_ptr
[3] = (buf_ptr
[3] & 0xffff0000) | ((addr
>> 16) & 0xffff);
399 buf_ptr
[4] = (buf_ptr
[4] & 0xffff0000) | (addr
& 0xffff);
405 SLJIT_CACHE_FLUSH(code
, code_ptr
);
406 compiler
->error
= SLJIT_ERR_COMPILED
;
407 compiler
->executable_size
= compiler
->size
* sizeof(sljit_ins
);
409 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
410 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
411 if (((sljit_sw
)code_ptr
) & 0x4)
413 sljit_set_function_context(NULL
, (struct sljit_function_context
*)code_ptr
, (sljit_sw
)code
, (void*)sljit_generate_code
);
416 sljit_set_function_context(NULL
, (struct sljit_function_context
*)code_ptr
, (sljit_sw
)code
, (void*)sljit_generate_code
);
424 /* --------------------------------------------------------------------- */
426 /* --------------------------------------------------------------------- */
430 /* Creates an index in data_transfer_insts array. */
431 #define LOAD_DATA 0x01
433 #define WRITE_BACK 0x04
434 #define WORD_DATA 0x00
435 #define BYTE_DATA 0x08
436 #define HALF_DATA 0x10
437 #define INT_DATA 0x18
438 #define SIGNED_DATA 0x20
439 /* Separates integer and floating point registers */
441 #define DOUBLE_DATA 0x40
443 #define MEM_MASK 0x7f
445 /* Other inp_flags. */
447 #define ARG_TEST 0x000100
448 /* Integer opertion and set flags -> requires exts on 64 bit systems. */
449 #define ALT_SIGN_EXT 0x000200
450 /* This flag affects the RC() and OERC() macros. */
451 #define ALT_SET_FLAGS 0x000400
452 #define ALT_FORM1 0x010000
453 #define ALT_FORM2 0x020000
454 #define ALT_FORM3 0x040000
455 #define ALT_FORM4 0x080000
456 #define ALT_FORM5 0x100000
457 #define ALT_FORM6 0x200000
459 /* Source and destination is register. */
460 #define REG_DEST 0x000001
461 #define REG1_SOURCE 0x000002
462 #define REG2_SOURCE 0x000004
463 /* getput_arg_fast returned true. */
464 #define FAST_DEST 0x000008
465 /* Multiple instructions are required. */
466 #define SLOW_DEST 0x000010
468 ALT_SIGN_EXT 0x000200
469 ALT_SET_FLAGS 0x000400
472 ALT_FORM6 0x200000 */
474 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
475 #include "sljitNativePPC_32.c"
477 #include "sljitNativePPC_64.c"
480 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
481 #define STACK_STORE STW
482 #define STACK_LOAD LWZ
484 #define STACK_STORE STD
485 #define STACK_LOAD LD
488 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_enter(struct sljit_compiler
*compiler
, sljit_si args
, sljit_si temporaries
, sljit_si saveds
, sljit_si local_size
)
491 check_sljit_emit_enter(compiler
, args
, temporaries
, saveds
, local_size
);
493 compiler
->temporaries
= temporaries
;
494 compiler
->saveds
= saveds
;
495 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
496 compiler
->logical_local_size
= local_size
;
499 FAIL_IF(push_inst(compiler
, MFLR
| D(0)));
500 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(ZERO_REG
) | A(SLJIT_LOCALS_REG
) | IMM(-(sljit_si
)(sizeof(sljit_sw
))) ));
502 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(SLJIT_SAVED_REG1
) | A(SLJIT_LOCALS_REG
) | IMM(-2 * (sljit_si
)(sizeof(sljit_sw
))) ));
504 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(SLJIT_SAVED_REG2
) | A(SLJIT_LOCALS_REG
) | IMM(-3 * (sljit_si
)(sizeof(sljit_sw
))) ));
506 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(SLJIT_SAVED_REG3
) | A(SLJIT_LOCALS_REG
) | IMM(-4 * (sljit_si
)(sizeof(sljit_sw
))) ));
508 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(SLJIT_SAVED_EREG1
) | A(SLJIT_LOCALS_REG
) | IMM(-5 * (sljit_si
)(sizeof(sljit_sw
))) ));
510 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(SLJIT_SAVED_EREG2
) | A(SLJIT_LOCALS_REG
) | IMM(-6 * (sljit_si
)(sizeof(sljit_sw
))) ));
511 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(0) | A(SLJIT_LOCALS_REG
) | IMM(sizeof(sljit_sw
)) ));
513 FAIL_IF(push_inst(compiler
, ADDI
| D(ZERO_REG
) | A(0) | 0));
515 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_TEMPORARY_REG1
) | A(SLJIT_SAVED_REG1
) | B(SLJIT_TEMPORARY_REG1
)));
517 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_TEMPORARY_REG2
) | A(SLJIT_SAVED_REG2
) | B(SLJIT_TEMPORARY_REG2
)));
519 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_TEMPORARY_REG3
) | A(SLJIT_SAVED_REG3
) | B(SLJIT_TEMPORARY_REG3
)));
521 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
522 compiler
->local_size
= (1 + saveds
+ 6 + 8) * sizeof(sljit_sw
) + local_size
;
524 compiler
->local_size
= (1 + saveds
+ 2) * sizeof(sljit_sw
) + local_size
;
526 compiler
->local_size
= (compiler
->local_size
+ 15) & ~0xf;
528 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
529 if (compiler
->local_size
<= SIMM_MAX
)
530 FAIL_IF(push_inst(compiler
, STWU
| S(SLJIT_LOCALS_REG
) | A(SLJIT_LOCALS_REG
) | IMM(-compiler
->local_size
)));
532 FAIL_IF(load_immediate(compiler
, 0, -compiler
->local_size
));
533 FAIL_IF(push_inst(compiler
, STWUX
| S(SLJIT_LOCALS_REG
) | A(SLJIT_LOCALS_REG
) | B(0)));
536 if (compiler
->local_size
<= SIMM_MAX
)
537 FAIL_IF(push_inst(compiler
, STDU
| S(SLJIT_LOCALS_REG
) | A(SLJIT_LOCALS_REG
) | IMM(-compiler
->local_size
)));
539 FAIL_IF(load_immediate(compiler
, 0, -compiler
->local_size
));
540 FAIL_IF(push_inst(compiler
, STDUX
| S(SLJIT_LOCALS_REG
) | A(SLJIT_LOCALS_REG
) | B(0)));
544 return SLJIT_SUCCESS
;
547 SLJIT_API_FUNC_ATTRIBUTE
void sljit_set_context(struct sljit_compiler
*compiler
, sljit_si args
, sljit_si temporaries
, sljit_si saveds
, sljit_si local_size
)
550 check_sljit_set_context(compiler
, args
, temporaries
, saveds
, local_size
);
552 compiler
->temporaries
= temporaries
;
553 compiler
->saveds
= saveds
;
554 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
555 compiler
->logical_local_size
= local_size
;
558 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
559 compiler
->local_size
= (1 + saveds
+ 6 + 8) * sizeof(sljit_sw
) + local_size
;
561 compiler
->local_size
= (1 + saveds
+ 2) * sizeof(sljit_sw
) + local_size
;
563 compiler
->local_size
= (compiler
->local_size
+ 15) & ~0xf;
566 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_return(struct sljit_compiler
*compiler
, sljit_si op
, sljit_si src
, sljit_sw srcw
)
569 check_sljit_emit_return(compiler
, op
, src
, srcw
);
571 FAIL_IF(emit_mov_before_return(compiler
, op
, src
, srcw
));
573 if (compiler
->local_size
<= SIMM_MAX
)
574 FAIL_IF(push_inst(compiler
, ADDI
| D(SLJIT_LOCALS_REG
) | A(SLJIT_LOCALS_REG
) | IMM(compiler
->local_size
)));
576 FAIL_IF(load_immediate(compiler
, 0, compiler
->local_size
));
577 FAIL_IF(push_inst(compiler
, ADD
| D(SLJIT_LOCALS_REG
) | A(SLJIT_LOCALS_REG
) | B(0)));
580 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(0) | A(SLJIT_LOCALS_REG
) | IMM(sizeof(sljit_sw
))));
581 if (compiler
->saveds
>= 5)
582 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(SLJIT_SAVED_EREG2
) | A(SLJIT_LOCALS_REG
) | IMM(-6 * (sljit_si
)(sizeof(sljit_sw
))) ));
583 if (compiler
->saveds
>= 4)
584 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(SLJIT_SAVED_EREG1
) | A(SLJIT_LOCALS_REG
) | IMM(-5 * (sljit_si
)(sizeof(sljit_sw
))) ));
585 if (compiler
->saveds
>= 3)
586 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(SLJIT_SAVED_REG3
) | A(SLJIT_LOCALS_REG
) | IMM(-4 * (sljit_si
)(sizeof(sljit_sw
))) ));
587 if (compiler
->saveds
>= 2)
588 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(SLJIT_SAVED_REG2
) | A(SLJIT_LOCALS_REG
) | IMM(-3 * (sljit_si
)(sizeof(sljit_sw
))) ));
589 if (compiler
->saveds
>= 1)
590 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(SLJIT_SAVED_REG1
) | A(SLJIT_LOCALS_REG
) | IMM(-2 * (sljit_si
)(sizeof(sljit_sw
))) ));
591 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(ZERO_REG
) | A(SLJIT_LOCALS_REG
) | IMM(-(sljit_si
)(sizeof(sljit_sw
))) ));
593 FAIL_IF(push_inst(compiler
, MTLR
| S(0)));
594 FAIL_IF(push_inst(compiler
, BLR
));
596 return SLJIT_SUCCESS
;
602 /* --------------------------------------------------------------------- */
604 /* --------------------------------------------------------------------- */
606 /* i/x - immediate/indexed form
607 n/w - no write-back / write-back (1 bit)
608 s/l - store/load (1 bit)
609 u/s - signed/unsigned (1 bit)
610 w/b/h/i - word/byte/half/int allowed (2 bit)
611 It contans 32 items, but not all are different. */
613 /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
614 #define ADDR_MODE2 0x10000
615 /* 64-bit only: there is no lwau instruction. */
616 #define UPDATE_REQ 0x20000
618 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
619 #define ARCH_32_64(a, b) a
620 #define INST_CODE_AND_DST(inst, flags, reg) \
621 ((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
623 #define ARCH_32_64(a, b) b
624 #define INST_CODE_AND_DST(inst, flags, reg) \
625 (((inst) & ~(ADDR_MODE2 | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
628 static SLJIT_CONST sljit_ins data_transfer_insts
[64 + 8] = {
630 /* -------- Unsigned -------- */
634 /* u w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | ADDR_MODE2
| 0x0 /* std */),
635 /* u w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2
| 0x0 /* ld */),
636 /* u w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
637 /* u w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
639 /* u w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | ADDR_MODE2
| 0x1 /* stdu */),
640 /* u w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2
| 0x1 /* ldu */),
641 /* u w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
642 /* u w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
646 /* u b n i s */ HI(38) /* stb */,
647 /* u b n i l */ HI(34) /* lbz */,
648 /* u b n x s */ HI(31) | LO(215) /* stbx */,
649 /* u b n x l */ HI(31) | LO(87) /* lbzx */,
651 /* u b w i s */ HI(39) /* stbu */,
652 /* u b w i l */ HI(35) /* lbzu */,
653 /* u b w x s */ HI(31) | LO(247) /* stbux */,
654 /* u b w x l */ HI(31) | LO(119) /* lbzux */,
658 /* u h n i s */ HI(44) /* sth */,
659 /* u h n i l */ HI(40) /* lhz */,
660 /* u h n x s */ HI(31) | LO(407) /* sthx */,
661 /* u h n x l */ HI(31) | LO(279) /* lhzx */,
663 /* u h w i s */ HI(45) /* sthu */,
664 /* u h w i l */ HI(41) /* lhzu */,
665 /* u h w x s */ HI(31) | LO(439) /* sthux */,
666 /* u h w x l */ HI(31) | LO(311) /* lhzux */,
670 /* u i n i s */ HI(36) /* stw */,
671 /* u i n i l */ HI(32) /* lwz */,
672 /* u i n x s */ HI(31) | LO(151) /* stwx */,
673 /* u i n x l */ HI(31) | LO(23) /* lwzx */,
675 /* u i w i s */ HI(37) /* stwu */,
676 /* u i w i l */ HI(33) /* lwzu */,
677 /* u i w x s */ HI(31) | LO(183) /* stwux */,
678 /* u i w x l */ HI(31) | LO(55) /* lwzux */,
680 /* -------- Signed -------- */
684 /* s w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | ADDR_MODE2
| 0x0 /* std */),
685 /* s w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2
| 0x0 /* ld */),
686 /* s w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
687 /* s w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
689 /* s w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | ADDR_MODE2
| 0x1 /* stdu */),
690 /* s w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2
| 0x1 /* ldu */),
691 /* s w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
692 /* s w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
696 /* s b n i s */ HI(38) /* stb */,
697 /* s b n i l */ HI(34) /* lbz */ /* EXTS_REQ */,
698 /* s b n x s */ HI(31) | LO(215) /* stbx */,
699 /* s b n x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
701 /* s b w i s */ HI(39) /* stbu */,
702 /* s b w i l */ HI(35) /* lbzu */ /* EXTS_REQ */,
703 /* s b w x s */ HI(31) | LO(247) /* stbux */,
704 /* s b w x l */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */,
708 /* s h n i s */ HI(44) /* sth */,
709 /* s h n i l */ HI(42) /* lha */,
710 /* s h n x s */ HI(31) | LO(407) /* sthx */,
711 /* s h n x l */ HI(31) | LO(343) /* lhax */,
713 /* s h w i s */ HI(45) /* sthu */,
714 /* s h w i l */ HI(43) /* lhau */,
715 /* s h w x s */ HI(31) | LO(439) /* sthux */,
716 /* s h w x l */ HI(31) | LO(375) /* lhaux */,
720 /* s i n i s */ HI(36) /* stw */,
721 /* s i n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2
| 0x2 /* lwa */),
722 /* s i n x s */ HI(31) | LO(151) /* stwx */,
723 /* s i n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
725 /* s i w i s */ HI(37) /* stwu */,
726 /* s i w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2
| UPDATE_REQ
| 0x2 /* lwa */),
727 /* s i w x s */ HI(31) | LO(183) /* stwux */,
728 /* s i w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
730 /* -------- Double -------- */
732 /* d n i s */ HI(54) /* stfd */,
733 /* d n i l */ HI(50) /* lfd */,
734 /* d n x s */ HI(31) | LO(727) /* stfdx */,
735 /* d n x l */ HI(31) | LO(599) /* lfdx */,
737 /* s n i s */ HI(52) /* stfs */,
738 /* s n i l */ HI(48) /* lfs */,
739 /* s n x s */ HI(31) | LO(663) /* stfsx */,
740 /* s n x l */ HI(31) | LO(535) /* lfsx */,
746 /* Simple cases, (no caching is required). */
747 static sljit_si
getput_arg_fast(struct sljit_compiler
*compiler
, sljit_si inp_flags
, sljit_si reg
, sljit_si arg
, sljit_sw argw
)
750 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
754 SLJIT_ASSERT(arg
& SLJIT_MEM
);
756 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
757 if (argw
<= SIMM_MAX
&& argw
>= SIMM_MIN
) {
758 if (inp_flags
& ARG_TEST
)
761 inst
= data_transfer_insts
[(inp_flags
& ~WRITE_BACK
) & MEM_MASK
];
762 SLJIT_ASSERT(!(inst
& (ADDR_MODE2
| UPDATE_REQ
)));
763 push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | IMM(argw
));
767 inst
= data_transfer_insts
[(inp_flags
& ~WRITE_BACK
) & MEM_MASK
];
768 if (argw
<= SIMM_MAX
&& argw
>= SIMM_MIN
&&
769 (!(inst
& ADDR_MODE2
) || (argw
& 0x3) == 0)) {
770 if (inp_flags
& ARG_TEST
)
773 push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | IMM(argw
));
781 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
782 if (argw
<= SIMM_MAX
&& argw
>= SIMM_MIN
) {
783 if (inp_flags
& ARG_TEST
)
786 inst
= data_transfer_insts
[inp_flags
& MEM_MASK
];
787 SLJIT_ASSERT(!(inst
& (ADDR_MODE2
| UPDATE_REQ
)));
788 push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
& 0xf) | IMM(argw
));
792 inst
= data_transfer_insts
[inp_flags
& MEM_MASK
];
793 if (argw
<= SIMM_MAX
&& argw
>= SIMM_MIN
&& (!(inst
& ADDR_MODE2
) || (argw
& 0x3) == 0)) {
794 if (inp_flags
& ARG_TEST
)
797 if ((inp_flags
& WRITE_BACK
) && (inst
& UPDATE_REQ
)) {
798 tmp_reg
= (inp_flags
& LOAD_DATA
) ? (arg
& 0xf) : TMP_REG3
;
799 if (push_inst(compiler
, ADDI
| D(tmp_reg
) | A(arg
& 0xf) | IMM(argw
)))
801 arg
= tmp_reg
| SLJIT_MEM
;
804 push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
& 0xf) | IMM(argw
));
809 else if (!(argw
& 0x3)) {
810 if (inp_flags
& ARG_TEST
)
812 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
813 SLJIT_ASSERT(!(inst
& (ADDR_MODE2
| UPDATE_REQ
)));
814 push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
& 0xf) | B((arg
>> 4) & 0xf));
820 /* See getput_arg below.
821 Note: can_cache is called only for binary operators. Those operator always
822 uses word arguments without write back. */
823 static sljit_si
can_cache(sljit_si arg
, sljit_sw argw
, sljit_si next_arg
, sljit_sw next_argw
)
825 SLJIT_ASSERT((arg
& SLJIT_MEM
) && (next_arg
& SLJIT_MEM
));
828 return (next_arg
& SLJIT_MEM
) && ((sljit_uw
)argw
- (sljit_uw
)next_argw
<= SIMM_MAX
|| (sljit_uw
)next_argw
- (sljit_uw
)argw
<= SIMM_MAX
);
831 return ((arg
& 0xf0) == (next_arg
& 0xf0) && (argw
& 0x3) == (next_argw
& 0x3));
833 if (argw
<= SIMM_MAX
&& argw
>= SIMM_MIN
) {
834 if (arg
== next_arg
&& (next_argw
>= SIMM_MAX
&& next_argw
<= SIMM_MIN
))
838 if (arg
== next_arg
&& ((sljit_uw
)argw
- (sljit_uw
)next_argw
<= SIMM_MAX
|| (sljit_uw
)next_argw
- (sljit_uw
)argw
<= SIMM_MAX
))
844 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
845 #define ADJUST_CACHED_IMM(imm) \
846 if ((inst & ADDR_MODE2) && (imm & 0x3)) { \
847 /* Adjust cached value. Fortunately this is really a rare case */ \
848 compiler->cache_argw += imm & 0x3; \
849 FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | (imm & 0x3))); \
853 #define ADJUST_CACHED_IMM(imm)
856 /* Emit the necessary instructions. See can_cache above. */
857 static sljit_si
getput_arg(struct sljit_compiler
*compiler
, sljit_si inp_flags
, sljit_si reg
, sljit_si arg
, sljit_sw argw
, sljit_si next_arg
, sljit_sw next_argw
)
862 SLJIT_ASSERT(arg
& SLJIT_MEM
);
864 tmp_r
= ((inp_flags
& LOAD_DATA
) && ((inp_flags
) & MEM_MASK
) <= GPR_REG
) ? reg
: TMP_REG1
;
865 /* Special case for "mov reg, [reg, ... ]". */
866 if ((arg
& 0xf) == tmp_r
)
870 inst
= data_transfer_insts
[(inp_flags
& ~WRITE_BACK
) & MEM_MASK
];
871 if ((compiler
->cache_arg
& SLJIT_IMM
) && (((sljit_uw
)argw
- (sljit_uw
)compiler
->cache_argw
) <= SIMM_MAX
|| ((sljit_uw
)compiler
->cache_argw
- (sljit_uw
)argw
) <= SIMM_MAX
)) {
872 argw
= argw
- compiler
->cache_argw
;
873 ADJUST_CACHED_IMM(argw
);
874 SLJIT_ASSERT(!(inst
& UPDATE_REQ
));
875 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(TMP_REG3
) | IMM(argw
));
878 if ((next_arg
& SLJIT_MEM
) && (argw
- next_argw
<= SIMM_MAX
|| next_argw
- argw
<= SIMM_MAX
)) {
879 SLJIT_ASSERT(inp_flags
& LOAD_DATA
);
881 compiler
->cache_arg
= SLJIT_IMM
;
882 compiler
->cache_argw
= argw
;
886 FAIL_IF(load_immediate(compiler
, tmp_r
, argw
));
887 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(tmp_r
));
890 if (SLJIT_UNLIKELY(arg
& 0xf0)) {
892 /* Otherwise getput_arg_fast would capture it. */
895 if ((SLJIT_MEM
| (arg
& 0xf0)) == compiler
->cache_arg
&& argw
== compiler
->cache_argw
)
898 if ((arg
& 0xf0) == (next_arg
& 0xf0) && argw
== (next_argw
& 0x3)) {
899 compiler
->cache_arg
= SLJIT_MEM
| (arg
& 0xf0);
900 compiler
->cache_argw
= argw
;
903 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
904 FAIL_IF(push_inst(compiler
, RLWINM
| S((arg
>> 4) & 0xf) | A(tmp_r
) | (argw
<< 11) | ((31 - argw
) << 1)));
906 FAIL_IF(push_inst(compiler
, RLDI(tmp_r
, (arg
>> 4) & 0xf, argw
, 63 - argw
, 1)));
909 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
910 SLJIT_ASSERT(!(inst
& (ADDR_MODE2
| UPDATE_REQ
)));
911 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
& 0xf) | B(tmp_r
));
914 inst
= data_transfer_insts
[inp_flags
& MEM_MASK
];
916 if (compiler
->cache_arg
== arg
&& ((sljit_uw
)argw
- (sljit_uw
)compiler
->cache_argw
<= SIMM_MAX
|| (sljit_uw
)compiler
->cache_argw
- (sljit_uw
)argw
<= SIMM_MAX
)) {
917 SLJIT_ASSERT(!(inp_flags
& WRITE_BACK
));
918 argw
= argw
- compiler
->cache_argw
;
919 ADJUST_CACHED_IMM(argw
);
920 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(TMP_REG3
) | IMM(argw
));
923 if ((compiler
->cache_arg
& SLJIT_IMM
) && compiler
->cache_argw
== argw
) {
924 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
925 SLJIT_ASSERT(!(inst
& (ADDR_MODE2
| UPDATE_REQ
)));
926 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
& 0xf) | B(TMP_REG3
));
929 if (argw
== next_argw
&& (next_arg
& SLJIT_MEM
)) {
930 SLJIT_ASSERT(inp_flags
& LOAD_DATA
);
931 FAIL_IF(load_immediate(compiler
, TMP_REG3
, argw
));
933 compiler
->cache_arg
= SLJIT_IMM
;
934 compiler
->cache_argw
= argw
;
936 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
937 SLJIT_ASSERT(!(inst
& (ADDR_MODE2
| UPDATE_REQ
)));
938 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
& 0xf) | B(TMP_REG3
));
941 if (arg
== next_arg
&& !(inp_flags
& WRITE_BACK
) && ((sljit_uw
)argw
- (sljit_uw
)next_argw
<= SIMM_MAX
|| (sljit_uw
)next_argw
- (sljit_uw
)argw
<= SIMM_MAX
)) {
942 SLJIT_ASSERT(inp_flags
& LOAD_DATA
);
943 FAIL_IF(load_immediate(compiler
, TMP_REG3
, argw
));
944 FAIL_IF(push_inst(compiler
, ADD
| D(TMP_REG3
) | A(TMP_REG3
) | B(arg
& 0xf)));
946 compiler
->cache_arg
= arg
;
947 compiler
->cache_argw
= argw
;
949 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(TMP_REG3
));
952 /* Get the indexed version instead of the normal one. */
953 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
954 SLJIT_ASSERT(!(inst
& (ADDR_MODE2
| UPDATE_REQ
)));
955 FAIL_IF(load_immediate(compiler
, tmp_r
, argw
));
956 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
& 0xf) | B(tmp_r
));
959 static SLJIT_INLINE sljit_si
emit_op_mem2(struct sljit_compiler
*compiler
, sljit_si flags
, sljit_si reg
, sljit_si arg1
, sljit_sw arg1w
, sljit_si arg2
, sljit_sw arg2w
)
961 if (getput_arg_fast(compiler
, flags
, reg
, arg1
, arg1w
))
962 return compiler
->error
;
963 return getput_arg(compiler
, flags
, reg
, arg1
, arg1w
, arg2
, arg2w
);
966 static sljit_si
emit_op(struct sljit_compiler
*compiler
, sljit_si op
, sljit_si input_flags
,
967 sljit_si dst
, sljit_sw dstw
,
968 sljit_si src1
, sljit_sw src1w
,
969 sljit_si src2
, sljit_sw src2w
)
971 /* arg1 goes to TMP_REG1 or src reg
972 arg2 goes to TMP_REG2, imm or src reg
973 TMP_REG3 can be used for caching
974 result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
978 sljit_si sugg_src2_r
= TMP_REG2
;
979 sljit_si flags
= input_flags
& (ALT_FORM1
| ALT_FORM2
| ALT_FORM3
| ALT_FORM4
| ALT_FORM5
| ALT_FORM6
| ALT_SIGN_EXT
| ALT_SET_FLAGS
);
981 compiler
->cache_arg
= 0;
982 compiler
->cache_argw
= 0;
984 /* Destination check. */
985 if (dst
>= SLJIT_TEMPORARY_REG1
&& dst
<= ZERO_REG
) {
988 if (op
>= SLJIT_MOV
&& op
<= SLJIT_MOVU_SI
)
991 else if (dst
== SLJIT_UNUSED
) {
992 if (op
>= SLJIT_MOV
&& op
<= SLJIT_MOVU_SI
&& !(src2
& SLJIT_MEM
))
993 return SLJIT_SUCCESS
;
997 SLJIT_ASSERT(dst
& SLJIT_MEM
);
998 if (getput_arg_fast(compiler
, input_flags
| ARG_TEST
, TMP_REG2
, dst
, dstw
)) {
1009 if (src1
>= SLJIT_TEMPORARY_REG1
&& src1
<= ZERO_REG
) {
1011 flags
|= REG1_SOURCE
;
1013 else if (src1
& SLJIT_IMM
) {
1014 FAIL_IF(load_immediate(compiler
, TMP_REG1
, src1w
));
1017 else if (getput_arg_fast(compiler
, input_flags
| LOAD_DATA
, TMP_REG1
, src1
, src1w
)) {
1018 FAIL_IF(compiler
->error
);
1025 if (src2
>= SLJIT_TEMPORARY_REG1
&& src2
<= ZERO_REG
) {
1027 flags
|= REG2_SOURCE
;
1028 if (!(flags
& REG_DEST
) && op
>= SLJIT_MOV
&& op
<= SLJIT_MOVU_SI
)
1031 else if (src2
& SLJIT_IMM
) {
1032 FAIL_IF(load_immediate(compiler
, sugg_src2_r
, src2w
));
1033 src2_r
= sugg_src2_r
;
1035 else if (getput_arg_fast(compiler
, input_flags
| LOAD_DATA
, sugg_src2_r
, src2
, src2w
)) {
1036 FAIL_IF(compiler
->error
);
1037 src2_r
= sugg_src2_r
;
1042 /* src1_r, src2_r and dst_r can be zero (=unprocessed).
1043 All arguments are complex addressing modes, and it is a binary operator. */
1044 if (src1_r
== 0 && src2_r
== 0 && dst_r
== 0) {
1045 if (!can_cache(src1
, src1w
, src2
, src2w
) && can_cache(src1
, src1w
, dst
, dstw
)) {
1046 FAIL_IF(getput_arg(compiler
, input_flags
| LOAD_DATA
, TMP_REG2
, src2
, src2w
, src1
, src1w
));
1047 FAIL_IF(getput_arg(compiler
, input_flags
| LOAD_DATA
, TMP_REG1
, src1
, src1w
, dst
, dstw
));
1050 FAIL_IF(getput_arg(compiler
, input_flags
| LOAD_DATA
, TMP_REG1
, src1
, src1w
, src2
, src2w
));
1051 FAIL_IF(getput_arg(compiler
, input_flags
| LOAD_DATA
, TMP_REG2
, src2
, src2w
, dst
, dstw
));
1056 else if (src1_r
== 0 && src2_r
== 0) {
1057 FAIL_IF(getput_arg(compiler
, input_flags
| LOAD_DATA
, TMP_REG1
, src1
, src1w
, src2
, src2w
));
1060 else if (src1_r
== 0 && dst_r
== 0) {
1061 FAIL_IF(getput_arg(compiler
, input_flags
| LOAD_DATA
, TMP_REG1
, src1
, src1w
, dst
, dstw
));
1064 else if (src2_r
== 0 && dst_r
== 0) {
1065 FAIL_IF(getput_arg(compiler
, input_flags
| LOAD_DATA
, sugg_src2_r
, src2
, src2w
, dst
, dstw
));
1066 src2_r
= sugg_src2_r
;
1073 FAIL_IF(getput_arg(compiler
, input_flags
| LOAD_DATA
, TMP_REG1
, src1
, src1w
, 0, 0));
1078 FAIL_IF(getput_arg(compiler
, input_flags
| LOAD_DATA
, sugg_src2_r
, src2
, src2w
, 0, 0));
1079 src2_r
= sugg_src2_r
;
1082 FAIL_IF(emit_single_op(compiler
, op
, flags
, dst_r
, src1_r
, src2_r
));
1084 if (flags
& (FAST_DEST
| SLOW_DEST
)) {
1085 if (flags
& FAST_DEST
)
1086 FAIL_IF(getput_arg_fast(compiler
, input_flags
, dst_r
, dst
, dstw
));
1088 FAIL_IF(getput_arg(compiler
, input_flags
, dst_r
, dst
, dstw
, 0, 0));
1090 return SLJIT_SUCCESS
;
1093 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_op0(struct sljit_compiler
*compiler
, sljit_si op
)
1096 check_sljit_emit_op0(compiler
, op
);
1098 switch (GET_OPCODE(op
)) {
1099 case SLJIT_BREAKPOINT
:
1101 return push_inst(compiler
, NOP
);
1105 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_TEMPORARY_REG1
) | A(TMP_REG1
) | B(SLJIT_TEMPORARY_REG1
)));
1106 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1107 FAIL_IF(push_inst(compiler
, MULLD
| D(SLJIT_TEMPORARY_REG1
) | A(TMP_REG1
) | B(SLJIT_TEMPORARY_REG2
)));
1108 return push_inst(compiler
, (GET_OPCODE(op
) == SLJIT_UMUL
? MULHDU
: MULHD
) | D(SLJIT_TEMPORARY_REG2
) | A(TMP_REG1
) | B(SLJIT_TEMPORARY_REG2
));
1110 FAIL_IF(push_inst(compiler
, MULLW
| D(SLJIT_TEMPORARY_REG1
) | A(TMP_REG1
) | B(SLJIT_TEMPORARY_REG2
)));
1111 return push_inst(compiler
, (GET_OPCODE(op
) == SLJIT_UMUL
? MULHWU
: MULHW
) | D(SLJIT_TEMPORARY_REG2
) | A(TMP_REG1
) | B(SLJIT_TEMPORARY_REG2
));
1115 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_TEMPORARY_REG1
) | A(TMP_REG1
) | B(SLJIT_TEMPORARY_REG1
)));
1116 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1117 if (op
& SLJIT_INT_OP
) {
1118 FAIL_IF(push_inst(compiler
, (GET_OPCODE(op
) == SLJIT_UDIV
? DIVWU
: DIVW
) | D(SLJIT_TEMPORARY_REG1
) | A(TMP_REG1
) | B(SLJIT_TEMPORARY_REG2
)));
1119 FAIL_IF(push_inst(compiler
, MULLW
| D(SLJIT_TEMPORARY_REG2
) | A(SLJIT_TEMPORARY_REG1
) | B(SLJIT_TEMPORARY_REG2
)));
1120 return push_inst(compiler
, SUBF
| D(SLJIT_TEMPORARY_REG2
) | A(SLJIT_TEMPORARY_REG2
) | B(TMP_REG1
));
1122 FAIL_IF(push_inst(compiler
, (GET_OPCODE(op
) == SLJIT_UDIV
? DIVDU
: DIVD
) | D(SLJIT_TEMPORARY_REG1
) | A(TMP_REG1
) | B(SLJIT_TEMPORARY_REG2
)));
1123 FAIL_IF(push_inst(compiler
, MULLD
| D(SLJIT_TEMPORARY_REG2
) | A(SLJIT_TEMPORARY_REG1
) | B(SLJIT_TEMPORARY_REG2
)));
1124 return push_inst(compiler
, SUBF
| D(SLJIT_TEMPORARY_REG2
) | A(SLJIT_TEMPORARY_REG2
) | B(TMP_REG1
));
1126 FAIL_IF(push_inst(compiler
, (GET_OPCODE(op
) == SLJIT_UDIV
? DIVWU
: DIVW
) | D(SLJIT_TEMPORARY_REG1
) | A(TMP_REG1
) | B(SLJIT_TEMPORARY_REG2
)));
1127 FAIL_IF(push_inst(compiler
, MULLW
| D(SLJIT_TEMPORARY_REG2
) | A(SLJIT_TEMPORARY_REG1
) | B(SLJIT_TEMPORARY_REG2
)));
1128 return push_inst(compiler
, SUBF
| D(SLJIT_TEMPORARY_REG2
) | A(SLJIT_TEMPORARY_REG2
) | B(TMP_REG1
));
1132 return SLJIT_SUCCESS
;
1135 #define EMIT_MOV(type, type_flags, type_cast) \
1136 emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw)
1138 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_op1(struct sljit_compiler
*compiler
, sljit_si op
,
1139 sljit_si dst
, sljit_sw dstw
,
1140 sljit_si src
, sljit_sw srcw
)
1142 sljit_si flags
= GET_FLAGS(op
) ? ALT_SET_FLAGS
: 0;
1143 sljit_si op_flags
= GET_ALL_FLAGS(op
);
1146 check_sljit_emit_op1(compiler
, op
, dst
, dstw
, src
, srcw
);
1147 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1148 ADJUST_LOCAL_OFFSET(src
, srcw
);
1150 op
= GET_OPCODE(op
);
1151 if ((src
& SLJIT_IMM
) && srcw
== 0 && op
>= SLJIT_NOT
)
1154 if (op_flags
& SLJIT_SET_O
)
1155 FAIL_IF(push_inst(compiler
, MTXER
| S(ZERO_REG
)));
1157 if (op_flags
& SLJIT_INT_OP
) {
1158 if (op
>= SLJIT_MOV
&& op
<= SLJIT_MOVU_P
) {
1159 if (src
<= SLJIT_NO_REGISTERS
&& src
== dst
) {
1160 if (!TYPE_CAST_NEEDED(op
))
1161 return SLJIT_SUCCESS
;
1163 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1164 if (op
== SLJIT_MOV_SI
&& (src
& SLJIT_MEM
))
1166 if (op
== SLJIT_MOVU_SI
&& (src
& SLJIT_MEM
))
1168 if (op
== SLJIT_MOV_UI
&& (src
& SLJIT_IMM
))
1170 if (op
== SLJIT_MOVU_UI
&& (src
& SLJIT_IMM
))
1174 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1176 /* Most operations expect sign extended arguments. */
1177 flags
|= INT_DATA
| SIGNED_DATA
;
1178 if (src
& SLJIT_IMM
)
1179 srcw
= (sljit_si
)srcw
;
1187 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1191 return emit_op(compiler
, SLJIT_MOV
, flags
| WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1193 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1195 return EMIT_MOV(SLJIT_MOV_UI
, INT_DATA
, (sljit_ui
));
1198 return EMIT_MOV(SLJIT_MOV_SI
, INT_DATA
| SIGNED_DATA
, (sljit_si
));
1202 return EMIT_MOV(SLJIT_MOV_UB
, BYTE_DATA
, (sljit_ub
));
1205 return EMIT_MOV(SLJIT_MOV_SB
, BYTE_DATA
| SIGNED_DATA
, (sljit_sb
));
1208 return EMIT_MOV(SLJIT_MOV_UH
, HALF_DATA
, (sljit_uh
));
1211 return EMIT_MOV(SLJIT_MOV_SH
, HALF_DATA
| SIGNED_DATA
, (sljit_sh
));
1215 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1219 return emit_op(compiler
, SLJIT_MOV
, flags
| WORD_DATA
| WRITE_BACK
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1221 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1223 return EMIT_MOV(SLJIT_MOV_UI
, INT_DATA
| WRITE_BACK
, (sljit_ui
));
1226 return EMIT_MOV(SLJIT_MOV_SI
, INT_DATA
| SIGNED_DATA
| WRITE_BACK
, (sljit_si
));
1230 return EMIT_MOV(SLJIT_MOV_UB
, BYTE_DATA
| WRITE_BACK
, (sljit_ub
));
1233 return EMIT_MOV(SLJIT_MOV_SB
, BYTE_DATA
| SIGNED_DATA
| WRITE_BACK
, (sljit_sb
));
1236 return EMIT_MOV(SLJIT_MOV_UH
, HALF_DATA
| WRITE_BACK
, (sljit_uh
));
1239 return EMIT_MOV(SLJIT_MOV_SH
, HALF_DATA
| SIGNED_DATA
| WRITE_BACK
, (sljit_sh
));
1242 return emit_op(compiler
, SLJIT_NOT
, flags
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1245 return emit_op(compiler
, SLJIT_NEG
, flags
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1248 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1249 return emit_op(compiler
, SLJIT_CLZ
, flags
| (!(op_flags
& SLJIT_INT_OP
) ? 0 : ALT_FORM1
), dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1251 return emit_op(compiler
, SLJIT_CLZ
, flags
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1255 return SLJIT_SUCCESS
;
1260 #define TEST_SL_IMM(src, srcw) \
1261 (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)
1263 #define TEST_UL_IMM(src, srcw) \
1264 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff))
1266 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1267 #define TEST_SH_IMM(src, srcw) \
1268 (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= SLJIT_W(0x7fffffff) && (srcw) >= SLJIT_W(-0x80000000))
1270 #define TEST_SH_IMM(src, srcw) \
1271 (((src) & SLJIT_IMM) && !((srcw) & 0xffff))
1274 #define TEST_UH_IMM(src, srcw) \
1275 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000))
1277 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1278 #define TEST_ADD_IMM(src, srcw) \
1279 (((src) & SLJIT_IMM) && (srcw) <= SLJIT_W(0x7fff7fff) && (srcw) >= SLJIT_W(-0x80000000))
1281 #define TEST_ADD_IMM(src, srcw) \
1285 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1286 #define TEST_UI_IMM(src, srcw) \
1287 (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
1289 #define TEST_UI_IMM(src, srcw) \
1293 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_op2(struct sljit_compiler
*compiler
, sljit_si op
,
1294 sljit_si dst
, sljit_sw dstw
,
1295 sljit_si src1
, sljit_sw src1w
,
1296 sljit_si src2
, sljit_sw src2w
)
1298 sljit_si flags
= GET_FLAGS(op
) ? ALT_SET_FLAGS
: 0;
1301 check_sljit_emit_op2(compiler
, op
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1302 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1303 ADJUST_LOCAL_OFFSET(src1
, src1w
);
1304 ADJUST_LOCAL_OFFSET(src2
, src2w
);
1306 if ((src1
& SLJIT_IMM
) && src1w
== 0)
1308 if ((src2
& SLJIT_IMM
) && src2w
== 0)
1311 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1312 if (op
& SLJIT_INT_OP
) {
1313 /* Most operations expect sign extended arguments. */
1314 flags
|= INT_DATA
| SIGNED_DATA
;
1315 if (src1
& SLJIT_IMM
)
1316 src1w
= (sljit_si
)(src1w
);
1317 if (src2
& SLJIT_IMM
)
1318 src2w
= (sljit_si
)(src2w
);
1320 flags
|= ALT_SIGN_EXT
;
1323 if (op
& SLJIT_SET_O
)
1324 FAIL_IF(push_inst(compiler
, MTXER
| S(ZERO_REG
)));
1326 switch (GET_OPCODE(op
)) {
1328 if (!GET_FLAGS(op
) && ((src1
| src2
) & SLJIT_IMM
)) {
1329 if (TEST_SL_IMM(src2
, src2w
)) {
1330 compiler
->imm
= src2w
& 0xffff;
1331 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1333 if (TEST_SL_IMM(src1
, src1w
)) {
1334 compiler
->imm
= src1w
& 0xffff;
1335 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM1
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1337 if (TEST_SH_IMM(src2
, src2w
)) {
1338 compiler
->imm
= (src2w
>> 16) & 0xffff;
1339 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1341 if (TEST_SH_IMM(src1
, src1w
)) {
1342 compiler
->imm
= (src1w
>> 16) & 0xffff;
1343 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1345 /* Range between -1 and -32768 is covered above. */
1346 if (TEST_ADD_IMM(src2
, src2w
)) {
1347 compiler
->imm
= src2w
& 0xffffffff;
1348 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1350 if (TEST_ADD_IMM(src1
, src1w
)) {
1351 compiler
->imm
= src1w
& 0xffffffff;
1352 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM4
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1355 if (!(GET_FLAGS(op
) & (SLJIT_SET_E
| SLJIT_SET_O
))) {
1356 if (TEST_SL_IMM(src2
, src2w
)) {
1357 compiler
->imm
= src2w
& 0xffff;
1358 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1360 if (TEST_SL_IMM(src1
, src1w
)) {
1361 compiler
->imm
= src1w
& 0xffff;
1362 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM3
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1365 return emit_op(compiler
, SLJIT_ADD
, flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1368 return emit_op(compiler
, SLJIT_ADDC
, flags
| (!(op
& SLJIT_KEEP_FLAGS
) ? 0 : ALT_FORM1
), dst
, dstw
, src1
, src1w
, src2
, src2w
);
1371 if (!GET_FLAGS(op
) && ((src1
| src2
) & SLJIT_IMM
)) {
1372 if (TEST_SL_IMM(src2
, -src2w
)) {
1373 compiler
->imm
= (-src2w
) & 0xffff;
1374 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1376 if (TEST_SL_IMM(src1
, src1w
)) {
1377 compiler
->imm
= src1w
& 0xffff;
1378 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM1
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1380 if (TEST_SH_IMM(src2
, -src2w
)) {
1381 compiler
->imm
= ((-src2w
) >> 16) & 0xffff;
1382 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1384 /* Range between -1 and -32768 is covered above. */
1385 if (TEST_ADD_IMM(src2
, -src2w
)) {
1386 compiler
->imm
= -src2w
& 0xffffffff;
1387 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1390 if (dst
== SLJIT_UNUSED
&& (op
& (SLJIT_SET_E
| SLJIT_SET_S
| SLJIT_SET_U
)) && !(op
& (SLJIT_SET_O
| SLJIT_SET_C
))) {
1391 if (!(op
& SLJIT_SET_U
)) {
1392 /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
1393 if (TEST_SL_IMM(src2
, src2w
)) {
1394 compiler
->imm
= src2w
& 0xffff;
1395 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1397 if (GET_FLAGS(op
) == SLJIT_SET_E
&& TEST_SL_IMM(src1
, src1w
)) {
1398 compiler
->imm
= src1w
& 0xffff;
1399 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1402 if (!(op
& (SLJIT_SET_E
| SLJIT_SET_S
))) {
1403 /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
1404 if (TEST_UL_IMM(src2
, src2w
)) {
1405 compiler
->imm
= src2w
& 0xffff;
1406 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1408 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1410 if ((src2
& SLJIT_IMM
) && src2w
>= 0 && src2w
<= 0x7fff) {
1411 compiler
->imm
= src2w
;
1412 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1414 return emit_op(compiler
, SLJIT_SUB
, flags
| ((op
& SLJIT_SET_U
) ? ALT_FORM4
: 0) | ((op
& (SLJIT_SET_E
| SLJIT_SET_S
)) ? ALT_FORM5
: 0), dst
, dstw
, src1
, src1w
, src2
, src2w
);
1416 if (!(op
& (SLJIT_SET_E
| SLJIT_SET_S
| SLJIT_SET_U
| SLJIT_SET_O
))) {
1417 if (TEST_SL_IMM(src2
, -src2w
)) {
1418 compiler
->imm
= (-src2w
) & 0xffff;
1419 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1422 /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
1423 return emit_op(compiler
, SLJIT_SUB
, flags
| (!(op
& SLJIT_SET_U
) ? 0 : ALT_FORM6
), dst
, dstw
, src1
, src1w
, src2
, src2w
);
1426 return emit_op(compiler
, SLJIT_SUBC
, flags
| (!(op
& SLJIT_KEEP_FLAGS
) ? 0 : ALT_FORM1
), dst
, dstw
, src1
, src1w
, src2
, src2w
);
1429 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1430 if (op
& SLJIT_INT_OP
)
1433 if (!GET_FLAGS(op
)) {
1434 if (TEST_SL_IMM(src2
, src2w
)) {
1435 compiler
->imm
= src2w
& 0xffff;
1436 return emit_op(compiler
, SLJIT_MUL
, flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1438 if (TEST_SL_IMM(src1
, src1w
)) {
1439 compiler
->imm
= src1w
& 0xffff;
1440 return emit_op(compiler
, SLJIT_MUL
, flags
| ALT_FORM1
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1443 return emit_op(compiler
, SLJIT_MUL
, flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1448 /* Commutative unsigned operations. */
1449 if (!GET_FLAGS(op
) || GET_OPCODE(op
) == SLJIT_AND
) {
1450 if (TEST_UL_IMM(src2
, src2w
)) {
1451 compiler
->imm
= src2w
;
1452 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1454 if (TEST_UL_IMM(src1
, src1w
)) {
1455 compiler
->imm
= src1w
;
1456 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM1
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1458 if (TEST_UH_IMM(src2
, src2w
)) {
1459 compiler
->imm
= (src2w
>> 16) & 0xffff;
1460 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1462 if (TEST_UH_IMM(src1
, src1w
)) {
1463 compiler
->imm
= (src1w
>> 16) & 0xffff;
1464 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM2
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1467 if (!GET_FLAGS(op
) && GET_OPCODE(op
) != SLJIT_AND
) {
1468 if (TEST_UI_IMM(src2
, src2w
)) {
1469 compiler
->imm
= src2w
;
1470 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1472 if (TEST_UI_IMM(src1
, src1w
)) {
1473 compiler
->imm
= src1w
;
1474 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM3
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1477 return emit_op(compiler
, GET_OPCODE(op
), flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1480 if (op
& SLJIT_KEEP_FLAGS
)
1485 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1486 if (op
& SLJIT_INT_OP
)
1489 if (src2
& SLJIT_IMM
) {
1490 compiler
->imm
= src2w
;
1491 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1493 return emit_op(compiler
, GET_OPCODE(op
), flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1496 return SLJIT_SUCCESS
;
1499 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_get_register_index(sljit_si reg
)
1501 check_sljit_get_register_index(reg
);
1502 return reg_map
[reg
];
1505 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_op_custom(struct sljit_compiler
*compiler
,
1506 void *instruction
, sljit_si size
)
1509 check_sljit_emit_op_custom(compiler
, instruction
, size
);
1510 SLJIT_ASSERT(size
== 4);
1512 return push_inst(compiler
, *(sljit_ins
*)instruction
);
1515 /* --------------------------------------------------------------------- */
1516 /* Floating point operators */
1517 /* --------------------------------------------------------------------- */
1519 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_is_fpu_available(void)
1521 /* Always available. */
1525 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 6))
1526 #define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double)
1528 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_fop1(struct sljit_compiler
*compiler
, sljit_si op
,
1529 sljit_si dst
, sljit_sw dstw
,
1530 sljit_si src
, sljit_sw srcw
)
1535 check_sljit_emit_fop1(compiler
, op
, dst
, dstw
, src
, srcw
);
1536 SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP
== 0x100) && !(DOUBLE_DATA
& 0x4), float_transfer_bit_error
);
1538 compiler
->cache_arg
= 0;
1539 compiler
->cache_argw
= 0;
1541 if (GET_OPCODE(op
) == SLJIT_CMPD
) {
1542 if (dst
> SLJIT_FLOAT_REG6
) {
1543 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, dst
, dstw
, src
, srcw
));
1547 if (src
> SLJIT_FLOAT_REG6
) {
1548 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG2
, src
, srcw
, 0, 0));
1552 return push_inst(compiler
, FCMPU
| CRD(4) | FA(dst
) | FB(src
));
1555 dst_fr
= (dst
> SLJIT_FLOAT_REG6
) ? TMP_FREG1
: dst
;
1557 if (src
> SLJIT_FLOAT_REG6
) {
1558 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, dst_fr
, src
, srcw
, dst
, dstw
));
1562 switch (GET_OPCODE(op
)) {
1564 if (src
!= dst_fr
&& dst_fr
!= TMP_FREG1
)
1565 FAIL_IF(push_inst(compiler
, FMR
| FD(dst_fr
) | FB(src
)));
1568 FAIL_IF(push_inst(compiler
, FNEG
| FD(dst_fr
) | FB(src
)));
1571 FAIL_IF(push_inst(compiler
, FABS
| FD(dst_fr
) | FB(src
)));
1575 if (dst_fr
== TMP_FREG1
) {
1576 if (GET_OPCODE(op
) == SLJIT_MOVD
)
1578 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
), dst_fr
, dst
, dstw
, 0, 0));
1581 return SLJIT_SUCCESS
;
1584 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_fop2(struct sljit_compiler
*compiler
, sljit_si op
,
1585 sljit_si dst
, sljit_sw dstw
,
1586 sljit_si src1
, sljit_sw src1w
,
1587 sljit_si src2
, sljit_sw src2w
)
1589 sljit_si dst_fr
, flags
= 0;
1592 check_sljit_emit_fop2(compiler
, op
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1594 compiler
->cache_arg
= 0;
1595 compiler
->cache_argw
= 0;
1597 dst_fr
= (dst
> SLJIT_FLOAT_REG6
) ? TMP_FREG2
: dst
;
1599 if (src1
> SLJIT_FLOAT_REG6
) {
1600 if (getput_arg_fast(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, src1
, src1w
)) {
1601 FAIL_IF(compiler
->error
);
1607 if (src2
> SLJIT_FLOAT_REG6
) {
1608 if (getput_arg_fast(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG2
, src2
, src2w
)) {
1609 FAIL_IF(compiler
->error
);
1615 if ((flags
& (ALT_FORM1
| ALT_FORM2
)) == (ALT_FORM1
| ALT_FORM2
)) {
1616 if (!can_cache(src1
, src1w
, src2
, src2w
) && can_cache(src1
, src1w
, dst
, dstw
)) {
1617 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG2
, src2
, src2w
, src1
, src1w
));
1618 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, src1
, src1w
, dst
, dstw
));
1621 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, src1
, src1w
, src2
, src2w
));
1622 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG2
, src2
, src2w
, dst
, dstw
));
1625 else if (flags
& ALT_FORM1
)
1626 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, src1
, src1w
, dst
, dstw
));
1627 else if (flags
& ALT_FORM2
)
1628 FAIL_IF(getput_arg(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG2
, src2
, src2w
, dst
, dstw
));
1630 if (flags
& ALT_FORM1
)
1632 if (flags
& ALT_FORM2
)
1635 switch (GET_OPCODE(op
)) {
1637 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FADDS
, FADD
) | FD(dst_fr
) | FA(src1
) | FB(src2
)));
1641 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FSUBS
, FSUB
) | FD(dst_fr
) | FA(src1
) | FB(src2
)));
1645 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FMULS
, FMUL
) | FD(dst_fr
) | FA(src1
) | FC(src2
) /* FMUL use FC as src2 */));
1649 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FDIVS
, FDIV
) | FD(dst_fr
) | FA(src1
) | FB(src2
)));
1653 if (dst_fr
== TMP_FREG2
)
1654 FAIL_IF(emit_op_mem2(compiler
, FLOAT_DATA(op
), TMP_FREG2
, dst
, dstw
, 0, 0));
1656 return SLJIT_SUCCESS
;
1662 /* --------------------------------------------------------------------- */
1663 /* Other instructions */
1664 /* --------------------------------------------------------------------- */
1666 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_fast_enter(struct sljit_compiler
*compiler
, sljit_si dst
, sljit_sw dstw
)
1669 check_sljit_emit_fast_enter(compiler
, dst
, dstw
);
1670 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1672 if (dst
>= SLJIT_TEMPORARY_REG1
&& dst
<= SLJIT_NO_REGISTERS
)
1673 return push_inst(compiler
, MFLR
| D(dst
));
1674 else if (dst
& SLJIT_MEM
) {
1675 FAIL_IF(push_inst(compiler
, MFLR
| D(TMP_REG2
)));
1676 return emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0);
1679 /* SLJIT_UNUSED is also possible, although highly unlikely. */
1680 return SLJIT_SUCCESS
;
1683 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_fast_return(struct sljit_compiler
*compiler
, sljit_si src
, sljit_sw srcw
)
1686 check_sljit_emit_fast_return(compiler
, src
, srcw
);
1687 ADJUST_LOCAL_OFFSET(src
, srcw
);
1689 if (src
>= SLJIT_TEMPORARY_REG1
&& src
<= SLJIT_NO_REGISTERS
)
1690 FAIL_IF(push_inst(compiler
, MTLR
| S(src
)));
1692 if (src
& SLJIT_MEM
)
1693 FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, TMP_REG2
, 0, TMP_REG1
, 0, src
, srcw
));
1694 else if (src
& SLJIT_IMM
)
1695 FAIL_IF(load_immediate(compiler
, TMP_REG2
, srcw
));
1696 FAIL_IF(push_inst(compiler
, MTLR
| S(TMP_REG2
)));
1698 return push_inst(compiler
, BLR
);
1701 /* --------------------------------------------------------------------- */
1702 /* Conditional instructions */
1703 /* --------------------------------------------------------------------- */
1705 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_label
* sljit_emit_label(struct sljit_compiler
*compiler
)
1707 struct sljit_label
*label
;
1710 check_sljit_emit_label(compiler
);
1712 if (compiler
->last_label
&& compiler
->last_label
->size
== compiler
->size
)
1713 return compiler
->last_label
;
1715 label
= (struct sljit_label
*)ensure_abuf(compiler
, sizeof(struct sljit_label
));
1716 PTR_FAIL_IF(!label
);
1717 set_label(label
, compiler
);
1721 static sljit_ins
get_bo_bi_flags(sljit_si type
)
1725 return (12 << 21) | (2 << 16);
1727 case SLJIT_C_NOT_EQUAL
:
1728 return (4 << 21) | (2 << 16);
1731 case SLJIT_C_FLOAT_LESS
:
1732 return (12 << 21) | ((4 + 0) << 16);
1734 case SLJIT_C_GREATER_EQUAL
:
1735 case SLJIT_C_FLOAT_GREATER_EQUAL
:
1736 return (4 << 21) | ((4 + 0) << 16);
1738 case SLJIT_C_GREATER
:
1739 case SLJIT_C_FLOAT_GREATER
:
1740 return (12 << 21) | ((4 + 1) << 16);
1742 case SLJIT_C_LESS_EQUAL
:
1743 case SLJIT_C_FLOAT_LESS_EQUAL
:
1744 return (4 << 21) | ((4 + 1) << 16);
1746 case SLJIT_C_SIG_LESS
:
1747 return (12 << 21) | (0 << 16);
1749 case SLJIT_C_SIG_GREATER_EQUAL
:
1750 return (4 << 21) | (0 << 16);
1752 case SLJIT_C_SIG_GREATER
:
1753 return (12 << 21) | (1 << 16);
1755 case SLJIT_C_SIG_LESS_EQUAL
:
1756 return (4 << 21) | (1 << 16);
1758 case SLJIT_C_OVERFLOW
:
1759 case SLJIT_C_MUL_OVERFLOW
:
1760 return (12 << 21) | (3 << 16);
1762 case SLJIT_C_NOT_OVERFLOW
:
1763 case SLJIT_C_MUL_NOT_OVERFLOW
:
1764 return (4 << 21) | (3 << 16);
1766 case SLJIT_C_FLOAT_EQUAL
:
1767 return (12 << 21) | ((4 + 2) << 16);
1769 case SLJIT_C_FLOAT_NOT_EQUAL
:
1770 return (4 << 21) | ((4 + 2) << 16);
1772 case SLJIT_C_FLOAT_UNORDERED
:
1773 return (12 << 21) | ((4 + 3) << 16);
1775 case SLJIT_C_FLOAT_ORDERED
:
1776 return (4 << 21) | ((4 + 3) << 16);
1779 SLJIT_ASSERT(type
>= SLJIT_JUMP
&& type
<= SLJIT_CALL3
);
1784 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_jump(struct sljit_compiler
*compiler
, sljit_si type
)
1786 struct sljit_jump
*jump
;
1787 sljit_ins bo_bi_flags
;
1790 check_sljit_emit_jump(compiler
, type
);
1792 bo_bi_flags
= get_bo_bi_flags(type
& 0xff);
1796 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
1798 set_jump(jump
, compiler
, type
& SLJIT_REWRITABLE_JUMP
);
1801 /* In PPC, we don't need to touch the arguments. */
1802 if (type
>= SLJIT_JUMP
)
1803 jump
->flags
|= UNCOND_B
;
1805 PTR_FAIL_IF(emit_const(compiler
, TMP_REG1
, 0));
1806 PTR_FAIL_IF(push_inst(compiler
, MTCTR
| S(TMP_REG1
)));
1807 jump
->addr
= compiler
->size
;
1808 PTR_FAIL_IF(push_inst(compiler
, BCCTR
| bo_bi_flags
| (type
>= SLJIT_FAST_CALL
? 1 : 0)));
1812 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_ijump(struct sljit_compiler
*compiler
, sljit_si type
, sljit_si src
, sljit_sw srcw
)
1814 struct sljit_jump
*jump
= NULL
;
1818 check_sljit_emit_ijump(compiler
, type
, src
, srcw
);
1819 ADJUST_LOCAL_OFFSET(src
, srcw
);
1821 if (src
>= SLJIT_TEMPORARY_REG1
&& src
<= SLJIT_NO_REGISTERS
)
1823 else if (src
& SLJIT_IMM
) {
1824 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
1826 set_jump(jump
, compiler
, JUMP_ADDR
| UNCOND_B
);
1827 jump
->u
.target
= srcw
;
1829 FAIL_IF(emit_const(compiler
, TMP_REG2
, 0));
1833 FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, TMP_REG2
, 0, TMP_REG1
, 0, src
, srcw
));
1837 FAIL_IF(push_inst(compiler
, MTCTR
| S(src_r
)));
1839 jump
->addr
= compiler
->size
;
1840 return push_inst(compiler
, BCCTR
| (20 << 21) | (type
>= SLJIT_FAST_CALL
? 1 : 0));
1843 /* Get a bit from CR, all other bits are zeroed. */
1844 #define GET_CR_BIT(bit, dst) \
1845 FAIL_IF(push_inst(compiler, MFCR | D(dst))); \
1846 FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | ((1 + (bit)) << 11) | (31 << 6) | (31 << 1)));
1848 #define INVERT_BIT(dst) \
1849 FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1));
1851 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_cond_value(struct sljit_compiler
*compiler
, sljit_si op
, sljit_si dst
, sljit_sw dstw
, sljit_si type
)
1853 sljit_si reg
, flags
= GET_ALL_FLAGS(op
);
1856 check_sljit_emit_cond_value(compiler
, op
, dst
, dstw
, type
);
1857 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1859 if (dst
== SLJIT_UNUSED
)
1860 return SLJIT_SUCCESS
;
1862 op
= GET_OPCODE(op
);
1863 reg
= (op
< SLJIT_ADD
&& dst
>= SLJIT_TEMPORARY_REG1
&& dst
<= SLJIT_NO_REGISTERS
) ? dst
: TMP_REG2
;
1870 case SLJIT_C_NOT_EQUAL
:
1876 case SLJIT_C_FLOAT_LESS
:
1877 GET_CR_BIT(4 + 0, reg
);
1880 case SLJIT_C_GREATER_EQUAL
:
1881 case SLJIT_C_FLOAT_GREATER_EQUAL
:
1882 GET_CR_BIT(4 + 0, reg
);
1886 case SLJIT_C_GREATER
:
1887 case SLJIT_C_FLOAT_GREATER
:
1888 GET_CR_BIT(4 + 1, reg
);
1891 case SLJIT_C_LESS_EQUAL
:
1892 case SLJIT_C_FLOAT_LESS_EQUAL
:
1893 GET_CR_BIT(4 + 1, reg
);
1897 case SLJIT_C_SIG_LESS
:
1901 case SLJIT_C_SIG_GREATER_EQUAL
:
1906 case SLJIT_C_SIG_GREATER
:
1910 case SLJIT_C_SIG_LESS_EQUAL
:
1915 case SLJIT_C_OVERFLOW
:
1916 case SLJIT_C_MUL_OVERFLOW
:
1920 case SLJIT_C_NOT_OVERFLOW
:
1921 case SLJIT_C_MUL_NOT_OVERFLOW
:
1926 case SLJIT_C_FLOAT_EQUAL
:
1927 GET_CR_BIT(4 + 2, reg
);
1930 case SLJIT_C_FLOAT_NOT_EQUAL
:
1931 GET_CR_BIT(4 + 2, reg
);
1935 case SLJIT_C_FLOAT_UNORDERED
:
1936 GET_CR_BIT(4 + 3, reg
);
1939 case SLJIT_C_FLOAT_ORDERED
:
1940 GET_CR_BIT(4 + 3, reg
);
1945 SLJIT_ASSERT_STOP();
1949 if (op
< SLJIT_ADD
) {
1950 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1951 if (op
== SLJIT_MOV
)
1961 return (reg
== TMP_REG2
) ? emit_op(compiler
, op
, flags
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0) : SLJIT_SUCCESS
;
1964 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1965 compiler
->skip_checks
= 1;
1967 return sljit_emit_op2(compiler
, op
| flags
, dst
, dstw
, dst
, dstw
, TMP_REG2
, 0);
1970 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_const
* sljit_emit_const(struct sljit_compiler
*compiler
, sljit_si dst
, sljit_sw dstw
, sljit_sw init_value
)
1972 struct sljit_const
*const_
;
1976 check_sljit_emit_const(compiler
, dst
, dstw
, init_value
);
1977 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1979 const_
= (struct sljit_const
*)ensure_abuf(compiler
, sizeof(struct sljit_const
));
1980 PTR_FAIL_IF(!const_
);
1981 set_const(const_
, compiler
);
1983 reg
= (dst
>= SLJIT_TEMPORARY_REG1
&& dst
<= SLJIT_NO_REGISTERS
) ? dst
: TMP_REG2
;
1985 PTR_FAIL_IF(emit_const(compiler
, reg
, init_value
));
1987 if (dst
& SLJIT_MEM
)
1988 PTR_FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0));