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