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