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