NCBI C++ ToolKit
sljitNativePPC_common.c
Go to the documentation of this file.

Go to the SVN repository for this file.

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