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