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 SLJIT_API_FUNC_ATTRIBUTE
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_u32 sljit_ins
;
36 #if ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && (defined _AIX)) \
37 || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
38 #define SLJIT_PPC_STACK_FRAME_V2 1
42 #include <sys/cache.h>
45 #if (defined _CALL_ELF && _CALL_ELF == 2)
46 #define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1
49 #if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL)
51 static void ppc_cache_flush(sljit_ins
*from
, sljit_ins
*to
)
54 _sync_cache_range((caddr_t
)from
, (int)((size_t)to
- (size_t)from
));
55 #elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
56 # if defined(_ARCH_PWR) || defined(_ARCH_PWR2)
57 /* Cache flush for POWER architecture. */
66 __asm__
volatile ( "ics" );
67 # elif defined(_ARCH_COM) && !defined(_ARCH_PPC)
68 # error "Cache flush is not implemented for PowerPC/POWER common mode."
70 /* Cache flush for PowerPC architecture. */
80 __asm__
volatile ( "isync" );
83 # warning "This file may fail to compile if -qfuncsect is used"
85 #elif defined(__xlc__)
86 #error "Please enable GCC syntax for inline assembly statements with -qasm=gcc"
88 #error "This platform requires a cache flush implementation."
92 #endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */
94 #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
95 #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
96 #define TMP_ZERO (SLJIT_NUMBER_OF_REGISTERS + 4)
98 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
99 #define TMP_CALL_REG (SLJIT_NUMBER_OF_REGISTERS + 5)
101 #define TMP_CALL_REG TMP_REG2
104 #define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
105 #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
107 static const sljit_u8 reg_map
[SLJIT_NUMBER_OF_REGISTERS
+ 7] = {
108 0, 3, 4, 5, 6, 7, 8, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 9, 10, 31, 12
111 static const sljit_u8 freg_map
[SLJIT_NUMBER_OF_FLOAT_REGISTERS
+ 3] = {
112 0, 1, 2, 3, 4, 5, 6, 0, 7
115 /* --------------------------------------------------------------------- */
116 /* Instrucion forms */
117 /* --------------------------------------------------------------------- */
118 #define D(d) (reg_map[d] << 21)
119 #define S(s) (reg_map[s] << 21)
120 #define A(a) (reg_map[a] << 16)
121 #define B(b) (reg_map[b] << 11)
122 #define C(c) (reg_map[c] << 6)
123 #define FD(fd) (freg_map[fd] << 21)
124 #define FS(fs) (freg_map[fs] << 21)
125 #define FA(fa) (freg_map[fa] << 16)
126 #define FB(fb) (freg_map[fb] << 11)
127 #define FC(fc) (freg_map[fc] << 6)
128 #define IMM(imm) ((imm) & 0xffff)
129 #define CRD(d) ((d) << 21)
131 /* Instruction bit sections.
132 OE and Rc flag (see ALT_SET_FLAGS). */
133 #define OE(flags) ((flags) & ALT_SET_FLAGS)
134 /* Rc flag (see ALT_SET_FLAGS). */
135 #define RC(flags) (((flags) & ALT_SET_FLAGS) >> 10)
136 #define HI(opcode) ((opcode) << 26)
137 #define LO(opcode) ((opcode) << 1)
139 #define ADD (HI(31) | LO(266))
140 #define ADDC (HI(31) | LO(10))
141 #define ADDE (HI(31) | LO(138))
142 #define ADDI (HI(14))
143 #define ADDIC (HI(13))
144 #define ADDIS (HI(15))
145 #define ADDME (HI(31) | LO(234))
146 #define AND (HI(31) | LO(28))
147 #define ANDI (HI(28))
148 #define ANDIS (HI(29))
151 #define BCCTR (HI(19) | LO(528) | (3 << 11))
152 #define BLR (HI(19) | LO(16) | (0x14 << 21))
153 #define CNTLZD (HI(31) | LO(58))
154 #define CNTLZW (HI(31) | LO(26))
155 #define CMP (HI(31) | LO(0))
156 #define CMPI (HI(11))
157 #define CMPL (HI(31) | LO(32))
158 #define CMPLI (HI(10))
159 #define CROR (HI(19) | LO(449))
160 #define DCBT (HI(31) | LO(278))
161 #define DIVD (HI(31) | LO(489))
162 #define DIVDU (HI(31) | LO(457))
163 #define DIVW (HI(31) | LO(491))
164 #define DIVWU (HI(31) | LO(459))
165 #define EXTSB (HI(31) | LO(954))
166 #define EXTSH (HI(31) | LO(922))
167 #define EXTSW (HI(31) | LO(986))
168 #define FABS (HI(63) | LO(264))
169 #define FADD (HI(63) | LO(21))
170 #define FADDS (HI(59) | LO(21))
171 #define FCFID (HI(63) | LO(846))
172 #define FCMPU (HI(63) | LO(0))
173 #define FCTIDZ (HI(63) | LO(815))
174 #define FCTIWZ (HI(63) | LO(15))
175 #define FDIV (HI(63) | LO(18))
176 #define FDIVS (HI(59) | LO(18))
177 #define FMR (HI(63) | LO(72))
178 #define FMUL (HI(63) | LO(25))
179 #define FMULS (HI(59) | LO(25))
180 #define FNEG (HI(63) | LO(40))
181 #define FRSP (HI(63) | LO(12))
182 #define FSUB (HI(63) | LO(20))
183 #define FSUBS (HI(59) | LO(20))
184 #define LD (HI(58) | 0)
186 #define MFCR (HI(31) | LO(19))
187 #define MFLR (HI(31) | LO(339) | 0x80000)
188 #define MFXER (HI(31) | LO(339) | 0x10000)
189 #define MTCTR (HI(31) | LO(467) | 0x90000)
190 #define MTLR (HI(31) | LO(467) | 0x80000)
191 #define MTXER (HI(31) | LO(467) | 0x10000)
192 #define MULHD (HI(31) | LO(73))
193 #define MULHDU (HI(31) | LO(9))
194 #define MULHW (HI(31) | LO(75))
195 #define MULHWU (HI(31) | LO(11))
196 #define MULLD (HI(31) | LO(233))
197 #define MULLI (HI(7))
198 #define MULLW (HI(31) | LO(235))
199 #define NEG (HI(31) | LO(104))
201 #define NOR (HI(31) | LO(124))
202 #define OR (HI(31) | LO(444))
204 #define ORIS (HI(25))
205 #define RLDICL (HI(30))
206 #define RLWINM (HI(21))
207 #define SLD (HI(31) | LO(27))
208 #define SLW (HI(31) | LO(24))
209 #define SRAD (HI(31) | LO(794))
210 #define SRADI (HI(31) | LO(413 << 1))
211 #define SRAW (HI(31) | LO(792))
212 #define SRAWI (HI(31) | LO(824))
213 #define SRD (HI(31) | LO(539))
214 #define SRW (HI(31) | LO(536))
215 #define STD (HI(62) | 0)
216 #define STDU (HI(62) | 1)
217 #define STDUX (HI(31) | LO(181))
218 #define STFIWX (HI(31) | LO(983))
220 #define STWU (HI(37))
221 #define STWUX (HI(31) | LO(183))
222 #define SUBF (HI(31) | LO(40))
223 #define SUBFC (HI(31) | LO(8))
224 #define SUBFE (HI(31) | LO(136))
225 #define SUBFIC (HI(8))
226 #define XOR (HI(31) | LO(316))
227 #define XORI (HI(26))
228 #define XORIS (HI(27))
230 #define SIMM_MAX (0x7fff)
231 #define SIMM_MIN (-0x8000)
232 #define UIMM_MAX (0xffff)
234 #define RLDI(dst, src, sh, mb, type) \
235 (HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20))
237 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
238 SLJIT_API_FUNC_ATTRIBUTE
void sljit_set_function_context(void** func_ptr
, struct sljit_function_context
* context
, sljit_sw addr
, void* func
)
242 *func_ptr
= (void*)context
;
243 ptrs
= (sljit_sw
*)func
;
244 context
->addr
= addr
? addr
: ptrs
[0];
245 context
->r2
= ptrs
[1];
246 context
->r11
= ptrs
[2];
250 static sljit_s32
push_inst(struct sljit_compiler
*compiler
, sljit_ins ins
)
252 sljit_ins
*ptr
= (sljit_ins
*)ensure_buf(compiler
, sizeof(sljit_ins
));
256 return SLJIT_SUCCESS
;
259 static SLJIT_INLINE sljit_s32
detect_jump_type(struct sljit_jump
*jump
, sljit_ins
*code_ptr
, sljit_ins
*code
, sljit_sw executable_offset
)
262 sljit_uw target_addr
;
263 sljit_sw extra_jump_flags
;
265 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
266 if (jump
->flags
& (SLJIT_REWRITABLE_JUMP
| IS_CALL
))
269 if (jump
->flags
& SLJIT_REWRITABLE_JUMP
)
273 if (jump
->flags
& JUMP_ADDR
)
274 target_addr
= jump
->u
.target
;
276 SLJIT_ASSERT(jump
->flags
& JUMP_LABEL
);
277 target_addr
= (sljit_uw
)(code
+ jump
->u
.label
->size
) + (sljit_uw
)executable_offset
;
280 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
281 if (jump
->flags
& IS_CALL
)
285 diff
= ((sljit_sw
)target_addr
- (sljit_sw
)(code_ptr
) - executable_offset
) & ~0x3l
;
287 extra_jump_flags
= 0;
288 if (jump
->flags
& IS_COND
) {
289 if (diff
<= 0x7fff && diff
>= -0x8000) {
290 jump
->flags
|= PATCH_B
;
293 if (target_addr
<= 0xffff) {
294 jump
->flags
|= PATCH_B
| PATCH_ABS_B
;
297 extra_jump_flags
= REMOVE_COND
;
299 diff
-= sizeof(sljit_ins
);
302 if (diff
<= 0x01ffffff && diff
>= -0x02000000) {
303 jump
->flags
|= PATCH_B
| extra_jump_flags
;
307 if (target_addr
<= 0x03ffffff) {
308 jump
->flags
|= PATCH_B
| PATCH_ABS_B
| extra_jump_flags
;
312 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
313 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
316 if (target_addr
<= 0x7fffffff) {
317 jump
->flags
|= PATCH_ABS32
;
321 if (target_addr
<= 0x7fffffffffffl
) {
322 jump
->flags
|= PATCH_ABS48
;
330 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
332 static SLJIT_INLINE sljit_sw
put_label_get_length(struct sljit_put_label
*put_label
, sljit_uw max_label
)
334 if (max_label
< 0x100000000l
) {
335 put_label
->flags
= 0;
339 if (max_label
< 0x1000000000000l
) {
340 put_label
->flags
= 1;
344 put_label
->flags
= 2;
348 static SLJIT_INLINE
void put_label_set(struct sljit_put_label
*put_label
)
350 sljit_uw addr
= put_label
->label
->addr
;
351 sljit_ins
*inst
= (sljit_ins
*)put_label
->addr
;
352 sljit_s32 reg
= *inst
;
354 if (put_label
->flags
== 0) {
355 SLJIT_ASSERT(addr
< 0x100000000l
);
356 inst
[0] = ORIS
| S(TMP_ZERO
) | A(reg
) | IMM(addr
>> 16);
359 if (put_label
->flags
== 1) {
360 SLJIT_ASSERT(addr
< 0x1000000000000l
);
361 inst
[0] = ORI
| S(TMP_ZERO
) | A(reg
) | IMM(addr
>> 32);
364 inst
[0] = ORIS
| S(TMP_ZERO
) | A(reg
) | IMM(addr
>> 48);
365 inst
[1] = ORI
| S(reg
) | A(reg
) | IMM((addr
>> 32) & 0xffff);
369 inst
[1] = RLDI(reg
, reg
, 32, 31, 1);
370 inst
[2] = ORIS
| S(reg
) | A(reg
) | IMM((addr
>> 16) & 0xffff);
374 inst
[1] = ORI
| S(reg
) | A(reg
) | IMM(addr
& 0xffff);
379 SLJIT_API_FUNC_ATTRIBUTE
void* sljit_generate_code(struct sljit_compiler
*compiler
)
381 struct sljit_memory_fragment
*buf
;
388 sljit_sw executable_offset
;
391 struct sljit_label
*label
;
392 struct sljit_jump
*jump
;
393 struct sljit_const
*const_
;
394 struct sljit_put_label
*put_label
;
397 CHECK_PTR(check_sljit_generate_code(compiler
));
398 reverse_buf(compiler
);
400 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
401 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
402 compiler
->size
+= (compiler
->size
& 0x1) + (sizeof(struct sljit_function_context
) / sizeof(sljit_ins
));
404 compiler
->size
+= (sizeof(struct sljit_function_context
) / sizeof(sljit_ins
));
407 code
= (sljit_ins
*)SLJIT_MALLOC_EXEC(compiler
->size
* sizeof(sljit_ins
), compiler
->exec_allocator_data
);
408 PTR_FAIL_WITH_EXEC_IF(code
);
414 executable_offset
= SLJIT_EXEC_OFFSET(code
);
416 label
= compiler
->labels
;
417 jump
= compiler
->jumps
;
418 const_
= compiler
->consts
;
419 put_label
= compiler
->put_labels
;
422 buf_ptr
= (sljit_ins
*)buf
->memory
;
423 buf_end
= buf_ptr
+ (buf
->used_size
>> 2);
425 *code_ptr
= *buf_ptr
++;
426 if (next_addr
== word_count
) {
427 SLJIT_ASSERT(!label
|| label
->size
>= word_count
);
428 SLJIT_ASSERT(!jump
|| jump
->addr
>= word_count
);
429 SLJIT_ASSERT(!const_
|| const_
->addr
>= word_count
);
430 SLJIT_ASSERT(!put_label
|| put_label
->addr
>= word_count
);
432 /* These structures are ordered by their address. */
433 if (label
&& label
->size
== word_count
) {
434 /* Just recording the address. */
435 label
->addr
= (sljit_uw
)SLJIT_ADD_EXEC_OFFSET(code_ptr
, executable_offset
);
436 label
->size
= code_ptr
- code
;
439 if (jump
&& jump
->addr
== word_count
) {
440 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
441 jump
->addr
= (sljit_uw
)(code_ptr
- 3);
443 jump
->addr
= (sljit_uw
)(code_ptr
- 6);
445 if (detect_jump_type(jump
, code_ptr
, code
, executable_offset
)) {
446 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
447 code_ptr
[-3] = code_ptr
[0];
450 if (jump
->flags
& PATCH_ABS32
) {
452 code_ptr
[-1] = code_ptr
[2];
453 code_ptr
[0] = code_ptr
[3];
455 else if (jump
->flags
& PATCH_ABS48
) {
457 code_ptr
[-1] = code_ptr
[0];
458 code_ptr
[0] = code_ptr
[1];
459 /* rldicr rX,rX,32,31 -> rX,rX,16,47 */
460 SLJIT_ASSERT((code_ptr
[-3] & 0xfc00ffff) == 0x780007c6);
461 code_ptr
[-3] ^= 0x8422;
463 code_ptr
[-2] ^= 0x4000000;
466 code_ptr
[-6] = code_ptr
[0];
470 if (jump
->flags
& REMOVE_COND
) {
471 code_ptr
[0] = BCx
| (2 << 2) | ((code_ptr
[0] ^ (8 << 21)) & 0x03ff0001);
473 jump
->addr
+= sizeof(sljit_ins
);
475 jump
->flags
-= IS_COND
;
480 if (const_
&& const_
->addr
== word_count
) {
481 const_
->addr
= (sljit_uw
)code_ptr
;
482 const_
= const_
->next
;
484 if (put_label
&& put_label
->addr
== word_count
) {
485 SLJIT_ASSERT(put_label
->label
);
486 put_label
->addr
= (sljit_uw
)code_ptr
;
487 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
488 code_ptr
+= put_label_get_length(put_label
, (sljit_uw
)(SLJIT_ADD_EXEC_OFFSET(code
, executable_offset
) + put_label
->label
->size
));
491 put_label
= put_label
->next
;
493 next_addr
= compute_next_addr(label
, jump
, const_
, put_label
);
497 } while (buf_ptr
< buf_end
);
502 if (label
&& label
->size
== word_count
) {
503 label
->addr
= (sljit_uw
)SLJIT_ADD_EXEC_OFFSET(code_ptr
, executable_offset
);
504 label
->size
= code_ptr
- code
;
508 SLJIT_ASSERT(!label
);
510 SLJIT_ASSERT(!const_
);
511 SLJIT_ASSERT(!put_label
);
513 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
514 SLJIT_ASSERT(code_ptr
- code
<= (sljit_sw
)compiler
->size
- (sizeof(struct sljit_function_context
) / sizeof(sljit_ins
)));
516 SLJIT_ASSERT(code_ptr
- code
<= (sljit_sw
)compiler
->size
);
519 jump
= compiler
->jumps
;
522 addr
= (jump
->flags
& JUMP_LABEL
) ? jump
->u
.label
->addr
: jump
->u
.target
;
523 buf_ptr
= (sljit_ins
*)jump
->addr
;
525 if (jump
->flags
& PATCH_B
) {
526 if (jump
->flags
& IS_COND
) {
527 if (!(jump
->flags
& PATCH_ABS_B
)) {
528 addr
-= (sljit_uw
)SLJIT_ADD_EXEC_OFFSET(buf_ptr
, executable_offset
);
529 SLJIT_ASSERT((sljit_sw
)addr
<= 0x7fff && (sljit_sw
)addr
>= -0x8000);
530 *buf_ptr
= BCx
| (addr
& 0xfffc) | ((*buf_ptr
) & 0x03ff0001);
533 SLJIT_ASSERT(addr
<= 0xffff);
534 *buf_ptr
= BCx
| (addr
& 0xfffc) | 0x2 | ((*buf_ptr
) & 0x03ff0001);
538 if (!(jump
->flags
& PATCH_ABS_B
)) {
539 addr
-= (sljit_uw
)SLJIT_ADD_EXEC_OFFSET(buf_ptr
, executable_offset
);
540 SLJIT_ASSERT((sljit_sw
)addr
<= 0x01ffffff && (sljit_sw
)addr
>= -0x02000000);
541 *buf_ptr
= Bx
| (addr
& 0x03fffffc) | ((*buf_ptr
) & 0x1);
544 SLJIT_ASSERT(addr
<= 0x03ffffff);
545 *buf_ptr
= Bx
| (addr
& 0x03fffffc) | 0x2 | ((*buf_ptr
) & 0x1);
551 /* Set the fields of immediate loads. */
552 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
553 buf_ptr
[0] = (buf_ptr
[0] & 0xffff0000) | ((addr
>> 16) & 0xffff);
554 buf_ptr
[1] = (buf_ptr
[1] & 0xffff0000) | (addr
& 0xffff);
556 if (jump
->flags
& PATCH_ABS32
) {
557 SLJIT_ASSERT(addr
<= 0x7fffffff);
558 buf_ptr
[0] = (buf_ptr
[0] & 0xffff0000) | ((addr
>> 16) & 0xffff);
559 buf_ptr
[1] = (buf_ptr
[1] & 0xffff0000) | (addr
& 0xffff);
562 if (jump
->flags
& PATCH_ABS48
) {
563 SLJIT_ASSERT(addr
<= 0x7fffffffffff);
564 buf_ptr
[0] = (buf_ptr
[0] & 0xffff0000) | ((addr
>> 32) & 0xffff);
565 buf_ptr
[1] = (buf_ptr
[1] & 0xffff0000) | ((addr
>> 16) & 0xffff);
566 buf_ptr
[3] = (buf_ptr
[3] & 0xffff0000) | (addr
& 0xffff);
569 buf_ptr
[0] = (buf_ptr
[0] & 0xffff0000) | ((addr
>> 48) & 0xffff);
570 buf_ptr
[1] = (buf_ptr
[1] & 0xffff0000) | ((addr
>> 32) & 0xffff);
571 buf_ptr
[3] = (buf_ptr
[3] & 0xffff0000) | ((addr
>> 16) & 0xffff);
572 buf_ptr
[4] = (buf_ptr
[4] & 0xffff0000) | (addr
& 0xffff);
578 put_label
= compiler
->put_labels
;
580 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
581 addr
= put_label
->label
->addr
;
582 buf_ptr
= (sljit_ins
*)put_label
->addr
;
584 SLJIT_ASSERT((buf_ptr
[0] & 0xfc1f0000) == ADDIS
&& (buf_ptr
[1] & 0xfc000000) == ORI
);
585 buf_ptr
[0] |= (addr
>> 16) & 0xffff;
586 buf_ptr
[1] |= addr
& 0xffff;
588 put_label_set(put_label
);
590 put_label
= put_label
->next
;
593 compiler
->error
= SLJIT_ERR_COMPILED
;
594 compiler
->executable_offset
= executable_offset
;
595 compiler
->executable_size
= (code_ptr
- code
) * sizeof(sljit_ins
);
597 code
= (sljit_ins
*)SLJIT_ADD_EXEC_OFFSET(code
, executable_offset
);
599 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
600 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
601 if (((sljit_sw
)code_ptr
) & 0x4)
604 sljit_set_function_context(NULL
, (struct sljit_function_context
*)code_ptr
, (sljit_sw
)code
, (void*)sljit_generate_code
);
607 code_ptr
= (sljit_ins
*)SLJIT_ADD_EXEC_OFFSET(code_ptr
, executable_offset
);
609 SLJIT_CACHE_FLUSH(code
, code_ptr
);
610 SLJIT_UPDATE_WX_FLAGS(code
, code_ptr
, 1);
612 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
619 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_has_cpu_feature(sljit_s32 feature_type
)
621 switch (feature_type
) {
623 #ifdef SLJIT_IS_FPU_AVAILABLE
624 return SLJIT_IS_FPU_AVAILABLE
;
626 /* Available by default. */
630 /* A saved register is set to a zero value. */
631 case SLJIT_HAS_ZERO_REGISTER
:
633 case SLJIT_HAS_PREFETCH
:
641 /* --------------------------------------------------------------------- */
643 /* --------------------------------------------------------------------- */
647 /* Creates an index in data_transfer_insts array. */
648 #define LOAD_DATA 0x01
650 #define SIGNED_DATA 0x04
652 #define WORD_DATA 0x00
653 #define BYTE_DATA 0x08
654 #define HALF_DATA 0x10
655 #define INT_DATA 0x18
656 /* Separates integer and floating point registers */
658 #define DOUBLE_DATA 0x20
660 #define MEM_MASK 0x7f
662 /* Other inp_flags. */
664 /* Integer opertion and set flags -> requires exts on 64 bit systems. */
665 #define ALT_SIGN_EXT 0x000100
666 /* This flag affects the RC() and OERC() macros. */
667 #define ALT_SET_FLAGS 0x000400
668 #define ALT_FORM1 0x001000
669 #define ALT_FORM2 0x002000
670 #define ALT_FORM3 0x004000
671 #define ALT_FORM4 0x008000
672 #define ALT_FORM5 0x010000
674 /* Source and destination is register. */
675 #define REG_DEST 0x000001
676 #define REG1_SOURCE 0x000002
677 #define REG2_SOURCE 0x000004
679 ALT_SIGN_EXT 0x000100
680 ALT_SET_FLAGS 0x000200
683 ALT_FORM5 0x010000 */
685 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
686 #include "sljitNativePPC_32.c"
688 #include "sljitNativePPC_64.c"
691 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
692 #define STACK_STORE STW
693 #define STACK_LOAD LWZ
695 #define STACK_STORE STD
696 #define STACK_LOAD LD
699 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_enter(struct sljit_compiler
*compiler
,
700 sljit_s32 options
, sljit_s32 arg_types
, sljit_s32 scratches
, sljit_s32 saveds
,
701 sljit_s32 fscratches
, sljit_s32 fsaveds
, sljit_s32 local_size
)
703 sljit_s32 args
, i
, tmp
, offs
;
706 CHECK(check_sljit_emit_enter(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
));
707 set_emit_enter(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
);
709 FAIL_IF(push_inst(compiler
, MFLR
| D(0)));
710 offs
= -(sljit_s32
)(sizeof(sljit_sw
));
711 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(TMP_ZERO
) | A(SLJIT_SP
) | IMM(offs
)));
713 tmp
= saveds
< SLJIT_NUMBER_OF_SAVED_REGISTERS
? (SLJIT_S0
+ 1 - saveds
) : SLJIT_FIRST_SAVED_REG
;
714 for (i
= SLJIT_S0
; i
>= tmp
; i
--) {
715 offs
-= (sljit_s32
)(sizeof(sljit_sw
));
716 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(i
) | A(SLJIT_SP
) | IMM(offs
)));
719 for (i
= scratches
; i
>= SLJIT_FIRST_SAVED_REG
; i
--) {
720 offs
-= (sljit_s32
)(sizeof(sljit_sw
));
721 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(i
) | A(SLJIT_SP
) | IMM(offs
)));
724 SLJIT_ASSERT(offs
== -(sljit_s32
)GET_SAVED_REGISTERS_SIZE(compiler
->scratches
, compiler
->saveds
, 1));
726 #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
727 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(0) | A(SLJIT_SP
) | IMM(2 * sizeof(sljit_sw
))));
729 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(0) | A(SLJIT_SP
) | IMM(sizeof(sljit_sw
))));
732 FAIL_IF(push_inst(compiler
, ADDI
| D(TMP_ZERO
) | A(0) | 0));
734 args
= get_arg_count(arg_types
);
737 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_R0
) | A(SLJIT_S0
) | B(SLJIT_R0
)));
739 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_R1
) | A(SLJIT_S1
) | B(SLJIT_R1
)));
741 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_R2
) | A(SLJIT_S2
) | B(SLJIT_R2
)));
743 local_size
+= GET_SAVED_REGISTERS_SIZE(scratches
, saveds
, 1) + SLJIT_LOCALS_OFFSET
;
744 local_size
= (local_size
+ 15) & ~0xf;
745 compiler
->local_size
= local_size
;
747 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
748 if (local_size
<= SIMM_MAX
)
749 FAIL_IF(push_inst(compiler
, STWU
| S(SLJIT_SP
) | A(SLJIT_SP
) | IMM(-local_size
)));
751 FAIL_IF(load_immediate(compiler
, 0, -local_size
));
752 FAIL_IF(push_inst(compiler
, STWUX
| S(SLJIT_SP
) | A(SLJIT_SP
) | B(0)));
755 if (local_size
<= SIMM_MAX
)
756 FAIL_IF(push_inst(compiler
, STDU
| S(SLJIT_SP
) | A(SLJIT_SP
) | IMM(-local_size
)));
758 FAIL_IF(load_immediate(compiler
, 0, -local_size
));
759 FAIL_IF(push_inst(compiler
, STDUX
| S(SLJIT_SP
) | A(SLJIT_SP
) | B(0)));
763 return SLJIT_SUCCESS
;
766 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_set_context(struct sljit_compiler
*compiler
,
767 sljit_s32 options
, sljit_s32 arg_types
, sljit_s32 scratches
, sljit_s32 saveds
,
768 sljit_s32 fscratches
, sljit_s32 fsaveds
, sljit_s32 local_size
)
771 CHECK(check_sljit_set_context(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
));
772 set_set_context(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
);
774 local_size
+= GET_SAVED_REGISTERS_SIZE(scratches
, saveds
, 1) + SLJIT_LOCALS_OFFSET
;
775 compiler
->local_size
= (local_size
+ 15) & ~0xf;
776 return SLJIT_SUCCESS
;
779 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_return(struct sljit_compiler
*compiler
, sljit_s32 op
, sljit_s32 src
, sljit_sw srcw
)
781 sljit_s32 i
, tmp
, offs
;
784 CHECK(check_sljit_emit_return(compiler
, op
, src
, srcw
));
786 FAIL_IF(emit_mov_before_return(compiler
, op
, src
, srcw
));
788 if (compiler
->local_size
<= SIMM_MAX
)
789 FAIL_IF(push_inst(compiler
, ADDI
| D(SLJIT_SP
) | A(SLJIT_SP
) | IMM(compiler
->local_size
)));
791 FAIL_IF(load_immediate(compiler
, 0, compiler
->local_size
));
792 FAIL_IF(push_inst(compiler
, ADD
| D(SLJIT_SP
) | A(SLJIT_SP
) | B(0)));
795 #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
796 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(0) | A(SLJIT_SP
) | IMM(2 * sizeof(sljit_sw
))));
798 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(0) | A(SLJIT_SP
) | IMM(sizeof(sljit_sw
))));
801 offs
= -(sljit_s32
)GET_SAVED_REGISTERS_SIZE(compiler
->scratches
, compiler
->saveds
, 1);
803 tmp
= compiler
->scratches
;
804 for (i
= SLJIT_FIRST_SAVED_REG
; i
<= tmp
; i
++) {
805 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(i
) | A(SLJIT_SP
) | IMM(offs
)));
806 offs
+= (sljit_s32
)(sizeof(sljit_sw
));
809 tmp
= compiler
->saveds
< SLJIT_NUMBER_OF_SAVED_REGISTERS
? (SLJIT_S0
+ 1 - compiler
->saveds
) : SLJIT_FIRST_SAVED_REG
;
810 for (i
= tmp
; i
<= SLJIT_S0
; i
++) {
811 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(i
) | A(SLJIT_SP
) | IMM(offs
)));
812 offs
+= (sljit_s32
)(sizeof(sljit_sw
));
815 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(TMP_ZERO
) | A(SLJIT_SP
) | IMM(offs
)));
816 SLJIT_ASSERT(offs
== -(sljit_sw
)(sizeof(sljit_sw
)));
818 FAIL_IF(push_inst(compiler
, MTLR
| S(0)));
819 FAIL_IF(push_inst(compiler
, BLR
));
821 return SLJIT_SUCCESS
;
827 /* --------------------------------------------------------------------- */
829 /* --------------------------------------------------------------------- */
831 /* s/l - store/load (1 bit)
832 i/x - immediate/indexed form
833 u/s - signed/unsigned (1 bit)
834 w/b/h/i - word/byte/half/int allowed (2 bit)
836 Some opcodes are repeated (e.g. store signed / unsigned byte is the same instruction). */
838 /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
839 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
840 #define INT_ALIGNED 0x10000
843 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
844 #define ARCH_32_64(a, b) a
845 #define INST_CODE_AND_DST(inst, flags, reg) \
846 ((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
848 #define ARCH_32_64(a, b) b
849 #define INST_CODE_AND_DST(inst, flags, reg) \
850 (((inst) & ~INT_ALIGNED) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
853 static const sljit_ins data_transfer_insts
[64 + 16] = {
855 /* -------- Integer -------- */
859 /* w u i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED
| 0x0 /* std */),
860 /* w u i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED
| 0x0 /* ld */),
861 /* w u x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
862 /* w u x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
864 /* w s i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED
| 0x0 /* std */),
865 /* w s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED
| 0x0 /* ld */),
866 /* w s x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
867 /* w s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
871 /* b u i s */ HI(38) /* stb */,
872 /* b u i l */ HI(34) /* lbz */,
873 /* b u x s */ HI(31) | LO(215) /* stbx */,
874 /* b u x l */ HI(31) | LO(87) /* lbzx */,
876 /* b s i s */ HI(38) /* stb */,
877 /* b s i l */ HI(34) /* lbz */ /* EXTS_REQ */,
878 /* b s x s */ HI(31) | LO(215) /* stbx */,
879 /* b s x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
883 /* h u i s */ HI(44) /* sth */,
884 /* h u i l */ HI(40) /* lhz */,
885 /* h u x s */ HI(31) | LO(407) /* sthx */,
886 /* h u x l */ HI(31) | LO(279) /* lhzx */,
888 /* h s i s */ HI(44) /* sth */,
889 /* h s i l */ HI(42) /* lha */,
890 /* h s x s */ HI(31) | LO(407) /* sthx */,
891 /* h s x l */ HI(31) | LO(343) /* lhax */,
895 /* i u i s */ HI(36) /* stw */,
896 /* i u i l */ HI(32) /* lwz */,
897 /* i u x s */ HI(31) | LO(151) /* stwx */,
898 /* i u x l */ HI(31) | LO(23) /* lwzx */,
900 /* i s i s */ HI(36) /* stw */,
901 /* i s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED
| 0x2 /* lwa */),
902 /* i s x s */ HI(31) | LO(151) /* stwx */,
903 /* i s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
905 /* -------- Floating point -------- */
907 /* d i s */ HI(54) /* stfd */,
908 /* d i l */ HI(50) /* lfd */,
909 /* d x s */ HI(31) | LO(727) /* stfdx */,
910 /* d x l */ HI(31) | LO(599) /* lfdx */,
912 /* s i s */ HI(52) /* stfs */,
913 /* s i l */ HI(48) /* lfs */,
914 /* s x s */ HI(31) | LO(663) /* stfsx */,
915 /* s x l */ HI(31) | LO(535) /* lfsx */,
918 static const sljit_ins updated_data_transfer_insts
[64] = {
920 /* -------- Integer -------- */
924 /* w u i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED
| 0x1 /* stdu */),
925 /* w u i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED
| 0x1 /* ldu */),
926 /* w u x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
927 /* w u x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
929 /* w s i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED
| 0x1 /* stdu */),
930 /* w s i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED
| 0x1 /* ldu */),
931 /* w s x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
932 /* w s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
936 /* b u i s */ HI(39) /* stbu */,
937 /* b u i l */ HI(35) /* lbzu */,
938 /* b u x s */ HI(31) | LO(247) /* stbux */,
939 /* b u x l */ HI(31) | LO(119) /* lbzux */,
941 /* b s i s */ HI(39) /* stbu */,
942 /* b s i l */ 0 /* no such instruction */,
943 /* b s x s */ HI(31) | LO(247) /* stbux */,
944 /* b s x l */ 0 /* no such instruction */,
948 /* h u i s */ HI(45) /* sthu */,
949 /* h u i l */ HI(41) /* lhzu */,
950 /* h u x s */ HI(31) | LO(439) /* sthux */,
951 /* h u x l */ HI(31) | LO(311) /* lhzux */,
953 /* h s i s */ HI(45) /* sthu */,
954 /* h s i l */ HI(43) /* lhau */,
955 /* h s x s */ HI(31) | LO(439) /* sthux */,
956 /* h s x l */ HI(31) | LO(375) /* lhaux */,
960 /* i u i s */ HI(37) /* stwu */,
961 /* i u i l */ HI(33) /* lwzu */,
962 /* i u x s */ HI(31) | LO(183) /* stwux */,
963 /* i u x l */ HI(31) | LO(55) /* lwzux */,
965 /* i s i s */ HI(37) /* stwu */,
966 /* i s i l */ ARCH_32_64(HI(33) /* lwzu */, 0 /* no such instruction */),
967 /* i s x s */ HI(31) | LO(183) /* stwux */,
968 /* i s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
970 /* -------- Floating point -------- */
972 /* d i s */ HI(55) /* stfdu */,
973 /* d i l */ HI(51) /* lfdu */,
974 /* d x s */ HI(31) | LO(759) /* stfdux */,
975 /* d x l */ HI(31) | LO(631) /* lfdux */,
977 /* s i s */ HI(53) /* stfsu */,
978 /* s i l */ HI(49) /* lfsu */,
979 /* s x s */ HI(31) | LO(695) /* stfsux */,
980 /* s x l */ HI(31) | LO(567) /* lfsux */,
985 /* Simple cases, (no caching is required). */
986 static sljit_s32
emit_op_mem(struct sljit_compiler
*compiler
, sljit_s32 inp_flags
, sljit_s32 reg
,
987 sljit_s32 arg
, sljit_sw argw
, sljit_s32 tmp_reg
)
993 /* Should work when (arg & REG_MASK) == 0. */
994 SLJIT_ASSERT(A(0) == 0);
995 SLJIT_ASSERT(arg
& SLJIT_MEM
);
997 if (SLJIT_UNLIKELY(arg
& OFFS_REG_MASK
)) {
999 offs_reg
= OFFS_REG(arg
);
1002 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1003 FAIL_IF(push_inst(compiler
, RLWINM
| S(OFFS_REG(arg
)) | A(tmp_reg
) | (argw
<< 11) | ((31 - argw
) << 1)));
1005 FAIL_IF(push_inst(compiler
, RLDI(tmp_reg
, OFFS_REG(arg
), argw
, 63 - argw
, 1)));
1010 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
1012 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1013 SLJIT_ASSERT(!(inst
& INT_ALIGNED
));
1016 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
& REG_MASK
) | B(offs_reg
));
1019 inst
= data_transfer_insts
[inp_flags
& MEM_MASK
];
1022 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1023 if ((inst
& INT_ALIGNED
) && (argw
& 0x3) != 0) {
1024 FAIL_IF(load_immediate(compiler
, tmp_reg
, argw
));
1026 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
1027 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
) | B(tmp_reg
));
1031 if (argw
<= SIMM_MAX
&& argw
>= SIMM_MIN
)
1032 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
) | IMM(argw
));
1034 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1035 if (argw
<= 0x7fff7fffl
&& argw
>= -0x80000000l
) {
1038 high_short
= (sljit_s32
)(argw
+ ((argw
& 0x8000) << 1)) & ~0xffff;
1040 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1041 SLJIT_ASSERT(high_short
&& high_short
<= 0x7fffffffl
&& high_short
>= -0x80000000l
);
1043 SLJIT_ASSERT(high_short
);
1046 FAIL_IF(push_inst(compiler
, ADDIS
| D(tmp_reg
) | A(arg
) | IMM(high_short
>> 16)));
1047 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(tmp_reg
) | IMM(argw
));
1049 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1052 /* The rest is PPC-64 only. */
1054 FAIL_IF(load_immediate(compiler
, tmp_reg
, argw
));
1056 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
1057 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
) | B(tmp_reg
));
1061 static sljit_s32
emit_op(struct sljit_compiler
*compiler
, sljit_s32 op
, sljit_s32 input_flags
,
1062 sljit_s32 dst
, sljit_sw dstw
,
1063 sljit_s32 src1
, sljit_sw src1w
,
1064 sljit_s32 src2
, sljit_sw src2w
)
1066 /* arg1 goes to TMP_REG1 or src reg
1067 arg2 goes to TMP_REG2, imm or src reg
1068 result goes to TMP_REG2, so put result can use TMP_REG1. */
1069 sljit_s32 dst_r
= TMP_REG2
;
1072 sljit_s32 sugg_src2_r
= TMP_REG2
;
1073 sljit_s32 flags
= input_flags
& (ALT_FORM1
| ALT_FORM2
| ALT_FORM3
| ALT_FORM4
| ALT_FORM5
| ALT_SIGN_EXT
| ALT_SET_FLAGS
);
1075 /* Destination check. */
1076 if (SLOW_IS_REG(dst
)) {
1080 if (op
>= SLJIT_MOV
&& op
<= SLJIT_MOV_P
)
1081 sugg_src2_r
= dst_r
;
1085 if (FAST_IS_REG(src1
)) {
1087 flags
|= REG1_SOURCE
;
1089 else if (src1
& SLJIT_IMM
) {
1090 FAIL_IF(load_immediate(compiler
, TMP_REG1
, src1w
));
1094 FAIL_IF(emit_op_mem(compiler
, input_flags
| LOAD_DATA
, TMP_REG1
, src1
, src1w
, TMP_REG1
));
1099 if (FAST_IS_REG(src2
)) {
1101 flags
|= REG2_SOURCE
;
1103 if (!(flags
& REG_DEST
) && op
>= SLJIT_MOV
&& op
<= SLJIT_MOV_P
)
1106 else if (src2
& SLJIT_IMM
) {
1107 FAIL_IF(load_immediate(compiler
, sugg_src2_r
, src2w
));
1108 src2_r
= sugg_src2_r
;
1111 FAIL_IF(emit_op_mem(compiler
, input_flags
| LOAD_DATA
, sugg_src2_r
, src2
, src2w
, TMP_REG2
));
1112 src2_r
= sugg_src2_r
;
1115 FAIL_IF(emit_single_op(compiler
, op
, flags
, dst_r
, src1_r
, src2_r
));
1117 if (!(dst
& SLJIT_MEM
))
1118 return SLJIT_SUCCESS
;
1120 return emit_op_mem(compiler
, input_flags
, dst_r
, dst
, dstw
, TMP_REG1
);
1123 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op0(struct sljit_compiler
*compiler
, sljit_s32 op
)
1125 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1126 sljit_s32 int_op
= op
& SLJIT_I32_OP
;
1130 CHECK(check_sljit_emit_op0(compiler
, op
));
1132 op
= GET_OPCODE(op
);
1134 case SLJIT_BREAKPOINT
:
1136 return push_inst(compiler
, NOP
);
1139 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_R0
) | A(TMP_REG1
) | B(SLJIT_R0
)));
1140 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1141 FAIL_IF(push_inst(compiler
, MULLD
| D(SLJIT_R0
) | A(TMP_REG1
) | B(SLJIT_R1
)));
1142 return push_inst(compiler
, (op
== SLJIT_LMUL_UW
? MULHDU
: MULHD
) | D(SLJIT_R1
) | A(TMP_REG1
) | B(SLJIT_R1
));
1144 FAIL_IF(push_inst(compiler
, MULLW
| D(SLJIT_R0
) | A(TMP_REG1
) | B(SLJIT_R1
)));
1145 return push_inst(compiler
, (op
== SLJIT_LMUL_UW
? MULHWU
: MULHW
) | D(SLJIT_R1
) | A(TMP_REG1
) | B(SLJIT_R1
));
1147 case SLJIT_DIVMOD_UW
:
1148 case SLJIT_DIVMOD_SW
:
1149 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_R0
) | A(TMP_REG1
) | B(SLJIT_R0
)));
1150 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1151 FAIL_IF(push_inst(compiler
, (int_op
? (op
== SLJIT_DIVMOD_UW
? DIVWU
: DIVW
) : (op
== SLJIT_DIVMOD_UW
? DIVDU
: DIVD
)) | D(SLJIT_R0
) | A(SLJIT_R0
) | B(SLJIT_R1
)));
1152 FAIL_IF(push_inst(compiler
, (int_op
? MULLW
: MULLD
) | D(SLJIT_R1
) | A(SLJIT_R0
) | B(SLJIT_R1
)));
1154 FAIL_IF(push_inst(compiler
, (op
== SLJIT_DIVMOD_UW
? DIVWU
: DIVW
) | D(SLJIT_R0
) | A(SLJIT_R0
) | B(SLJIT_R1
)));
1155 FAIL_IF(push_inst(compiler
, MULLW
| D(SLJIT_R1
) | A(SLJIT_R0
) | B(SLJIT_R1
)));
1157 return push_inst(compiler
, SUBF
| D(SLJIT_R1
) | A(SLJIT_R1
) | B(TMP_REG1
));
1160 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1161 return push_inst(compiler
, (int_op
? (op
== SLJIT_DIV_UW
? DIVWU
: DIVW
) : (op
== SLJIT_DIV_UW
? DIVDU
: DIVD
)) | D(SLJIT_R0
) | A(SLJIT_R0
) | B(SLJIT_R1
));
1163 return push_inst(compiler
, (op
== SLJIT_DIV_UW
? DIVWU
: DIVW
) | D(SLJIT_R0
) | A(SLJIT_R0
) | B(SLJIT_R1
));
1166 case SLJIT_SKIP_FRAMES_BEFORE_RETURN
:
1167 return SLJIT_SUCCESS
;
1170 return SLJIT_SUCCESS
;
1173 static sljit_s32
emit_prefetch(struct sljit_compiler
*compiler
,
1174 sljit_s32 src
, sljit_sw srcw
)
1176 if (!(src
& OFFS_REG_MASK
)) {
1177 if (srcw
== 0 && (src
& REG_MASK
) != SLJIT_UNUSED
)
1178 return push_inst(compiler
, DCBT
| A(0) | B(src
& REG_MASK
));
1180 FAIL_IF(load_immediate(compiler
, TMP_REG1
, srcw
));
1181 /* Works with SLJIT_MEM0() case as well. */
1182 return push_inst(compiler
, DCBT
| A(src
& REG_MASK
) | B(TMP_REG1
));
1188 return push_inst(compiler
, DCBT
| A(src
& REG_MASK
) | B(OFFS_REG(src
)));
1190 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1191 FAIL_IF(push_inst(compiler
, RLWINM
| S(OFFS_REG(src
)) | A(TMP_REG1
) | (srcw
<< 11) | ((31 - srcw
) << 1)));
1193 FAIL_IF(push_inst(compiler
, RLDI(TMP_REG1
, OFFS_REG(src
), srcw
, 63 - srcw
, 1)));
1195 return push_inst(compiler
, DCBT
| A(src
& REG_MASK
) | B(TMP_REG1
));
1198 #define EMIT_MOV(type, type_flags, type_cast) \
1199 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)
1201 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op1(struct sljit_compiler
*compiler
, sljit_s32 op
,
1202 sljit_s32 dst
, sljit_sw dstw
,
1203 sljit_s32 src
, sljit_sw srcw
)
1205 sljit_s32 flags
= HAS_FLAGS(op
) ? ALT_SET_FLAGS
: 0;
1206 sljit_s32 op_flags
= GET_ALL_FLAGS(op
);
1209 CHECK(check_sljit_emit_op1(compiler
, op
, dst
, dstw
, src
, srcw
));
1210 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1211 ADJUST_LOCAL_OFFSET(src
, srcw
);
1213 op
= GET_OPCODE(op
);
1214 if ((src
& SLJIT_IMM
) && srcw
== 0)
1217 if (GET_FLAG_TYPE(op_flags
) == SLJIT_OVERFLOW
)
1218 FAIL_IF(push_inst(compiler
, MTXER
| S(TMP_ZERO
)));
1220 if (op
< SLJIT_NOT
&& FAST_IS_REG(src
) && src
== dst
) {
1221 if (!TYPE_CAST_NEEDED(op
))
1222 return SLJIT_SUCCESS
;
1225 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1226 if (op_flags
& SLJIT_I32_OP
) {
1227 if (op
< SLJIT_NOT
) {
1228 if (src
& SLJIT_MEM
) {
1229 if (op
== SLJIT_MOV_S32
)
1232 else if (src
& SLJIT_IMM
) {
1233 if (op
== SLJIT_MOV_U32
)
1238 /* Most operations expect sign extended arguments. */
1239 flags
|= INT_DATA
| SIGNED_DATA
;
1240 if (HAS_FLAGS(op_flags
))
1241 flags
|= ALT_SIGN_EXT
;
1249 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1253 return emit_op(compiler
, SLJIT_MOV
, flags
| WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1255 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1257 return EMIT_MOV(SLJIT_MOV_U32
, INT_DATA
, (sljit_u32
));
1260 return EMIT_MOV(SLJIT_MOV_S32
, INT_DATA
| SIGNED_DATA
, (sljit_s32
));
1264 return EMIT_MOV(SLJIT_MOV_U8
, BYTE_DATA
, (sljit_u8
));
1267 return EMIT_MOV(SLJIT_MOV_S8
, BYTE_DATA
| SIGNED_DATA
, (sljit_s8
));
1270 return EMIT_MOV(SLJIT_MOV_U16
, HALF_DATA
, (sljit_u16
));
1273 return EMIT_MOV(SLJIT_MOV_S16
, HALF_DATA
| SIGNED_DATA
, (sljit_s16
));
1276 return emit_op(compiler
, SLJIT_NOT
, flags
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1279 return emit_op(compiler
, SLJIT_NEG
, flags
| (GET_FLAG_TYPE(op_flags
) ? ALT_FORM1
: 0), dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1282 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1283 return emit_op(compiler
, SLJIT_CLZ
, flags
| (!(op_flags
& SLJIT_I32_OP
) ? 0 : ALT_FORM1
), dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1285 return emit_op(compiler
, SLJIT_CLZ
, flags
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1289 return SLJIT_SUCCESS
;
1294 #define TEST_SL_IMM(src, srcw) \
1295 (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)
1297 #define TEST_UL_IMM(src, srcw) \
1298 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff))
1300 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1301 #define TEST_SH_IMM(src, srcw) \
1302 (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l)
1304 #define TEST_SH_IMM(src, srcw) \
1305 (((src) & SLJIT_IMM) && !((srcw) & 0xffff))
1308 #define TEST_UH_IMM(src, srcw) \
1309 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000))
1311 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1312 #define TEST_ADD_IMM(src, srcw) \
1313 (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l)
1315 #define TEST_ADD_IMM(src, srcw) \
1319 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1320 #define TEST_UI_IMM(src, srcw) \
1321 (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
1323 #define TEST_UI_IMM(src, srcw) \
1327 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1328 #define TEST_ADD_FORM1(op) \
1329 (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \
1330 || (op & (SLJIT_I32_OP | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_I32_OP | SLJIT_SET_Z | SLJIT_SET_CARRY))
1331 #define TEST_SUB_FORM2(op) \
1332 ((GET_FLAG_TYPE(op) >= SLJIT_SIG_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) \
1333 || (op & (SLJIT_I32_OP | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_I32_OP | SLJIT_SET_Z))
1334 #define TEST_SUB_FORM3(op) \
1335 (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \
1336 || (op & (SLJIT_I32_OP | SLJIT_SET_Z)) == (SLJIT_I32_OP | SLJIT_SET_Z))
1338 #define TEST_ADD_FORM1(op) \
1339 (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1340 #define TEST_SUB_FORM2(op) \
1341 (GET_FLAG_TYPE(op) >= SLJIT_SIG_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL)
1342 #define TEST_SUB_FORM3(op) \
1343 (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1346 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op2(struct sljit_compiler
*compiler
, sljit_s32 op
,
1347 sljit_s32 dst
, sljit_sw dstw
,
1348 sljit_s32 src1
, sljit_sw src1w
,
1349 sljit_s32 src2
, sljit_sw src2w
)
1351 sljit_s32 flags
= HAS_FLAGS(op
) ? ALT_SET_FLAGS
: 0;
1354 CHECK(check_sljit_emit_op2(compiler
, op
, dst
, dstw
, src1
, src1w
, src2
, src2w
));
1355 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1356 ADJUST_LOCAL_OFFSET(src1
, src1w
);
1357 ADJUST_LOCAL_OFFSET(src2
, src2w
);
1359 if (dst
== SLJIT_UNUSED
&& !HAS_FLAGS(op
))
1360 return SLJIT_SUCCESS
;
1362 if ((src1
& SLJIT_IMM
) && src1w
== 0)
1364 if ((src2
& SLJIT_IMM
) && src2w
== 0)
1367 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1368 if (op
& SLJIT_I32_OP
) {
1369 /* Most operations expect sign extended arguments. */
1370 flags
|= INT_DATA
| SIGNED_DATA
;
1371 if (src1
& SLJIT_IMM
)
1372 src1w
= (sljit_s32
)(src1w
);
1373 if (src2
& SLJIT_IMM
)
1374 src2w
= (sljit_s32
)(src2w
);
1376 flags
|= ALT_SIGN_EXT
;
1379 if (GET_FLAG_TYPE(op
) == SLJIT_OVERFLOW
)
1380 FAIL_IF(push_inst(compiler
, MTXER
| S(TMP_ZERO
)));
1382 switch (GET_OPCODE(op
)) {
1384 if (TEST_ADD_FORM1(op
))
1385 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1387 if (!HAS_FLAGS(op
) && ((src1
| src2
) & SLJIT_IMM
)) {
1388 if (TEST_SL_IMM(src2
, src2w
)) {
1389 compiler
->imm
= src2w
& 0xffff;
1390 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1392 if (TEST_SL_IMM(src1
, src1w
)) {
1393 compiler
->imm
= src1w
& 0xffff;
1394 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1396 if (TEST_SH_IMM(src2
, src2w
)) {
1397 compiler
->imm
= (src2w
>> 16) & 0xffff;
1398 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1400 if (TEST_SH_IMM(src1
, src1w
)) {
1401 compiler
->imm
= (src1w
>> 16) & 0xffff;
1402 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1404 /* Range between -1 and -32768 is covered above. */
1405 if (TEST_ADD_IMM(src2
, src2w
)) {
1406 compiler
->imm
= src2w
& 0xffffffff;
1407 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1409 if (TEST_ADD_IMM(src1
, src1w
)) {
1410 compiler
->imm
= src1w
& 0xffffffff;
1411 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM4
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1415 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1416 if ((op
& (SLJIT_I32_OP
| SLJIT_SET_Z
)) == (SLJIT_I32_OP
| SLJIT_SET_Z
)) {
1417 if (TEST_SL_IMM(src2
, src2w
)) {
1418 compiler
->imm
= src2w
& 0xffff;
1419 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM4
| ALT_FORM5
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1421 if (TEST_SL_IMM(src1
, src1w
)) {
1422 compiler
->imm
= src1w
& 0xffff;
1423 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM4
| ALT_FORM5
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1425 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1428 if (HAS_FLAGS(op
)) {
1429 if (TEST_SL_IMM(src2
, src2w
)) {
1430 compiler
->imm
= src2w
& 0xffff;
1431 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1433 if (TEST_SL_IMM(src1
, src1w
)) {
1434 compiler
->imm
= src1w
& 0xffff;
1435 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM3
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1438 return emit_op(compiler
, SLJIT_ADD
, flags
| ((GET_FLAG_TYPE(op
) == GET_FLAG_TYPE(SLJIT_SET_CARRY
)) ? ALT_FORM5
: 0), dst
, dstw
, src1
, src1w
, src2
, src2w
);
1441 return emit_op(compiler
, SLJIT_ADDC
, flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1444 if (GET_FLAG_TYPE(op
) >= SLJIT_LESS
&& GET_FLAG_TYPE(op
) <= SLJIT_LESS_EQUAL
) {
1445 if (dst
== SLJIT_UNUSED
) {
1446 if (TEST_UL_IMM(src2
, src2w
)) {
1447 compiler
->imm
= src2w
& 0xffff;
1448 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM1
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1450 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1453 if ((src2
& SLJIT_IMM
) && src2w
>= 0 && src2w
<= (SIMM_MAX
+ 1)) {
1454 compiler
->imm
= src2w
;
1455 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM1
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1457 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM1
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1460 if (dst
== SLJIT_UNUSED
&& GET_FLAG_TYPE(op
) <= SLJIT_SIG_LESS_EQUAL
) {
1461 if (TEST_SL_IMM(src2
, src2w
)) {
1462 compiler
->imm
= src2w
& 0xffff;
1463 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1465 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1468 if (TEST_SUB_FORM2(op
)) {
1469 if ((src2
& SLJIT_IMM
) && src2w
>= -SIMM_MAX
&& src2w
<= SIMM_MAX
) {
1470 compiler
->imm
= src2w
& 0xffff;
1471 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
| ALT_FORM3
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1473 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1476 if (TEST_SUB_FORM3(op
))
1477 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1479 if (TEST_SL_IMM(src2
, -src2w
)) {
1480 compiler
->imm
= (-src2w
) & 0xffff;
1481 return emit_op(compiler
, SLJIT_ADD
, flags
| (!HAS_FLAGS(op
) ? ALT_FORM2
: ALT_FORM3
), dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1484 if (TEST_SL_IMM(src1
, src1w
) && !(op
& SLJIT_SET_Z
)) {
1485 compiler
->imm
= src1w
& 0xffff;
1486 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM4
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1489 if (!HAS_FLAGS(op
)) {
1490 if (TEST_SH_IMM(src2
, -src2w
)) {
1491 compiler
->imm
= ((-src2w
) >> 16) & 0xffff;
1492 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1494 /* Range between -1 and -32768 is covered above. */
1495 if (TEST_ADD_IMM(src2
, -src2w
)) {
1496 compiler
->imm
= -src2w
& 0xffffffff;
1497 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1501 /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */
1502 return emit_op(compiler
, SLJIT_SUB
, flags
| ((GET_FLAG_TYPE(op
) == GET_FLAG_TYPE(SLJIT_SET_CARRY
)) ? ALT_FORM5
: 0), dst
, dstw
, src1
, src1w
, src2
, src2w
);
1505 return emit_op(compiler
, SLJIT_SUBC
, flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1508 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1509 if (op
& SLJIT_I32_OP
)
1512 if (!HAS_FLAGS(op
)) {
1513 if (TEST_SL_IMM(src2
, src2w
)) {
1514 compiler
->imm
= src2w
& 0xffff;
1515 return emit_op(compiler
, SLJIT_MUL
, flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1517 if (TEST_SL_IMM(src1
, src1w
)) {
1518 compiler
->imm
= src1w
& 0xffff;
1519 return emit_op(compiler
, SLJIT_MUL
, flags
| ALT_FORM1
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1523 FAIL_IF(push_inst(compiler
, MTXER
| S(TMP_ZERO
)));
1524 return emit_op(compiler
, SLJIT_MUL
, flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1529 /* Commutative unsigned operations. */
1530 if (!HAS_FLAGS(op
) || GET_OPCODE(op
) == SLJIT_AND
) {
1531 if (TEST_UL_IMM(src2
, src2w
)) {
1532 compiler
->imm
= src2w
;
1533 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1535 if (TEST_UL_IMM(src1
, src1w
)) {
1536 compiler
->imm
= src1w
;
1537 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM1
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1539 if (TEST_UH_IMM(src2
, src2w
)) {
1540 compiler
->imm
= (src2w
>> 16) & 0xffff;
1541 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1543 if (TEST_UH_IMM(src1
, src1w
)) {
1544 compiler
->imm
= (src1w
>> 16) & 0xffff;
1545 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM2
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1548 if (GET_OPCODE(op
) != SLJIT_AND
&& GET_OPCODE(op
) != SLJIT_AND
) {
1549 /* Unlike or and xor, and resets unwanted bits as well. */
1550 if (TEST_UI_IMM(src2
, src2w
)) {
1551 compiler
->imm
= src2w
;
1552 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1554 if (TEST_UI_IMM(src1
, src1w
)) {
1555 compiler
->imm
= src1w
;
1556 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM3
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1559 return emit_op(compiler
, GET_OPCODE(op
), flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1564 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1565 if (op
& SLJIT_I32_OP
)
1568 if (src2
& SLJIT_IMM
) {
1569 compiler
->imm
= src2w
;
1570 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1572 return emit_op(compiler
, GET_OPCODE(op
), flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1575 return SLJIT_SUCCESS
;
1578 #undef TEST_ADD_FORM1
1579 #undef TEST_SUB_FORM2
1580 #undef TEST_SUB_FORM3
1582 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_src(struct sljit_compiler
*compiler
, sljit_s32 op
,
1583 sljit_s32 src
, sljit_sw srcw
)
1586 CHECK(check_sljit_emit_op_src(compiler
, op
, src
, srcw
));
1587 ADJUST_LOCAL_OFFSET(src
, srcw
);
1590 case SLJIT_FAST_RETURN
:
1591 if (FAST_IS_REG(src
))
1592 FAIL_IF(push_inst(compiler
, MTLR
| S(src
)));
1594 FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, TMP_REG2
, 0, TMP_REG1
, 0, src
, srcw
));
1595 FAIL_IF(push_inst(compiler
, MTLR
| S(TMP_REG2
)));
1598 return push_inst(compiler
, BLR
);
1599 case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN
:
1600 return SLJIT_SUCCESS
;
1601 case SLJIT_PREFETCH_L1
:
1602 case SLJIT_PREFETCH_L2
:
1603 case SLJIT_PREFETCH_L3
:
1604 case SLJIT_PREFETCH_ONCE
:
1605 return emit_prefetch(compiler
, src
, srcw
);
1608 return SLJIT_SUCCESS
;
1611 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_get_register_index(sljit_s32 reg
)
1613 CHECK_REG_INDEX(check_sljit_get_register_index(reg
));
1614 return reg_map
[reg
];
1617 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_get_float_register_index(sljit_s32 reg
)
1619 CHECK_REG_INDEX(check_sljit_get_float_register_index(reg
));
1620 return freg_map
[reg
];
1623 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_custom(struct sljit_compiler
*compiler
,
1624 void *instruction
, sljit_s32 size
)
1627 CHECK(check_sljit_emit_op_custom(compiler
, instruction
, size
));
1629 return push_inst(compiler
, *(sljit_ins
*)instruction
);
1632 /* --------------------------------------------------------------------- */
1633 /* Floating point operators */
1634 /* --------------------------------------------------------------------- */
1636 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 6))
1637 #define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)
1639 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1640 #define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw))
1642 #define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw))
1644 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
1645 #define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw))
1646 #define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw))
1648 #define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw))
1649 #define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw))
1652 #endif /* SLJIT_CONFIG_PPC_64 */
1654 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler
*compiler
, sljit_s32 op
,
1655 sljit_s32 dst
, sljit_sw dstw
,
1656 sljit_s32 src
, sljit_sw srcw
)
1658 if (src
& SLJIT_MEM
) {
1659 /* We can ignore the temporary data store on the stack from caching point of view. */
1660 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, src
, srcw
, TMP_REG1
));
1664 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1665 op
= GET_OPCODE(op
);
1666 FAIL_IF(push_inst(compiler
, (op
== SLJIT_CONV_S32_FROM_F64
? FCTIWZ
: FCTIDZ
) | FD(TMP_FREG1
) | FB(src
)));
1668 if (op
== SLJIT_CONV_SW_FROM_F64
) {
1669 if (FAST_IS_REG(dst
)) {
1670 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
, TMP_FREG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1671 return emit_op_mem(compiler
, WORD_DATA
| LOAD_DATA
, dst
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
);
1673 return emit_op_mem(compiler
, DOUBLE_DATA
, TMP_FREG1
, dst
, dstw
, TMP_REG1
);
1676 FAIL_IF(push_inst(compiler
, FCTIWZ
| FD(TMP_FREG1
) | FB(src
)));
1679 if (FAST_IS_REG(dst
)) {
1680 FAIL_IF(load_immediate(compiler
, TMP_REG1
, FLOAT_TMP_MEM_OFFSET
));
1681 FAIL_IF(push_inst(compiler
, STFIWX
| FS(TMP_FREG1
) | A(SLJIT_SP
) | B(TMP_REG1
)));
1682 return emit_op_mem(compiler
, INT_DATA
| LOAD_DATA
, dst
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
);
1685 SLJIT_ASSERT(dst
& SLJIT_MEM
);
1687 if (dst
& OFFS_REG_MASK
) {
1690 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1691 FAIL_IF(push_inst(compiler
, RLWINM
| S(OFFS_REG(dst
)) | A(TMP_REG1
) | (dstw
<< 11) | ((31 - dstw
) << 1)));
1693 FAIL_IF(push_inst(compiler
, RLDI(TMP_REG1
, OFFS_REG(dst
), dstw
, 63 - dstw
, 1)));
1698 dstw
= OFFS_REG(dst
);
1701 if ((dst
& REG_MASK
) && !dstw
) {
1702 dstw
= dst
& REG_MASK
;
1706 /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */
1707 FAIL_IF(load_immediate(compiler
, TMP_REG1
, dstw
));
1712 return push_inst(compiler
, STFIWX
| FS(TMP_FREG1
) | A(dst
& REG_MASK
) | B(dstw
));
1715 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler
*compiler
, sljit_s32 op
,
1716 sljit_s32 dst
, sljit_sw dstw
,
1717 sljit_s32 src
, sljit_sw srcw
)
1719 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1721 sljit_s32 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG1
;
1723 if (src
& SLJIT_IMM
) {
1724 if (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_S32
)
1725 srcw
= (sljit_s32
)srcw
;
1726 FAIL_IF(load_immediate(compiler
, TMP_REG1
, srcw
));
1729 else if (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_S32
) {
1730 if (FAST_IS_REG(src
))
1731 FAIL_IF(push_inst(compiler
, EXTSW
| S(src
) | A(TMP_REG1
)));
1733 FAIL_IF(emit_op_mem(compiler
, INT_DATA
| SIGNED_DATA
| LOAD_DATA
, TMP_REG1
, src
, srcw
, TMP_REG1
));
1737 if (FAST_IS_REG(src
)) {
1738 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, src
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1739 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
| LOAD_DATA
, TMP_FREG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1742 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
| LOAD_DATA
, TMP_FREG1
, src
, srcw
, TMP_REG1
));
1744 FAIL_IF(push_inst(compiler
, FCFID
| FD(dst_r
) | FB(TMP_FREG1
)));
1746 if (dst
& SLJIT_MEM
)
1747 return emit_op_mem(compiler
, FLOAT_DATA(op
), TMP_FREG1
, dst
, dstw
, TMP_REG1
);
1748 if (op
& SLJIT_F32_OP
)
1749 return push_inst(compiler
, FRSP
| FD(dst_r
) | FB(dst_r
));
1750 return SLJIT_SUCCESS
;
1754 sljit_s32 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG1
;
1755 sljit_s32 invert_sign
= 1;
1757 if (src
& SLJIT_IMM
) {
1758 FAIL_IF(load_immediate(compiler
, TMP_REG1
, srcw
^ 0x80000000));
1762 else if (!FAST_IS_REG(src
)) {
1763 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
| SIGNED_DATA
| LOAD_DATA
, TMP_REG1
, src
, srcw
, TMP_REG1
));
1767 /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31)))
1768 The double precision format has exactly 53 bit precision, so the lower 32 bit represents
1769 the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000
1770 to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating
1771 point value, we need to substract 2^53 + 2^31 from the constructed value. */
1772 FAIL_IF(push_inst(compiler
, ADDIS
| D(TMP_REG2
) | A(0) | 0x4330));
1774 FAIL_IF(push_inst(compiler
, XORIS
| S(src
) | A(TMP_REG1
) | 0x8000));
1775 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, TMP_REG2
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET_HI
, TMP_REG1
));
1776 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, TMP_REG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET_LOW
, TMP_REG2
));
1777 FAIL_IF(push_inst(compiler
, ADDIS
| D(TMP_REG1
) | A(0) | 0x8000));
1778 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
| LOAD_DATA
, TMP_FREG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1779 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, TMP_REG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET_LOW
, TMP_REG2
));
1780 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
| LOAD_DATA
, TMP_FREG2
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1782 FAIL_IF(push_inst(compiler
, FSUB
| FD(dst_r
) | FA(TMP_FREG1
) | FB(TMP_FREG2
)));
1784 if (dst
& SLJIT_MEM
)
1785 return emit_op_mem(compiler
, FLOAT_DATA(op
), TMP_FREG1
, dst
, dstw
, TMP_REG1
);
1786 if (op
& SLJIT_F32_OP
)
1787 return push_inst(compiler
, FRSP
| FD(dst_r
) | FB(dst_r
));
1788 return SLJIT_SUCCESS
;
1793 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_cmp(struct sljit_compiler
*compiler
, sljit_s32 op
,
1794 sljit_s32 src1
, sljit_sw src1w
,
1795 sljit_s32 src2
, sljit_sw src2w
)
1797 if (src1
& SLJIT_MEM
) {
1798 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, src1
, src1w
, TMP_REG1
));
1802 if (src2
& SLJIT_MEM
) {
1803 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG2
, src2
, src2w
, TMP_REG2
));
1807 return push_inst(compiler
, FCMPU
| CRD(4) | FA(src1
) | FB(src2
));
1810 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fop1(struct sljit_compiler
*compiler
, sljit_s32 op
,
1811 sljit_s32 dst
, sljit_sw dstw
,
1812 sljit_s32 src
, sljit_sw srcw
)
1818 SLJIT_COMPILE_ASSERT((SLJIT_F32_OP
== 0x100) && !(DOUBLE_DATA
& 0x4), float_transfer_bit_error
);
1819 SELECT_FOP1_OPERATION_WITH_CHECKS(compiler
, op
, dst
, dstw
, src
, srcw
);
1821 if (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_F32
)
1824 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG1
;
1826 if (src
& SLJIT_MEM
) {
1827 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, dst_r
, src
, srcw
, TMP_REG1
));
1831 switch (GET_OPCODE(op
)) {
1832 case SLJIT_CONV_F64_FROM_F32
:
1834 if (op
& SLJIT_F32_OP
) {
1835 FAIL_IF(push_inst(compiler
, FRSP
| FD(dst_r
) | FB(src
)));
1841 if (dst_r
!= TMP_FREG1
)
1842 FAIL_IF(push_inst(compiler
, FMR
| FD(dst_r
) | FB(src
)));
1848 FAIL_IF(push_inst(compiler
, FNEG
| FD(dst_r
) | FB(src
)));
1851 FAIL_IF(push_inst(compiler
, FABS
| FD(dst_r
) | FB(src
)));
1855 if (dst
& SLJIT_MEM
)
1856 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
), dst_r
, dst
, dstw
, TMP_REG1
));
1857 return SLJIT_SUCCESS
;
1860 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fop2(struct sljit_compiler
*compiler
, sljit_s32 op
,
1861 sljit_s32 dst
, sljit_sw dstw
,
1862 sljit_s32 src1
, sljit_sw src1w
,
1863 sljit_s32 src2
, sljit_sw src2w
)
1868 CHECK(check_sljit_emit_fop2(compiler
, op
, dst
, dstw
, src1
, src1w
, src2
, src2w
));
1869 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1870 ADJUST_LOCAL_OFFSET(src1
, src1w
);
1871 ADJUST_LOCAL_OFFSET(src2
, src2w
);
1873 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG2
;
1875 if (src1
& SLJIT_MEM
) {
1876 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, src1
, src1w
, TMP_REG1
));
1880 if (src2
& SLJIT_MEM
) {
1881 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG2
, src2
, src2w
, TMP_REG2
));
1885 switch (GET_OPCODE(op
)) {
1887 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FADDS
, FADD
) | FD(dst_r
) | FA(src1
) | FB(src2
)));
1891 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FSUBS
, FSUB
) | FD(dst_r
) | FA(src1
) | FB(src2
)));
1895 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FMULS
, FMUL
) | FD(dst_r
) | FA(src1
) | FC(src2
) /* FMUL use FC as src2 */));
1899 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FDIVS
, FDIV
) | FD(dst_r
) | FA(src1
) | FB(src2
)));
1903 if (dst
& SLJIT_MEM
)
1904 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
), TMP_FREG2
, dst
, dstw
, TMP_REG1
));
1906 return SLJIT_SUCCESS
;
1911 /* --------------------------------------------------------------------- */
1912 /* Other instructions */
1913 /* --------------------------------------------------------------------- */
1915 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fast_enter(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
)
1918 CHECK(check_sljit_emit_fast_enter(compiler
, dst
, dstw
));
1919 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1921 if (FAST_IS_REG(dst
))
1922 return push_inst(compiler
, MFLR
| D(dst
));
1925 FAIL_IF(push_inst(compiler
, MFLR
| D(TMP_REG2
)));
1926 return emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0);
1929 /* --------------------------------------------------------------------- */
1930 /* Conditional instructions */
1931 /* --------------------------------------------------------------------- */
1933 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_label
* sljit_emit_label(struct sljit_compiler
*compiler
)
1935 struct sljit_label
*label
;
1938 CHECK_PTR(check_sljit_emit_label(compiler
));
1940 if (compiler
->last_label
&& compiler
->last_label
->size
== compiler
->size
)
1941 return compiler
->last_label
;
1943 label
= (struct sljit_label
*)ensure_abuf(compiler
, sizeof(struct sljit_label
));
1944 PTR_FAIL_IF(!label
);
1945 set_label(label
, compiler
);
1949 static sljit_ins
get_bo_bi_flags(sljit_s32 type
)
1953 return (12 << 21) | (2 << 16);
1955 case SLJIT_NOT_EQUAL
:
1956 return (4 << 21) | (2 << 16);
1959 case SLJIT_SIG_LESS
:
1960 return (12 << 21) | (0 << 16);
1962 case SLJIT_GREATER_EQUAL
:
1963 case SLJIT_SIG_GREATER_EQUAL
:
1964 return (4 << 21) | (0 << 16);
1967 case SLJIT_SIG_GREATER
:
1968 return (12 << 21) | (1 << 16);
1970 case SLJIT_LESS_EQUAL
:
1971 case SLJIT_SIG_LESS_EQUAL
:
1972 return (4 << 21) | (1 << 16);
1974 case SLJIT_LESS_F64
:
1975 return (12 << 21) | ((4 + 0) << 16);
1977 case SLJIT_GREATER_EQUAL_F64
:
1978 return (4 << 21) | ((4 + 0) << 16);
1980 case SLJIT_GREATER_F64
:
1981 return (12 << 21) | ((4 + 1) << 16);
1983 case SLJIT_LESS_EQUAL_F64
:
1984 return (4 << 21) | ((4 + 1) << 16);
1986 case SLJIT_OVERFLOW
:
1987 return (12 << 21) | (3 << 16);
1989 case SLJIT_NOT_OVERFLOW
:
1990 return (4 << 21) | (3 << 16);
1992 case SLJIT_EQUAL_F64
:
1993 return (12 << 21) | ((4 + 2) << 16);
1995 case SLJIT_NOT_EQUAL_F64
:
1996 return (4 << 21) | ((4 + 2) << 16);
1998 case SLJIT_UNORDERED_F64
:
1999 return (12 << 21) | ((4 + 3) << 16);
2001 case SLJIT_ORDERED_F64
:
2002 return (4 << 21) | ((4 + 3) << 16);
2005 SLJIT_ASSERT(type
>= SLJIT_JUMP
&& type
<= SLJIT_CALL_CDECL
);
2010 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_jump(struct sljit_compiler
*compiler
, sljit_s32 type
)
2012 struct sljit_jump
*jump
;
2013 sljit_ins bo_bi_flags
;
2016 CHECK_PTR(check_sljit_emit_jump(compiler
, type
));
2018 bo_bi_flags
= get_bo_bi_flags(type
& 0xff);
2022 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
2024 set_jump(jump
, compiler
, type
& SLJIT_REWRITABLE_JUMP
);
2027 /* In PPC, we don't need to touch the arguments. */
2028 if (type
< SLJIT_JUMP
)
2029 jump
->flags
|= IS_COND
;
2030 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2031 if (type
>= SLJIT_CALL
)
2032 jump
->flags
|= IS_CALL
;
2035 PTR_FAIL_IF(emit_const(compiler
, TMP_CALL_REG
, 0));
2036 PTR_FAIL_IF(push_inst(compiler
, MTCTR
| S(TMP_CALL_REG
)));
2037 jump
->addr
= compiler
->size
;
2038 PTR_FAIL_IF(push_inst(compiler
, BCCTR
| bo_bi_flags
| (type
>= SLJIT_FAST_CALL
? 1 : 0)));
2042 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_call(struct sljit_compiler
*compiler
, sljit_s32 type
,
2043 sljit_s32 arg_types
)
2046 CHECK_PTR(check_sljit_emit_call(compiler
, type
, arg_types
));
2048 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2049 PTR_FAIL_IF(call_with_args(compiler
, arg_types
, NULL
));
2052 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2053 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2054 compiler
->skip_checks
= 1;
2057 return sljit_emit_jump(compiler
, type
);
2060 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_ijump(struct sljit_compiler
*compiler
, sljit_s32 type
, sljit_s32 src
, sljit_sw srcw
)
2062 struct sljit_jump
*jump
= NULL
;
2066 CHECK(check_sljit_emit_ijump(compiler
, type
, src
, srcw
));
2067 ADJUST_LOCAL_OFFSET(src
, srcw
);
2069 if (FAST_IS_REG(src
)) {
2070 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2071 if (type
>= SLJIT_CALL
) {
2072 FAIL_IF(push_inst(compiler
, OR
| S(src
) | A(TMP_CALL_REG
) | B(src
)));
2073 src_r
= TMP_CALL_REG
;
2080 } else if (src
& SLJIT_IMM
) {
2081 /* These jumps are converted to jump/call instructions when possible. */
2082 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
2084 set_jump(jump
, compiler
, JUMP_ADDR
);
2085 jump
->u
.target
= srcw
;
2086 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2087 if (type
>= SLJIT_CALL
)
2088 jump
->flags
|= IS_CALL
;
2090 FAIL_IF(emit_const(compiler
, TMP_CALL_REG
, 0));
2091 src_r
= TMP_CALL_REG
;
2094 FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, TMP_CALL_REG
, 0, TMP_REG1
, 0, src
, srcw
));
2095 src_r
= TMP_CALL_REG
;
2098 FAIL_IF(push_inst(compiler
, MTCTR
| S(src_r
)));
2100 jump
->addr
= compiler
->size
;
2101 return push_inst(compiler
, BCCTR
| (20 << 21) | (type
>= SLJIT_FAST_CALL
? 1 : 0));
2104 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_icall(struct sljit_compiler
*compiler
, sljit_s32 type
,
2105 sljit_s32 arg_types
,
2106 sljit_s32 src
, sljit_sw srcw
)
2109 CHECK(check_sljit_emit_icall(compiler
, type
, arg_types
, src
, srcw
));
2111 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2112 if (src
& SLJIT_MEM
) {
2113 ADJUST_LOCAL_OFFSET(src
, srcw
);
2114 FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, TMP_CALL_REG
, 0, TMP_REG1
, 0, src
, srcw
));
2118 FAIL_IF(call_with_args(compiler
, arg_types
, &src
));
2121 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2122 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2123 compiler
->skip_checks
= 1;
2126 return sljit_emit_ijump(compiler
, type
, src
, srcw
);
2129 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_flags(struct sljit_compiler
*compiler
, sljit_s32 op
,
2130 sljit_s32 dst
, sljit_sw dstw
,
2133 sljit_s32 reg
, input_flags
, cr_bit
, invert
;
2134 sljit_s32 saved_op
= op
;
2135 sljit_sw saved_dstw
= dstw
;
2138 CHECK(check_sljit_emit_op_flags(compiler
, op
, dst
, dstw
, type
));
2139 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2141 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2142 input_flags
= (op
& SLJIT_I32_OP
) ? INT_DATA
: WORD_DATA
;
2144 input_flags
= WORD_DATA
;
2147 op
= GET_OPCODE(op
);
2148 reg
= (op
< SLJIT_ADD
&& FAST_IS_REG(dst
)) ? dst
: TMP_REG2
;
2150 if (op
>= SLJIT_ADD
&& (dst
& SLJIT_MEM
))
2151 FAIL_IF(emit_op_mem(compiler
, input_flags
| LOAD_DATA
, TMP_REG1
, dst
, dstw
, TMP_REG1
));
2156 switch (type
& 0xff) {
2158 case SLJIT_SIG_LESS
:
2161 case SLJIT_GREATER_EQUAL
:
2162 case SLJIT_SIG_GREATER_EQUAL
:
2167 case SLJIT_SIG_GREATER
:
2171 case SLJIT_LESS_EQUAL
:
2172 case SLJIT_SIG_LESS_EQUAL
:
2181 case SLJIT_NOT_EQUAL
:
2186 case SLJIT_OVERFLOW
:
2190 case SLJIT_NOT_OVERFLOW
:
2195 case SLJIT_LESS_F64
:
2199 case SLJIT_GREATER_EQUAL_F64
:
2204 case SLJIT_GREATER_F64
:
2208 case SLJIT_LESS_EQUAL_F64
:
2213 case SLJIT_EQUAL_F64
:
2217 case SLJIT_NOT_EQUAL_F64
:
2222 case SLJIT_UNORDERED_F64
:
2226 case SLJIT_ORDERED_F64
:
2232 SLJIT_UNREACHABLE();
2236 FAIL_IF(push_inst(compiler
, MFCR
| D(reg
)));
2237 FAIL_IF(push_inst(compiler
, RLWINM
| S(reg
) | A(reg
) | ((1 + (cr_bit
)) << 11) | (31 << 6) | (31 << 1)));
2240 FAIL_IF(push_inst(compiler
, XORI
| S(reg
) | A(reg
) | 0x1));
2242 if (op
< SLJIT_ADD
) {
2243 if (!(dst
& SLJIT_MEM
))
2244 return SLJIT_SUCCESS
;
2245 return emit_op_mem(compiler
, input_flags
, reg
, dst
, dstw
, TMP_REG1
);
2248 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2249 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2250 compiler
->skip_checks
= 1;
2252 if (dst
& SLJIT_MEM
)
2253 return sljit_emit_op2(compiler
, saved_op
, dst
, saved_dstw
, TMP_REG1
, 0, TMP_REG2
, 0);
2254 return sljit_emit_op2(compiler
, saved_op
, dst
, 0, dst
, 0, TMP_REG2
, 0);
2257 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_cmov(struct sljit_compiler
*compiler
, sljit_s32 type
,
2259 sljit_s32 src
, sljit_sw srcw
)
2262 CHECK(check_sljit_emit_cmov(compiler
, type
, dst_reg
, src
, srcw
));
2264 return sljit_emit_cmov_generic(compiler
, type
, dst_reg
, src
, srcw
);;
2267 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_mem(struct sljit_compiler
*compiler
, sljit_s32 type
,
2269 sljit_s32 mem
, sljit_sw memw
)
2271 sljit_s32 mem_flags
;
2275 CHECK(check_sljit_emit_mem(compiler
, type
, reg
, mem
, memw
));
2277 if (type
& SLJIT_MEM_POST
)
2278 return SLJIT_ERR_UNSUPPORTED
;
2280 switch (type
& 0xff) {
2283 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
2287 mem_flags
= WORD_DATA
;
2290 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2292 mem_flags
= INT_DATA
;
2296 mem_flags
= INT_DATA
;
2298 if (!(type
& SLJIT_MEM_STORE
) && !(type
& SLJIT_I32_OP
)) {
2299 if (mem
& OFFS_REG_MASK
)
2300 mem_flags
|= SIGNED_DATA
;
2302 return SLJIT_ERR_UNSUPPORTED
;
2309 mem_flags
= BYTE_DATA
;
2313 mem_flags
= HALF_DATA
;
2317 mem_flags
= HALF_DATA
| SIGNED_DATA
;
2321 SLJIT_UNREACHABLE();
2322 mem_flags
= WORD_DATA
;
2326 if (!(type
& SLJIT_MEM_STORE
))
2327 mem_flags
|= LOAD_DATA
;
2329 if (SLJIT_UNLIKELY(mem
& OFFS_REG_MASK
)) {
2331 return SLJIT_ERR_UNSUPPORTED
;
2333 if (type
& SLJIT_MEM_SUPP
)
2334 return SLJIT_SUCCESS
;
2336 inst
= updated_data_transfer_insts
[mem_flags
| INDEXED
];
2337 FAIL_IF(push_inst(compiler
, INST_CODE_AND_DST(inst
, 0, reg
) | A(mem
& REG_MASK
) | B(OFFS_REG(mem
))));
2340 if (memw
> SIMM_MAX
|| memw
< SIMM_MIN
)
2341 return SLJIT_ERR_UNSUPPORTED
;
2343 inst
= updated_data_transfer_insts
[mem_flags
];
2345 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2346 if ((inst
& INT_ALIGNED
) && (memw
& 0x3) != 0)
2347 return SLJIT_ERR_UNSUPPORTED
;
2350 if (type
& SLJIT_MEM_SUPP
)
2351 return SLJIT_SUCCESS
;
2353 FAIL_IF(push_inst(compiler
, INST_CODE_AND_DST(inst
, 0, reg
) | A(mem
& REG_MASK
) | IMM(memw
)));
2356 if ((mem_flags
& LOAD_DATA
) && (type
& 0xff) == SLJIT_MOV_S8
)
2357 return push_inst(compiler
, EXTSB
| S(reg
) | A(reg
));
2358 return SLJIT_SUCCESS
;
2361 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fmem(struct sljit_compiler
*compiler
, sljit_s32 type
,
2363 sljit_s32 mem
, sljit_sw memw
)
2365 sljit_s32 mem_flags
;
2369 CHECK(check_sljit_emit_fmem(compiler
, type
, freg
, mem
, memw
));
2371 if (type
& SLJIT_MEM_POST
)
2372 return SLJIT_ERR_UNSUPPORTED
;
2374 if (SLJIT_UNLIKELY(mem
& OFFS_REG_MASK
)) {
2376 return SLJIT_ERR_UNSUPPORTED
;
2379 if (memw
> SIMM_MAX
|| memw
< SIMM_MIN
)
2380 return SLJIT_ERR_UNSUPPORTED
;
2383 if (type
& SLJIT_MEM_SUPP
)
2384 return SLJIT_SUCCESS
;
2386 mem_flags
= FLOAT_DATA(type
);
2388 if (!(type
& SLJIT_MEM_STORE
))
2389 mem_flags
|= LOAD_DATA
;
2391 if (SLJIT_UNLIKELY(mem
& OFFS_REG_MASK
)) {
2392 inst
= updated_data_transfer_insts
[mem_flags
| INDEXED
];
2393 return push_inst(compiler
, INST_CODE_AND_DST(inst
, DOUBLE_DATA
, freg
) | A(mem
& REG_MASK
) | B(OFFS_REG(mem
)));
2396 inst
= updated_data_transfer_insts
[mem_flags
];
2397 return push_inst(compiler
, INST_CODE_AND_DST(inst
, DOUBLE_DATA
, freg
) | A(mem
& REG_MASK
) | IMM(memw
));
2400 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_const
* sljit_emit_const(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
, sljit_sw init_value
)
2402 struct sljit_const
*const_
;
2406 CHECK_PTR(check_sljit_emit_const(compiler
, dst
, dstw
, init_value
));
2407 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2409 const_
= (struct sljit_const
*)ensure_abuf(compiler
, sizeof(struct sljit_const
));
2410 PTR_FAIL_IF(!const_
);
2411 set_const(const_
, compiler
);
2413 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_REG2
;
2414 PTR_FAIL_IF(emit_const(compiler
, dst_r
, init_value
));
2416 if (dst
& SLJIT_MEM
)
2417 PTR_FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0));
2422 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_put_label
* sljit_emit_put_label(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
)
2424 struct sljit_put_label
*put_label
;
2428 CHECK_PTR(check_sljit_emit_put_label(compiler
, dst
, dstw
));
2429 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2431 put_label
= (struct sljit_put_label
*)ensure_abuf(compiler
, sizeof(struct sljit_put_label
));
2432 PTR_FAIL_IF(!put_label
);
2433 set_put_label(put_label
, compiler
, 0);
2435 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_REG2
;
2436 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
2437 PTR_FAIL_IF(emit_const(compiler
, dst_r
, 0));
2439 PTR_FAIL_IF(push_inst(compiler
, dst_r
));
2440 compiler
->size
+= 4;
2443 if (dst
& SLJIT_MEM
)
2444 PTR_FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0));