1 /*
2  *    Stack-less Just-In-Time compiler
3  *
4  *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without modification, are
7  * permitted provided that the following conditions are met:
8  *
9  *   1. Redistributions of source code must retain the above copyright notice, this list of
10  *      conditions and the following disclaimer.
11  *
12  *   2. Redistributions in binary form must reproduce the above copyright notice, this list
13  *      of conditions and the following disclaimer in the documentation and/or other materials
14  *      provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19  * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
sljit_get_platform_name(void)27 SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
28 {
29 	return "PowerPC" SLJIT_CPUINFO;
30 }
31 
32 /* Length of an instruction word.
33    Both for ppc-32 and ppc-64. */
34 typedef sljit_u32 sljit_ins;
35 
36 #if ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && (defined _AIX)) \
37 	|| (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
38 #define SLJIT_PPC_STACK_FRAME_V2 1
39 #endif
40 
41 #ifdef _AIX
42 #include <sys/cache.h>
43 #endif
44 
45 #if (defined _CALL_ELF && _CALL_ELF == 2)
46 #define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1
47 #endif
48 
49 #if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL)
50 
ppc_cache_flush(sljit_ins * from,sljit_ins * to)51 static void ppc_cache_flush(sljit_ins *from, sljit_ins *to)
52 {
53 #ifdef _AIX
54 	_sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from));
55 #elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
56 #	if defined(_ARCH_PWR) || defined(_ARCH_PWR2)
57 	/* Cache flush for POWER architecture. */
58 	while (from < to) {
59 		__asm__ volatile (
60 			"clf 0, %0\n"
61 			"dcs\n"
62 			: : "r"(from)
63 		);
64 		from++;
65 	}
66 	__asm__ volatile ( "ics" );
67 #	elif defined(_ARCH_COM) && !defined(_ARCH_PPC)
68 #	error "Cache flush is not implemented for PowerPC/POWER common mode."
69 #	else
70 	/* Cache flush for PowerPC architecture. */
71 	while (from < to) {
72 		__asm__ volatile (
73 			"dcbf 0, %0\n"
74 			"sync\n"
75 			"icbi 0, %0\n"
76 			: : "r"(from)
77 		);
78 		from++;
79 	}
80 	__asm__ volatile ( "isync" );
81 #	endif
82 #	ifdef __xlc__
83 #	warning "This file may fail to compile if -qfuncsect is used"
84 #	endif
85 #elif defined(__xlc__)
86 #error "Please enable GCC syntax for inline assembly statements with -qasm=gcc"
87 #else
88 #error "This platform requires a cache flush implementation."
89 #endif /* _AIX */
90 }
91 
92 #endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */
93 
94 #define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)
95 #define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)
96 #define TMP_ZERO	(SLJIT_NUMBER_OF_REGISTERS + 4)
97 
98 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
99 #define TMP_CALL_REG	(SLJIT_NUMBER_OF_REGISTERS + 5)
100 #else
101 #define TMP_CALL_REG	TMP_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)
sljit_set_function_context(void ** func_ptr,struct sljit_function_context * context,sljit_uw addr,void * func)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 
push_inst(struct sljit_compiler * compiler,sljit_ins ins)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 
detect_jump_type(struct sljit_jump * jump,sljit_ins * code_ptr,sljit_ins * code,sljit_sw executable_offset)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 
mov_addr_get_length(struct sljit_jump * jump,sljit_ins * code,sljit_sw executable_offset)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 
generate_jump_or_mov_addr(struct sljit_jump * jump,sljit_sw executable_offset)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 
reduce_code_size(struct sljit_compiler * compiler)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;
501 	sljit_uw total_size;
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 
sljit_generate_code(struct sljit_compiler * compiler,sljit_s32 options,void * exec_allocator_data)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);
616 	PTR_FAIL_WITH_EXEC_IF(code);
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 
687 	SLJIT_ASSERT(!label);
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 
sljit_has_cpu_feature(sljit_s32 feature_type)730 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
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. */
747 	case SLJIT_HAS_ZERO_REGISTER:
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 
sljit_cmp_info(sljit_s32 type)761 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
762 {
763 	switch (type) {
764 	case SLJIT_UNORDERED_OR_EQUAL:
765 	case SLJIT_ORDERED_NOT_EQUAL:
766 	case SLJIT_UNORDERED_OR_LESS:
767 	case SLJIT_ORDERED_GREATER_EQUAL:
768 	case SLJIT_UNORDERED_OR_GREATER:
769 	case SLJIT_ORDERED_LESS_EQUAL:
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 
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)847 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
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 
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)964 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
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 
emit_stack_frame_release(struct sljit_compiler * compiler,sljit_s32 is_return_to)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 
987 	SLJIT_ASSERT(TMP_CALL_REG != TMP_REG2);
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 
sljit_emit_return_void(struct sljit_compiler * compiler)1045 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
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 
sljit_emit_return_to(struct sljit_compiler * compiler,sljit_s32 src,sljit_sw srcw)1054 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
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 
1168 static const sljit_ins updated_data_transfer_insts[64] = {
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). */
emit_op_mem(struct sljit_compiler * compiler,sljit_s32 inp_flags,sljit_s32 reg,sljit_s32 arg,sljit_sw argw,sljit_s32 tmp_reg)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 
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)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;
1306 	sljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_SIGN_EXT | ALT_SET_FLAGS);
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 
sljit_emit_op0(struct sljit_compiler * compiler,sljit_s32 op)1360 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
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:
1403 	case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
1404 		return SLJIT_SUCCESS;
1405 	}
1406 
1407 	return SLJIT_SUCCESS;
1408 }
1409 
emit_rev(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)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 
sljit_emit_op1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1566 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
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:
1621 		return EMIT_MOV(SLJIT_MOV_U32, INT_DATA, (sljit_u32));
1622 
1623 	case SLJIT_MOV_S32:
1624 	case SLJIT_MOV32:
1625 		return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, (sljit_s32));
1626 #endif
1627 
1628 	case SLJIT_MOV_U8:
1629 		return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA, (sljit_u8));
1630 
1631 	case SLJIT_MOV_S8:
1632 		return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, (sljit_s8));
1633 
1634 	case SLJIT_MOV_U16:
1635 		return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA, (sljit_u16));
1636 
1637 	case SLJIT_MOV_S16:
1638 		return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (sljit_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 
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)1709 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
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 
sljit_emit_op2u(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)1951 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
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 
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)1966 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
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 
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)1984 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
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 
emit_prefetch(struct sljit_compiler * compiler,sljit_s32 src,sljit_sw srcw)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 
sljit_emit_op_src(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)2093 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
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);
2110 	case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
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 
sljit_emit_op_dst(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw)2122 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,
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;
2138 	case SLJIT_GET_RETURN_ADDRESS:
2139 		dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
2140 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size + LR_SAVE_OFFSET, TMP_REG2));
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 
sljit_get_register_index(sljit_s32 type,sljit_s32 reg)2150 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)
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 
sljit_emit_op_custom(struct sljit_compiler * compiler,void * instruction,sljit_u32 size)2163 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
2164 	void *instruction, sljit_u32 size)
2165 {
2166 	SLJIT_UNUSED_ARG(size);
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 
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)2180 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
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)) {
2206 		FAIL_IF(load_immediate(compiler, TMP_REG1, TMP_MEM_OFFSET));
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 
sljit_emit_fop1_cmp(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2235 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
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)) {
2252 	case SLJIT_UNORDERED_OR_EQUAL:
2253 		return push_inst(compiler, CROR | ((4 + 2) << 21) | ((4 + 2) << 16) | ((4 + 3) << 11));
2254 	case SLJIT_UNORDERED_OR_LESS:
2255 		return push_inst(compiler, CROR | ((4 + 0) << 21) | ((4 + 0) << 16) | ((4 + 3) << 11));
2256 	case SLJIT_UNORDERED_OR_GREATER:
2257 		return push_inst(compiler, CROR | ((4 + 1) << 21) | ((4 + 1) << 16) | ((4 + 3) << 11));
2258 	}
2259 
2260 	return SLJIT_SUCCESS;
2261 }
2262 
sljit_emit_fop1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)2263 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
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)) {
2285 	case SLJIT_CONV_F64_FROM_F32:
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 
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)2313 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
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 
sljit_emit_fset32(struct sljit_compiler * compiler,sljit_s32 freg,sljit_f32 value)2376 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,
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 
sljit_emit_label(struct sljit_compiler * compiler)2400 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
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 
get_bo_bi_flags(struct sljit_compiler * compiler,sljit_s32 type)2416 static sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, sljit_s32 type)
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:
2440 	case SLJIT_SIG_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:
2459 	case SLJIT_UNORDERED_OR_LESS:
2460 		return (12 << 21) | ((4 + 0) << 16);
2461 
2462 	case SLJIT_F_GREATER_EQUAL:
2463 	case SLJIT_ORDERED_GREATER_EQUAL:
2464 	case SLJIT_UNORDERED_OR_GREATER_EQUAL:
2465 		return (4 << 21) | ((4 + 0) << 16);
2466 
2467 	case SLJIT_F_GREATER:
2468 	case SLJIT_ORDERED_GREATER:
2469 	case SLJIT_UNORDERED_OR_GREATER:
2470 		return (12 << 21) | ((4 + 1) << 16);
2471 
2472 	case SLJIT_F_LESS_EQUAL:
2473 	case SLJIT_ORDERED_LESS_EQUAL:
2474 	case SLJIT_UNORDERED_OR_LESS_EQUAL:
2475 		return (4 << 21) | ((4 + 1) << 16);
2476 
2477 	case SLJIT_F_EQUAL:
2478 	case SLJIT_ORDERED_EQUAL:
2479 	case SLJIT_UNORDERED_OR_EQUAL:
2480 		return (12 << 21) | ((4 + 2) << 16);
2481 
2482 	case SLJIT_F_NOT_EQUAL:
2483 	case SLJIT_ORDERED_NOT_EQUAL:
2484 	case SLJIT_UNORDERED_OR_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:
2494 		SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL_REG_ARG);
2495 		return (20 << 21);
2496 	}
2497 }
2498 
sljit_emit_jump(struct sljit_compiler * compiler,sljit_s32 type)2499 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
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)
2517 		PTR_FAIL_IF(push_inst(compiler, ADDE | RC(ALT_SET_FLAGS) | D(TMP_REG2) | A(TMP_ZERO) | B(TMP_ZERO)));
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 
sljit_emit_call(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types)2535 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
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));
2550 		type = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);
2551 	}
2552 
2553 	SLJIT_SKIP_CHECKS(compiler);
2554 	return sljit_emit_jump(compiler, type);
2555 }
2556 
sljit_emit_ijump(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src,sljit_sw srcw)2557 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
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 
sljit_emit_icall(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types,sljit_s32 src,sljit_sw srcw)2605 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
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 
sljit_emit_op_flags(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 type)2639 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
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:
2673 	case SLJIT_SIG_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:
2722 	case SLJIT_UNORDERED_OR_LESS:
2723 		bit = 4 + 0;
2724 		break;
2725 
2726 	case SLJIT_F_GREATER_EQUAL:
2727 	case SLJIT_ORDERED_GREATER_EQUAL:
2728 	case SLJIT_UNORDERED_OR_GREATER_EQUAL:
2729 		bit = 4 + 0;
2730 		invert = 1;
2731 		break;
2732 
2733 	case SLJIT_F_GREATER:
2734 	case SLJIT_ORDERED_GREATER:
2735 	case SLJIT_UNORDERED_OR_GREATER:
2736 		bit = 4 + 1;
2737 		break;
2738 
2739 	case SLJIT_F_LESS_EQUAL:
2740 	case SLJIT_ORDERED_LESS_EQUAL:
2741 	case SLJIT_UNORDERED_OR_LESS_EQUAL:
2742 		bit = 4 + 1;
2743 		invert = 1;
2744 		break;
2745 
2746 	case SLJIT_F_EQUAL:
2747 	case SLJIT_ORDERED_EQUAL:
2748 	case SLJIT_UNORDERED_OR_EQUAL:
2749 		bit = 4 + 2;
2750 		break;
2751 
2752 	case SLJIT_F_NOT_EQUAL:
2753 	case SLJIT_ORDERED_NOT_EQUAL:
2754 	case SLJIT_UNORDERED_OR_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:
2769 		SLJIT_UNREACHABLE();
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 
sljit_emit_select(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_reg,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2_reg)2793 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,
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 
sljit_emit_fselect(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_freg,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2_freg)2855 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,
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 
sljit_emit_mem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 reg,sljit_s32 mem,sljit_sw memw)2909 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
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 
2923 	inst = data_transfer_insts[WORD_DATA | ((type & SLJIT_MEM_STORE) ? 0 : LOAD_DATA)];
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 
sljit_emit_mem_update(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 reg,sljit_s32 mem,sljit_sw memw)2974 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
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:
3030 		SLJIT_UNREACHABLE();
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 
sljit_emit_fmem_update(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 mem,sljit_sw memw)3070 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,
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 
sljit_emit_const(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw init_value)3109 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
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 
sljit_emit_mov_addr(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)3131 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
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 
sljit_set_const(sljit_uw addr,sljit_sw new_constant,sljit_sw executable_offset)3158 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
3159 {
3160 	sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
3161 }
3162