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