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));
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
611 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
612 return code_ptr;
613 #else
614 return code;
615 #endif
616 }
617
sljit_has_cpu_feature(sljit_s32 feature_type)618 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
619 {
620 switch (feature_type) {
621 case SLJIT_HAS_FPU:
622 #ifdef SLJIT_IS_FPU_AVAILABLE
623 return SLJIT_IS_FPU_AVAILABLE;
624 #else
625 /* Available by default. */
626 return 1;
627 #endif
628
629 /* A saved register is set to a zero value. */
630 case SLJIT_HAS_ZERO_REGISTER:
631 case SLJIT_HAS_CLZ:
632 case SLJIT_HAS_PREFETCH:
633 return 1;
634
635 default:
636 return 0;
637 }
638 }
639
640 /* --------------------------------------------------------------------- */
641 /* Entry, exit */
642 /* --------------------------------------------------------------------- */
643
644 /* inp_flags: */
645
646 /* Creates an index in data_transfer_insts array. */
647 #define LOAD_DATA 0x01
648 #define INDEXED 0x02
649 #define SIGNED_DATA 0x04
650
651 #define WORD_DATA 0x00
652 #define BYTE_DATA 0x08
653 #define HALF_DATA 0x10
654 #define INT_DATA 0x18
655 /* Separates integer and floating point registers */
656 #define GPR_REG 0x1f
657 #define DOUBLE_DATA 0x20
658
659 #define MEM_MASK 0x7f
660
661 /* Other inp_flags. */
662
663 /* Integer opertion and set flags -> requires exts on 64 bit systems. */
664 #define ALT_SIGN_EXT 0x000100
665 /* This flag affects the RC() and OERC() macros. */
666 #define ALT_SET_FLAGS 0x000400
667 #define ALT_FORM1 0x001000
668 #define ALT_FORM2 0x002000
669 #define ALT_FORM3 0x004000
670 #define ALT_FORM4 0x008000
671 #define ALT_FORM5 0x010000
672
673 /* Source and destination is register. */
674 #define REG_DEST 0x000001
675 #define REG1_SOURCE 0x000002
676 #define REG2_SOURCE 0x000004
677 /*
678 ALT_SIGN_EXT 0x000100
679 ALT_SET_FLAGS 0x000200
680 ALT_FORM1 0x001000
681 ...
682 ALT_FORM5 0x010000 */
683
684 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
685 #include "sljitNativePPC_32.c"
686 #else
687 #include "sljitNativePPC_64.c"
688 #endif
689
690 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
691 #define STACK_STORE STW
692 #define STACK_LOAD LWZ
693 #else
694 #define STACK_STORE STD
695 #define STACK_LOAD LD
696 #endif
697
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)698 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
699 sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
700 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
701 {
702 sljit_s32 args, i, tmp, offs;
703
704 CHECK_ERROR();
705 CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
706 set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
707
708 FAIL_IF(push_inst(compiler, MFLR | D(0)));
709 offs = -(sljit_s32)(sizeof(sljit_sw));
710 FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
711
712 tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
713 for (i = SLJIT_S0; i >= tmp; i--) {
714 offs -= (sljit_s32)(sizeof(sljit_sw));
715 FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
716 }
717
718 for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
719 offs -= (sljit_s32)(sizeof(sljit_sw));
720 FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
721 }
722
723 SLJIT_ASSERT(offs == -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1));
724
725 #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
726 FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
727 #else
728 FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
729 #endif
730
731 FAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0));
732
733 args = get_arg_count(arg_types);
734
735 if (args >= 1)
736 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(SLJIT_S0) | B(SLJIT_R0)));
737 if (args >= 2)
738 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R1) | A(SLJIT_S1) | B(SLJIT_R1)));
739 if (args >= 3)
740 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R2) | A(SLJIT_S2) | B(SLJIT_R2)));
741
742 local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
743 local_size = (local_size + 15) & ~0xf;
744 compiler->local_size = local_size;
745
746 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
747 if (local_size <= SIMM_MAX)
748 FAIL_IF(push_inst(compiler, STWU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
749 else {
750 FAIL_IF(load_immediate(compiler, 0, -local_size));
751 FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
752 }
753 #else
754 if (local_size <= SIMM_MAX)
755 FAIL_IF(push_inst(compiler, STDU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
756 else {
757 FAIL_IF(load_immediate(compiler, 0, -local_size));
758 FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
759 }
760 #endif
761
762 return SLJIT_SUCCESS;
763 }
764
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)765 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
766 sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
767 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
768 {
769 CHECK_ERROR();
770 CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
771 set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
772
773 local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
774 compiler->local_size = (local_size + 15) & ~0xf;
775 return SLJIT_SUCCESS;
776 }
777
sljit_emit_return(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)778 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
779 {
780 sljit_s32 i, tmp, offs;
781
782 CHECK_ERROR();
783 CHECK(check_sljit_emit_return(compiler, op, src, srcw));
784
785 FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
786
787 if (compiler->local_size <= SIMM_MAX)
788 FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_SP) | A(SLJIT_SP) | IMM(compiler->local_size)));
789 else {
790 FAIL_IF(load_immediate(compiler, 0, compiler->local_size));
791 FAIL_IF(push_inst(compiler, ADD | D(SLJIT_SP) | A(SLJIT_SP) | B(0)));
792 }
793
794 #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
795 FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
796 #else
797 FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
798 #endif
799
800 offs = -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1);
801
802 tmp = compiler->scratches;
803 for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
804 FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
805 offs += (sljit_s32)(sizeof(sljit_sw));
806 }
807
808 tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
809 for (i = tmp; i <= SLJIT_S0; i++) {
810 FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
811 offs += (sljit_s32)(sizeof(sljit_sw));
812 }
813
814 FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
815 SLJIT_ASSERT(offs == -(sljit_sw)(sizeof(sljit_sw)));
816
817 FAIL_IF(push_inst(compiler, MTLR | S(0)));
818 FAIL_IF(push_inst(compiler, BLR));
819
820 return SLJIT_SUCCESS;
821 }
822
823 #undef STACK_STORE
824 #undef STACK_LOAD
825
826 /* --------------------------------------------------------------------- */
827 /* Operators */
828 /* --------------------------------------------------------------------- */
829
830 /* s/l - store/load (1 bit)
831 i/x - immediate/indexed form
832 u/s - signed/unsigned (1 bit)
833 w/b/h/i - word/byte/half/int allowed (2 bit)
834
835 Some opcodes are repeated (e.g. store signed / unsigned byte is the same instruction). */
836
837 /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
838 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
839 #define INT_ALIGNED 0x10000
840 #endif
841
842 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
843 #define ARCH_32_64(a, b) a
844 #define INST_CODE_AND_DST(inst, flags, reg) \
845 ((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
846 #else
847 #define ARCH_32_64(a, b) b
848 #define INST_CODE_AND_DST(inst, flags, reg) \
849 (((inst) & ~INT_ALIGNED) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
850 #endif
851
852 static const sljit_ins data_transfer_insts[64 + 16] = {
853
854 /* -------- Integer -------- */
855
856 /* Word. */
857
858 /* w u i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
859 /* w u i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
860 /* w u x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
861 /* w u x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
862
863 /* w s i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
864 /* w s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
865 /* w s x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
866 /* w s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
867
868 /* Byte. */
869
870 /* b u i s */ HI(38) /* stb */,
871 /* b u i l */ HI(34) /* lbz */,
872 /* b u x s */ HI(31) | LO(215) /* stbx */,
873 /* b u x l */ HI(31) | LO(87) /* lbzx */,
874
875 /* b s i s */ HI(38) /* stb */,
876 /* b s i l */ HI(34) /* lbz */ /* EXTS_REQ */,
877 /* b s x s */ HI(31) | LO(215) /* stbx */,
878 /* b s x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
879
880 /* Half. */
881
882 /* h u i s */ HI(44) /* sth */,
883 /* h u i l */ HI(40) /* lhz */,
884 /* h u x s */ HI(31) | LO(407) /* sthx */,
885 /* h u x l */ HI(31) | LO(279) /* lhzx */,
886
887 /* h s i s */ HI(44) /* sth */,
888 /* h s i l */ HI(42) /* lha */,
889 /* h s x s */ HI(31) | LO(407) /* sthx */,
890 /* h s x l */ HI(31) | LO(343) /* lhax */,
891
892 /* Int. */
893
894 /* i u i s */ HI(36) /* stw */,
895 /* i u i l */ HI(32) /* lwz */,
896 /* i u x s */ HI(31) | LO(151) /* stwx */,
897 /* i u x l */ HI(31) | LO(23) /* lwzx */,
898
899 /* i s i s */ HI(36) /* stw */,
900 /* i s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */),
901 /* i s x s */ HI(31) | LO(151) /* stwx */,
902 /* i s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
903
904 /* -------- Floating point -------- */
905
906 /* d i s */ HI(54) /* stfd */,
907 /* d i l */ HI(50) /* lfd */,
908 /* d x s */ HI(31) | LO(727) /* stfdx */,
909 /* d x l */ HI(31) | LO(599) /* lfdx */,
910
911 /* s i s */ HI(52) /* stfs */,
912 /* s i l */ HI(48) /* lfs */,
913 /* s x s */ HI(31) | LO(663) /* stfsx */,
914 /* s x l */ HI(31) | LO(535) /* lfsx */,
915 };
916
917 static const sljit_ins updated_data_transfer_insts[64] = {
918
919 /* -------- Integer -------- */
920
921 /* Word. */
922
923 /* w u i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
924 /* w u i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
925 /* w u x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
926 /* w u x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
927
928 /* w s i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
929 /* w s i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
930 /* w s x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
931 /* w s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
932
933 /* Byte. */
934
935 /* b u i s */ HI(39) /* stbu */,
936 /* b u i l */ HI(35) /* lbzu */,
937 /* b u x s */ HI(31) | LO(247) /* stbux */,
938 /* b u x l */ HI(31) | LO(119) /* lbzux */,
939
940 /* b s i s */ HI(39) /* stbu */,
941 /* b s i l */ 0 /* no such instruction */,
942 /* b s x s */ HI(31) | LO(247) /* stbux */,
943 /* b s x l */ 0 /* no such instruction */,
944
945 /* Half. */
946
947 /* h u i s */ HI(45) /* sthu */,
948 /* h u i l */ HI(41) /* lhzu */,
949 /* h u x s */ HI(31) | LO(439) /* sthux */,
950 /* h u x l */ HI(31) | LO(311) /* lhzux */,
951
952 /* h s i s */ HI(45) /* sthu */,
953 /* h s i l */ HI(43) /* lhau */,
954 /* h s x s */ HI(31) | LO(439) /* sthux */,
955 /* h s x l */ HI(31) | LO(375) /* lhaux */,
956
957 /* Int. */
958
959 /* i u i s */ HI(37) /* stwu */,
960 /* i u i l */ HI(33) /* lwzu */,
961 /* i u x s */ HI(31) | LO(183) /* stwux */,
962 /* i u x l */ HI(31) | LO(55) /* lwzux */,
963
964 /* i s i s */ HI(37) /* stwu */,
965 /* i s i l */ ARCH_32_64(HI(33) /* lwzu */, 0 /* no such instruction */),
966 /* i s x s */ HI(31) | LO(183) /* stwux */,
967 /* i s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
968
969 /* -------- Floating point -------- */
970
971 /* d i s */ HI(55) /* stfdu */,
972 /* d i l */ HI(51) /* lfdu */,
973 /* d x s */ HI(31) | LO(759) /* stfdux */,
974 /* d x l */ HI(31) | LO(631) /* lfdux */,
975
976 /* s i s */ HI(53) /* stfsu */,
977 /* s i l */ HI(49) /* lfsu */,
978 /* s x s */ HI(31) | LO(695) /* stfsux */,
979 /* s x l */ HI(31) | LO(567) /* lfsux */,
980 };
981
982 #undef ARCH_32_64
983
984 /* 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)985 static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg,
986 sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)
987 {
988 sljit_ins inst;
989 sljit_s32 offs_reg;
990 sljit_sw high_short;
991
992 /* Should work when (arg & REG_MASK) == 0. */
993 SLJIT_ASSERT(A(0) == 0);
994 SLJIT_ASSERT(arg & SLJIT_MEM);
995
996 if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
997 argw &= 0x3;
998 offs_reg = OFFS_REG(arg);
999
1000 if (argw != 0) {
1001 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1002 FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(arg)) | A(tmp_reg) | (argw << 11) | ((31 - argw) << 1)));
1003 #else
1004 FAIL_IF(push_inst(compiler, RLDI(tmp_reg, OFFS_REG(arg), argw, 63 - argw, 1)));
1005 #endif
1006 offs_reg = tmp_reg;
1007 }
1008
1009 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
1010
1011 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1012 SLJIT_ASSERT(!(inst & INT_ALIGNED));
1013 #endif
1014
1015 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(offs_reg));
1016 }
1017
1018 inst = data_transfer_insts[inp_flags & MEM_MASK];
1019 arg &= REG_MASK;
1020
1021 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1022 if ((inst & INT_ALIGNED) && (argw & 0x3) != 0) {
1023 FAIL_IF(load_immediate(compiler, tmp_reg, argw));
1024
1025 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
1026 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | B(tmp_reg));
1027 }
1028 #endif
1029
1030 if (argw <= SIMM_MAX && argw >= SIMM_MIN)
1031 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | IMM(argw));
1032
1033 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1034 if (argw <= 0x7fff7fffl && argw >= -0x80000000l) {
1035 #endif
1036
1037 high_short = (sljit_s32)(argw + ((argw & 0x8000) << 1)) & ~0xffff;
1038
1039 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1040 SLJIT_ASSERT(high_short && high_short <= 0x7fffffffl && high_short >= -0x80000000l);
1041 #else
1042 SLJIT_ASSERT(high_short);
1043 #endif
1044
1045 FAIL_IF(push_inst(compiler, ADDIS | D(tmp_reg) | A(arg) | IMM(high_short >> 16)));
1046 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_reg) | IMM(argw));
1047
1048 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1049 }
1050
1051 /* The rest is PPC-64 only. */
1052
1053 FAIL_IF(load_immediate(compiler, tmp_reg, argw));
1054
1055 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
1056 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | B(tmp_reg));
1057 #endif
1058 }
1059
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)1060 static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 input_flags,
1061 sljit_s32 dst, sljit_sw dstw,
1062 sljit_s32 src1, sljit_sw src1w,
1063 sljit_s32 src2, sljit_sw src2w)
1064 {
1065 /* arg1 goes to TMP_REG1 or src reg
1066 arg2 goes to TMP_REG2, imm or src reg
1067 result goes to TMP_REG2, so put result can use TMP_REG1. */
1068 sljit_s32 dst_r = TMP_REG2;
1069 sljit_s32 src1_r;
1070 sljit_s32 src2_r;
1071 sljit_s32 sugg_src2_r = TMP_REG2;
1072 sljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_SIGN_EXT | ALT_SET_FLAGS);
1073
1074 /* Destination check. */
1075 if (SLOW_IS_REG(dst)) {
1076 dst_r = dst;
1077 flags |= REG_DEST;
1078
1079 if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)
1080 sugg_src2_r = dst_r;
1081 }
1082
1083 /* Source 1. */
1084 if (FAST_IS_REG(src1)) {
1085 src1_r = src1;
1086 flags |= REG1_SOURCE;
1087 }
1088 else if (src1 & SLJIT_IMM) {
1089 FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
1090 src1_r = TMP_REG1;
1091 }
1092 else {
1093 FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));
1094 src1_r = TMP_REG1;
1095 }
1096
1097 /* Source 2. */
1098 if (FAST_IS_REG(src2)) {
1099 src2_r = src2;
1100 flags |= REG2_SOURCE;
1101
1102 if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)
1103 dst_r = src2_r;
1104 }
1105 else if (src2 & SLJIT_IMM) {
1106 FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
1107 src2_r = sugg_src2_r;
1108 }
1109 else {
1110 FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, TMP_REG2));
1111 src2_r = sugg_src2_r;
1112 }
1113
1114 FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
1115
1116 if (!(dst & SLJIT_MEM))
1117 return SLJIT_SUCCESS;
1118
1119 return emit_op_mem(compiler, input_flags, dst_r, dst, dstw, TMP_REG1);
1120 }
1121
sljit_emit_op0(struct sljit_compiler * compiler,sljit_s32 op)1122 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
1123 {
1124 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1125 sljit_s32 int_op = op & SLJIT_I32_OP;
1126 #endif
1127
1128 CHECK_ERROR();
1129 CHECK(check_sljit_emit_op0(compiler, op));
1130
1131 op = GET_OPCODE(op);
1132 switch (op) {
1133 case SLJIT_BREAKPOINT:
1134 case SLJIT_NOP:
1135 return push_inst(compiler, NOP);
1136 case SLJIT_LMUL_UW:
1137 case SLJIT_LMUL_SW:
1138 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
1139 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1140 FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
1141 return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
1142 #else
1143 FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
1144 return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
1145 #endif
1146 case SLJIT_DIVMOD_UW:
1147 case SLJIT_DIVMOD_SW:
1148 FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
1149 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1150 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)));
1151 FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
1152 #else
1153 FAIL_IF(push_inst(compiler, (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
1154 FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
1155 #endif
1156 return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));
1157 case SLJIT_DIV_UW:
1158 case SLJIT_DIV_SW:
1159 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1160 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));
1161 #else
1162 return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
1163 #endif
1164 case SLJIT_ENDBR:
1165 case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
1166 return SLJIT_SUCCESS;
1167 }
1168
1169 return SLJIT_SUCCESS;
1170 }
1171
emit_prefetch(struct sljit_compiler * compiler,sljit_s32 src,sljit_sw srcw)1172 static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
1173 sljit_s32 src, sljit_sw srcw)
1174 {
1175 if (!(src & OFFS_REG_MASK)) {
1176 if (srcw == 0 && (src & REG_MASK) != SLJIT_UNUSED)
1177 return push_inst(compiler, DCBT | A(0) | B(src & REG_MASK));
1178
1179 FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
1180 /* Works with SLJIT_MEM0() case as well. */
1181 return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));
1182 }
1183
1184 srcw &= 0x3;
1185
1186 if (srcw == 0)
1187 return push_inst(compiler, DCBT | A(src & REG_MASK) | B(OFFS_REG(src)));
1188
1189 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1190 FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(src)) | A(TMP_REG1) | (srcw << 11) | ((31 - srcw) << 1)));
1191 #else
1192 FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(src), srcw, 63 - srcw, 1)));
1193 #endif
1194 return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));
1195 }
1196
1197 #define EMIT_MOV(type, type_flags, type_cast) \
1198 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)
1199
sljit_emit_op1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1200 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
1201 sljit_s32 dst, sljit_sw dstw,
1202 sljit_s32 src, sljit_sw srcw)
1203 {
1204 sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;
1205 sljit_s32 op_flags = GET_ALL_FLAGS(op);
1206
1207 CHECK_ERROR();
1208 CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
1209 ADJUST_LOCAL_OFFSET(dst, dstw);
1210 ADJUST_LOCAL_OFFSET(src, srcw);
1211
1212 op = GET_OPCODE(op);
1213 if ((src & SLJIT_IMM) && srcw == 0)
1214 src = TMP_ZERO;
1215
1216 if (GET_FLAG_TYPE(op_flags) == SLJIT_OVERFLOW)
1217 FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
1218
1219 if (op < SLJIT_NOT && FAST_IS_REG(src) && src == dst) {
1220 if (!TYPE_CAST_NEEDED(op))
1221 return SLJIT_SUCCESS;
1222 }
1223
1224 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1225 if (op_flags & SLJIT_I32_OP) {
1226 if (op < SLJIT_NOT) {
1227 if (src & SLJIT_MEM) {
1228 if (op == SLJIT_MOV_S32)
1229 op = SLJIT_MOV_U32;
1230 }
1231 else if (src & SLJIT_IMM) {
1232 if (op == SLJIT_MOV_U32)
1233 op = SLJIT_MOV_S32;
1234 }
1235 }
1236 else {
1237 /* Most operations expect sign extended arguments. */
1238 flags |= INT_DATA | SIGNED_DATA;
1239 if (HAS_FLAGS(op_flags))
1240 flags |= ALT_SIGN_EXT;
1241 }
1242 }
1243 #endif
1244
1245 switch (op) {
1246 case SLJIT_MOV:
1247 case SLJIT_MOV_P:
1248 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1249 case SLJIT_MOV_U32:
1250 case SLJIT_MOV_S32:
1251 #endif
1252 return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
1253
1254 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1255 case SLJIT_MOV_U32:
1256 return EMIT_MOV(SLJIT_MOV_U32, INT_DATA, (sljit_u32));
1257
1258 case SLJIT_MOV_S32:
1259 return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, (sljit_s32));
1260 #endif
1261
1262 case SLJIT_MOV_U8:
1263 return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA, (sljit_u8));
1264
1265 case SLJIT_MOV_S8:
1266 return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, (sljit_s8));
1267
1268 case SLJIT_MOV_U16:
1269 return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA, (sljit_u16));
1270
1271 case SLJIT_MOV_S16:
1272 return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (sljit_s16));
1273
1274 case SLJIT_NOT:
1275 return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw);
1276
1277 case SLJIT_NEG:
1278 return emit_op(compiler, SLJIT_NEG, flags | (GET_FLAG_TYPE(op_flags) ? ALT_FORM1 : 0), dst, dstw, TMP_REG1, 0, src, srcw);
1279
1280 case SLJIT_CLZ:
1281 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1282 return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_I32_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw);
1283 #else
1284 return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw);
1285 #endif
1286 }
1287
1288 return SLJIT_SUCCESS;
1289 }
1290
1291 #undef EMIT_MOV
1292
1293 #define TEST_SL_IMM(src, srcw) \
1294 (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)
1295
1296 #define TEST_UL_IMM(src, srcw) \
1297 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff))
1298
1299 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1300 #define TEST_SH_IMM(src, srcw) \
1301 (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l)
1302 #else
1303 #define TEST_SH_IMM(src, srcw) \
1304 (((src) & SLJIT_IMM) && !((srcw) & 0xffff))
1305 #endif
1306
1307 #define TEST_UH_IMM(src, srcw) \
1308 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000))
1309
1310 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1311 #define TEST_ADD_IMM(src, srcw) \
1312 (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l)
1313 #else
1314 #define TEST_ADD_IMM(src, srcw) \
1315 ((src) & SLJIT_IMM)
1316 #endif
1317
1318 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1319 #define TEST_UI_IMM(src, srcw) \
1320 (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
1321 #else
1322 #define TEST_UI_IMM(src, srcw) \
1323 ((src) & SLJIT_IMM)
1324 #endif
1325
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)1326 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
1327 sljit_s32 dst, sljit_sw dstw,
1328 sljit_s32 src1, sljit_sw src1w,
1329 sljit_s32 src2, sljit_sw src2w)
1330 {
1331 sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;
1332
1333 CHECK_ERROR();
1334 CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
1335 ADJUST_LOCAL_OFFSET(dst, dstw);
1336 ADJUST_LOCAL_OFFSET(src1, src1w);
1337 ADJUST_LOCAL_OFFSET(src2, src2w);
1338
1339 if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
1340 return SLJIT_SUCCESS;
1341
1342 if ((src1 & SLJIT_IMM) && src1w == 0)
1343 src1 = TMP_ZERO;
1344 if ((src2 & SLJIT_IMM) && src2w == 0)
1345 src2 = TMP_ZERO;
1346
1347 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1348 if (op & SLJIT_I32_OP) {
1349 /* Most operations expect sign extended arguments. */
1350 flags |= INT_DATA | SIGNED_DATA;
1351 if (src1 & SLJIT_IMM)
1352 src1w = (sljit_s32)(src1w);
1353 if (src2 & SLJIT_IMM)
1354 src2w = (sljit_s32)(src2w);
1355 if (HAS_FLAGS(op))
1356 flags |= ALT_SIGN_EXT;
1357 }
1358 #endif
1359 if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1360 FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
1361
1362 switch (GET_OPCODE(op)) {
1363 case SLJIT_ADD:
1364 if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1365 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);
1366
1367 if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
1368 if (TEST_SL_IMM(src2, src2w)) {
1369 compiler->imm = src2w & 0xffff;
1370 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1371 }
1372 if (TEST_SL_IMM(src1, src1w)) {
1373 compiler->imm = src1w & 0xffff;
1374 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
1375 }
1376 if (TEST_SH_IMM(src2, src2w)) {
1377 compiler->imm = (src2w >> 16) & 0xffff;
1378 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1379 }
1380 if (TEST_SH_IMM(src1, src1w)) {
1381 compiler->imm = (src1w >> 16) & 0xffff;
1382 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1383 }
1384 /* Range between -1 and -32768 is covered above. */
1385 if (TEST_ADD_IMM(src2, src2w)) {
1386 compiler->imm = src2w & 0xffffffff;
1387 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
1388 }
1389 if (TEST_ADD_IMM(src1, src1w)) {
1390 compiler->imm = src1w & 0xffffffff;
1391 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);
1392 }
1393 }
1394 if (HAS_FLAGS(op)) {
1395 if (TEST_SL_IMM(src2, src2w)) {
1396 compiler->imm = src2w & 0xffff;
1397 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1398 }
1399 if (TEST_SL_IMM(src1, src1w)) {
1400 compiler->imm = src1w & 0xffff;
1401 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1402 }
1403 }
1404 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);
1405
1406 case SLJIT_ADDC:
1407 return emit_op(compiler, SLJIT_ADDC, flags, dst, dstw, src1, src1w, src2, src2w);
1408
1409 case SLJIT_SUB:
1410 if (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_LESS_EQUAL) {
1411 if (dst == SLJIT_UNUSED) {
1412 if (TEST_UL_IMM(src2, src2w)) {
1413 compiler->imm = src2w & 0xffff;
1414 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1415 }
1416 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);
1417 }
1418
1419 if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= (SIMM_MAX + 1)) {
1420 compiler->imm = src2w;
1421 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1422 }
1423 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM3, dst, dstw, src1, src1w, src2, src2w);
1424 }
1425
1426 if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1427 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, src2, src2w);
1428
1429 if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
1430 if (TEST_SL_IMM(src2, -src2w)) {
1431 compiler->imm = (-src2w) & 0xffff;
1432 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1433 }
1434 if (TEST_SL_IMM(src1, src1w)) {
1435 compiler->imm = src1w & 0xffff;
1436 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1437 }
1438 if (TEST_SH_IMM(src2, -src2w)) {
1439 compiler->imm = ((-src2w) >> 16) & 0xffff;
1440 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1441 }
1442 /* Range between -1 and -32768 is covered above. */
1443 if (TEST_ADD_IMM(src2, -src2w)) {
1444 compiler->imm = -src2w & 0xffffffff;
1445 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
1446 }
1447 }
1448
1449 if (dst == SLJIT_UNUSED && GET_FLAG_TYPE(op) != GET_FLAG_TYPE(SLJIT_SET_CARRY)) {
1450 if (TEST_SL_IMM(src2, src2w)) {
1451 compiler->imm = src2w & 0xffff;
1452 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4 | ALT_FORM5, dst, dstw, src1, src1w, TMP_REG2, 0);
1453 }
1454 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
1455 }
1456
1457 if (TEST_SL_IMM(src2, -src2w)) {
1458 compiler->imm = (-src2w) & 0xffff;
1459 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1460 }
1461 /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */
1462 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);
1463
1464 case SLJIT_SUBC:
1465 return emit_op(compiler, SLJIT_SUBC, flags, dst, dstw, src1, src1w, src2, src2w);
1466
1467 case SLJIT_MUL:
1468 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1469 if (op & SLJIT_I32_OP)
1470 flags |= ALT_FORM2;
1471 #endif
1472 if (!HAS_FLAGS(op)) {
1473 if (TEST_SL_IMM(src2, src2w)) {
1474 compiler->imm = src2w & 0xffff;
1475 return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1476 }
1477 if (TEST_SL_IMM(src1, src1w)) {
1478 compiler->imm = src1w & 0xffff;
1479 return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1480 }
1481 }
1482 else
1483 FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
1484 return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w);
1485
1486 case SLJIT_AND:
1487 case SLJIT_OR:
1488 case SLJIT_XOR:
1489 /* Commutative unsigned operations. */
1490 if (!HAS_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) {
1491 if (TEST_UL_IMM(src2, src2w)) {
1492 compiler->imm = src2w;
1493 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1494 }
1495 if (TEST_UL_IMM(src1, src1w)) {
1496 compiler->imm = src1w;
1497 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1498 }
1499 if (TEST_UH_IMM(src2, src2w)) {
1500 compiler->imm = (src2w >> 16) & 0xffff;
1501 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1502 }
1503 if (TEST_UH_IMM(src1, src1w)) {
1504 compiler->imm = (src1w >> 16) & 0xffff;
1505 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
1506 }
1507 }
1508 if (GET_OPCODE(op) != SLJIT_AND && GET_OPCODE(op) != SLJIT_AND) {
1509 /* Unlike or and xor, and resets unwanted bits as well. */
1510 if (TEST_UI_IMM(src2, src2w)) {
1511 compiler->imm = src2w;
1512 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1513 }
1514 if (TEST_UI_IMM(src1, src1w)) {
1515 compiler->imm = src1w;
1516 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1517 }
1518 }
1519 return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
1520
1521 case SLJIT_SHL:
1522 case SLJIT_LSHR:
1523 case SLJIT_ASHR:
1524 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1525 if (op & SLJIT_I32_OP)
1526 flags |= ALT_FORM2;
1527 #endif
1528 if (src2 & SLJIT_IMM) {
1529 compiler->imm = src2w;
1530 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1531 }
1532 return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
1533 }
1534
1535 return SLJIT_SUCCESS;
1536 }
1537
sljit_emit_op_src(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)1538 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
1539 sljit_s32 src, sljit_sw srcw)
1540 {
1541 CHECK_ERROR();
1542 CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
1543 ADJUST_LOCAL_OFFSET(src, srcw);
1544
1545 switch (op) {
1546 case SLJIT_FAST_RETURN:
1547 if (FAST_IS_REG(src))
1548 FAIL_IF(push_inst(compiler, MTLR | S(src)));
1549 else {
1550 FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
1551 FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
1552 }
1553
1554 return push_inst(compiler, BLR);
1555 case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
1556 return SLJIT_SUCCESS;
1557 case SLJIT_PREFETCH_L1:
1558 case SLJIT_PREFETCH_L2:
1559 case SLJIT_PREFETCH_L3:
1560 case SLJIT_PREFETCH_ONCE:
1561 return emit_prefetch(compiler, src, srcw);
1562 }
1563
1564 return SLJIT_SUCCESS;
1565 }
1566
sljit_get_register_index(sljit_s32 reg)1567 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
1568 {
1569 CHECK_REG_INDEX(check_sljit_get_register_index(reg));
1570 return reg_map[reg];
1571 }
1572
sljit_get_float_register_index(sljit_s32 reg)1573 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
1574 {
1575 CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
1576 return freg_map[reg];
1577 }
1578
sljit_emit_op_custom(struct sljit_compiler * compiler,void * instruction,sljit_s32 size)1579 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
1580 void *instruction, sljit_s32 size)
1581 {
1582 CHECK_ERROR();
1583 CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
1584
1585 return push_inst(compiler, *(sljit_ins*)instruction);
1586 }
1587
1588 /* --------------------------------------------------------------------- */
1589 /* Floating point operators */
1590 /* --------------------------------------------------------------------- */
1591
1592 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 6))
1593 #define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)
1594
1595 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1596 #define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw))
1597 #else
1598 #define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw))
1599
1600 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
1601 #define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw))
1602 #define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw))
1603 #else
1604 #define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw))
1605 #define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw))
1606 #endif
1607
1608 #endif /* SLJIT_CONFIG_PPC_64 */
1609
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)1610 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
1611 sljit_s32 dst, sljit_sw dstw,
1612 sljit_s32 src, sljit_sw srcw)
1613 {
1614 if (src & SLJIT_MEM) {
1615 /* We can ignore the temporary data store on the stack from caching point of view. */
1616 FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));
1617 src = TMP_FREG1;
1618 }
1619
1620 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1621 op = GET_OPCODE(op);
1622 FAIL_IF(push_inst(compiler, (op == SLJIT_CONV_S32_FROM_F64 ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src)));
1623
1624 if (op == SLJIT_CONV_SW_FROM_F64) {
1625 if (FAST_IS_REG(dst)) {
1626 FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1627 return emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1);
1628 }
1629 return emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, TMP_REG1);
1630 }
1631 #else
1632 FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src)));
1633 #endif
1634
1635 if (FAST_IS_REG(dst)) {
1636 FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET));
1637 FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1)));
1638 return emit_op_mem(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1);
1639 }
1640
1641 SLJIT_ASSERT(dst & SLJIT_MEM);
1642
1643 if (dst & OFFS_REG_MASK) {
1644 dstw &= 0x3;
1645 if (dstw) {
1646 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1647 FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(dst)) | A(TMP_REG1) | (dstw << 11) | ((31 - dstw) << 1)));
1648 #else
1649 FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(dst), dstw, 63 - dstw, 1)));
1650 #endif
1651 dstw = TMP_REG1;
1652 }
1653 else
1654 dstw = OFFS_REG(dst);
1655 }
1656 else {
1657 if ((dst & REG_MASK) && !dstw) {
1658 dstw = dst & REG_MASK;
1659 dst = 0;
1660 }
1661 else {
1662 /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */
1663 FAIL_IF(load_immediate(compiler, TMP_REG1, dstw));
1664 dstw = TMP_REG1;
1665 }
1666 }
1667
1668 return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw));
1669 }
1670
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)1671 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
1672 sljit_s32 dst, sljit_sw dstw,
1673 sljit_s32 src, sljit_sw srcw)
1674 {
1675 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1676
1677 sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1678
1679 if (src & SLJIT_IMM) {
1680 if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
1681 srcw = (sljit_s32)srcw;
1682 FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
1683 src = TMP_REG1;
1684 }
1685 else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) {
1686 if (FAST_IS_REG(src))
1687 FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1)));
1688 else
1689 FAIL_IF(emit_op_mem(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
1690 src = TMP_REG1;
1691 }
1692
1693 if (FAST_IS_REG(src)) {
1694 FAIL_IF(emit_op_mem(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1695 FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1696 }
1697 else
1698 FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));
1699
1700 FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
1701
1702 if (dst & SLJIT_MEM)
1703 return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
1704 if (op & SLJIT_F32_OP)
1705 return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
1706 return SLJIT_SUCCESS;
1707
1708 #else
1709
1710 sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1711 sljit_s32 invert_sign = 1;
1712
1713 if (src & SLJIT_IMM) {
1714 FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000));
1715 src = TMP_REG1;
1716 invert_sign = 0;
1717 }
1718 else if (!FAST_IS_REG(src)) {
1719 FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
1720 src = TMP_REG1;
1721 }
1722
1723 /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31)))
1724 The double precision format has exactly 53 bit precision, so the lower 32 bit represents
1725 the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000
1726 to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating
1727 point value, we need to substract 2^53 + 2^31 from the constructed value. */
1728 FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
1729 if (invert_sign)
1730 FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000));
1731 FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, TMP_REG1));
1732 FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2));
1733 FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000));
1734 FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1735 FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2));
1736 FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1737
1738 FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
1739
1740 if (dst & SLJIT_MEM)
1741 return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
1742 if (op & SLJIT_F32_OP)
1743 return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
1744 return SLJIT_SUCCESS;
1745
1746 #endif
1747 }
1748
sljit_emit_fop1_cmp(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)1749 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
1750 sljit_s32 src1, sljit_sw src1w,
1751 sljit_s32 src2, sljit_sw src2w)
1752 {
1753 if (src1 & SLJIT_MEM) {
1754 FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));
1755 src1 = TMP_FREG1;
1756 }
1757
1758 if (src2 & SLJIT_MEM) {
1759 FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));
1760 src2 = TMP_FREG2;
1761 }
1762
1763 return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2));
1764 }
1765
sljit_emit_fop1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1766 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
1767 sljit_s32 dst, sljit_sw dstw,
1768 sljit_s32 src, sljit_sw srcw)
1769 {
1770 sljit_s32 dst_r;
1771
1772 CHECK_ERROR();
1773
1774 SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error);
1775 SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
1776
1777 if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
1778 op ^= SLJIT_F32_OP;
1779
1780 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1781
1782 if (src & SLJIT_MEM) {
1783 FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, TMP_REG1));
1784 src = dst_r;
1785 }
1786
1787 switch (GET_OPCODE(op)) {
1788 case SLJIT_CONV_F64_FROM_F32:
1789 op ^= SLJIT_F32_OP;
1790 if (op & SLJIT_F32_OP) {
1791 FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src)));
1792 break;
1793 }
1794 /* Fall through. */
1795 case SLJIT_MOV_F64:
1796 if (src != dst_r) {
1797 if (dst_r != TMP_FREG1)
1798 FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src)));
1799 else
1800 dst_r = src;
1801 }
1802 break;
1803 case SLJIT_NEG_F64:
1804 FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src)));
1805 break;
1806 case SLJIT_ABS_F64:
1807 FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src)));
1808 break;
1809 }
1810
1811 if (dst & SLJIT_MEM)
1812 FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), dst_r, dst, dstw, TMP_REG1));
1813 return SLJIT_SUCCESS;
1814 }
1815
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)1816 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
1817 sljit_s32 dst, sljit_sw dstw,
1818 sljit_s32 src1, sljit_sw src1w,
1819 sljit_s32 src2, sljit_sw src2w)
1820 {
1821 sljit_s32 dst_r;
1822
1823 CHECK_ERROR();
1824 CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
1825 ADJUST_LOCAL_OFFSET(dst, dstw);
1826 ADJUST_LOCAL_OFFSET(src1, src1w);
1827 ADJUST_LOCAL_OFFSET(src2, src2w);
1828
1829 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
1830
1831 if (src1 & SLJIT_MEM) {
1832 FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));
1833 src1 = TMP_FREG1;
1834 }
1835
1836 if (src2 & SLJIT_MEM) {
1837 FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));
1838 src2 = TMP_FREG2;
1839 }
1840
1841 switch (GET_OPCODE(op)) {
1842 case SLJIT_ADD_F64:
1843 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2)));
1844 break;
1845
1846 case SLJIT_SUB_F64:
1847 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2)));
1848 break;
1849
1850 case SLJIT_MUL_F64:
1851 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));
1852 break;
1853
1854 case SLJIT_DIV_F64:
1855 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2)));
1856 break;
1857 }
1858
1859 if (dst & SLJIT_MEM)
1860 FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, TMP_REG1));
1861
1862 return SLJIT_SUCCESS;
1863 }
1864
1865 #undef SELECT_FOP
1866
1867 /* --------------------------------------------------------------------- */
1868 /* Other instructions */
1869 /* --------------------------------------------------------------------- */
1870
sljit_emit_fast_enter(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)1871 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
1872 {
1873 CHECK_ERROR();
1874 CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
1875 ADJUST_LOCAL_OFFSET(dst, dstw);
1876
1877 if (FAST_IS_REG(dst))
1878 return push_inst(compiler, MFLR | D(dst));
1879
1880 /* Memory. */
1881 FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2)));
1882 return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
1883 }
1884
1885 /* --------------------------------------------------------------------- */
1886 /* Conditional instructions */
1887 /* --------------------------------------------------------------------- */
1888
sljit_emit_label(struct sljit_compiler * compiler)1889 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
1890 {
1891 struct sljit_label *label;
1892
1893 CHECK_ERROR_PTR();
1894 CHECK_PTR(check_sljit_emit_label(compiler));
1895
1896 if (compiler->last_label && compiler->last_label->size == compiler->size)
1897 return compiler->last_label;
1898
1899 label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
1900 PTR_FAIL_IF(!label);
1901 set_label(label, compiler);
1902 return label;
1903 }
1904
get_bo_bi_flags(sljit_s32 type)1905 static sljit_ins get_bo_bi_flags(sljit_s32 type)
1906 {
1907 switch (type) {
1908 case SLJIT_EQUAL:
1909 return (12 << 21) | (2 << 16);
1910
1911 case SLJIT_NOT_EQUAL:
1912 return (4 << 21) | (2 << 16);
1913
1914 case SLJIT_LESS:
1915 case SLJIT_SIG_LESS:
1916 return (12 << 21) | (0 << 16);
1917
1918 case SLJIT_GREATER_EQUAL:
1919 case SLJIT_SIG_GREATER_EQUAL:
1920 return (4 << 21) | (0 << 16);
1921
1922 case SLJIT_GREATER:
1923 case SLJIT_SIG_GREATER:
1924 return (12 << 21) | (1 << 16);
1925
1926 case SLJIT_LESS_EQUAL:
1927 case SLJIT_SIG_LESS_EQUAL:
1928 return (4 << 21) | (1 << 16);
1929
1930 case SLJIT_LESS_F64:
1931 return (12 << 21) | ((4 + 0) << 16);
1932
1933 case SLJIT_GREATER_EQUAL_F64:
1934 return (4 << 21) | ((4 + 0) << 16);
1935
1936 case SLJIT_GREATER_F64:
1937 return (12 << 21) | ((4 + 1) << 16);
1938
1939 case SLJIT_LESS_EQUAL_F64:
1940 return (4 << 21) | ((4 + 1) << 16);
1941
1942 case SLJIT_OVERFLOW:
1943 case SLJIT_MUL_OVERFLOW:
1944 return (12 << 21) | (3 << 16);
1945
1946 case SLJIT_NOT_OVERFLOW:
1947 case SLJIT_MUL_NOT_OVERFLOW:
1948 return (4 << 21) | (3 << 16);
1949
1950 case SLJIT_EQUAL_F64:
1951 return (12 << 21) | ((4 + 2) << 16);
1952
1953 case SLJIT_NOT_EQUAL_F64:
1954 return (4 << 21) | ((4 + 2) << 16);
1955
1956 case SLJIT_UNORDERED_F64:
1957 return (12 << 21) | ((4 + 3) << 16);
1958
1959 case SLJIT_ORDERED_F64:
1960 return (4 << 21) | ((4 + 3) << 16);
1961
1962 default:
1963 SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL_CDECL);
1964 return (20 << 21);
1965 }
1966 }
1967
sljit_emit_jump(struct sljit_compiler * compiler,sljit_s32 type)1968 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
1969 {
1970 struct sljit_jump *jump;
1971 sljit_ins bo_bi_flags;
1972
1973 CHECK_ERROR_PTR();
1974 CHECK_PTR(check_sljit_emit_jump(compiler, type));
1975
1976 bo_bi_flags = get_bo_bi_flags(type & 0xff);
1977 if (!bo_bi_flags)
1978 return NULL;
1979
1980 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
1981 PTR_FAIL_IF(!jump);
1982 set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
1983 type &= 0xff;
1984
1985 /* In PPC, we don't need to touch the arguments. */
1986 if (type < SLJIT_JUMP)
1987 jump->flags |= IS_COND;
1988 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
1989 if (type >= SLJIT_CALL)
1990 jump->flags |= IS_CALL;
1991 #endif
1992
1993 PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
1994 PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG)));
1995 jump->addr = compiler->size;
1996 PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));
1997 return jump;
1998 }
1999
sljit_emit_call(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types)2000 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
2001 sljit_s32 arg_types)
2002 {
2003 CHECK_ERROR_PTR();
2004 CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
2005
2006 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2007 PTR_FAIL_IF(call_with_args(compiler, arg_types, NULL));
2008 #endif
2009
2010 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2011 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2012 compiler->skip_checks = 1;
2013 #endif
2014
2015 return sljit_emit_jump(compiler, type);
2016 }
2017
sljit_emit_ijump(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src,sljit_sw srcw)2018 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
2019 {
2020 struct sljit_jump *jump = NULL;
2021 sljit_s32 src_r;
2022
2023 CHECK_ERROR();
2024 CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
2025 ADJUST_LOCAL_OFFSET(src, srcw);
2026
2027 if (FAST_IS_REG(src)) {
2028 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2029 if (type >= SLJIT_CALL) {
2030 FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
2031 src_r = TMP_CALL_REG;
2032 }
2033 else
2034 src_r = src;
2035 #else
2036 src_r = src;
2037 #endif
2038 } else if (src & SLJIT_IMM) {
2039 /* These jumps are converted to jump/call instructions when possible. */
2040 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2041 FAIL_IF(!jump);
2042 set_jump(jump, compiler, JUMP_ADDR);
2043 jump->u.target = srcw;
2044 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2045 if (type >= SLJIT_CALL)
2046 jump->flags |= IS_CALL;
2047 #endif
2048 FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
2049 src_r = TMP_CALL_REG;
2050 }
2051 else {
2052 FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
2053 src_r = TMP_CALL_REG;
2054 }
2055
2056 FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));
2057 if (jump)
2058 jump->addr = compiler->size;
2059 return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0));
2060 }
2061
sljit_emit_icall(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types,sljit_s32 src,sljit_sw srcw)2062 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
2063 sljit_s32 arg_types,
2064 sljit_s32 src, sljit_sw srcw)
2065 {
2066 CHECK_ERROR();
2067 CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
2068
2069 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2070 if (src & SLJIT_MEM) {
2071 ADJUST_LOCAL_OFFSET(src, srcw);
2072 FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
2073 src = TMP_CALL_REG;
2074 }
2075
2076 FAIL_IF(call_with_args(compiler, arg_types, &src));
2077 #endif
2078
2079 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2080 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2081 compiler->skip_checks = 1;
2082 #endif
2083
2084 return sljit_emit_ijump(compiler, type, src, srcw);
2085 }
2086
sljit_emit_op_flags(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 type)2087 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
2088 sljit_s32 dst, sljit_sw dstw,
2089 sljit_s32 type)
2090 {
2091 sljit_s32 reg, input_flags, cr_bit, invert;
2092 sljit_s32 saved_op = op;
2093 sljit_sw saved_dstw = dstw;
2094
2095 CHECK_ERROR();
2096 CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
2097 ADJUST_LOCAL_OFFSET(dst, dstw);
2098
2099 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2100 input_flags = (op & SLJIT_I32_OP) ? INT_DATA : WORD_DATA;
2101 #else
2102 input_flags = WORD_DATA;
2103 #endif
2104
2105 op = GET_OPCODE(op);
2106 reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
2107
2108 if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
2109 FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, dst, dstw, TMP_REG1));
2110
2111 invert = 0;
2112 cr_bit = 0;
2113
2114 switch (type & 0xff) {
2115 case SLJIT_LESS:
2116 case SLJIT_SIG_LESS:
2117 break;
2118
2119 case SLJIT_GREATER_EQUAL:
2120 case SLJIT_SIG_GREATER_EQUAL:
2121 invert = 1;
2122 break;
2123
2124 case SLJIT_GREATER:
2125 case SLJIT_SIG_GREATER:
2126 cr_bit = 1;
2127 break;
2128
2129 case SLJIT_LESS_EQUAL:
2130 case SLJIT_SIG_LESS_EQUAL:
2131 cr_bit = 1;
2132 invert = 1;
2133 break;
2134
2135 case SLJIT_EQUAL:
2136 cr_bit = 2;
2137 break;
2138
2139 case SLJIT_NOT_EQUAL:
2140 cr_bit = 2;
2141 invert = 1;
2142 break;
2143
2144 case SLJIT_OVERFLOW:
2145 case SLJIT_MUL_OVERFLOW:
2146 cr_bit = 3;
2147 break;
2148
2149 case SLJIT_NOT_OVERFLOW:
2150 case SLJIT_MUL_NOT_OVERFLOW:
2151 cr_bit = 3;
2152 invert = 1;
2153 break;
2154
2155 case SLJIT_LESS_F64:
2156 cr_bit = 4 + 0;
2157 break;
2158
2159 case SLJIT_GREATER_EQUAL_F64:
2160 cr_bit = 4 + 0;
2161 invert = 1;
2162 break;
2163
2164 case SLJIT_GREATER_F64:
2165 cr_bit = 4 + 1;
2166 break;
2167
2168 case SLJIT_LESS_EQUAL_F64:
2169 cr_bit = 4 + 1;
2170 invert = 1;
2171 break;
2172
2173 case SLJIT_EQUAL_F64:
2174 cr_bit = 4 + 2;
2175 break;
2176
2177 case SLJIT_NOT_EQUAL_F64:
2178 cr_bit = 4 + 2;
2179 invert = 1;
2180 break;
2181
2182 case SLJIT_UNORDERED_F64:
2183 cr_bit = 4 + 3;
2184 break;
2185
2186 case SLJIT_ORDERED_F64:
2187 cr_bit = 4 + 3;
2188 invert = 1;
2189 break;
2190
2191 default:
2192 SLJIT_UNREACHABLE();
2193 break;
2194 }
2195
2196 FAIL_IF(push_inst(compiler, MFCR | D(reg)));
2197 FAIL_IF(push_inst(compiler, RLWINM | S(reg) | A(reg) | ((1 + (cr_bit)) << 11) | (31 << 6) | (31 << 1)));
2198
2199 if (invert)
2200 FAIL_IF(push_inst(compiler, XORI | S(reg) | A(reg) | 0x1));
2201
2202 if (op < SLJIT_ADD) {
2203 if (!(dst & SLJIT_MEM))
2204 return SLJIT_SUCCESS;
2205 return emit_op_mem(compiler, input_flags, reg, dst, dstw, TMP_REG1);
2206 }
2207
2208 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2209 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2210 compiler->skip_checks = 1;
2211 #endif
2212 if (dst & SLJIT_MEM)
2213 return sljit_emit_op2(compiler, saved_op, dst, saved_dstw, TMP_REG1, 0, TMP_REG2, 0);
2214 return sljit_emit_op2(compiler, saved_op, dst, 0, dst, 0, TMP_REG2, 0);
2215 }
2216
sljit_emit_cmov(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_reg,sljit_s32 src,sljit_sw srcw)2217 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
2218 sljit_s32 dst_reg,
2219 sljit_s32 src, sljit_sw srcw)
2220 {
2221 CHECK_ERROR();
2222 CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
2223
2224 return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);;
2225 }
2226
sljit_emit_mem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 reg,sljit_s32 mem,sljit_sw memw)2227 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
2228 sljit_s32 reg,
2229 sljit_s32 mem, sljit_sw memw)
2230 {
2231 sljit_s32 mem_flags;
2232 sljit_ins inst;
2233
2234 CHECK_ERROR();
2235 CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
2236
2237 if (type & SLJIT_MEM_POST)
2238 return SLJIT_ERR_UNSUPPORTED;
2239
2240 switch (type & 0xff) {
2241 case SLJIT_MOV:
2242 case SLJIT_MOV_P:
2243 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
2244 case SLJIT_MOV_U32:
2245 case SLJIT_MOV_S32:
2246 #endif
2247 mem_flags = WORD_DATA;
2248 break;
2249
2250 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2251 case SLJIT_MOV_U32:
2252 mem_flags = INT_DATA;
2253 break;
2254
2255 case SLJIT_MOV_S32:
2256 mem_flags = INT_DATA;
2257
2258 if (!(type & SLJIT_MEM_STORE) && !(type & SLJIT_I32_OP)) {
2259 if (mem & OFFS_REG_MASK)
2260 mem_flags |= SIGNED_DATA;
2261 else
2262 return SLJIT_ERR_UNSUPPORTED;
2263 }
2264 break;
2265 #endif
2266
2267 case SLJIT_MOV_U8:
2268 case SLJIT_MOV_S8:
2269 mem_flags = BYTE_DATA;
2270 break;
2271
2272 case SLJIT_MOV_U16:
2273 mem_flags = HALF_DATA;
2274 break;
2275
2276 case SLJIT_MOV_S16:
2277 mem_flags = HALF_DATA | SIGNED_DATA;
2278 break;
2279
2280 default:
2281 SLJIT_UNREACHABLE();
2282 mem_flags = WORD_DATA;
2283 break;
2284 }
2285
2286 if (!(type & SLJIT_MEM_STORE))
2287 mem_flags |= LOAD_DATA;
2288
2289 if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
2290 if (memw != 0)
2291 return SLJIT_ERR_UNSUPPORTED;
2292
2293 if (type & SLJIT_MEM_SUPP)
2294 return SLJIT_SUCCESS;
2295
2296 inst = updated_data_transfer_insts[mem_flags | INDEXED];
2297 FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | B(OFFS_REG(mem))));
2298 }
2299 else {
2300 if (memw > SIMM_MAX || memw < SIMM_MIN)
2301 return SLJIT_ERR_UNSUPPORTED;
2302
2303 inst = updated_data_transfer_insts[mem_flags];
2304
2305 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2306 if ((inst & INT_ALIGNED) && (memw & 0x3) != 0)
2307 return SLJIT_ERR_UNSUPPORTED;
2308 #endif
2309
2310 if (type & SLJIT_MEM_SUPP)
2311 return SLJIT_SUCCESS;
2312
2313 FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | IMM(memw)));
2314 }
2315
2316 if ((mem_flags & LOAD_DATA) && (type & 0xff) == SLJIT_MOV_S8)
2317 return push_inst(compiler, EXTSB | S(reg) | A(reg));
2318 return SLJIT_SUCCESS;
2319 }
2320
sljit_emit_fmem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 mem,sljit_sw memw)2321 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
2322 sljit_s32 freg,
2323 sljit_s32 mem, sljit_sw memw)
2324 {
2325 sljit_s32 mem_flags;
2326 sljit_ins inst;
2327
2328 CHECK_ERROR();
2329 CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
2330
2331 if (type & SLJIT_MEM_POST)
2332 return SLJIT_ERR_UNSUPPORTED;
2333
2334 if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
2335 if (memw != 0)
2336 return SLJIT_ERR_UNSUPPORTED;
2337 }
2338 else {
2339 if (memw > SIMM_MAX || memw < SIMM_MIN)
2340 return SLJIT_ERR_UNSUPPORTED;
2341 }
2342
2343 if (type & SLJIT_MEM_SUPP)
2344 return SLJIT_SUCCESS;
2345
2346 mem_flags = FLOAT_DATA(type);
2347
2348 if (!(type & SLJIT_MEM_STORE))
2349 mem_flags |= LOAD_DATA;
2350
2351 if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
2352 inst = updated_data_transfer_insts[mem_flags | INDEXED];
2353 return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | B(OFFS_REG(mem)));
2354 }
2355
2356 inst = updated_data_transfer_insts[mem_flags];
2357 return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | IMM(memw));
2358 }
2359
sljit_emit_const(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw init_value)2360 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
2361 {
2362 struct sljit_const *const_;
2363 sljit_s32 dst_r;
2364
2365 CHECK_ERROR_PTR();
2366 CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
2367 ADJUST_LOCAL_OFFSET(dst, dstw);
2368
2369 const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
2370 PTR_FAIL_IF(!const_);
2371 set_const(const_, compiler);
2372
2373 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
2374 PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
2375
2376 if (dst & SLJIT_MEM)
2377 PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
2378
2379 return const_;
2380 }
2381
sljit_emit_put_label(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)2382 SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
2383 {
2384 struct sljit_put_label *put_label;
2385 sljit_s32 dst_r;
2386
2387 CHECK_ERROR_PTR();
2388 CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
2389 ADJUST_LOCAL_OFFSET(dst, dstw);
2390
2391 put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
2392 PTR_FAIL_IF(!put_label);
2393 set_put_label(put_label, compiler, 0);
2394
2395 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
2396 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
2397 PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
2398 #else
2399 PTR_FAIL_IF(push_inst(compiler, dst_r));
2400 compiler->size += 4;
2401 #endif
2402
2403 if (dst & SLJIT_MEM)
2404 PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
2405
2406 return put_label;
2407 }
2408