165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/*
265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *    Stack-less Just-In-Time compiler
365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *
465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *    Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved.
565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *
765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * Redistribution and use in source and binary forms, with or without modification, are
865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * permitted provided that the following conditions are met:
965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *
1065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *   1. Redistributions of source code must retain the above copyright notice, this list of
1165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *      conditions and the following disclaimer.
1265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *
1365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *   2. Redistributions in binary form must reproduce the above copyright notice, this list
1465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *      of conditions and the following disclaimer in the documentation and/or other materials
1565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *      provided with the distribution.
1665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *
1765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
1865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
2065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
2265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
2565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich */
2765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
2865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* TileGX architecture. */
2965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Contributed by Tilera Corporation. */
3065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include "sljitNativeTILEGX-encoder.c"
3165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
3265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SIMM_8BIT_MAX (0x7f)
3365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SIMM_8BIT_MIN (-0x80)
3465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SIMM_16BIT_MAX (0x7fff)
3565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SIMM_16BIT_MIN (-0x8000)
3665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SIMM_17BIT_MAX (0xffff)
3765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SIMM_17BIT_MIN (-0x10000)
3865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SIMM_32BIT_MIN (-0x80000000)
3965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SIMM_32BIT_MAX (0x7fffffff)
4065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SIMM_48BIT_MIN (0x800000000000L)
4165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SIMM_48BIT_MAX (0x7fffffff0000L)
4265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define IMM16(imm) ((imm) & 0xffff)
4365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
4465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define UIMM_16BIT_MAX (0xffff)
4565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
4665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
4765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
4865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
4965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ADDR_TMP (SLJIT_NO_REGISTERS + 4)
5065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define PIC_ADDR_REG TMP_REG2
5165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
5265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
5365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	63, 0, 1, 2, 3, 4, 30, 31, 32, 33, 34, 54, 5, 16, 6, 7
5465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich};
5565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
5665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLJIT_LOCALS_REG_mapped 54
5765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define TMP_REG1_mapped 5
5865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define TMP_REG2_mapped 16
5965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define TMP_REG3_mapped 6
6065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ADDR_TMP_mapped 7
6165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLJIT_SAVED_REG1_mapped 30
6265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLJIT_SAVED_REG2_mapped 31
6365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLJIT_SAVED_REG3_mapped 32
6465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLJIT_SAVED_EREG1_mapped 33
6565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLJIT_SAVED_EREG2_mapped 34
6665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
6765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Flags are keept in volatile registers. */
6865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define EQUAL_FLAG 8
6965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* And carry flag as well. */
7065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ULESS_FLAG 9
7165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define UGREATER_FLAG 10
7265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define LESS_FLAG 11
7365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define GREATER_FLAG 12
7465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define OVERFLOW_FLAG 13
7565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
7665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ZERO 63
7765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define RA 55
7865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define TMP_EREG1 14
7965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define TMP_EREG2 15
8065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
8165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define LOAD_DATA 0x01
8265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define WORD_DATA 0x00
8365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BYTE_DATA 0x02
8465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define HALF_DATA 0x04
8565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define INT_DATA 0x06
8665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SIGNED_DATA 0x08
8765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define DOUBLE_DATA 0x10
8865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
8965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Separates integer and floating point registers */
9065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define GPR_REG 0xf
9165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
9265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define MEM_MASK 0x1f
9365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
9465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define WRITE_BACK 0x00020
9565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ARG_TEST 0x00040
9665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ALT_KEEP_CACHE 0x00080
9765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CUMULATIVE_OP 0x00100
9865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define LOGICAL_OP 0x00200
9965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define IMM_OP 0x00400
10065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SRC2_IMM 0x00800
10165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
10265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define UNUSED_DEST 0x01000
10365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define REG_DEST 0x02000
10465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define REG1_SOURCE 0x04000
10565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define REG2_SOURCE 0x08000
10665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLOW_SRC1 0x10000
10765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLOW_SRC2 0x20000
10865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLOW_DEST 0x40000
10965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
11065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Only these flags are set. UNUSED_DEST is not set when no flags should be set.
11165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich */
11265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CHECK_FLAGS(list) (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list))))
11365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
11465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char *sljit_get_platform_name(void)
11565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
11665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return "TileGX" SLJIT_CPUINFO;
11765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
11865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
11965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Length of an instruction word */
12065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef sljit_uw sljit_ins;
12165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
12265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct jit_instr {
12365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const struct tilegx_opcode* opcode;
12465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	tilegx_pipeline pipe;
12565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	unsigned long input_registers;
12665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	unsigned long output_registers;
12765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	int operand_value[4];
12865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	int line;
12965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich};
13065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
13165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Opcode Helper Macros */
13265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define TILEGX_X_MODE 0
13365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
13465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define X_MODE create_Mode(TILEGX_X_MODE)
13565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
13665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define FNOP_X0 \
13765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Opcode_X0(RRR_0_OPCODE_X0) | \
13865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \
13965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0)
14065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
14165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define FNOP_X1 \
14265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Opcode_X1(RRR_0_OPCODE_X1) | \
14365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
14465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_UnaryOpcodeExtension_X1(FNOP_UNARY_OPCODE_X1)
14565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
14665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define NOP \
14765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | FNOP_X0 | FNOP_X1
14865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
14965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ANOP_X0 \
15065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Opcode_X0(RRR_0_OPCODE_X0) | \
15165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \
15265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_UnaryOpcodeExtension_X0(NOP_UNARY_OPCODE_X0)
15365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
15465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BPT create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
15565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
15665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_UnaryOpcodeExtension_X1(ILL_UNARY_OPCODE_X1) | \
15765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Dest_X1(0x1C) | create_SrcA_X1(0x25) | ANOP_X0
15865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
15965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ADD_X1 \
16065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
16165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(ADD_RRR_0_OPCODE_X1) | FNOP_X0
16265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
16365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ADDI_X1 \
16465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
16565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Imm8OpcodeExtension_X1(ADDI_IMM8_OPCODE_X1) | FNOP_X0
16665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
16765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SUB_X1 \
16865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
16965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(SUB_RRR_0_OPCODE_X1) | FNOP_X0
17065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
17165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define NOR_X1 \
17265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
17365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(NOR_RRR_0_OPCODE_X1) | FNOP_X0
17465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
17565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define OR_X1 \
17665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
17765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(OR_RRR_0_OPCODE_X1) | FNOP_X0
17865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
17965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define AND_X1 \
18065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
18165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(AND_RRR_0_OPCODE_X1) | FNOP_X0
18265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
18365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define XOR_X1 \
18465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
18565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(XOR_RRR_0_OPCODE_X1) | FNOP_X0
18665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
18765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CMOVNEZ_X0 \
18865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \
18965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X0(CMOVNEZ_RRR_0_OPCODE_X0) | FNOP_X1
19065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
19165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CMOVEQZ_X0 \
19265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \
19365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X0(CMOVEQZ_RRR_0_OPCODE_X0) | FNOP_X1
19465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
19565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ADDLI_X1 \
19665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(ADDLI_OPCODE_X1) | FNOP_X0
19765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
19865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define V4INT_L_X1 \
19965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
20065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(V4INT_L_RRR_0_OPCODE_X1) | FNOP_X0
20165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
20265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BFEXTU_X0 \
20365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \
20465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_BFOpcodeExtension_X0(BFEXTU_BF_OPCODE_X0) | FNOP_X1
20565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
20665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BFEXTS_X0 \
20765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \
20865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_BFOpcodeExtension_X0(BFEXTS_BF_OPCODE_X0) | FNOP_X1
20965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
21065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SHL16INSLI_X1 \
21165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHL16INSLI_OPCODE_X1) | FNOP_X0
21265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
21365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ST_X1 \
21465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
21565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(ST_RRR_0_OPCODE_X1) | create_Dest_X1(0x0) | FNOP_X0
21665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
21765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define LD_X1 \
21865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
21965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
22065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_UnaryOpcodeExtension_X1(LD_UNARY_OPCODE_X1) | FNOP_X0
22165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
22265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define JR_X1 \
22365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
22465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
22565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_UnaryOpcodeExtension_X1(JR_UNARY_OPCODE_X1) | FNOP_X0
22665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
22765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define JALR_X1 \
22865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
22965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
23065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_UnaryOpcodeExtension_X1(JALR_UNARY_OPCODE_X1) | FNOP_X0
23165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
23265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CLZ_X0 \
23365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \
23465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \
23565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_UnaryOpcodeExtension_X0(CNTLZ_UNARY_OPCODE_X0) | FNOP_X1
23665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
23765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CMPLTUI_X1 \
23865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
23965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Imm8OpcodeExtension_X1(CMPLTUI_IMM8_OPCODE_X1) | FNOP_X0
24065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
24165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CMPLTU_X1 \
24265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
24365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(CMPLTU_RRR_0_OPCODE_X1) | FNOP_X0
24465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
24565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CMPLTS_X1 \
24665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
24765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(CMPLTS_RRR_0_OPCODE_X1) | FNOP_X0
24865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
24965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define XORI_X1 \
25065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
25165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Imm8OpcodeExtension_X1(XORI_IMM8_OPCODE_X1) | FNOP_X0
25265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
25365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ORI_X1 \
25465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
25565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Imm8OpcodeExtension_X1(ORI_IMM8_OPCODE_X1) | FNOP_X0
25665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
25765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ANDI_X1 \
25865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
25965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Imm8OpcodeExtension_X1(ANDI_IMM8_OPCODE_X1) | FNOP_X0
26065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
26165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SHLI_X1 \
26265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \
26365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_ShiftOpcodeExtension_X1(SHLI_SHIFT_OPCODE_X1) | FNOP_X0
26465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
26565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SHL_X1 \
26665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
26765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(SHL_RRR_0_OPCODE_X1) | FNOP_X0
26865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
26965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SHRSI_X1 \
27065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \
27165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_ShiftOpcodeExtension_X1(SHRSI_SHIFT_OPCODE_X1) | FNOP_X0
27265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
27365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SHRS_X1 \
27465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
27565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(SHRS_RRR_0_OPCODE_X1) | FNOP_X0
27665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
27765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SHRUI_X1 \
27865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \
27965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_ShiftOpcodeExtension_X1(SHRUI_SHIFT_OPCODE_X1) | FNOP_X0
28065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
28165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SHRU_X1 \
28265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
28365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_RRROpcodeExtension_X1(SHRU_RRR_0_OPCODE_X1) | FNOP_X0
28465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
28565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BEQZ_X1 \
28665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \
28765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_BrType_X1(BEQZ_BRANCH_OPCODE_X1) | FNOP_X0
28865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
28965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BNEZ_X1 \
29065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \
29165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_BrType_X1(BNEZ_BRANCH_OPCODE_X1) | FNOP_X0
29265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
29365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define J_X1 \
29465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \
29565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_JumpOpcodeExtension_X1(J_JUMP_OPCODE_X1) | FNOP_X0
29665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
29765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define JAL_X1 \
29865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \
29965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	create_JumpOpcodeExtension_X1(JAL_JUMP_OPCODE_X1) | FNOP_X0
30065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
30165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define DEST_X0(x) create_Dest_X0(x)
30265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SRCA_X0(x) create_SrcA_X0(x)
30365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SRCB_X0(x) create_SrcB_X0(x)
30465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define DEST_X1(x) create_Dest_X1(x)
30565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SRCA_X1(x) create_SrcA_X1(x)
30665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SRCB_X1(x) create_SrcB_X1(x)
30765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define IMM16_X1(x) create_Imm16_X1(x)
30865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define IMM8_X1(x) create_Imm8_X1(x)
30965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BFSTART_X0(x) create_BFStart_X0(x)
31065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BFEND_X0(x) create_BFEnd_X0(x)
31165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SHIFTIMM_X1(x) create_ShAmt_X1(x)
31265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define JOFF_X1(x) create_JumpOff_X1(x)
31365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BOFF_X1(x) create_BrOff_X1(x)
31465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
31565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_CONST tilegx_mnemonic data_transfer_insts[16] = {
31665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* u w s */ TILEGX_OPC_ST   /* st */,
31765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* u w l */ TILEGX_OPC_LD   /* ld */,
31865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* u b s */ TILEGX_OPC_ST1  /* st1 */,
31965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* u b l */ TILEGX_OPC_LD1U /* ld1u */,
32065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* u h s */ TILEGX_OPC_ST2  /* st2 */,
32165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* u h l */ TILEGX_OPC_LD2U /* ld2u */,
32265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* u i s */ TILEGX_OPC_ST4  /* st4 */,
32365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* u i l */ TILEGX_OPC_LD4U /* ld4u */,
32465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* s w s */ TILEGX_OPC_ST   /* st */,
32565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* s w l */ TILEGX_OPC_LD   /* ld */,
32665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* s b s */ TILEGX_OPC_ST1  /* st1 */,
32765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* s b l */ TILEGX_OPC_LD1S /* ld1s */,
32865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* s h s */ TILEGX_OPC_ST2  /* st2 */,
32965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* s h l */ TILEGX_OPC_LD2S /* ld2s */,
33065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* s i s */ TILEGX_OPC_ST4  /* st4 */,
33165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* s i l */ TILEGX_OPC_LD4S /* ld4s */,
33265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich};
33365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
33465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
33565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, int line)
33665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
33765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
33865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(!ptr);
33965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	*ptr = ins;
34065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->size++;
34165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	printf("|%04d|S0|:\t\t", line);
34265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	print_insn_tilegx(ptr);
34365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
34465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
34565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
34665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins)
34765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
34865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
34965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(!ptr);
35065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	*ptr = ins;
35165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->size++;
35265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
35365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
35465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
35565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define push_inst(a, b) push_inst_debug(a, b, __LINE__)
35665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else
35765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins)
35865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
35965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
36065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(!ptr);
36165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	*ptr = ins;
36265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->size++;
36365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
36465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
36565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
36665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
36765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BUNDLE_FORMAT_MASK(p0, p1, p2) \
36865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	((p0) | ((p1) << 8) | ((p2) << 16))
36965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
37065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BUNDLE_FORMAT(p0, p1, p2) \
37165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	{ \
37265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		{ \
37365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			(tilegx_pipeline)(p0), \
37465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			(tilegx_pipeline)(p1), \
37565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			(tilegx_pipeline)(p2) \
37665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}, \
37765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		BUNDLE_FORMAT_MASK(1 << (p0), 1 << (p1), (1 << (p2))) \
37865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
37965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
38065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define NO_PIPELINE TILEGX_NUM_PIPELINE_ENCODINGS
38165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
38265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1)
38365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
38465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define PI(encoding) \
38565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_inst(compiler, encoding)
38665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
38765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define PB3(opcode, dst, srca, srcb) \
38865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, opcode, dst, srca, srcb, __LINE__)
38965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
39065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define PB2(opcode, dst, src) \
39165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_2_buffer(compiler, opcode, dst, src, __LINE__)
39265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
39365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define JR(reg) \
39465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_jr_buffer(compiler, TILEGX_OPC_JR, reg, __LINE__)
39565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
39665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ADD(dst, srca, srcb) \
39765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_ADD, dst, srca, srcb, __LINE__)
39865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
39965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SUB(dst, srca, srcb) \
40065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_SUB, dst, srca, srcb, __LINE__)
40165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
40265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define NOR(dst, srca, srcb) \
40365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_NOR, dst, srca, srcb, __LINE__)
40465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
40565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define OR(dst, srca, srcb) \
40665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_OR, dst, srca, srcb, __LINE__)
40765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
40865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define XOR(dst, srca, srcb) \
40965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_XOR, dst, srca, srcb, __LINE__)
41065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
41165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define AND(dst, srca, srcb) \
41265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_AND, dst, srca, srcb, __LINE__)
41365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
41465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CLZ(dst, src) \
41565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_2_buffer(compiler, TILEGX_OPC_CLZ, dst, src, __LINE__)
41665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
41765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SHLI(dst, srca, srcb) \
41865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_SHLI, dst, srca, srcb, __LINE__)
41965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
42065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SHRUI(dst, srca, imm) \
42165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_SHRUI, dst, srca, imm, __LINE__)
42265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
42365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define XORI(dst, srca, imm) \
42465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_XORI, dst, srca, imm, __LINE__)
42565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
42665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ORI(dst, srca, imm) \
42765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_ORI, dst, srca, imm, __LINE__)
42865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
42965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CMPLTU(dst, srca, srcb) \
43065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_CMPLTU, dst, srca, srcb, __LINE__)
43165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
43265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CMPLTS(dst, srca, srcb) \
43365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_CMPLTS, dst, srca, srcb, __LINE__)
43465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
43565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CMPLTUI(dst, srca, imm) \
43665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_CMPLTUI, dst, srca, imm, __LINE__)
43765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
43865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CMOVNEZ(dst, srca, srcb) \
43965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_CMOVNEZ, dst, srca, srcb, __LINE__)
44065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
44165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CMOVEQZ(dst, srca, srcb) \
44265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_CMOVEQZ, dst, srca, srcb, __LINE__)
44365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
44465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ADDLI(dst, srca, srcb) \
44565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_ADDLI, dst, srca, srcb, __LINE__)
44665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
44765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SHL16INSLI(dst, srca, srcb) \
44865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_SHL16INSLI, dst, srca, srcb, __LINE__)
44965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
45065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define LD_ADD(dst, addr, adjust) \
45165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_LD_ADD, dst, addr, adjust, __LINE__)
45265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
45365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ST_ADD(src, addr, adjust) \
45465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_3_buffer(compiler, TILEGX_OPC_ST_ADD, src, addr, adjust, __LINE__)
45565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
45665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define LD(dst, addr) \
45765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_2_buffer(compiler, TILEGX_OPC_LD, dst, addr, __LINE__)
45865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
45965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BFEXTU(dst, src, start, end) \
46065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_4_buffer(compiler, TILEGX_OPC_BFEXTU, dst, src, start, end, __LINE__)
46165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
46265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BFEXTS(dst, src, start, end) \
46365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_4_buffer(compiler, TILEGX_OPC_BFEXTS, dst, src, start, end, __LINE__)
46465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
46565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ADD_SOLO(dest, srca, srcb) \
46665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_inst(compiler, ADD_X1 | DEST_X1(dest) | SRCA_X1(srca) | SRCB_X1(srcb))
46765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
46865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ADDI_SOLO(dest, srca, imm) \
46965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_inst(compiler, ADDI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM8_X1(imm))
47065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
47165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ADDLI_SOLO(dest, srca, imm) \
47265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_inst(compiler, ADDLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm))
47365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
47465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SHL16INSLI_SOLO(dest, srca, imm) \
47565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_inst(compiler, SHL16INSLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm))
47665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
47765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define JALR_SOLO(reg) \
47865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_inst(compiler, JALR_X1 | SRCA_X1(reg))
47965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
48065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define JR_SOLO(reg) \
48165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	push_inst(compiler, JR_X1 | SRCA_X1(reg))
48265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
48365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct Format {
48465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* Mapping of bundle issue slot to assigned pipe. */
48565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	tilegx_pipeline pipe[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
48665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
48765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* Mask of pipes used by this bundle. */
48865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	unsigned int pipe_mask;
48965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich};
49065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
49165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconst struct Format formats[] =
49265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
49365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* In Y format we must always have something in Y2, since it has
49465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	* no fnop, so this conveys that Y2 must always be used. */
49565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, NO_PIPELINE),
49665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, NO_PIPELINE),
49765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, NO_PIPELINE),
49865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, NO_PIPELINE),
49965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
50065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* Y format has three instructions. */
50165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2),
50265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1),
50365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2),
50465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0),
50565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1),
50665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0),
50765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
50865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* X format has only two instructions. */
50965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	BUNDLE_FORMAT(TILEGX_PIPELINE_X0, TILEGX_PIPELINE_X1, NO_PIPELINE),
51065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	BUNDLE_FORMAT(TILEGX_PIPELINE_X1, TILEGX_PIPELINE_X0, NO_PIPELINE)
51165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich};
51265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
51365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
51465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct jit_instr inst_buf[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
51565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichunsigned long inst_buf_index;
51665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
51765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtilegx_pipeline get_any_valid_pipe(const struct tilegx_opcode* opcode)
51865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
51965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* FIXME: tile: we could pregenerate this. */
52065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	int pipe;
52165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	for (pipe = 0; ((opcode->pipes & (1 << pipe)) == 0 && pipe < TILEGX_NUM_PIPELINE_ENCODINGS); pipe++)
52265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		;
52365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return (tilegx_pipeline)(pipe);
52465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
52565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
52665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichvoid insert_nop(tilegx_mnemonic opc, int line)
52765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
52865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const struct tilegx_opcode* opcode = NULL;
52965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
53065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	memmove(&inst_buf[1], &inst_buf[0], inst_buf_index * sizeof inst_buf[0]);
53165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
53265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	opcode = &tilegx_opcodes[opc];
53365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[0].opcode = opcode;
53465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[0].pipe = get_any_valid_pipe(opcode);
53565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[0].input_registers = 0;
53665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[0].output_registers = 0;
53765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[0].line = line;
53865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	++inst_buf_index;
53965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
54065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
54165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconst struct Format* compute_format()
54265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
54365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	unsigned int compatible_pipes = BUNDLE_FORMAT_MASK(
54465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[0].opcode->pipes,
54565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[1].opcode->pipes,
54665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		(inst_buf_index == 3 ? inst_buf[2].opcode->pipes : (1 << NO_PIPELINE)));
54765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
54865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const struct Format* match = NULL;
54965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const struct Format *b = NULL;
55065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	unsigned int i = 0;
55165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	for (i; i < sizeof formats / sizeof formats[0]; i++) {
55265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		b = &formats[i];
55365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if ((b->pipe_mask & compatible_pipes) == b->pipe_mask) {
55465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			match = b;
55565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			break;
55665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
55765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
55865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
55965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return match;
56065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
56165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
56265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_si assign_pipes()
56365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
56465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	unsigned long output_registers = 0;
56565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	unsigned int i = 0;
56665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
56765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (inst_buf_index == 1) {
56865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		tilegx_mnemonic opc = inst_buf[0].opcode->can_bundle
56965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					? TILEGX_OPC_FNOP : TILEGX_OPC_NOP;
57065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		insert_nop(opc, __LINE__);
57165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
57265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
57365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const struct Format* match = compute_format();
57465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
57565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (match == NULL)
57665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return -1;
57765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
57865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	for (i = 0; i < inst_buf_index; i++) {
57965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
58065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if ((i > 0) && ((inst_buf[i].input_registers & output_registers) != 0))
58165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return -1;
58265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
58365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if ((i > 0) && ((inst_buf[i].output_registers & output_registers) != 0))
58465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return -1;
58565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
58665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		/* Don't include Rzero in the match set, to avoid triggering
58765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		   needlessly on 'prefetch' instrs. */
58865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
58965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		output_registers |= inst_buf[i].output_registers & 0xFFFFFFFFFFFFFFL;
59065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
59165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[i].pipe = match->pipe[i];
59265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
59365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
59465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* If only 2 instrs, and in Y-mode, insert a nop. */
59565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (inst_buf_index == 2 && !tilegx_is_x_pipeline(match->pipe[0])) {
59665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		insert_nop(TILEGX_OPC_FNOP, __LINE__);
59765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
59865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		/* Select the yet unassigned pipe. */
59965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		tilegx_pipeline pipe = (tilegx_pipeline)(((TILEGX_PIPELINE_Y0
60065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					+ TILEGX_PIPELINE_Y1 + TILEGX_PIPELINE_Y2)
60165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					- (inst_buf[1].pipe + inst_buf[2].pipe)));
60265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
60365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[0].pipe = pipe;
60465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
60565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
60665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return 0;
60765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
60865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
60965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtilegx_bundle_bits get_bundle_bit(struct jit_instr *inst)
61065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
61165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	int i, val;
61265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const struct tilegx_opcode* opcode = inst->opcode;
61365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	tilegx_bundle_bits bits = opcode->fixed_bit_values[inst->pipe];
61465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
61565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const struct tilegx_operand* operand = NULL;
61665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	for (i = 0; i < opcode->num_operands; i++) {
61765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		operand = &tilegx_operands[opcode->operands[inst->pipe][i]];
61865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		val = inst->operand_value[i];
61965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
62065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		bits |= operand->insert(val);
62165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
62265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
62365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return bits;
62465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
62565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
62665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si update_buffer(struct sljit_compiler *compiler)
62765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
62865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	int count;
62965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	int i;
63065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	int orig_index = inst_buf_index;
63165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	struct jit_instr inst0 = inst_buf[0];
63265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	struct jit_instr inst1 = inst_buf[1];
63365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	struct jit_instr inst2 = inst_buf[2];
63465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	tilegx_bundle_bits bits = 0;
63565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
63665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* If the bundle is valid as is, perform the encoding and return 1. */
63765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (assign_pipes() == 0) {
63865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		for (i = 0; i < inst_buf_index; i++) {
63965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			bits |= get_bundle_bit(inst_buf + i);
64065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
64165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			printf("|%04d", inst_buf[i].line);
64265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
64365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
64465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
64565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (inst_buf_index == 3)
64665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			printf("|M0|:\t");
64765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		else
64865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			printf("|M0|:\t\t");
64965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		print_insn_tilegx(&bits);
65065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
65165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
65265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf_index = 0;
65365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
65465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
65565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return push_inst_nodebug(compiler, bits);
65665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else
65765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return push_inst(compiler, bits);
65865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
65965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
66065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
66165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* If the bundle is invalid, split it in two. First encode the first two
66265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	   (or possibly 1) instructions, and then the last, separately. Note that
66365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	   assign_pipes may have re-ordered the instrs (by inserting no-ops in
66465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	   lower slots) so we need to reset them. */
66565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
66665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf_index = orig_index - 1;
66765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[0] = inst0;
66865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[1] = inst1;
66965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[2] = inst2;
67065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (assign_pipes() == 0) {
67165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		for (i = 0; i < inst_buf_index; i++) {
67265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			bits |= get_bundle_bit(inst_buf + i);
67365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
67465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			printf("|%04d", inst_buf[i].line);
67565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
67665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
67765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
67865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
67965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (inst_buf_index == 3)
68065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			printf("|M1|:\t");
68165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		else
68265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			printf("|M1|:\t\t");
68365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		print_insn_tilegx(&bits);
68465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
68565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
68665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if ((orig_index - 1) == 2) {
68765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			inst_buf[0] = inst2;
68865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			inst_buf_index = 1;
68965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else if ((orig_index - 1) == 1) {
69065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			inst_buf[0] = inst1;
69165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			inst_buf_index = 1;
69265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else
69365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			SLJIT_ASSERT_STOP();
69465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
69565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
69665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return push_inst_nodebug(compiler, bits);
69765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else
69865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return push_inst(compiler, bits);
69965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
70065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else {
70165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		/* We had 3 instrs of which the first 2 can't live in the same bundle.
70265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		   Split those two. Note that we don't try to then combine the second
70365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		   and third instr into a single bundle.  First instruction: */
70465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf_index = 1;
70565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[0] = inst0;
70665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[1] = inst1;
70765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[2] = inst2;
70865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (assign_pipes() == 0) {
70965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			for (i = 0; i < inst_buf_index; i++) {
71065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				bits |= get_bundle_bit(inst_buf + i);
71165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
71265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				printf("|%04d", inst_buf[i].line);
71365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
71465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
71565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
71665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
71765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (inst_buf_index == 3)
71865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				printf("|M2|:\t");
71965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			else
72065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				printf("|M2|:\t\t");
72165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			print_insn_tilegx(&bits);
72265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
72365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
72465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			inst_buf[0] = inst1;
72565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			inst_buf[1] = inst2;
72665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			inst_buf_index = orig_index - 1;
72765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
72865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return push_inst_nodebug(compiler, bits);
72965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else
73065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return push_inst(compiler, bits);
73165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
73265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else
73365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			SLJIT_ASSERT_STOP();
73465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
73565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
73665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_ASSERT_STOP();
73765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
73865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
73965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si flush_buffer(struct sljit_compiler *compiler)
74065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
74165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	while (inst_buf_index != 0)
74265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		update_buffer(compiler);
74365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
74465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
74565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line)
74665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
74765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
74865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(update_buffer(compiler));
74965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
75065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
75165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].opcode = opcode;
75265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
75365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].operand_value[0] = op0;
75465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].operand_value[1] = op1;
75565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].operand_value[2] = op2;
75665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].operand_value[3] = op3;
75765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].input_registers = 1L << op1;
75865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].output_registers = 1L << op0;
75965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].line = line;
76065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf_index++;
76165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
76265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
76365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
76465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
76565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int line)
76665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
76765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
76865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(update_buffer(compiler));
76965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
77065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
77165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].opcode = opcode;
77265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
77365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].operand_value[0] = op0;
77465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].operand_value[1] = op1;
77565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].operand_value[2] = op2;
77665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].line = line;
77765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
77865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	switch (opc) {
77965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_ST_ADD:
78065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1);
78165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[inst_buf_index].output_registers = 1L << op0;
78265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
78365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_LD_ADD:
78465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[inst_buf_index].input_registers = 1L << op1;
78565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[inst_buf_index].output_registers = (1L << op0) | (1L << op1);
78665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
78765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_ADD:
78865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_AND:
78965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_SUB:
79065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_OR:
79165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_XOR:
79265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_NOR:
79365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_SHL:
79465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_SHRU:
79565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_SHRS:
79665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_CMPLTU:
79765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_CMPLTS:
79865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_CMOVEQZ:
79965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_CMOVNEZ:
80065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[inst_buf_index].input_registers = (1L << op1) | (1L << op2);
80165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[inst_buf_index].output_registers = 1L << op0;
80265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
80365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_ADDLI:
80465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_XORI:
80565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_ORI:
80665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_SHLI:
80765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_SHRUI:
80865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_SHRSI:
80965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_SHL16INSLI:
81065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_CMPLTUI:
81165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_CMPLTSI:
81265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[inst_buf_index].input_registers = 1L << op1;
81365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[inst_buf_index].output_registers = 1L << op0;
81465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
81565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	default:
81665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		printf("unrecoginzed opc: %s\n", opcode->name);
81765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT_STOP();
81865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
81965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
82065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf_index++;
82165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
82265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
82365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
82465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
82565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int line)
82665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
82765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
82865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(update_buffer(compiler));
82965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
83065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
83165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].opcode = opcode;
83265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
83365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].operand_value[0] = op0;
83465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].operand_value[1] = op1;
83565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].line = line;
83665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
83765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	switch (opc) {
83865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_BEQZ:
83965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_BNEZ:
84065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[inst_buf_index].input_registers = 1L << op0;
84165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
84265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_ST:
84365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_ST1:
84465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_ST2:
84565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_ST4:
84665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1);
84765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[inst_buf_index].output_registers = 0;
84865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
84965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_CLZ:
85065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_LD:
85165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_LD1U:
85265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_LD1S:
85365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_LD2U:
85465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_LD2S:
85565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_LD4U:
85665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case TILEGX_OPC_LD4S:
85765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[inst_buf_index].input_registers = 1L << op1;
85865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst_buf[inst_buf_index].output_registers = 1L << op0;
85965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
86065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	default:
86165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		printf("unrecoginzed opc: %s\n", opcode->name);
86265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT_STOP();
86365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
86465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
86565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf_index++;
86665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
86765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
86865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
86965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
87065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int line)
87165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
87265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
87365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(update_buffer(compiler));
87465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
87565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
87665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].opcode = opcode;
87765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
87865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].input_registers = 0;
87965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].output_registers = 0;
88065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].line = line;
88165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf_index++;
88265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
88365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
88465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
88565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
88665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int line)
88765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
88865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
88965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(update_buffer(compiler));
89065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
89165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
89265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].opcode = opcode;
89365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
89465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].operand_value[0] = op0;
89565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].input_registers = 1L << op0;
89665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].output_registers = 0;
89765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf[inst_buf_index].line = line;
89865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst_buf_index++;
89965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
90065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return flush_buffer(compiler);
90165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
90265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
90365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE sljit_ins * detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
90465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
90565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_sw diff;
90665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_uw target_addr;
90765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins *inst;
90865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins saved_inst;
90965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
91065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (jump->flags & SLJIT_REWRITABLE_JUMP)
91165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return code_ptr;
91265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
91365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (jump->flags & JUMP_ADDR)
91465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		target_addr = jump->u.target;
91565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	else {
91665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT(jump->flags & JUMP_LABEL);
91765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		target_addr = (sljit_uw)(code + jump->u.label->size);
91865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
91965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
92065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst = (sljit_ins *)jump->addr;
92165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (jump->flags & IS_COND)
92265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst--;
92365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
92465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	diff = ((sljit_sw) target_addr - (sljit_sw) inst) >> 3;
92565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (diff <= SIMM_17BIT_MAX && diff >= SIMM_17BIT_MIN) {
92665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		jump->flags |= PATCH_B;
92765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
92865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (!(jump->flags & IS_COND)) {
92965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (jump->flags & IS_JAL) {
93065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				jump->flags &= ~(PATCH_B);
93165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				jump->flags |= PATCH_J;
93265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				inst[0] = JAL_X1;
93365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
93465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
93565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				printf("[runtime relocate]%04d:\t", __LINE__);
93665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				print_insn_tilegx(inst);
93765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
93865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			} else {
93965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				inst[0] = BEQZ_X1 | SRCA_X1(ZERO);
94065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
94165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
94265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				printf("[runtime relocate]%04d:\t", __LINE__);
94365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				print_insn_tilegx(inst);
94465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
94565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
94665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
94765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return inst;
94865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
94965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
95065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst[0] = inst[0] ^ (0x7L << 55);
95165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
95265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
95365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		printf("[runtime relocate]%04d:\t", __LINE__);
95465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		print_insn_tilegx(inst);
95565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
95665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		jump->addr -= sizeof(sljit_ins);
95765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return inst;
95865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
95965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
96065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (jump->flags & IS_COND) {
96165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) {
96265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			jump->flags |= PATCH_J;
96365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			inst[0] = (inst[0] & ~(BOFF_X1(-1))) | BOFF_X1(2);
96465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			inst[1] = J_X1;
96565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return inst + 1;
96665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
96765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
96865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return code_ptr;
96965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
97065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
97165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) {
97265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		jump->flags |= PATCH_J;
97365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
97465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (jump->flags & IS_JAL) {
97565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			inst[0] = JAL_X1;
97665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
97765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
97865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			printf("[runtime relocate]%04d:\t", __LINE__);
97965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			print_insn_tilegx(inst);
98065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
98165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
98265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else {
98365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			inst[0] = J_X1;
98465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
98565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
98665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			printf("[runtime relocate]%04d:\t", __LINE__);
98765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			print_insn_tilegx(inst);
98865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
98965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
99065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
99165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return inst;
99265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
99365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
99465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return code_ptr;
99565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
99665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
99765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compiler)
99865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
99965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	struct sljit_memory_fragment *buf;
100065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins *code;
100165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins *code_ptr;
100265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins *buf_ptr;
100365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins *buf_end;
100465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_uw word_count;
100565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_uw addr;
100665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
100765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	struct sljit_label *label;
100865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	struct sljit_jump *jump;
100965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	struct sljit_const *const_;
101065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
101165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR_PTR();
101265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_generate_code(compiler);
101365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	reverse_buf(compiler);
101465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
101565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	code = (sljit_ins *)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
101665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	PTR_FAIL_WITH_EXEC_IF(code);
101765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	buf = compiler->buf;
101865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
101965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	code_ptr = code;
102065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	word_count = 0;
102165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	label = compiler->labels;
102265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	jump = compiler->jumps;
102365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const_ = compiler->consts;
102465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	do {
102565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		buf_ptr = (sljit_ins *)buf->memory;
102665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		buf_end = buf_ptr + (buf->used_size >> 3);
102765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		do {
102865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			*code_ptr = *buf_ptr++;
102965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			SLJIT_ASSERT(!label || label->size >= word_count);
103065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			SLJIT_ASSERT(!jump || jump->addr >= word_count);
103165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			SLJIT_ASSERT(!const_ || const_->addr >= word_count);
103265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			/* These structures are ordered by their address. */
103365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (label && label->size == word_count) {
103465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				/* Just recording the address. */
103565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				label->addr = (sljit_uw) code_ptr;
103665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				label->size = code_ptr - code;
103765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				label = label->next;
103865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
103965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
104065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (jump && jump->addr == word_count) {
104165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if (jump->flags & IS_JAL)
104265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					jump->addr = (sljit_uw)(code_ptr - 4);
104365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				else
104465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					jump->addr = (sljit_uw)(code_ptr - 3);
104565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
104665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				code_ptr = detect_jump_type(jump, code_ptr, code);
104765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				jump = jump->next;
104865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
104965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
105065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (const_ && const_->addr == word_count) {
105165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				/* Just recording the address. */
105265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				const_->addr = (sljit_uw) code_ptr;
105365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				const_ = const_->next;
105465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
105565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
105665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			code_ptr++;
105765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			word_count++;
105865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} while (buf_ptr < buf_end);
105965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
106065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		buf = buf->next;
106165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} while (buf);
106265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
106365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (label && label->size == word_count) {
106465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		label->addr = (sljit_uw) code_ptr;
106565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		label->size = code_ptr - code;
106665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		label = label->next;
106765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
106865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
106965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_ASSERT(!label);
107065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_ASSERT(!jump);
107165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_ASSERT(!const_);
107265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
107365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
107465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	jump = compiler->jumps;
107565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	while (jump) {
107665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		do {
107765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
107865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			buf_ptr = (sljit_ins *)jump->addr;
107965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
108065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (jump->flags & PATCH_B) {
108165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				addr = (sljit_sw)(addr - (jump->addr)) >> 3;
108265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				SLJIT_ASSERT((sljit_sw) addr <= SIMM_17BIT_MAX && (sljit_sw) addr >= SIMM_17BIT_MIN);
108365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				buf_ptr[0] = (buf_ptr[0] & ~(BOFF_X1(-1))) | BOFF_X1(addr);
108465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
108565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
108665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				printf("[runtime relocate]%04d:\t", __LINE__);
108765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				print_insn_tilegx(buf_ptr);
108865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
108965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				break;
109065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
109165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
109265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (jump->flags & PATCH_J) {
109365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				SLJIT_ASSERT((addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL));
109465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				addr = (sljit_sw)(addr - (jump->addr)) >> 3;
109565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				buf_ptr[0] = (buf_ptr[0] & ~(JOFF_X1(-1))) | JOFF_X1(addr);
109665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
109765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef TILEGX_JIT_DEBUG
109865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				printf("[runtime relocate]%04d:\t", __LINE__);
109965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				print_insn_tilegx(buf_ptr);
110065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
110165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				break;
110265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
110365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
110465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			SLJIT_ASSERT(!(jump->flags & IS_JAL));
110565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
110665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			/* Set the fields of immediate loads. */
110765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			buf_ptr[0] = (buf_ptr[0] & ~(0xFFFFL << 43)) | (((addr >> 32) & 0xFFFFL) << 43);
110865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			buf_ptr[1] = (buf_ptr[1] & ~(0xFFFFL << 43)) | (((addr >> 16) & 0xFFFFL) << 43);
110965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			buf_ptr[2] = (buf_ptr[2] & ~(0xFFFFL << 43)) | ((addr & 0xFFFFL) << 43);
111065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} while (0);
111165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
111265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		jump = jump->next;
111365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
111465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
111565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->error = SLJIT_ERR_COMPILED;
111665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
111765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_CACHE_FLUSH(code, code_ptr);
111865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return code;
111965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
112065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
112165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm)
112265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
112365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
112465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (imm <= SIMM_16BIT_MAX && imm >= SIMM_16BIT_MIN)
112565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return ADDLI(dst_ar, ZERO, imm);
112665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
112765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (imm <= SIMM_32BIT_MAX && imm >= SIMM_32BIT_MIN) {
112865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 16));
112965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SHL16INSLI(dst_ar, dst_ar, imm);
113065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
113165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
113265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (imm <= SIMM_48BIT_MAX && imm >= SIMM_48BIT_MIN) {
113365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32));
113465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));
113565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SHL16INSLI(dst_ar, dst_ar, imm);
113665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
113765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
113865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 48));
113965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 32));
114065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));
114165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SHL16INSLI(dst_ar, dst_ar, imm);
114265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
114365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
114465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm, int flush)
114565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
114665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* Should *not* be optimized as load_immediate, as pcre relocation
114765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	   mechanism will match this fixed 4-instruction pattern. */
114865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (flush) {
114965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADDLI_SOLO(dst_ar, ZERO, imm >> 32));
115065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(SHL16INSLI_SOLO(dst_ar, dst_ar, imm >> 16));
115165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SHL16INSLI_SOLO(dst_ar, dst_ar, imm);
115265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
115365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
115465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32));
115565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));
115665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SHL16INSLI(dst_ar, dst_ar, imm);
115765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
115865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
115965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si emit_const_64(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm, int flush)
116065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
116165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* Should *not* be optimized as load_immediate, as pcre relocation
116265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	   mechanism will match this fixed 4-instruction pattern. */
116365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (flush) {
116465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADDLI_SOLO(reg_map[dst_ar], ZERO, imm >> 48));
116565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 32));
116665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 16));
116765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm);
116865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
116965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
117065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(ADDLI(reg_map[dst_ar], ZERO, imm >> 48));
117165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 32));
117265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 16));
117365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm);
117465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
117565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
117665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
117765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
117865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
117965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
118065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins base;
118165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins bundle = 0;
118265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
118365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR();
118465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
118565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
118665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->options = options;
118765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->scratches = scratches;
118865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->saveds = saveds;
118965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->fscratches = fscratches;
119065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->fsaveds = fsaveds;
119165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
119265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->logical_local_size = local_size;
119365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
119465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
119565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	local_size += (saveds + 1) * sizeof(sljit_sw);
119665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	local_size = (local_size + 7) & ~7;
119765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->local_size = local_size;
119865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
119965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (local_size <= SIMM_16BIT_MAX) {
120065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		/* Frequent case. */
120165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, -local_size));
120265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		base = SLJIT_LOCALS_REG_mapped;
120365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else {
120465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size));
120565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADD(TMP_REG2_mapped, SLJIT_LOCALS_REG_mapped, ZERO));
120665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(SUB(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped));
120765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		base = TMP_REG2_mapped;
120865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		local_size = 0;
120965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
121065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
121165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));
121265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(ST_ADD(ADDR_TMP_mapped, RA, -8));
121365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
121465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (saveds >= 1)
121565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_REG1_mapped, -8));
121665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
121765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (saveds >= 2)
121865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_REG2_mapped, -8));
121965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
122065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (saveds >= 3)
122165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_REG3_mapped, -8));
122265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
122365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (saveds >= 4)
122465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_EREG1_mapped, -8));
122565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
122665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (saveds >= 5)
122765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_EREG2_mapped, -8));
122865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
122965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (args >= 1)
123065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADD(SLJIT_SAVED_REG1_mapped, 0, ZERO));
123165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
123265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (args >= 2)
123365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADD(SLJIT_SAVED_REG2_mapped, 1, ZERO));
123465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
123565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (args >= 3)
123665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADD(SLJIT_SAVED_REG3_mapped, 2, ZERO));
123765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
123865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
123965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
124065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
124165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
124265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
124365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
124465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
124565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR_VOID();
124665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
124765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
124865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->options = options;
124965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->scratches = scratches;
125065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->saveds = saveds;
125165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->fscratches = fscratches;
125265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->fsaveds = fsaveds;
125365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
125465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->logical_local_size = local_size;
125565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
125665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
125765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	local_size += (saveds + 1) * sizeof(sljit_sw);
125865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->local_size = (local_size + 7) & ~7;
125965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
126065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
126165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
126265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
126365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si local_size;
126465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins base;
126565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	int addr_initialized = 0;
126665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
126765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR();
126865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_emit_return(compiler, op, src, srcw);
126965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
127065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
127165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
127265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	local_size = compiler->local_size;
127365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (local_size <= SIMM_16BIT_MAX)
127465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		base = SLJIT_LOCALS_REG_mapped;
127565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	else {
127665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size));
127765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADD(TMP_REG1_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped));
127865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		base = TMP_REG1_mapped;
127965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		local_size = 0;
128065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
128165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
128265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));
128365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(LD(RA, ADDR_TMP_mapped));
128465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
128565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (compiler->saveds >= 5) {
128665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 48));
128765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		addr_initialized = 1;
128865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
128965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(LD_ADD(SLJIT_SAVED_EREG2_mapped, ADDR_TMP_mapped, 8));
129065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
129165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
129265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (compiler->saveds >= 4) {
129365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (addr_initialized == 0) {
129465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 40));
129565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			addr_initialized = 1;
129665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
129765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
129865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(LD_ADD(SLJIT_SAVED_EREG1_mapped, ADDR_TMP_mapped, 8));
129965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
130065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
130165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (compiler->saveds >= 3) {
130265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (addr_initialized == 0) {
130365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 32));
130465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			addr_initialized = 1;
130565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
130665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
130765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(LD_ADD(SLJIT_SAVED_REG3_mapped, ADDR_TMP_mapped, 8));
130865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
130965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
131065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (compiler->saveds >= 2) {
131165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (addr_initialized == 0) {
131265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 24));
131365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			addr_initialized = 1;
131465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
131565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
131665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(LD_ADD(SLJIT_SAVED_REG2_mapped, ADDR_TMP_mapped, 8));
131765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
131865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
131965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (compiler->saveds >= 1) {
132065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (addr_initialized == 0) {
132165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 16));
132265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			/* addr_initialized = 1; no need to initialize as it's the last one. */
132365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
132465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
132565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(LD_ADD(SLJIT_SAVED_REG1_mapped, ADDR_TMP_mapped, 8));
132665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
132765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
132865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (compiler->local_size <= SIMM_16BIT_MAX)
132965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, compiler->local_size));
133065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	else
133165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADD(SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped, ZERO));
133265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
133365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return JR(RA);
133465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
133565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
133665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* reg_ar is an absoulute register! */
133765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
133865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Can perform an operation using at most 1 instruction. */
133965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw)
134065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
134165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_ASSERT(arg & SLJIT_MEM);
134265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
134365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if ((!(flags & WRITE_BACK) || !(arg & REG_MASK))
134465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			&& !(arg & OFFS_REG_MASK) && argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
134565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		/* Works for both absoulte and relative addresses. */
134665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (SLJIT_UNLIKELY(flags & ARG_TEST))
134765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return 1;
134865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
134965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[arg & REG_MASK], argw));
135065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
135165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (flags & LOAD_DATA)
135265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped));
135365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		else
135465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar));
135565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
135665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return -1;
135765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
135865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
135965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return 0;
136065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
136165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
136265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* See getput_arg below.
136365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich   Note: can_cache is called only for binary operators. Those
136465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich   operators always uses word arguments without write back. */
136565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
136665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
136765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
136865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
136965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* Simple operation except for updates. */
137065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (arg & OFFS_REG_MASK) {
137165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		argw &= 0x3;
137265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		next_argw &= 0x3;
137365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (argw && argw == next_argw
137465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				&& (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))
137565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return 1;
137665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return 0;
137765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
137865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
137965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (arg == next_arg) {
138065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (((next_argw - argw) <= SIMM_16BIT_MAX
138165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				&& (next_argw - argw) >= SIMM_16BIT_MIN))
138265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return 1;
138365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
138465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return 0;
138565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
138665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
138765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return 0;
138865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
138965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
139065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Emit the necessary instructions. See can_cache above. */
139165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
139265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
139365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si tmp_ar, base;
139465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
139565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_ASSERT(arg & SLJIT_MEM);
139665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (!(next_arg & SLJIT_MEM)) {
139765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		next_arg = 0;
139865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		next_argw = 0;
139965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
140065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
140165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA))
140265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		tmp_ar = reg_ar;
140365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	else
140465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		tmp_ar = TMP_REG1_mapped;
140565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
140665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	base = arg & REG_MASK;
140765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
140865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
140965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		argw &= 0x3;
141065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
141165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if ((flags & WRITE_BACK) && reg_ar == reg_map[base]) {
141265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			SLJIT_ASSERT(!(flags & LOAD_DATA) && reg_map[TMP_REG1] != reg_ar);
141365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO));
141465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			reg_ar = TMP_REG1_mapped;
141565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
141665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
141765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		/* Using the cache. */
141865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (argw == compiler->cache_argw) {
141965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (!(flags & WRITE_BACK)) {
142065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if (arg == compiler->cache_arg) {
142165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					if (flags & LOAD_DATA)
142265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich						return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
142365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					else
142465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich						return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
142565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				}
142665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
142765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
142865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					if (arg == next_arg && argw == (next_argw & 0x3)) {
142965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich						compiler->cache_arg = arg;
143065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich						compiler->cache_argw = argw;
143165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich						FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], TMP_REG3_mapped));
143265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich						if (flags & LOAD_DATA)
143365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich							return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
143465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich						else
143565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich							return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
143665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					}
143765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
143865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(ADD(tmp_ar, reg_map[base], TMP_REG3_mapped));
143965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					if (flags & LOAD_DATA)
144065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich						return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
144165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					else
144265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich						return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
144365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				}
144465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			} else {
144565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
144665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
144765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					if (flags & LOAD_DATA)
144865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich						return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
144965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					else
145065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich						return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
145165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				}
145265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
145365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
145465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
145565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (SLJIT_UNLIKELY(argw)) {
145665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
145765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			compiler->cache_argw = argw;
145865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(SHLI(TMP_REG3_mapped, reg_map[OFFS_REG(arg)], argw));
145965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
146065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
146165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (!(flags & WRITE_BACK)) {
146265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (arg == next_arg && argw == (next_argw & 0x3)) {
146365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				compiler->cache_arg = arg;
146465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				compiler->cache_argw = argw;
146565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
146665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				tmp_ar = TMP_REG3_mapped;
146765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			} else
146865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(ADD(tmp_ar, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
146965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
147065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (flags & LOAD_DATA)
147165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
147265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			else
147365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
147465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
147565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
147665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADD(reg_map[base], reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
147765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
147865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (flags & LOAD_DATA)
147965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
148065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		else
148165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
148265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
148365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
148465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) {
148565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		/* Update only applies if a base register exists. */
148665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (reg_ar == reg_map[base]) {
148765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			SLJIT_ASSERT(!(flags & LOAD_DATA) && TMP_REG1_mapped != reg_ar);
148865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
148965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[base], argw));
149065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if (flags & LOAD_DATA)
149165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped));
149265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				else
149365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar));
149465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
149565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if (argw)
149665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					return ADDLI(reg_map[base], reg_map[base], argw);
149765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
149865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				return SLJIT_SUCCESS;
149965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
150065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
150165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO));
150265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			reg_ar = TMP_REG1_mapped;
150365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
150465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
150565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
150665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (argw)
150765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(ADDLI(reg_map[base], reg_map[base], argw));
150865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else {
150965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (compiler->cache_arg == SLJIT_MEM
151065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					&& argw - compiler->cache_argw <= SIMM_16BIT_MAX
151165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					&& argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
151265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if (argw != compiler->cache_argw) {
151365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
151465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					compiler->cache_argw = argw;
151565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				}
151665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
151765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
151865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			} else {
151965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				compiler->cache_arg = SLJIT_MEM;
152065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				compiler->cache_argw = argw;
152165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw));
152265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
152365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
152465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
152565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
152665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (flags & LOAD_DATA)
152765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
152865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		else
152965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
153065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
153165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
153265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (compiler->cache_arg == arg
153365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			&& argw - compiler->cache_argw <= SIMM_16BIT_MAX
153465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			&& argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
153565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (argw != compiler->cache_argw) {
153665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
153765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			compiler->cache_argw = argw;
153865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
153965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
154065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (flags & LOAD_DATA)
154165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
154265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		else
154365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
154465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
154565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
154665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (compiler->cache_arg == SLJIT_MEM
154765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			&& argw - compiler->cache_argw <= SIMM_16BIT_MAX
154865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			&& argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
154965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (argw != compiler->cache_argw)
155065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
155165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else {
155265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		compiler->cache_arg = SLJIT_MEM;
155365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw));
155465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
155565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
155665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->cache_argw = argw;
155765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
155865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (!base) {
155965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (flags & LOAD_DATA)
156065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
156165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		else
156265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
156365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
156465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
156565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (arg == next_arg
156665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			&& next_argw - argw <= SIMM_16BIT_MAX
156765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			&& next_argw - argw >= SIMM_16BIT_MIN) {
156865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		compiler->cache_arg = arg;
156965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, reg_map[base]));
157065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (flags & LOAD_DATA)
157165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
157265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		else
157365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
157465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
157565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
157665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(ADD(tmp_ar, TMP_REG3_mapped, reg_map[base]));
157765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
157865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (flags & LOAD_DATA)
157965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
158065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	else
158165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
158265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
158365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
158465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw)
158565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
158665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
158765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return compiler->error;
158865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
158965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->cache_arg = 0;
159065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->cache_argw = 0;
159165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0);
159265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
159365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
159465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w)
159565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
159665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
159765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return compiler->error;
159865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
159965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
160065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
160165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
160265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
160365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR();
160465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_emit_fast_enter(compiler, dst, dstw);
160565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	ADJUST_LOCAL_OFFSET(dst, dstw);
160665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
160765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* For UNUSED dst. Uncommon, but possible. */
160865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (dst == SLJIT_UNUSED)
160965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
161065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
161165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (FAST_IS_REG(dst))
161265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return ADD(reg_map[dst], RA, ZERO);
161365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
161465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* Memory. */
161565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return emit_op_mem(compiler, WORD_DATA, RA, dst, dstw);
161665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
161765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
161865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
161965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
162065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR();
162165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_emit_fast_return(compiler, src, srcw);
162265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	ADJUST_LOCAL_OFFSET(src, srcw);
162365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
162465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (FAST_IS_REG(src))
162565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADD(RA, reg_map[src], ZERO));
162665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
162765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	else if (src & SLJIT_MEM)
162865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RA, src, srcw));
162965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
163065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	else if (src & SLJIT_IMM)
163165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(load_immediate(compiler, RA, srcw));
163265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
163365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return JR(RA);
163465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
163565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
163665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, sljit_si dst, sljit_si src1, sljit_sw src2)
163765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
163865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si overflow_ra = 0;
163965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
164065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	switch (GET_OPCODE(op)) {
164165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV:
164265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_P:
164365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
164465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (dst != src2)
164565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return ADD(reg_map[dst], reg_map[src2], ZERO);
164665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
164765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
164865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_UI:
164965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_SI:
165065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
165165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
165265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op == SLJIT_MOV_SI)
165365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				return BFEXTS(reg_map[dst], reg_map[src2], 0, 31);
165465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
165565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return BFEXTU(reg_map[dst], reg_map[src2], 0, 31);
165665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else if (dst != src2)
165765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			SLJIT_ASSERT_STOP();
165865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
165965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
166065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
166165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_UB:
166265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_SB:
166365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
166465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
166565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op == SLJIT_MOV_SB)
166665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				return BFEXTS(reg_map[dst], reg_map[src2], 0, 7);
166765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
166865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return BFEXTU(reg_map[dst], reg_map[src2], 0, 7);
166965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else if (dst != src2)
167065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			SLJIT_ASSERT_STOP();
167165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
167265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
167365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
167465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_UH:
167565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_SH:
167665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
167765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
167865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op == SLJIT_MOV_SH)
167965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				return BFEXTS(reg_map[dst], reg_map[src2], 0, 15);
168065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
168165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return BFEXTU(reg_map[dst], reg_map[src2], 0, 15);
168265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else if (dst != src2)
168365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			SLJIT_ASSERT_STOP();
168465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
168565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
168665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
168765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_NOT:
168865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
168965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op & SLJIT_SET_E)
169065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(NOR(EQUAL_FLAG, reg_map[src2], reg_map[src2]));
169165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (CHECK_FLAGS(SLJIT_SET_E))
169265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(NOR(reg_map[dst], reg_map[src2], reg_map[src2]));
169365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
169465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
169565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
169665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_CLZ:
169765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
169865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op & SLJIT_SET_E)
169965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(CLZ(EQUAL_FLAG, reg_map[src2]));
170065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (CHECK_FLAGS(SLJIT_SET_E))
170165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(CLZ(reg_map[dst], reg_map[src2]));
170265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
170365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
170465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
170565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_ADD:
170665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (flags & SRC2_IMM) {
170765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_O) {
170865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(SHRUI(TMP_EREG1, reg_map[src1], 63));
170965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if (src2 < 0)
171065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1));
171165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
171265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
171365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_E)
171465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], src2));
171565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
171665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_C) {
171765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if (src2 >= 0)
171865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(ORI(ULESS_FLAG ,reg_map[src1], src2));
171965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				else {
172065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(ADDLI(ULESS_FLAG ,ZERO, src2));
172165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(OR(ULESS_FLAG,reg_map[src1],ULESS_FLAG));
172265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				}
172365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
172465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
172565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			/* dst may be the same as src1 or src2. */
172665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (CHECK_FLAGS(SLJIT_SET_E))
172765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2));
172865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
172965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_O) {
173065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(SHRUI(OVERFLOW_FLAG, reg_map[dst], 63));
173165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
173265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if (src2 < 0)
173365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(XORI(OVERFLOW_FLAG, OVERFLOW_FLAG, 1));
173465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
173565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else {
173665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_O) {
173765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2]));
173865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63));
173965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
174065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if (src1 != dst)
174165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					overflow_ra = reg_map[src1];
174265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				else if (src2 != dst)
174365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					overflow_ra = reg_map[src2];
174465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				else {
174565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					/* Rare ocasion. */
174665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
174765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					overflow_ra = TMP_EREG2;
174865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				}
174965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
175065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
175165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_E)
175265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(ADD(EQUAL_FLAG ,reg_map[src1], reg_map[src2]));
175365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
175465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_C)
175565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(OR(ULESS_FLAG,reg_map[src1], reg_map[src2]));
175665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
175765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			/* dst may be the same as src1 or src2. */
175865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (CHECK_FLAGS(SLJIT_SET_E))
175965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(ADD(reg_map[dst],reg_map[src1], reg_map[src2]));
176065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
176165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_O) {
176265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(XOR(OVERFLOW_FLAG,reg_map[dst], overflow_ra));
176365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63));
176465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
176565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
176665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
176765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		/* a + b >= a | b (otherwise, the carry should be set to 1). */
176865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op & SLJIT_SET_C)
176965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(CMPLTU(ULESS_FLAG ,reg_map[dst] ,ULESS_FLAG));
177065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
177165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op & SLJIT_SET_O)
177265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return CMOVNEZ(OVERFLOW_FLAG, TMP_EREG1, ZERO);
177365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
177465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
177565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
177665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_ADDC:
177765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (flags & SRC2_IMM) {
177865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_C) {
177965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if (src2 >= 0)
178065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(ORI(TMP_EREG1, reg_map[src1], src2));
178165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				else {
178265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(ADDLI(TMP_EREG1, ZERO, src2));
178365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(OR(TMP_EREG1, reg_map[src1], TMP_EREG1));
178465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				}
178565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
178665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
178765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2));
178865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
178965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else {
179065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_C)
179165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(OR(TMP_EREG1, reg_map[src1], reg_map[src2]));
179265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
179365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			/* dst may be the same as src1 or src2. */
179465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADD(reg_map[dst], reg_map[src1], reg_map[src2]));
179565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
179665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
179765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op & SLJIT_SET_C)
179865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(CMPLTU(TMP_EREG1, reg_map[dst], TMP_EREG1));
179965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
180065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADD(reg_map[dst], reg_map[dst], ULESS_FLAG));
180165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
180265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (!(op & SLJIT_SET_C))
180365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return SLJIT_SUCCESS;
180465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
180565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		/* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */
180665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(CMPLTUI(TMP_EREG2, reg_map[dst], 1));
180765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(AND(TMP_EREG2, TMP_EREG2, ULESS_FLAG));
180865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		/* Set carry flag. */
180965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return OR(ULESS_FLAG, TMP_EREG2, TMP_EREG1);
181065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
181165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_SUB:
181265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_16BIT_MIN)) {
181365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2));
181465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			src2 = TMP_REG2;
181565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			flags &= ~SRC2_IMM;
181665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
181765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
181865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (flags & SRC2_IMM) {
181965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_O) {
182065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(SHRUI(TMP_EREG1,reg_map[src1], 63));
182165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
182265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if (src2 < 0)
182365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1));
182465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
182565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if (src1 != dst)
182665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					overflow_ra = reg_map[src1];
182765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				else {
182865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					/* Rare ocasion. */
182965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
183065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
183165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					overflow_ra = TMP_EREG2;
183265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				}
183365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
183465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
183565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_E)
183665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], -src2));
183765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
183865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_C) {
183965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2));
184065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], ADDR_TMP_mapped));
184165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
184265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
184365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			/* dst may be the same as src1 or src2. */
184465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (CHECK_FLAGS(SLJIT_SET_E))
184565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2));
184665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
184765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else {
184865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
184965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_O) {
185065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2]));
185165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63));
185265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
185365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if (src1 != dst)
185465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					overflow_ra = reg_map[src1];
185565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				else {
185665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					/* Rare ocasion. */
185765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
185865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					overflow_ra = TMP_EREG2;
185965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				}
186065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
186165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
186265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_E)
186365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(SUB(EQUAL_FLAG, reg_map[src1], reg_map[src2]));
186465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
186565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & (SLJIT_SET_U | SLJIT_SET_C))
186665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], reg_map[src2]));
186765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
186865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_U)
186965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(CMPLTU(UGREATER_FLAG, reg_map[src2], reg_map[src1]));
187065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
187165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_S) {
187265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(CMPLTS(LESS_FLAG ,reg_map[src1] ,reg_map[src2]));
187365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(CMPLTS(GREATER_FLAG ,reg_map[src2] ,reg_map[src1]));
187465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
187565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
187665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			/* dst may be the same as src1 or src2. */
187765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))
187865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2]));
187965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
188065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
188165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op & SLJIT_SET_O) {
188265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(XOR(OVERFLOW_FLAG, reg_map[dst], overflow_ra));
188365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63));
188465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return CMOVEQZ(OVERFLOW_FLAG, TMP_EREG1, ZERO);
188565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
188665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
188765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
188865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
188965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_SUBC:
189065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if ((flags & SRC2_IMM) && src2 == SIMM_16BIT_MIN) {
189165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2));
189265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			src2 = TMP_REG2;
189365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			flags &= ~SRC2_IMM;
189465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
189565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
189665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (flags & SRC2_IMM) {
189765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_C) {
189865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, -src2));
189965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], ADDR_TMP_mapped));
190065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
190165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
190265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			/* dst may be the same as src1 or src2. */
190365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2));
190465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
190565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else {
190665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (op & SLJIT_SET_C)
190765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], reg_map[src2]));
190865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				/* dst may be the same as src1 or src2. */
190965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2]));
191065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
191165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
191265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op & SLJIT_SET_C)
191365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(CMOVEQZ(TMP_EREG1, reg_map[dst], ULESS_FLAG));
191465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
191565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(SUB(reg_map[dst], reg_map[dst], ULESS_FLAG));
191665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
191765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op & SLJIT_SET_C)
191865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADD(ULESS_FLAG, TMP_EREG1, ZERO));
191965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
192065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
192165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
192265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define EMIT_LOGICAL(op_imm, op_norm) \
192365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (flags & SRC2_IMM) { \
192465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); \
192565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op & SLJIT_SET_E) \
192665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(push_3_buffer( \
192765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				compiler, op_norm, EQUAL_FLAG, reg_map[src1], \
192865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				ADDR_TMP_mapped, __LINE__)); \
192965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (CHECK_FLAGS(SLJIT_SET_E)) \
193065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(push_3_buffer( \
193165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				compiler, op_norm, reg_map[dst], reg_map[src1], \
193265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				ADDR_TMP_mapped, __LINE__)); \
193365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else { \
193465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op & SLJIT_SET_E) \
193565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(push_3_buffer( \
193665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				compiler, op_norm, EQUAL_FLAG, reg_map[src1], \
193765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				reg_map[src2], __LINE__)); \
193865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (CHECK_FLAGS(SLJIT_SET_E)) \
193965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(push_3_buffer( \
194065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				compiler, op_norm, reg_map[dst], reg_map[src1], \
194165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				reg_map[src2], __LINE__)); \
194265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
194365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
194465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_AND:
194565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		EMIT_LOGICAL(TILEGX_OPC_ANDI, TILEGX_OPC_AND);
194665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
194765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
194865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_OR:
194965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		EMIT_LOGICAL(TILEGX_OPC_ORI, TILEGX_OPC_OR);
195065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
195165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
195265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_XOR:
195365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		EMIT_LOGICAL(TILEGX_OPC_XORI, TILEGX_OPC_XOR);
195465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
195565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
195665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define EMIT_SHIFT(op_imm, op_norm) \
195765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (flags & SRC2_IMM) { \
195865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op & SLJIT_SET_E) \
195965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(push_3_buffer( \
196065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				compiler, op_imm, EQUAL_FLAG, reg_map[src1], \
196165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				src2 & 0x3F, __LINE__)); \
196265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (CHECK_FLAGS(SLJIT_SET_E)) \
196365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(push_3_buffer( \
196465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				compiler, op_imm, reg_map[dst], reg_map[src1], \
196565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				src2 & 0x3F, __LINE__)); \
196665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else { \
196765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op & SLJIT_SET_E) \
196865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(push_3_buffer( \
196965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				compiler, op_imm, reg_map[dst], reg_map[src1], \
197065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				src2 & 0x3F, __LINE__)); \
197165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (CHECK_FLAGS(SLJIT_SET_E)) \
197265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(push_3_buffer( \
197365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				compiler, op_norm, reg_map[dst], reg_map[src1], \
197465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				reg_map[src2], __LINE__)); \
197565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
197665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
197765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_SHL:
197865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		EMIT_SHIFT(TILEGX_OPC_SHLI, TILEGX_OPC_SHL);
197965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
198065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
198165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_LSHR:
198265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		EMIT_SHIFT(TILEGX_OPC_SHRUI, TILEGX_OPC_SHRU);
198365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
198465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
198565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_ASHR:
198665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		EMIT_SHIFT(TILEGX_OPC_SHRSI, TILEGX_OPC_SHRS);
198765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
198865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
198965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
199065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_ASSERT_STOP();
199165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
199265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
199365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
199465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w)
199565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
199665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* arg1 goes to TMP_REG1 or src reg.
199765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	   arg2 goes to TMP_REG2, imm or src reg.
199865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	   TMP_REG3 can be used for caching.
199965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	   result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
200065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si dst_r = TMP_REG2;
200165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si src1_r;
200265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_sw src2_r = 0;
200365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si sugg_src2_r = TMP_REG2;
200465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
200565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (!(flags & ALT_KEEP_CACHE)) {
200665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		compiler->cache_arg = 0;
200765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		compiler->cache_argw = 0;
200865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
200965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
201065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
201165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM))
201265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return SLJIT_SUCCESS;
201365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (GET_FLAGS(op))
201465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			flags |= UNUSED_DEST;
201565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else if (FAST_IS_REG(dst)) {
201665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		dst_r = dst;
201765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		flags |= REG_DEST;
201865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
201965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			sugg_src2_r = dst_r;
202065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1_mapped, dst, dstw))
202165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		flags |= SLOW_DEST;
202265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
202365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (flags & IMM_OP) {
202465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if ((src2 & SLJIT_IMM) && src2w) {
202565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if ((!(flags & LOGICAL_OP)
202665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					&& (src2w <= SIMM_16BIT_MAX && src2w >= SIMM_16BIT_MIN))
202765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					|| ((flags & LOGICAL_OP) && !(src2w & ~UIMM_16BIT_MAX))) {
202865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				flags |= SRC2_IMM;
202965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				src2_r = src2w;
203065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
203165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
203265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
203365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {
203465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if ((!(flags & LOGICAL_OP)
203565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					&& (src1w <= SIMM_16BIT_MAX && src1w >= SIMM_16BIT_MIN))
203665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					|| ((flags & LOGICAL_OP) && !(src1w & ~UIMM_16BIT_MAX))) {
203765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				flags |= SRC2_IMM;
203865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				src2_r = src1w;
203965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
204065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				/* And swap arguments. */
204165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				src1 = src2;
204265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				src1w = src2w;
204365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				src2 = SLJIT_IMM;
204465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				/* src2w = src2_r unneeded. */
204565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
204665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
204765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
204865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
204965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* Source 1. */
205065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (FAST_IS_REG(src1)) {
205165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		src1_r = src1;
205265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		flags |= REG1_SOURCE;
205365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else if (src1 & SLJIT_IMM) {
205465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (src1w) {
205565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, src1w));
205665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			src1_r = TMP_REG1;
205765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else
205865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			src1_r = 0;
205965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else {
206065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w))
206165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(compiler->error);
206265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		else
206365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			flags |= SLOW_SRC1;
206465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		src1_r = TMP_REG1;
206565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
206665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
206765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	/* Source 2. */
206865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (FAST_IS_REG(src2)) {
206965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		src2_r = src2;
207065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		flags |= REG2_SOURCE;
207165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
207265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			dst_r = src2_r;
207365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else if (src2 & SLJIT_IMM) {
207465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (!(flags & SRC2_IMM)) {
207565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (src2w) {
207665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(load_immediate(compiler, reg_map[sugg_src2_r], src2w));
207765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				src2_r = sugg_src2_r;
207865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			} else {
207965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				src2_r = 0;
208065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM))
208165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich					dst_r = 0;
208265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
208365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
208465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else {
208565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (getput_arg_fast(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w))
208665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(compiler->error);
208765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		else
208865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			flags |= SLOW_SRC2;
208965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		src2_r = sugg_src2_r;
209065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
209165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
209265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
209365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT(src2_r == TMP_REG2);
209465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
209565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, src1, src1w));
209665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw));
209765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else {
209865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, src2, src2w));
209965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, dst, dstw));
210065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
210165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else if (flags & SLOW_SRC1)
210265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw));
210365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	else if (flags & SLOW_SRC2)
210465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w, dst, dstw));
210565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
210665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
210765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
210865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (dst & SLJIT_MEM) {
210965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (!(flags & SLOW_DEST)) {
211065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			getput_arg_fast(compiler, flags, reg_map[dst_r], dst, dstw);
211165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return compiler->error;
211265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
211365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
211465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return getput_arg(compiler, flags, reg_map[dst_r], dst, dstw, 0, 0);
211565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
211665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
211765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
211865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
211965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
212065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw, sljit_si type)
212165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
212265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si sugg_dst_ar, dst_ar;
212365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si flags = GET_ALL_FLAGS(op);
212465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
212565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR();
212665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
212765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	ADJUST_LOCAL_OFFSET(dst, dstw);
212865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
212965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (dst == SLJIT_UNUSED)
213065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
213165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
213265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	op = GET_OPCODE(op);
213365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sugg_dst_ar = reg_map[(op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2];
213465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
213565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->cache_arg = 0;
213665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	compiler->cache_argw = 0;
213765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
213865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		ADJUST_LOCAL_OFFSET(src, srcw);
213965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1_mapped, src, srcw, dst, dstw));
214065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		src = TMP_REG1;
214165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		srcw = 0;
214265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
214365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
214465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	switch (type) {
214565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_EQUAL:
214665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_NOT_EQUAL:
214765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(CMPLTUI(sugg_dst_ar, EQUAL_FLAG, 1));
214865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		dst_ar = sugg_dst_ar;
214965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
215065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_LESS:
215165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_GREATER_EQUAL:
215265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_FLOAT_LESS:
215365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_FLOAT_GREATER_EQUAL:
215465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		dst_ar = ULESS_FLAG;
215565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
215665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_GREATER:
215765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_LESS_EQUAL:
215865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_FLOAT_GREATER:
215965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_FLOAT_LESS_EQUAL:
216065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		dst_ar = UGREATER_FLAG;
216165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
216265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_SIG_LESS:
216365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_SIG_GREATER_EQUAL:
216465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		dst_ar = LESS_FLAG;
216565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
216665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_SIG_GREATER:
216765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_SIG_LESS_EQUAL:
216865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		dst_ar = GREATER_FLAG;
216965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
217065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_OVERFLOW:
217165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_NOT_OVERFLOW:
217265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		dst_ar = OVERFLOW_FLAG;
217365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
217465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_MUL_OVERFLOW:
217565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_MUL_NOT_OVERFLOW:
217665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(CMPLTUI(sugg_dst_ar, OVERFLOW_FLAG, 1));
217765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		dst_ar = sugg_dst_ar;
217865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		type ^= 0x1; /* Flip type bit for the XORI below. */
217965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
218065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_FLOAT_EQUAL:
218165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_FLOAT_NOT_EQUAL:
218265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		dst_ar = EQUAL_FLAG;
218365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
218465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
218565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	default:
218665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT_STOP();
218765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		dst_ar = sugg_dst_ar;
218865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
218965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
219065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
219165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (type & 0x1) {
219265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(XORI(sugg_dst_ar, dst_ar, 1));
219365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		dst_ar = sugg_dst_ar;
219465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
219565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
219665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (op >= SLJIT_ADD) {
219765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (TMP_REG2_mapped != dst_ar)
219865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADD(TMP_REG2_mapped, dst_ar, ZERO));
219965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, op | flags, CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
220065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
220165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
220265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (dst & SLJIT_MEM)
220365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw);
220465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
220565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (sugg_dst_ar != dst_ar)
220665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return ADD(sugg_dst_ar, dst_ar, ZERO);
220765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
220865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
220965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
221065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
221165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) {
221265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR();
221365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_emit_op0(compiler, op);
221465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
221565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	op = GET_OPCODE(op);
221665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	switch (op) {
221765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_NOP:
221865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return push_0_buffer(compiler, TILEGX_OPC_FNOP, __LINE__);
221965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
222065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_BREAKPOINT:
222165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return PI(BPT);
222265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
222365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_UMUL:
222465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_SMUL:
222565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_UDIV:
222665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_SDIV:
222765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT_STOP();
222865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
222965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
223065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
223165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
223265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
223365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw)
223465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
223565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR();
223665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
223765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	ADJUST_LOCAL_OFFSET(dst, dstw);
223865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	ADJUST_LOCAL_OFFSET(src, srcw);
223965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
224065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	switch (GET_OPCODE(op)) {
224165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV:
224265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_P:
224365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
224465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
224565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_UI:
224665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
224765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
224865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_SI:
224965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
225065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
225165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_UB:
225265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub) srcw : srcw);
225365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
225465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_SB:
225565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb) srcw : srcw);
225665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
225765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_UH:
225865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh) srcw : srcw);
225965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
226065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOV_SH:
226165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh) srcw : srcw);
226265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
226365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOVU:
226465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOVU_P:
226565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
226665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
226765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOVU_UI:
226865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
226965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
227065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOVU_SI:
227165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
227265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
227365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOVU_UB:
227465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub) srcw : srcw);
227565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
227665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOVU_SB:
227765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb) srcw : srcw);
227865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
227965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOVU_UH:
228065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh) srcw : srcw);
228165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
228265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MOVU_SH:
228365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh) srcw : srcw);
228465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
228565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_NOT:
228665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw);
228765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
228865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_NEG:
228965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
229065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
229165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_CLZ:
229265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw);
229365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
229465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
229565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
229665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
229765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
229865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w)
229965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
230065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR();
230165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
230265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	ADJUST_LOCAL_OFFSET(dst, dstw);
230365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	ADJUST_LOCAL_OFFSET(src1, src1w);
230465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	ADJUST_LOCAL_OFFSET(src2, src2w);
230565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
230665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	switch (GET_OPCODE(op)) {
230765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_ADD:
230865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_ADDC:
230965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, op, CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
231065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
231165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_SUB:
231265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_SUBC:
231365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w);
231465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
231565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_MUL:
231665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, op, CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
231765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
231865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_AND:
231965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_OR:
232065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_XOR:
232165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
232265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
232365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_SHL:
232465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_LSHR:
232565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_ASHR:
232665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (src2 & SLJIT_IMM)
232765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			src2w &= 0x3f;
232865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (op & SLJIT_INT_OP)
232965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			src2w &= 0x1f;
233065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
233165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w);
233265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
233365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
233465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
233565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
233665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
233765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE struct sljit_label * sljit_emit_label(struct sljit_compiler *compiler)
233865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
233965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	struct sljit_label *label;
234065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
234165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	flush_buffer(compiler);
234265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
234365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR_PTR();
234465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_emit_label(compiler);
234565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
234665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (compiler->last_label && compiler->last_label->size == compiler->size)
234765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return compiler->last_label;
234865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
234965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	label = (struct sljit_label *)ensure_abuf(compiler, sizeof(struct sljit_label));
235065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	PTR_FAIL_IF(!label);
235165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	set_label(label, compiler);
235265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return label;
235365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
235465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
235565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
235665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
235765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si src_r = TMP_REG2;
235865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	struct sljit_jump *jump = NULL;
235965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
236065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	flush_buffer(compiler);
236165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
236265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR();
236365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_emit_ijump(compiler, type, src, srcw);
236465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	ADJUST_LOCAL_OFFSET(src, srcw);
236565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
236665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (FAST_IS_REG(src)) {
236765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (reg_map[src] != 0)
236865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			src_r = src;
236965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		else
237065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADD_SOLO(TMP_REG2_mapped, reg_map[src], ZERO));
237165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
237265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
237365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (type >= SLJIT_CALL0) {
237465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2);
237565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (src & (SLJIT_IMM | SLJIT_MEM)) {
237665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			if (src & SLJIT_IMM)
237765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(emit_const(compiler, reg_map[PIC_ADDR_REG], srcw, 1));
237865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			else {
237965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM));
238065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich				FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
238165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			}
238265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
238365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
238465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
238565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADDI_SOLO(54, 54, -16));
238665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
238765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(JALR_SOLO(reg_map[PIC_ADDR_REG]));
238865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
238965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			return ADDI_SOLO(54, 54, 16);
239065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
239165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
239265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		/* Register input. */
239365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (type >= SLJIT_CALL1)
239465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
239565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
239665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADD_SOLO(reg_map[PIC_ADDR_REG], reg_map[src_r], ZERO));
239765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
239865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(ADDI_SOLO(54, 54, -16));
239965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
240065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(JALR_SOLO(reg_map[src_r]));
240165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
240265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return ADDI_SOLO(54, 54, 16);
240365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
240465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
240565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (src & SLJIT_IMM) {
240665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
240765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(!jump);
240865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
240965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		jump->u.target = srcw;
241065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1));
241165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
241265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		if (type >= SLJIT_FAST_CALL) {
241365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(ADD_SOLO(ZERO, ZERO, ZERO));
241465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			jump->addr = compiler->size;
241565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(JR_SOLO(reg_map[src_r]));
241665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		} else {
241765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			jump->addr = compiler->size;
241865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich			FAIL_IF(JR_SOLO(reg_map[src_r]));
241965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		}
242065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
242165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		return SLJIT_SUCCESS;
242265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
242365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else if (src & SLJIT_MEM)
242465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
242565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
242665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	FAIL_IF(JR_SOLO(reg_map[src_r]));
242765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
242865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (jump)
242965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		jump->addr = compiler->size;
243065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
243165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return SLJIT_SUCCESS;
243265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
243365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
243465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BR_Z(src) \
243565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst = BEQZ_X1 | SRCA_X1(src); \
243665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	flags = IS_COND;
243765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
243865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BR_NZ(src) \
243965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst = BNEZ_X1 | SRCA_X1(src); \
244065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	flags = IS_COND;
244165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
244265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
244365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
244465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	struct sljit_jump *jump;
244565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins inst;
244665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si flags = 0;
244765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
244865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	flush_buffer(compiler);
244965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
245065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR_PTR();
245165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_emit_jump(compiler, type);
245265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
245365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
245465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	PTR_FAIL_IF(!jump);
245565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
245665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	type &= 0xff;
245765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
245865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	switch (type) {
245965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_EQUAL:
246065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_FLOAT_NOT_EQUAL:
246165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		BR_NZ(EQUAL_FLAG);
246265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
246365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_NOT_EQUAL:
246465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_FLOAT_EQUAL:
246565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		BR_Z(EQUAL_FLAG);
246665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
246765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_LESS:
246865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_FLOAT_LESS:
246965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		BR_Z(ULESS_FLAG);
247065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
247165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_GREATER_EQUAL:
247265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_FLOAT_GREATER_EQUAL:
247365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		BR_NZ(ULESS_FLAG);
247465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
247565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_GREATER:
247665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_FLOAT_GREATER:
247765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		BR_Z(UGREATER_FLAG);
247865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
247965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_LESS_EQUAL:
248065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_FLOAT_LESS_EQUAL:
248165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		BR_NZ(UGREATER_FLAG);
248265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
248365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_SIG_LESS:
248465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		BR_Z(LESS_FLAG);
248565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
248665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_SIG_GREATER_EQUAL:
248765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		BR_NZ(LESS_FLAG);
248865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
248965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_SIG_GREATER:
249065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		BR_Z(GREATER_FLAG);
249165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
249265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_SIG_LESS_EQUAL:
249365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		BR_NZ(GREATER_FLAG);
249465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
249565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_OVERFLOW:
249665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_MUL_OVERFLOW:
249765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		BR_Z(OVERFLOW_FLAG);
249865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
249965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_NOT_OVERFLOW:
250065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	case SLJIT_C_MUL_NOT_OVERFLOW:
250165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		BR_NZ(OVERFLOW_FLAG);
250265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
250365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	default:
250465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		/* Not conditional branch. */
250565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst = 0;
250665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		break;
250765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
250865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
250965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	jump->flags |= flags;
251065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
251165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (inst) {
251265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		inst = inst | ((type <= SLJIT_JUMP) ? BOFF_X1(5) : BOFF_X1(6));
251365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		PTR_FAIL_IF(PI(inst));
251465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
251565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
251665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	PTR_FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1));
251765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (type <= SLJIT_JUMP) {
251865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		jump->addr = compiler->size;
251965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		PTR_FAIL_IF(JR_SOLO(TMP_REG2_mapped));
252065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	} else {
252165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2);
252265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		/* Cannot be optimized out if type is >= CALL0. */
252365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0);
252465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		PTR_FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
252565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		jump->addr = compiler->size;
252665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		PTR_FAIL_IF(JALR_SOLO(TMP_REG2_mapped));
252765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	}
252865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
252965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return jump;
253065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
253165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
253265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
253365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
253465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return 0;
253565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
253665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
253765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw)
253865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
253965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_ASSERT_STOP();
254065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
254165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
254265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w)
254365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
254465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_ASSERT_STOP();
254565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
254665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
254765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
254865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
254965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	struct sljit_const *const_;
255065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_si reg;
255165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
255265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	flush_buffer(compiler);
255365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
255465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	CHECK_ERROR_PTR();
255565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	check_sljit_emit_const(compiler, dst, dstw, init_value);
255665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	ADJUST_LOCAL_OFFSET(dst, dstw);
255765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
255865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	const_ = (struct sljit_const *)ensure_abuf(compiler, sizeof(struct sljit_const));
255965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	PTR_FAIL_IF(!const_);
256065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	set_const(const_, compiler);
256165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
256265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
256365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
256465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	PTR_FAIL_IF(emit_const_64(compiler, reg, init_value, 1));
256565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
256665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	if (dst & SLJIT_MEM)
256765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
256865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	return const_;
256965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
257065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
257165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
257265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
257365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins *inst = (sljit_ins *)addr;
257465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
257565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_addr >> 32) & 0xffff) << 43);
257665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_addr >> 16) & 0xffff) << 43);
257765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_addr & 0xffff) << 43);
257865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_CACHE_FLUSH(inst, inst + 3);
257965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
258065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
258165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
258265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{
258365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	sljit_ins *inst = (sljit_ins *)addr;
258465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
258565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_constant >> 48) & 0xFFFFL) << 43);
258665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_constant >> 32) & 0xFFFFL) << 43);
258765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst[2] = (inst[2] & ~(0xFFFFL << 43)) | (((new_constant >> 16) & 0xFFFFL) << 43);
258865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	inst[3] = (inst[3] & ~(0xFFFFL << 43)) | ((new_constant & 0xFFFFL) << 43);
258965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich	SLJIT_CACHE_FLUSH(inst, inst + 4);
259065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
2591