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