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));
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 
611 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
612 	return code_ptr;
613 #else
614 	return code;
615 #endif
616 }
617 
sljit_has_cpu_feature(sljit_s32 feature_type)618 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
619 {
620 	switch (feature_type) {
621 	case SLJIT_HAS_FPU:
622 #ifdef SLJIT_IS_FPU_AVAILABLE
623 		return SLJIT_IS_FPU_AVAILABLE;
624 #else
625 		/* Available by default. */
626 		return 1;
627 #endif
628 
629 	case SLJIT_HAS_CLZ:
630 		return 1;
631 
632 	default:
633 		return 0;
634 	}
635 }
636 
637 /* --------------------------------------------------------------------- */
638 /*  Entry, exit                                                          */
639 /* --------------------------------------------------------------------- */
640 
641 /* inp_flags: */
642 
643 /* Creates an index in data_transfer_insts array. */
644 #define LOAD_DATA	0x01
645 #define INDEXED		0x02
646 #define SIGNED_DATA	0x04
647 
648 #define WORD_DATA	0x00
649 #define BYTE_DATA	0x08
650 #define HALF_DATA	0x10
651 #define INT_DATA	0x18
652 /* Separates integer and floating point registers */
653 #define GPR_REG		0x1f
654 #define DOUBLE_DATA	0x20
655 
656 #define MEM_MASK	0x7f
657 
658 /* Other inp_flags. */
659 
660 /* Integer opertion and set flags -> requires exts on 64 bit systems. */
661 #define ALT_SIGN_EXT	0x000100
662 /* This flag affects the RC() and OERC() macros. */
663 #define ALT_SET_FLAGS	0x000400
664 #define ALT_FORM1	0x001000
665 #define ALT_FORM2	0x002000
666 #define ALT_FORM3	0x004000
667 #define ALT_FORM4	0x008000
668 #define ALT_FORM5	0x010000
669 
670 /* Source and destination is register. */
671 #define REG_DEST	0x000001
672 #define REG1_SOURCE	0x000002
673 #define REG2_SOURCE	0x000004
674 /*
675 ALT_SIGN_EXT		0x000100
676 ALT_SET_FLAGS		0x000200
677 ALT_FORM1		0x001000
678 ...
679 ALT_FORM5		0x010000 */
680 
681 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
682 #include "sljitNativePPC_32.c"
683 #else
684 #include "sljitNativePPC_64.c"
685 #endif
686 
687 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
688 #define STACK_STORE	STW
689 #define STACK_LOAD	LWZ
690 #else
691 #define STACK_STORE	STD
692 #define STACK_LOAD	LD
693 #endif
694 
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)695 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
696 	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
697 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
698 {
699 	sljit_s32 args, i, tmp, offs;
700 
701 	CHECK_ERROR();
702 	CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
703 	set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
704 
705 	FAIL_IF(push_inst(compiler, MFLR | D(0)));
706 	offs = -(sljit_s32)(sizeof(sljit_sw));
707 	FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
708 
709 	tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
710 	for (i = SLJIT_S0; i >= tmp; i--) {
711 		offs -= (sljit_s32)(sizeof(sljit_sw));
712 		FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
713 	}
714 
715 	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
716 		offs -= (sljit_s32)(sizeof(sljit_sw));
717 		FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
718 	}
719 
720 	SLJIT_ASSERT(offs == -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1));
721 
722 #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
723 	FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
724 #else
725 	FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
726 #endif
727 
728 	FAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0));
729 
730 	args = get_arg_count(arg_types);
731 
732 	if (args >= 1)
733 		FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(SLJIT_S0) | B(SLJIT_R0)));
734 	if (args >= 2)
735 		FAIL_IF(push_inst(compiler, OR | S(SLJIT_R1) | A(SLJIT_S1) | B(SLJIT_R1)));
736 	if (args >= 3)
737 		FAIL_IF(push_inst(compiler, OR | S(SLJIT_R2) | A(SLJIT_S2) | B(SLJIT_R2)));
738 
739 	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
740 	local_size = (local_size + 15) & ~0xf;
741 	compiler->local_size = local_size;
742 
743 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
744 	if (local_size <= SIMM_MAX)
745 		FAIL_IF(push_inst(compiler, STWU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
746 	else {
747 		FAIL_IF(load_immediate(compiler, 0, -local_size));
748 		FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
749 	}
750 #else
751 	if (local_size <= SIMM_MAX)
752 		FAIL_IF(push_inst(compiler, STDU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
753 	else {
754 		FAIL_IF(load_immediate(compiler, 0, -local_size));
755 		FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
756 	}
757 #endif
758 
759 	return SLJIT_SUCCESS;
760 }
761 
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)762 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
763 	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
764 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
765 {
766 	CHECK_ERROR();
767 	CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
768 	set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
769 
770 	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
771 	compiler->local_size = (local_size + 15) & ~0xf;
772 	return SLJIT_SUCCESS;
773 }
774 
sljit_emit_return(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)775 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
776 {
777 	sljit_s32 i, tmp, offs;
778 
779 	CHECK_ERROR();
780 	CHECK(check_sljit_emit_return(compiler, op, src, srcw));
781 
782 	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
783 
784 	if (compiler->local_size <= SIMM_MAX)
785 		FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_SP) | A(SLJIT_SP) | IMM(compiler->local_size)));
786 	else {
787 		FAIL_IF(load_immediate(compiler, 0, compiler->local_size));
788 		FAIL_IF(push_inst(compiler, ADD | D(SLJIT_SP) | A(SLJIT_SP) | B(0)));
789 	}
790 
791 #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
792 	FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
793 #else
794 	FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
795 #endif
796 
797 	offs = -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1);
798 
799 	tmp = compiler->scratches;
800 	for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
801 		FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
802 		offs += (sljit_s32)(sizeof(sljit_sw));
803 	}
804 
805 	tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
806 	for (i = tmp; i <= SLJIT_S0; i++) {
807 		FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
808 		offs += (sljit_s32)(sizeof(sljit_sw));
809 	}
810 
811 	FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
812 	SLJIT_ASSERT(offs == -(sljit_sw)(sizeof(sljit_sw)));
813 
814 	FAIL_IF(push_inst(compiler, MTLR | S(0)));
815 	FAIL_IF(push_inst(compiler, BLR));
816 
817 	return SLJIT_SUCCESS;
818 }
819 
820 #undef STACK_STORE
821 #undef STACK_LOAD
822 
823 /* --------------------------------------------------------------------- */
824 /*  Operators                                                            */
825 /* --------------------------------------------------------------------- */
826 
827 /* s/l - store/load (1 bit)
828    i/x - immediate/indexed form
829    u/s - signed/unsigned (1 bit)
830    w/b/h/i - word/byte/half/int allowed (2 bit)
831 
832    Some opcodes are repeated (e.g. store signed / unsigned byte is the same instruction). */
833 
834 /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
835 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
836 #define INT_ALIGNED	0x10000
837 #endif
838 
839 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
840 #define ARCH_32_64(a, b)	a
841 #define INST_CODE_AND_DST(inst, flags, reg) \
842 	((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
843 #else
844 #define ARCH_32_64(a, b)	b
845 #define INST_CODE_AND_DST(inst, flags, reg) \
846 	(((inst) & ~INT_ALIGNED) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
847 #endif
848 
849 static const sljit_ins data_transfer_insts[64 + 16] = {
850 
851 /* -------- Integer -------- */
852 
853 /* Word. */
854 
855 /* w u i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
856 /* w u i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
857 /* w u x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
858 /* w u x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
859 
860 /* w s i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
861 /* w s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
862 /* w s x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
863 /* w s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
864 
865 /* Byte. */
866 
867 /* b u i s */ HI(38) /* stb */,
868 /* b u i l */ HI(34) /* lbz */,
869 /* b u x s */ HI(31) | LO(215) /* stbx */,
870 /* b u x l */ HI(31) | LO(87) /* lbzx */,
871 
872 /* b s i s */ HI(38) /* stb */,
873 /* b s i l */ HI(34) /* lbz */ /* EXTS_REQ */,
874 /* b s x s */ HI(31) | LO(215) /* stbx */,
875 /* b s x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
876 
877 /* Half. */
878 
879 /* h u i s */ HI(44) /* sth */,
880 /* h u i l */ HI(40) /* lhz */,
881 /* h u x s */ HI(31) | LO(407) /* sthx */,
882 /* h u x l */ HI(31) | LO(279) /* lhzx */,
883 
884 /* h s i s */ HI(44) /* sth */,
885 /* h s i l */ HI(42) /* lha */,
886 /* h s x s */ HI(31) | LO(407) /* sthx */,
887 /* h s x l */ HI(31) | LO(343) /* lhax */,
888 
889 /* Int. */
890 
891 /* i u i s */ HI(36) /* stw */,
892 /* i u i l */ HI(32) /* lwz */,
893 /* i u x s */ HI(31) | LO(151) /* stwx */,
894 /* i u x l */ HI(31) | LO(23) /* lwzx */,
895 
896 /* i s i s */ HI(36) /* stw */,
897 /* i s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */),
898 /* i s x s */ HI(31) | LO(151) /* stwx */,
899 /* i s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
900 
901 /* -------- Floating point -------- */
902 
903 /* d   i s */ HI(54) /* stfd */,
904 /* d   i l */ HI(50) /* lfd */,
905 /* d   x s */ HI(31) | LO(727) /* stfdx */,
906 /* d   x l */ HI(31) | LO(599) /* lfdx */,
907 
908 /* s   i s */ HI(52) /* stfs */,
909 /* s   i l */ HI(48) /* lfs */,
910 /* s   x s */ HI(31) | LO(663) /* stfsx */,
911 /* s   x l */ HI(31) | LO(535) /* lfsx */,
912 };
913 
914 static const sljit_ins updated_data_transfer_insts[64] = {
915 
916 /* -------- Integer -------- */
917 
918 /* Word. */
919 
920 /* w u i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
921 /* w u i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
922 /* w u x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
923 /* w u x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
924 
925 /* w s i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
926 /* w s i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
927 /* w s x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
928 /* w s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
929 
930 /* Byte. */
931 
932 /* b u i s */ HI(39) /* stbu */,
933 /* b u i l */ HI(35) /* lbzu */,
934 /* b u x s */ HI(31) | LO(247) /* stbux */,
935 /* b u x l */ HI(31) | LO(119) /* lbzux */,
936 
937 /* b s i s */ HI(39) /* stbu */,
938 /* b s i l */ 0 /* no such instruction */,
939 /* b s x s */ HI(31) | LO(247) /* stbux */,
940 /* b s x l */ 0 /* no such instruction */,
941 
942 /* Half. */
943 
944 /* h u i s */ HI(45) /* sthu */,
945 /* h u i l */ HI(41) /* lhzu */,
946 /* h u x s */ HI(31) | LO(439) /* sthux */,
947 /* h u x l */ HI(31) | LO(311) /* lhzux */,
948 
949 /* h s i s */ HI(45) /* sthu */,
950 /* h s i l */ HI(43) /* lhau */,
951 /* h s x s */ HI(31) | LO(439) /* sthux */,
952 /* h s x l */ HI(31) | LO(375) /* lhaux */,
953 
954 /* Int. */
955 
956 /* i u i s */ HI(37) /* stwu */,
957 /* i u i l */ HI(33) /* lwzu */,
958 /* i u x s */ HI(31) | LO(183) /* stwux */,
959 /* i u x l */ HI(31) | LO(55) /* lwzux */,
960 
961 /* i s i s */ HI(37) /* stwu */,
962 /* i s i l */ ARCH_32_64(HI(33) /* lwzu */, 0 /* no such instruction */),
963 /* i s x s */ HI(31) | LO(183) /* stwux */,
964 /* i s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
965 
966 /* -------- Floating point -------- */
967 
968 /* d   i s */ HI(55) /* stfdu */,
969 /* d   i l */ HI(51) /* lfdu */,
970 /* d   x s */ HI(31) | LO(759) /* stfdux */,
971 /* d   x l */ HI(31) | LO(631) /* lfdux */,
972 
973 /* s   i s */ HI(53) /* stfsu */,
974 /* s   i l */ HI(49) /* lfsu */,
975 /* s   x s */ HI(31) | LO(695) /* stfsux */,
976 /* s   x l */ HI(31) | LO(567) /* lfsux */,
977 };
978 
979 #undef ARCH_32_64
980 
981 /* 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)982 static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg,
983 	sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)
984 {
985 	sljit_ins inst;
986 	sljit_s32 offs_reg;
987 	sljit_sw high_short;
988 
989 	/* Should work when (arg & REG_MASK) == 0. */
990 	SLJIT_ASSERT(A(0) == 0);
991 	SLJIT_ASSERT(arg & SLJIT_MEM);
992 
993 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
994 		argw &= 0x3;
995 		offs_reg = OFFS_REG(arg);
996 
997 		if (argw != 0) {
998 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
999 			FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(arg)) | A(tmp_reg) | (argw << 11) | ((31 - argw) << 1)));
1000 #else
1001 			FAIL_IF(push_inst(compiler, RLDI(tmp_reg, OFFS_REG(arg), argw, 63 - argw, 1)));
1002 #endif
1003 			offs_reg = tmp_reg;
1004 		}
1005 
1006 		inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
1007 
1008 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1009 		SLJIT_ASSERT(!(inst & INT_ALIGNED));
1010 #endif
1011 
1012 		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(offs_reg));
1013 	}
1014 
1015 	inst = data_transfer_insts[inp_flags & MEM_MASK];
1016 	arg &= REG_MASK;
1017 
1018 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1019 	if ((inst & INT_ALIGNED) && (argw & 0x3) != 0) {
1020 		FAIL_IF(load_immediate(compiler, tmp_reg, argw));
1021 
1022 		inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
1023 		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | B(tmp_reg));
1024 	}
1025 #endif
1026 
1027 	if (argw <= SIMM_MAX && argw >= SIMM_MIN)
1028 		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | IMM(argw));
1029 
1030 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1031 	if (argw <= 0x7fff7fffl && argw >= -0x80000000l) {
1032 #endif
1033 
1034 		high_short = (sljit_s32)(argw + ((argw & 0x8000) << 1)) & ~0xffff;
1035 
1036 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1037 		SLJIT_ASSERT(high_short && high_short <= 0x7fffffffl && high_short >= -0x80000000l);
1038 #else
1039 		SLJIT_ASSERT(high_short);
1040 #endif
1041 
1042 		FAIL_IF(push_inst(compiler, ADDIS | D(tmp_reg) | A(arg) | IMM(high_short >> 16)));
1043 		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_reg) | IMM(argw));
1044 
1045 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1046 	}
1047 
1048 	/* The rest is PPC-64 only. */
1049 
1050 	FAIL_IF(load_immediate(compiler, tmp_reg, argw));
1051 
1052 	inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
1053 	return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | B(tmp_reg));
1054 #endif
1055 }
1056 
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)1057 static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 input_flags,
1058 	sljit_s32 dst, sljit_sw dstw,
1059 	sljit_s32 src1, sljit_sw src1w,
1060 	sljit_s32 src2, sljit_sw src2w)
1061 {
1062 	/* arg1 goes to TMP_REG1 or src reg
1063 	   arg2 goes to TMP_REG2, imm or src reg
1064 	   result goes to TMP_REG2, so put result can use TMP_REG1. */
1065 	sljit_s32 dst_r = TMP_REG2;
1066 	sljit_s32 src1_r;
1067 	sljit_s32 src2_r;
1068 	sljit_s32 sugg_src2_r = TMP_REG2;
1069 	sljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_SIGN_EXT | ALT_SET_FLAGS);
1070 
1071 	/* Destination check. */
1072 	if (SLOW_IS_REG(dst)) {
1073 		dst_r = dst;
1074 		flags |= REG_DEST;
1075 
1076 		if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)
1077 			sugg_src2_r = dst_r;
1078 	}
1079 
1080 	/* Source 1. */
1081 	if (FAST_IS_REG(src1)) {
1082 		src1_r = src1;
1083 		flags |= REG1_SOURCE;
1084 	}
1085 	else if (src1 & SLJIT_IMM) {
1086 		FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
1087 		src1_r = TMP_REG1;
1088 	}
1089 	else {
1090 		FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));
1091 		src1_r = TMP_REG1;
1092 	}
1093 
1094 	/* Source 2. */
1095 	if (FAST_IS_REG(src2)) {
1096 		src2_r = src2;
1097 		flags |= REG2_SOURCE;
1098 
1099 		if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)
1100 			dst_r = src2_r;
1101 	}
1102 	else if (src2 & SLJIT_IMM) {
1103 		FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
1104 		src2_r = sugg_src2_r;
1105 	}
1106 	else {
1107 		FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, TMP_REG2));
1108 		src2_r = sugg_src2_r;
1109 	}
1110 
1111 	FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
1112 
1113 	if (!(dst & SLJIT_MEM))
1114 		return SLJIT_SUCCESS;
1115 
1116 	return emit_op_mem(compiler, input_flags, dst_r, dst, dstw, TMP_REG1);
1117 }
1118 
sljit_emit_op0(struct sljit_compiler * compiler,sljit_s32 op)1119 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
1120 {
1121 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1122 	sljit_s32 int_op = op & SLJIT_I32_OP;
1123 #endif
1124 
1125 	CHECK_ERROR();
1126 	CHECK(check_sljit_emit_op0(compiler, op));
1127 
1128 	op = GET_OPCODE(op);
1129 	switch (op) {
1130 	case SLJIT_BREAKPOINT:
1131 	case SLJIT_NOP:
1132 		return push_inst(compiler, NOP);
1133 	case SLJIT_LMUL_UW:
1134 	case SLJIT_LMUL_SW:
1135 		FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
1136 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1137 		FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
1138 		return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
1139 #else
1140 		FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
1141 		return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
1142 #endif
1143 	case SLJIT_DIVMOD_UW:
1144 	case SLJIT_DIVMOD_SW:
1145 		FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
1146 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1147 		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)));
1148 		FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
1149 #else
1150 		FAIL_IF(push_inst(compiler, (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
1151 		FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
1152 #endif
1153 		return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));
1154 	case SLJIT_DIV_UW:
1155 	case SLJIT_DIV_SW:
1156 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1157 		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));
1158 #else
1159 		return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
1160 #endif
1161 	}
1162 
1163 	return SLJIT_SUCCESS;
1164 }
1165 
emit_prefetch(struct sljit_compiler * compiler,sljit_s32 src,sljit_sw srcw)1166 static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
1167         sljit_s32 src, sljit_sw srcw)
1168 {
1169 	if (!(src & OFFS_REG_MASK)) {
1170 		if (srcw == 0 && (src & REG_MASK) != SLJIT_UNUSED)
1171 			return push_inst(compiler, DCBT | A(0) | B(src & REG_MASK));
1172 
1173 		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
1174 		/* Works with SLJIT_MEM0() case as well. */
1175 		return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));
1176 	}
1177 
1178 	srcw &= 0x3;
1179 
1180 	if (srcw == 0)
1181 		return push_inst(compiler, DCBT | A(src & REG_MASK) | B(OFFS_REG(src)));
1182 
1183 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1184 	FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(src)) | A(TMP_REG1) | (srcw << 11) | ((31 - srcw) << 1)));
1185 #else
1186 	FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(src), srcw, 63 - srcw, 1)));
1187 #endif
1188 	return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));
1189 }
1190 
1191 #define EMIT_MOV(type, type_flags, type_cast) \
1192 	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)
1193 
sljit_emit_op1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1194 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
1195 	sljit_s32 dst, sljit_sw dstw,
1196 	sljit_s32 src, sljit_sw srcw)
1197 {
1198 	sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;
1199 	sljit_s32 op_flags = GET_ALL_FLAGS(op);
1200 
1201 	CHECK_ERROR();
1202 	CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
1203 	ADJUST_LOCAL_OFFSET(dst, dstw);
1204 	ADJUST_LOCAL_OFFSET(src, srcw);
1205 
1206 	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
1207 		if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
1208 			return emit_prefetch(compiler, src, srcw);
1209 
1210 		return SLJIT_SUCCESS;
1211 	}
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_get_register_index(sljit_s32 reg)1539 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
1540 {
1541 	CHECK_REG_INDEX(check_sljit_get_register_index(reg));
1542 	return reg_map[reg];
1543 }
1544 
sljit_get_float_register_index(sljit_s32 reg)1545 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
1546 {
1547 	CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
1548 	return freg_map[reg];
1549 }
1550 
sljit_emit_op_custom(struct sljit_compiler * compiler,void * instruction,sljit_s32 size)1551 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
1552 	void *instruction, sljit_s32 size)
1553 {
1554 	CHECK_ERROR();
1555 	CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
1556 
1557 	return push_inst(compiler, *(sljit_ins*)instruction);
1558 }
1559 
1560 /* --------------------------------------------------------------------- */
1561 /*  Floating point operators                                             */
1562 /* --------------------------------------------------------------------- */
1563 
1564 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 6))
1565 #define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)
1566 
1567 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1568 #define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw))
1569 #else
1570 #define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw))
1571 
1572 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
1573 #define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw))
1574 #define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw))
1575 #else
1576 #define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw))
1577 #define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw))
1578 #endif
1579 
1580 #endif /* SLJIT_CONFIG_PPC_64 */
1581 
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)1582 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
1583 	sljit_s32 dst, sljit_sw dstw,
1584 	sljit_s32 src, sljit_sw srcw)
1585 {
1586 	if (src & SLJIT_MEM) {
1587 		/* We can ignore the temporary data store on the stack from caching point of view. */
1588 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));
1589 		src = TMP_FREG1;
1590 	}
1591 
1592 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1593 	op = GET_OPCODE(op);
1594 	FAIL_IF(push_inst(compiler, (op == SLJIT_CONV_S32_FROM_F64 ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src)));
1595 
1596 	if (op == SLJIT_CONV_SW_FROM_F64) {
1597 		if (FAST_IS_REG(dst)) {
1598 			FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1599 			return emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1);
1600 		}
1601 		return emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, TMP_REG1);
1602 	}
1603 #else
1604 	FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src)));
1605 #endif
1606 
1607 	if (FAST_IS_REG(dst)) {
1608 		FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET));
1609 		FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1)));
1610 		return emit_op_mem(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1);
1611 	}
1612 
1613 	SLJIT_ASSERT(dst & SLJIT_MEM);
1614 
1615 	if (dst & OFFS_REG_MASK) {
1616 		dstw &= 0x3;
1617 		if (dstw) {
1618 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1619 			FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(dst)) | A(TMP_REG1) | (dstw << 11) | ((31 - dstw) << 1)));
1620 #else
1621 			FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(dst), dstw, 63 - dstw, 1)));
1622 #endif
1623 			dstw = TMP_REG1;
1624 		}
1625 		else
1626 			dstw = OFFS_REG(dst);
1627 	}
1628 	else {
1629 		if ((dst & REG_MASK) && !dstw) {
1630 			dstw = dst & REG_MASK;
1631 			dst = 0;
1632 		}
1633 		else {
1634 			/* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */
1635 			FAIL_IF(load_immediate(compiler, TMP_REG1, dstw));
1636 			dstw = TMP_REG1;
1637 		}
1638 	}
1639 
1640 	return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw));
1641 }
1642 
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)1643 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
1644 	sljit_s32 dst, sljit_sw dstw,
1645 	sljit_s32 src, sljit_sw srcw)
1646 {
1647 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1648 
1649 	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1650 
1651 	if (src & SLJIT_IMM) {
1652 		if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
1653 			srcw = (sljit_s32)srcw;
1654 		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
1655 		src = TMP_REG1;
1656 	}
1657 	else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) {
1658 		if (FAST_IS_REG(src))
1659 			FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1)));
1660 		else
1661 			FAIL_IF(emit_op_mem(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
1662 		src = TMP_REG1;
1663 	}
1664 
1665 	if (FAST_IS_REG(src)) {
1666 		FAIL_IF(emit_op_mem(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1667 		FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1668 	}
1669 	else
1670 		FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));
1671 
1672 	FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
1673 
1674 	if (dst & SLJIT_MEM)
1675 		return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
1676 	if (op & SLJIT_F32_OP)
1677 		return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
1678 	return SLJIT_SUCCESS;
1679 
1680 #else
1681 
1682 	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1683 	sljit_s32 invert_sign = 1;
1684 
1685 	if (src & SLJIT_IMM) {
1686 		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000));
1687 		src = TMP_REG1;
1688 		invert_sign = 0;
1689 	}
1690 	else if (!FAST_IS_REG(src)) {
1691 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
1692 		src = TMP_REG1;
1693 	}
1694 
1695 	/* First, a special double floating point value is constructed: (2^53 + (input xor (2^31)))
1696 	   The double precision format has exactly 53 bit precision, so the lower 32 bit represents
1697 	   the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000
1698 	   to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating
1699 	   point value, we need to substract 2^53 + 2^31 from the constructed value. */
1700 	FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
1701 	if (invert_sign)
1702 		FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000));
1703 	FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, TMP_REG1));
1704 	FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2));
1705 	FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000));
1706 	FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1707 	FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2));
1708 	FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
1709 
1710 	FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
1711 
1712 	if (dst & SLJIT_MEM)
1713 		return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
1714 	if (op & SLJIT_F32_OP)
1715 		return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
1716 	return SLJIT_SUCCESS;
1717 
1718 #endif
1719 }
1720 
sljit_emit_fop1_cmp(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)1721 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
1722 	sljit_s32 src1, sljit_sw src1w,
1723 	sljit_s32 src2, sljit_sw src2w)
1724 {
1725 	if (src1 & SLJIT_MEM) {
1726 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));
1727 		src1 = TMP_FREG1;
1728 	}
1729 
1730 	if (src2 & SLJIT_MEM) {
1731 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));
1732 		src2 = TMP_FREG2;
1733 	}
1734 
1735 	return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2));
1736 }
1737 
sljit_emit_fop1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1738 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
1739 	sljit_s32 dst, sljit_sw dstw,
1740 	sljit_s32 src, sljit_sw srcw)
1741 {
1742 	sljit_s32 dst_r;
1743 
1744 	CHECK_ERROR();
1745 
1746 	SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error);
1747 	SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
1748 
1749 	if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
1750 		op ^= SLJIT_F32_OP;
1751 
1752 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
1753 
1754 	if (src & SLJIT_MEM) {
1755 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, TMP_REG1));
1756 		src = dst_r;
1757 	}
1758 
1759 	switch (GET_OPCODE(op)) {
1760 	case SLJIT_CONV_F64_FROM_F32:
1761 		op ^= SLJIT_F32_OP;
1762 		if (op & SLJIT_F32_OP) {
1763 			FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src)));
1764 			break;
1765 		}
1766 		/* Fall through. */
1767 	case SLJIT_MOV_F64:
1768 		if (src != dst_r) {
1769 			if (dst_r != TMP_FREG1)
1770 				FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src)));
1771 			else
1772 				dst_r = src;
1773 		}
1774 		break;
1775 	case SLJIT_NEG_F64:
1776 		FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src)));
1777 		break;
1778 	case SLJIT_ABS_F64:
1779 		FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src)));
1780 		break;
1781 	}
1782 
1783 	if (dst & SLJIT_MEM)
1784 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), dst_r, dst, dstw, TMP_REG1));
1785 	return SLJIT_SUCCESS;
1786 }
1787 
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)1788 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
1789 	sljit_s32 dst, sljit_sw dstw,
1790 	sljit_s32 src1, sljit_sw src1w,
1791 	sljit_s32 src2, sljit_sw src2w)
1792 {
1793 	sljit_s32 dst_r;
1794 
1795 	CHECK_ERROR();
1796 	CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
1797 	ADJUST_LOCAL_OFFSET(dst, dstw);
1798 	ADJUST_LOCAL_OFFSET(src1, src1w);
1799 	ADJUST_LOCAL_OFFSET(src2, src2w);
1800 
1801 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
1802 
1803 	if (src1 & SLJIT_MEM) {
1804 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));
1805 		src1 = TMP_FREG1;
1806 	}
1807 
1808 	if (src2 & SLJIT_MEM) {
1809 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));
1810 		src2 = TMP_FREG2;
1811 	}
1812 
1813 	switch (GET_OPCODE(op)) {
1814 	case SLJIT_ADD_F64:
1815 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2)));
1816 		break;
1817 
1818 	case SLJIT_SUB_F64:
1819 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2)));
1820 		break;
1821 
1822 	case SLJIT_MUL_F64:
1823 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));
1824 		break;
1825 
1826 	case SLJIT_DIV_F64:
1827 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2)));
1828 		break;
1829 	}
1830 
1831 	if (dst & SLJIT_MEM)
1832 		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, TMP_REG1));
1833 
1834 	return SLJIT_SUCCESS;
1835 }
1836 
1837 #undef SELECT_FOP
1838 
1839 /* --------------------------------------------------------------------- */
1840 /*  Other instructions                                                   */
1841 /* --------------------------------------------------------------------- */
1842 
sljit_emit_fast_enter(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)1843 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
1844 {
1845 	CHECK_ERROR();
1846 	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
1847 	ADJUST_LOCAL_OFFSET(dst, dstw);
1848 
1849 	if (FAST_IS_REG(dst))
1850 		return push_inst(compiler, MFLR | D(dst));
1851 
1852 	/* Memory. */
1853 	FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2)));
1854 	return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
1855 }
1856 
sljit_emit_fast_return(struct sljit_compiler * compiler,sljit_s32 src,sljit_sw srcw)1857 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
1858 {
1859 	CHECK_ERROR();
1860 	CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
1861 	ADJUST_LOCAL_OFFSET(src, srcw);
1862 
1863 	if (FAST_IS_REG(src))
1864 		FAIL_IF(push_inst(compiler, MTLR | S(src)));
1865 	else {
1866 		FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
1867 		FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
1868 	}
1869 
1870 	return push_inst(compiler, BLR);
1871 }
1872 
1873 /* --------------------------------------------------------------------- */
1874 /*  Conditional instructions                                             */
1875 /* --------------------------------------------------------------------- */
1876 
sljit_emit_label(struct sljit_compiler * compiler)1877 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
1878 {
1879 	struct sljit_label *label;
1880 
1881 	CHECK_ERROR_PTR();
1882 	CHECK_PTR(check_sljit_emit_label(compiler));
1883 
1884 	if (compiler->last_label && compiler->last_label->size == compiler->size)
1885 		return compiler->last_label;
1886 
1887 	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
1888 	PTR_FAIL_IF(!label);
1889 	set_label(label, compiler);
1890 	return label;
1891 }
1892 
get_bo_bi_flags(sljit_s32 type)1893 static sljit_ins get_bo_bi_flags(sljit_s32 type)
1894 {
1895 	switch (type) {
1896 	case SLJIT_EQUAL:
1897 		return (12 << 21) | (2 << 16);
1898 
1899 	case SLJIT_NOT_EQUAL:
1900 		return (4 << 21) | (2 << 16);
1901 
1902 	case SLJIT_LESS:
1903 	case SLJIT_SIG_LESS:
1904 		return (12 << 21) | (0 << 16);
1905 
1906 	case SLJIT_GREATER_EQUAL:
1907 	case SLJIT_SIG_GREATER_EQUAL:
1908 		return (4 << 21) | (0 << 16);
1909 
1910 	case SLJIT_GREATER:
1911 	case SLJIT_SIG_GREATER:
1912 		return (12 << 21) | (1 << 16);
1913 
1914 	case SLJIT_LESS_EQUAL:
1915 	case SLJIT_SIG_LESS_EQUAL:
1916 		return (4 << 21) | (1 << 16);
1917 
1918 	case SLJIT_LESS_F64:
1919 		return (12 << 21) | ((4 + 0) << 16);
1920 
1921 	case SLJIT_GREATER_EQUAL_F64:
1922 		return (4 << 21) | ((4 + 0) << 16);
1923 
1924 	case SLJIT_GREATER_F64:
1925 		return (12 << 21) | ((4 + 1) << 16);
1926 
1927 	case SLJIT_LESS_EQUAL_F64:
1928 		return (4 << 21) | ((4 + 1) << 16);
1929 
1930 	case SLJIT_OVERFLOW:
1931 	case SLJIT_MUL_OVERFLOW:
1932 		return (12 << 21) | (3 << 16);
1933 
1934 	case SLJIT_NOT_OVERFLOW:
1935 	case SLJIT_MUL_NOT_OVERFLOW:
1936 		return (4 << 21) | (3 << 16);
1937 
1938 	case SLJIT_EQUAL_F64:
1939 		return (12 << 21) | ((4 + 2) << 16);
1940 
1941 	case SLJIT_NOT_EQUAL_F64:
1942 		return (4 << 21) | ((4 + 2) << 16);
1943 
1944 	case SLJIT_UNORDERED_F64:
1945 		return (12 << 21) | ((4 + 3) << 16);
1946 
1947 	case SLJIT_ORDERED_F64:
1948 		return (4 << 21) | ((4 + 3) << 16);
1949 
1950 	default:
1951 		SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL_CDECL);
1952 		return (20 << 21);
1953 	}
1954 }
1955 
sljit_emit_jump(struct sljit_compiler * compiler,sljit_s32 type)1956 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
1957 {
1958 	struct sljit_jump *jump;
1959 	sljit_ins bo_bi_flags;
1960 
1961 	CHECK_ERROR_PTR();
1962 	CHECK_PTR(check_sljit_emit_jump(compiler, type));
1963 
1964 	bo_bi_flags = get_bo_bi_flags(type & 0xff);
1965 	if (!bo_bi_flags)
1966 		return NULL;
1967 
1968 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
1969 	PTR_FAIL_IF(!jump);
1970 	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
1971 	type &= 0xff;
1972 
1973 	/* In PPC, we don't need to touch the arguments. */
1974 	if (type < SLJIT_JUMP)
1975 		jump->flags |= IS_COND;
1976 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
1977 	if (type >= SLJIT_CALL)
1978 		jump->flags |= IS_CALL;
1979 #endif
1980 
1981 	PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
1982 	PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG)));
1983 	jump->addr = compiler->size;
1984 	PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));
1985 	return jump;
1986 }
1987 
sljit_emit_call(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types)1988 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
1989 	sljit_s32 arg_types)
1990 {
1991 	CHECK_ERROR_PTR();
1992 	CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
1993 
1994 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1995 	PTR_FAIL_IF(call_with_args(compiler, arg_types, NULL));
1996 #endif
1997 
1998 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
1999 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2000 	compiler->skip_checks = 1;
2001 #endif
2002 
2003 	return sljit_emit_jump(compiler, type);
2004 }
2005 
sljit_emit_ijump(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src,sljit_sw srcw)2006 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
2007 {
2008 	struct sljit_jump *jump = NULL;
2009 	sljit_s32 src_r;
2010 
2011 	CHECK_ERROR();
2012 	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
2013 	ADJUST_LOCAL_OFFSET(src, srcw);
2014 
2015 	if (FAST_IS_REG(src)) {
2016 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2017 		if (type >= SLJIT_CALL) {
2018 			FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
2019 			src_r = TMP_CALL_REG;
2020 		}
2021 		else
2022 			src_r = src;
2023 #else
2024 		src_r = src;
2025 #endif
2026 	} else if (src & SLJIT_IMM) {
2027 		/* These jumps are converted to jump/call instructions when possible. */
2028 		jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
2029 		FAIL_IF(!jump);
2030 		set_jump(jump, compiler, JUMP_ADDR);
2031 		jump->u.target = srcw;
2032 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
2033 		if (type >= SLJIT_CALL)
2034 			jump->flags |= IS_CALL;
2035 #endif
2036 		FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
2037 		src_r = TMP_CALL_REG;
2038 	}
2039 	else {
2040 		FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
2041 		src_r = TMP_CALL_REG;
2042 	}
2043 
2044 	FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));
2045 	if (jump)
2046 		jump->addr = compiler->size;
2047 	return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0));
2048 }
2049 
sljit_emit_icall(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types,sljit_s32 src,sljit_sw srcw)2050 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
2051 	sljit_s32 arg_types,
2052 	sljit_s32 src, sljit_sw srcw)
2053 {
2054 	CHECK_ERROR();
2055 	CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
2056 
2057 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2058 	if (src & SLJIT_MEM) {
2059 		ADJUST_LOCAL_OFFSET(src, srcw);
2060 		FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
2061 		src = TMP_CALL_REG;
2062 	}
2063 
2064 	FAIL_IF(call_with_args(compiler, arg_types, &src));
2065 #endif
2066 
2067 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2068 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2069 	compiler->skip_checks = 1;
2070 #endif
2071 
2072 	return sljit_emit_ijump(compiler, type, src, srcw);
2073 }
2074 
sljit_emit_op_flags(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 type)2075 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
2076 	sljit_s32 dst, sljit_sw dstw,
2077 	sljit_s32 type)
2078 {
2079 	sljit_s32 reg, input_flags, cr_bit, invert;
2080 	sljit_s32 saved_op = op;
2081 	sljit_sw saved_dstw = dstw;
2082 
2083 	CHECK_ERROR();
2084 	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
2085 	ADJUST_LOCAL_OFFSET(dst, dstw);
2086 
2087 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2088 	input_flags = (op & SLJIT_I32_OP) ? INT_DATA : WORD_DATA;
2089 #else
2090 	input_flags = WORD_DATA;
2091 #endif
2092 
2093 	op = GET_OPCODE(op);
2094 	reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
2095 
2096 	if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
2097 		FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, dst, dstw, TMP_REG1));
2098 
2099 	invert = 0;
2100 	cr_bit = 0;
2101 
2102 	switch (type & 0xff) {
2103 	case SLJIT_LESS:
2104 	case SLJIT_SIG_LESS:
2105 		break;
2106 
2107 	case SLJIT_GREATER_EQUAL:
2108 	case SLJIT_SIG_GREATER_EQUAL:
2109 		invert = 1;
2110 		break;
2111 
2112 	case SLJIT_GREATER:
2113 	case SLJIT_SIG_GREATER:
2114 		cr_bit = 1;
2115 		break;
2116 
2117 	case SLJIT_LESS_EQUAL:
2118 	case SLJIT_SIG_LESS_EQUAL:
2119 		cr_bit = 1;
2120 		invert = 1;
2121 		break;
2122 
2123 	case SLJIT_EQUAL:
2124 		cr_bit = 2;
2125 		break;
2126 
2127 	case SLJIT_NOT_EQUAL:
2128 		cr_bit = 2;
2129 		invert = 1;
2130 		break;
2131 
2132 	case SLJIT_OVERFLOW:
2133 	case SLJIT_MUL_OVERFLOW:
2134 		cr_bit = 3;
2135 		break;
2136 
2137 	case SLJIT_NOT_OVERFLOW:
2138 	case SLJIT_MUL_NOT_OVERFLOW:
2139 		cr_bit = 3;
2140 		invert = 1;
2141 		break;
2142 
2143 	case SLJIT_LESS_F64:
2144 		cr_bit = 4 + 0;
2145 		break;
2146 
2147 	case SLJIT_GREATER_EQUAL_F64:
2148 		cr_bit = 4 + 0;
2149 		invert = 1;
2150 		break;
2151 
2152 	case SLJIT_GREATER_F64:
2153 		cr_bit = 4 + 1;
2154 		break;
2155 
2156 	case SLJIT_LESS_EQUAL_F64:
2157 		cr_bit = 4 + 1;
2158 		invert = 1;
2159 		break;
2160 
2161 	case SLJIT_EQUAL_F64:
2162 		cr_bit = 4 + 2;
2163 		break;
2164 
2165 	case SLJIT_NOT_EQUAL_F64:
2166 		cr_bit = 4 + 2;
2167 		invert = 1;
2168 		break;
2169 
2170 	case SLJIT_UNORDERED_F64:
2171 		cr_bit = 4 + 3;
2172 		break;
2173 
2174 	case SLJIT_ORDERED_F64:
2175 		cr_bit = 4 + 3;
2176 		invert = 1;
2177 		break;
2178 
2179 	default:
2180 		SLJIT_UNREACHABLE();
2181 		break;
2182 	}
2183 
2184 	FAIL_IF(push_inst(compiler, MFCR | D(reg)));
2185 	FAIL_IF(push_inst(compiler, RLWINM | S(reg) | A(reg) | ((1 + (cr_bit)) << 11) | (31 << 6) | (31 << 1)));
2186 
2187 	if (invert)
2188 		FAIL_IF(push_inst(compiler, XORI | S(reg) | A(reg) | 0x1));
2189 
2190 	if (op < SLJIT_ADD) {
2191 		if (!(dst & SLJIT_MEM))
2192 			return SLJIT_SUCCESS;
2193 		return emit_op_mem(compiler, input_flags, reg, dst, dstw, TMP_REG1);
2194 	}
2195 
2196 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2197 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2198 	compiler->skip_checks = 1;
2199 #endif
2200 	if (dst & SLJIT_MEM)
2201 		return sljit_emit_op2(compiler, saved_op, dst, saved_dstw, TMP_REG1, 0, TMP_REG2, 0);
2202 	return sljit_emit_op2(compiler, saved_op, dst, 0, dst, 0, TMP_REG2, 0);
2203 }
2204 
sljit_emit_cmov(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_reg,sljit_s32 src,sljit_sw srcw)2205 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
2206 	sljit_s32 dst_reg,
2207 	sljit_s32 src, sljit_sw srcw)
2208 {
2209 	CHECK_ERROR();
2210 	CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
2211 
2212 	return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);;
2213 }
2214 
sljit_emit_mem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 reg,sljit_s32 mem,sljit_sw memw)2215 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
2216 	sljit_s32 reg,
2217 	sljit_s32 mem, sljit_sw memw)
2218 {
2219 	sljit_s32 mem_flags;
2220 	sljit_ins inst;
2221 
2222 	CHECK_ERROR();
2223 	CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
2224 
2225 	if (type & SLJIT_MEM_POST)
2226 		return SLJIT_ERR_UNSUPPORTED;
2227 
2228 	switch (type & 0xff) {
2229 	case SLJIT_MOV:
2230 	case SLJIT_MOV_P:
2231 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
2232 	case SLJIT_MOV_U32:
2233 	case SLJIT_MOV_S32:
2234 #endif
2235 		mem_flags = WORD_DATA;
2236 		break;
2237 
2238 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2239 	case SLJIT_MOV_U32:
2240 		mem_flags = INT_DATA;
2241 		break;
2242 
2243 	case SLJIT_MOV_S32:
2244 		mem_flags = INT_DATA;
2245 
2246 		if (!(type & SLJIT_MEM_STORE) && !(type & SLJIT_I32_OP)) {
2247 			if (mem & OFFS_REG_MASK)
2248 				mem_flags |= SIGNED_DATA;
2249 			else
2250 				return SLJIT_ERR_UNSUPPORTED;
2251 		}
2252 		break;
2253 #endif
2254 
2255 	case SLJIT_MOV_U8:
2256 	case SLJIT_MOV_S8:
2257 		mem_flags = BYTE_DATA;
2258 		break;
2259 
2260 	case SLJIT_MOV_U16:
2261 		mem_flags = HALF_DATA;
2262 		break;
2263 
2264 	case SLJIT_MOV_S16:
2265 		mem_flags = HALF_DATA | SIGNED_DATA;
2266 		break;
2267 
2268 	default:
2269 		SLJIT_UNREACHABLE();
2270 		mem_flags = WORD_DATA;
2271 		break;
2272 	}
2273 
2274 	if (!(type & SLJIT_MEM_STORE))
2275 		mem_flags |= LOAD_DATA;
2276 
2277 	if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
2278 		if (memw != 0)
2279 			return SLJIT_ERR_UNSUPPORTED;
2280 
2281 		if (type & SLJIT_MEM_SUPP)
2282 			return SLJIT_SUCCESS;
2283 
2284 		inst = updated_data_transfer_insts[mem_flags | INDEXED];
2285 		FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | B(OFFS_REG(mem))));
2286 	}
2287 	else {
2288 		if (memw > SIMM_MAX || memw < SIMM_MIN)
2289 			return SLJIT_ERR_UNSUPPORTED;
2290 
2291 		inst = updated_data_transfer_insts[mem_flags];
2292 
2293 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
2294 		if ((inst & INT_ALIGNED) && (memw & 0x3) != 0)
2295 			return SLJIT_ERR_UNSUPPORTED;
2296 #endif
2297 
2298 		if (type & SLJIT_MEM_SUPP)
2299 			return SLJIT_SUCCESS;
2300 
2301 		FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | IMM(memw)));
2302 	}
2303 
2304 	if ((mem_flags & LOAD_DATA) && (type & 0xff) == SLJIT_MOV_S8)
2305 		return push_inst(compiler, EXTSB | S(reg) | A(reg));
2306 	return SLJIT_SUCCESS;
2307 }
2308 
sljit_emit_fmem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 mem,sljit_sw memw)2309 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
2310 	sljit_s32 freg,
2311 	sljit_s32 mem, sljit_sw memw)
2312 {
2313 	sljit_s32 mem_flags;
2314 	sljit_ins inst;
2315 
2316 	CHECK_ERROR();
2317 	CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
2318 
2319 	if (type & SLJIT_MEM_POST)
2320 		return SLJIT_ERR_UNSUPPORTED;
2321 
2322 	if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
2323 		if (memw != 0)
2324 			return SLJIT_ERR_UNSUPPORTED;
2325 	}
2326 	else {
2327 		if (memw > SIMM_MAX || memw < SIMM_MIN)
2328 			return SLJIT_ERR_UNSUPPORTED;
2329 	}
2330 
2331 	if (type & SLJIT_MEM_SUPP)
2332 		return SLJIT_SUCCESS;
2333 
2334 	mem_flags = FLOAT_DATA(type);
2335 
2336 	if (!(type & SLJIT_MEM_STORE))
2337 		mem_flags |= LOAD_DATA;
2338 
2339 	if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
2340 		inst = updated_data_transfer_insts[mem_flags | INDEXED];
2341 		return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | B(OFFS_REG(mem)));
2342 	}
2343 
2344 	inst = updated_data_transfer_insts[mem_flags];
2345 	return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | IMM(memw));
2346 }
2347 
sljit_emit_const(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw init_value)2348 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
2349 {
2350 	struct sljit_const *const_;
2351 	sljit_s32 dst_r;
2352 
2353 	CHECK_ERROR_PTR();
2354 	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
2355 	ADJUST_LOCAL_OFFSET(dst, dstw);
2356 
2357 	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
2358 	PTR_FAIL_IF(!const_);
2359 	set_const(const_, compiler);
2360 
2361 	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
2362 	PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
2363 
2364 	if (dst & SLJIT_MEM)
2365 		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
2366 
2367 	return const_;
2368 }
2369 
sljit_emit_put_label(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)2370 SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
2371 {
2372 	struct sljit_put_label *put_label;
2373 	sljit_s32 dst_r;
2374 
2375 	CHECK_ERROR_PTR();
2376 	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
2377 	ADJUST_LOCAL_OFFSET(dst, dstw);
2378 
2379 	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
2380 	PTR_FAIL_IF(!put_label);
2381 	set_put_label(put_label, compiler, 0);
2382 
2383 	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
2384 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
2385 	PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
2386 #else
2387 	PTR_FAIL_IF(push_inst(compiler, dst_r));
2388 	compiler->size += 4;
2389 #endif
2390 
2391 	if (dst & SLJIT_MEM)
2392 		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
2393 
2394 	return put_label;
2395 }
2396