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 
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)1327 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
1328 	sljit_s32 dst, sljit_sw dstw,
1329 	sljit_s32 src1, sljit_sw src1w,
1330 	sljit_s32 src2, sljit_sw src2w)
1331 {
1332 	sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;
1333 
1334 	CHECK_ERROR();
1335 	CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
1336 	ADJUST_LOCAL_OFFSET(dst, dstw);
1337 	ADJUST_LOCAL_OFFSET(src1, src1w);
1338 	ADJUST_LOCAL_OFFSET(src2, src2w);
1339 
1340 	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
1341 		return SLJIT_SUCCESS;
1342 
1343 	if ((src1 & SLJIT_IMM) && src1w == 0)
1344 		src1 = TMP_ZERO;
1345 	if ((src2 & SLJIT_IMM) && src2w == 0)
1346 		src2 = TMP_ZERO;
1347 
1348 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1349 	if (op & SLJIT_I32_OP) {
1350 		/* Most operations expect sign extended arguments. */
1351 		flags |= INT_DATA | SIGNED_DATA;
1352 		if (src1 & SLJIT_IMM)
1353 			src1w = (sljit_s32)(src1w);
1354 		if (src2 & SLJIT_IMM)
1355 			src2w = (sljit_s32)(src2w);
1356 		if (HAS_FLAGS(op))
1357 			flags |= ALT_SIGN_EXT;
1358 	}
1359 #endif
1360 	if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1361 		FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
1362 
1363 	switch (GET_OPCODE(op)) {
1364 	case SLJIT_ADD:
1365 		if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1366 			return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);
1367 
1368 		if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
1369 			if (TEST_SL_IMM(src2, src2w)) {
1370 				compiler->imm = src2w & 0xffff;
1371 				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1372 			}
1373 			if (TEST_SL_IMM(src1, src1w)) {
1374 				compiler->imm = src1w & 0xffff;
1375 				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
1376 			}
1377 			if (TEST_SH_IMM(src2, src2w)) {
1378 				compiler->imm = (src2w >> 16) & 0xffff;
1379 				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1380 			}
1381 			if (TEST_SH_IMM(src1, src1w)) {
1382 				compiler->imm = (src1w >> 16) & 0xffff;
1383 				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1384 			}
1385 			/* Range between -1 and -32768 is covered above. */
1386 			if (TEST_ADD_IMM(src2, src2w)) {
1387 				compiler->imm = src2w & 0xffffffff;
1388 				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
1389 			}
1390 			if (TEST_ADD_IMM(src1, src1w)) {
1391 				compiler->imm = src1w & 0xffffffff;
1392 				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);
1393 			}
1394 		}
1395 		if (HAS_FLAGS(op)) {
1396 			if (TEST_SL_IMM(src2, src2w)) {
1397 				compiler->imm = src2w & 0xffff;
1398 				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1399 			}
1400 			if (TEST_SL_IMM(src1, src1w)) {
1401 				compiler->imm = src1w & 0xffff;
1402 				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1403 			}
1404 		}
1405 		return emit_op(compiler, SLJIT_ADD, flags | ((GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)) ? ALT_FORM4 : 0), dst, dstw, src1, src1w, src2, src2w);
1406 
1407 	case SLJIT_ADDC:
1408 		return emit_op(compiler, SLJIT_ADDC, flags, dst, dstw, src1, src1w, src2, src2w);
1409 
1410 	case SLJIT_SUB:
1411 		if (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_LESS_EQUAL) {
1412 			if (dst == SLJIT_UNUSED) {
1413 				if (TEST_UL_IMM(src2, src2w)) {
1414 					compiler->imm = src2w & 0xffff;
1415 					return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1416 				}
1417 				return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);
1418 			}
1419 
1420 			if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= (SIMM_MAX + 1)) {
1421 				compiler->imm = src2w;
1422 				return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1423 			}
1424 			return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM3, dst, dstw, src1, src1w, src2, src2w);
1425 		}
1426 
1427 		if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
1428 			return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, src2, src2w);
1429 
1430 		if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
1431 			if (TEST_SL_IMM(src2, -src2w)) {
1432 				compiler->imm = (-src2w) & 0xffff;
1433 				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1434 			}
1435 			if (TEST_SL_IMM(src1, src1w)) {
1436 				compiler->imm = src1w & 0xffff;
1437 				return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1438 			}
1439 			if (TEST_SH_IMM(src2, -src2w)) {
1440 				compiler->imm = ((-src2w) >> 16) & 0xffff;
1441 				return emit_op(compiler, SLJIT_ADD, flags |  ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1442 			}
1443 			/* Range between -1 and -32768 is covered above. */
1444 			if (TEST_ADD_IMM(src2, -src2w)) {
1445 				compiler->imm = -src2w & 0xffffffff;
1446 				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
1447 			}
1448 		}
1449 
1450 		if (dst == SLJIT_UNUSED && GET_FLAG_TYPE(op) != GET_FLAG_TYPE(SLJIT_SET_CARRY)) {
1451 			if (TEST_SL_IMM(src2, src2w)) {
1452 				compiler->imm = src2w & 0xffff;
1453 				return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4 | ALT_FORM5, dst, dstw, src1, src1w, TMP_REG2, 0);
1454 			}
1455 			return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
1456 		}
1457 
1458 		if (TEST_SL_IMM(src2, -src2w)) {
1459 			compiler->imm = (-src2w) & 0xffff;
1460 			return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1461 		}
1462 		/* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */
1463 		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);
1464 
1465 	case SLJIT_SUBC:
1466 		return emit_op(compiler, SLJIT_SUBC, flags, dst, dstw, src1, src1w, src2, src2w);
1467 
1468 	case SLJIT_MUL:
1469 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1470 		if (op & SLJIT_I32_OP)
1471 			flags |= ALT_FORM2;
1472 #endif
1473 		if (!HAS_FLAGS(op)) {
1474 			if (TEST_SL_IMM(src2, src2w)) {
1475 				compiler->imm = src2w & 0xffff;
1476 				return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1477 			}
1478 			if (TEST_SL_IMM(src1, src1w)) {
1479 				compiler->imm = src1w & 0xffff;
1480 				return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1481 			}
1482 		}
1483 		else
1484 			FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
1485 		return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w);
1486 
1487 	case SLJIT_AND:
1488 	case SLJIT_OR:
1489 	case SLJIT_XOR:
1490 		/* Commutative unsigned operations. */
1491 		if (!HAS_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) {
1492 			if (TEST_UL_IMM(src2, src2w)) {
1493 				compiler->imm = src2w;
1494 				return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1495 			}
1496 			if (TEST_UL_IMM(src1, src1w)) {
1497 				compiler->imm = src1w;
1498 				return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1499 			}
1500 			if (TEST_UH_IMM(src2, src2w)) {
1501 				compiler->imm = (src2w >> 16) & 0xffff;
1502 				return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1503 			}
1504 			if (TEST_UH_IMM(src1, src1w)) {
1505 				compiler->imm = (src1w >> 16) & 0xffff;
1506 				return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
1507 			}
1508 		}
1509 		if (GET_OPCODE(op) != SLJIT_AND && GET_OPCODE(op) != SLJIT_AND) {
1510 			/* Unlike or and xor, and resets unwanted bits as well. */
1511 			if (TEST_UI_IMM(src2, src2w)) {
1512 				compiler->imm = src2w;
1513 				return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1514 			}
1515 			if (TEST_UI_IMM(src1, src1w)) {
1516 				compiler->imm = src1w;
1517 				return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1518 			}
1519 		}
1520 		return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
1521 
1522 	case SLJIT_SHL:
1523 	case SLJIT_LSHR:
1524 	case SLJIT_ASHR:
1525 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1526 		if (op & SLJIT_I32_OP)
1527 			flags |= ALT_FORM2;
1528 #endif
1529 		if (src2 & SLJIT_IMM) {
1530 			compiler->imm = src2w;
1531 			return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1532 		}
1533 		return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
1534 	}
1535 
1536 	return SLJIT_SUCCESS;
1537 }
1538 
sljit_emit_op_src(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)1539 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
1540 	sljit_s32 src, sljit_sw srcw)
1541 {
1542 	CHECK_ERROR();
1543 	CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
1544 	ADJUST_LOCAL_OFFSET(src, srcw);
1545 
1546 	switch (op) {
1547 	case SLJIT_FAST_RETURN:
1548 		if (FAST_IS_REG(src))
1549 			FAIL_IF(push_inst(compiler, MTLR | S(src)));
1550 		else {
1551 			FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
1552 			FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
1553 		}
1554 
1555 		return push_inst(compiler, BLR);
1556 	case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
1557 		return SLJIT_SUCCESS;
1558 	case SLJIT_PREFETCH_L1:
1559 	case SLJIT_PREFETCH_L2:
1560 	case SLJIT_PREFETCH_L3:
1561 	case SLJIT_PREFETCH_ONCE:
1562 		return emit_prefetch(compiler, src, srcw);
1563 	}
1564 
1565 	return SLJIT_SUCCESS;
1566 }
1567 
sljit_get_register_index(sljit_s32 reg)1568 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
1569 {
1570 	CHECK_REG_INDEX(check_sljit_get_register_index(reg));
1571 	return reg_map[reg];
1572 }
1573 
sljit_get_float_register_index(sljit_s32 reg)1574 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
1575 {
1576 	CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
1577 	return freg_map[reg];
1578 }
1579 
sljit_emit_op_custom(struct sljit_compiler * compiler,void * instruction,sljit_s32 size)1580 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
1581 	void *instruction, sljit_s32 size)
1582 {
1583 	CHECK_ERROR();
1584 	CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
1585 
1586 	return push_inst(compiler, *(sljit_ins*)instruction);
1587 }
1588 
1589 /* --------------------------------------------------------------------- */
1590 /*  Floating point operators                                             */
1591 /* --------------------------------------------------------------------- */
1592 
1593 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 6))
1594 #define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)
1595 
1596 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1597 #define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw))
1598 #else
1599 #define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw))
1600 
1601 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
1602 #define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw))
1603 #define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw))
1604 #else
1605 #define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw))
1606 #define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw))
1607 #endif
1608 
1609 #endif /* SLJIT_CONFIG_PPC_64 */
1610 
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)1611 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
1612 	sljit_s32 dst, sljit_sw dstw,
1613 	sljit_s32 src, sljit_sw srcw)
1614 {
1615 	if (src & SLJIT_MEM) {
1616 		/* We can ignore the temporary data store on the stack from caching point of view. */
1617 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));
1618 		src = TMP_FREG1;
1619 	}
1620 
1621 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1622 	op = GET_OPCODE(op);
1623 	FAIL_IF(push_inst(compiler, (op == SLJIT_CONV_S32_FROM_F64 ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src)));
1624 
1625 	if (op == SLJIT_CONV_SW_FROM_F64) {
1626 		if (FAST_IS_REG(dst)) {
1627 			FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1628 			return emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1);
1629 		}
1630 		return emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, TMP_REG1);
1631 	}
1632 #else
1633 	FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src)));
1634 #endif
1635 
1636 	if (FAST_IS_REG(dst)) {
1637 		FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET));
1638 		FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1)));
1639 		return emit_op_mem(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1);
1640 	}
1641 
1642 	SLJIT_ASSERT(dst & SLJIT_MEM);
1643 
1644 	if (dst & OFFS_REG_MASK) {
1645 		dstw &= 0x3;
1646 		if (dstw) {
1647 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1648 			FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(dst)) | A(TMP_REG1) | (dstw << 11) | ((31 - dstw) << 1)));
1649 #else
1650 			FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(dst), dstw, 63 - dstw, 1)));
1651 #endif
1652 			dstw = TMP_REG1;
1653 		}
1654 		else
1655 			dstw = OFFS_REG(dst);
1656 	}
1657 	else {
1658 		if ((dst & REG_MASK) && !dstw) {
1659 			dstw = dst & REG_MASK;
1660 			dst = 0;
1661 		}
1662 		else {
1663 			/* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */
1664 			FAIL_IF(load_immediate(compiler, TMP_REG1, dstw));
1665 			dstw = TMP_REG1;
1666 		}
1667 	}
1668 
1669 	return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw));
1670 }
1671 
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)1672 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
1673 	sljit_s32 dst, sljit_sw dstw,
1674 	sljit_s32 src, sljit_sw srcw)
1675 {
1676 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1677 
1678 	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1679 
1680 	if (src & SLJIT_IMM) {
1681 		if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
1682 			srcw = (sljit_s32)srcw;
1683 		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
1684 		src = TMP_REG1;
1685 	}
1686 	else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) {
1687 		if (FAST_IS_REG(src))
1688 			FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1)));
1689 		else
1690 			FAIL_IF(emit_op_mem(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
1691 		src = TMP_REG1;
1692 	}
1693 
1694 	if (FAST_IS_REG(src)) {
1695 		FAIL_IF(emit_op_mem(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1696 		FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1697 	}
1698 	else
1699 		FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));
1700 
1701 	FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
1702 
1703 	if (dst & SLJIT_MEM)
1704 		return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
1705 	if (op & SLJIT_F32_OP)
1706 		return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
1707 	return SLJIT_SUCCESS;
1708 
1709 #else
1710 
1711 	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1712 	sljit_s32 invert_sign = 1;
1713 
1714 	if (src & SLJIT_IMM) {
1715 		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000));
1716 		src = TMP_REG1;
1717 		invert_sign = 0;
1718 	}
1719 	else if (!FAST_IS_REG(src)) {
1720 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
1721 		src = TMP_REG1;
1722 	}
1723 
1724 	/* First, a special double floating point value is constructed: (2^53 + (input xor (2^31)))
1725 	   The double precision format has exactly 53 bit precision, so the lower 32 bit represents
1726 	   the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000
1727 	   to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating
1728 	   point value, we need to substract 2^53 + 2^31 from the constructed value. */
1729 	FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
1730 	if (invert_sign)
1731 		FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000));
1732 	FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, TMP_REG1));
1733 	FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2));
1734 	FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000));
1735 	FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1736 	FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2));
1737 	FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1738 
1739 	FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
1740 
1741 	if (dst & SLJIT_MEM)
1742 		return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
1743 	if (op & SLJIT_F32_OP)
1744 		return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
1745 	return SLJIT_SUCCESS;
1746 
1747 #endif
1748 }
1749 
sljit_emit_fop1_cmp(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)1750 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
1751 	sljit_s32 src1, sljit_sw src1w,
1752 	sljit_s32 src2, sljit_sw src2w)
1753 {
1754 	if (src1 & SLJIT_MEM) {
1755 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));
1756 		src1 = TMP_FREG1;
1757 	}
1758 
1759 	if (src2 & SLJIT_MEM) {
1760 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));
1761 		src2 = TMP_FREG2;
1762 	}
1763 
1764 	return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2));
1765 }
1766 
sljit_emit_fop1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1767 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
1768 	sljit_s32 dst, sljit_sw dstw,
1769 	sljit_s32 src, sljit_sw srcw)
1770 {
1771 	sljit_s32 dst_r;
1772 
1773 	CHECK_ERROR();
1774 
1775 	SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error);
1776 	SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
1777 
1778 	if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
1779 		op ^= SLJIT_F32_OP;
1780 
1781 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1782 
1783 	if (src & SLJIT_MEM) {
1784 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, TMP_REG1));
1785 		src = dst_r;
1786 	}
1787 
1788 	switch (GET_OPCODE(op)) {
1789 	case SLJIT_CONV_F64_FROM_F32:
1790 		op ^= SLJIT_F32_OP;
1791 		if (op & SLJIT_F32_OP) {
1792 			FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src)));
1793 			break;
1794 		}
1795 		/* Fall through. */
1796 	case SLJIT_MOV_F64:
1797 		if (src != dst_r) {
1798 			if (dst_r != TMP_FREG1)
1799 				FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src)));
1800 			else
1801 				dst_r = src;
1802 		}
1803 		break;
1804 	case SLJIT_NEG_F64:
1805 		FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src)));
1806 		break;
1807 	case SLJIT_ABS_F64:
1808 		FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src)));
1809 		break;
1810 	}
1811 
1812 	if (dst & SLJIT_MEM)
1813 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), dst_r, dst, dstw, TMP_REG1));
1814 	return SLJIT_SUCCESS;
1815 }
1816 
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)1817 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
1818 	sljit_s32 dst, sljit_sw dstw,
1819 	sljit_s32 src1, sljit_sw src1w,
1820 	sljit_s32 src2, sljit_sw src2w)
1821 {
1822 	sljit_s32 dst_r;
1823 
1824 	CHECK_ERROR();
1825 	CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
1826 	ADJUST_LOCAL_OFFSET(dst, dstw);
1827 	ADJUST_LOCAL_OFFSET(src1, src1w);
1828 	ADJUST_LOCAL_OFFSET(src2, src2w);
1829 
1830 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
1831 
1832 	if (src1 & SLJIT_MEM) {
1833 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));
1834 		src1 = TMP_FREG1;
1835 	}
1836 
1837 	if (src2 & SLJIT_MEM) {
1838 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));
1839 		src2 = TMP_FREG2;
1840 	}
1841 
1842 	switch (GET_OPCODE(op)) {
1843 	case SLJIT_ADD_F64:
1844 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2)));
1845 		break;
1846 
1847 	case SLJIT_SUB_F64:
1848 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2)));
1849 		break;
1850 
1851 	case SLJIT_MUL_F64:
1852 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));
1853 		break;
1854 
1855 	case SLJIT_DIV_F64:
1856 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2)));
1857 		break;
1858 	}
1859 
1860 	if (dst & SLJIT_MEM)
1861 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, TMP_REG1));
1862 
1863 	return SLJIT_SUCCESS;
1864 }
1865 
1866 #undef SELECT_FOP
1867 
1868 /* --------------------------------------------------------------------- */
1869 /*  Other instructions                                                   */
1870 /* --------------------------------------------------------------------- */
1871 
sljit_emit_fast_enter(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)1872 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
1873 {
1874 	CHECK_ERROR();
1875 	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
1876 	ADJUST_LOCAL_OFFSET(dst, dstw);
1877 
1878 	if (FAST_IS_REG(dst))
1879 		return push_inst(compiler, MFLR | D(dst));
1880 
1881 	/* Memory. */
1882 	FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2)));
1883 	return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
1884 }
1885 
1886 /* --------------------------------------------------------------------- */
1887 /*  Conditional instructions                                             */
1888 /* --------------------------------------------------------------------- */
1889 
sljit_emit_label(struct sljit_compiler * compiler)1890 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
1891 {
1892 	struct sljit_label *label;
1893 
1894 	CHECK_ERROR_PTR();
1895 	CHECK_PTR(check_sljit_emit_label(compiler));
1896 
1897 	if (compiler->last_label && compiler->last_label->size == compiler->size)
1898 		return compiler->last_label;
1899 
1900 	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
1901 	PTR_FAIL_IF(!label);
1902 	set_label(label, compiler);
1903 	return label;
1904 }
1905 
get_bo_bi_flags(sljit_s32 type)1906 static sljit_ins get_bo_bi_flags(sljit_s32 type)
1907 {
1908 	switch (type) {
1909 	case SLJIT_EQUAL:
1910 		return (12 << 21) | (2 << 16);
1911 
1912 	case SLJIT_NOT_EQUAL:
1913 		return (4 << 21) | (2 << 16);
1914 
1915 	case SLJIT_LESS:
1916 	case SLJIT_SIG_LESS:
1917 		return (12 << 21) | (0 << 16);
1918 
1919 	case SLJIT_GREATER_EQUAL:
1920 	case SLJIT_SIG_GREATER_EQUAL:
1921 		return (4 << 21) | (0 << 16);
1922 
1923 	case SLJIT_GREATER:
1924 	case SLJIT_SIG_GREATER:
1925 		return (12 << 21) | (1 << 16);
1926 
1927 	case SLJIT_LESS_EQUAL:
1928 	case SLJIT_SIG_LESS_EQUAL:
1929 		return (4 << 21) | (1 << 16);
1930 
1931 	case SLJIT_LESS_F64:
1932 		return (12 << 21) | ((4 + 0) << 16);
1933 
1934 	case SLJIT_GREATER_EQUAL_F64:
1935 		return (4 << 21) | ((4 + 0) << 16);
1936 
1937 	case SLJIT_GREATER_F64:
1938 		return (12 << 21) | ((4 + 1) << 16);
1939 
1940 	case SLJIT_LESS_EQUAL_F64:
1941 		return (4 << 21) | ((4 + 1) << 16);
1942 
1943 	case SLJIT_OVERFLOW:
1944 	case SLJIT_MUL_OVERFLOW:
1945 		return (12 << 21) | (3 << 16);
1946 
1947 	case SLJIT_NOT_OVERFLOW:
1948 	case SLJIT_MUL_NOT_OVERFLOW:
1949 		return (4 << 21) | (3 << 16);
1950 
1951 	case SLJIT_EQUAL_F64:
1952 		return (12 << 21) | ((4 + 2) << 16);
1953 
1954 	case SLJIT_NOT_EQUAL_F64:
1955 		return (4 << 21) | ((4 + 2) << 16);
1956 
1957 	case SLJIT_UNORDERED_F64:
1958 		return (12 << 21) | ((4 + 3) << 16);
1959 
1960 	case SLJIT_ORDERED_F64:
1961 		return (4 << 21) | ((4 + 3) << 16);
1962 
1963 	default:
1964 		SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL_CDECL);
1965 		return (20 << 21);
1966 	}
1967 }
1968 
sljit_emit_jump(struct sljit_compiler * compiler,sljit_s32 type)1969 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
1970 {
1971 	struct sljit_jump *jump;
1972 	sljit_ins bo_bi_flags;
1973 
1974 	CHECK_ERROR_PTR();
1975 	CHECK_PTR(check_sljit_emit_jump(compiler, type));
1976 
1977 	bo_bi_flags = get_bo_bi_flags(type & 0xff);
1978 	if (!bo_bi_flags)
1979 		return NULL;
1980 
1981 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
1982 	PTR_FAIL_IF(!jump);
1983 	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
1984 	type &= 0xff;
1985 
1986 	/* In PPC, we don't need to touch the arguments. */
1987 	if (type < SLJIT_JUMP)
1988 		jump->flags |= IS_COND;
1989 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
1990 	if (type >= SLJIT_CALL)
1991 		jump->flags |= IS_CALL;
1992 #endif
1993 
1994 	PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
1995 	PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG)));
1996 	jump->addr = compiler->size;
1997 	PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));
1998 	return jump;
1999 }
2000 
sljit_emit_call(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types)2001 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
2002 	sljit_s32 arg_types)
2003 {
2004 	CHECK_ERROR_PTR();
2005 	CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
2006 
2007 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2008 	PTR_FAIL_IF(call_with_args(compiler, arg_types, NULL));
2009 #endif
2010 
2011 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2012 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2013 	compiler->skip_checks = 1;
2014 #endif
2015 
2016 	return sljit_emit_jump(compiler, type);
2017 }
2018 
sljit_emit_ijump(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src,sljit_sw srcw)2019 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
2020 {
2021 	struct sljit_jump *jump = NULL;
2022 	sljit_s32 src_r;
2023 
2024 	CHECK_ERROR();
2025 	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
2026 	ADJUST_LOCAL_OFFSET(src, srcw);
2027 
2028 	if (FAST_IS_REG(src)) {
2029 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2030 		if (type >= SLJIT_CALL) {
2031 			FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
2032 			src_r = TMP_CALL_REG;
2033 		}
2034 		else
2035 			src_r = src;
2036 #else
2037 		src_r = src;
2038 #endif
2039 	} else if (src & SLJIT_IMM) {
2040 		/* These jumps are converted to jump/call instructions when possible. */
2041 		jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2042 		FAIL_IF(!jump);
2043 		set_jump(jump, compiler, JUMP_ADDR);
2044 		jump->u.target = srcw;
2045 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2046 		if (type >= SLJIT_CALL)
2047 			jump->flags |= IS_CALL;
2048 #endif
2049 		FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
2050 		src_r = TMP_CALL_REG;
2051 	}
2052 	else {
2053 		FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
2054 		src_r = TMP_CALL_REG;
2055 	}
2056 
2057 	FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));
2058 	if (jump)
2059 		jump->addr = compiler->size;
2060 	return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0));
2061 }
2062 
sljit_emit_icall(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types,sljit_s32 src,sljit_sw srcw)2063 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
2064 	sljit_s32 arg_types,
2065 	sljit_s32 src, sljit_sw srcw)
2066 {
2067 	CHECK_ERROR();
2068 	CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
2069 
2070 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2071 	if (src & SLJIT_MEM) {
2072 		ADJUST_LOCAL_OFFSET(src, srcw);
2073 		FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
2074 		src = TMP_CALL_REG;
2075 	}
2076 
2077 	FAIL_IF(call_with_args(compiler, arg_types, &src));
2078 #endif
2079 
2080 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2081 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2082 	compiler->skip_checks = 1;
2083 #endif
2084 
2085 	return sljit_emit_ijump(compiler, type, src, srcw);
2086 }
2087 
sljit_emit_op_flags(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 type)2088 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
2089 	sljit_s32 dst, sljit_sw dstw,
2090 	sljit_s32 type)
2091 {
2092 	sljit_s32 reg, input_flags, cr_bit, invert;
2093 	sljit_s32 saved_op = op;
2094 	sljit_sw saved_dstw = dstw;
2095 
2096 	CHECK_ERROR();
2097 	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
2098 	ADJUST_LOCAL_OFFSET(dst, dstw);
2099 
2100 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2101 	input_flags = (op & SLJIT_I32_OP) ? INT_DATA : WORD_DATA;
2102 #else
2103 	input_flags = WORD_DATA;
2104 #endif
2105 
2106 	op = GET_OPCODE(op);
2107 	reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
2108 
2109 	if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
2110 		FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, dst, dstw, TMP_REG1));
2111 
2112 	invert = 0;
2113 	cr_bit = 0;
2114 
2115 	switch (type & 0xff) {
2116 	case SLJIT_LESS:
2117 	case SLJIT_SIG_LESS:
2118 		break;
2119 
2120 	case SLJIT_GREATER_EQUAL:
2121 	case SLJIT_SIG_GREATER_EQUAL:
2122 		invert = 1;
2123 		break;
2124 
2125 	case SLJIT_GREATER:
2126 	case SLJIT_SIG_GREATER:
2127 		cr_bit = 1;
2128 		break;
2129 
2130 	case SLJIT_LESS_EQUAL:
2131 	case SLJIT_SIG_LESS_EQUAL:
2132 		cr_bit = 1;
2133 		invert = 1;
2134 		break;
2135 
2136 	case SLJIT_EQUAL:
2137 		cr_bit = 2;
2138 		break;
2139 
2140 	case SLJIT_NOT_EQUAL:
2141 		cr_bit = 2;
2142 		invert = 1;
2143 		break;
2144 
2145 	case SLJIT_OVERFLOW:
2146 	case SLJIT_MUL_OVERFLOW:
2147 		cr_bit = 3;
2148 		break;
2149 
2150 	case SLJIT_NOT_OVERFLOW:
2151 	case SLJIT_MUL_NOT_OVERFLOW:
2152 		cr_bit = 3;
2153 		invert = 1;
2154 		break;
2155 
2156 	case SLJIT_LESS_F64:
2157 		cr_bit = 4 + 0;
2158 		break;
2159 
2160 	case SLJIT_GREATER_EQUAL_F64:
2161 		cr_bit = 4 + 0;
2162 		invert = 1;
2163 		break;
2164 
2165 	case SLJIT_GREATER_F64:
2166 		cr_bit = 4 + 1;
2167 		break;
2168 
2169 	case SLJIT_LESS_EQUAL_F64:
2170 		cr_bit = 4 + 1;
2171 		invert = 1;
2172 		break;
2173 
2174 	case SLJIT_EQUAL_F64:
2175 		cr_bit = 4 + 2;
2176 		break;
2177 
2178 	case SLJIT_NOT_EQUAL_F64:
2179 		cr_bit = 4 + 2;
2180 		invert = 1;
2181 		break;
2182 
2183 	case SLJIT_UNORDERED_F64:
2184 		cr_bit = 4 + 3;
2185 		break;
2186 
2187 	case SLJIT_ORDERED_F64:
2188 		cr_bit = 4 + 3;
2189 		invert = 1;
2190 		break;
2191 
2192 	default:
2193 		SLJIT_UNREACHABLE();
2194 		break;
2195 	}
2196 
2197 	FAIL_IF(push_inst(compiler, MFCR | D(reg)));
2198 	FAIL_IF(push_inst(compiler, RLWINM | S(reg) | A(reg) | ((1 + (cr_bit)) << 11) | (31 << 6) | (31 << 1)));
2199 
2200 	if (invert)
2201 		FAIL_IF(push_inst(compiler, XORI | S(reg) | A(reg) | 0x1));
2202 
2203 	if (op < SLJIT_ADD) {
2204 		if (!(dst & SLJIT_MEM))
2205 			return SLJIT_SUCCESS;
2206 		return emit_op_mem(compiler, input_flags, reg, dst, dstw, TMP_REG1);
2207 	}
2208 
2209 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2210 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2211 	compiler->skip_checks = 1;
2212 #endif
2213 	if (dst & SLJIT_MEM)
2214 		return sljit_emit_op2(compiler, saved_op, dst, saved_dstw, TMP_REG1, 0, TMP_REG2, 0);
2215 	return sljit_emit_op2(compiler, saved_op, dst, 0, dst, 0, TMP_REG2, 0);
2216 }
2217 
sljit_emit_cmov(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_reg,sljit_s32 src,sljit_sw srcw)2218 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
2219 	sljit_s32 dst_reg,
2220 	sljit_s32 src, sljit_sw srcw)
2221 {
2222 	CHECK_ERROR();
2223 	CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
2224 
2225 	return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);;
2226 }
2227 
sljit_emit_mem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 reg,sljit_s32 mem,sljit_sw memw)2228 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
2229 	sljit_s32 reg,
2230 	sljit_s32 mem, sljit_sw memw)
2231 {
2232 	sljit_s32 mem_flags;
2233 	sljit_ins inst;
2234 
2235 	CHECK_ERROR();
2236 	CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
2237 
2238 	if (type & SLJIT_MEM_POST)
2239 		return SLJIT_ERR_UNSUPPORTED;
2240 
2241 	switch (type & 0xff) {
2242 	case SLJIT_MOV:
2243 	case SLJIT_MOV_P:
2244 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
2245 	case SLJIT_MOV_U32:
2246 	case SLJIT_MOV_S32:
2247 #endif
2248 		mem_flags = WORD_DATA;
2249 		break;
2250 
2251 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2252 	case SLJIT_MOV_U32:
2253 		mem_flags = INT_DATA;
2254 		break;
2255 
2256 	case SLJIT_MOV_S32:
2257 		mem_flags = INT_DATA;
2258 
2259 		if (!(type & SLJIT_MEM_STORE) && !(type & SLJIT_I32_OP)) {
2260 			if (mem & OFFS_REG_MASK)
2261 				mem_flags |= SIGNED_DATA;
2262 			else
2263 				return SLJIT_ERR_UNSUPPORTED;
2264 		}
2265 		break;
2266 #endif
2267 
2268 	case SLJIT_MOV_U8:
2269 	case SLJIT_MOV_S8:
2270 		mem_flags = BYTE_DATA;
2271 		break;
2272 
2273 	case SLJIT_MOV_U16:
2274 		mem_flags = HALF_DATA;
2275 		break;
2276 
2277 	case SLJIT_MOV_S16:
2278 		mem_flags = HALF_DATA | SIGNED_DATA;
2279 		break;
2280 
2281 	default:
2282 		SLJIT_UNREACHABLE();
2283 		mem_flags = WORD_DATA;
2284 		break;
2285 	}
2286 
2287 	if (!(type & SLJIT_MEM_STORE))
2288 		mem_flags |= LOAD_DATA;
2289 
2290 	if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
2291 		if (memw != 0)
2292 			return SLJIT_ERR_UNSUPPORTED;
2293 
2294 		if (type & SLJIT_MEM_SUPP)
2295 			return SLJIT_SUCCESS;
2296 
2297 		inst = updated_data_transfer_insts[mem_flags | INDEXED];
2298 		FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | B(OFFS_REG(mem))));
2299 	}
2300 	else {
2301 		if (memw > SIMM_MAX || memw < SIMM_MIN)
2302 			return SLJIT_ERR_UNSUPPORTED;
2303 
2304 		inst = updated_data_transfer_insts[mem_flags];
2305 
2306 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2307 		if ((inst & INT_ALIGNED) && (memw & 0x3) != 0)
2308 			return SLJIT_ERR_UNSUPPORTED;
2309 #endif
2310 
2311 		if (type & SLJIT_MEM_SUPP)
2312 			return SLJIT_SUCCESS;
2313 
2314 		FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | IMM(memw)));
2315 	}
2316 
2317 	if ((mem_flags & LOAD_DATA) && (type & 0xff) == SLJIT_MOV_S8)
2318 		return push_inst(compiler, EXTSB | S(reg) | A(reg));
2319 	return SLJIT_SUCCESS;
2320 }
2321 
sljit_emit_fmem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 mem,sljit_sw memw)2322 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
2323 	sljit_s32 freg,
2324 	sljit_s32 mem, sljit_sw memw)
2325 {
2326 	sljit_s32 mem_flags;
2327 	sljit_ins inst;
2328 
2329 	CHECK_ERROR();
2330 	CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
2331 
2332 	if (type & SLJIT_MEM_POST)
2333 		return SLJIT_ERR_UNSUPPORTED;
2334 
2335 	if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
2336 		if (memw != 0)
2337 			return SLJIT_ERR_UNSUPPORTED;
2338 	}
2339 	else {
2340 		if (memw > SIMM_MAX || memw < SIMM_MIN)
2341 			return SLJIT_ERR_UNSUPPORTED;
2342 	}
2343 
2344 	if (type & SLJIT_MEM_SUPP)
2345 		return SLJIT_SUCCESS;
2346 
2347 	mem_flags = FLOAT_DATA(type);
2348 
2349 	if (!(type & SLJIT_MEM_STORE))
2350 		mem_flags |= LOAD_DATA;
2351 
2352 	if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
2353 		inst = updated_data_transfer_insts[mem_flags | INDEXED];
2354 		return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | B(OFFS_REG(mem)));
2355 	}
2356 
2357 	inst = updated_data_transfer_insts[mem_flags];
2358 	return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | IMM(memw));
2359 }
2360 
sljit_emit_const(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw init_value)2361 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
2362 {
2363 	struct sljit_const *const_;
2364 	sljit_s32 dst_r;
2365 
2366 	CHECK_ERROR_PTR();
2367 	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
2368 	ADJUST_LOCAL_OFFSET(dst, dstw);
2369 
2370 	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
2371 	PTR_FAIL_IF(!const_);
2372 	set_const(const_, compiler);
2373 
2374 	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
2375 	PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
2376 
2377 	if (dst & SLJIT_MEM)
2378 		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
2379 
2380 	return const_;
2381 }
2382 
sljit_emit_put_label(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)2383 SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
2384 {
2385 	struct sljit_put_label *put_label;
2386 	sljit_s32 dst_r;
2387 
2388 	CHECK_ERROR_PTR();
2389 	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
2390 	ADJUST_LOCAL_OFFSET(dst, dstw);
2391 
2392 	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
2393 	PTR_FAIL_IF(!put_label);
2394 	set_put_label(put_label, compiler, 0);
2395 
2396 	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
2397 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
2398 	PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
2399 #else
2400 	PTR_FAIL_IF(push_inst(compiler, dst_r));
2401 	compiler->size += 4;
2402 #endif
2403 
2404 	if (dst & SLJIT_MEM)
2405 		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
2406 
2407 	return put_label;
2408 }
2409