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