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, 7, 8, 9, 10, 11, 12, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 0, 13
115 /* --------------------------------------------------------------------- */
116 /* Instrucion forms */
117 /* --------------------------------------------------------------------- */
118 #define D(d) ((sljit_ins)reg_map[d] << 21)
119 #define S(s) ((sljit_ins)reg_map[s] << 21)
120 #define A(a) ((sljit_ins)reg_map[a] << 16)
121 #define B(b) ((sljit_ins)reg_map[b] << 11)
122 #define C(c) ((sljit_ins)reg_map[c] << 6)
123 #define FD(fd) ((sljit_ins)freg_map[fd] << 21)
124 #define FS(fs) ((sljit_ins)freg_map[fs] << 21)
125 #define FA(fa) ((sljit_ins)freg_map[fa] << 16)
126 #define FB(fb) ((sljit_ins)freg_map[fb] << 11)
127 #define FC(fc) ((sljit_ins)freg_map[fc] << 6)
128 #define IMM(imm) ((sljit_ins)(imm) & 0xffff)
129 #define CRD(d) ((sljit_ins)(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) ((sljit_ins)(opcode) << 26)
137 #define LO(opcode) ((sljit_ins)(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)
187 #define MFCR (HI(31) | LO(19))
188 #define MFLR (HI(31) | LO(339) | 0x80000)
189 #define MFXER (HI(31) | LO(339) | 0x10000)
190 #define MTCTR (HI(31) | LO(467) | 0x90000)
191 #define MTLR (HI(31) | LO(467) | 0x80000)
192 #define MTXER (HI(31) | LO(467) | 0x10000)
193 #define MULHD (HI(31) | LO(73))
194 #define MULHDU (HI(31) | LO(9))
195 #define MULHW (HI(31) | LO(75))
196 #define MULHWU (HI(31) | LO(11))
197 #define MULLD (HI(31) | LO(233))
198 #define MULLI (HI(7))
199 #define MULLW (HI(31) | LO(235))
200 #define NEG (HI(31) | LO(104))
202 #define NOR (HI(31) | LO(124))
203 #define OR (HI(31) | LO(444))
205 #define ORIS (HI(25))
206 #define RLDICL (HI(30))
207 #define RLWINM (HI(21))
208 #define SLD (HI(31) | LO(27))
209 #define SLW (HI(31) | LO(24))
210 #define SRAD (HI(31) | LO(794))
211 #define SRADI (HI(31) | LO(413 << 1))
212 #define SRAW (HI(31) | LO(792))
213 #define SRAWI (HI(31) | LO(824))
214 #define SRD (HI(31) | LO(539))
215 #define SRW (HI(31) | LO(536))
216 #define STD (HI(62) | 0)
217 #define STDU (HI(62) | 1)
218 #define STDUX (HI(31) | LO(181))
219 #define STFD (HI(54))
220 #define STFIWX (HI(31) | LO(983))
222 #define STWU (HI(37))
223 #define STWUX (HI(31) | LO(183))
224 #define SUBF (HI(31) | LO(40))
225 #define SUBFC (HI(31) | LO(8))
226 #define SUBFE (HI(31) | LO(136))
227 #define SUBFIC (HI(8))
228 #define XOR (HI(31) | LO(316))
229 #define XORI (HI(26))
230 #define XORIS (HI(27))
232 #define SIMM_MAX (0x7fff)
233 #define SIMM_MIN (-0x8000)
234 #define UIMM_MAX (0xffff)
236 #define RLDI(dst, src, sh, mb, type) \
237 (HI(30) | S(src) | A(dst) | ((sljit_ins)(type) << 2) | (((sljit_ins)(sh) & 0x1f) << 11) \
238 | (((sljit_ins)(sh) & 0x20) >> 4) | (((sljit_ins)(mb) & 0x1f) << 6) | ((sljit_ins)(mb) & 0x20))
240 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
241 SLJIT_API_FUNC_ATTRIBUTE
void sljit_set_function_context(void** func_ptr
, struct sljit_function_context
* context
, sljit_uw addr
, void* func
)
246 *func_ptr
= (void*)context
;
248 ptrs
= (sljit_uw
*)func
;
249 context
->addr
= addr
? addr
: ptrs
[0];
250 context
->r2
= ptrs
[1];
251 context
->r11
= ptrs
[2];
255 static sljit_s32
push_inst(struct sljit_compiler
*compiler
, sljit_ins ins
)
257 sljit_ins
*ptr
= (sljit_ins
*)ensure_buf(compiler
, sizeof(sljit_ins
));
261 return SLJIT_SUCCESS
;
264 static SLJIT_INLINE sljit_s32
detect_jump_type(struct sljit_jump
*jump
, sljit_ins
*code_ptr
, sljit_ins
*code
, sljit_sw executable_offset
)
267 sljit_uw target_addr
;
268 sljit_uw extra_jump_flags
;
270 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
271 if (jump
->flags
& (SLJIT_REWRITABLE_JUMP
| IS_CALL
))
274 if (jump
->flags
& SLJIT_REWRITABLE_JUMP
)
278 if (jump
->flags
& JUMP_ADDR
)
279 target_addr
= jump
->u
.target
;
281 SLJIT_ASSERT(jump
->flags
& JUMP_LABEL
);
282 target_addr
= (sljit_uw
)(code
+ jump
->u
.label
->size
) + (sljit_uw
)executable_offset
;
285 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
286 if (jump
->flags
& IS_CALL
)
290 diff
= ((sljit_sw
)target_addr
- (sljit_sw
)(code_ptr
) - executable_offset
) & ~0x3l
;
292 extra_jump_flags
= 0;
293 if (jump
->flags
& IS_COND
) {
294 if (diff
<= 0x7fff && diff
>= -0x8000) {
295 jump
->flags
|= PATCH_B
;
298 if (target_addr
<= 0xffff) {
299 jump
->flags
|= PATCH_B
| PATCH_ABS_B
;
302 extra_jump_flags
= REMOVE_COND
;
304 diff
-= SSIZE_OF(ins
);
307 if (diff
<= 0x01ffffff && diff
>= -0x02000000) {
308 jump
->flags
|= PATCH_B
| extra_jump_flags
;
312 if (target_addr
<= 0x03ffffff) {
313 jump
->flags
|= PATCH_B
| PATCH_ABS_B
| extra_jump_flags
;
317 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
318 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
321 if (target_addr
<= 0x7fffffff) {
322 jump
->flags
|= PATCH_ABS32
;
326 if (target_addr
<= 0x7fffffffffffl
) {
327 jump
->flags
|= PATCH_ABS48
;
335 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
337 static SLJIT_INLINE sljit_sw
put_label_get_length(struct sljit_put_label
*put_label
, sljit_uw max_label
)
339 if (max_label
< 0x100000000l
) {
340 put_label
->flags
= 0;
344 if (max_label
< 0x1000000000000l
) {
345 put_label
->flags
= 1;
349 put_label
->flags
= 2;
353 static SLJIT_INLINE
void put_label_set(struct sljit_put_label
*put_label
)
355 sljit_uw addr
= put_label
->label
->addr
;
356 sljit_ins
*inst
= (sljit_ins
*)put_label
->addr
;
357 sljit_u32 reg
= *inst
;
359 if (put_label
->flags
== 0) {
360 SLJIT_ASSERT(addr
< 0x100000000l
);
361 inst
[0] = ORIS
| S(TMP_ZERO
) | A(reg
) | IMM(addr
>> 16);
364 if (put_label
->flags
== 1) {
365 SLJIT_ASSERT(addr
< 0x1000000000000l
);
366 inst
[0] = ORI
| S(TMP_ZERO
) | A(reg
) | IMM(addr
>> 32);
369 inst
[0] = ORIS
| S(TMP_ZERO
) | A(reg
) | IMM(addr
>> 48);
370 inst
[1] = ORI
| S(reg
) | A(reg
) | IMM((addr
>> 32) & 0xffff);
374 inst
[1] = RLDI(reg
, reg
, 32, 31, 1);
375 inst
[2] = ORIS
| S(reg
) | A(reg
) | IMM((addr
>> 16) & 0xffff);
379 inst
[1] = ORI
| S(reg
) | A(reg
) | IMM(addr
& 0xffff);
384 SLJIT_API_FUNC_ATTRIBUTE
void* sljit_generate_code(struct sljit_compiler
*compiler
)
386 struct sljit_memory_fragment
*buf
;
393 sljit_sw executable_offset
;
396 struct sljit_label
*label
;
397 struct sljit_jump
*jump
;
398 struct sljit_const
*const_
;
399 struct sljit_put_label
*put_label
;
402 CHECK_PTR(check_sljit_generate_code(compiler
));
403 reverse_buf(compiler
);
405 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
406 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
407 compiler
->size
+= (compiler
->size
& 0x1) + (sizeof(struct sljit_function_context
) / sizeof(sljit_ins
));
409 compiler
->size
+= (sizeof(struct sljit_function_context
) / sizeof(sljit_ins
));
412 code
= (sljit_ins
*)SLJIT_MALLOC_EXEC(compiler
->size
* sizeof(sljit_ins
), compiler
->exec_allocator_data
);
413 PTR_FAIL_WITH_EXEC_IF(code
);
419 executable_offset
= SLJIT_EXEC_OFFSET(code
);
421 label
= compiler
->labels
;
422 jump
= compiler
->jumps
;
423 const_
= compiler
->consts
;
424 put_label
= compiler
->put_labels
;
427 buf_ptr
= (sljit_ins
*)buf
->memory
;
428 buf_end
= buf_ptr
+ (buf
->used_size
>> 2);
430 *code_ptr
= *buf_ptr
++;
431 if (next_addr
== word_count
) {
432 SLJIT_ASSERT(!label
|| label
->size
>= word_count
);
433 SLJIT_ASSERT(!jump
|| jump
->addr
>= word_count
);
434 SLJIT_ASSERT(!const_
|| const_
->addr
>= word_count
);
435 SLJIT_ASSERT(!put_label
|| put_label
->addr
>= word_count
);
437 /* These structures are ordered by their address. */
438 if (label
&& label
->size
== word_count
) {
439 /* Just recording the address. */
440 label
->addr
= (sljit_uw
)SLJIT_ADD_EXEC_OFFSET(code_ptr
, executable_offset
);
441 label
->size
= (sljit_uw
)(code_ptr
- code
);
444 if (jump
&& jump
->addr
== word_count
) {
445 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
446 jump
->addr
= (sljit_uw
)(code_ptr
- 3);
448 jump
->addr
= (sljit_uw
)(code_ptr
- 6);
450 if (detect_jump_type(jump
, code_ptr
, code
, executable_offset
)) {
451 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
452 code_ptr
[-3] = code_ptr
[0];
455 if (jump
->flags
& PATCH_ABS32
) {
457 code_ptr
[-1] = code_ptr
[2];
458 code_ptr
[0] = code_ptr
[3];
460 else if (jump
->flags
& PATCH_ABS48
) {
462 code_ptr
[-1] = code_ptr
[0];
463 code_ptr
[0] = code_ptr
[1];
464 /* rldicr rX,rX,32,31 -> rX,rX,16,47 */
465 SLJIT_ASSERT((code_ptr
[-3] & 0xfc00ffff) == 0x780007c6);
466 code_ptr
[-3] ^= 0x8422;
468 code_ptr
[-2] ^= 0x4000000;
471 code_ptr
[-6] = code_ptr
[0];
475 if (jump
->flags
& REMOVE_COND
) {
476 code_ptr
[0] = BCx
| (2 << 2) | ((code_ptr
[0] ^ (8 << 21)) & 0x03ff0001);
478 jump
->addr
+= sizeof(sljit_ins
);
480 jump
->flags
-= IS_COND
;
485 if (const_
&& const_
->addr
== word_count
) {
486 const_
->addr
= (sljit_uw
)code_ptr
;
487 const_
= const_
->next
;
489 if (put_label
&& put_label
->addr
== word_count
) {
490 SLJIT_ASSERT(put_label
->label
);
491 put_label
->addr
= (sljit_uw
)code_ptr
;
492 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
493 code_ptr
+= put_label_get_length(put_label
, (sljit_uw
)(SLJIT_ADD_EXEC_OFFSET(code
, executable_offset
) + put_label
->label
->size
));
496 put_label
= put_label
->next
;
498 next_addr
= compute_next_addr(label
, jump
, const_
, put_label
);
502 } while (buf_ptr
< buf_end
);
507 if (label
&& label
->size
== word_count
) {
508 label
->addr
= (sljit_uw
)SLJIT_ADD_EXEC_OFFSET(code_ptr
, executable_offset
);
509 label
->size
= (sljit_uw
)(code_ptr
- code
);
513 SLJIT_ASSERT(!label
);
515 SLJIT_ASSERT(!const_
);
516 SLJIT_ASSERT(!put_label
);
518 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
519 SLJIT_ASSERT(code_ptr
- code
<= (sljit_sw
)(compiler
->size
- (sizeof(struct sljit_function_context
) / sizeof(sljit_ins
))));
521 SLJIT_ASSERT(code_ptr
- code
<= (sljit_sw
)compiler
->size
);
524 jump
= compiler
->jumps
;
527 addr
= (jump
->flags
& JUMP_LABEL
) ? jump
->u
.label
->addr
: jump
->u
.target
;
528 buf_ptr
= (sljit_ins
*)jump
->addr
;
530 if (jump
->flags
& PATCH_B
) {
531 if (jump
->flags
& IS_COND
) {
532 if (!(jump
->flags
& PATCH_ABS_B
)) {
533 addr
-= (sljit_uw
)SLJIT_ADD_EXEC_OFFSET(buf_ptr
, executable_offset
);
534 SLJIT_ASSERT((sljit_sw
)addr
<= 0x7fff && (sljit_sw
)addr
>= -0x8000);
535 *buf_ptr
= BCx
| ((sljit_ins
)addr
& 0xfffc) | ((*buf_ptr
) & 0x03ff0001);
538 SLJIT_ASSERT(addr
<= 0xffff);
539 *buf_ptr
= BCx
| ((sljit_ins
)addr
& 0xfffc) | 0x2 | ((*buf_ptr
) & 0x03ff0001);
543 if (!(jump
->flags
& PATCH_ABS_B
)) {
544 addr
-= (sljit_uw
)SLJIT_ADD_EXEC_OFFSET(buf_ptr
, executable_offset
);
545 SLJIT_ASSERT((sljit_sw
)addr
<= 0x01ffffff && (sljit_sw
)addr
>= -0x02000000);
546 *buf_ptr
= Bx
| ((sljit_ins
)addr
& 0x03fffffc) | ((*buf_ptr
) & 0x1);
549 SLJIT_ASSERT(addr
<= 0x03ffffff);
550 *buf_ptr
= Bx
| ((sljit_ins
)addr
& 0x03fffffc) | 0x2 | ((*buf_ptr
) & 0x1);
556 /* Set the fields of immediate loads. */
557 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
558 SLJIT_ASSERT(((buf_ptr
[0] | buf_ptr
[1]) & 0xffff) == 0);
559 buf_ptr
[0] |= (sljit_ins
)(addr
>> 16) & 0xffff;
560 buf_ptr
[1] |= (sljit_ins
)addr
& 0xffff;
562 if (jump
->flags
& PATCH_ABS32
) {
563 SLJIT_ASSERT(addr
<= 0x7fffffff);
564 SLJIT_ASSERT(((buf_ptr
[0] | buf_ptr
[1]) & 0xffff) == 0);
565 buf_ptr
[0] |= (sljit_ins
)(addr
>> 16) & 0xffff;
566 buf_ptr
[1] |= (sljit_ins
)addr
& 0xffff;
570 if (jump
->flags
& PATCH_ABS48
) {
571 SLJIT_ASSERT(addr
<= 0x7fffffffffff);
572 SLJIT_ASSERT(((buf_ptr
[0] | buf_ptr
[1] | buf_ptr
[3]) & 0xffff) == 0);
573 buf_ptr
[0] |= (sljit_ins
)(addr
>> 32) & 0xffff;
574 buf_ptr
[1] |= (sljit_ins
)(addr
>> 16) & 0xffff;
575 buf_ptr
[3] |= (sljit_ins
)addr
& 0xffff;
579 SLJIT_ASSERT(((buf_ptr
[0] | buf_ptr
[1] | buf_ptr
[3] | buf_ptr
[4]) & 0xffff) == 0);
580 buf_ptr
[0] |= (sljit_ins
)(addr
>> 48) & 0xffff;
581 buf_ptr
[1] |= (sljit_ins
)(addr
>> 32) & 0xffff;
582 buf_ptr
[3] |= (sljit_ins
)(addr
>> 16) & 0xffff;
583 buf_ptr
[4] |= (sljit_ins
)addr
& 0xffff;
589 put_label
= compiler
->put_labels
;
591 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
592 addr
= put_label
->label
->addr
;
593 buf_ptr
= (sljit_ins
*)put_label
->addr
;
595 SLJIT_ASSERT((buf_ptr
[0] & 0xfc1f0000) == ADDIS
&& (buf_ptr
[1] & 0xfc000000) == ORI
);
596 buf_ptr
[0] |= (addr
>> 16) & 0xffff;
597 buf_ptr
[1] |= addr
& 0xffff;
599 put_label_set(put_label
);
601 put_label
= put_label
->next
;
604 compiler
->error
= SLJIT_ERR_COMPILED
;
605 compiler
->executable_offset
= executable_offset
;
606 compiler
->executable_size
= (sljit_uw
)(code_ptr
- code
) * sizeof(sljit_ins
);
608 code
= (sljit_ins
*)SLJIT_ADD_EXEC_OFFSET(code
, executable_offset
);
610 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
611 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
612 if (((sljit_sw
)code_ptr
) & 0x4)
615 sljit_set_function_context(NULL
, (struct sljit_function_context
*)code_ptr
, (sljit_uw
)code
, (void*)sljit_generate_code
);
618 code_ptr
= (sljit_ins
*)SLJIT_ADD_EXEC_OFFSET(code_ptr
, executable_offset
);
620 SLJIT_CACHE_FLUSH(code
, code_ptr
);
621 SLJIT_UPDATE_WX_FLAGS(code
, code_ptr
, 1);
623 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
630 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_has_cpu_feature(sljit_s32 feature_type
)
632 switch (feature_type
) {
634 #ifdef SLJIT_IS_FPU_AVAILABLE
635 return SLJIT_IS_FPU_AVAILABLE
;
637 /* Available by default. */
641 /* A saved register is set to a zero value. */
642 case SLJIT_HAS_ZERO_REGISTER
:
644 case SLJIT_HAS_PREFETCH
:
652 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_cmp_info(sljit_s32 type
)
654 return (type
>= SLJIT_UNORDERED
&& type
<= SLJIT_ORDERED_LESS_EQUAL
);
657 /* --------------------------------------------------------------------- */
659 /* --------------------------------------------------------------------- */
663 /* Creates an index in data_transfer_insts array. */
664 #define LOAD_DATA 0x01
666 #define SIGNED_DATA 0x04
668 #define WORD_DATA 0x00
669 #define BYTE_DATA 0x08
670 #define HALF_DATA 0x10
671 #define INT_DATA 0x18
672 /* Separates integer and floating point registers */
674 #define DOUBLE_DATA 0x20
676 #define MEM_MASK 0x7f
678 /* Other inp_flags. */
680 /* Integer opertion and set flags -> requires exts on 64 bit systems. */
681 #define ALT_SIGN_EXT 0x000100
682 /* This flag affects the RC() and OERC() macros. */
683 #define ALT_SET_FLAGS 0x000400
684 #define ALT_FORM1 0x001000
685 #define ALT_FORM2 0x002000
686 #define ALT_FORM3 0x004000
687 #define ALT_FORM4 0x008000
688 #define ALT_FORM5 0x010000
690 /* Source and destination is register. */
691 #define REG_DEST 0x000001
692 #define REG1_SOURCE 0x000002
693 #define REG2_SOURCE 0x000004
695 ALT_SIGN_EXT 0x000100
696 ALT_SET_FLAGS 0x000200
699 ALT_FORM5 0x010000 */
701 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
702 #include "sljitNativePPC_32.c"
704 #include "sljitNativePPC_64.c"
707 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
708 #define STACK_STORE STW
709 #define STACK_LOAD LWZ
711 #define STACK_STORE STD
712 #define STACK_LOAD LD
715 #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
716 #define LR_SAVE_OFFSET 2 * SSIZE_OF(sw)
718 #define LR_SAVE_OFFSET SSIZE_OF(sw)
721 #define STACK_MAX_DISTANCE (0x8000 - SSIZE_OF(sw) - LR_SAVE_OFFSET)
723 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_enter(struct sljit_compiler
*compiler
,
724 sljit_s32 options
, sljit_s32 arg_types
, sljit_s32 scratches
, sljit_s32 saveds
,
725 sljit_s32 fscratches
, sljit_s32 fsaveds
, sljit_s32 local_size
)
727 sljit_s32 i
, tmp
, base
, offset
;
728 sljit_s32 word_arg_count
= 0;
729 sljit_s32 saved_arg_count
= SLJIT_KEPT_SAVEDS_COUNT(options
);
730 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
731 sljit_s32 arg_count
= 0;
735 CHECK(check_sljit_emit_enter(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
));
736 set_emit_enter(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
);
738 local_size
+= GET_SAVED_REGISTERS_SIZE(scratches
, saveds
- saved_arg_count
, 1)
739 + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches
, fsaveds
, sizeof(sljit_f64
));
740 local_size
= (local_size
+ SLJIT_LOCALS_OFFSET
+ 15) & ~0xf;
741 compiler
->local_size
= local_size
;
743 FAIL_IF(push_inst(compiler
, MFLR
| D(0)));
748 if (local_size
<= STACK_MAX_DISTANCE
) {
749 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
750 FAIL_IF(push_inst(compiler
, STWU
| S(SLJIT_SP
) | A(SLJIT_SP
) | IMM(-local_size
)));
752 FAIL_IF(push_inst(compiler
, STDU
| S(SLJIT_SP
) | A(SLJIT_SP
) | IMM(-local_size
)));
756 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_SP
) | A(TMP_REG1
) | B(SLJIT_SP
)));
757 FAIL_IF(load_immediate(compiler
, TMP_REG2
, -local_size
));
758 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
759 FAIL_IF(push_inst(compiler
, STWUX
| S(SLJIT_SP
) | A(SLJIT_SP
) | B(TMP_REG2
)));
761 FAIL_IF(push_inst(compiler
, STDUX
| S(SLJIT_SP
) | A(SLJIT_SP
) | B(TMP_REG2
)));
767 tmp
= SLJIT_FS0
- fsaveds
;
768 for (i
= SLJIT_FS0
; i
> tmp
; i
--) {
769 offset
-= SSIZE_OF(f64
);
770 FAIL_IF(push_inst(compiler
, STFD
| FS(i
) | A(base
) | IMM(offset
)));
773 for (i
= fscratches
; i
>= SLJIT_FIRST_SAVED_FLOAT_REG
; i
--) {
774 offset
-= SSIZE_OF(f64
);
775 FAIL_IF(push_inst(compiler
, STFD
| FS(i
) | A(base
) | IMM(offset
)));
778 offset
-= SSIZE_OF(sw
);
779 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(TMP_ZERO
) | A(base
) | IMM(offset
)));
781 tmp
= SLJIT_S0
- saveds
;
782 for (i
= SLJIT_S0
- saved_arg_count
; i
> tmp
; i
--) {
783 offset
-= SSIZE_OF(sw
);
784 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(i
) | A(base
) | IMM(offset
)));
787 for (i
= scratches
; i
>= SLJIT_FIRST_SAVED_REG
; i
--) {
788 offset
-= SSIZE_OF(sw
);
789 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(i
) | A(base
) | IMM(offset
)));
792 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(0) | A(base
) | IMM(local_size
+ LR_SAVE_OFFSET
)));
793 FAIL_IF(push_inst(compiler
, ADDI
| D(TMP_ZERO
) | A(0) | 0));
795 arg_types
>>= SLJIT_ARG_SHIFT
;
797 while (arg_types
> 0) {
798 if ((arg_types
& SLJIT_ARG_MASK
) < SLJIT_ARG_TYPE_F64
) {
799 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
801 if (!(arg_types
& SLJIT_ARG_TYPE_SCRATCH_REG
)) {
802 tmp
= SLJIT_S0
- saved_arg_count
;
804 } else if (arg_count
!= word_arg_count
)
805 tmp
= SLJIT_R0
+ word_arg_count
;
809 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_R0
+ arg_count
) | A(tmp
) | B(SLJIT_R0
+ arg_count
)));
812 if (!(arg_types
& SLJIT_ARG_TYPE_SCRATCH_REG
)) {
813 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_R0
+ word_arg_count
) | A(SLJIT_S0
- saved_arg_count
) | B(SLJIT_R0
+ word_arg_count
)));
820 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
823 arg_types
>>= SLJIT_ARG_SHIFT
;
826 return SLJIT_SUCCESS
;
829 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_set_context(struct sljit_compiler
*compiler
,
830 sljit_s32 options
, sljit_s32 arg_types
, sljit_s32 scratches
, sljit_s32 saveds
,
831 sljit_s32 fscratches
, sljit_s32 fsaveds
, sljit_s32 local_size
)
834 CHECK(check_sljit_set_context(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
));
835 set_set_context(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
);
837 local_size
+= GET_SAVED_REGISTERS_SIZE(scratches
, saveds
- SLJIT_KEPT_SAVEDS_COUNT(options
), 1)
838 + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches
, fsaveds
, sizeof(sljit_f64
));
839 compiler
->local_size
= (local_size
+ SLJIT_LOCALS_OFFSET
+ 15) & ~0xf;
840 return SLJIT_SUCCESS
;
844 static sljit_s32
emit_stack_frame_release(struct sljit_compiler
*compiler
)
846 sljit_s32 i
, tmp
, base
, offset
;
847 sljit_s32 local_size
= compiler
->local_size
;
850 if (local_size
> STACK_MAX_DISTANCE
) {
852 if (local_size
> 2 * STACK_MAX_DISTANCE
+ LR_SAVE_OFFSET
) {
853 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(base
) | A(SLJIT_SP
) | IMM(0)));
856 FAIL_IF(push_inst(compiler
, ADDI
| D(TMP_REG1
) | A(SLJIT_SP
) | IMM(local_size
- STACK_MAX_DISTANCE
)));
857 local_size
= STACK_MAX_DISTANCE
;
862 FAIL_IF(push_inst(compiler
, STACK_LOAD
| S(0) | A(base
) | IMM(offset
+ LR_SAVE_OFFSET
)));
864 tmp
= SLJIT_FS0
- compiler
->fsaveds
;
865 for (i
= SLJIT_FS0
; i
> tmp
; i
--) {
866 offset
-= SSIZE_OF(f64
);
867 FAIL_IF(push_inst(compiler
, LFD
| FS(i
) | A(base
) | IMM(offset
)));
870 for (i
= compiler
->fscratches
; i
>= SLJIT_FIRST_SAVED_FLOAT_REG
; i
--) {
871 offset
-= SSIZE_OF(f64
);
872 FAIL_IF(push_inst(compiler
, LFD
| FS(i
) | A(base
) | IMM(offset
)));
875 offset
-= SSIZE_OF(sw
);
876 FAIL_IF(push_inst(compiler
, STACK_LOAD
| S(TMP_ZERO
) | A(base
) | IMM(offset
)));
878 tmp
= SLJIT_S0
- compiler
->saveds
;
879 for (i
= SLJIT_S0
- SLJIT_KEPT_SAVEDS_COUNT(compiler
->options
); i
> tmp
; i
--) {
880 offset
-= SSIZE_OF(sw
);
881 FAIL_IF(push_inst(compiler
, STACK_LOAD
| S(i
) | A(base
) | IMM(offset
)));
884 for (i
= compiler
->scratches
; i
>= SLJIT_FIRST_SAVED_REG
; i
--) {
885 offset
-= SSIZE_OF(sw
);
886 FAIL_IF(push_inst(compiler
, STACK_LOAD
| S(i
) | A(base
) | IMM(offset
)));
889 push_inst(compiler
, MTLR
| S(0));
892 return push_inst(compiler
, ADDI
| D(SLJIT_SP
) | A(base
) | IMM(local_size
));
894 SLJIT_ASSERT(base
== TMP_REG1
);
895 return push_inst(compiler
, OR
| S(base
) | A(SLJIT_SP
) | B(base
));
898 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_return_void(struct sljit_compiler
*compiler
)
901 CHECK(check_sljit_emit_return_void(compiler
));
903 FAIL_IF(emit_stack_frame_release(compiler
));
904 return push_inst(compiler
, BLR
);
910 /* --------------------------------------------------------------------- */
912 /* --------------------------------------------------------------------- */
914 /* s/l - store/load (1 bit)
915 i/x - immediate/indexed form
916 u/s - signed/unsigned (1 bit)
917 w/b/h/i - word/byte/half/int allowed (2 bit)
919 Some opcodes are repeated (e.g. store signed / unsigned byte is the same instruction). */
921 /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
922 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
923 #define INT_ALIGNED 0x10000
926 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
927 #define ARCH_32_64(a, b) a
928 #define INST_CODE_AND_DST(inst, flags, reg) \
929 ((sljit_ins)(inst) | (sljit_ins)(((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
931 #define ARCH_32_64(a, b) b
932 #define INST_CODE_AND_DST(inst, flags, reg) \
933 (((sljit_ins)(inst) & ~(sljit_ins)INT_ALIGNED) | (sljit_ins)(((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
936 static const sljit_ins data_transfer_insts
[64 + 16] = {
938 /* -------- Integer -------- */
942 /* w u i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED
| 0x0 /* std */),
943 /* w u i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED
| 0x0 /* ld */),
944 /* w u x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
945 /* w u x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
947 /* w s i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED
| 0x0 /* std */),
948 /* w s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED
| 0x0 /* ld */),
949 /* w s x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
950 /* w s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
954 /* b u i s */ HI(38) /* stb */,
955 /* b u i l */ HI(34) /* lbz */,
956 /* b u x s */ HI(31) | LO(215) /* stbx */,
957 /* b u x l */ HI(31) | LO(87) /* lbzx */,
959 /* b s i s */ HI(38) /* stb */,
960 /* b s i l */ HI(34) /* lbz */ /* EXTS_REQ */,
961 /* b s x s */ HI(31) | LO(215) /* stbx */,
962 /* b s x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
966 /* h u i s */ HI(44) /* sth */,
967 /* h u i l */ HI(40) /* lhz */,
968 /* h u x s */ HI(31) | LO(407) /* sthx */,
969 /* h u x l */ HI(31) | LO(279) /* lhzx */,
971 /* h s i s */ HI(44) /* sth */,
972 /* h s i l */ HI(42) /* lha */,
973 /* h s x s */ HI(31) | LO(407) /* sthx */,
974 /* h s x l */ HI(31) | LO(343) /* lhax */,
978 /* i u i s */ HI(36) /* stw */,
979 /* i u i l */ HI(32) /* lwz */,
980 /* i u x s */ HI(31) | LO(151) /* stwx */,
981 /* i u x l */ HI(31) | LO(23) /* lwzx */,
983 /* i s i s */ HI(36) /* stw */,
984 /* i s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED
| 0x2 /* lwa */),
985 /* i s x s */ HI(31) | LO(151) /* stwx */,
986 /* i s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
988 /* -------- Floating point -------- */
990 /* d i s */ HI(54) /* stfd */,
991 /* d i l */ HI(50) /* lfd */,
992 /* d x s */ HI(31) | LO(727) /* stfdx */,
993 /* d x l */ HI(31) | LO(599) /* lfdx */,
995 /* s i s */ HI(52) /* stfs */,
996 /* s i l */ HI(48) /* lfs */,
997 /* s x s */ HI(31) | LO(663) /* stfsx */,
998 /* s x l */ HI(31) | LO(535) /* lfsx */,
1001 static const sljit_ins updated_data_transfer_insts
[64] = {
1003 /* -------- Integer -------- */
1007 /* w u i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED
| 0x1 /* stdu */),
1008 /* w u i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED
| 0x1 /* ldu */),
1009 /* w u x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
1010 /* w u x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
1012 /* w s i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED
| 0x1 /* stdu */),
1013 /* w s i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED
| 0x1 /* ldu */),
1014 /* w s x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
1015 /* w s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
1019 /* b u i s */ HI(39) /* stbu */,
1020 /* b u i l */ HI(35) /* lbzu */,
1021 /* b u x s */ HI(31) | LO(247) /* stbux */,
1022 /* b u x l */ HI(31) | LO(119) /* lbzux */,
1024 /* b s i s */ HI(39) /* stbu */,
1025 /* b s i l */ 0 /* no such instruction */,
1026 /* b s x s */ HI(31) | LO(247) /* stbux */,
1027 /* b s x l */ 0 /* no such instruction */,
1031 /* h u i s */ HI(45) /* sthu */,
1032 /* h u i l */ HI(41) /* lhzu */,
1033 /* h u x s */ HI(31) | LO(439) /* sthux */,
1034 /* h u x l */ HI(31) | LO(311) /* lhzux */,
1036 /* h s i s */ HI(45) /* sthu */,
1037 /* h s i l */ HI(43) /* lhau */,
1038 /* h s x s */ HI(31) | LO(439) /* sthux */,
1039 /* h s x l */ HI(31) | LO(375) /* lhaux */,
1043 /* i u i s */ HI(37) /* stwu */,
1044 /* i u i l */ HI(33) /* lwzu */,
1045 /* i u x s */ HI(31) | LO(183) /* stwux */,
1046 /* i u x l */ HI(31) | LO(55) /* lwzux */,
1048 /* i s i s */ HI(37) /* stwu */,
1049 /* i s i l */ ARCH_32_64(HI(33) /* lwzu */, 0 /* no such instruction */),
1050 /* i s x s */ HI(31) | LO(183) /* stwux */,
1051 /* i s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
1053 /* -------- Floating point -------- */
1055 /* d i s */ HI(55) /* stfdu */,
1056 /* d i l */ HI(51) /* lfdu */,
1057 /* d x s */ HI(31) | LO(759) /* stfdux */,
1058 /* d x l */ HI(31) | LO(631) /* lfdux */,
1060 /* s i s */ HI(53) /* stfsu */,
1061 /* s i l */ HI(49) /* lfsu */,
1062 /* s x s */ HI(31) | LO(695) /* stfsux */,
1063 /* s x l */ HI(31) | LO(567) /* lfsux */,
1068 /* Simple cases, (no caching is required). */
1069 static sljit_s32
emit_op_mem(struct sljit_compiler
*compiler
, sljit_s32 inp_flags
, sljit_s32 reg
,
1070 sljit_s32 arg
, sljit_sw argw
, sljit_s32 tmp_reg
)
1074 sljit_sw high_short
;
1076 /* Should work when (arg & REG_MASK) == 0. */
1077 SLJIT_ASSERT(A(0) == 0);
1078 SLJIT_ASSERT(arg
& SLJIT_MEM
);
1080 if (SLJIT_UNLIKELY(arg
& OFFS_REG_MASK
)) {
1082 offs_reg
= OFFS_REG(arg
);
1085 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1086 FAIL_IF(push_inst(compiler
, RLWINM
| S(OFFS_REG(arg
)) | A(tmp_reg
) | ((sljit_ins
)argw
<< 11) | ((31 - (sljit_ins
)argw
) << 1)));
1088 FAIL_IF(push_inst(compiler
, RLDI(tmp_reg
, OFFS_REG(arg
), argw
, 63 - argw
, 1)));
1093 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
1095 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1096 SLJIT_ASSERT(!(inst
& INT_ALIGNED
));
1099 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
& REG_MASK
) | B(offs_reg
));
1102 inst
= data_transfer_insts
[inp_flags
& MEM_MASK
];
1105 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1106 if ((inst
& INT_ALIGNED
) && (argw
& 0x3) != 0) {
1107 FAIL_IF(load_immediate(compiler
, tmp_reg
, argw
));
1109 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
1110 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
) | B(tmp_reg
));
1114 if (argw
<= SIMM_MAX
&& argw
>= SIMM_MIN
)
1115 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
) | IMM(argw
));
1117 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1118 if (argw
<= 0x7fff7fffl
&& argw
>= -0x80000000l
) {
1121 high_short
= (sljit_s32
)(argw
+ ((argw
& 0x8000) << 1)) & ~0xffff;
1123 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1124 SLJIT_ASSERT(high_short
&& high_short
<= 0x7fffffffl
&& high_short
>= -0x80000000l
);
1126 SLJIT_ASSERT(high_short
);
1129 FAIL_IF(push_inst(compiler
, ADDIS
| D(tmp_reg
) | A(arg
) | IMM(high_short
>> 16)));
1130 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(tmp_reg
) | IMM(argw
));
1132 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1135 /* The rest is PPC-64 only. */
1137 FAIL_IF(load_immediate(compiler
, tmp_reg
, argw
));
1139 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
1140 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
) | B(tmp_reg
));
1144 static sljit_s32
emit_op(struct sljit_compiler
*compiler
, sljit_s32 op
, sljit_s32 input_flags
,
1145 sljit_s32 dst
, sljit_sw dstw
,
1146 sljit_s32 src1
, sljit_sw src1w
,
1147 sljit_s32 src2
, sljit_sw src2w
)
1149 /* arg1 goes to TMP_REG1 or src reg
1150 arg2 goes to TMP_REG2, imm or src reg
1151 result goes to TMP_REG2, so put result can use TMP_REG1. */
1152 sljit_s32 dst_r
= TMP_REG2
;
1155 sljit_s32 sugg_src2_r
= TMP_REG2
;
1156 sljit_s32 flags
= input_flags
& (ALT_FORM1
| ALT_FORM2
| ALT_FORM3
| ALT_FORM4
| ALT_FORM5
| ALT_SIGN_EXT
| ALT_SET_FLAGS
);
1158 /* Destination check. */
1159 if (FAST_IS_REG(dst
)) {
1161 /* The REG_DEST is only used by SLJIT_MOV operations, although
1162 * it is set for op2 operations with unset destination. */
1165 if (op
>= SLJIT_MOV
&& op
<= SLJIT_MOV_P
)
1166 sugg_src2_r
= dst_r
;
1170 if (FAST_IS_REG(src1
)) {
1172 flags
|= REG1_SOURCE
;
1174 else if (src1
& SLJIT_IMM
) {
1177 FAIL_IF(load_immediate(compiler
, TMP_REG1
, src1w
));
1182 FAIL_IF(emit_op_mem(compiler
, input_flags
| LOAD_DATA
, TMP_REG1
, src1
, src1w
, TMP_REG1
));
1187 if (FAST_IS_REG(src2
)) {
1189 flags
|= REG2_SOURCE
;
1191 if (!(flags
& REG_DEST
) && op
>= SLJIT_MOV
&& op
<= SLJIT_MOV_P
)
1194 else if (src2
& SLJIT_IMM
) {
1197 FAIL_IF(load_immediate(compiler
, sugg_src2_r
, src2w
));
1198 src2_r
= sugg_src2_r
;
1202 FAIL_IF(emit_op_mem(compiler
, input_flags
| LOAD_DATA
, sugg_src2_r
, src2
, src2w
, TMP_REG2
));
1203 src2_r
= sugg_src2_r
;
1206 FAIL_IF(emit_single_op(compiler
, op
, flags
, dst_r
, src1_r
, src2_r
));
1208 if (!(dst
& SLJIT_MEM
))
1209 return SLJIT_SUCCESS
;
1211 return emit_op_mem(compiler
, input_flags
, dst_r
, dst
, dstw
, TMP_REG1
);
1214 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op0(struct sljit_compiler
*compiler
, sljit_s32 op
)
1216 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1217 sljit_s32 int_op
= op
& SLJIT_32
;
1221 CHECK(check_sljit_emit_op0(compiler
, op
));
1223 op
= GET_OPCODE(op
);
1225 case SLJIT_BREAKPOINT
:
1227 return push_inst(compiler
, NOP
);
1230 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_R0
) | A(TMP_REG1
) | B(SLJIT_R0
)));
1231 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1232 FAIL_IF(push_inst(compiler
, MULLD
| D(SLJIT_R0
) | A(TMP_REG1
) | B(SLJIT_R1
)));
1233 return push_inst(compiler
, (op
== SLJIT_LMUL_UW
? MULHDU
: MULHD
) | D(SLJIT_R1
) | A(TMP_REG1
) | B(SLJIT_R1
));
1235 FAIL_IF(push_inst(compiler
, MULLW
| D(SLJIT_R0
) | A(TMP_REG1
) | B(SLJIT_R1
)));
1236 return push_inst(compiler
, (op
== SLJIT_LMUL_UW
? MULHWU
: MULHW
) | D(SLJIT_R1
) | A(TMP_REG1
) | B(SLJIT_R1
));
1238 case SLJIT_DIVMOD_UW
:
1239 case SLJIT_DIVMOD_SW
:
1240 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_R0
) | A(TMP_REG1
) | B(SLJIT_R0
)));
1241 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1242 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
)));
1243 FAIL_IF(push_inst(compiler
, (int_op
? MULLW
: MULLD
) | D(SLJIT_R1
) | A(SLJIT_R0
) | B(SLJIT_R1
)));
1245 FAIL_IF(push_inst(compiler
, (op
== SLJIT_DIVMOD_UW
? DIVWU
: DIVW
) | D(SLJIT_R0
) | A(SLJIT_R0
) | B(SLJIT_R1
)));
1246 FAIL_IF(push_inst(compiler
, MULLW
| D(SLJIT_R1
) | A(SLJIT_R0
) | B(SLJIT_R1
)));
1248 return push_inst(compiler
, SUBF
| D(SLJIT_R1
) | A(SLJIT_R1
) | B(TMP_REG1
));
1251 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1252 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
));
1254 return push_inst(compiler
, (op
== SLJIT_DIV_UW
? DIVWU
: DIVW
) | D(SLJIT_R0
) | A(SLJIT_R0
) | B(SLJIT_R1
));
1257 case SLJIT_SKIP_FRAMES_BEFORE_RETURN
:
1258 return SLJIT_SUCCESS
;
1261 return SLJIT_SUCCESS
;
1264 static sljit_s32
emit_prefetch(struct sljit_compiler
*compiler
,
1265 sljit_s32 src
, sljit_sw srcw
)
1267 if (!(src
& OFFS_REG_MASK
)) {
1268 if (srcw
== 0 && (src
& REG_MASK
))
1269 return push_inst(compiler
, DCBT
| A(0) | B(src
& REG_MASK
));
1271 FAIL_IF(load_immediate(compiler
, TMP_REG1
, srcw
));
1272 /* Works with SLJIT_MEM0() case as well. */
1273 return push_inst(compiler
, DCBT
| A(src
& REG_MASK
) | B(TMP_REG1
));
1279 return push_inst(compiler
, DCBT
| A(src
& REG_MASK
) | B(OFFS_REG(src
)));
1281 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1282 FAIL_IF(push_inst(compiler
, RLWINM
| S(OFFS_REG(src
)) | A(TMP_REG1
) | ((sljit_ins
)srcw
<< 11) | ((31 - (sljit_ins
)srcw
) << 1)));
1284 FAIL_IF(push_inst(compiler
, RLDI(TMP_REG1
, OFFS_REG(src
), srcw
, 63 - srcw
, 1)));
1286 return push_inst(compiler
, DCBT
| A(src
& REG_MASK
) | B(TMP_REG1
));
1289 #define EMIT_MOV(type, type_flags, type_cast) \
1290 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)
1292 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op1(struct sljit_compiler
*compiler
, sljit_s32 op
,
1293 sljit_s32 dst
, sljit_sw dstw
,
1294 sljit_s32 src
, sljit_sw srcw
)
1296 sljit_s32 flags
= HAS_FLAGS(op
) ? ALT_SET_FLAGS
: 0;
1297 sljit_s32 op_flags
= GET_ALL_FLAGS(op
);
1300 CHECK(check_sljit_emit_op1(compiler
, op
, dst
, dstw
, src
, srcw
));
1301 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1302 ADJUST_LOCAL_OFFSET(src
, srcw
);
1304 op
= GET_OPCODE(op
);
1306 if (GET_FLAG_TYPE(op_flags
) == SLJIT_OVERFLOW
)
1307 FAIL_IF(push_inst(compiler
, MTXER
| S(TMP_ZERO
)));
1309 if (op
< SLJIT_NOT
&& FAST_IS_REG(src
) && src
== dst
) {
1310 if (!TYPE_CAST_NEEDED(op
))
1311 return SLJIT_SUCCESS
;
1314 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1315 if (op_flags
& SLJIT_32
) {
1316 if (op
< SLJIT_NOT
) {
1317 if (src
& SLJIT_MEM
) {
1318 if (op
== SLJIT_MOV_S32
)
1321 else if (src
& SLJIT_IMM
) {
1322 if (op
== SLJIT_MOV_U32
)
1327 /* Most operations expect sign extended arguments. */
1328 flags
|= INT_DATA
| SIGNED_DATA
;
1329 if (HAS_FLAGS(op_flags
))
1330 flags
|= ALT_SIGN_EXT
;
1337 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1343 return emit_op(compiler
, SLJIT_MOV
, flags
| WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1345 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1347 return EMIT_MOV(SLJIT_MOV_U32
, INT_DATA
, (sljit_u32
));
1351 return EMIT_MOV(SLJIT_MOV_S32
, INT_DATA
| SIGNED_DATA
, (sljit_s32
));
1355 return EMIT_MOV(SLJIT_MOV_U8
, BYTE_DATA
, (sljit_u8
));
1358 return EMIT_MOV(SLJIT_MOV_S8
, BYTE_DATA
| SIGNED_DATA
, (sljit_s8
));
1361 return EMIT_MOV(SLJIT_MOV_U16
, HALF_DATA
, (sljit_u16
));
1364 return EMIT_MOV(SLJIT_MOV_S16
, HALF_DATA
| SIGNED_DATA
, (sljit_s16
));
1367 return emit_op(compiler
, SLJIT_NOT
, flags
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1370 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1371 return emit_op(compiler
, SLJIT_CLZ
, flags
| (!(op_flags
& SLJIT_32
) ? 0 : ALT_FORM1
), dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1373 return emit_op(compiler
, SLJIT_CLZ
, flags
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1377 return SLJIT_SUCCESS
;
1382 #define TEST_SL_IMM(src, srcw) \
1383 (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)
1385 #define TEST_UL_IMM(src, srcw) \
1386 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff))
1388 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1389 #define TEST_SH_IMM(src, srcw) \
1390 (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l)
1392 #define TEST_SH_IMM(src, srcw) \
1393 (((src) & SLJIT_IMM) && !((srcw) & 0xffff))
1396 #define TEST_UH_IMM(src, srcw) \
1397 (((src) & SLJIT_IMM) && !((srcw) & ~(sljit_sw)0xffff0000))
1399 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1400 #define TEST_ADD_IMM(src, srcw) \
1401 (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l)
1403 #define TEST_ADD_IMM(src, srcw) \
1407 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1408 #define TEST_UI_IMM(src, srcw) \
1409 (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
1411 #define TEST_UI_IMM(src, srcw) \
1415 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1416 #define TEST_ADD_FORM1(op) \
1417 (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \
1418 || (op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_32 | SLJIT_SET_Z | SLJIT_SET_CARRY))
1419 #define TEST_SUB_FORM2(op) \
1420 ((GET_FLAG_TYPE(op) >= SLJIT_SIG_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) \
1421 || (op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_32 | SLJIT_SET_Z))
1422 #define TEST_SUB_FORM3(op) \
1423 (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \
1424 || (op & (SLJIT_32 | SLJIT_SET_Z)) == (SLJIT_32 | SLJIT_SET_Z))
1426 #define TEST_ADD_FORM1(op) \
1427 (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1428 #define TEST_SUB_FORM2(op) \
1429 (GET_FLAG_TYPE(op) >= SLJIT_SIG_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL)
1430 #define TEST_SUB_FORM3(op) \
1431 (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1434 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op2(struct sljit_compiler
*compiler
, sljit_s32 op
,
1435 sljit_s32 dst
, sljit_sw dstw
,
1436 sljit_s32 src1
, sljit_sw src1w
,
1437 sljit_s32 src2
, sljit_sw src2w
)
1439 sljit_s32 flags
= HAS_FLAGS(op
) ? ALT_SET_FLAGS
: 0;
1442 CHECK(check_sljit_emit_op2(compiler
, op
, 0, dst
, dstw
, src1
, src1w
, src2
, src2w
));
1443 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1444 ADJUST_LOCAL_OFFSET(src1
, src1w
);
1445 ADJUST_LOCAL_OFFSET(src2
, src2w
);
1447 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1448 if (op
& SLJIT_32
) {
1449 /* Most operations expect sign extended arguments. */
1450 flags
|= INT_DATA
| SIGNED_DATA
;
1451 if (src1
& SLJIT_IMM
)
1452 src1w
= (sljit_s32
)(src1w
);
1453 if (src2
& SLJIT_IMM
)
1454 src2w
= (sljit_s32
)(src2w
);
1456 flags
|= ALT_SIGN_EXT
;
1459 if (GET_FLAG_TYPE(op
) == SLJIT_OVERFLOW
)
1460 FAIL_IF(push_inst(compiler
, MTXER
| S(TMP_ZERO
)));
1462 switch (GET_OPCODE(op
)) {
1464 compiler
->status_flags_state
= SLJIT_CURRENT_FLAGS_ADD
;
1466 if (TEST_ADD_FORM1(op
))
1467 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1469 if (!HAS_FLAGS(op
) && ((src1
| src2
) & SLJIT_IMM
)) {
1470 if (TEST_SL_IMM(src2
, src2w
)) {
1471 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1472 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1474 if (TEST_SL_IMM(src1
, src1w
)) {
1475 compiler
->imm
= (sljit_ins
)src1w
& 0xffff;
1476 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1478 if (TEST_SH_IMM(src2
, src2w
)) {
1479 compiler
->imm
= (sljit_ins
)(src2w
>> 16) & 0xffff;
1480 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1482 if (TEST_SH_IMM(src1
, src1w
)) {
1483 compiler
->imm
= (sljit_ins
)(src1w
>> 16) & 0xffff;
1484 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1486 /* Range between -1 and -32768 is covered above. */
1487 if (TEST_ADD_IMM(src2
, src2w
)) {
1488 compiler
->imm
= (sljit_ins
)src2w
& 0xffffffff;
1489 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1491 if (TEST_ADD_IMM(src1
, src1w
)) {
1492 compiler
->imm
= (sljit_ins
)src1w
& 0xffffffff;
1493 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM4
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1497 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1498 if ((op
& (SLJIT_32
| SLJIT_SET_Z
)) == (SLJIT_32
| SLJIT_SET_Z
)) {
1499 if (TEST_SL_IMM(src2
, src2w
)) {
1500 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1501 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM4
| ALT_FORM5
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1503 if (TEST_SL_IMM(src1
, src1w
)) {
1504 compiler
->imm
= (sljit_ins
)src1w
& 0xffff;
1505 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM4
| ALT_FORM5
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1507 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1510 if (HAS_FLAGS(op
)) {
1511 if (TEST_SL_IMM(src2
, src2w
)) {
1512 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1513 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1515 if (TEST_SL_IMM(src1
, src1w
)) {
1516 compiler
->imm
= (sljit_ins
)src1w
& 0xffff;
1517 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM3
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1520 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
);
1523 compiler
->status_flags_state
= SLJIT_CURRENT_FLAGS_ADD
;
1524 return emit_op(compiler
, SLJIT_ADDC
, flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1527 compiler
->status_flags_state
= SLJIT_CURRENT_FLAGS_SUB
;
1529 if (GET_FLAG_TYPE(op
) >= SLJIT_LESS
&& GET_FLAG_TYPE(op
) <= SLJIT_LESS_EQUAL
) {
1530 if (dst
== TMP_REG2
) {
1531 if (TEST_UL_IMM(src2
, src2w
)) {
1532 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1533 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM1
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1535 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1538 if ((src2
& SLJIT_IMM
) && src2w
>= 0 && src2w
<= (SIMM_MAX
+ 1)) {
1539 compiler
->imm
= (sljit_ins
)src2w
;
1540 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM1
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1542 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM1
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1545 if (dst
== TMP_REG2
&& GET_FLAG_TYPE(op
) <= SLJIT_SIG_LESS_EQUAL
) {
1546 if (TEST_SL_IMM(src2
, src2w
)) {
1547 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1548 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1550 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1553 if (TEST_SUB_FORM2(op
)) {
1554 if ((src2
& SLJIT_IMM
) && src2w
>= -SIMM_MAX
&& src2w
<= SIMM_MAX
) {
1555 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1556 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
| ALT_FORM3
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1558 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1561 if (TEST_SUB_FORM3(op
))
1562 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1564 if (TEST_SL_IMM(src2
, -src2w
)) {
1565 compiler
->imm
= (sljit_ins
)(-src2w
) & 0xffff;
1566 return emit_op(compiler
, SLJIT_ADD
, flags
| (!HAS_FLAGS(op
) ? ALT_FORM2
: ALT_FORM3
), dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1569 if (TEST_SL_IMM(src1
, src1w
) && !(op
& SLJIT_SET_Z
)) {
1570 compiler
->imm
= (sljit_ins
)src1w
& 0xffff;
1571 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM4
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1574 if (!HAS_FLAGS(op
)) {
1575 if (TEST_SH_IMM(src2
, -src2w
)) {
1576 compiler
->imm
= (sljit_ins
)((-src2w
) >> 16) & 0xffff;
1577 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1579 /* Range between -1 and -32768 is covered above. */
1580 if (TEST_ADD_IMM(src2
, -src2w
)) {
1581 compiler
->imm
= (sljit_ins
)-src2w
;
1582 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1586 /* We know ALT_SIGN_EXT is set if it is an SLJIT_32 on 64 bit systems. */
1587 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
);
1590 compiler
->status_flags_state
= SLJIT_CURRENT_FLAGS_SUB
;
1591 return emit_op(compiler
, SLJIT_SUBC
, flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1594 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1598 if (!HAS_FLAGS(op
)) {
1599 if (TEST_SL_IMM(src2
, src2w
)) {
1600 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1601 return emit_op(compiler
, SLJIT_MUL
, flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1603 if (TEST_SL_IMM(src1
, src1w
)) {
1604 compiler
->imm
= (sljit_ins
)src1w
& 0xffff;
1605 return emit_op(compiler
, SLJIT_MUL
, flags
| ALT_FORM1
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1609 FAIL_IF(push_inst(compiler
, MTXER
| S(TMP_ZERO
)));
1610 return emit_op(compiler
, SLJIT_MUL
, flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1615 /* Commutative unsigned operations. */
1616 if (!HAS_FLAGS(op
) || GET_OPCODE(op
) == SLJIT_AND
) {
1617 if (TEST_UL_IMM(src2
, src2w
)) {
1618 compiler
->imm
= (sljit_ins
)src2w
;
1619 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1621 if (TEST_UL_IMM(src1
, src1w
)) {
1622 compiler
->imm
= (sljit_ins
)src1w
;
1623 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM1
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1625 if (TEST_UH_IMM(src2
, src2w
)) {
1626 compiler
->imm
= (sljit_ins
)(src2w
>> 16) & 0xffff;
1627 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1629 if (TEST_UH_IMM(src1
, src1w
)) {
1630 compiler
->imm
= (sljit_ins
)(src1w
>> 16) & 0xffff;
1631 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM2
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1634 if (GET_OPCODE(op
) != SLJIT_AND
) {
1635 /* Unlike or and xor, the and resets unwanted bits as well. */
1636 if (TEST_UI_IMM(src2
, src2w
)) {
1637 compiler
->imm
= (sljit_ins
)src2w
;
1638 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1640 if (TEST_UI_IMM(src1
, src1w
)) {
1641 compiler
->imm
= (sljit_ins
)src1w
;
1642 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM3
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1645 return emit_op(compiler
, GET_OPCODE(op
), flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1650 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1654 if (src2
& SLJIT_IMM
) {
1655 compiler
->imm
= (sljit_ins
)src2w
;
1656 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1658 return emit_op(compiler
, GET_OPCODE(op
), flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1661 return SLJIT_SUCCESS
;
1664 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op2u(struct sljit_compiler
*compiler
, sljit_s32 op
,
1665 sljit_s32 src1
, sljit_sw src1w
,
1666 sljit_s32 src2
, sljit_sw src2w
)
1669 CHECK(check_sljit_emit_op2(compiler
, op
, 1, 0, 0, src1
, src1w
, src2
, src2w
));
1671 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
1672 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1673 compiler
->skip_checks
= 1;
1675 return sljit_emit_op2(compiler
, op
, TMP_REG2
, 0, src1
, src1w
, src2
, src2w
);
1678 #undef TEST_ADD_FORM1
1679 #undef TEST_SUB_FORM2
1680 #undef TEST_SUB_FORM3
1682 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_src(struct sljit_compiler
*compiler
, sljit_s32 op
,
1683 sljit_s32 src
, sljit_sw srcw
)
1686 CHECK(check_sljit_emit_op_src(compiler
, op
, src
, srcw
));
1687 ADJUST_LOCAL_OFFSET(src
, srcw
);
1690 case SLJIT_FAST_RETURN
:
1691 if (FAST_IS_REG(src
))
1692 FAIL_IF(push_inst(compiler
, MTLR
| S(src
)));
1694 FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, TMP_REG2
, 0, TMP_REG1
, 0, src
, srcw
));
1695 FAIL_IF(push_inst(compiler
, MTLR
| S(TMP_REG2
)));
1698 return push_inst(compiler
, BLR
);
1699 case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN
:
1700 return SLJIT_SUCCESS
;
1701 case SLJIT_PREFETCH_L1
:
1702 case SLJIT_PREFETCH_L2
:
1703 case SLJIT_PREFETCH_L3
:
1704 case SLJIT_PREFETCH_ONCE
:
1705 return emit_prefetch(compiler
, src
, srcw
);
1708 return SLJIT_SUCCESS
;
1711 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_get_register_index(sljit_s32 reg
)
1713 CHECK_REG_INDEX(check_sljit_get_register_index(reg
));
1714 return reg_map
[reg
];
1717 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_get_float_register_index(sljit_s32 reg
)
1719 CHECK_REG_INDEX(check_sljit_get_float_register_index(reg
));
1720 return freg_map
[reg
];
1723 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_custom(struct sljit_compiler
*compiler
,
1724 void *instruction
, sljit_u32 size
)
1727 CHECK(check_sljit_emit_op_custom(compiler
, instruction
, size
));
1729 return push_inst(compiler
, *(sljit_ins
*)instruction
);
1732 /* --------------------------------------------------------------------- */
1733 /* Floating point operators */
1734 /* --------------------------------------------------------------------- */
1736 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 6))
1737 #define SELECT_FOP(op, single, double) ((sljit_ins)((op & SLJIT_32) ? single : double))
1739 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1740 #define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw))
1742 #define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw))
1744 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
1745 #define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw))
1746 #define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw))
1748 #define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw))
1749 #define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw))
1752 #endif /* SLJIT_CONFIG_PPC_64 */
1754 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler
*compiler
, sljit_s32 op
,
1755 sljit_s32 dst
, sljit_sw dstw
,
1756 sljit_s32 src
, sljit_sw srcw
)
1758 if (src
& SLJIT_MEM
) {
1759 /* We can ignore the temporary data store on the stack from caching point of view. */
1760 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, src
, srcw
, TMP_REG1
));
1764 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1765 op
= GET_OPCODE(op
);
1766 FAIL_IF(push_inst(compiler
, (op
== SLJIT_CONV_S32_FROM_F64
? FCTIWZ
: FCTIDZ
) | FD(TMP_FREG1
) | FB(src
)));
1768 if (op
== SLJIT_CONV_SW_FROM_F64
) {
1769 if (FAST_IS_REG(dst
)) {
1770 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
, TMP_FREG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1771 return emit_op_mem(compiler
, WORD_DATA
| LOAD_DATA
, dst
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
);
1773 return emit_op_mem(compiler
, DOUBLE_DATA
, TMP_FREG1
, dst
, dstw
, TMP_REG1
);
1776 FAIL_IF(push_inst(compiler
, FCTIWZ
| FD(TMP_FREG1
) | FB(src
)));
1779 if (FAST_IS_REG(dst
)) {
1780 FAIL_IF(load_immediate(compiler
, TMP_REG1
, FLOAT_TMP_MEM_OFFSET
));
1781 FAIL_IF(push_inst(compiler
, STFIWX
| FS(TMP_FREG1
) | A(SLJIT_SP
) | B(TMP_REG1
)));
1782 return emit_op_mem(compiler
, INT_DATA
| LOAD_DATA
, dst
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
);
1785 SLJIT_ASSERT(dst
& SLJIT_MEM
);
1787 if (dst
& OFFS_REG_MASK
) {
1790 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1791 FAIL_IF(push_inst(compiler
, RLWINM
| S(OFFS_REG(dst
)) | A(TMP_REG1
) | ((sljit_ins
)dstw
<< 11) | ((31 - (sljit_ins
)dstw
) << 1)));
1793 FAIL_IF(push_inst(compiler
, RLDI(TMP_REG1
, OFFS_REG(dst
), dstw
, 63 - dstw
, 1)));
1798 dstw
= OFFS_REG(dst
);
1801 if ((dst
& REG_MASK
) && !dstw
) {
1802 dstw
= dst
& REG_MASK
;
1806 /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */
1807 FAIL_IF(load_immediate(compiler
, TMP_REG1
, dstw
));
1812 return push_inst(compiler
, STFIWX
| FS(TMP_FREG1
) | A(dst
& REG_MASK
) | B(dstw
));
1815 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler
*compiler
, sljit_s32 op
,
1816 sljit_s32 dst
, sljit_sw dstw
,
1817 sljit_s32 src
, sljit_sw srcw
)
1819 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1821 sljit_s32 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG1
;
1823 if (src
& SLJIT_IMM
) {
1824 if (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_S32
)
1825 srcw
= (sljit_s32
)srcw
;
1826 FAIL_IF(load_immediate(compiler
, TMP_REG1
, srcw
));
1829 else if (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_S32
) {
1830 if (FAST_IS_REG(src
))
1831 FAIL_IF(push_inst(compiler
, EXTSW
| S(src
) | A(TMP_REG1
)));
1833 FAIL_IF(emit_op_mem(compiler
, INT_DATA
| SIGNED_DATA
| LOAD_DATA
, TMP_REG1
, src
, srcw
, TMP_REG1
));
1837 if (FAST_IS_REG(src
)) {
1838 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, src
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1839 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
| LOAD_DATA
, TMP_FREG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1842 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
| LOAD_DATA
, TMP_FREG1
, src
, srcw
, TMP_REG1
));
1844 FAIL_IF(push_inst(compiler
, FCFID
| FD(dst_r
) | FB(TMP_FREG1
)));
1846 if (dst
& SLJIT_MEM
)
1847 return emit_op_mem(compiler
, FLOAT_DATA(op
), TMP_FREG1
, dst
, dstw
, TMP_REG1
);
1849 return push_inst(compiler
, FRSP
| FD(dst_r
) | FB(dst_r
));
1850 return SLJIT_SUCCESS
;
1854 sljit_s32 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG1
;
1855 sljit_s32 invert_sign
= 1;
1857 if (src
& SLJIT_IMM
) {
1858 FAIL_IF(load_immediate(compiler
, TMP_REG1
, srcw
^ (sljit_sw
)0x80000000));
1862 else if (!FAST_IS_REG(src
)) {
1863 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
| SIGNED_DATA
| LOAD_DATA
, TMP_REG1
, src
, srcw
, TMP_REG1
));
1867 /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31)))
1868 The double precision format has exactly 53 bit precision, so the lower 32 bit represents
1869 the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000
1870 to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating
1871 point value, we need to substract 2^53 + 2^31 from the constructed value. */
1872 FAIL_IF(push_inst(compiler
, ADDIS
| D(TMP_REG2
) | A(0) | 0x4330));
1874 FAIL_IF(push_inst(compiler
, XORIS
| S(src
) | A(TMP_REG1
) | 0x8000));
1875 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, TMP_REG2
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET_HI
, TMP_REG1
));
1876 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, TMP_REG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET_LOW
, TMP_REG2
));
1877 FAIL_IF(push_inst(compiler
, ADDIS
| D(TMP_REG1
) | A(0) | 0x8000));
1878 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
| LOAD_DATA
, TMP_FREG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1879 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, TMP_REG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET_LOW
, TMP_REG2
));
1880 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
| LOAD_DATA
, TMP_FREG2
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1882 FAIL_IF(push_inst(compiler
, FSUB
| FD(dst_r
) | FA(TMP_FREG1
) | FB(TMP_FREG2
)));
1884 if (dst
& SLJIT_MEM
)
1885 return emit_op_mem(compiler
, FLOAT_DATA(op
), TMP_FREG1
, dst
, dstw
, TMP_REG1
);
1887 return push_inst(compiler
, FRSP
| FD(dst_r
) | FB(dst_r
));
1888 return SLJIT_SUCCESS
;
1893 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_cmp(struct sljit_compiler
*compiler
, sljit_s32 op
,
1894 sljit_s32 src1
, sljit_sw src1w
,
1895 sljit_s32 src2
, sljit_sw src2w
)
1897 if (src1
& SLJIT_MEM
) {
1898 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, src1
, src1w
, TMP_REG1
));
1902 if (src2
& SLJIT_MEM
) {
1903 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG2
, src2
, src2w
, TMP_REG2
));
1907 FAIL_IF(push_inst(compiler
, FCMPU
| CRD(4) | FA(src1
) | FB(src2
)));
1909 switch (GET_FLAG_TYPE(op
)) {
1910 case SLJIT_UNORDERED_OR_EQUAL
:
1911 case SLJIT_ORDERED_NOT_EQUAL
:
1912 return push_inst(compiler
, CROR
| ((4 + 2) << 21) | ((4 + 2) << 16) | ((4 + 3) << 11));
1913 case SLJIT_UNORDERED_OR_LESS
:
1914 case SLJIT_ORDERED_GREATER_EQUAL
:
1915 return push_inst(compiler
, CROR
| ((4 + 0) << 21) | ((4 + 0) << 16) | ((4 + 3) << 11));
1916 case SLJIT_UNORDERED_OR_GREATER
:
1917 case SLJIT_ORDERED_LESS_EQUAL
:
1918 return push_inst(compiler
, CROR
| ((4 + 1) << 21) | ((4 + 1) << 16) | ((4 + 3) << 11));
1921 return SLJIT_SUCCESS
;
1924 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fop1(struct sljit_compiler
*compiler
, sljit_s32 op
,
1925 sljit_s32 dst
, sljit_sw dstw
,
1926 sljit_s32 src
, sljit_sw srcw
)
1932 SLJIT_COMPILE_ASSERT((SLJIT_32
== 0x100) && !(DOUBLE_DATA
& 0x4), float_transfer_bit_error
);
1933 SELECT_FOP1_OPERATION_WITH_CHECKS(compiler
, op
, dst
, dstw
, src
, srcw
);
1935 if (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_F32
)
1938 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG1
;
1940 if (src
& SLJIT_MEM
) {
1941 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, dst_r
, src
, srcw
, TMP_REG1
));
1945 switch (GET_OPCODE(op
)) {
1946 case SLJIT_CONV_F64_FROM_F32
:
1948 if (op
& SLJIT_32
) {
1949 FAIL_IF(push_inst(compiler
, FRSP
| FD(dst_r
) | FB(src
)));
1955 if (dst_r
!= TMP_FREG1
)
1956 FAIL_IF(push_inst(compiler
, FMR
| FD(dst_r
) | FB(src
)));
1962 FAIL_IF(push_inst(compiler
, FNEG
| FD(dst_r
) | FB(src
)));
1965 FAIL_IF(push_inst(compiler
, FABS
| FD(dst_r
) | FB(src
)));
1969 if (dst
& SLJIT_MEM
)
1970 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
), dst_r
, dst
, dstw
, TMP_REG1
));
1971 return SLJIT_SUCCESS
;
1974 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fop2(struct sljit_compiler
*compiler
, sljit_s32 op
,
1975 sljit_s32 dst
, sljit_sw dstw
,
1976 sljit_s32 src1
, sljit_sw src1w
,
1977 sljit_s32 src2
, sljit_sw src2w
)
1982 CHECK(check_sljit_emit_fop2(compiler
, op
, dst
, dstw
, src1
, src1w
, src2
, src2w
));
1983 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1984 ADJUST_LOCAL_OFFSET(src1
, src1w
);
1985 ADJUST_LOCAL_OFFSET(src2
, src2w
);
1987 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG2
;
1989 if (src1
& SLJIT_MEM
) {
1990 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, src1
, src1w
, TMP_REG1
));
1994 if (src2
& SLJIT_MEM
) {
1995 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG2
, src2
, src2w
, TMP_REG2
));
1999 switch (GET_OPCODE(op
)) {
2001 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FADDS
, FADD
) | FD(dst_r
) | FA(src1
) | FB(src2
)));
2005 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FSUBS
, FSUB
) | FD(dst_r
) | FA(src1
) | FB(src2
)));
2009 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FMULS
, FMUL
) | FD(dst_r
) | FA(src1
) | FC(src2
) /* FMUL use FC as src2 */));
2013 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FDIVS
, FDIV
) | FD(dst_r
) | FA(src1
) | FB(src2
)));
2017 if (dst
& SLJIT_MEM
)
2018 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
), TMP_FREG2
, dst
, dstw
, TMP_REG1
));
2020 return SLJIT_SUCCESS
;
2025 /* --------------------------------------------------------------------- */
2026 /* Other instructions */
2027 /* --------------------------------------------------------------------- */
2029 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fast_enter(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
)
2032 CHECK(check_sljit_emit_fast_enter(compiler
, dst
, dstw
));
2033 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2035 if (FAST_IS_REG(dst
))
2036 return push_inst(compiler
, MFLR
| D(dst
));
2039 FAIL_IF(push_inst(compiler
, MFLR
| D(TMP_REG2
)));
2040 return emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0);
2043 /* --------------------------------------------------------------------- */
2044 /* Conditional instructions */
2045 /* --------------------------------------------------------------------- */
2047 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_label
* sljit_emit_label(struct sljit_compiler
*compiler
)
2049 struct sljit_label
*label
;
2052 CHECK_PTR(check_sljit_emit_label(compiler
));
2054 if (compiler
->last_label
&& compiler
->last_label
->size
== compiler
->size
)
2055 return compiler
->last_label
;
2057 label
= (struct sljit_label
*)ensure_abuf(compiler
, sizeof(struct sljit_label
));
2058 PTR_FAIL_IF(!label
);
2059 set_label(label
, compiler
);
2063 static sljit_ins
get_bo_bi_flags(struct sljit_compiler
*compiler
, sljit_s32 type
)
2066 case SLJIT_NOT_CARRY
:
2067 if (compiler
->status_flags_state
& SLJIT_CURRENT_FLAGS_SUB
)
2068 return (4 << 21) | (2 << 16);
2072 return (12 << 21) | (2 << 16);
2075 if (compiler
->status_flags_state
& SLJIT_CURRENT_FLAGS_SUB
)
2076 return (12 << 21) | (2 << 16);
2079 case SLJIT_NOT_EQUAL
:
2080 return (4 << 21) | (2 << 16);
2083 case SLJIT_SIG_LESS
:
2084 return (12 << 21) | (0 << 16);
2086 case SLJIT_GREATER_EQUAL
:
2087 case SLJIT_SIG_GREATER_EQUAL
:
2088 return (4 << 21) | (0 << 16);
2091 case SLJIT_SIG_GREATER
:
2092 return (12 << 21) | (1 << 16);
2094 case SLJIT_LESS_EQUAL
:
2095 case SLJIT_SIG_LESS_EQUAL
:
2096 return (4 << 21) | (1 << 16);
2098 case SLJIT_OVERFLOW
:
2099 return (12 << 21) | (3 << 16);
2101 case SLJIT_NOT_OVERFLOW
:
2102 return (4 << 21) | (3 << 16);
2105 case SLJIT_ORDERED_LESS
:
2106 case SLJIT_UNORDERED_OR_LESS
:
2107 return (12 << 21) | ((4 + 0) << 16);
2109 case SLJIT_F_GREATER_EQUAL
:
2110 case SLJIT_ORDERED_GREATER_EQUAL
:
2111 case SLJIT_UNORDERED_OR_GREATER_EQUAL
:
2112 return (4 << 21) | ((4 + 0) << 16);
2114 case SLJIT_F_GREATER
:
2115 case SLJIT_ORDERED_GREATER
:
2116 case SLJIT_UNORDERED_OR_GREATER
:
2117 return (12 << 21) | ((4 + 1) << 16);
2119 case SLJIT_F_LESS_EQUAL
:
2120 case SLJIT_ORDERED_LESS_EQUAL
:
2121 case SLJIT_UNORDERED_OR_LESS_EQUAL
:
2122 return (4 << 21) | ((4 + 1) << 16);
2125 case SLJIT_ORDERED_EQUAL
:
2126 case SLJIT_UNORDERED_OR_EQUAL
:
2127 return (12 << 21) | ((4 + 2) << 16);
2129 case SLJIT_F_NOT_EQUAL
:
2130 case SLJIT_ORDERED_NOT_EQUAL
:
2131 case SLJIT_UNORDERED_OR_NOT_EQUAL
:
2132 return (4 << 21) | ((4 + 2) << 16);
2134 case SLJIT_UNORDERED
:
2135 return (12 << 21) | ((4 + 3) << 16);
2138 return (4 << 21) | ((4 + 3) << 16);
2141 SLJIT_ASSERT(type
>= SLJIT_JUMP
&& type
<= SLJIT_CALL_CDECL
);
2146 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_jump(struct sljit_compiler
*compiler
, sljit_s32 type
)
2148 struct sljit_jump
*jump
;
2149 sljit_ins bo_bi_flags
;
2152 CHECK_PTR(check_sljit_emit_jump(compiler
, type
));
2154 bo_bi_flags
= get_bo_bi_flags(compiler
, type
& 0xff);
2158 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
2160 set_jump(jump
, compiler
, (sljit_u32
)type
& SLJIT_REWRITABLE_JUMP
);
2163 if (type
== SLJIT_CARRY
|| type
== SLJIT_NOT_CARRY
)
2164 PTR_FAIL_IF(push_inst(compiler
, ADDE
| RC(ALT_SET_FLAGS
) | D(TMP_REG1
) | A(TMP_ZERO
) | B(TMP_ZERO
)));
2166 /* In PPC, we don't need to touch the arguments. */
2167 if (type
< SLJIT_JUMP
)
2168 jump
->flags
|= IS_COND
;
2169 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2170 if (type
>= SLJIT_CALL
)
2171 jump
->flags
|= IS_CALL
;
2174 PTR_FAIL_IF(emit_const(compiler
, TMP_CALL_REG
, 0));
2175 PTR_FAIL_IF(push_inst(compiler
, MTCTR
| S(TMP_CALL_REG
)));
2176 jump
->addr
= compiler
->size
;
2177 PTR_FAIL_IF(push_inst(compiler
, BCCTR
| bo_bi_flags
| (type
>= SLJIT_FAST_CALL
? 1 : 0)));
2181 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_call(struct sljit_compiler
*compiler
, sljit_s32 type
,
2182 sljit_s32 arg_types
)
2185 CHECK_PTR(check_sljit_emit_call(compiler
, type
, arg_types
));
2187 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2188 PTR_FAIL_IF(call_with_args(compiler
, arg_types
, NULL
));
2191 if (type
& SLJIT_CALL_RETURN
) {
2192 PTR_FAIL_IF(emit_stack_frame_release(compiler
));
2193 type
= SLJIT_JUMP
| (type
& SLJIT_REWRITABLE_JUMP
);
2196 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2197 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2198 compiler
->skip_checks
= 1;
2201 return sljit_emit_jump(compiler
, type
);
2204 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_ijump(struct sljit_compiler
*compiler
, sljit_s32 type
, sljit_s32 src
, sljit_sw srcw
)
2206 struct sljit_jump
*jump
= NULL
;
2210 CHECK(check_sljit_emit_ijump(compiler
, type
, src
, srcw
));
2211 ADJUST_LOCAL_OFFSET(src
, srcw
);
2213 if (FAST_IS_REG(src
)) {
2214 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2215 if (type
>= SLJIT_CALL
&& src
!= TMP_CALL_REG
) {
2216 FAIL_IF(push_inst(compiler
, OR
| S(src
) | A(TMP_CALL_REG
) | B(src
)));
2217 src_r
= TMP_CALL_REG
;
2221 #else /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
2223 #endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
2224 } else if (src
& SLJIT_IMM
) {
2225 /* These jumps are converted to jump/call instructions when possible. */
2226 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
2228 set_jump(jump
, compiler
, JUMP_ADDR
);
2229 jump
->u
.target
= (sljit_uw
)srcw
;
2231 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2232 if (type
>= SLJIT_CALL
)
2233 jump
->flags
|= IS_CALL
;
2234 #endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
2236 FAIL_IF(emit_const(compiler
, TMP_CALL_REG
, 0));
2237 src_r
= TMP_CALL_REG
;
2240 FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, TMP_CALL_REG
, 0, TMP_REG1
, 0, src
, srcw
));
2241 src_r
= TMP_CALL_REG
;
2244 FAIL_IF(push_inst(compiler
, MTCTR
| S(src_r
)));
2246 jump
->addr
= compiler
->size
;
2247 return push_inst(compiler
, BCCTR
| (20 << 21) | (type
>= SLJIT_FAST_CALL
? 1 : 0));
2250 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_icall(struct sljit_compiler
*compiler
, sljit_s32 type
,
2251 sljit_s32 arg_types
,
2252 sljit_s32 src
, sljit_sw srcw
)
2255 CHECK(check_sljit_emit_icall(compiler
, type
, arg_types
, src
, srcw
));
2257 if (src
& SLJIT_MEM
) {
2258 ADJUST_LOCAL_OFFSET(src
, srcw
);
2259 FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, TMP_CALL_REG
, 0, TMP_REG1
, 0, src
, srcw
));
2263 if (type
& SLJIT_CALL_RETURN
) {
2264 if (src
>= SLJIT_FIRST_SAVED_REG
&& src
<= SLJIT_S0
) {
2265 FAIL_IF(push_inst(compiler
, OR
| S(src
) | A(TMP_CALL_REG
) | B(src
)));
2269 FAIL_IF(emit_stack_frame_release(compiler
));
2273 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2274 FAIL_IF(call_with_args(compiler
, arg_types
, &src
));
2277 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2278 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2279 compiler
->skip_checks
= 1;
2282 return sljit_emit_ijump(compiler
, type
, src
, srcw
);
2285 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_flags(struct sljit_compiler
*compiler
, sljit_s32 op
,
2286 sljit_s32 dst
, sljit_sw dstw
,
2289 sljit_s32 reg
, invert
;
2290 sljit_u32 bit
, from_xer
;
2291 sljit_s32 saved_op
= op
;
2292 sljit_sw saved_dstw
= dstw
;
2293 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2294 sljit_s32 input_flags
= ((op
& SLJIT_32
) || op
== SLJIT_MOV32
) ? INT_DATA
: WORD_DATA
;
2296 sljit_s32 input_flags
= WORD_DATA
;
2300 CHECK(check_sljit_emit_op_flags(compiler
, op
, dst
, dstw
, type
));
2301 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2303 op
= GET_OPCODE(op
);
2304 reg
= (op
< SLJIT_ADD
&& FAST_IS_REG(dst
)) ? dst
: TMP_REG2
;
2306 if (op
>= SLJIT_ADD
&& (dst
& SLJIT_MEM
))
2307 FAIL_IF(emit_op_mem(compiler
, input_flags
| LOAD_DATA
, TMP_REG1
, dst
, dstw
, TMP_REG1
));
2315 case SLJIT_SIG_LESS
:
2318 case SLJIT_GREATER_EQUAL
:
2319 case SLJIT_SIG_GREATER_EQUAL
:
2324 case SLJIT_SIG_GREATER
:
2328 case SLJIT_LESS_EQUAL
:
2329 case SLJIT_SIG_LESS_EQUAL
:
2338 case SLJIT_NOT_EQUAL
:
2343 case SLJIT_OVERFLOW
:
2348 case SLJIT_NOT_OVERFLOW
:
2357 invert
= (compiler
->status_flags_state
& SLJIT_CURRENT_FLAGS_SUB
) != 0;
2360 case SLJIT_NOT_CARRY
:
2363 invert
= (compiler
->status_flags_state
& SLJIT_CURRENT_FLAGS_ADD
) != 0;
2367 case SLJIT_ORDERED_LESS
:
2368 case SLJIT_UNORDERED_OR_LESS
:
2372 case SLJIT_F_GREATER_EQUAL
:
2373 case SLJIT_ORDERED_GREATER_EQUAL
:
2374 case SLJIT_UNORDERED_OR_GREATER_EQUAL
:
2379 case SLJIT_F_GREATER
:
2380 case SLJIT_ORDERED_GREATER
:
2381 case SLJIT_UNORDERED_OR_GREATER
:
2385 case SLJIT_F_LESS_EQUAL
:
2386 case SLJIT_ORDERED_LESS_EQUAL
:
2387 case SLJIT_UNORDERED_OR_LESS_EQUAL
:
2393 case SLJIT_ORDERED_EQUAL
:
2394 case SLJIT_UNORDERED_OR_EQUAL
:
2398 case SLJIT_F_NOT_EQUAL
:
2399 case SLJIT_ORDERED_NOT_EQUAL
:
2400 case SLJIT_UNORDERED_OR_NOT_EQUAL
:
2405 case SLJIT_UNORDERED
:
2415 SLJIT_UNREACHABLE();
2419 FAIL_IF(push_inst(compiler
, (from_xer
? MFXER
: MFCR
) | D(reg
)));
2420 FAIL_IF(push_inst(compiler
, RLWINM
| S(reg
) | A(reg
) | ((1 + bit
) << 11) | (31 << 6) | (31 << 1)));
2423 FAIL_IF(push_inst(compiler
, XORI
| S(reg
) | A(reg
) | 0x1));
2425 if (op
< SLJIT_ADD
) {
2426 if (!(dst
& SLJIT_MEM
))
2427 return SLJIT_SUCCESS
;
2428 return emit_op_mem(compiler
, input_flags
, reg
, dst
, dstw
, TMP_REG1
);
2431 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2432 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2433 compiler
->skip_checks
= 1;
2435 if (dst
& SLJIT_MEM
)
2436 return sljit_emit_op2(compiler
, saved_op
, dst
, saved_dstw
, TMP_REG1
, 0, TMP_REG2
, 0);
2437 return sljit_emit_op2(compiler
, saved_op
, dst
, 0, dst
, 0, TMP_REG2
, 0);
2440 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_cmov(struct sljit_compiler
*compiler
, sljit_s32 type
,
2442 sljit_s32 src
, sljit_sw srcw
)
2445 CHECK(check_sljit_emit_cmov(compiler
, type
, dst_reg
, src
, srcw
));
2447 return sljit_emit_cmov_generic(compiler
, type
, dst_reg
, src
, srcw
);;
2450 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_mem(struct sljit_compiler
*compiler
, sljit_s32 type
,
2452 sljit_s32 mem
, sljit_sw memw
)
2454 sljit_s32 mem_flags
;
2458 CHECK(check_sljit_emit_mem(compiler
, type
, reg
, mem
, memw
));
2460 if (type
& SLJIT_MEM_POST
)
2461 return SLJIT_ERR_UNSUPPORTED
;
2463 switch (type
& 0xff) {
2466 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
2471 mem_flags
= WORD_DATA
;
2474 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2477 mem_flags
= INT_DATA
;
2481 mem_flags
= INT_DATA
;
2483 if (!(type
& SLJIT_MEM_STORE
) && !(type
& SLJIT_32
)) {
2484 if (mem
& OFFS_REG_MASK
)
2485 mem_flags
|= SIGNED_DATA
;
2487 return SLJIT_ERR_UNSUPPORTED
;
2494 mem_flags
= BYTE_DATA
;
2498 mem_flags
= HALF_DATA
;
2502 mem_flags
= HALF_DATA
| SIGNED_DATA
;
2506 SLJIT_UNREACHABLE();
2507 mem_flags
= WORD_DATA
;
2511 if (!(type
& SLJIT_MEM_STORE
))
2512 mem_flags
|= LOAD_DATA
;
2514 if (SLJIT_UNLIKELY(mem
& OFFS_REG_MASK
)) {
2516 return SLJIT_ERR_UNSUPPORTED
;
2518 if (type
& SLJIT_MEM_SUPP
)
2519 return SLJIT_SUCCESS
;
2521 inst
= updated_data_transfer_insts
[mem_flags
| INDEXED
];
2522 FAIL_IF(push_inst(compiler
, INST_CODE_AND_DST(inst
, 0, reg
) | A(mem
& REG_MASK
) | B(OFFS_REG(mem
))));
2525 if (memw
> SIMM_MAX
|| memw
< SIMM_MIN
)
2526 return SLJIT_ERR_UNSUPPORTED
;
2528 inst
= updated_data_transfer_insts
[mem_flags
];
2530 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2531 if ((inst
& INT_ALIGNED
) && (memw
& 0x3) != 0)
2532 return SLJIT_ERR_UNSUPPORTED
;
2535 if (type
& SLJIT_MEM_SUPP
)
2536 return SLJIT_SUCCESS
;
2538 FAIL_IF(push_inst(compiler
, INST_CODE_AND_DST(inst
, 0, reg
) | A(mem
& REG_MASK
) | IMM(memw
)));
2541 if ((mem_flags
& LOAD_DATA
) && (type
& 0xff) == SLJIT_MOV_S8
)
2542 return push_inst(compiler
, EXTSB
| S(reg
) | A(reg
));
2543 return SLJIT_SUCCESS
;
2546 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fmem(struct sljit_compiler
*compiler
, sljit_s32 type
,
2548 sljit_s32 mem
, sljit_sw memw
)
2550 sljit_s32 mem_flags
;
2554 CHECK(check_sljit_emit_fmem(compiler
, type
, freg
, mem
, memw
));
2556 if (type
& SLJIT_MEM_POST
)
2557 return SLJIT_ERR_UNSUPPORTED
;
2559 if (SLJIT_UNLIKELY(mem
& OFFS_REG_MASK
)) {
2561 return SLJIT_ERR_UNSUPPORTED
;
2564 if (memw
> SIMM_MAX
|| memw
< SIMM_MIN
)
2565 return SLJIT_ERR_UNSUPPORTED
;
2568 if (type
& SLJIT_MEM_SUPP
)
2569 return SLJIT_SUCCESS
;
2571 mem_flags
= FLOAT_DATA(type
);
2573 if (!(type
& SLJIT_MEM_STORE
))
2574 mem_flags
|= LOAD_DATA
;
2576 if (SLJIT_UNLIKELY(mem
& OFFS_REG_MASK
)) {
2577 inst
= updated_data_transfer_insts
[mem_flags
| INDEXED
];
2578 return push_inst(compiler
, INST_CODE_AND_DST(inst
, DOUBLE_DATA
, freg
) | A(mem
& REG_MASK
) | B(OFFS_REG(mem
)));
2581 inst
= updated_data_transfer_insts
[mem_flags
];
2582 return push_inst(compiler
, INST_CODE_AND_DST(inst
, DOUBLE_DATA
, freg
) | A(mem
& REG_MASK
) | IMM(memw
));
2585 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_const
* sljit_emit_const(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
, sljit_sw init_value
)
2587 struct sljit_const
*const_
;
2591 CHECK_PTR(check_sljit_emit_const(compiler
, dst
, dstw
, init_value
));
2592 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2594 const_
= (struct sljit_const
*)ensure_abuf(compiler
, sizeof(struct sljit_const
));
2595 PTR_FAIL_IF(!const_
);
2596 set_const(const_
, compiler
);
2598 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_REG2
;
2599 PTR_FAIL_IF(emit_const(compiler
, dst_r
, init_value
));
2601 if (dst
& SLJIT_MEM
)
2602 PTR_FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0));
2607 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_put_label
* sljit_emit_put_label(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
)
2609 struct sljit_put_label
*put_label
;
2613 CHECK_PTR(check_sljit_emit_put_label(compiler
, dst
, dstw
));
2614 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2616 put_label
= (struct sljit_put_label
*)ensure_abuf(compiler
, sizeof(struct sljit_put_label
));
2617 PTR_FAIL_IF(!put_label
);
2618 set_put_label(put_label
, compiler
, 0);
2620 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_REG2
;
2621 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
2622 PTR_FAIL_IF(emit_const(compiler
, dst_r
, 0));
2624 PTR_FAIL_IF(push_inst(compiler
, (sljit_ins
)dst_r
));
2625 compiler
->size
+= 4;
2628 if (dst
& SLJIT_MEM
)
2629 PTR_FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0));