/[pcre]/code/trunk/sljit/sljitNativePPC_common.c
ViewVC logotype

Contents of /code/trunk/sljit/sljitNativePPC_common.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1709 - (show annotations)
Tue Aug 1 08:29:13 2017 UTC (2 years, 1 month ago) by zherczeg
File MIME type: text/plain
File size: 79105 byte(s)
Minor JIT compiler update.
1 /*
2 * Stack-less Just-In-Time compiler
3 *
4 * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modification, are
7 * permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice, this list of
10 * conditions and the following disclaimer.
11 *
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.
15 *
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.
25 */
26
27 SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
28 {
29 return "PowerPC" SLJIT_CPUINFO;
30 }
31
32 /* Length of an instruction word.
33 Both for ppc-32 and ppc-64. */
34 typedef sljit_u32 sljit_ins;
35
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
39 #endif
40
41 #ifdef _AIX
42 #include <sys/cache.h>
43 #endif
44
45 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
46 #define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1
47 #endif
48
49 #if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL)
50
51 static void ppc_cache_flush(sljit_ins *from, sljit_ins *to)
52 {
53 #ifdef _AIX
54 _sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from));
55 #elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
56 # if defined(_ARCH_PWR) || defined(_ARCH_PWR2)
57 /* Cache flush for POWER architecture. */
58 while (from < to) {
59 __asm__ volatile (
60 "clf 0, %0\n"
61 "dcs\n"
62 : : "r"(from)
63 );
64 from++;
65 }
66 __asm__ volatile ( "ics" );
67 # elif defined(_ARCH_COM) && !defined(_ARCH_PPC)
68 # error "Cache flush is not implemented for PowerPC/POWER common mode."
69 # else
70 /* Cache flush for PowerPC architecture. */
71 while (from < to) {
72 __asm__ volatile (
73 "dcbf 0, %0\n"
74 "sync\n"
75 "icbi 0, %0\n"
76 : : "r"(from)
77 );
78 from++;
79 }
80 __asm__ volatile ( "isync" );
81 # endif
82 # ifdef __xlc__
83 # warning "This file may fail to compile if -qfuncsect is used"
84 # endif
85 #elif defined(__xlc__)
86 #error "Please enable GCC syntax for inline assembly statements with -qasm=gcc"
87 #else
88 #error "This platform requires a cache flush implementation."
89 #endif /* _AIX */
90 }
91
92 #endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */
93
94 #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
95 #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
96 #define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
97 #define TMP_ZERO (SLJIT_NUMBER_OF_REGISTERS + 5)
98
99 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
100 #define TMP_CALL_REG (SLJIT_NUMBER_OF_REGISTERS + 6)
101 #else
102 #define TMP_CALL_REG TMP_REG2
103 #endif
104
105 #define TMP_FREG1 (0)
106 #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
107
108 static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {
109 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
110 };
111
112 /* --------------------------------------------------------------------- */
113 /* Instrucion forms */
114 /* --------------------------------------------------------------------- */
115 #define D(d) (reg_map[d] << 21)
116 #define S(s) (reg_map[s] << 21)
117 #define A(a) (reg_map[a] << 16)
118 #define B(b) (reg_map[b] << 11)
119 #define C(c) (reg_map[c] << 6)
120 #define FD(fd) ((fd) << 21)
121 #define FS(fs) ((fs) << 21)
122 #define FA(fa) ((fa) << 16)
123 #define FB(fb) ((fb) << 11)
124 #define FC(fc) ((fc) << 6)
125 #define IMM(imm) ((imm) & 0xffff)
126 #define CRD(d) ((d) << 21)
127
128 /* Instruction bit sections.
129 OE and Rc flag (see ALT_SET_FLAGS). */
130 #define OE(flags) ((flags) & ALT_SET_FLAGS)
131 /* Rc flag (see ALT_SET_FLAGS). */
132 #define RC(flags) (((flags) & ALT_SET_FLAGS) >> 10)
133 #define HI(opcode) ((opcode) << 26)
134 #define LO(opcode) ((opcode) << 1)
135
136 #define ADD (HI(31) | LO(266))
137 #define ADDC (HI(31) | LO(10))
138 #define ADDE (HI(31) | LO(138))
139 #define ADDI (HI(14))
140 #define ADDIC (HI(13))
141 #define ADDIS (HI(15))
142 #define ADDME (HI(31) | LO(234))
143 #define AND (HI(31) | LO(28))
144 #define ANDI (HI(28))
145 #define ANDIS (HI(29))
146 #define Bx (HI(18))
147 #define BCx (HI(16))
148 #define BCCTR (HI(19) | LO(528) | (3 << 11))
149 #define BLR (HI(19) | LO(16) | (0x14 << 21))
150 #define CNTLZD (HI(31) | LO(58))
151 #define CNTLZW (HI(31) | LO(26))
152 #define CMP (HI(31) | LO(0))
153 #define CMPI (HI(11))
154 #define CMPL (HI(31) | LO(32))
155 #define CMPLI (HI(10))
156 #define CROR (HI(19) | LO(449))
157 #define DCBT (HI(31) | LO(278))
158 #define DIVD (HI(31) | LO(489))
159 #define DIVDU (HI(31) | LO(457))
160 #define DIVW (HI(31) | LO(491))
161 #define DIVWU (HI(31) | LO(459))
162 #define EXTSB (HI(31) | LO(954))
163 #define EXTSH (HI(31) | LO(922))
164 #define EXTSW (HI(31) | LO(986))
165 #define FABS (HI(63) | LO(264))
166 #define FADD (HI(63) | LO(21))
167 #define FADDS (HI(59) | LO(21))
168 #define FCFID (HI(63) | LO(846))
169 #define FCMPU (HI(63) | LO(0))
170 #define FCTIDZ (HI(63) | LO(815))
171 #define FCTIWZ (HI(63) | LO(15))
172 #define FDIV (HI(63) | LO(18))
173 #define FDIVS (HI(59) | LO(18))
174 #define FMR (HI(63) | LO(72))
175 #define FMUL (HI(63) | LO(25))
176 #define FMULS (HI(59) | LO(25))
177 #define FNEG (HI(63) | LO(40))
178 #define FRSP (HI(63) | LO(12))
179 #define FSUB (HI(63) | LO(20))
180 #define FSUBS (HI(59) | LO(20))
181 #define LD (HI(58) | 0)
182 #define LWZ (HI(32))
183 #define MFCR (HI(31) | LO(19))
184 #define MFLR (HI(31) | LO(339) | 0x80000)
185 #define MFXER (HI(31) | LO(339) | 0x10000)
186 #define MTCTR (HI(31) | LO(467) | 0x90000)
187 #define MTLR (HI(31) | LO(467) | 0x80000)
188 #define MTXER (HI(31) | LO(467) | 0x10000)
189 #define MULHD (HI(31) | LO(73))
190 #define MULHDU (HI(31) | LO(9))
191 #define MULHW (HI(31) | LO(75))
192 #define MULHWU (HI(31) | LO(11))
193 #define MULLD (HI(31) | LO(233))
194 #define MULLI (HI(7))
195 #define MULLW (HI(31) | LO(235))
196 #define NEG (HI(31) | LO(104))
197 #define NOP (HI(24))
198 #define NOR (HI(31) | LO(124))
199 #define OR (HI(31) | LO(444))
200 #define ORI (HI(24))
201 #define ORIS (HI(25))
202 #define RLDICL (HI(30))
203 #define RLWINM (HI(21))
204 #define SLD (HI(31) | LO(27))
205 #define SLW (HI(31) | LO(24))
206 #define SRAD (HI(31) | LO(794))
207 #define SRADI (HI(31) | LO(413 << 1))
208 #define SRAW (HI(31) | LO(792))
209 #define SRAWI (HI(31) | LO(824))
210 #define SRD (HI(31) | LO(539))
211 #define SRW (HI(31) | LO(536))
212 #define STD (HI(62) | 0)
213 #define STDU (HI(62) | 1)
214 #define STDUX (HI(31) | LO(181))
215 #define STFIWX (HI(31) | LO(983))
216 #define STW (HI(36))
217 #define STWU (HI(37))
218 #define STWUX (HI(31) | LO(183))
219 #define SUBF (HI(31) | LO(40))
220 #define SUBFC (HI(31) | LO(8))
221 #define SUBFE (HI(31) | LO(136))
222 #define SUBFIC (HI(8))
223 #define XOR (HI(31) | LO(316))
224 #define XORI (HI(26))
225 #define XORIS (HI(27))
226
227 #define SIMM_MAX (0x7fff)
228 #define SIMM_MIN (-0x8000)
229 #define UIMM_MAX (0xffff)
230
231 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
232 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func)
233 {
234 sljit_sw* ptrs;
235 if (func_ptr)
236 *func_ptr = (void*)context;
237 ptrs = (sljit_sw*)func;
238 context->addr = addr ? addr : ptrs[0];
239 context->r2 = ptrs[1];
240 context->r11 = ptrs[2];
241 }
242 #endif
243
244 static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
245 {
246 sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
247 FAIL_IF(!ptr);
248 *ptr = ins;
249 compiler->size++;
250 return SLJIT_SUCCESS;
251 }
252
253 static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
254 {
255 sljit_sw diff;
256 sljit_uw target_addr;
257 sljit_sw extra_jump_flags;
258
259 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
260 if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))
261 return 0;
262 #else
263 if (jump->flags & SLJIT_REWRITABLE_JUMP)
264 return 0;
265 #endif
266
267 if (jump->flags & JUMP_ADDR)
268 target_addr = jump->u.target;
269 else {
270 SLJIT_ASSERT(jump->flags & JUMP_LABEL);
271 target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
272 }
273
274 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
275 if (jump->flags & IS_CALL)
276 goto keep_address;
277 #endif
278
279 diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr) - executable_offset) & ~0x3l;
280
281 extra_jump_flags = 0;
282 if (jump->flags & IS_COND) {
283 if (diff <= 0x7fff && diff >= -0x8000) {
284 jump->flags |= PATCH_B;
285 return 1;
286 }
287 if (target_addr <= 0xffff) {
288 jump->flags |= PATCH_B | PATCH_ABS_B;
289 return 1;
290 }
291 extra_jump_flags = REMOVE_COND;
292
293 diff -= sizeof(sljit_ins);
294 }
295
296 if (diff <= 0x01ffffff && diff >= -0x02000000) {
297 jump->flags |= PATCH_B | extra_jump_flags;
298 return 1;
299 }
300
301 if (target_addr <= 0x03ffffff) {
302 jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags;
303 return 1;
304 }
305
306 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
307 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
308 keep_address:
309 #endif
310 if (target_addr <= 0x7fffffff) {
311 jump->flags |= PATCH_ABS32;
312 return 1;
313 }
314
315 if (target_addr <= 0x7fffffffffffl) {
316 jump->flags |= PATCH_ABS48;
317 return 1;
318 }
319 #endif
320
321 return 0;
322 }
323
324 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
325 {
326 struct sljit_memory_fragment *buf;
327 sljit_ins *code;
328 sljit_ins *code_ptr;
329 sljit_ins *buf_ptr;
330 sljit_ins *buf_end;
331 sljit_uw word_count;
332 sljit_sw executable_offset;
333 sljit_uw addr;
334
335 struct sljit_label *label;
336 struct sljit_jump *jump;
337 struct sljit_const *const_;
338
339 CHECK_ERROR_PTR();
340 CHECK_PTR(check_sljit_generate_code(compiler));
341 reverse_buf(compiler);
342
343 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
344 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
345 compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
346 #else
347 compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
348 #endif
349 #endif
350 code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
351 PTR_FAIL_WITH_EXEC_IF(code);
352 buf = compiler->buf;
353
354 code_ptr = code;
355 word_count = 0;
356 executable_offset = SLJIT_EXEC_OFFSET(code);
357
358 label = compiler->labels;
359 jump = compiler->jumps;
360 const_ = compiler->consts;
361
362 do {
363 buf_ptr = (sljit_ins*)buf->memory;
364 buf_end = buf_ptr + (buf->used_size >> 2);
365 do {
366 *code_ptr = *buf_ptr++;
367 SLJIT_ASSERT(!label || label->size >= word_count);
368 SLJIT_ASSERT(!jump || jump->addr >= word_count);
369 SLJIT_ASSERT(!const_ || const_->addr >= word_count);
370 /* These structures are ordered by their address. */
371 if (label && label->size == word_count) {
372 /* Just recording the address. */
373 label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
374 label->size = code_ptr - code;
375 label = label->next;
376 }
377 if (jump && jump->addr == word_count) {
378 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
379 jump->addr = (sljit_uw)(code_ptr - 3);
380 #else
381 jump->addr = (sljit_uw)(code_ptr - 6);
382 #endif
383 if (detect_jump_type(jump, code_ptr, code, executable_offset)) {
384 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
385 code_ptr[-3] = code_ptr[0];
386 code_ptr -= 3;
387 #else
388 if (jump->flags & PATCH_ABS32) {
389 code_ptr -= 3;
390 code_ptr[-1] = code_ptr[2];
391 code_ptr[0] = code_ptr[3];
392 }
393 else if (jump->flags & PATCH_ABS48) {
394 code_ptr--;
395 code_ptr[-1] = code_ptr[0];
396 code_ptr[0] = code_ptr[1];
397 /* rldicr rX,rX,32,31 -> rX,rX,16,47 */
398 SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6);
399 code_ptr[-3] ^= 0x8422;
400 /* oris -> ori */
401 code_ptr[-2] ^= 0x4000000;
402 }
403 else {
404 code_ptr[-6] = code_ptr[0];
405 code_ptr -= 6;
406 }
407 #endif
408 if (jump->flags & REMOVE_COND) {
409 code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001);
410 code_ptr++;
411 jump->addr += sizeof(sljit_ins);
412 code_ptr[0] = Bx;
413 jump->flags -= IS_COND;
414 }
415 }
416 jump = jump->next;
417 }
418 if (const_ && const_->addr == word_count) {
419 const_->addr = (sljit_uw)code_ptr;
420 const_ = const_->next;
421 }
422 code_ptr ++;
423 word_count ++;
424 } while (buf_ptr < buf_end);
425
426 buf = buf->next;
427 } while (buf);
428
429 if (label && label->size == word_count) {
430 label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
431 label->size = code_ptr - code;
432 label = label->next;
433 }
434
435 SLJIT_ASSERT(!label);
436 SLJIT_ASSERT(!jump);
437 SLJIT_ASSERT(!const_);
438 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
439 SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins)));
440 #else
441 SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
442 #endif
443
444 jump = compiler->jumps;
445 while (jump) {
446 do {
447 addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
448 buf_ptr = (sljit_ins *)jump->addr;
449
450 if (jump->flags & PATCH_B) {
451 if (jump->flags & IS_COND) {
452 if (!(jump->flags & PATCH_ABS_B)) {
453 addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
454 SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000);
455 *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001);
456 }
457 else {
458 SLJIT_ASSERT(addr <= 0xffff);
459 *buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001);
460 }
461 }
462 else {
463 if (!(jump->flags & PATCH_ABS_B)) {
464 addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
465 SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000);
466 *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1);
467 }
468 else {
469 SLJIT_ASSERT(addr <= 0x03ffffff);
470 *buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1);
471 }
472 }
473 break;
474 }
475
476 /* Set the fields of immediate loads. */
477 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
478 buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
479 buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
480 #else
481 if (jump->flags & PATCH_ABS32) {
482 SLJIT_ASSERT(addr <= 0x7fffffff);
483 buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
484 buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
485 break;
486 }
487 if (jump->flags & PATCH_ABS48) {
488 SLJIT_ASSERT(addr <= 0x7fffffffffff);
489 buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff);
490 buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff);
491 buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff);
492 break;
493 }
494 buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff);
495 buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff);
496 buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff);
497 buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff);
498 #endif
499 } while (0);
500 jump = jump->next;
501 }
502
503 compiler->error = SLJIT_ERR_COMPILED;
504 compiler->executable_offset = executable_offset;
505 compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
506
507 code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
508
509 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
510 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
511 if (((sljit_sw)code_ptr) & 0x4)
512 code_ptr++;
513 #endif
514 sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code);
515 #endif
516
517 code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
518
519 SLJIT_CACHE_FLUSH(code, code_ptr);
520
521 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
522 return code_ptr;
523 #else
524 return code;
525 #endif
526 }
527
528 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
529 {
530 switch (feature_type) {
531 case SLJIT_HAS_FPU:
532 #ifdef SLJIT_IS_FPU_AVAILABLE
533 return SLJIT_IS_FPU_AVAILABLE;
534 #else
535 /* Available by default. */
536 return 1;
537 #endif
538
539 case SLJIT_HAS_PRE_UPDATE:
540 case SLJIT_HAS_CLZ:
541 return 1;
542
543 default:
544 return 0;
545 }
546 }
547
548 /* --------------------------------------------------------------------- */
549 /* Entry, exit */
550 /* --------------------------------------------------------------------- */
551
552 /* inp_flags: */
553
554 /* Creates an index in data_transfer_insts array. */
555 #define LOAD_DATA 0x01
556 #define INDEXED 0x02
557 #define WRITE_BACK 0x04
558 #define WORD_DATA 0x00
559 #define BYTE_DATA 0x08
560 #define HALF_DATA 0x10
561 #define INT_DATA 0x18
562 #define SIGNED_DATA 0x20
563 /* Separates integer and floating point registers */
564 #define GPR_REG 0x3f
565 #define DOUBLE_DATA 0x40
566
567 #define MEM_MASK 0x7f
568
569 /* Other inp_flags. */
570
571 #define ARG_TEST 0x000100
572 /* Integer opertion and set flags -> requires exts on 64 bit systems. */
573 #define ALT_SIGN_EXT 0x000200
574 /* This flag affects the RC() and OERC() macros. */
575 #define ALT_SET_FLAGS 0x000400
576 #define ALT_KEEP_CACHE 0x000800
577 #define ALT_FORM1 0x010000
578 #define ALT_FORM2 0x020000
579 #define ALT_FORM3 0x040000
580 #define ALT_FORM4 0x080000
581 #define ALT_FORM5 0x100000
582
583 /* Source and destination is register. */
584 #define REG_DEST 0x000001
585 #define REG1_SOURCE 0x000002
586 #define REG2_SOURCE 0x000004
587 /* getput_arg_fast returned true. */
588 #define FAST_DEST 0x000008
589 /* Multiple instructions are required. */
590 #define SLOW_DEST 0x000010
591 /*
592 ALT_SIGN_EXT 0x000200
593 ALT_SET_FLAGS 0x000400
594 ALT_FORM1 0x010000
595 ...
596 ALT_FORM5 0x100000 */
597
598 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
599 #include "sljitNativePPC_32.c"
600 #else
601 #include "sljitNativePPC_64.c"
602 #endif
603
604 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
605 #define STACK_STORE STW
606 #define STACK_LOAD LWZ
607 #else
608 #define STACK_STORE STD
609 #define STACK_LOAD LD
610 #endif
611
612 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
613 sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
614 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
615 {
616 sljit_s32 i, tmp, offs;
617
618 CHECK_ERROR();
619 CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
620 set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
621
622 FAIL_IF(push_inst(compiler, MFLR | D(0)));
623 offs = -(sljit_s32)(sizeof(sljit_sw));
624 FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
625
626 tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
627 for (i = SLJIT_S0; i >= tmp; i--) {
628 offs -= (sljit_s32)(sizeof(sljit_sw));
629 FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
630 }
631
632 for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
633 offs -= (sljit_s32)(sizeof(sljit_sw));
634 FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
635 }
636
637 SLJIT_ASSERT(offs == -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1));
638
639 #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
640 FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
641 #else
642 FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
643 #endif
644
645 FAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0));
646 if (args >= 1)
647 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(SLJIT_S0) | B(SLJIT_R0)));
648 if (args >= 2)
649 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R1) | A(SLJIT_S1) | B(SLJIT_R1)));
650 if (args >= 3)
651 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R2) | A(SLJIT_S2) | B(SLJIT_R2)));
652
653 local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
654 local_size = (local_size + 15) & ~0xf;
655 compiler->local_size = local_size;
656
657 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
658 if (local_size <= SIMM_MAX)
659 FAIL_IF(push_inst(compiler, STWU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
660 else {
661 FAIL_IF(load_immediate(compiler, 0, -local_size));
662 FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
663 }
664 #else
665 if (local_size <= SIMM_MAX)
666 FAIL_IF(push_inst(compiler, STDU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
667 else {
668 FAIL_IF(load_immediate(compiler, 0, -local_size));
669 FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
670 }
671 #endif
672
673 return SLJIT_SUCCESS;
674 }
675
676 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
677 sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
678 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
679 {
680 CHECK_ERROR();
681 CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
682 set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
683
684 local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
685 compiler->local_size = (local_size + 15) & ~0xf;
686 return SLJIT_SUCCESS;
687 }
688
689 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
690 {
691 sljit_s32 i, tmp, offs;
692
693 CHECK_ERROR();
694 CHECK(check_sljit_emit_return(compiler, op, src, srcw));
695
696 FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
697
698 if (compiler->local_size <= SIMM_MAX)
699 FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_SP) | A(SLJIT_SP) | IMM(compiler->local_size)));
700 else {
701 FAIL_IF(load_immediate(compiler, 0, compiler->local_size));
702 FAIL_IF(push_inst(compiler, ADD | D(SLJIT_SP) | A(SLJIT_SP) | B(0)));
703 }
704
705 #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
706 FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
707 #else
708 FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
709 #endif
710
711 offs = -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1);
712
713 tmp = compiler->scratches;
714 for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
715 FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
716 offs += (sljit_s32)(sizeof(sljit_sw));
717 }
718
719 tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
720 for (i = tmp; i <= SLJIT_S0; i++) {
721 FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
722 offs += (sljit_s32)(sizeof(sljit_sw));
723 }
724
725 FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
726 SLJIT_ASSERT(offs == -(sljit_sw)(sizeof(sljit_sw)));
727
728 FAIL_IF(push_inst(compiler, MTLR | S(0)));
729 FAIL_IF(push_inst(compiler, BLR));
730
731 return SLJIT_SUCCESS;
732 }
733
734 #undef STACK_STORE
735 #undef STACK_LOAD
736
737 /* --------------------------------------------------------------------- */
738 /* Operators */
739 /* --------------------------------------------------------------------- */
740
741 /* i/x - immediate/indexed form
742 n/w - no write-back / write-back (1 bit)
743 s/l - store/load (1 bit)
744 u/s - signed/unsigned (1 bit)
745 w/b/h/i - word/byte/half/int allowed (2 bit)
746 It contans 32 items, but not all are different. */
747
748 /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
749 #define INT_ALIGNED 0x10000
750 /* 64-bit only: there is no lwau instruction. */
751 #define UPDATE_REQ 0x20000
752
753 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
754 #define ARCH_32_64(a, b) a
755 #define INST_CODE_AND_DST(inst, flags, reg) \
756 ((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
757 #else
758 #define ARCH_32_64(a, b) b
759 #define INST_CODE_AND_DST(inst, flags, reg) \
760 (((inst) & ~(INT_ALIGNED | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
761 #endif
762
763 static const sljit_ins data_transfer_insts[64 + 16] = {
764
765 /* -------- Unsigned -------- */
766
767 /* Word. */
768
769 /* u w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
770 /* u w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
771 /* u w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
772 /* u w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
773
774 /* u w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
775 /* u w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
776 /* u w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
777 /* u w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
778
779 /* Byte. */
780
781 /* u b n i s */ HI(38) /* stb */,
782 /* u b n i l */ HI(34) /* lbz */,
783 /* u b n x s */ HI(31) | LO(215) /* stbx */,
784 /* u b n x l */ HI(31) | LO(87) /* lbzx */,
785
786 /* u b w i s */ HI(39) /* stbu */,
787 /* u b w i l */ HI(35) /* lbzu */,
788 /* u b w x s */ HI(31) | LO(247) /* stbux */,
789 /* u b w x l */ HI(31) | LO(119) /* lbzux */,
790
791 /* Half. */
792
793 /* u h n i s */ HI(44) /* sth */,
794 /* u h n i l */ HI(40) /* lhz */,
795 /* u h n x s */ HI(31) | LO(407) /* sthx */,
796 /* u h n x l */ HI(31) | LO(279) /* lhzx */,
797
798 /* u h w i s */ HI(45) /* sthu */,
799 /* u h w i l */ HI(41) /* lhzu */,
800 /* u h w x s */ HI(31) | LO(439) /* sthux */,
801 /* u h w x l */ HI(31) | LO(311) /* lhzux */,
802
803 /* Int. */
804
805 /* u i n i s */ HI(36) /* stw */,
806 /* u i n i l */ HI(32) /* lwz */,
807 /* u i n x s */ HI(31) | LO(151) /* stwx */,
808 /* u i n x l */ HI(31) | LO(23) /* lwzx */,
809
810 /* u i w i s */ HI(37) /* stwu */,
811 /* u i w i l */ HI(33) /* lwzu */,
812 /* u i w x s */ HI(31) | LO(183) /* stwux */,
813 /* u i w x l */ HI(31) | LO(55) /* lwzux */,
814
815 /* -------- Signed -------- */
816
817 /* Word. */
818
819 /* s w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
820 /* s w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
821 /* s w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
822 /* s w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
823
824 /* s w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
825 /* s w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
826 /* s w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
827 /* s w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
828
829 /* Byte. */
830
831 /* s b n i s */ HI(38) /* stb */,
832 /* s b n i l */ HI(34) /* lbz */ /* EXTS_REQ */,
833 /* s b n x s */ HI(31) | LO(215) /* stbx */,
834 /* s b n x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
835
836 /* s b w i s */ HI(39) /* stbu */,
837 /* s b w i l */ HI(35) /* lbzu */ /* EXTS_REQ */,
838 /* s b w x s */ HI(31) | LO(247) /* stbux */,
839 /* s b w x l */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */,
840
841 /* Half. */
842
843 /* s h n i s */ HI(44) /* sth */,
844 /* s h n i l */ HI(42) /* lha */,
845 /* s h n x s */ HI(31) | LO(407) /* sthx */,
846 /* s h n x l */ HI(31) | LO(343) /* lhax */,
847
848 /* s h w i s */ HI(45) /* sthu */,
849 /* s h w i l */ HI(43) /* lhau */,
850 /* s h w x s */ HI(31) | LO(439) /* sthux */,
851 /* s h w x l */ HI(31) | LO(375) /* lhaux */,
852
853 /* Int. */
854
855 /* s i n i s */ HI(36) /* stw */,
856 /* s i n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */),
857 /* s i n x s */ HI(31) | LO(151) /* stwx */,
858 /* s i n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
859
860 /* s i w i s */ HI(37) /* stwu */,
861 /* s i w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | UPDATE_REQ | 0x2 /* lwa */),
862 /* s i w x s */ HI(31) | LO(183) /* stwux */,
863 /* s i w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
864
865 /* -------- Double -------- */
866
867 /* d n i s */ HI(54) /* stfd */,
868 /* d n i l */ HI(50) /* lfd */,
869 /* d n x s */ HI(31) | LO(727) /* stfdx */,
870 /* d n x l */ HI(31) | LO(599) /* lfdx */,
871
872 /* d w i s */ HI(55) /* stfdu */,
873 /* d w i l */ HI(51) /* lfdu */,
874 /* d w x s */ HI(31) | LO(759) /* stfdux */,
875 /* d w x l */ HI(31) | LO(631) /* lfdux */,
876
877 /* s n i s */ HI(52) /* stfs */,
878 /* s n i l */ HI(48) /* lfs */,
879 /* s n x s */ HI(31) | LO(663) /* stfsx */,
880 /* s n x l */ HI(31) | LO(535) /* lfsx */,
881
882 /* s w i s */ HI(53) /* stfsu */,
883 /* s w i l */ HI(49) /* lfsu */,
884 /* s w x s */ HI(31) | LO(695) /* stfsux */,
885 /* s w x l */ HI(31) | LO(567) /* lfsux */,
886 };
887
888 #undef ARCH_32_64
889
890 /* Simple cases, (no caching is required). */
891 static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
892 {
893 sljit_ins inst;
894
895 /* Should work when (arg & REG_MASK) == 0. */
896 SLJIT_ASSERT(A(0) == 0);
897 SLJIT_ASSERT(arg & SLJIT_MEM);
898
899 if (arg & OFFS_REG_MASK) {
900 if (argw & 0x3)
901 return 0;
902 if (inp_flags & ARG_TEST)
903 return 1;
904
905 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
906 SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
907 FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(OFFS_REG(arg))));
908 return -1;
909 }
910
911 if (SLJIT_UNLIKELY(!(arg & REG_MASK)))
912 inp_flags &= ~WRITE_BACK;
913
914 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
915 inst = data_transfer_insts[inp_flags & MEM_MASK];
916 SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ));
917
918 if (argw > SIMM_MAX || argw < SIMM_MIN || ((inst & INT_ALIGNED) && (argw & 0x3)) || (inst & UPDATE_REQ))
919 return 0;
920 if (inp_flags & ARG_TEST)
921 return 1;
922 #endif
923
924 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
925 if (argw > SIMM_MAX || argw < SIMM_MIN)
926 return 0;
927 if (inp_flags & ARG_TEST)
928 return 1;
929
930 inst = data_transfer_insts[inp_flags & MEM_MASK];
931 SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
932 #endif
933
934 FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | IMM(argw)));
935 return -1;
936 }
937
938 /* See getput_arg below.
939 Note: can_cache is called only for binary operators. Those operator always
940 uses word arguments without write back. */
941 static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
942 {
943 sljit_sw high_short, next_high_short;
944 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
945 sljit_sw diff;
946 #endif
947
948 SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
949
950 if (arg & OFFS_REG_MASK)
951 return ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && (argw & 0x3) == (next_argw & 0x3));
952
953 if (next_arg & OFFS_REG_MASK)
954 return 0;
955
956 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
957 high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff;
958 next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff;
959 return high_short == next_high_short;
960 #else
961 if (argw <= 0x7fffffffl && argw >= -0x80000000l) {
962 high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff;
963 next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff;
964 if (high_short == next_high_short)
965 return 1;
966 }
967
968 diff = argw - next_argw;
969 if (!(arg & REG_MASK))
970 return diff <= SIMM_MAX && diff >= SIMM_MIN;
971
972 if (arg == next_arg && diff <= SIMM_MAX && diff >= SIMM_MIN)
973 return 1;
974
975 return 0;
976 #endif
977 }
978
979 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
980 #define ADJUST_CACHED_IMM(imm) \
981 if ((inst & INT_ALIGNED) && (imm & 0x3)) { \
982 /* Adjust cached value. Fortunately this is really a rare case */ \
983 compiler->cache_argw += imm & 0x3; \
984 FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | (imm & 0x3))); \
985 imm &= ~0x3; \
986 }
987 #endif
988
989 /* Emit the necessary instructions. See can_cache above. */
990 static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
991 {
992 sljit_s32 tmp_r;
993 sljit_ins inst;
994 sljit_sw high_short, next_high_short;
995 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
996 sljit_sw diff;
997 #endif
998
999 SLJIT_ASSERT(arg & SLJIT_MEM);
1000
1001 tmp_r = ((inp_flags & LOAD_DATA) && ((inp_flags) & MEM_MASK) <= GPR_REG) ? reg : TMP_REG1;
1002 /* Special case for "mov reg, [reg, ... ]". */
1003 if ((arg & REG_MASK) == tmp_r)
1004 tmp_r = TMP_REG1;
1005
1006 if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
1007 argw &= 0x3;
1008 /* Otherwise getput_arg_fast would capture it. */
1009 SLJIT_ASSERT(argw);
1010
1011 if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg && argw == compiler->cache_argw)
1012 tmp_r = TMP_REG3;
1013 else {
1014 if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) {
1015 compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
1016 compiler->cache_argw = argw;
1017 tmp_r = TMP_REG3;
1018 }
1019 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1020 FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(arg)) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1)));
1021 #else
1022 FAIL_IF(push_inst(compiler, RLDI(tmp_r, OFFS_REG(arg), argw, 63 - argw, 1)));
1023 #endif
1024 }
1025 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
1026 SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
1027 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r));
1028 }
1029
1030 if (SLJIT_UNLIKELY(!(arg & REG_MASK)))
1031 inp_flags &= ~WRITE_BACK;
1032
1033 inst = data_transfer_insts[inp_flags & MEM_MASK];
1034 SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ));
1035
1036 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1037 if (argw <= 0x7fff7fffl && argw >= -0x80000000l
1038 && (!(inst & INT_ALIGNED) || !(argw & 0x3)) && !(inst & UPDATE_REQ)) {
1039 #endif
1040
1041 arg &= REG_MASK;
1042 high_short = (sljit_s32)(argw + ((argw & 0x8000) << 1)) & ~0xffff;
1043 /* The getput_arg_fast should handle this otherwise. */
1044 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1045 SLJIT_ASSERT(high_short && high_short <= 0x7fffffffl && high_short >= -0x80000000l);
1046 #else
1047 SLJIT_ASSERT(high_short && !(inst & (INT_ALIGNED | UPDATE_REQ)));
1048 #endif
1049
1050 if (inp_flags & WRITE_BACK) {
1051 tmp_r = arg;
1052 FAIL_IF(push_inst(compiler, ADDIS | D(arg) | A(arg) | IMM(high_short >> 16)));
1053 }
1054 else if (compiler->cache_arg != (SLJIT_MEM | arg) || high_short != compiler->cache_argw) {
1055 if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK)) {
1056 next_high_short = (sljit_s32)(next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff;
1057 if (high_short == next_high_short) {
1058 compiler->cache_arg = SLJIT_MEM | arg;
1059 compiler->cache_argw = high_short;
1060 tmp_r = TMP_REG3;
1061 }
1062 }
1063 FAIL_IF(push_inst(compiler, ADDIS | D(tmp_r) | A(arg & REG_MASK) | IMM(high_short >> 16)));
1064 }
1065 else
1066 tmp_r = TMP_REG3;
1067
1068 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r) | IMM(argw));
1069
1070 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1071 }
1072
1073 /* Everything else is PPC-64 only. */
1074 if (SLJIT_UNLIKELY(!(arg & REG_MASK))) {
1075 diff = argw - compiler->cache_argw;
1076 if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
1077 ADJUST_CACHED_IMM(diff);
1078 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff));
1079 }
1080
1081 diff = argw - next_argw;
1082 if ((next_arg & SLJIT_MEM) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
1083 SLJIT_ASSERT(inp_flags & LOAD_DATA);
1084
1085 compiler->cache_arg = SLJIT_IMM;
1086 compiler->cache_argw = argw;
1087 tmp_r = TMP_REG3;
1088 }
1089
1090 FAIL_IF(load_immediate(compiler, tmp_r, argw));
1091 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r));
1092 }
1093
1094 diff = argw - compiler->cache_argw;
1095 if (compiler->cache_arg == arg && diff <= SIMM_MAX && diff >= SIMM_MIN) {
1096 SLJIT_ASSERT(!(inp_flags & WRITE_BACK) && !(inst & UPDATE_REQ));
1097 ADJUST_CACHED_IMM(diff);
1098 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff));
1099 }
1100
1101 if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
1102 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
1103 SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
1104 if (compiler->cache_argw != argw) {
1105 FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | IMM(diff)));
1106 compiler->cache_argw = argw;
1107 }
1108 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3));
1109 }
1110
1111 if (argw == next_argw && (next_arg & SLJIT_MEM)) {
1112 SLJIT_ASSERT(inp_flags & LOAD_DATA);
1113 FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
1114
1115 compiler->cache_arg = SLJIT_IMM;
1116 compiler->cache_argw = argw;
1117
1118 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
1119 SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
1120 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3));
1121 }
1122
1123 diff = argw - next_argw;
1124 if (arg == next_arg && !(inp_flags & WRITE_BACK) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
1125 SLJIT_ASSERT(inp_flags & LOAD_DATA);
1126 FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
1127 FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | A(TMP_REG3) | B(arg & REG_MASK)));
1128
1129 compiler->cache_arg = arg;
1130 compiler->cache_argw = argw;
1131
1132 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3));
1133 }
1134
1135 if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
1136 SLJIT_ASSERT(inp_flags & LOAD_DATA);
1137 FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
1138
1139 compiler->cache_arg = SLJIT_IMM;
1140 compiler->cache_argw = argw;
1141 tmp_r = TMP_REG3;
1142 }
1143 else
1144 FAIL_IF(load_immediate(compiler, tmp_r, argw));
1145
1146 /* Get the indexed version instead of the normal one. */
1147 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
1148 SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
1149 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r));
1150 #endif
1151 }
1152
1153 static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
1154 {
1155 if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
1156 return compiler->error;
1157 return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
1158 }
1159
1160 static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 input_flags,
1161 sljit_s32 dst, sljit_sw dstw,
1162 sljit_s32 src1, sljit_sw src1w,
1163 sljit_s32 src2, sljit_sw src2w)
1164 {
1165 /* arg1 goes to TMP_REG1 or src reg
1166 arg2 goes to TMP_REG2, imm or src reg
1167 TMP_REG3 can be used for caching
1168 result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
1169 sljit_s32 dst_r;
1170 sljit_s32 src1_r;
1171 sljit_s32 src2_r;
1172 sljit_s32 sugg_src2_r = TMP_REG2;
1173 sljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_SIGN_EXT | ALT_SET_FLAGS);
1174
1175 if (!(input_flags & ALT_KEEP_CACHE)) {
1176 compiler->cache_arg = 0;
1177 compiler->cache_argw = 0;
1178 }
1179
1180 /* Destination check. */
1181 if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
1182 dst_r = TMP_REG2;
1183 }
1184 else if (FAST_IS_REG(dst)) {
1185 dst_r = dst;
1186 flags |= REG_DEST;
1187 if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
1188 sugg_src2_r = dst_r;
1189 }
1190 else {
1191 SLJIT_ASSERT(dst & SLJIT_MEM);
1192 if (getput_arg_fast(compiler, input_flags | ARG_TEST, TMP_REG2, dst, dstw)) {
1193 flags |= FAST_DEST;
1194 dst_r = TMP_REG2;
1195 }
1196 else {
1197 flags |= SLOW_DEST;
1198 dst_r = 0;
1199 }
1200 }
1201
1202 /* Source 1. */
1203 if (FAST_IS_REG(src1)) {
1204 src1_r = src1;
1205 flags |= REG1_SOURCE;
1206 }
1207 else if (src1 & SLJIT_IMM) {
1208 FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
1209 src1_r = TMP_REG1;
1210 }
1211 else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w)) {
1212 FAIL_IF(compiler->error);
1213 src1_r = TMP_REG1;
1214 }
1215 else
1216 src1_r = 0;
1217
1218 /* Source 2. */
1219 if (FAST_IS_REG(src2)) {
1220 src2_r = src2;
1221 flags |= REG2_SOURCE;
1222 if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
1223 dst_r = src2_r;
1224 }
1225 else if (src2 & SLJIT_IMM) {
1226 FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
1227 src2_r = sugg_src2_r;
1228 }
1229 else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) {
1230 FAIL_IF(compiler->error);
1231 src2_r = sugg_src2_r;
1232 }
1233 else
1234 src2_r = 0;
1235
1236 /* src1_r, src2_r and dst_r can be zero (=unprocessed).
1237 All arguments are complex addressing modes, and it is a binary operator. */
1238 if (src1_r == 0 && src2_r == 0 && dst_r == 0) {
1239 if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
1240 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
1241 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
1242 }
1243 else {
1244 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
1245 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
1246 }
1247 src1_r = TMP_REG1;
1248 src2_r = TMP_REG2;
1249 }
1250 else if (src1_r == 0 && src2_r == 0) {
1251 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
1252 src1_r = TMP_REG1;
1253 }
1254 else if (src1_r == 0 && dst_r == 0) {
1255 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
1256 src1_r = TMP_REG1;
1257 }
1258 else if (src2_r == 0 && dst_r == 0) {
1259 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
1260 src2_r = sugg_src2_r;
1261 }
1262
1263 if (dst_r == 0)
1264 dst_r = TMP_REG2;
1265
1266 if (src1_r == 0) {
1267 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0));
1268 src1_r = TMP_REG1;
1269 }
1270
1271 if (src2_r == 0) {
1272 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0));
1273 src2_r = sugg_src2_r;
1274 }
1275
1276 FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
1277
1278 if (flags & (FAST_DEST | SLOW_DEST)) {
1279 if (flags & FAST_DEST)
1280 FAIL_IF(getput_arg_fast(compiler, input_flags, dst_r, dst, dstw));
1281 else
1282 FAIL_IF(getput_arg(compiler, input_flags, dst_r, dst, dstw, 0, 0));
1283 }
1284 return SLJIT_SUCCESS;
1285 }
1286
1287 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
1288 {
1289 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1290 sljit_s32 int_op = op & SLJIT_I32_OP;
1291 #endif
1292
1293 CHECK_ERROR();
1294 CHECK(check_sljit_emit_op0(compiler, op));
1295
1296 op = GET_OPCODE(op);
1297 switch (op) {
1298 case SLJIT_BREAKPOINT:
1299 case SLJIT_NOP:
1300 return push_inst(compiler, NOP);
1301 case SLJIT_LMUL_UW:
1302 case SLJIT_LMUL_SW:
1303 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
1304 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1305 FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
1306 return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
1307 #else
1308 FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
1309 return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
1310 #endif
1311 case SLJIT_DIVMOD_UW:
1312 case SLJIT_DIVMOD_SW:
1313 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
1314 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1315 FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) : (op == SLJIT_DIVMOD_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
1316 FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
1317 #else
1318 FAIL_IF(push_inst(compiler, (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
1319 FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
1320 #endif
1321 return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));
1322 case SLJIT_DIV_UW:
1323 case SLJIT_DIV_SW:
1324 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1325 return push_inst(compiler, (int_op ? (op == SLJIT_DIV_UW ? DIVWU : DIVW) : (op == SLJIT_DIV_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
1326 #else
1327 return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
1328 #endif
1329 }
1330
1331 return SLJIT_SUCCESS;
1332 }
1333
1334 static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
1335 sljit_s32 src, sljit_sw srcw)
1336 {
1337 if (!(src & OFFS_REG_MASK)) {
1338 if (srcw == 0 && (src & REG_MASK) != SLJIT_UNUSED)
1339 return push_inst(compiler, DCBT | A(0) | B(src & REG_MASK));
1340
1341 FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
1342 /* Works with SLJIT_MEM0() case as well. */
1343 return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));
1344 }
1345
1346 srcw &= 0x3;
1347
1348 if (srcw == 0)
1349 return push_inst(compiler, DCBT | A(src & REG_MASK) | B(OFFS_REG(src)));
1350
1351 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1352 FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(src)) | A(TMP_REG1) | (srcw << 11) | ((31 - srcw) << 1)));
1353 #else
1354 FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(src), srcw, 63 - srcw, 1)));
1355 #endif
1356 return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));
1357 }
1358
1359 #define EMIT_MOV(type, type_flags, type_cast) \
1360 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)
1361
1362 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
1363 sljit_s32 dst, sljit_sw dstw,
1364 sljit_s32 src, sljit_sw srcw)
1365 {
1366 sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;
1367 sljit_s32 op_flags = GET_ALL_FLAGS(op);
1368
1369 CHECK_ERROR();
1370 CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
1371 ADJUST_LOCAL_OFFSET(dst, dstw);
1372 ADJUST_LOCAL_OFFSET(src, srcw);
1373
1374 if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
1375 if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
1376 return emit_prefetch(compiler, src, srcw);
1377
1378 return SLJIT_SUCCESS;
1379 }
1380
1381 op = GET_OPCODE(op);
1382 if ((src & SLJIT_IMM) && srcw == 0)
1383 src = TMP_ZERO;
1384
1385 if (GET_FLAG_TYPE(op_flags) == SLJIT_OVERFLOW)
1386 FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
1387
1388 if (op_flags & SLJIT_I32_OP) {
1389 if (op < SLJIT_NOT) {
1390 if (FAST_IS_REG(src) && src == dst) {
1391 if (!TYPE_CAST_NEEDED(op))
1392 return SLJIT_SUCCESS;
1393 }
1394 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1395 if (op == SLJIT_MOV_S32 && (src & SLJIT_MEM))
1396 op = SLJIT_MOV_U32;
1397 if (op == SLJIT_MOVU_S32 && (src & SLJIT_MEM))
1398 op = SLJIT_MOVU_U32;
1399 if (op == SLJIT_MOV_U32 && (src & SLJIT_IMM))
1400 op = SLJIT_MOV_S32;
1401 if (op == SLJIT_MOVU_U32 && (src & SLJIT_IMM))
1402 op = SLJIT_MOVU_S32;
1403 #endif
1404 }
1405 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1406 else {
1407 /* Most operations expect sign extended arguments. */
1408 flags |= INT_DATA | SIGNED_DATA;
1409 if (src & SLJIT_IMM)
1410 srcw = (sljit_s32)srcw;
1411 if (HAS_FLAGS(op_flags))
1412 flags |= ALT_SIGN_EXT;
1413 }
1414 #endif
1415 }
1416
1417 switch (op) {
1418 case SLJIT_MOV:
1419 case SLJIT_MOV_P:
1420 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1421 case SLJIT_MOV_U32:
1422 case SLJIT_MOV_S32:
1423 #endif
1424 return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
1425
1426 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1427 case SLJIT_MOV_U32:
1428 return EMIT_MOV(SLJIT_MOV_U32, INT_DATA, (sljit_u32));
1429
1430 case SLJIT_MOV_S32:
1431 return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, (sljit_s32));
1432 #endif
1433
1434 case SLJIT_MOV_U8:
1435 return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA, (sljit_u8));
1436
1437 case SLJIT_MOV_S8:
1438 return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, (sljit_s8));
1439
1440 case SLJIT_MOV_U16:
1441 return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA, (sljit_u16));
1442
1443 case SLJIT_MOV_S16:
1444 return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (sljit_s16));
1445
1446 case SLJIT_MOVU:
1447 case SLJIT_MOVU_P:
1448 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1449 case SLJIT_MOVU_U32:
1450 case SLJIT_MOVU_S32:
1451 #endif
1452 return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
1453
1454 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1455 case SLJIT_MOVU_U32:
1456 return EMIT_MOV(SLJIT_MOV_U32, INT_DATA | WRITE_BACK, (sljit_u32));
1457
1458 case SLJIT_MOVU_S32:
1459 return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s32));
1460 #endif
1461
1462 case SLJIT_MOVU_U8:
1463 return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, (sljit_u8));
1464
1465 case SLJIT_MOVU_S8:
1466 return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s8));
1467
1468 case SLJIT_MOVU_U16:
1469 return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, (sljit_u16));
1470
1471 case SLJIT_MOVU_S16:
1472 return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s16));
1473
1474 case SLJIT_NOT:
1475 return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw);
1476
1477 case SLJIT_NEG:
1478 return emit_op(compiler, SLJIT_NEG, flags | (GET_FLAG_TYPE(op_flags) ? ALT_FORM1 : 0), dst, dstw, TMP_REG1, 0, src, srcw);
1479
1480 case SLJIT_CLZ:
1481 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1482 return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_I32_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw);
1483 #else
1484 return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw);
1485 #endif
1486 }
1487
1488 return SLJIT_SUCCESS;
1489 }
1490
1491 #undef EMIT_MOV
1492
1493 #define TEST_SL_IMM(src, srcw) \
1494 (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)
1495
1496 #define TEST_UL_IMM(src, srcw) \
1497 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff))
1498
1499 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1500 #define TEST_SH_IMM(src, srcw) \
1501 (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l)
1502 #else
1503 #define TEST_SH_IMM(src, srcw) \
1504 (((src) & SLJIT_IMM) && !((srcw) & 0xffff))
1505 #endif
1506
1507 #define TEST_UH_IMM(src, srcw) \
1508 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000))
1509
1510 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1511 #define TEST_ADD_IMM(src, srcw) \
1512 (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l)
1513 #else
1514 #define TEST_ADD_IMM(src, srcw) \
1515 ((src) & SLJIT_IMM)
1516 #endif
1517
1518 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1519 #define TEST_UI_IMM(src, srcw) \
1520 (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
1521 #else
1522 #define TEST_UI_IMM(src, srcw) \
1523 ((src) & SLJIT_IMM)
1524 #endif
1525
1526 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
1527 sljit_s32 dst, sljit_sw dstw,
1528 sljit_s32 src1, sljit_sw src1w,
1529 sljit_s32 src2, sljit_sw src2w)
1530 {
1531 sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;
1532
1533 CHECK_ERROR();
1534 CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
1535 ADJUST_LOCAL_OFFSET(dst, dstw);
1536 ADJUST_LOCAL_OFFSET(src1, src1w);
1537 ADJUST_LOCAL_OFFSET(src2, src2w);
1538
1539 if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
1540 return SLJIT_SUCCESS;
1541
1542 if ((src1 & SLJIT_IMM) && src1w == 0)
1543 src1 = TMP_ZERO;
1544 if ((src2 & SLJIT_IMM) && src2w == 0)
1545 src2 = TMP_ZERO;
1546
1547 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1548 if (op & SLJIT_I32_OP) {
1549 /* Most operations expect sign extended arguments. */
1550 flags |= INT_DATA | SIGNED_DATA;
1551 if (src1 & SLJIT_IMM)
1552 src1w = (sljit_s32)(src1w);
1553 if (src2 & SLJIT_IMM)
1554 src2w = (sljit_s32)(src2w);
1555 if (HAS_FLAGS(op))
1556 flags |= ALT_SIGN_EXT;
1557 }
1558 #endif
1559 if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1560 FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
1561 if (src2 == TMP_REG2)
1562 flags |= ALT_KEEP_CACHE;
1563
1564 switch (GET_OPCODE(op)) {
1565 case SLJIT_ADD:
1566 if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1567 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);
1568
1569 if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
1570 if (TEST_SL_IMM(src2, src2w)) {
1571 compiler->imm = src2w & 0xffff;
1572 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1573 }
1574 if (TEST_SL_IMM(src1, src1w)) {
1575 compiler->imm = src1w & 0xffff;
1576 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
1577 }
1578 if (TEST_SH_IMM(src2, src2w)) {
1579 compiler->imm = (src2w >> 16) & 0xffff;
1580 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1581 }
1582 if (TEST_SH_IMM(src1, src1w)) {
1583 compiler->imm = (src1w >> 16) & 0xffff;
1584 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1585 }
1586 /* Range between -1 and -32768 is covered above. */
1587 if (TEST_ADD_IMM(src2, src2w)) {
1588 compiler->imm = src2w & 0xffffffff;
1589 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
1590 }
1591 if (TEST_ADD_IMM(src1, src1w)) {
1592 compiler->imm = src1w & 0xffffffff;
1593 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);
1594 }
1595 }
1596 if (HAS_FLAGS(op)) {
1597 if (TEST_SL_IMM(src2, src2w)) {
1598 compiler->imm = src2w & 0xffff;
1599 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1600 }
1601 if (TEST_SL_IMM(src1, src1w)) {
1602 compiler->imm = src1w & 0xffff;
1603 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1604 }
1605 }
1606 return emit_op(compiler, SLJIT_ADD, flags | ((GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)) ? ALT_FORM4 : 0), dst, dstw, src1, src1w, src2, src2w);
1607
1608 case SLJIT_ADDC:
1609 return emit_op(compiler, SLJIT_ADDC, flags, dst, dstw, src1, src1w, src2, src2w);
1610
1611 case SLJIT_SUB:
1612 if (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_LESS_EQUAL) {
1613 if (dst == SLJIT_UNUSED) {
1614 if (TEST_UL_IMM(src2, src2w)) {
1615 compiler->imm = src2w & 0xffff;
1616 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1617 }
1618 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);
1619 }
1620
1621 if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= (SIMM_MAX + 1)) {
1622 compiler->imm = src2w;
1623 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1624 }
1625 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM3, dst, dstw, src1, src1w, src2, src2w);
1626 }
1627
1628 if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1629 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, src2, src2w);
1630
1631 if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
1632 if (TEST_SL_IMM(src2, -src2w)) {
1633 compiler->imm = (-src2w) & 0xffff;
1634 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1635 }
1636 if (TEST_SL_IMM(src1, src1w)) {
1637 compiler->imm = src1w & 0xffff;
1638 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1639 }
1640 if (TEST_SH_IMM(src2, -src2w)) {
1641 compiler->imm = ((-src2w) >> 16) & 0xffff;
1642 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1643 }
1644 /* Range between -1 and -32768 is covered above. */
1645 if (TEST_ADD_IMM(src2, -src2w)) {
1646 compiler->imm = -src2w & 0xffffffff;
1647 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
1648 }
1649 }
1650
1651 if (dst == SLJIT_UNUSED && GET_FLAG_TYPE(op) != GET_FLAG_TYPE(SLJIT_SET_CARRY)) {
1652 if (TEST_SL_IMM(src2, src2w)) {
1653 compiler->imm = src2w & 0xffff;
1654 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4 | ALT_FORM5, dst, dstw, src1, src1w, TMP_REG2, 0);
1655 }
1656 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
1657 }
1658
1659 if (TEST_SL_IMM(src2, -src2w)) {
1660 compiler->imm = (-src2w) & 0xffff;
1661 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1662 }
1663 /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */
1664 return emit_op(compiler, SLJIT_SUB, flags | ((GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w);
1665
1666 case SLJIT_SUBC:
1667 return emit_op(compiler, SLJIT_SUBC, flags, dst, dstw, src1, src1w, src2, src2w);
1668
1669 case SLJIT_MUL:
1670 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1671 if (op & SLJIT_I32_OP)
1672 flags |= ALT_FORM2;
1673 #endif
1674 if (!HAS_FLAGS(op)) {
1675 if (TEST_SL_IMM(src2, src2w)) {
1676 compiler->imm = src2w & 0xffff;
1677 return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1678 }
1679 if (TEST_SL_IMM(src1, src1w)) {
1680 compiler->imm = src1w & 0xffff;
1681 return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1682 }
1683 }
1684 else
1685 FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
1686 return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w);
1687
1688 case SLJIT_AND:
1689 case SLJIT_OR:
1690 case SLJIT_XOR:
1691 /* Commutative unsigned operations. */
1692 if (!HAS_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) {
1693 if (TEST_UL_IMM(src2, src2w)) {
1694 compiler->imm = src2w;
1695 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1696 }
1697 if (TEST_UL_IMM(src1, src1w)) {
1698 compiler->imm = src1w;
1699 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1700 }
1701 if (TEST_UH_IMM(src2, src2w)) {
1702 compiler->imm = (src2w >> 16) & 0xffff;
1703 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1704 }
1705 if (TEST_UH_IMM(src1, src1w)) {
1706 compiler->imm = (src1w >> 16) & 0xffff;
1707 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
1708 }
1709 }
1710 if (GET_OPCODE(op) != SLJIT_AND && GET_OPCODE(op) != SLJIT_AND) {
1711 /* Unlike or and xor, and resets unwanted bits as well. */
1712 if (TEST_UI_IMM(src2, src2w)) {
1713 compiler->imm = src2w;
1714 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1715 }
1716 if (TEST_UI_IMM(src1, src1w)) {
1717 compiler->imm = src1w;
1718 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1719 }
1720 }
1721 return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
1722
1723 case SLJIT_SHL:
1724 case SLJIT_LSHR:
1725 case SLJIT_ASHR:
1726 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1727 if (op & SLJIT_I32_OP)
1728 flags |= ALT_FORM2;
1729 #endif
1730 if (src2 & SLJIT_IMM) {
1731 compiler->imm = src2w;
1732 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1733 }
1734 return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
1735 }
1736
1737 return SLJIT_SUCCESS;
1738 }
1739
1740 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
1741 {
1742 CHECK_REG_INDEX(check_sljit_get_register_index(reg));
1743 return reg_map[reg];
1744 }
1745
1746 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
1747 {
1748 CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
1749 return reg;
1750 }
1751
1752 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
1753 void *instruction, sljit_s32 size)
1754 {
1755 CHECK_ERROR();
1756 CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
1757
1758 return push_inst(compiler, *(sljit_ins*)instruction);
1759 }
1760
1761 /* --------------------------------------------------------------------- */
1762 /* Floating point operators */
1763 /* --------------------------------------------------------------------- */
1764
1765 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 5))
1766 #define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)
1767
1768 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1769 #define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw))
1770 #else
1771 #define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw))
1772
1773 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
1774 #define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw))
1775 #define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw))
1776 #else
1777 #define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw))
1778 #define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw))
1779 #endif
1780
1781 #endif /* SLJIT_CONFIG_PPC_64 */
1782
1783 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
1784 sljit_s32 dst, sljit_sw dstw,
1785 sljit_s32 src, sljit_sw srcw)
1786 {
1787 if (src & SLJIT_MEM) {
1788 /* We can ignore the temporary data store on the stack from caching point of view. */
1789 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
1790 src = TMP_FREG1;
1791 }
1792
1793 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1794 op = GET_OPCODE(op);
1795 FAIL_IF(push_inst(compiler, (op == SLJIT_CONV_S32_FROM_F64 ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src)));
1796
1797 if (op == SLJIT_CONV_SW_FROM_F64) {
1798 if (FAST_IS_REG(dst)) {
1799 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0));
1800 return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0);
1801 }
1802 return emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
1803 }
1804 #else
1805 FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src)));
1806 #endif
1807
1808 if (FAST_IS_REG(dst)) {
1809 FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET));
1810 FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1)));
1811 return emit_op_mem2(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0);
1812 }
1813
1814 SLJIT_ASSERT(dst & SLJIT_MEM);
1815
1816 if (dst & OFFS_REG_MASK) {
1817 dstw &= 0x3;
1818 if (dstw) {
1819 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1820 FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(dst)) | A(TMP_REG1) | (dstw << 11) | ((31 - dstw) << 1)));
1821 #else
1822 FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(dst), dstw, 63 - dstw, 1)));
1823 #endif
1824 dstw = TMP_REG1;
1825 }
1826 else
1827 dstw = OFFS_REG(dst);
1828 }
1829 else {
1830 if ((dst & REG_MASK) && !dstw) {
1831 dstw = dst & REG_MASK;
1832 dst = 0;
1833 }
1834 else {
1835 /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */
1836 FAIL_IF(load_immediate(compiler, TMP_REG1, dstw));
1837 dstw = TMP_REG1;
1838 }
1839 }
1840
1841 return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw));
1842 }
1843
1844 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
1845 sljit_s32 dst, sljit_sw dstw,
1846 sljit_s32 src, sljit_sw srcw)
1847 {
1848 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1849
1850 sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1851
1852 if (src & SLJIT_IMM) {
1853 if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
1854 srcw = (sljit_s32)srcw;
1855 FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
1856 src = TMP_REG1;
1857 }
1858 else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) {
1859 if (FAST_IS_REG(src))
1860 FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1)));
1861 else
1862 FAIL_IF(emit_op_mem2(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
1863 src = TMP_REG1;
1864 }
1865
1866 if (FAST_IS_REG(src)) {
1867 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));
1868 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, dst, dstw));
1869 }
1870 else
1871 FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
1872
1873 FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
1874
1875 if (dst & SLJIT_MEM)
1876 return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
1877 if (op & SLJIT_F32_OP)
1878 return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
1879 return SLJIT_SUCCESS;
1880
1881 #else
1882
1883 sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1884 sljit_s32 invert_sign = 1;
1885
1886 if (src & SLJIT_IMM) {
1887 FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000));
1888 src = TMP_REG1;
1889 invert_sign = 0;
1890 }
1891 else if (!FAST_IS_REG(src)) {
1892 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));
1893 src = TMP_REG1;
1894 }
1895
1896 /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31)))
1897 The double precision format has exactly 53 bit precision, so the lower 32 bit represents
1898 the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000
1899 to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating
1900 point value, we need to substract 2^53 + 2^31 from the constructed value. */
1901 FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
1902 if (invert_sign)
1903 FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000));
1904 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));
1905 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));
1906 FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000));
1907 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));
1908 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));
1909 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));
1910
1911 FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
1912
1913 if (dst & SLJIT_MEM)
1914 return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
1915 if (op & SLJIT_F32_OP)
1916 return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
1917 return SLJIT_SUCCESS;
1918
1919 #endif
1920 }
1921
1922 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
1923 sljit_s32 src1, sljit_sw src1w,
1924 sljit_s32 src2, sljit_sw src2w)
1925 {
1926 if (src1 & SLJIT_MEM) {
1927 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
1928 src1 = TMP_FREG1;
1929 }
1930
1931 if (src2 & SLJIT_MEM) {
1932 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
1933 src2 = TMP_FREG2;
1934 }
1935
1936 return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2));
1937 }
1938
1939 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
1940 sljit_s32 dst, sljit_sw dstw,
1941 sljit_s32 src, sljit_sw srcw)
1942 {
1943 sljit_s32 dst_r;
1944
1945 CHECK_ERROR();
1946 compiler->cache_arg = 0;
1947 compiler->cache_argw = 0;
1948
1949 SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error);
1950 SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
1951
1952 if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
1953 op ^= SLJIT_F32_OP;
1954
1955 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1956
1957 if (src & SLJIT_MEM) {
1958 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
1959 src = dst_r;
1960 }
1961
1962 switch (GET_OPCODE(op)) {
1963 case SLJIT_CONV_F64_FROM_F32:
1964 op ^= SLJIT_F32_OP;
1965 if (op & SLJIT_F32_OP) {
1966 FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src)));
1967 break;
1968 }
1969 /* Fall through. */
1970 case SLJIT_MOV_F64:
1971 if (src != dst_r) {
1972 if (dst_r != TMP_FREG1)
1973 FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src)));
1974 else
1975 dst_r = src;
1976 }
1977 break;
1978 case SLJIT_NEG_F64:
1979 FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src)));
1980 break;
1981 case SLJIT_ABS_F64:
1982 FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src)));
1983 break;
1984 }
1985
1986 if (dst & SLJIT_MEM)
1987 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0));
1988 return SLJIT_SUCCESS;
1989 }
1990
1991 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
1992 sljit_s32 dst, sljit_sw dstw,
1993 sljit_s32 src1, sljit_sw src1w,
1994 sljit_s32 src2, sljit_sw src2w)
1995 {
1996 sljit_s32 dst_r, flags = 0;
1997
1998 CHECK_ERROR();
1999 CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
2000 ADJUST_LOCAL_OFFSET(dst, dstw);
2001 ADJUST_LOCAL_OFFSET(src1, src1w);
2002 ADJUST_LOCAL_OFFSET(src2, src2w);
2003
2004 compiler->cache_arg = 0;
2005 compiler->cache_argw = 0;
2006
2007 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
2008
2009 if (src1 & SLJIT_MEM) {
2010 if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
2011 FAIL_IF(compiler->error);
2012 src1 = TMP_FREG1;
2013 } else
2014 flags |= ALT_FORM1;
2015 }
2016
2017 if (src2 & SLJIT_MEM) {
2018 if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
2019 FAIL_IF(compiler->error);
2020 src2 = TMP_FREG2;
2021 } else
2022 flags |= ALT_FORM2;
2023 }
2024
2025 if ((flags & (ALT_FORM1 | ALT_FORM2)) == (ALT_FORM1 | ALT_FORM2)) {
2026 if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
2027 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
2028 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
2029 }
2030 else {
2031 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
2032 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
2033 }
2034 }
2035 else if (flags & ALT_FORM1)
2036 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
2037 else if (flags & ALT_FORM2)
2038 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
2039
2040 if (flags & ALT_FORM1)
2041 src1 = TMP_FREG1;
2042 if (flags & ALT_FORM2)
2043 src2 = TMP_FREG2;
2044
2045 switch (GET_OPCODE(op)) {
2046 case SLJIT_ADD_F64:
2047 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2)));
2048 break;
2049
2050 case SLJIT_SUB_F64:
2051 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2)));
2052 break;
2053
2054 case SLJIT_MUL_F64:
2055 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));
2056 break;
2057
2058 case SLJIT_DIV_F64:
2059 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2)));
2060 break;
2061 }
2062
2063 if (dst_r == TMP_FREG2)
2064 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
2065
2066 return SLJIT_SUCCESS;
2067 }
2068
2069 #undef FLOAT_DATA
2070 #undef SELECT_FOP
2071
2072 /* --------------------------------------------------------------------- */
2073 /* Other instructions */
2074 /* --------------------------------------------------------------------- */
2075
2076 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
2077 {
2078 CHECK_ERROR();
2079 CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
2080 ADJUST_LOCAL_OFFSET(dst, dstw);
2081
2082 if (FAST_IS_REG(dst))
2083 return push_inst(compiler, MFLR | D(dst));
2084
2085 /* Memory. */
2086 FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2)));
2087 return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
2088 }
2089
2090 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
2091 {
2092 CHECK_ERROR();
2093 CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
2094 ADJUST_LOCAL_OFFSET(src, srcw);
2095
2096 if (FAST_IS_REG(src))
2097 FAIL_IF(push_inst(compiler, MTLR | S(src)));
2098 else {
2099 if (src & SLJIT_MEM)
2100 FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
2101 else if (src & SLJIT_IMM)
2102 FAIL_IF(load_immediate(compiler, TMP_REG2, srcw));
2103 FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
2104 }
2105 return push_inst(compiler, BLR);
2106 }
2107
2108 /* --------------------------------------------------------------------- */
2109 /* Conditional instructions */
2110 /* --------------------------------------------------------------------- */
2111
2112 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
2113 {
2114 struct sljit_label *label;
2115
2116 CHECK_ERROR_PTR();
2117 CHECK_PTR(check_sljit_emit_label(compiler));
2118
2119 if (compiler->last_label && compiler->last_label->size == compiler->size)
2120 return compiler->last_label;
2121
2122 label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
2123 PTR_FAIL_IF(!label);
2124 set_label(label, compiler);
2125 return label;
2126 }
2127
2128 static sljit_ins get_bo_bi_flags(sljit_s32 type)
2129 {
2130 switch (type) {
2131 case SLJIT_EQUAL:
2132 return (12 << 21) | (2 << 16);
2133
2134 case SLJIT_NOT_EQUAL:
2135 return (4 << 21) | (2 << 16);
2136
2137 case SLJIT_LESS:
2138 case SLJIT_SIG_LESS:
2139 return (12 << 21) | (0 << 16);
2140
2141 case SLJIT_GREATER_EQUAL:
2142 case SLJIT_SIG_GREATER_EQUAL:
2143 return (4 << 21) | (0 << 16);
2144
2145 case SLJIT_GREATER:
2146 case SLJIT_SIG_GREATER:
2147 return (12 << 21) | (1 << 16);
2148
2149 case SLJIT_LESS_EQUAL:
2150 case SLJIT_SIG_LESS_EQUAL:
2151 return (4 << 21) | (1 << 16);
2152
2153 case SLJIT_LESS_F64:
2154 return (12 << 21) | ((4 + 0) << 16);
2155
2156 case SLJIT_GREATER_EQUAL_F64:
2157 return (4 << 21) | ((4 + 0) << 16);
2158
2159 case SLJIT_GREATER_F64:
2160 return (12 << 21) | ((4 + 1) << 16);
2161
2162 case SLJIT_LESS_EQUAL_F64:
2163 return (4 << 21) | ((4 + 1) << 16);
2164
2165 case SLJIT_OVERFLOW:
2166 case SLJIT_MUL_OVERFLOW:
2167 return (12 << 21) | (3 << 16);
2168
2169 case SLJIT_NOT_OVERFLOW:
2170 case SLJIT_MUL_NOT_OVERFLOW:
2171 return (4 << 21) | (3 << 16);
2172
2173 case SLJIT_EQUAL_F64:
2174 return (12 << 21) | ((4 + 2) << 16);
2175
2176 case SLJIT_NOT_EQUAL_F64:
2177 return (4 << 21) | ((4 + 2) << 16);
2178
2179 case SLJIT_UNORDERED_F64:
2180 return (12 << 21) | ((4 + 3) << 16);
2181
2182 case SLJIT_ORDERED_F64:
2183 return (4 << 21) | ((4 + 3) << 16);
2184
2185 default:
2186 SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
2187 return (20 << 21);
2188 }
2189 }
2190
2191 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
2192 {
2193 struct sljit_jump *jump;
2194 sljit_ins bo_bi_flags;
2195
2196 CHECK_ERROR_PTR();
2197 CHECK_PTR(check_sljit_emit_jump(compiler, type));
2198
2199 bo_bi_flags = get_bo_bi_flags(type & 0xff);
2200 if (!bo_bi_flags)
2201 return NULL;
2202
2203 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2204 PTR_FAIL_IF(!jump);
2205 set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
2206 type &= 0xff;
2207
2208 /* In PPC, we don't need to touch the arguments. */
2209 if (type < SLJIT_JUMP)
2210 jump->flags |= IS_COND;
2211 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2212 if (type >= SLJIT_CALL0)
2213 jump->flags |= IS_CALL;
2214 #endif
2215
2216 PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
2217 PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG)));
2218 jump->addr = compiler->size;
2219 PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));
2220 return jump;
2221 }
2222
2223 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
2224 {
2225 struct sljit_jump *jump = NULL;
2226 sljit_s32 src_r;
2227
2228 CHECK_ERROR();
2229 CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
2230 ADJUST_LOCAL_OFFSET(src, srcw);
2231
2232 if (FAST_IS_REG(src)) {
2233 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2234 if (type >= SLJIT_CALL0) {
2235 FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
2236 src_r = TMP_CALL_REG;
2237 }
2238 else
2239 src_r = src;
2240 #else
2241 src_r = src;
2242 #endif
2243 } else if (src & SLJIT_IMM) {
2244 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2245 FAIL_IF(!jump);
2246 set_jump(jump, compiler, JUMP_ADDR);
2247 jump->u.target = srcw;
2248 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2249 if (type >= SLJIT_CALL0)
2250 jump->flags |= IS_CALL;
2251 #endif
2252 FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
2253 src_r = TMP_CALL_REG;
2254 }
2255 else {
2256 FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
2257 src_r = TMP_CALL_REG;
2258 }
2259
2260 FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));
2261 if (jump)
2262 jump->addr = compiler->size;
2263 return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0));
2264 }
2265
2266 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
2267 sljit_s32 dst, sljit_sw dstw,
2268 sljit_s32 type)
2269 {
2270 sljit_s32 reg, input_flags, cr_bit, invert;
2271 sljit_s32 saved_op = op;
2272 sljit_sw saved_dstw = dstw;
2273
2274 CHECK_ERROR();
2275 CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
2276 ADJUST_LOCAL_OFFSET(dst, dstw);
2277
2278 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2279 input_flags = (op & SLJIT_I32_OP) ? INT_DATA : WORD_DATA;
2280 #else
2281 input_flags = WORD_DATA;
2282 #endif
2283
2284 op = GET_OPCODE(op);
2285 reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
2286
2287 compiler->cache_arg = 0;
2288 compiler->cache_argw = 0;
2289
2290 if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
2291 FAIL_IF(emit_op_mem2(compiler, input_flags | LOAD_DATA, TMP_REG1, dst, dstw, dst, dstw));
2292
2293 invert = 0;
2294 cr_bit = 0;
2295
2296 switch (type & 0xff) {
2297 case SLJIT_LESS:
2298 case SLJIT_SIG_LESS:
2299 break;
2300
2301 case SLJIT_GREATER_EQUAL:
2302 case SLJIT_SIG_GREATER_EQUAL:
2303 invert = 1;
2304 break;
2305
2306 case SLJIT_GREATER:
2307 case SLJIT_SIG_GREATER:
2308 cr_bit = 1;
2309 break;
2310
2311 case SLJIT_LESS_EQUAL:
2312 case SLJIT_SIG_LESS_EQUAL:
2313 cr_bit = 1;
2314 invert = 1;
2315 break;
2316
2317 case SLJIT_EQUAL:
2318 cr_bit = 2;
2319 break;
2320
2321 case SLJIT_NOT_EQUAL:
2322 cr_bit = 2;
2323 invert = 1;
2324 break;
2325
2326 case SLJIT_OVERFLOW:
2327 case SLJIT_MUL_OVERFLOW:
2328 cr_bit = 3;
2329 break;
2330
2331 case SLJIT_NOT_OVERFLOW:
2332 case SLJIT_MUL_NOT_OVERFLOW:
2333 cr_bit = 3;
2334 invert = 1;
2335 break;
2336
2337 case SLJIT_LESS_F64:
2338 cr_bit = 4 + 0;
2339 break;
2340
2341 case SLJIT_GREATER_EQUAL_F64:
2342 cr_bit = 4 + 0;
2343 invert = 1;
2344 break;
2345
2346 case SLJIT_GREATER_F64:
2347 cr_bit = 4 + 1;
2348 break;
2349
2350 case SLJIT_LESS_EQUAL_F64:
2351 cr_bit = 4 + 1;
2352 invert = 1;
2353 break;
2354
2355 case SLJIT_EQUAL_F64:
2356 cr_bit = 4 + 2;
2357 break;
2358
2359 case SLJIT_NOT_EQUAL_F64:
2360 cr_bit = 4 + 2;
2361 invert = 1;
2362 break;
2363
2364 case SLJIT_UNORDERED_F64:
2365 cr_bit = 4 + 3;
2366 break;
2367
2368 case SLJIT_ORDERED_F64:
2369 cr_bit = 4 + 3;
2370 invert = 1;
2371 break;
2372
2373 default:
2374 SLJIT_UNREACHABLE();
2375 break;
2376 }
2377
2378 FAIL_IF(push_inst(compiler, MFCR | D(reg)));
2379 FAIL_IF(push_inst(compiler, RLWINM | S(reg) | A(reg) | ((1 + (cr_bit)) << 11) | (31 << 6) | (31 << 1)));
2380
2381 if (invert)
2382 FAIL_IF(push_inst(compiler, XORI | S(reg) | A(reg) | 0x1));
2383
2384 if (op < SLJIT_ADD) {
2385 if (!(dst & SLJIT_MEM))
2386 return SLJIT_SUCCESS;
2387 return emit_op_mem2(compiler, input_flags, reg, dst, dstw, reg, 0);
2388 }
2389
2390 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2391 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2392 compiler->skip_checks = 1;
2393 #endif
2394 if (dst & SLJIT_MEM)
2395 return sljit_emit_op2(compiler, saved_op, dst, saved_dstw, TMP_REG1, 0, TMP_REG2, 0);
2396 return sljit_emit_op2(compiler, saved_op, dst, 0, dst, 0, TMP_REG2, 0);
2397 }
2398
2399 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
2400 sljit_s32 dst_reg,
2401 sljit_s32 src, sljit_sw srcw)
2402 {
2403 CHECK_ERROR();
2404 CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
2405
2406 return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);;
2407 }
2408
2409 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
2410 {
2411 struct sljit_const *const_;
2412 sljit_s32 reg;
2413
2414 CHECK_ERROR_PTR();
2415 CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
2416 ADJUST_LOCAL_OFFSET(dst, dstw);
2417
2418 const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
2419 PTR_FAIL_IF(!const_);
2420 set_const(const_, compiler);
2421
2422 reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
2423
2424 PTR_FAIL_IF(emit_const(compiler, reg, init_value));
2425
2426 if (dst & SLJIT_MEM)
2427 PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
2428 return const_;
2429 }

  ViewVC Help
Powered by ViewVC 1.1.5