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