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