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
, 0)
739 + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches
, fsaveds
, sizeof(sljit_f64
));
741 if (!(options
& SLJIT_ENTER_REG_ARG
))
742 local_size
+= SSIZE_OF(sw
);
744 local_size
= (local_size
+ SLJIT_LOCALS_OFFSET
+ 15) & ~0xf;
745 compiler
->local_size
= local_size
;
747 FAIL_IF(push_inst(compiler
, MFLR
| D(0)));
752 if (local_size
<= STACK_MAX_DISTANCE
) {
753 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
754 FAIL_IF(push_inst(compiler
, STWU
| S(SLJIT_SP
) | A(SLJIT_SP
) | IMM(-local_size
)));
756 FAIL_IF(push_inst(compiler
, STDU
| S(SLJIT_SP
) | A(SLJIT_SP
) | IMM(-local_size
)));
760 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_SP
) | A(TMP_REG1
) | B(SLJIT_SP
)));
761 FAIL_IF(load_immediate(compiler
, TMP_REG2
, -local_size
));
762 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
763 FAIL_IF(push_inst(compiler
, STWUX
| S(SLJIT_SP
) | A(SLJIT_SP
) | B(TMP_REG2
)));
765 FAIL_IF(push_inst(compiler
, STDUX
| S(SLJIT_SP
) | A(SLJIT_SP
) | B(TMP_REG2
)));
771 tmp
= SLJIT_FS0
- fsaveds
;
772 for (i
= SLJIT_FS0
; i
> tmp
; i
--) {
773 offset
-= SSIZE_OF(f64
);
774 FAIL_IF(push_inst(compiler
, STFD
| FS(i
) | A(base
) | IMM(offset
)));
777 for (i
= fscratches
; i
>= SLJIT_FIRST_SAVED_FLOAT_REG
; i
--) {
778 offset
-= SSIZE_OF(f64
);
779 FAIL_IF(push_inst(compiler
, STFD
| FS(i
) | A(base
) | IMM(offset
)));
782 if (!(options
& SLJIT_ENTER_REG_ARG
)) {
783 offset
-= SSIZE_OF(sw
);
784 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(TMP_ZERO
) | A(base
) | IMM(offset
)));
787 tmp
= SLJIT_S0
- saveds
;
788 for (i
= SLJIT_S0
- saved_arg_count
; i
> tmp
; i
--) {
789 offset
-= SSIZE_OF(sw
);
790 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(i
) | A(base
) | IMM(offset
)));
793 for (i
= scratches
; i
>= SLJIT_FIRST_SAVED_REG
; i
--) {
794 offset
-= SSIZE_OF(sw
);
795 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(i
) | A(base
) | IMM(offset
)));
798 FAIL_IF(push_inst(compiler
, STACK_STORE
| S(0) | A(base
) | IMM(local_size
+ LR_SAVE_OFFSET
)));
800 if (options
& SLJIT_ENTER_REG_ARG
)
801 return SLJIT_SUCCESS
;
803 FAIL_IF(push_inst(compiler
, ADDI
| D(TMP_ZERO
) | A(0) | 0));
805 arg_types
>>= SLJIT_ARG_SHIFT
;
808 while (arg_types
> 0) {
809 if ((arg_types
& SLJIT_ARG_MASK
) < SLJIT_ARG_TYPE_F64
) {
810 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
812 if (!(arg_types
& SLJIT_ARG_TYPE_SCRATCH_REG
)) {
813 tmp
= SLJIT_S0
- saved_arg_count
;
815 } else if (arg_count
!= word_arg_count
)
816 tmp
= SLJIT_R0
+ word_arg_count
;
820 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_R0
+ arg_count
) | A(tmp
) | B(SLJIT_R0
+ arg_count
)));
823 if (!(arg_types
& SLJIT_ARG_TYPE_SCRATCH_REG
)) {
824 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_R0
+ word_arg_count
) | A(SLJIT_S0
- saved_arg_count
) | B(SLJIT_R0
+ word_arg_count
)));
831 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
834 arg_types
>>= SLJIT_ARG_SHIFT
;
837 return SLJIT_SUCCESS
;
840 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_set_context(struct sljit_compiler
*compiler
,
841 sljit_s32 options
, sljit_s32 arg_types
, sljit_s32 scratches
, sljit_s32 saveds
,
842 sljit_s32 fscratches
, sljit_s32 fsaveds
, sljit_s32 local_size
)
845 CHECK(check_sljit_set_context(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
));
846 set_set_context(compiler
, options
, arg_types
, scratches
, saveds
, fscratches
, fsaveds
, local_size
);
848 local_size
+= GET_SAVED_REGISTERS_SIZE(scratches
, saveds
- SLJIT_KEPT_SAVEDS_COUNT(options
), 0)
849 + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches
, fsaveds
, sizeof(sljit_f64
));
851 if (!(options
& SLJIT_ENTER_REG_ARG
))
852 local_size
+= SSIZE_OF(sw
);
854 compiler
->local_size
= (local_size
+ SLJIT_LOCALS_OFFSET
+ 15) & ~0xf;
855 return SLJIT_SUCCESS
;
858 static sljit_s32
emit_stack_frame_release(struct sljit_compiler
*compiler
)
860 sljit_s32 i
, tmp
, base
, offset
;
861 sljit_s32 local_size
= compiler
->local_size
;
864 if (local_size
> STACK_MAX_DISTANCE
) {
866 if (local_size
> 2 * STACK_MAX_DISTANCE
+ LR_SAVE_OFFSET
) {
867 FAIL_IF(push_inst(compiler
, STACK_LOAD
| D(base
) | A(SLJIT_SP
) | IMM(0)));
870 FAIL_IF(push_inst(compiler
, ADDI
| D(TMP_REG1
) | A(SLJIT_SP
) | IMM(local_size
- STACK_MAX_DISTANCE
)));
871 local_size
= STACK_MAX_DISTANCE
;
876 FAIL_IF(push_inst(compiler
, STACK_LOAD
| S(0) | A(base
) | IMM(offset
+ LR_SAVE_OFFSET
)));
878 tmp
= SLJIT_FS0
- compiler
->fsaveds
;
879 for (i
= SLJIT_FS0
; i
> tmp
; i
--) {
880 offset
-= SSIZE_OF(f64
);
881 FAIL_IF(push_inst(compiler
, LFD
| FS(i
) | A(base
) | IMM(offset
)));
884 for (i
= compiler
->fscratches
; i
>= SLJIT_FIRST_SAVED_FLOAT_REG
; i
--) {
885 offset
-= SSIZE_OF(f64
);
886 FAIL_IF(push_inst(compiler
, LFD
| FS(i
) | A(base
) | IMM(offset
)));
889 if (!(compiler
->options
& SLJIT_ENTER_REG_ARG
)) {
890 offset
-= SSIZE_OF(sw
);
891 FAIL_IF(push_inst(compiler
, STACK_LOAD
| S(TMP_ZERO
) | A(base
) | IMM(offset
)));
894 tmp
= SLJIT_S0
- compiler
->saveds
;
895 for (i
= SLJIT_S0
- SLJIT_KEPT_SAVEDS_COUNT(compiler
->options
); i
> tmp
; i
--) {
896 offset
-= SSIZE_OF(sw
);
897 FAIL_IF(push_inst(compiler
, STACK_LOAD
| S(i
) | A(base
) | IMM(offset
)));
900 for (i
= compiler
->scratches
; i
>= SLJIT_FIRST_SAVED_REG
; i
--) {
901 offset
-= SSIZE_OF(sw
);
902 FAIL_IF(push_inst(compiler
, STACK_LOAD
| S(i
) | A(base
) | IMM(offset
)));
905 push_inst(compiler
, MTLR
| S(0));
908 return push_inst(compiler
, ADDI
| D(SLJIT_SP
) | A(base
) | IMM(local_size
));
910 SLJIT_ASSERT(base
== TMP_REG1
);
911 return push_inst(compiler
, OR
| S(base
) | A(SLJIT_SP
) | B(base
));
914 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_return_void(struct sljit_compiler
*compiler
)
917 CHECK(check_sljit_emit_return_void(compiler
));
919 FAIL_IF(emit_stack_frame_release(compiler
));
920 return push_inst(compiler
, BLR
);
926 /* --------------------------------------------------------------------- */
928 /* --------------------------------------------------------------------- */
930 /* s/l - store/load (1 bit)
931 i/x - immediate/indexed form
932 u/s - signed/unsigned (1 bit)
933 w/b/h/i - word/byte/half/int allowed (2 bit)
935 Some opcodes are repeated (e.g. store signed / unsigned byte is the same instruction). */
937 /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
938 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
939 #define INT_ALIGNED 0x10000
942 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
943 #define ARCH_32_64(a, b) a
944 #define INST_CODE_AND_DST(inst, flags, reg) \
945 ((sljit_ins)(inst) | (sljit_ins)(((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
947 #define ARCH_32_64(a, b) b
948 #define INST_CODE_AND_DST(inst, flags, reg) \
949 (((sljit_ins)(inst) & ~(sljit_ins)INT_ALIGNED) | (sljit_ins)(((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
952 static const sljit_ins data_transfer_insts
[64 + 16] = {
954 /* -------- Integer -------- */
958 /* w u i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED
| 0x0 /* std */),
959 /* w u i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED
| 0x0 /* ld */),
960 /* w u x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
961 /* w u x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
963 /* w s i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED
| 0x0 /* std */),
964 /* w s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED
| 0x0 /* ld */),
965 /* w s x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
966 /* w s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
970 /* b u i s */ HI(38) /* stb */,
971 /* b u i l */ HI(34) /* lbz */,
972 /* b u x s */ HI(31) | LO(215) /* stbx */,
973 /* b u x l */ HI(31) | LO(87) /* lbzx */,
975 /* b s i s */ HI(38) /* stb */,
976 /* b s i l */ HI(34) /* lbz */ /* EXTS_REQ */,
977 /* b s x s */ HI(31) | LO(215) /* stbx */,
978 /* b s x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
982 /* h u i s */ HI(44) /* sth */,
983 /* h u i l */ HI(40) /* lhz */,
984 /* h u x s */ HI(31) | LO(407) /* sthx */,
985 /* h u x l */ HI(31) | LO(279) /* lhzx */,
987 /* h s i s */ HI(44) /* sth */,
988 /* h s i l */ HI(42) /* lha */,
989 /* h s x s */ HI(31) | LO(407) /* sthx */,
990 /* h s x l */ HI(31) | LO(343) /* lhax */,
994 /* i u i s */ HI(36) /* stw */,
995 /* i u i l */ HI(32) /* lwz */,
996 /* i u x s */ HI(31) | LO(151) /* stwx */,
997 /* i u x l */ HI(31) | LO(23) /* lwzx */,
999 /* i s i s */ HI(36) /* stw */,
1000 /* i s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED
| 0x2 /* lwa */),
1001 /* i s x s */ HI(31) | LO(151) /* stwx */,
1002 /* i s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
1004 /* -------- Floating point -------- */
1006 /* d i s */ HI(54) /* stfd */,
1007 /* d i l */ HI(50) /* lfd */,
1008 /* d x s */ HI(31) | LO(727) /* stfdx */,
1009 /* d x l */ HI(31) | LO(599) /* lfdx */,
1011 /* s i s */ HI(52) /* stfs */,
1012 /* s i l */ HI(48) /* lfs */,
1013 /* s x s */ HI(31) | LO(663) /* stfsx */,
1014 /* s x l */ HI(31) | LO(535) /* lfsx */,
1017 static const sljit_ins updated_data_transfer_insts
[64] = {
1019 /* -------- Integer -------- */
1023 /* w u i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED
| 0x1 /* stdu */),
1024 /* w u i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED
| 0x1 /* ldu */),
1025 /* w u x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
1026 /* w u x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
1028 /* w s i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED
| 0x1 /* stdu */),
1029 /* w s i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED
| 0x1 /* ldu */),
1030 /* w s x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
1031 /* w s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
1035 /* b u i s */ HI(39) /* stbu */,
1036 /* b u i l */ HI(35) /* lbzu */,
1037 /* b u x s */ HI(31) | LO(247) /* stbux */,
1038 /* b u x l */ HI(31) | LO(119) /* lbzux */,
1040 /* b s i s */ HI(39) /* stbu */,
1041 /* b s i l */ 0 /* no such instruction */,
1042 /* b s x s */ HI(31) | LO(247) /* stbux */,
1043 /* b s x l */ 0 /* no such instruction */,
1047 /* h u i s */ HI(45) /* sthu */,
1048 /* h u i l */ HI(41) /* lhzu */,
1049 /* h u x s */ HI(31) | LO(439) /* sthux */,
1050 /* h u x l */ HI(31) | LO(311) /* lhzux */,
1052 /* h s i s */ HI(45) /* sthu */,
1053 /* h s i l */ HI(43) /* lhau */,
1054 /* h s x s */ HI(31) | LO(439) /* sthux */,
1055 /* h s x l */ HI(31) | LO(375) /* lhaux */,
1059 /* i u i s */ HI(37) /* stwu */,
1060 /* i u i l */ HI(33) /* lwzu */,
1061 /* i u x s */ HI(31) | LO(183) /* stwux */,
1062 /* i u x l */ HI(31) | LO(55) /* lwzux */,
1064 /* i s i s */ HI(37) /* stwu */,
1065 /* i s i l */ ARCH_32_64(HI(33) /* lwzu */, 0 /* no such instruction */),
1066 /* i s x s */ HI(31) | LO(183) /* stwux */,
1067 /* i s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
1069 /* -------- Floating point -------- */
1071 /* d i s */ HI(55) /* stfdu */,
1072 /* d i l */ HI(51) /* lfdu */,
1073 /* d x s */ HI(31) | LO(759) /* stfdux */,
1074 /* d x l */ HI(31) | LO(631) /* lfdux */,
1076 /* s i s */ HI(53) /* stfsu */,
1077 /* s i l */ HI(49) /* lfsu */,
1078 /* s x s */ HI(31) | LO(695) /* stfsux */,
1079 /* s x l */ HI(31) | LO(567) /* lfsux */,
1084 /* Simple cases, (no caching is required). */
1085 static sljit_s32
emit_op_mem(struct sljit_compiler
*compiler
, sljit_s32 inp_flags
, sljit_s32 reg
,
1086 sljit_s32 arg
, sljit_sw argw
, sljit_s32 tmp_reg
)
1090 sljit_sw high_short
;
1092 /* Should work when (arg & REG_MASK) == 0. */
1093 SLJIT_ASSERT(A(0) == 0);
1094 SLJIT_ASSERT(arg
& SLJIT_MEM
);
1096 if (SLJIT_UNLIKELY(arg
& OFFS_REG_MASK
)) {
1098 offs_reg
= OFFS_REG(arg
);
1101 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1102 FAIL_IF(push_inst(compiler
, RLWINM
| S(OFFS_REG(arg
)) | A(tmp_reg
) | ((sljit_ins
)argw
<< 11) | ((31 - (sljit_ins
)argw
) << 1)));
1104 FAIL_IF(push_inst(compiler
, RLDI(tmp_reg
, OFFS_REG(arg
), argw
, 63 - argw
, 1)));
1109 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
1111 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1112 SLJIT_ASSERT(!(inst
& INT_ALIGNED
));
1115 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
& REG_MASK
) | B(offs_reg
));
1118 inst
= data_transfer_insts
[inp_flags
& MEM_MASK
];
1121 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1122 if ((inst
& INT_ALIGNED
) && (argw
& 0x3) != 0) {
1123 FAIL_IF(load_immediate(compiler
, tmp_reg
, argw
));
1125 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
1126 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
) | B(tmp_reg
));
1130 if (argw
<= SIMM_MAX
&& argw
>= SIMM_MIN
)
1131 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
) | IMM(argw
));
1133 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1134 if (argw
<= 0x7fff7fffl
&& argw
>= -0x80000000l
) {
1137 high_short
= (sljit_s32
)(argw
+ ((argw
& 0x8000) << 1)) & ~0xffff;
1139 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1140 SLJIT_ASSERT(high_short
&& high_short
<= 0x7fffffffl
&& high_short
>= -0x80000000l
);
1142 SLJIT_ASSERT(high_short
);
1145 FAIL_IF(push_inst(compiler
, ADDIS
| D(tmp_reg
) | A(arg
) | IMM(high_short
>> 16)));
1146 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(tmp_reg
) | IMM(argw
));
1148 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1151 /* The rest is PPC-64 only. */
1153 FAIL_IF(load_immediate(compiler
, tmp_reg
, argw
));
1155 inst
= data_transfer_insts
[(inp_flags
| INDEXED
) & MEM_MASK
];
1156 return push_inst(compiler
, INST_CODE_AND_DST(inst
, inp_flags
, reg
) | A(arg
) | B(tmp_reg
));
1160 static sljit_s32
emit_op(struct sljit_compiler
*compiler
, sljit_s32 op
, sljit_s32 input_flags
,
1161 sljit_s32 dst
, sljit_sw dstw
,
1162 sljit_s32 src1
, sljit_sw src1w
,
1163 sljit_s32 src2
, sljit_sw src2w
)
1165 /* arg1 goes to TMP_REG1 or src reg
1166 arg2 goes to TMP_REG2, imm or src reg
1167 result goes to TMP_REG2, so put result can use TMP_REG1. */
1168 sljit_s32 dst_r
= TMP_REG2
;
1171 sljit_s32 sugg_src2_r
= TMP_REG2
;
1172 sljit_s32 flags
= input_flags
& (ALT_FORM1
| ALT_FORM2
| ALT_FORM3
| ALT_FORM4
| ALT_FORM5
| ALT_SIGN_EXT
| ALT_SET_FLAGS
);
1174 /* Destination check. */
1175 if (FAST_IS_REG(dst
)) {
1177 /* The REG_DEST is only used by SLJIT_MOV operations, although
1178 * it is set for op2 operations with unset destination. */
1181 if (op
>= SLJIT_MOV
&& op
<= SLJIT_MOV_P
)
1182 sugg_src2_r
= dst_r
;
1186 if (FAST_IS_REG(src1
)) {
1188 flags
|= REG1_SOURCE
;
1190 else if (src1
& SLJIT_IMM
) {
1193 FAIL_IF(load_immediate(compiler
, TMP_REG1
, src1w
));
1198 FAIL_IF(emit_op_mem(compiler
, input_flags
| LOAD_DATA
, TMP_REG1
, src1
, src1w
, TMP_REG1
));
1203 if (FAST_IS_REG(src2
)) {
1205 flags
|= REG2_SOURCE
;
1207 if (!(flags
& REG_DEST
) && op
>= SLJIT_MOV
&& op
<= SLJIT_MOV_P
)
1210 else if (src2
& SLJIT_IMM
) {
1213 FAIL_IF(load_immediate(compiler
, sugg_src2_r
, src2w
));
1214 src2_r
= sugg_src2_r
;
1218 FAIL_IF(emit_op_mem(compiler
, input_flags
| LOAD_DATA
, sugg_src2_r
, src2
, src2w
, TMP_REG2
));
1219 src2_r
= sugg_src2_r
;
1222 FAIL_IF(emit_single_op(compiler
, op
, flags
, dst_r
, src1_r
, src2_r
));
1224 if (!(dst
& SLJIT_MEM
))
1225 return SLJIT_SUCCESS
;
1227 return emit_op_mem(compiler
, input_flags
, dst_r
, dst
, dstw
, TMP_REG1
);
1230 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op0(struct sljit_compiler
*compiler
, sljit_s32 op
)
1232 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1233 sljit_s32 int_op
= op
& SLJIT_32
;
1237 CHECK(check_sljit_emit_op0(compiler
, op
));
1239 op
= GET_OPCODE(op
);
1241 case SLJIT_BREAKPOINT
:
1243 return push_inst(compiler
, NOP
);
1246 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_R0
) | A(TMP_REG1
) | B(SLJIT_R0
)));
1247 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1248 FAIL_IF(push_inst(compiler
, MULLD
| D(SLJIT_R0
) | A(TMP_REG1
) | B(SLJIT_R1
)));
1249 return push_inst(compiler
, (op
== SLJIT_LMUL_UW
? MULHDU
: MULHD
) | D(SLJIT_R1
) | A(TMP_REG1
) | B(SLJIT_R1
));
1251 FAIL_IF(push_inst(compiler
, MULLW
| D(SLJIT_R0
) | A(TMP_REG1
) | B(SLJIT_R1
)));
1252 return push_inst(compiler
, (op
== SLJIT_LMUL_UW
? MULHWU
: MULHW
) | D(SLJIT_R1
) | A(TMP_REG1
) | B(SLJIT_R1
));
1254 case SLJIT_DIVMOD_UW
:
1255 case SLJIT_DIVMOD_SW
:
1256 FAIL_IF(push_inst(compiler
, OR
| S(SLJIT_R0
) | A(TMP_REG1
) | B(SLJIT_R0
)));
1257 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1258 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
)));
1259 FAIL_IF(push_inst(compiler
, (int_op
? MULLW
: MULLD
) | D(SLJIT_R1
) | A(SLJIT_R0
) | B(SLJIT_R1
)));
1261 FAIL_IF(push_inst(compiler
, (op
== SLJIT_DIVMOD_UW
? DIVWU
: DIVW
) | D(SLJIT_R0
) | A(SLJIT_R0
) | B(SLJIT_R1
)));
1262 FAIL_IF(push_inst(compiler
, MULLW
| D(SLJIT_R1
) | A(SLJIT_R0
) | B(SLJIT_R1
)));
1264 return push_inst(compiler
, SUBF
| D(SLJIT_R1
) | A(SLJIT_R1
) | B(TMP_REG1
));
1267 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1268 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
));
1270 return push_inst(compiler
, (op
== SLJIT_DIV_UW
? DIVWU
: DIVW
) | D(SLJIT_R0
) | A(SLJIT_R0
) | B(SLJIT_R1
));
1273 case SLJIT_SKIP_FRAMES_BEFORE_RETURN
:
1274 return SLJIT_SUCCESS
;
1277 return SLJIT_SUCCESS
;
1280 static sljit_s32
emit_prefetch(struct sljit_compiler
*compiler
,
1281 sljit_s32 src
, sljit_sw srcw
)
1283 if (!(src
& OFFS_REG_MASK
)) {
1284 if (srcw
== 0 && (src
& REG_MASK
))
1285 return push_inst(compiler
, DCBT
| A(0) | B(src
& REG_MASK
));
1287 FAIL_IF(load_immediate(compiler
, TMP_REG1
, srcw
));
1288 /* Works with SLJIT_MEM0() case as well. */
1289 return push_inst(compiler
, DCBT
| A(src
& REG_MASK
) | B(TMP_REG1
));
1295 return push_inst(compiler
, DCBT
| A(src
& REG_MASK
) | B(OFFS_REG(src
)));
1297 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1298 FAIL_IF(push_inst(compiler
, RLWINM
| S(OFFS_REG(src
)) | A(TMP_REG1
) | ((sljit_ins
)srcw
<< 11) | ((31 - (sljit_ins
)srcw
) << 1)));
1300 FAIL_IF(push_inst(compiler
, RLDI(TMP_REG1
, OFFS_REG(src
), srcw
, 63 - srcw
, 1)));
1302 return push_inst(compiler
, DCBT
| A(src
& REG_MASK
) | B(TMP_REG1
));
1305 #define EMIT_MOV(type, type_flags, type_cast) \
1306 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)
1308 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op1(struct sljit_compiler
*compiler
, sljit_s32 op
,
1309 sljit_s32 dst
, sljit_sw dstw
,
1310 sljit_s32 src
, sljit_sw srcw
)
1312 sljit_s32 flags
= HAS_FLAGS(op
) ? ALT_SET_FLAGS
: 0;
1313 sljit_s32 op_flags
= GET_ALL_FLAGS(op
);
1316 CHECK(check_sljit_emit_op1(compiler
, op
, dst
, dstw
, src
, srcw
));
1317 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1318 ADJUST_LOCAL_OFFSET(src
, srcw
);
1320 op
= GET_OPCODE(op
);
1322 if (GET_FLAG_TYPE(op_flags
) == SLJIT_OVERFLOW
)
1323 FAIL_IF(push_inst(compiler
, MTXER
| S(TMP_ZERO
)));
1325 if (op
< SLJIT_NOT
&& FAST_IS_REG(src
) && src
== dst
) {
1326 if (!TYPE_CAST_NEEDED(op
))
1327 return SLJIT_SUCCESS
;
1330 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1331 if (op_flags
& SLJIT_32
) {
1332 if (op
< SLJIT_NOT
) {
1333 if (src
& SLJIT_MEM
) {
1334 if (op
== SLJIT_MOV_S32
)
1337 else if (src
& SLJIT_IMM
) {
1338 if (op
== SLJIT_MOV_U32
)
1343 /* Most operations expect sign extended arguments. */
1344 flags
|= INT_DATA
| SIGNED_DATA
;
1345 if (HAS_FLAGS(op_flags
))
1346 flags
|= ALT_SIGN_EXT
;
1353 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1359 return emit_op(compiler
, SLJIT_MOV
, flags
| WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1361 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1363 return EMIT_MOV(SLJIT_MOV_U32
, INT_DATA
, (sljit_u32
));
1367 return EMIT_MOV(SLJIT_MOV_S32
, INT_DATA
| SIGNED_DATA
, (sljit_s32
));
1371 return EMIT_MOV(SLJIT_MOV_U8
, BYTE_DATA
, (sljit_u8
));
1374 return EMIT_MOV(SLJIT_MOV_S8
, BYTE_DATA
| SIGNED_DATA
, (sljit_s8
));
1377 return EMIT_MOV(SLJIT_MOV_U16
, HALF_DATA
, (sljit_u16
));
1380 return EMIT_MOV(SLJIT_MOV_S16
, HALF_DATA
| SIGNED_DATA
, (sljit_s16
));
1383 return emit_op(compiler
, SLJIT_NOT
, flags
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1386 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1387 return emit_op(compiler
, SLJIT_CLZ
, flags
| (!(op_flags
& SLJIT_32
) ? 0 : ALT_FORM1
), dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1389 return emit_op(compiler
, SLJIT_CLZ
, flags
, dst
, dstw
, TMP_REG1
, 0, src
, srcw
);
1393 return SLJIT_SUCCESS
;
1398 #define TEST_SL_IMM(src, srcw) \
1399 (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)
1401 #define TEST_UL_IMM(src, srcw) \
1402 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff))
1404 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1405 #define TEST_SH_IMM(src, srcw) \
1406 (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l)
1408 #define TEST_SH_IMM(src, srcw) \
1409 (((src) & SLJIT_IMM) && !((srcw) & 0xffff))
1412 #define TEST_UH_IMM(src, srcw) \
1413 (((src) & SLJIT_IMM) && !((srcw) & ~(sljit_sw)0xffff0000))
1415 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1416 #define TEST_ADD_IMM(src, srcw) \
1417 (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l)
1419 #define TEST_ADD_IMM(src, srcw) \
1423 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1424 #define TEST_UI_IMM(src, srcw) \
1425 (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
1427 #define TEST_UI_IMM(src, srcw) \
1431 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1432 #define TEST_ADD_FORM1(op) \
1433 (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \
1434 || (op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_32 | SLJIT_SET_Z | SLJIT_SET_CARRY))
1435 #define TEST_SUB_FORM2(op) \
1436 ((GET_FLAG_TYPE(op) >= SLJIT_SIG_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) \
1437 || (op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_32 | SLJIT_SET_Z))
1438 #define TEST_SUB_FORM3(op) \
1439 (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \
1440 || (op & (SLJIT_32 | SLJIT_SET_Z)) == (SLJIT_32 | SLJIT_SET_Z))
1442 #define TEST_ADD_FORM1(op) \
1443 (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1444 #define TEST_SUB_FORM2(op) \
1445 (GET_FLAG_TYPE(op) >= SLJIT_SIG_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL)
1446 #define TEST_SUB_FORM3(op) \
1447 (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1450 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op2(struct sljit_compiler
*compiler
, sljit_s32 op
,
1451 sljit_s32 dst
, sljit_sw dstw
,
1452 sljit_s32 src1
, sljit_sw src1w
,
1453 sljit_s32 src2
, sljit_sw src2w
)
1455 sljit_s32 flags
= HAS_FLAGS(op
) ? ALT_SET_FLAGS
: 0;
1458 CHECK(check_sljit_emit_op2(compiler
, op
, 0, dst
, dstw
, src1
, src1w
, src2
, src2w
));
1459 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1460 ADJUST_LOCAL_OFFSET(src1
, src1w
);
1461 ADJUST_LOCAL_OFFSET(src2
, src2w
);
1463 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1464 if (op
& SLJIT_32
) {
1465 /* Most operations expect sign extended arguments. */
1466 flags
|= INT_DATA
| SIGNED_DATA
;
1467 if (src1
& SLJIT_IMM
)
1468 src1w
= (sljit_s32
)(src1w
);
1469 if (src2
& SLJIT_IMM
)
1470 src2w
= (sljit_s32
)(src2w
);
1472 flags
|= ALT_SIGN_EXT
;
1475 if (GET_FLAG_TYPE(op
) == SLJIT_OVERFLOW
)
1476 FAIL_IF(push_inst(compiler
, MTXER
| S(TMP_ZERO
)));
1478 switch (GET_OPCODE(op
)) {
1480 compiler
->status_flags_state
= SLJIT_CURRENT_FLAGS_ADD
;
1482 if (TEST_ADD_FORM1(op
))
1483 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1485 if (!HAS_FLAGS(op
) && ((src1
| src2
) & SLJIT_IMM
)) {
1486 if (TEST_SL_IMM(src2
, src2w
)) {
1487 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1488 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1490 if (TEST_SL_IMM(src1
, src1w
)) {
1491 compiler
->imm
= (sljit_ins
)src1w
& 0xffff;
1492 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1494 if (TEST_SH_IMM(src2
, src2w
)) {
1495 compiler
->imm
= (sljit_ins
)(src2w
>> 16) & 0xffff;
1496 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1498 if (TEST_SH_IMM(src1
, src1w
)) {
1499 compiler
->imm
= (sljit_ins
)(src1w
>> 16) & 0xffff;
1500 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1502 /* Range between -1 and -32768 is covered above. */
1503 if (TEST_ADD_IMM(src2
, src2w
)) {
1504 compiler
->imm
= (sljit_ins
)src2w
& 0xffffffff;
1505 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1507 if (TEST_ADD_IMM(src1
, src1w
)) {
1508 compiler
->imm
= (sljit_ins
)src1w
& 0xffffffff;
1509 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM4
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1513 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1514 if ((op
& (SLJIT_32
| SLJIT_SET_Z
)) == (SLJIT_32
| SLJIT_SET_Z
)) {
1515 if (TEST_SL_IMM(src2
, src2w
)) {
1516 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1517 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM4
| ALT_FORM5
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1519 if (TEST_SL_IMM(src1
, src1w
)) {
1520 compiler
->imm
= (sljit_ins
)src1w
& 0xffff;
1521 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM4
| ALT_FORM5
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1523 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1526 if (HAS_FLAGS(op
)) {
1527 if (TEST_SL_IMM(src2
, src2w
)) {
1528 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1529 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1531 if (TEST_SL_IMM(src1
, src1w
)) {
1532 compiler
->imm
= (sljit_ins
)src1w
& 0xffff;
1533 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM3
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1536 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
);
1539 compiler
->status_flags_state
= SLJIT_CURRENT_FLAGS_ADD
;
1540 return emit_op(compiler
, SLJIT_ADDC
, flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1543 compiler
->status_flags_state
= SLJIT_CURRENT_FLAGS_SUB
;
1545 if (GET_FLAG_TYPE(op
) >= SLJIT_LESS
&& GET_FLAG_TYPE(op
) <= SLJIT_LESS_EQUAL
) {
1546 if (dst
== TMP_REG2
) {
1547 if (TEST_UL_IMM(src2
, src2w
)) {
1548 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1549 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM1
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1551 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1554 if ((src2
& SLJIT_IMM
) && src2w
>= 0 && src2w
<= (SIMM_MAX
+ 1)) {
1555 compiler
->imm
= (sljit_ins
)src2w
;
1556 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM1
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1558 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM1
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1561 if (dst
== TMP_REG2
&& GET_FLAG_TYPE(op
) <= SLJIT_SIG_LESS_EQUAL
) {
1562 if (TEST_SL_IMM(src2
, src2w
)) {
1563 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1564 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1566 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1569 if (TEST_SUB_FORM2(op
)) {
1570 if ((src2
& SLJIT_IMM
) && src2w
>= -SIMM_MAX
&& src2w
<= SIMM_MAX
) {
1571 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1572 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
| ALT_FORM3
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1574 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM2
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1577 if (TEST_SUB_FORM3(op
))
1578 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1580 if (TEST_SL_IMM(src2
, -src2w
)) {
1581 compiler
->imm
= (sljit_ins
)(-src2w
) & 0xffff;
1582 return emit_op(compiler
, SLJIT_ADD
, flags
| (!HAS_FLAGS(op
) ? ALT_FORM2
: ALT_FORM3
), dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1585 if (TEST_SL_IMM(src1
, src1w
) && !(op
& SLJIT_SET_Z
)) {
1586 compiler
->imm
= (sljit_ins
)src1w
& 0xffff;
1587 return emit_op(compiler
, SLJIT_SUB
, flags
| ALT_FORM4
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1590 if (!HAS_FLAGS(op
)) {
1591 if (TEST_SH_IMM(src2
, -src2w
)) {
1592 compiler
->imm
= (sljit_ins
)((-src2w
) >> 16) & 0xffff;
1593 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1595 /* Range between -1 and -32768 is covered above. */
1596 if (TEST_ADD_IMM(src2
, -src2w
)) {
1597 compiler
->imm
= (sljit_ins
)-src2w
;
1598 return emit_op(compiler
, SLJIT_ADD
, flags
| ALT_FORM2
| ALT_FORM4
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1602 /* We know ALT_SIGN_EXT is set if it is an SLJIT_32 on 64 bit systems. */
1603 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
);
1606 compiler
->status_flags_state
= SLJIT_CURRENT_FLAGS_SUB
;
1607 return emit_op(compiler
, SLJIT_SUBC
, flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1610 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1614 if (!HAS_FLAGS(op
)) {
1615 if (TEST_SL_IMM(src2
, src2w
)) {
1616 compiler
->imm
= (sljit_ins
)src2w
& 0xffff;
1617 return emit_op(compiler
, SLJIT_MUL
, flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1619 if (TEST_SL_IMM(src1
, src1w
)) {
1620 compiler
->imm
= (sljit_ins
)src1w
& 0xffff;
1621 return emit_op(compiler
, SLJIT_MUL
, flags
| ALT_FORM1
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1625 FAIL_IF(push_inst(compiler
, MTXER
| S(TMP_ZERO
)));
1626 return emit_op(compiler
, SLJIT_MUL
, flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1631 /* Commutative unsigned operations. */
1632 if (!HAS_FLAGS(op
) || GET_OPCODE(op
) == SLJIT_AND
) {
1633 if (TEST_UL_IMM(src2
, src2w
)) {
1634 compiler
->imm
= (sljit_ins
)src2w
;
1635 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1637 if (TEST_UL_IMM(src1
, src1w
)) {
1638 compiler
->imm
= (sljit_ins
)src1w
;
1639 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM1
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1641 if (TEST_UH_IMM(src2
, src2w
)) {
1642 compiler
->imm
= (sljit_ins
)(src2w
>> 16) & 0xffff;
1643 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM2
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1645 if (TEST_UH_IMM(src1
, src1w
)) {
1646 compiler
->imm
= (sljit_ins
)(src1w
>> 16) & 0xffff;
1647 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM2
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1650 if (!HAS_FLAGS(op
) && GET_OPCODE(op
) != SLJIT_AND
) {
1651 /* Unlike or and xor, the and resets unwanted bits as well. */
1652 if (TEST_UI_IMM(src2
, src2w
)) {
1653 compiler
->imm
= (sljit_ins
)src2w
;
1654 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM3
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1656 if (TEST_UI_IMM(src1
, src1w
)) {
1657 compiler
->imm
= (sljit_ins
)src1w
;
1658 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM3
, dst
, dstw
, src2
, src2w
, TMP_REG2
, 0);
1661 return emit_op(compiler
, GET_OPCODE(op
), flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1666 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1670 if (src2
& SLJIT_IMM
) {
1671 compiler
->imm
= (sljit_ins
)src2w
;
1672 return emit_op(compiler
, GET_OPCODE(op
), flags
| ALT_FORM1
, dst
, dstw
, src1
, src1w
, TMP_REG2
, 0);
1674 return emit_op(compiler
, GET_OPCODE(op
), flags
, dst
, dstw
, src1
, src1w
, src2
, src2w
);
1677 return SLJIT_SUCCESS
;
1680 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op2u(struct sljit_compiler
*compiler
, sljit_s32 op
,
1681 sljit_s32 src1
, sljit_sw src1w
,
1682 sljit_s32 src2
, sljit_sw src2w
)
1685 CHECK(check_sljit_emit_op2(compiler
, op
, 1, 0, 0, src1
, src1w
, src2
, src2w
));
1687 SLJIT_SKIP_CHECKS(compiler
);
1688 return sljit_emit_op2(compiler
, op
, TMP_REG2
, 0, src1
, src1w
, src2
, src2w
);
1691 #undef TEST_ADD_FORM1
1692 #undef TEST_SUB_FORM2
1693 #undef TEST_SUB_FORM3
1695 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_src(struct sljit_compiler
*compiler
, sljit_s32 op
,
1696 sljit_s32 src
, sljit_sw srcw
)
1699 CHECK(check_sljit_emit_op_src(compiler
, op
, src
, srcw
));
1700 ADJUST_LOCAL_OFFSET(src
, srcw
);
1703 case SLJIT_FAST_RETURN
:
1704 if (FAST_IS_REG(src
))
1705 FAIL_IF(push_inst(compiler
, MTLR
| S(src
)));
1707 FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, TMP_REG2
, 0, TMP_REG1
, 0, src
, srcw
));
1708 FAIL_IF(push_inst(compiler
, MTLR
| S(TMP_REG2
)));
1711 return push_inst(compiler
, BLR
);
1712 case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN
:
1713 return SLJIT_SUCCESS
;
1714 case SLJIT_PREFETCH_L1
:
1715 case SLJIT_PREFETCH_L2
:
1716 case SLJIT_PREFETCH_L3
:
1717 case SLJIT_PREFETCH_ONCE
:
1718 return emit_prefetch(compiler
, src
, srcw
);
1721 return SLJIT_SUCCESS
;
1724 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_get_register_index(sljit_s32 reg
)
1726 CHECK_REG_INDEX(check_sljit_get_register_index(reg
));
1727 return reg_map
[reg
];
1730 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_get_float_register_index(sljit_s32 reg
)
1732 CHECK_REG_INDEX(check_sljit_get_float_register_index(reg
));
1733 return freg_map
[reg
];
1736 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_custom(struct sljit_compiler
*compiler
,
1737 void *instruction
, sljit_u32 size
)
1740 CHECK(check_sljit_emit_op_custom(compiler
, instruction
, size
));
1742 return push_inst(compiler
, *(sljit_ins
*)instruction
);
1745 /* --------------------------------------------------------------------- */
1746 /* Floating point operators */
1747 /* --------------------------------------------------------------------- */
1749 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 6))
1750 #define SELECT_FOP(op, single, double) ((sljit_ins)((op & SLJIT_32) ? single : double))
1752 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1753 #define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw))
1755 #define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw))
1757 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
1758 #define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw))
1759 #define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw))
1761 #define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw))
1762 #define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw))
1765 #endif /* SLJIT_CONFIG_PPC_64 */
1767 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler
*compiler
, sljit_s32 op
,
1768 sljit_s32 dst
, sljit_sw dstw
,
1769 sljit_s32 src
, sljit_sw srcw
)
1771 if (src
& SLJIT_MEM
) {
1772 /* We can ignore the temporary data store on the stack from caching point of view. */
1773 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, src
, srcw
, TMP_REG1
));
1777 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1778 op
= GET_OPCODE(op
);
1779 FAIL_IF(push_inst(compiler
, (op
== SLJIT_CONV_S32_FROM_F64
? FCTIWZ
: FCTIDZ
) | FD(TMP_FREG1
) | FB(src
)));
1781 if (op
== SLJIT_CONV_SW_FROM_F64
) {
1782 if (FAST_IS_REG(dst
)) {
1783 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
, TMP_FREG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1784 return emit_op_mem(compiler
, WORD_DATA
| LOAD_DATA
, dst
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
);
1786 return emit_op_mem(compiler
, DOUBLE_DATA
, TMP_FREG1
, dst
, dstw
, TMP_REG1
);
1789 FAIL_IF(push_inst(compiler
, FCTIWZ
| FD(TMP_FREG1
) | FB(src
)));
1792 if (FAST_IS_REG(dst
)) {
1793 FAIL_IF(load_immediate(compiler
, TMP_REG1
, FLOAT_TMP_MEM_OFFSET
));
1794 FAIL_IF(push_inst(compiler
, STFIWX
| FS(TMP_FREG1
) | A(SLJIT_SP
) | B(TMP_REG1
)));
1795 return emit_op_mem(compiler
, INT_DATA
| LOAD_DATA
, dst
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
);
1798 SLJIT_ASSERT(dst
& SLJIT_MEM
);
1800 if (dst
& OFFS_REG_MASK
) {
1803 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1804 FAIL_IF(push_inst(compiler
, RLWINM
| S(OFFS_REG(dst
)) | A(TMP_REG1
) | ((sljit_ins
)dstw
<< 11) | ((31 - (sljit_ins
)dstw
) << 1)));
1806 FAIL_IF(push_inst(compiler
, RLDI(TMP_REG1
, OFFS_REG(dst
), dstw
, 63 - dstw
, 1)));
1811 dstw
= OFFS_REG(dst
);
1814 if ((dst
& REG_MASK
) && !dstw
) {
1815 dstw
= dst
& REG_MASK
;
1819 /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */
1820 FAIL_IF(load_immediate(compiler
, TMP_REG1
, dstw
));
1825 return push_inst(compiler
, STFIWX
| FS(TMP_FREG1
) | A(dst
& REG_MASK
) | B(dstw
));
1828 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler
*compiler
, sljit_s32 op
,
1829 sljit_s32 dst
, sljit_sw dstw
,
1830 sljit_s32 src
, sljit_sw srcw
)
1832 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1834 sljit_s32 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG1
;
1836 if (src
& SLJIT_IMM
) {
1837 if (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_S32
)
1838 srcw
= (sljit_s32
)srcw
;
1840 FAIL_IF(load_immediate(compiler
, TMP_REG1
, srcw
));
1843 else if (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_S32
) {
1844 if (FAST_IS_REG(src
))
1845 FAIL_IF(push_inst(compiler
, EXTSW
| S(src
) | A(TMP_REG1
)));
1847 FAIL_IF(emit_op_mem(compiler
, INT_DATA
| SIGNED_DATA
| LOAD_DATA
, TMP_REG1
, src
, srcw
, TMP_REG1
));
1851 if (FAST_IS_REG(src
)) {
1852 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, src
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1853 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
| LOAD_DATA
, TMP_FREG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1856 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
| LOAD_DATA
, TMP_FREG1
, src
, srcw
, TMP_REG1
));
1858 FAIL_IF(push_inst(compiler
, FCFID
| FD(dst_r
) | FB(TMP_FREG1
)));
1860 if (dst
& SLJIT_MEM
)
1861 return emit_op_mem(compiler
, FLOAT_DATA(op
), TMP_FREG1
, dst
, dstw
, TMP_REG1
);
1863 return push_inst(compiler
, FRSP
| FD(dst_r
) | FB(dst_r
));
1864 return SLJIT_SUCCESS
;
1868 sljit_s32 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG1
;
1869 sljit_s32 invert_sign
= 1;
1871 if (src
& SLJIT_IMM
) {
1872 FAIL_IF(load_immediate(compiler
, TMP_REG1
, srcw
^ (sljit_sw
)0x80000000));
1876 else if (!FAST_IS_REG(src
)) {
1877 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
| SIGNED_DATA
| LOAD_DATA
, TMP_REG1
, src
, srcw
, TMP_REG1
));
1881 /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31)))
1882 The double precision format has exactly 53 bit precision, so the lower 32 bit represents
1883 the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000
1884 to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating
1885 point value, we need to substract 2^53 + 2^31 from the constructed value. */
1886 FAIL_IF(push_inst(compiler
, ADDIS
| D(TMP_REG2
) | A(0) | 0x4330));
1888 FAIL_IF(push_inst(compiler
, XORIS
| S(src
) | A(TMP_REG1
) | 0x8000));
1889 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, TMP_REG2
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET_HI
, TMP_REG1
));
1890 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, TMP_REG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET_LOW
, TMP_REG2
));
1891 FAIL_IF(push_inst(compiler
, ADDIS
| D(TMP_REG1
) | A(0) | 0x8000));
1892 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
| LOAD_DATA
, TMP_FREG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1893 FAIL_IF(emit_op_mem(compiler
, WORD_DATA
, TMP_REG1
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET_LOW
, TMP_REG2
));
1894 FAIL_IF(emit_op_mem(compiler
, DOUBLE_DATA
| LOAD_DATA
, TMP_FREG2
, SLJIT_MEM1(SLJIT_SP
), FLOAT_TMP_MEM_OFFSET
, TMP_REG1
));
1896 FAIL_IF(push_inst(compiler
, FSUB
| FD(dst_r
) | FA(TMP_FREG1
) | FB(TMP_FREG2
)));
1898 if (dst
& SLJIT_MEM
)
1899 return emit_op_mem(compiler
, FLOAT_DATA(op
), TMP_FREG1
, dst
, dstw
, TMP_REG1
);
1901 return push_inst(compiler
, FRSP
| FD(dst_r
) | FB(dst_r
));
1902 return SLJIT_SUCCESS
;
1907 static SLJIT_INLINE sljit_s32
sljit_emit_fop1_cmp(struct sljit_compiler
*compiler
, sljit_s32 op
,
1908 sljit_s32 src1
, sljit_sw src1w
,
1909 sljit_s32 src2
, sljit_sw src2w
)
1911 if (src1
& SLJIT_MEM
) {
1912 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, src1
, src1w
, TMP_REG1
));
1916 if (src2
& SLJIT_MEM
) {
1917 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG2
, src2
, src2w
, TMP_REG2
));
1921 FAIL_IF(push_inst(compiler
, FCMPU
| CRD(4) | FA(src1
) | FB(src2
)));
1923 switch (GET_FLAG_TYPE(op
)) {
1924 case SLJIT_UNORDERED_OR_EQUAL
:
1925 case SLJIT_ORDERED_NOT_EQUAL
:
1926 return push_inst(compiler
, CROR
| ((4 + 2) << 21) | ((4 + 2) << 16) | ((4 + 3) << 11));
1927 case SLJIT_UNORDERED_OR_LESS
:
1928 case SLJIT_ORDERED_GREATER_EQUAL
:
1929 return push_inst(compiler
, CROR
| ((4 + 0) << 21) | ((4 + 0) << 16) | ((4 + 3) << 11));
1930 case SLJIT_UNORDERED_OR_GREATER
:
1931 case SLJIT_ORDERED_LESS_EQUAL
:
1932 return push_inst(compiler
, CROR
| ((4 + 1) << 21) | ((4 + 1) << 16) | ((4 + 3) << 11));
1935 return SLJIT_SUCCESS
;
1938 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fop1(struct sljit_compiler
*compiler
, sljit_s32 op
,
1939 sljit_s32 dst
, sljit_sw dstw
,
1940 sljit_s32 src
, sljit_sw srcw
)
1946 SLJIT_COMPILE_ASSERT((SLJIT_32
== 0x100) && !(DOUBLE_DATA
& 0x4), float_transfer_bit_error
);
1947 SELECT_FOP1_OPERATION_WITH_CHECKS(compiler
, op
, dst
, dstw
, src
, srcw
);
1949 if (GET_OPCODE(op
) == SLJIT_CONV_F64_FROM_F32
)
1952 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG1
;
1954 if (src
& SLJIT_MEM
) {
1955 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, dst_r
, src
, srcw
, TMP_REG1
));
1959 switch (GET_OPCODE(op
)) {
1960 case SLJIT_CONV_F64_FROM_F32
:
1962 if (op
& SLJIT_32
) {
1963 FAIL_IF(push_inst(compiler
, FRSP
| FD(dst_r
) | FB(src
)));
1969 if (dst_r
!= TMP_FREG1
)
1970 FAIL_IF(push_inst(compiler
, FMR
| FD(dst_r
) | FB(src
)));
1976 FAIL_IF(push_inst(compiler
, FNEG
| FD(dst_r
) | FB(src
)));
1979 FAIL_IF(push_inst(compiler
, FABS
| FD(dst_r
) | FB(src
)));
1983 if (dst
& SLJIT_MEM
)
1984 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
), dst_r
, dst
, dstw
, TMP_REG1
));
1985 return SLJIT_SUCCESS
;
1988 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fop2(struct sljit_compiler
*compiler
, sljit_s32 op
,
1989 sljit_s32 dst
, sljit_sw dstw
,
1990 sljit_s32 src1
, sljit_sw src1w
,
1991 sljit_s32 src2
, sljit_sw src2w
)
1996 CHECK(check_sljit_emit_fop2(compiler
, op
, dst
, dstw
, src1
, src1w
, src2
, src2w
));
1997 ADJUST_LOCAL_OFFSET(dst
, dstw
);
1998 ADJUST_LOCAL_OFFSET(src1
, src1w
);
1999 ADJUST_LOCAL_OFFSET(src2
, src2w
);
2001 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_FREG2
;
2003 if (src1
& SLJIT_MEM
) {
2004 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG1
, src1
, src1w
, TMP_REG1
));
2008 if (src2
& SLJIT_MEM
) {
2009 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
) | LOAD_DATA
, TMP_FREG2
, src2
, src2w
, TMP_REG2
));
2013 switch (GET_OPCODE(op
)) {
2015 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FADDS
, FADD
) | FD(dst_r
) | FA(src1
) | FB(src2
)));
2019 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FSUBS
, FSUB
) | FD(dst_r
) | FA(src1
) | FB(src2
)));
2023 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FMULS
, FMUL
) | FD(dst_r
) | FA(src1
) | FC(src2
) /* FMUL use FC as src2 */));
2027 FAIL_IF(push_inst(compiler
, SELECT_FOP(op
, FDIVS
, FDIV
) | FD(dst_r
) | FA(src1
) | FB(src2
)));
2031 if (dst
& SLJIT_MEM
)
2032 FAIL_IF(emit_op_mem(compiler
, FLOAT_DATA(op
), TMP_FREG2
, dst
, dstw
, TMP_REG1
));
2034 return SLJIT_SUCCESS
;
2039 /* --------------------------------------------------------------------- */
2040 /* Other instructions */
2041 /* --------------------------------------------------------------------- */
2043 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fast_enter(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
)
2046 CHECK(check_sljit_emit_fast_enter(compiler
, dst
, dstw
));
2047 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2049 if (FAST_IS_REG(dst
))
2050 return push_inst(compiler
, MFLR
| D(dst
));
2053 FAIL_IF(push_inst(compiler
, MFLR
| D(TMP_REG2
)));
2054 return emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0);
2057 /* --------------------------------------------------------------------- */
2058 /* Conditional instructions */
2059 /* --------------------------------------------------------------------- */
2061 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_label
* sljit_emit_label(struct sljit_compiler
*compiler
)
2063 struct sljit_label
*label
;
2066 CHECK_PTR(check_sljit_emit_label(compiler
));
2068 if (compiler
->last_label
&& compiler
->last_label
->size
== compiler
->size
)
2069 return compiler
->last_label
;
2071 label
= (struct sljit_label
*)ensure_abuf(compiler
, sizeof(struct sljit_label
));
2072 PTR_FAIL_IF(!label
);
2073 set_label(label
, compiler
);
2077 static sljit_ins
get_bo_bi_flags(struct sljit_compiler
*compiler
, sljit_s32 type
)
2080 case SLJIT_NOT_CARRY
:
2081 if (compiler
->status_flags_state
& SLJIT_CURRENT_FLAGS_SUB
)
2082 return (4 << 21) | (2 << 16);
2086 return (12 << 21) | (2 << 16);
2089 if (compiler
->status_flags_state
& SLJIT_CURRENT_FLAGS_SUB
)
2090 return (12 << 21) | (2 << 16);
2093 case SLJIT_NOT_EQUAL
:
2094 return (4 << 21) | (2 << 16);
2097 case SLJIT_SIG_LESS
:
2098 return (12 << 21) | (0 << 16);
2100 case SLJIT_GREATER_EQUAL
:
2101 case SLJIT_SIG_GREATER_EQUAL
:
2102 return (4 << 21) | (0 << 16);
2105 case SLJIT_SIG_GREATER
:
2106 return (12 << 21) | (1 << 16);
2108 case SLJIT_LESS_EQUAL
:
2109 case SLJIT_SIG_LESS_EQUAL
:
2110 return (4 << 21) | (1 << 16);
2112 case SLJIT_OVERFLOW
:
2113 return (12 << 21) | (3 << 16);
2115 case SLJIT_NOT_OVERFLOW
:
2116 return (4 << 21) | (3 << 16);
2119 case SLJIT_ORDERED_LESS
:
2120 case SLJIT_UNORDERED_OR_LESS
:
2121 return (12 << 21) | ((4 + 0) << 16);
2123 case SLJIT_F_GREATER_EQUAL
:
2124 case SLJIT_ORDERED_GREATER_EQUAL
:
2125 case SLJIT_UNORDERED_OR_GREATER_EQUAL
:
2126 return (4 << 21) | ((4 + 0) << 16);
2128 case SLJIT_F_GREATER
:
2129 case SLJIT_ORDERED_GREATER
:
2130 case SLJIT_UNORDERED_OR_GREATER
:
2131 return (12 << 21) | ((4 + 1) << 16);
2133 case SLJIT_F_LESS_EQUAL
:
2134 case SLJIT_ORDERED_LESS_EQUAL
:
2135 case SLJIT_UNORDERED_OR_LESS_EQUAL
:
2136 return (4 << 21) | ((4 + 1) << 16);
2139 case SLJIT_ORDERED_EQUAL
:
2140 case SLJIT_UNORDERED_OR_EQUAL
:
2141 return (12 << 21) | ((4 + 2) << 16);
2143 case SLJIT_F_NOT_EQUAL
:
2144 case SLJIT_ORDERED_NOT_EQUAL
:
2145 case SLJIT_UNORDERED_OR_NOT_EQUAL
:
2146 return (4 << 21) | ((4 + 2) << 16);
2148 case SLJIT_UNORDERED
:
2149 return (12 << 21) | ((4 + 3) << 16);
2152 return (4 << 21) | ((4 + 3) << 16);
2155 SLJIT_ASSERT(type
>= SLJIT_JUMP
&& type
<= SLJIT_CALL_REG_ARG
);
2160 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_jump(struct sljit_compiler
*compiler
, sljit_s32 type
)
2162 struct sljit_jump
*jump
;
2163 sljit_ins bo_bi_flags
;
2166 CHECK_PTR(check_sljit_emit_jump(compiler
, type
));
2168 bo_bi_flags
= get_bo_bi_flags(compiler
, type
& 0xff);
2172 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
2174 set_jump(jump
, compiler
, (sljit_u32
)type
& SLJIT_REWRITABLE_JUMP
);
2177 if (type
== SLJIT_CARRY
|| type
== SLJIT_NOT_CARRY
)
2178 PTR_FAIL_IF(push_inst(compiler
, ADDE
| RC(ALT_SET_FLAGS
) | D(TMP_REG1
) | A(TMP_ZERO
) | B(TMP_ZERO
)));
2180 /* In PPC, we don't need to touch the arguments. */
2181 if (type
< SLJIT_JUMP
)
2182 jump
->flags
|= IS_COND
;
2183 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2184 if (type
>= SLJIT_CALL
)
2185 jump
->flags
|= IS_CALL
;
2188 PTR_FAIL_IF(emit_const(compiler
, TMP_CALL_REG
, 0));
2189 PTR_FAIL_IF(push_inst(compiler
, MTCTR
| S(TMP_CALL_REG
)));
2190 jump
->addr
= compiler
->size
;
2191 PTR_FAIL_IF(push_inst(compiler
, BCCTR
| bo_bi_flags
| (type
>= SLJIT_FAST_CALL
? 1 : 0)));
2195 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_call(struct sljit_compiler
*compiler
, sljit_s32 type
,
2196 sljit_s32 arg_types
)
2199 CHECK_PTR(check_sljit_emit_call(compiler
, type
, arg_types
));
2201 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2202 if ((type
& 0xff) != SLJIT_CALL_REG_ARG
)
2203 PTR_FAIL_IF(call_with_args(compiler
, arg_types
, NULL
));
2206 if (type
& SLJIT_CALL_RETURN
) {
2207 PTR_FAIL_IF(emit_stack_frame_release(compiler
));
2208 type
= SLJIT_JUMP
| (type
& SLJIT_REWRITABLE_JUMP
);
2211 SLJIT_SKIP_CHECKS(compiler
);
2212 return sljit_emit_jump(compiler
, type
);
2215 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_ijump(struct sljit_compiler
*compiler
, sljit_s32 type
, sljit_s32 src
, sljit_sw srcw
)
2217 struct sljit_jump
*jump
= NULL
;
2221 CHECK(check_sljit_emit_ijump(compiler
, type
, src
, srcw
));
2222 ADJUST_LOCAL_OFFSET(src
, srcw
);
2224 if (FAST_IS_REG(src
)) {
2225 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2226 if (type
>= SLJIT_CALL
&& src
!= TMP_CALL_REG
) {
2227 FAIL_IF(push_inst(compiler
, OR
| S(src
) | A(TMP_CALL_REG
) | B(src
)));
2228 src_r
= TMP_CALL_REG
;
2232 #else /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
2234 #endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
2235 } else if (src
& SLJIT_IMM
) {
2236 /* These jumps are converted to jump/call instructions when possible. */
2237 jump
= (struct sljit_jump
*)ensure_abuf(compiler
, sizeof(struct sljit_jump
));
2239 set_jump(jump
, compiler
, JUMP_ADDR
);
2240 jump
->u
.target
= (sljit_uw
)srcw
;
2242 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2243 if (type
>= SLJIT_CALL
)
2244 jump
->flags
|= IS_CALL
;
2245 #endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
2247 FAIL_IF(emit_const(compiler
, TMP_CALL_REG
, 0));
2248 src_r
= TMP_CALL_REG
;
2251 FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, TMP_CALL_REG
, 0, TMP_REG1
, 0, src
, srcw
));
2252 src_r
= TMP_CALL_REG
;
2255 FAIL_IF(push_inst(compiler
, MTCTR
| S(src_r
)));
2257 jump
->addr
= compiler
->size
;
2258 return push_inst(compiler
, BCCTR
| (20 << 21) | (type
>= SLJIT_FAST_CALL
? 1 : 0));
2261 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_icall(struct sljit_compiler
*compiler
, sljit_s32 type
,
2262 sljit_s32 arg_types
,
2263 sljit_s32 src
, sljit_sw srcw
)
2266 CHECK(check_sljit_emit_icall(compiler
, type
, arg_types
, src
, srcw
));
2268 if (src
& SLJIT_MEM
) {
2269 ADJUST_LOCAL_OFFSET(src
, srcw
);
2270 FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, TMP_CALL_REG
, 0, TMP_REG1
, 0, src
, srcw
));
2274 if (type
& SLJIT_CALL_RETURN
) {
2275 if (src
>= SLJIT_FIRST_SAVED_REG
&& src
<= SLJIT_S0
) {
2276 FAIL_IF(push_inst(compiler
, OR
| S(src
) | A(TMP_CALL_REG
) | B(src
)));
2280 FAIL_IF(emit_stack_frame_release(compiler
));
2284 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2285 if ((type
& 0xff) != SLJIT_CALL_REG_ARG
)
2286 FAIL_IF(call_with_args(compiler
, arg_types
, &src
));
2289 SLJIT_SKIP_CHECKS(compiler
);
2290 return sljit_emit_ijump(compiler
, type
, src
, srcw
);
2293 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_op_flags(struct sljit_compiler
*compiler
, sljit_s32 op
,
2294 sljit_s32 dst
, sljit_sw dstw
,
2297 sljit_s32 reg
, invert
;
2298 sljit_u32 bit
, from_xer
;
2299 sljit_s32 saved_op
= op
;
2300 sljit_sw saved_dstw
= dstw
;
2301 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2302 sljit_s32 input_flags
= ((op
& SLJIT_32
) || op
== SLJIT_MOV32
) ? INT_DATA
: WORD_DATA
;
2304 sljit_s32 input_flags
= WORD_DATA
;
2308 CHECK(check_sljit_emit_op_flags(compiler
, op
, dst
, dstw
, type
));
2309 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2311 op
= GET_OPCODE(op
);
2312 reg
= (op
< SLJIT_ADD
&& FAST_IS_REG(dst
)) ? dst
: TMP_REG2
;
2314 if (op
>= SLJIT_ADD
&& (dst
& SLJIT_MEM
))
2315 FAIL_IF(emit_op_mem(compiler
, input_flags
| LOAD_DATA
, TMP_REG1
, dst
, dstw
, TMP_REG1
));
2323 case SLJIT_SIG_LESS
:
2326 case SLJIT_GREATER_EQUAL
:
2327 case SLJIT_SIG_GREATER_EQUAL
:
2332 case SLJIT_SIG_GREATER
:
2336 case SLJIT_LESS_EQUAL
:
2337 case SLJIT_SIG_LESS_EQUAL
:
2346 case SLJIT_NOT_EQUAL
:
2351 case SLJIT_OVERFLOW
:
2356 case SLJIT_NOT_OVERFLOW
:
2365 invert
= (compiler
->status_flags_state
& SLJIT_CURRENT_FLAGS_SUB
) != 0;
2368 case SLJIT_NOT_CARRY
:
2371 invert
= (compiler
->status_flags_state
& SLJIT_CURRENT_FLAGS_ADD
) != 0;
2375 case SLJIT_ORDERED_LESS
:
2376 case SLJIT_UNORDERED_OR_LESS
:
2380 case SLJIT_F_GREATER_EQUAL
:
2381 case SLJIT_ORDERED_GREATER_EQUAL
:
2382 case SLJIT_UNORDERED_OR_GREATER_EQUAL
:
2387 case SLJIT_F_GREATER
:
2388 case SLJIT_ORDERED_GREATER
:
2389 case SLJIT_UNORDERED_OR_GREATER
:
2393 case SLJIT_F_LESS_EQUAL
:
2394 case SLJIT_ORDERED_LESS_EQUAL
:
2395 case SLJIT_UNORDERED_OR_LESS_EQUAL
:
2401 case SLJIT_ORDERED_EQUAL
:
2402 case SLJIT_UNORDERED_OR_EQUAL
:
2406 case SLJIT_F_NOT_EQUAL
:
2407 case SLJIT_ORDERED_NOT_EQUAL
:
2408 case SLJIT_UNORDERED_OR_NOT_EQUAL
:
2413 case SLJIT_UNORDERED
:
2423 SLJIT_UNREACHABLE();
2427 FAIL_IF(push_inst(compiler
, (from_xer
? MFXER
: MFCR
) | D(reg
)));
2428 FAIL_IF(push_inst(compiler
, RLWINM
| S(reg
) | A(reg
) | ((1 + bit
) << 11) | (31 << 6) | (31 << 1)));
2431 FAIL_IF(push_inst(compiler
, XORI
| S(reg
) | A(reg
) | 0x1));
2433 if (op
< SLJIT_ADD
) {
2434 if (!(dst
& SLJIT_MEM
))
2435 return SLJIT_SUCCESS
;
2436 return emit_op_mem(compiler
, input_flags
, reg
, dst
, dstw
, TMP_REG1
);
2439 SLJIT_SKIP_CHECKS(compiler
);
2441 if (dst
& SLJIT_MEM
)
2442 return sljit_emit_op2(compiler
, saved_op
, dst
, saved_dstw
, TMP_REG1
, 0, TMP_REG2
, 0);
2443 return sljit_emit_op2(compiler
, saved_op
, dst
, 0, dst
, 0, TMP_REG2
, 0);
2446 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_cmov(struct sljit_compiler
*compiler
, sljit_s32 type
,
2448 sljit_s32 src
, sljit_sw srcw
)
2451 CHECK(check_sljit_emit_cmov(compiler
, type
, dst_reg
, src
, srcw
));
2453 return sljit_emit_cmov_generic(compiler
, type
, dst_reg
, src
, srcw
);;
2456 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_mem(struct sljit_compiler
*compiler
, sljit_s32 type
,
2458 sljit_s32 mem
, sljit_sw memw
)
2460 sljit_s32 mem_flags
;
2464 CHECK(check_sljit_emit_mem(compiler
, type
, reg
, mem
, memw
));
2466 if (type
& SLJIT_MEM_UNALIGNED
)
2467 return sljit_emit_mem_unaligned(compiler
, type
, reg
, mem
, memw
);
2469 if (type
& SLJIT_MEM_POST
)
2470 return SLJIT_ERR_UNSUPPORTED
;
2472 switch (type
& 0xff) {
2475 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
2480 mem_flags
= WORD_DATA
;
2483 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2486 mem_flags
= INT_DATA
;
2490 mem_flags
= INT_DATA
;
2492 if (!(type
& SLJIT_MEM_STORE
) && !(type
& SLJIT_32
)) {
2493 if (mem
& OFFS_REG_MASK
)
2494 mem_flags
|= SIGNED_DATA
;
2496 return SLJIT_ERR_UNSUPPORTED
;
2503 mem_flags
= BYTE_DATA
;
2507 mem_flags
= HALF_DATA
;
2511 mem_flags
= HALF_DATA
| SIGNED_DATA
;
2515 SLJIT_UNREACHABLE();
2516 mem_flags
= WORD_DATA
;
2520 if (!(type
& SLJIT_MEM_STORE
))
2521 mem_flags
|= LOAD_DATA
;
2523 if (SLJIT_UNLIKELY(mem
& OFFS_REG_MASK
)) {
2525 return SLJIT_ERR_UNSUPPORTED
;
2527 if (type
& SLJIT_MEM_SUPP
)
2528 return SLJIT_SUCCESS
;
2530 inst
= updated_data_transfer_insts
[mem_flags
| INDEXED
];
2531 FAIL_IF(push_inst(compiler
, INST_CODE_AND_DST(inst
, 0, reg
) | A(mem
& REG_MASK
) | B(OFFS_REG(mem
))));
2534 if (memw
> SIMM_MAX
|| memw
< SIMM_MIN
)
2535 return SLJIT_ERR_UNSUPPORTED
;
2537 inst
= updated_data_transfer_insts
[mem_flags
];
2539 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2540 if ((inst
& INT_ALIGNED
) && (memw
& 0x3) != 0)
2541 return SLJIT_ERR_UNSUPPORTED
;
2544 if (type
& SLJIT_MEM_SUPP
)
2545 return SLJIT_SUCCESS
;
2547 FAIL_IF(push_inst(compiler
, INST_CODE_AND_DST(inst
, 0, reg
) | A(mem
& REG_MASK
) | IMM(memw
)));
2550 if ((mem_flags
& LOAD_DATA
) && (type
& 0xff) == SLJIT_MOV_S8
)
2551 return push_inst(compiler
, EXTSB
| S(reg
) | A(reg
));
2552 return SLJIT_SUCCESS
;
2555 SLJIT_API_FUNC_ATTRIBUTE sljit_s32
sljit_emit_fmem(struct sljit_compiler
*compiler
, sljit_s32 type
,
2557 sljit_s32 mem
, sljit_sw memw
)
2559 sljit_s32 mem_flags
;
2563 CHECK(check_sljit_emit_fmem(compiler
, type
, freg
, mem
, memw
));
2565 if (type
& SLJIT_MEM_UNALIGNED
)
2566 return sljit_emit_fmem_unaligned(compiler
, type
, freg
, mem
, memw
);
2568 if (type
& SLJIT_MEM_POST
)
2569 return SLJIT_ERR_UNSUPPORTED
;
2571 if (SLJIT_UNLIKELY(mem
& OFFS_REG_MASK
)) {
2573 return SLJIT_ERR_UNSUPPORTED
;
2576 if (memw
> SIMM_MAX
|| memw
< SIMM_MIN
)
2577 return SLJIT_ERR_UNSUPPORTED
;
2580 if (type
& SLJIT_MEM_SUPP
)
2581 return SLJIT_SUCCESS
;
2583 mem_flags
= FLOAT_DATA(type
);
2585 if (!(type
& SLJIT_MEM_STORE
))
2586 mem_flags
|= LOAD_DATA
;
2588 if (SLJIT_UNLIKELY(mem
& OFFS_REG_MASK
)) {
2589 inst
= updated_data_transfer_insts
[mem_flags
| INDEXED
];
2590 return push_inst(compiler
, INST_CODE_AND_DST(inst
, DOUBLE_DATA
, freg
) | A(mem
& REG_MASK
) | B(OFFS_REG(mem
)));
2593 inst
= updated_data_transfer_insts
[mem_flags
];
2594 return push_inst(compiler
, INST_CODE_AND_DST(inst
, DOUBLE_DATA
, freg
) | A(mem
& REG_MASK
) | IMM(memw
));
2597 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_const
* sljit_emit_const(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
, sljit_sw init_value
)
2599 struct sljit_const
*const_
;
2603 CHECK_PTR(check_sljit_emit_const(compiler
, dst
, dstw
, init_value
));
2604 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2606 const_
= (struct sljit_const
*)ensure_abuf(compiler
, sizeof(struct sljit_const
));
2607 PTR_FAIL_IF(!const_
);
2608 set_const(const_
, compiler
);
2610 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_REG2
;
2611 PTR_FAIL_IF(emit_const(compiler
, dst_r
, init_value
));
2613 if (dst
& SLJIT_MEM
)
2614 PTR_FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0));
2619 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_put_label
* sljit_emit_put_label(struct sljit_compiler
*compiler
, sljit_s32 dst
, sljit_sw dstw
)
2621 struct sljit_put_label
*put_label
;
2625 CHECK_PTR(check_sljit_emit_put_label(compiler
, dst
, dstw
));
2626 ADJUST_LOCAL_OFFSET(dst
, dstw
);
2628 put_label
= (struct sljit_put_label
*)ensure_abuf(compiler
, sizeof(struct sljit_put_label
));
2629 PTR_FAIL_IF(!put_label
);
2630 set_put_label(put_label
, compiler
, 0);
2632 dst_r
= FAST_IS_REG(dst
) ? dst
: TMP_REG2
;
2633 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
2634 PTR_FAIL_IF(emit_const(compiler
, dst_r
, 0));
2636 PTR_FAIL_IF(push_inst(compiler
, (sljit_ins
)dst_r
));
2637 compiler
->size
+= 4;
2640 if (dst
& SLJIT_MEM
)
2641 PTR_FAIL_IF(emit_op(compiler
, SLJIT_MOV
, WORD_DATA
, dst
, dstw
, TMP_REG1
, 0, TMP_REG2
, 0));
2646 SLJIT_API_FUNC_ATTRIBUTE
void sljit_set_const(sljit_uw addr
, sljit_sw new_constant
, sljit_sw executable_offset
)
2648 sljit_set_jump_addr(addr
, (sljit_uw
)new_constant
, executable_offset
);