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