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