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