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