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