2 * Stack-less Just-In-Time compiler
4 * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
6 * Redistribution and use in source and binary forms, with or without modification, are
7 * permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice, this list of
10 * conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
13 * of conditions and the following disclaimer in the documentation and/or other materials
14 * provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
29 return "PowerPC" SLJIT_CPUINFO;
32 /* Length of an instruction word.
33 Both for ppc-32 and ppc-64. */
34 typedef sljit_ui sljit_ins;
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 SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
46 #define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1
49 static void ppc_cache_flush(sljit_ins *from, sljit_ins *to)
52 _sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from));
53 #elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
54 # if defined(_ARCH_PWR) || defined(_ARCH_PWR2)
55 /* Cache flush for POWER architecture. */
64 __asm__ volatile ( "ics" );
65 # elif defined(_ARCH_COM) && !defined(_ARCH_PPC)
66 # error "Cache flush is not implemented for PowerPC/POWER common mode."
68 /* Cache flush for PowerPC architecture. */
78 __asm__ volatile ( "isync" );
81 # warning "This file may fail to compile if -qfuncsect is used"
83 #elif defined(__xlc__)
84 #error "Please enable GCC syntax for inline assembly statements with -qasm=gcc"
86 #error "This platform requires a cache flush implementation."
90 #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
91 #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
92 #define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
93 #define TMP_ZERO (SLJIT_NUMBER_OF_REGISTERS + 5)
95 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
96 #define TMP_CALL_REG (SLJIT_NUMBER_OF_REGISTERS + 6)
98 #define TMP_CALL_REG TMP_REG2
101 #define TMP_FREG1 (0)
102 #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
104 static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {
105 0, 3, 4, 5, 6, 7, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 8, 9, 10, 31, 12
108 /* --------------------------------------------------------------------- */
109 /* Instrucion forms */
110 /* --------------------------------------------------------------------- */
111 #define D(d) (reg_map[d] << 21)
112 #define S(s) (reg_map[s] << 21)
113 #define A(a) (reg_map[a] << 16)
114 #define B(b) (reg_map[b] << 11)
115 #define C(c) (reg_map[c] << 6)
116 #define FD(fd) ((fd) << 21)
117 #define FS(fs) ((fs) << 21)
118 #define FA(fa) ((fa) << 16)
119 #define FB(fb) ((fb) << 11)
120 #define FC(fc) ((fc) << 6)
121 #define IMM(imm) ((imm) & 0xffff)
122 #define CRD(d) ((d) << 21)
124 /* Instruction bit sections.
125 OE and Rc flag (see ALT_SET_FLAGS). */
126 #define OERC(flags) (((flags & ALT_SET_FLAGS) >> 10) | (flags & ALT_SET_FLAGS))
127 /* Rc flag (see ALT_SET_FLAGS). */
128 #define RC(flags) ((flags & ALT_SET_FLAGS) >> 10)
129 #define HI(opcode) ((opcode) << 26)
130 #define LO(opcode) ((opcode) << 1)
132 #define ADD (HI(31) | LO(266))
133 #define ADDC (HI(31) | LO(10))
134 #define ADDE (HI(31) | LO(138))
135 #define ADDI (HI(14))
136 #define ADDIC (HI(13))
137 #define ADDIS (HI(15))
138 #define ADDME (HI(31) | LO(234))
139 #define AND (HI(31) | LO(28))
140 #define ANDI (HI(28))
141 #define ANDIS (HI(29))
144 #define BCCTR (HI(19) | LO(528) | (3 << 11))
145 #define BLR (HI(19) | LO(16) | (0x14 << 21))
146 #define CNTLZD (HI(31) | LO(58))
147 #define CNTLZW (HI(31) | LO(26))
148 #define CMP (HI(31) | LO(0))
149 #define CMPI (HI(11))
150 #define CMPL (HI(31) | LO(32))
151 #define CMPLI (HI(10))
152 #define CROR (HI(19) | LO(449))
153 #define DIVD (HI(31) | LO(489))
154 #define DIVDU (HI(31) | LO(457))
155 #define DIVW (HI(31) | LO(491))
156 #define DIVWU (HI(31) | LO(459))
157 #define EXTSB (HI(31) | LO(954))
158 #define EXTSH (HI(31) | LO(922))
159 #define EXTSW (HI(31) | LO(986))
160 #define FABS (HI(63) | LO(264))
161 #define FADD (HI(63) | LO(21))
162 #define FADDS (HI(59) | LO(21))
163 #define FCFID (HI(63) | LO(846))
164 #define FCMPU (HI(63) | LO(0))
165 #define FCTIDZ (HI(63) | LO(815))
166 #define FCTIWZ (HI(63) | LO(15))
167 #define FDIV (HI(63) | LO(18))
168 #define FDIVS (HI(59) | LO(18))
169 #define FMR (HI(63) | LO(72))
170 #define FMUL (HI(63) | LO(25))
171 #define FMULS (HI(59) | LO(25))
172 #define FNEG (HI(63) | LO(40))
173 #define FRSP (HI(63) | LO(12))
174 #define FSUB (HI(63) | LO(20))
175 #define FSUBS (HI(59) | LO(20))
176 #define LD (HI(58) | 0)
178 #define MFCR (HI(31) | LO(19))
179 #define MFLR (HI(31) | LO(339) | 0x80000)
180 #define MFXER (HI(31) | LO(339) | 0x10000)
181 #define MTCTR (HI(31) | LO(467) | 0x90000)
182 #define MTLR (HI(31) | LO(467) | 0x80000)
183 #define MTXER (HI(31) | LO(467) | 0x10000)
184 #define MULHD (HI(31) | LO(73))
185 #define MULHDU (HI(31) | LO(9))
186 #define MULHW (HI(31) | LO(75))
187 #define MULHWU (HI(31) | LO(11))
188 #define MULLD (HI(31) | LO(233))
189 #define MULLI (HI(7))
190 #define MULLW (HI(31) | LO(235))
191 #define NEG (HI(31) | LO(104))
193 #define NOR (HI(31) | LO(124))
194 #define OR (HI(31) | LO(444))
196 #define ORIS (HI(25))
197 #define RLDICL (HI(30))
198 #define RLWINM (HI(21))
199 #define SLD (HI(31) | LO(27))
200 #define SLW (HI(31) | LO(24))
201 #define SRAD (HI(31) | LO(794))
202 #define SRADI (HI(31) | LO(413 << 1))
203 #define SRAW (HI(31) | LO(792))
204 #define SRAWI (HI(31) | LO(824))
205 #define SRD (HI(31) | LO(539))
206 #define SRW (HI(31) | LO(536))
207 #define STD (HI(62) | 0)
208 #define STDU (HI(62) | 1)
209 #define STDUX (HI(31) | LO(181))
210 #define STFIWX (HI(31) | LO(983))
212 #define STWU (HI(37))
213 #define STWUX (HI(31) | LO(183))
214 #define SUBF (HI(31) | LO(40))
215 #define SUBFC (HI(31) | LO(8))
216 #define SUBFE (HI(31) | LO(136))
217 #define SUBFIC (HI(8))
218 #define XOR (HI(31) | LO(316))
219 #define XORI (HI(26))
220 #define XORIS (HI(27))
222 #define SIMM_MAX (0x7fff)
223 #define SIMM_MIN (-0x8000)
224 #define UIMM_MAX (0xffff)
226 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
227 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func)
231 *func_ptr = (void*)context;
232 ptrs = (sljit_sw*)func;
233 context->addr = addr ? addr : ptrs[0];
234 context->r2 = ptrs[1];
235 context->r11 = ptrs[2];
239 static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins)
241 sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
245 return SLJIT_SUCCESS;
248 static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
251 sljit_uw target_addr;
252 sljit_sw extra_jump_flags;
254 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
255 if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))
258 if (jump->flags & SLJIT_REWRITABLE_JUMP)
262 if (jump->flags & JUMP_ADDR)
263 target_addr = jump->u.target;
265 SLJIT_ASSERT(jump->flags & JUMP_LABEL);
266 target_addr = (sljit_uw)(code + jump->u.label->size);
269 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
270 if (jump->flags & IS_CALL)
274 diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr)) & ~0x3l;
276 extra_jump_flags = 0;
277 if (jump->flags & IS_COND) {
278 if (diff <= 0x7fff && diff >= -0x8000) {
279 jump->flags |= PATCH_B;
282 if (target_addr <= 0xffff) {
283 jump->flags |= PATCH_B | PATCH_ABS_B;
286 extra_jump_flags = REMOVE_COND;
288 diff -= sizeof(sljit_ins);
291 if (diff <= 0x01ffffff && diff >= -0x02000000) {
292 jump->flags |= PATCH_B | extra_jump_flags;
295 if (target_addr <= 0x03ffffff) {
296 jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags;
300 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
301 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
304 if (target_addr <= 0x7fffffff) {
305 jump->flags |= PATCH_ABS32;
308 if (target_addr <= 0x7fffffffffffl) {
309 jump->flags |= PATCH_ABS48;
317 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
319 struct sljit_memory_fragment *buf;
327 struct sljit_label *label;
328 struct sljit_jump *jump;
329 struct sljit_const *const_;
332 CHECK_PTR(check_sljit_generate_code(compiler));
333 reverse_buf(compiler);
335 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
336 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
337 compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
339 compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
342 code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
343 PTR_FAIL_WITH_EXEC_IF(code);
348 label = compiler->labels;
349 jump = compiler->jumps;
350 const_ = compiler->consts;
352 buf_ptr = (sljit_ins*)buf->memory;
353 buf_end = buf_ptr + (buf->used_size >> 2);
355 *code_ptr = *buf_ptr++;
356 SLJIT_ASSERT(!label || label->size >= word_count);
357 SLJIT_ASSERT(!jump || jump->addr >= word_count);
358 SLJIT_ASSERT(!const_ || const_->addr >= word_count);
359 /* These structures are ordered by their address. */
360 if (label && label->size == word_count) {
361 /* Just recording the address. */
362 label->addr = (sljit_uw)code_ptr;
363 label->size = code_ptr - code;
366 if (jump && jump->addr == word_count) {
367 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
368 jump->addr = (sljit_uw)(code_ptr - 3);
370 jump->addr = (sljit_uw)(code_ptr - 6);
372 if (detect_jump_type(jump, code_ptr, code)) {
373 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
374 code_ptr[-3] = code_ptr[0];
377 if (jump->flags & PATCH_ABS32) {
379 code_ptr[-1] = code_ptr[2];
380 code_ptr[0] = code_ptr[3];
382 else if (jump->flags & PATCH_ABS48) {
384 code_ptr[-1] = code_ptr[0];
385 code_ptr[0] = code_ptr[1];
386 /* rldicr rX,rX,32,31 -> rX,rX,16,47 */
387 SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6);
388 code_ptr[-3] ^= 0x8422;
390 code_ptr[-2] ^= 0x4000000;
393 code_ptr[-6] = code_ptr[0];
397 if (jump->flags & REMOVE_COND) {
398 code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001);
400 jump->addr += sizeof(sljit_ins);
402 jump->flags -= IS_COND;
407 if (const_ && const_->addr == word_count) {
408 const_->addr = (sljit_uw)code_ptr;
409 const_ = const_->next;
413 } while (buf_ptr < buf_end);
418 if (label && label->size == word_count) {
419 label->addr = (sljit_uw)code_ptr;
420 label->size = code_ptr - code;
424 SLJIT_ASSERT(!label);
426 SLJIT_ASSERT(!const_);
427 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
428 SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins)));
430 SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
433 jump = compiler->jumps;
436 addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
437 buf_ptr = (sljit_ins*)jump->addr;
438 if (jump->flags & PATCH_B) {
439 if (jump->flags & IS_COND) {
440 if (!(jump->flags & PATCH_ABS_B)) {
441 addr = addr - jump->addr;
442 SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000);
443 *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001);
446 SLJIT_ASSERT(addr <= 0xffff);
447 *buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001);
451 if (!(jump->flags & PATCH_ABS_B)) {
452 addr = addr - jump->addr;
453 SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000);
454 *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1);
457 SLJIT_ASSERT(addr <= 0x03ffffff);
458 *buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1);
463 /* Set the fields of immediate loads. */
464 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
465 buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
466 buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
468 if (jump->flags & PATCH_ABS32) {
469 SLJIT_ASSERT(addr <= 0x7fffffff);
470 buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
471 buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
474 if (jump->flags & PATCH_ABS48) {
475 SLJIT_ASSERT(addr <= 0x7fffffffffff);
476 buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff);
477 buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff);
478 buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff);
481 buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff);
482 buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff);
483 buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff);
484 buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff);
490 compiler->error = SLJIT_ERR_COMPILED;
491 compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
492 SLJIT_CACHE_FLUSH(code, code_ptr);
494 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
495 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
496 if (((sljit_sw)code_ptr) & 0x4)
498 sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code);
501 sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code);
509 /* --------------------------------------------------------------------- */
511 /* --------------------------------------------------------------------- */
515 /* Creates an index in data_transfer_insts array. */
516 #define LOAD_DATA 0x01
518 #define WRITE_BACK 0x04
519 #define WORD_DATA 0x00
520 #define BYTE_DATA 0x08
521 #define HALF_DATA 0x10
522 #define INT_DATA 0x18
523 #define SIGNED_DATA 0x20
524 /* Separates integer and floating point registers */
526 #define DOUBLE_DATA 0x40
528 #define MEM_MASK 0x7f
530 /* Other inp_flags. */
532 #define ARG_TEST 0x000100
533 /* Integer opertion and set flags -> requires exts on 64 bit systems. */
534 #define ALT_SIGN_EXT 0x000200
535 /* This flag affects the RC() and OERC() macros. */
536 #define ALT_SET_FLAGS 0x000400
537 #define ALT_KEEP_CACHE 0x000800
538 #define ALT_FORM1 0x010000
539 #define ALT_FORM2 0x020000
540 #define ALT_FORM3 0x040000
541 #define ALT_FORM4 0x080000
542 #define ALT_FORM5 0x100000
543 #define ALT_FORM6 0x200000
545 /* Source and destination is register. */
546 #define REG_DEST 0x000001
547 #define REG1_SOURCE 0x000002
548 #define REG2_SOURCE 0x000004
549 /* getput_arg_fast returned true. */
550 #define FAST_DEST 0x000008
551 /* Multiple instructions are required. */
552 #define SLOW_DEST 0x000010
554 ALT_SIGN_EXT 0x000200
555 ALT_SET_FLAGS 0x000400
558 ALT_FORM6 0x200000 */
560 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
561 #include "sljitNativePPC_32.c"
563 #include "sljitNativePPC_64.c"
566 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
567 #define STACK_STORE STW
568 #define STACK_LOAD LWZ
570 #define STACK_STORE STD
571 #define STACK_LOAD LD
574 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
575 sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
576 sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
578 sljit_si i, tmp, offs;
581 CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
582 set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
584 FAIL_IF(push_inst(compiler, MFLR | D(0)));
585 offs = -(sljit_si)(sizeof(sljit_sw));
586 FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
588 tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
589 for (i = SLJIT_S0; i >= tmp; i--) {
590 offs -= (sljit_si)(sizeof(sljit_sw));
591 FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
594 for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
595 offs -= (sljit_si)(sizeof(sljit_sw));
596 FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
599 SLJIT_ASSERT(offs == -(sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1));
601 #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
602 FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
604 FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
607 FAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0));
609 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(SLJIT_S0) | B(SLJIT_R0)));
611 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R1) | A(SLJIT_S1) | B(SLJIT_R1)));
613 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R2) | A(SLJIT_S2) | B(SLJIT_R2)));
615 local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
616 local_size = (local_size + 15) & ~0xf;
617 compiler->local_size = local_size;
619 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
620 if (local_size <= SIMM_MAX)
621 FAIL_IF(push_inst(compiler, STWU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
623 FAIL_IF(load_immediate(compiler, 0, -local_size));
624 FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
627 if (local_size <= SIMM_MAX)
628 FAIL_IF(push_inst(compiler, STDU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
630 FAIL_IF(load_immediate(compiler, 0, -local_size));
631 FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
635 return SLJIT_SUCCESS;
638 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
639 sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
640 sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
643 CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
644 set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
646 local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
647 compiler->local_size = (local_size + 15) & ~0xf;
648 return SLJIT_SUCCESS;
651 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
653 sljit_si i, tmp, offs;
656 CHECK(check_sljit_emit_return(compiler, op, src, srcw));
658 FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
660 if (compiler->local_size <= SIMM_MAX)
661 FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_SP) | A(SLJIT_SP) | IMM(compiler->local_size)));
663 FAIL_IF(load_immediate(compiler, 0, compiler->local_size));
664 FAIL_IF(push_inst(compiler, ADD | D(SLJIT_SP) | A(SLJIT_SP) | B(0)));
667 #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
668 FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
670 FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
673 offs = -(sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1);
675 tmp = compiler->scratches;
676 for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
677 FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
678 offs += (sljit_si)(sizeof(sljit_sw));
681 tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
682 for (i = tmp; i <= SLJIT_S0; i++) {
683 FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
684 offs += (sljit_si)(sizeof(sljit_sw));
687 FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
688 SLJIT_ASSERT(offs == -(sljit_sw)(sizeof(sljit_sw)));
690 FAIL_IF(push_inst(compiler, MTLR | S(0)));
691 FAIL_IF(push_inst(compiler, BLR));
693 return SLJIT_SUCCESS;
699 /* --------------------------------------------------------------------- */
701 /* --------------------------------------------------------------------- */
703 /* i/x - immediate/indexed form
704 n/w - no write-back / write-back (1 bit)
705 s/l - store/load (1 bit)
706 u/s - signed/unsigned (1 bit)
707 w/b/h/i - word/byte/half/int allowed (2 bit)
708 It contans 32 items, but not all are different. */
710 /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
711 #define INT_ALIGNED 0x10000
712 /* 64-bit only: there is no lwau instruction. */
713 #define UPDATE_REQ 0x20000
715 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
716 #define ARCH_32_64(a, b) a
717 #define INST_CODE_AND_DST(inst, flags, reg) \
718 ((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
720 #define ARCH_32_64(a, b) b
721 #define INST_CODE_AND_DST(inst, flags, reg) \
722 (((inst) & ~(INT_ALIGNED | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
725 static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = {
727 /* -------- Unsigned -------- */
731 /* u w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
732 /* u w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
733 /* u w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
734 /* u w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
736 /* u w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
737 /* u w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
738 /* u w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
739 /* u w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
743 /* u b n i s */ HI(38) /* stb */,
744 /* u b n i l */ HI(34) /* lbz */,
745 /* u b n x s */ HI(31) | LO(215) /* stbx */,
746 /* u b n x l */ HI(31) | LO(87) /* lbzx */,
748 /* u b w i s */ HI(39) /* stbu */,
749 /* u b w i l */ HI(35) /* lbzu */,
750 /* u b w x s */ HI(31) | LO(247) /* stbux */,
751 /* u b w x l */ HI(31) | LO(119) /* lbzux */,
755 /* u h n i s */ HI(44) /* sth */,
756 /* u h n i l */ HI(40) /* lhz */,
757 /* u h n x s */ HI(31) | LO(407) /* sthx */,
758 /* u h n x l */ HI(31) | LO(279) /* lhzx */,
760 /* u h w i s */ HI(45) /* sthu */,
761 /* u h w i l */ HI(41) /* lhzu */,
762 /* u h w x s */ HI(31) | LO(439) /* sthux */,
763 /* u h w x l */ HI(31) | LO(311) /* lhzux */,
767 /* u i n i s */ HI(36) /* stw */,
768 /* u i n i l */ HI(32) /* lwz */,
769 /* u i n x s */ HI(31) | LO(151) /* stwx */,
770 /* u i n x l */ HI(31) | LO(23) /* lwzx */,
772 /* u i w i s */ HI(37) /* stwu */,
773 /* u i w i l */ HI(33) /* lwzu */,
774 /* u i w x s */ HI(31) | LO(183) /* stwux */,
775 /* u i w x l */ HI(31) | LO(55) /* lwzux */,
777 /* -------- Signed -------- */
781 /* s w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
782 /* s w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
783 /* s w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
784 /* s w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
786 /* s w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
787 /* s w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
788 /* s w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
789 /* s w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
793 /* s b n i s */ HI(38) /* stb */,
794 /* s b n i l */ HI(34) /* lbz */ /* EXTS_REQ */,
795 /* s b n x s */ HI(31) | LO(215) /* stbx */,
796 /* s b n x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
798 /* s b w i s */ HI(39) /* stbu */,
799 /* s b w i l */ HI(35) /* lbzu */ /* EXTS_REQ */,
800 /* s b w x s */ HI(31) | LO(247) /* stbux */,
801 /* s b w x l */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */,
805 /* s h n i s */ HI(44) /* sth */,
806 /* s h n i l */ HI(42) /* lha */,
807 /* s h n x s */ HI(31) | LO(407) /* sthx */,
808 /* s h n x l */ HI(31) | LO(343) /* lhax */,
810 /* s h w i s */ HI(45) /* sthu */,
811 /* s h w i l */ HI(43) /* lhau */,
812 /* s h w x s */ HI(31) | LO(439) /* sthux */,
813 /* s h w x l */ HI(31) | LO(375) /* lhaux */,
817 /* s i n i s */ HI(36) /* stw */,
818 /* s i n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */),
819 /* s i n x s */ HI(31) | LO(151) /* stwx */,
820 /* s i n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
822 /* s i w i s */ HI(37) /* stwu */,
823 /* s i w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | UPDATE_REQ | 0x2 /* lwa */),
824 /* s i w x s */ HI(31) | LO(183) /* stwux */,
825 /* s i w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
827 /* -------- Double -------- */
829 /* d n i s */ HI(54) /* stfd */,
830 /* d n i l */ HI(50) /* lfd */,
831 /* d n x s */ HI(31) | LO(727) /* stfdx */,
832 /* d n x l */ HI(31) | LO(599) /* lfdx */,
834 /* s n i s */ HI(52) /* stfs */,
835 /* s n i l */ HI(48) /* lfs */,
836 /* s n x s */ HI(31) | LO(663) /* stfsx */,
837 /* s n x l */ HI(31) | LO(535) /* lfsx */,
843 /* Simple cases, (no caching is required). */
844 static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw)
848 /* Should work when (arg & REG_MASK) == 0. */
849 SLJIT_COMPILE_ASSERT(A(0) == 0, a0_must_be_0);
850 SLJIT_ASSERT(arg & SLJIT_MEM);
852 if (arg & OFFS_REG_MASK) {
855 if (inp_flags & ARG_TEST)
858 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
859 SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
860 FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(OFFS_REG(arg))));
864 if (SLJIT_UNLIKELY(!(arg & REG_MASK)))
865 inp_flags &= ~WRITE_BACK;
867 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
868 inst = data_transfer_insts[inp_flags & MEM_MASK];
869 SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ));
871 if (argw > SIMM_MAX || argw < SIMM_MIN || ((inst & INT_ALIGNED) && (argw & 0x3)) || (inst & UPDATE_REQ))
873 if (inp_flags & ARG_TEST)
877 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
878 if (argw > SIMM_MAX || argw < SIMM_MIN)
880 if (inp_flags & ARG_TEST)
883 inst = data_transfer_insts[inp_flags & MEM_MASK];
884 SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
887 FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | IMM(argw)));
891 /* See getput_arg below.
892 Note: can_cache is called only for binary operators. Those operator always
893 uses word arguments without write back. */
894 static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
896 sljit_sw high_short, next_high_short;
897 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
901 SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
903 if (arg & OFFS_REG_MASK)
904 return ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && (argw & 0x3) == (next_argw & 0x3));
906 if (next_arg & OFFS_REG_MASK)
909 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
910 high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff;
911 next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff;
912 return high_short == next_high_short;
914 if (argw <= 0x7fffffffl && argw >= -0x80000000l) {
915 high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff;
916 next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff;
917 if (high_short == next_high_short)
921 diff = argw - next_argw;
922 if (!(arg & REG_MASK))
923 return diff <= SIMM_MAX && diff >= SIMM_MIN;
925 if (arg == next_arg && diff <= SIMM_MAX && diff >= SIMM_MIN)
932 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
933 #define ADJUST_CACHED_IMM(imm) \
934 if ((inst & INT_ALIGNED) && (imm & 0x3)) { \
935 /* Adjust cached value. Fortunately this is really a rare case */ \
936 compiler->cache_argw += imm & 0x3; \
937 FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | (imm & 0x3))); \
942 /* Emit the necessary instructions. See can_cache above. */
943 static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
947 sljit_sw high_short, next_high_short;
948 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
952 SLJIT_ASSERT(arg & SLJIT_MEM);
954 tmp_r = ((inp_flags & LOAD_DATA) && ((inp_flags) & MEM_MASK) <= GPR_REG) ? reg : TMP_REG1;
955 /* Special case for "mov reg, [reg, ... ]". */
956 if ((arg & REG_MASK) == tmp_r)
959 if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
961 /* Otherwise getput_arg_fast would capture it. */
964 if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg && argw == compiler->cache_argw)
967 if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) {
968 compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
969 compiler->cache_argw = argw;
972 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
973 FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(arg)) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1)));
975 FAIL_IF(push_inst(compiler, RLDI(tmp_r, OFFS_REG(arg), argw, 63 - argw, 1)));
978 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
979 SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
980 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r));
983 if (SLJIT_UNLIKELY(!(arg & REG_MASK)))
984 inp_flags &= ~WRITE_BACK;
986 inst = data_transfer_insts[inp_flags & MEM_MASK];
987 SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ));
989 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
990 if (argw <= 0x7fff7fffl && argw >= -0x80000000l
991 && (!(inst & INT_ALIGNED) || !(argw & 0x3)) && !(inst & UPDATE_REQ)) {
995 high_short = (sljit_si)(argw + ((argw & 0x8000) << 1)) & ~0xffff;
996 /* The getput_arg_fast should handle this otherwise. */
997 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
998 SLJIT_ASSERT(high_short && high_short <= 0x7fffffffl && high_short >= -0x80000000l);
1000 SLJIT_ASSERT(high_short && !(inst & (INT_ALIGNED | UPDATE_REQ)));
1003 if (inp_flags & WRITE_BACK) {
1005 FAIL_IF(push_inst(compiler, OR | S(reg) | A(tmp_r) | B(reg)));
1009 FAIL_IF(push_inst(compiler, ADDIS | D(arg) | A(arg) | IMM(high_short >> 16)));
1011 else if (compiler->cache_arg != (SLJIT_MEM | arg) || high_short != compiler->cache_argw) {
1012 if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK)) {
1013 next_high_short = (sljit_si)(next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff;
1014 if (high_short == next_high_short) {
1015 compiler->cache_arg = SLJIT_MEM | arg;
1016 compiler->cache_argw = high_short;
1020 FAIL_IF(push_inst(compiler, ADDIS | D(tmp_r) | A(arg & REG_MASK) | IMM(high_short >> 16)));
1025 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r) | IMM(argw));
1027 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1030 /* Everything else is PPC-64 only. */
1031 if (SLJIT_UNLIKELY(!(arg & REG_MASK))) {
1032 diff = argw - compiler->cache_argw;
1033 if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
1034 ADJUST_CACHED_IMM(diff);
1035 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff));
1038 diff = argw - next_argw;
1039 if ((next_arg & SLJIT_MEM) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
1040 SLJIT_ASSERT(inp_flags & LOAD_DATA);
1042 compiler->cache_arg = SLJIT_IMM;
1043 compiler->cache_argw = argw;
1047 FAIL_IF(load_immediate(compiler, tmp_r, argw));
1048 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r));
1051 diff = argw - compiler->cache_argw;
1052 if (compiler->cache_arg == arg && diff <= SIMM_MAX && diff >= SIMM_MIN) {
1053 SLJIT_ASSERT(!(inp_flags & WRITE_BACK) && !(inst & UPDATE_REQ));
1054 ADJUST_CACHED_IMM(diff);
1055 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff));
1058 if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
1059 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
1060 SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
1061 if (compiler->cache_argw != argw) {
1062 FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | IMM(diff)));
1063 compiler->cache_argw = argw;
1065 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3));
1068 if (argw == next_argw && (next_arg & SLJIT_MEM)) {
1069 SLJIT_ASSERT(inp_flags & LOAD_DATA);
1070 FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
1072 compiler->cache_arg = SLJIT_IMM;
1073 compiler->cache_argw = argw;
1075 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
1076 SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
1077 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3));
1080 diff = argw - next_argw;
1081 if (arg == next_arg && !(inp_flags & WRITE_BACK) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
1082 SLJIT_ASSERT(inp_flags & LOAD_DATA);
1083 FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
1084 FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | A(TMP_REG3) | B(arg & REG_MASK)));
1086 compiler->cache_arg = arg;
1087 compiler->cache_argw = argw;
1089 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3));
1092 if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
1093 SLJIT_ASSERT(inp_flags & LOAD_DATA);
1094 FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
1096 compiler->cache_arg = SLJIT_IMM;
1097 compiler->cache_argw = argw;
1101 FAIL_IF(load_immediate(compiler, tmp_r, argw));
1103 /* Get the indexed version instead of the normal one. */
1104 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
1105 SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
1106 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r));
1110 static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w)
1112 if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
1113 return compiler->error;
1114 return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
1117 static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si input_flags,
1118 sljit_si dst, sljit_sw dstw,
1119 sljit_si src1, sljit_sw src1w,
1120 sljit_si src2, sljit_sw src2w)
1122 /* arg1 goes to TMP_REG1 or src reg
1123 arg2 goes to TMP_REG2, imm or src reg
1124 TMP_REG3 can be used for caching
1125 result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
1129 sljit_si sugg_src2_r = TMP_REG2;
1130 sljit_si flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS);
1132 if (!(input_flags & ALT_KEEP_CACHE)) {
1133 compiler->cache_arg = 0;
1134 compiler->cache_argw = 0;
1137 /* Destination check. */
1138 if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
1139 if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM))
1140 return SLJIT_SUCCESS;
1143 else if (FAST_IS_REG(dst)) {
1146 if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
1147 sugg_src2_r = dst_r;
1150 SLJIT_ASSERT(dst & SLJIT_MEM);
1151 if (getput_arg_fast(compiler, input_flags | ARG_TEST, TMP_REG2, dst, dstw)) {
1162 if (FAST_IS_REG(src1)) {
1164 flags |= REG1_SOURCE;
1166 else if (src1 & SLJIT_IMM) {
1167 FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
1170 else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w)) {
1171 FAIL_IF(compiler->error);
1178 if (FAST_IS_REG(src2)) {
1180 flags |= REG2_SOURCE;
1181 if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
1184 else if (src2 & SLJIT_IMM) {
1185 FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
1186 src2_r = sugg_src2_r;
1188 else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) {
1189 FAIL_IF(compiler->error);
1190 src2_r = sugg_src2_r;
1195 /* src1_r, src2_r and dst_r can be zero (=unprocessed).
1196 All arguments are complex addressing modes, and it is a binary operator. */
1197 if (src1_r == 0 && src2_r == 0 && dst_r == 0) {
1198 if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
1199 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
1200 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
1203 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
1204 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
1209 else if (src1_r == 0 && src2_r == 0) {
1210 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
1213 else if (src1_r == 0 && dst_r == 0) {
1214 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
1217 else if (src2_r == 0 && dst_r == 0) {
1218 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
1219 src2_r = sugg_src2_r;
1226 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0));
1231 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0));
1232 src2_r = sugg_src2_r;
1235 FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
1237 if (flags & (FAST_DEST | SLOW_DEST)) {
1238 if (flags & FAST_DEST)
1239 FAIL_IF(getput_arg_fast(compiler, input_flags, dst_r, dst, dstw));
1241 FAIL_IF(getput_arg(compiler, input_flags, dst_r, dst, dstw, 0, 0));
1243 return SLJIT_SUCCESS;
1246 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
1248 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1249 sljit_si int_op = op & SLJIT_INT_OP;
1253 CHECK(check_sljit_emit_op0(compiler, op));
1255 op = GET_OPCODE(op);
1257 case SLJIT_BREAKPOINT:
1259 return push_inst(compiler, NOP);
1262 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
1263 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1264 FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
1265 return push_inst(compiler, (op == SLJIT_LUMUL ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
1267 FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
1268 return push_inst(compiler, (op == SLJIT_LUMUL ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
1272 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
1273 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1274 FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_UDIVMOD ? DIVWU : DIVW) : (op == SLJIT_UDIVMOD ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
1275 FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
1277 FAIL_IF(push_inst(compiler, (op == SLJIT_UDIVMOD ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
1278 FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
1280 return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));
1283 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1284 return push_inst(compiler, (int_op ? (op == SLJIT_UDIVI ? DIVWU : DIVW) : (op == SLJIT_UDIVI ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
1286 return push_inst(compiler, (op == SLJIT_UDIVI ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
1290 return SLJIT_SUCCESS;
1293 #define EMIT_MOV(type, type_flags, type_cast) \
1294 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)
1296 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
1297 sljit_si dst, sljit_sw dstw,
1298 sljit_si src, sljit_sw srcw)
1300 sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0;
1301 sljit_si op_flags = GET_ALL_FLAGS(op);
1304 CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
1305 ADJUST_LOCAL_OFFSET(dst, dstw);
1306 ADJUST_LOCAL_OFFSET(src, srcw);
1308 op = GET_OPCODE(op);
1309 if ((src & SLJIT_IMM) && srcw == 0)
1312 if (op_flags & SLJIT_SET_O)
1313 FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
1315 if (op_flags & SLJIT_INT_OP) {
1316 if (op < SLJIT_NOT) {
1317 if (FAST_IS_REG(src) && src == dst) {
1318 if (!TYPE_CAST_NEEDED(op))
1319 return SLJIT_SUCCESS;
1321 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1322 if (op == SLJIT_MOV_SI && (src & SLJIT_MEM))
1324 if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM))
1326 if (op == SLJIT_MOV_UI && (src & SLJIT_IMM))
1328 if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM))
1332 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1334 /* Most operations expect sign extended arguments. */
1335 flags |= INT_DATA | SIGNED_DATA;
1336 if (src & SLJIT_IMM)
1337 srcw = (sljit_si)srcw;
1345 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1349 return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
1351 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1353 return EMIT_MOV(SLJIT_MOV_UI, INT_DATA, (sljit_ui));
1356 return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, (sljit_si));
1360 return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA, (sljit_ub));
1363 return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, (sljit_sb));
1366 return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA, (sljit_uh));
1369 return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, (sljit_sh));
1373 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1377 return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
1379 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1381 return EMIT_MOV(SLJIT_MOV_UI, INT_DATA | WRITE_BACK, (sljit_ui));
1384 return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_si));
1388 return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, (sljit_ub));
1391 return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sb));
1394 return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, (sljit_uh));
1397 return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sh));
1400 return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw);
1403 return emit_op(compiler, SLJIT_NEG, flags, dst, dstw, TMP_REG1, 0, src, srcw);
1406 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1407 return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_INT_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw);
1409 return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw);
1413 return SLJIT_SUCCESS;
1418 #define TEST_SL_IMM(src, srcw) \
1419 (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)
1421 #define TEST_UL_IMM(src, srcw) \
1422 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff))
1424 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1425 #define TEST_SH_IMM(src, srcw) \
1426 (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l)
1428 #define TEST_SH_IMM(src, srcw) \
1429 (((src) & SLJIT_IMM) && !((srcw) & 0xffff))
1432 #define TEST_UH_IMM(src, srcw) \
1433 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000))
1435 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1436 #define TEST_ADD_IMM(src, srcw) \
1437 (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l)
1439 #define TEST_ADD_IMM(src, srcw) \
1443 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1444 #define TEST_UI_IMM(src, srcw) \
1445 (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
1447 #define TEST_UI_IMM(src, srcw) \
1451 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
1452 sljit_si dst, sljit_sw dstw,
1453 sljit_si src1, sljit_sw src1w,
1454 sljit_si src2, sljit_sw src2w)
1456 sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0;
1459 CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
1460 ADJUST_LOCAL_OFFSET(dst, dstw);
1461 ADJUST_LOCAL_OFFSET(src1, src1w);
1462 ADJUST_LOCAL_OFFSET(src2, src2w);
1464 if ((src1 & SLJIT_IMM) && src1w == 0)
1466 if ((src2 & SLJIT_IMM) && src2w == 0)
1469 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1470 if (op & SLJIT_INT_OP) {
1471 /* Most operations expect sign extended arguments. */
1472 flags |= INT_DATA | SIGNED_DATA;
1473 if (src1 & SLJIT_IMM)
1474 src1w = (sljit_si)(src1w);
1475 if (src2 & SLJIT_IMM)
1476 src2w = (sljit_si)(src2w);
1478 flags |= ALT_SIGN_EXT;
1481 if (op & SLJIT_SET_O)
1482 FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
1483 if (src2 == TMP_REG2)
1484 flags |= ALT_KEEP_CACHE;
1486 switch (GET_OPCODE(op)) {
1488 if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
1489 if (TEST_SL_IMM(src2, src2w)) {
1490 compiler->imm = src2w & 0xffff;
1491 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1493 if (TEST_SL_IMM(src1, src1w)) {
1494 compiler->imm = src1w & 0xffff;
1495 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1497 if (TEST_SH_IMM(src2, src2w)) {
1498 compiler->imm = (src2w >> 16) & 0xffff;
1499 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1501 if (TEST_SH_IMM(src1, src1w)) {
1502 compiler->imm = (src1w >> 16) & 0xffff;
1503 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
1505 /* Range between -1 and -32768 is covered above. */
1506 if (TEST_ADD_IMM(src2, src2w)) {
1507 compiler->imm = src2w & 0xffffffff;
1508 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
1510 if (TEST_ADD_IMM(src1, src1w)) {
1511 compiler->imm = src1w & 0xffffffff;
1512 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);
1515 if (!(GET_FLAGS(op) & (SLJIT_SET_E | SLJIT_SET_O))) {
1516 if (TEST_SL_IMM(src2, src2w)) {
1517 compiler->imm = src2w & 0xffff;
1518 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1520 if (TEST_SL_IMM(src1, src1w)) {
1521 compiler->imm = src1w & 0xffff;
1522 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1525 return emit_op(compiler, SLJIT_ADD, flags, dst, dstw, src1, src1w, src2, src2w);
1528 return emit_op(compiler, SLJIT_ADDC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w);
1531 if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
1532 if (TEST_SL_IMM(src2, -src2w)) {
1533 compiler->imm = (-src2w) & 0xffff;
1534 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1536 if (TEST_SL_IMM(src1, src1w)) {
1537 compiler->imm = src1w & 0xffff;
1538 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1540 if (TEST_SH_IMM(src2, -src2w)) {
1541 compiler->imm = ((-src2w) >> 16) & 0xffff;
1542 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1544 /* Range between -1 and -32768 is covered above. */
1545 if (TEST_ADD_IMM(src2, -src2w)) {
1546 compiler->imm = -src2w & 0xffffffff;
1547 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
1550 if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S)) && !(op & (SLJIT_SET_O | SLJIT_SET_C))) {
1551 if (!(op & SLJIT_SET_U)) {
1552 /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
1553 if (TEST_SL_IMM(src2, src2w)) {
1554 compiler->imm = src2w & 0xffff;
1555 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1557 if (GET_FLAGS(op) == SLJIT_SET_E && TEST_SL_IMM(src1, src1w)) {
1558 compiler->imm = src1w & 0xffff;
1559 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
1562 if (!(op & (SLJIT_SET_E | SLJIT_SET_S))) {
1563 /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
1564 if (TEST_UL_IMM(src2, src2w)) {
1565 compiler->imm = src2w & 0xffff;
1566 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1568 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
1570 if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= 0x7fff) {
1571 compiler->imm = src2w;
1572 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1574 return emit_op(compiler, SLJIT_SUB, flags | ((op & SLJIT_SET_U) ? ALT_FORM4 : 0) | ((op & (SLJIT_SET_E | SLJIT_SET_S)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w);
1576 if (!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))) {
1577 if (TEST_SL_IMM(src2, -src2w)) {
1578 compiler->imm = (-src2w) & 0xffff;
1579 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1582 /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
1583 return emit_op(compiler, SLJIT_SUB, flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w);
1586 return emit_op(compiler, SLJIT_SUBC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w);
1589 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1590 if (op & SLJIT_INT_OP)
1593 if (!GET_FLAGS(op)) {
1594 if (TEST_SL_IMM(src2, src2w)) {
1595 compiler->imm = src2w & 0xffff;
1596 return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1598 if (TEST_SL_IMM(src1, src1w)) {
1599 compiler->imm = src1w & 0xffff;
1600 return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1603 return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w);
1608 /* Commutative unsigned operations. */
1609 if (!GET_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) {
1610 if (TEST_UL_IMM(src2, src2w)) {
1611 compiler->imm = src2w;
1612 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1614 if (TEST_UL_IMM(src1, src1w)) {
1615 compiler->imm = src1w;
1616 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1618 if (TEST_UH_IMM(src2, src2w)) {
1619 compiler->imm = (src2w >> 16) & 0xffff;
1620 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1622 if (TEST_UH_IMM(src1, src1w)) {
1623 compiler->imm = (src1w >> 16) & 0xffff;
1624 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
1627 if (!GET_FLAGS(op) && GET_OPCODE(op) != SLJIT_AND) {
1628 if (TEST_UI_IMM(src2, src2w)) {
1629 compiler->imm = src2w;
1630 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1632 if (TEST_UI_IMM(src1, src1w)) {
1633 compiler->imm = src1w;
1634 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1637 return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
1640 if (op & SLJIT_KEEP_FLAGS)
1645 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1646 if (op & SLJIT_INT_OP)
1649 if (src2 & SLJIT_IMM) {
1650 compiler->imm = src2w;
1651 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1653 return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
1656 return SLJIT_SUCCESS;
1659 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
1661 CHECK_REG_INDEX(check_sljit_get_register_index(reg));
1662 return reg_map[reg];
1665 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
1667 CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
1671 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
1672 void *instruction, sljit_si size)
1675 CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
1677 return push_inst(compiler, *(sljit_ins*)instruction);
1680 /* --------------------------------------------------------------------- */
1681 /* Floating point operators */
1682 /* --------------------------------------------------------------------- */
1684 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
1686 #ifdef SLJIT_IS_FPU_AVAILABLE
1687 return SLJIT_IS_FPU_AVAILABLE;
1689 /* Available by default. */
1694 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 6))
1695 #define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double)
1697 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1698 #define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw))
1700 #define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw))
1702 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
1703 #define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw))
1704 #define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw))
1706 #define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw))
1707 #define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw))
1710 #endif /* SLJIT_CONFIG_PPC_64 */
1712 static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
1713 sljit_si dst, sljit_sw dstw,
1714 sljit_si src, sljit_sw srcw)
1716 if (src & SLJIT_MEM) {
1717 /* We can ignore the temporary data store on the stack from caching point of view. */
1718 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
1722 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1723 op = GET_OPCODE(op);
1724 FAIL_IF(push_inst(compiler, (op == SLJIT_CONVI_FROMD ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src)));
1726 if (dst == SLJIT_UNUSED)
1727 return SLJIT_SUCCESS;
1729 if (op == SLJIT_CONVW_FROMD) {
1730 if (FAST_IS_REG(dst)) {
1731 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0));
1732 return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0);
1734 return emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
1738 FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src)));
1740 if (dst == SLJIT_UNUSED)
1741 return SLJIT_SUCCESS;
1744 if (FAST_IS_REG(dst)) {
1745 FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET));
1746 FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1)));
1747 return emit_op_mem2(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0);
1750 SLJIT_ASSERT(dst & SLJIT_MEM);
1752 if (dst & OFFS_REG_MASK) {
1755 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1756 FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(dst)) | A(TMP_REG1) | (dstw << 11) | ((31 - dstw) << 1)));
1758 FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(dst), dstw, 63 - dstw, 1)));
1763 dstw = OFFS_REG(dst);
1766 if ((dst & REG_MASK) && !dstw) {
1767 dstw = dst & REG_MASK;
1771 /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */
1772 FAIL_IF(load_immediate(compiler, TMP_REG1, dstw));
1777 return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw));
1780 static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
1781 sljit_si dst, sljit_sw dstw,
1782 sljit_si src, sljit_sw srcw)
1784 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1786 sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1788 if (src & SLJIT_IMM) {
1789 if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
1790 srcw = (sljit_si)srcw;
1791 FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
1794 else if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) {
1795 if (FAST_IS_REG(src))
1796 FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1)));
1798 FAIL_IF(emit_op_mem2(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
1802 if (FAST_IS_REG(src)) {
1803 FAIL_IF(emit_op_mem2(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
1804 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, dst, dstw));
1807 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
1809 FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
1811 if (dst & SLJIT_MEM)
1812 return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
1813 if (op & SLJIT_SINGLE_OP)
1814 return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
1815 return SLJIT_SUCCESS;
1819 sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1820 sljit_si invert_sign = 1;
1822 if (src & SLJIT_IMM) {
1823 FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000));
1827 else if (!FAST_IS_REG(src)) {
1828 FAIL_IF(emit_op_mem2(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW));
1832 /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31)))
1833 The double precision format has exactly 53 bit precision, so the lower 32 bit represents
1834 the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000
1835 to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating
1836 point value, we need to substract 2^53 + 2^31 from the constructed value. */
1837 FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
1839 FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000));
1840 FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
1841 FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI));
1842 FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000));
1843 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW));
1844 FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
1845 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW));
1847 FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
1849 if (dst & SLJIT_MEM)
1850 return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
1851 if (op & SLJIT_SINGLE_OP)
1852 return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
1853 return SLJIT_SUCCESS;
1858 static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
1859 sljit_si src1, sljit_sw src1w,
1860 sljit_si src2, sljit_sw src2w)
1862 if (src1 & SLJIT_MEM) {
1863 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
1867 if (src2 & SLJIT_MEM) {
1868 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
1872 return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2));
1875 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
1876 sljit_si dst, sljit_sw dstw,
1877 sljit_si src, sljit_sw srcw)
1882 compiler->cache_arg = 0;
1883 compiler->cache_argw = 0;
1885 SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error);
1886 SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
1888 if (GET_OPCODE(op) == SLJIT_CONVD_FROMS)
1889 op ^= SLJIT_SINGLE_OP;
1891 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1893 if (src & SLJIT_MEM) {
1894 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
1898 switch (GET_OPCODE(op)) {
1899 case SLJIT_CONVD_FROMS:
1900 op ^= SLJIT_SINGLE_OP;
1901 if (op & SLJIT_SINGLE_OP) {
1902 FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src)));
1908 if (dst_r != TMP_FREG1)
1909 FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src)));
1915 FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src)));
1918 FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src)));
1922 if (dst & SLJIT_MEM)
1923 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0));
1924 return SLJIT_SUCCESS;
1927 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
1928 sljit_si dst, sljit_sw dstw,
1929 sljit_si src1, sljit_sw src1w,
1930 sljit_si src2, sljit_sw src2w)
1932 sljit_si dst_r, flags = 0;
1935 CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
1936 ADJUST_LOCAL_OFFSET(dst, dstw);
1937 ADJUST_LOCAL_OFFSET(src1, src1w);
1938 ADJUST_LOCAL_OFFSET(src2, src2w);
1940 compiler->cache_arg = 0;
1941 compiler->cache_argw = 0;
1943 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
1945 if (src1 & SLJIT_MEM) {
1946 if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
1947 FAIL_IF(compiler->error);
1953 if (src2 & SLJIT_MEM) {
1954 if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
1955 FAIL_IF(compiler->error);
1961 if ((flags & (ALT_FORM1 | ALT_FORM2)) == (ALT_FORM1 | ALT_FORM2)) {
1962 if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
1963 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
1964 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
1967 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
1968 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
1971 else if (flags & ALT_FORM1)
1972 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
1973 else if (flags & ALT_FORM2)
1974 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
1976 if (flags & ALT_FORM1)
1978 if (flags & ALT_FORM2)
1981 switch (GET_OPCODE(op)) {
1983 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2)));
1987 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2)));
1991 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));
1995 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2)));
1999 if (dst_r == TMP_FREG2)
2000 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
2002 return SLJIT_SUCCESS;
2008 /* --------------------------------------------------------------------- */
2009 /* Other instructions */
2010 /* --------------------------------------------------------------------- */
2012 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
2015 CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
2016 ADJUST_LOCAL_OFFSET(dst, dstw);
2018 /* For UNUSED dst. Uncommon, but possible. */
2019 if (dst == SLJIT_UNUSED)
2020 return SLJIT_SUCCESS;
2022 if (FAST_IS_REG(dst))
2023 return push_inst(compiler, MFLR | D(dst));
2026 FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2)));
2027 return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
2030 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
2033 CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
2034 ADJUST_LOCAL_OFFSET(src, srcw);
2036 if (FAST_IS_REG(src))
2037 FAIL_IF(push_inst(compiler, MTLR | S(src)));
2039 if (src & SLJIT_MEM)
2040 FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
2041 else if (src & SLJIT_IMM)
2042 FAIL_IF(load_immediate(compiler, TMP_REG2, srcw));
2043 FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
2045 return push_inst(compiler, BLR);
2048 /* --------------------------------------------------------------------- */
2049 /* Conditional instructions */
2050 /* --------------------------------------------------------------------- */
2052 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
2054 struct sljit_label *label;
2057 CHECK_PTR(check_sljit_emit_label(compiler));
2059 if (compiler->last_label && compiler->last_label->size == compiler->size)
2060 return compiler->last_label;
2062 label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
2063 PTR_FAIL_IF(!label);
2064 set_label(label, compiler);
2068 static sljit_ins get_bo_bi_flags(sljit_si type)
2072 return (12 << 21) | (2 << 16);
2074 case SLJIT_NOT_EQUAL:
2075 return (4 << 21) | (2 << 16);
2079 return (12 << 21) | ((4 + 0) << 16);
2081 case SLJIT_GREATER_EQUAL:
2082 case SLJIT_D_GREATER_EQUAL:
2083 return (4 << 21) | ((4 + 0) << 16);
2086 case SLJIT_D_GREATER:
2087 return (12 << 21) | ((4 + 1) << 16);
2089 case SLJIT_LESS_EQUAL:
2090 case SLJIT_D_LESS_EQUAL:
2091 return (4 << 21) | ((4 + 1) << 16);
2093 case SLJIT_SIG_LESS:
2094 return (12 << 21) | (0 << 16);
2096 case SLJIT_SIG_GREATER_EQUAL:
2097 return (4 << 21) | (0 << 16);
2099 case SLJIT_SIG_GREATER:
2100 return (12 << 21) | (1 << 16);
2102 case SLJIT_SIG_LESS_EQUAL:
2103 return (4 << 21) | (1 << 16);
2105 case SLJIT_OVERFLOW:
2106 case SLJIT_MUL_OVERFLOW:
2107 return (12 << 21) | (3 << 16);
2109 case SLJIT_NOT_OVERFLOW:
2110 case SLJIT_MUL_NOT_OVERFLOW:
2111 return (4 << 21) | (3 << 16);
2114 return (12 << 21) | ((4 + 2) << 16);
2116 case SLJIT_D_NOT_EQUAL:
2117 return (4 << 21) | ((4 + 2) << 16);
2119 case SLJIT_D_UNORDERED:
2120 return (12 << 21) | ((4 + 3) << 16);
2122 case SLJIT_D_ORDERED:
2123 return (4 << 21) | ((4 + 3) << 16);
2126 SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
2131 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
2133 struct sljit_jump *jump;
2134 sljit_ins bo_bi_flags;
2137 CHECK_PTR(check_sljit_emit_jump(compiler, type));
2139 bo_bi_flags = get_bo_bi_flags(type & 0xff);
2143 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2145 set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
2148 /* In PPC, we don't need to touch the arguments. */
2149 if (type < SLJIT_JUMP)
2150 jump->flags |= IS_COND;
2151 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2152 if (type >= SLJIT_CALL0)
2153 jump->flags |= IS_CALL;
2156 PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
2157 PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG)));
2158 jump->addr = compiler->size;
2159 PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));
2163 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
2165 struct sljit_jump *jump = NULL;
2169 CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
2170 ADJUST_LOCAL_OFFSET(src, srcw);
2172 if (FAST_IS_REG(src)) {
2173 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2174 if (type >= SLJIT_CALL0) {
2175 FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
2176 src_r = TMP_CALL_REG;
2183 } else if (src & SLJIT_IMM) {
2184 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2186 set_jump(jump, compiler, JUMP_ADDR);
2187 jump->u.target = srcw;
2188 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2189 if (type >= SLJIT_CALL0)
2190 jump->flags |= IS_CALL;
2192 FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
2193 src_r = TMP_CALL_REG;
2196 FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
2197 src_r = TMP_CALL_REG;
2200 FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));
2202 jump->addr = compiler->size;
2203 return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0));
2206 /* Get a bit from CR, all other bits are zeroed. */
2207 #define GET_CR_BIT(bit, dst) \
2208 FAIL_IF(push_inst(compiler, MFCR | D(dst))); \
2209 FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | ((1 + (bit)) << 11) | (31 << 6) | (31 << 1)));
2211 #define INVERT_BIT(dst) \
2212 FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1));
2214 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
2215 sljit_si dst, sljit_sw dstw,
2216 sljit_si src, sljit_sw srcw,
2219 sljit_si reg, input_flags;
2220 sljit_si flags = GET_ALL_FLAGS(op);
2221 sljit_sw original_dstw = dstw;
2224 CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
2225 ADJUST_LOCAL_OFFSET(dst, dstw);
2227 if (dst == SLJIT_UNUSED)
2228 return SLJIT_SUCCESS;
2230 op = GET_OPCODE(op);
2231 reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
2233 compiler->cache_arg = 0;
2234 compiler->cache_argw = 0;
2235 if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
2236 ADJUST_LOCAL_OFFSET(src, srcw);
2237 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2238 input_flags = (flags & SLJIT_INT_OP) ? INT_DATA : WORD_DATA;
2240 input_flags = WORD_DATA;
2242 FAIL_IF(emit_op_mem2(compiler, input_flags | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
2247 switch (type & 0xff) {
2252 case SLJIT_NOT_EQUAL:
2259 GET_CR_BIT(4 + 0, reg);
2262 case SLJIT_GREATER_EQUAL:
2263 case SLJIT_D_GREATER_EQUAL:
2264 GET_CR_BIT(4 + 0, reg);
2269 case SLJIT_D_GREATER:
2270 GET_CR_BIT(4 + 1, reg);
2273 case SLJIT_LESS_EQUAL:
2274 case SLJIT_D_LESS_EQUAL:
2275 GET_CR_BIT(4 + 1, reg);
2279 case SLJIT_SIG_LESS:
2283 case SLJIT_SIG_GREATER_EQUAL:
2288 case SLJIT_SIG_GREATER:
2292 case SLJIT_SIG_LESS_EQUAL:
2297 case SLJIT_OVERFLOW:
2298 case SLJIT_MUL_OVERFLOW:
2302 case SLJIT_NOT_OVERFLOW:
2303 case SLJIT_MUL_NOT_OVERFLOW:
2309 GET_CR_BIT(4 + 2, reg);
2312 case SLJIT_D_NOT_EQUAL:
2313 GET_CR_BIT(4 + 2, reg);
2317 case SLJIT_D_UNORDERED:
2318 GET_CR_BIT(4 + 3, reg);
2321 case SLJIT_D_ORDERED:
2322 GET_CR_BIT(4 + 3, reg);
2327 SLJIT_ASSERT_STOP();
2331 if (op < SLJIT_ADD) {
2332 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2333 if (op == SLJIT_MOV)
2334 input_flags = WORD_DATA;
2337 input_flags = INT_DATA;
2341 input_flags = WORD_DATA;
2343 if (reg != TMP_REG2)
2344 return SLJIT_SUCCESS;
2345 return emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
2348 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2349 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2350 compiler->skip_checks = 1;
2352 return sljit_emit_op2(compiler, op | flags, dst, original_dstw, src, srcw, TMP_REG2, 0);
2355 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
2357 struct sljit_const *const_;
2361 CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
2362 ADJUST_LOCAL_OFFSET(dst, dstw);
2364 const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
2365 PTR_FAIL_IF(!const_);
2366 set_const(const_, compiler);
2368 reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
2370 PTR_FAIL_IF(emit_const(compiler, reg, init_value));
2372 if (dst & SLJIT_MEM)
2373 PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));