diff options
Diffstat (limited to 'deps/lightning/lib')
55 files changed, 91618 insertions, 0 deletions
diff --git a/deps/lightning/lib/Makefile.am b/deps/lightning/lib/Makefile.am new file mode 100644 index 0000000..f2ac2ba --- /dev/null +++ b/deps/lightning/lib/Makefile.am @@ -0,0 +1,83 @@ +# +# Copyright 2000, 2001, 2002, 2012-2019 Free Software Foundation, Inc. +# +# This file is part of GNU lightning. +# +# GNU lightning is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU lightning is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. +# + +AM_CFLAGS = -I$(top_srcdir)/include -D_GNU_SOURCE $(LIGHTNING_CFLAGS) +liblightning_LTLIBRARIES = liblightning.la +liblightning_la_LDFLAGS = -version-info 1:0:0 + +if get_jit_size +JIT_SIZE_PATH = "$(top_builddir)/jit_$(cpu)-sz.c" +AM_CPPFLAGS=-DGET_JIT_SIZE=1 -DJIT_SIZE_PATH='$(JIT_SIZE_PATH)' +endif + +liblightningdir = $(libdir) +liblightning_la_SOURCES = \ + jit_disasm.c \ + jit_memory.c \ + jit_names.c \ + jit_note.c \ + jit_print.c \ + jit_size.c \ + lightning.c + +EXTRA_DIST = \ + jit_rewind.c \ + jit_aarch64.c \ + jit_aarch64-cpu.c \ + jit_aarch64-fpu.c \ + jit_aarch64-sz.c \ + jit_alpha.c \ + jit_alpha-cpu.c \ + jit_alpha-fpu.c \ + jit_alpha-sz.c \ + jit_arm.c \ + jit_arm-cpu.c \ + jit_arm-swf.c \ + jit_arm-vfp.c \ + jit_arm-sz.c \ + jit_hppa.c \ + jit_hppa-cpu.c \ + jit_hppa-fpu.c \ + jit_hppa-sz.c \ + jit_ia64.c \ + jit_ia64-cpu.c \ + jit_ia64-fpu.c \ + jit_ia64-sz.c \ + jit_mips.c \ + jit_mips-cpu.c \ + jit_mips-fpu.c \ + jit_mips-sz.c \ + jit_ppc.c \ + jit_ppc-cpu.c \ + jit_ppc-fpu.c \ + jit_ppc-sz.c \ + jit_riscv.c \ + jit_riscv-cpu.c \ + jit_riscv-fpu.c \ + jit_riscv-sz.c \ + jit_s390.c \ + jit_s390-cpu.c \ + jit_s390-fpu.c \ + jit_s390-sz.c \ + jit_sparc.c \ + jit_sparc-cpu.c \ + jit_sparc-fpu.c \ + jit_sparc-sz.c \ + jit_x86.c \ + jit_x86-cpu.c \ + jit_x86-sse.c \ + jit_x86-x87.c \ + jit_x86-sz.c diff --git a/deps/lightning/lib/jit_aarch64-cpu.c b/deps/lightning/lib/jit_aarch64-cpu.c new file mode 100644 index 0000000..8e8a9a0 --- /dev/null +++ b/deps/lightning/lib/jit_aarch64-cpu.c @@ -0,0 +1,2446 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +typedef union { +/* aarch64-opc.c */ +# define ui jit_uint32_t +# if __BYTE_ORDER == __LITTLE_ENDIAN + /* cond2: condition in truly conditional-executed inst. */ + struct { ui b: 4; } cond2; + /* nzcv: flag bit specifier, encoded in the "nzcv" field. */ + struct { ui b: 4; } nzcv; + /* defgh: d:e:f:g:h bits in AdvSIMD modified immediate. */ + struct { ui _: 5; ui b: 5; } defgh; + /* abc: a:b:c bits in AdvSIMD modified immediate. */ + struct { ui _: 16; ui b: 3; } abc; + /* imm19: e.g. in CBZ. */ + struct { ui _: 5; ui b: 19; } imm19; + /* immhi: e.g. in ADRP. */ + struct { ui _: 5; ui b: 19; } immhi; + /* immlo: e.g. in ADRP. */ + struct { ui _: 29; ui b: 2; } immlo; + /* size: in most AdvSIMD and floating-point instructions. */ + struct { ui _: 22; ui b: 2; } size; + /* vldst_size: size field in the AdvSIMD load/store inst. */ + struct { ui _: 10; ui b: 2; } vldst_size; + /* op: in AdvSIMD modified immediate instructions. */ + struct { ui _: 29; ui b: 1; } op; + /* Q: in most AdvSIMD instructions. */ + struct { ui _: 30; ui b: 1; } Q; + /* Rt: in load/store instructions. */ + struct { ui b: 5; } Rt; + /* Rd: in many integer instructions. */ + struct { ui b: 5; } Rd; + /* Rn: in many integer instructions. */ + struct { ui _: 5; ui b: 5; } Rn; + /* Rt2: in load/store pair instructions. */ + struct { ui _: 10; ui b: 5; } Rt2; + /* Ra: in fp instructions. */ + struct { ui _: 10; ui b: 5; } Ra; + /* op2: in the system instructions. */ + struct { ui _: 5; ui b: 3; } op2; + /* CRm: in the system instructions. */ + struct { ui _: 8; ui b: 4; } CRm; + /* CRn: in the system instructions. */ + struct { ui _: 12; ui b: 4; } CRn; + /* op1: in the system instructions. */ + struct { ui _: 16; ui b: 3; } op1; + /* op0: in the system instructions. */ + struct { ui _: 19; ui b: 2; } op0; + /* imm3: in add/sub extended reg instructions. */ + struct { ui _: 10; ui b: 3; } imm3; + /* cond: condition flags as a source operand. */ + struct { ui _: 12; ui b: 4; } cond; + /* opcode: in advsimd load/store instructions. */ + struct { ui _: 12; ui b: 4; } opcode; + /* cmode: in advsimd modified immediate instructions. */ + struct { ui _: 12; ui b: 4; } cmode; + /* asisdlso_opcode: opcode in advsimd ld/st single element. */ + struct { ui _: 13; ui b: 3; } asisdlso_opcode; + /* len: in advsimd tbl/tbx instructions. */ + struct { ui _: 13; ui b: 2; } len; + /* Rm: in ld/st reg offset and some integer inst. */ + struct { ui _: 16; ui b: 5; } Rm; + /* Rs: in load/store exclusive instructions. */ + struct { ui _: 16; ui b: 5; } Rs; + /* option: in ld/st reg offset + add/sub extended reg inst. */ + struct { ui _: 13; ui b: 3; } option; + /* S: in load/store reg offset instructions. */ + struct { ui _: 12; ui b: 1; } S; + /* hw: in move wide constant instructions. */ + struct { ui _: 21; ui b: 2; } hw; + /* opc: in load/store reg offset instructions. */ + struct { ui _: 22; ui b: 2; } opc; + /* opc1: in load/store reg offset instructions. */ + struct { ui _: 23; ui b: 1; } opc1; + /* shift: in add/sub reg/imm shifted instructions. */ + struct { ui _: 22; ui b: 2; } shift; + /* type: floating point type field in fp data inst. */ + struct { ui _: 22; ui b: 2; } type; + /* ldst_size: size field in ld/st reg offset inst. */ + struct { ui _: 30; ui b: 2; } ldst_size; + /* imm6: in add/sub reg shifted instructions. */ + struct { ui _: 10; ui b: 6; } imm6; + /* imm4: in advsimd ext and advsimd ins instructions. */ + struct { ui _: 11; ui b: 4; } imm4; + /* imm5: in conditional compare (immediate) instructions. */ + struct { ui _: 16; ui b: 5; } imm5; + /* imm7: in load/store pair pre/post index instructions. */ + struct { ui _: 15; ui b: 7; } imm7; + /* imm8: in floating-point scalar move immediate inst. */ + struct { ui _: 13; ui b: 8; } imm8; + /* imm9: in load/store pre/post index instructions. */ + struct { ui _: 12; ui b: 9; } imm9; + /* imm12: in ld/st unsigned imm or add/sub shifted inst. */ + struct { ui _: 10; ui b: 12; } imm12; + /* imm14: in test bit and branch instructions. */ + struct { ui _: 5; ui b: 14; } imm14; + /* imm16: in exception instructions. */ + struct { ui _: 5; ui b: 16; } imm16; + /* imm26: in unconditional branch instructions. */ + struct { ui b: 26; } imm26; + /* imms: in bitfield and logical immediate instructions. */ + struct { ui _: 10; ui b: 6; } imms; + /* immr: in bitfield and logical immediate instructions. */ + struct { ui _: 16; ui b: 6; } immr; + /* immb: in advsimd shift by immediate instructions. */ + struct { ui _: 16; ui b: 3; } immb; + /* immh: in advsimd shift by immediate instructions. */ + struct { ui _: 19; ui b: 4; } immh; + /* N: in logical (immediate) instructions. */ + struct { ui _: 22; ui b: 1; } N; + /* index: in ld/st inst deciding the pre/post-index. */ + struct { ui _: 11; ui b: 1; } index; + /* index2: in ld/st pair inst deciding the pre/post-index. */ + struct { ui _: 24; ui b: 1; } index2; + /* sf: in integer data processing instructions. */ + struct { ui _: 31; ui b: 1; } sf; + /* H: in advsimd scalar x indexed element instructions. */ + struct { ui _: 11; ui b: 1; } H; + /* L: in advsimd scalar x indexed element instructions. */ + struct { ui _: 21; ui b: 1; } L; + /* M: in advsimd scalar x indexed element instructions. */ + struct { ui _: 20; ui b: 1; } M; + /* b5: in the test bit and branch instructions. */ + struct { ui _: 31; ui b: 1; } b5; + /* b40: in the test bit and branch instructions. */ + struct { ui _: 19; ui b: 5; } b40; + /* scale: in the fixed-point scalar to fp converting inst. */ + struct { ui _: 10; ui b: 6; } scale; +# else + struct { ui _: 28; ui b: 4; } cond2; + struct { ui _: 28; ui b: 4; } nzcv; + struct { ui _: 22; ui b: 5; } defgh; + struct { ui _: 13; ui b: 3; } abc; + struct { ui _: 8; ui b: 19; } imm19; + struct { ui _: 8; ui b: 19; } immhi; + struct { ui _: 1; ui b: 29; } immlo; + struct { ui _: 8; ui b: 2; } size; + struct { ui _: 20; ui b: 2; } vldst_size; + struct { ui _: 2; ui b: 1; } op; + struct { ui _: 1; ui b: 1; } Q; + struct { ui _: 27; ui b: 1; } Rt; + struct { ui _: 27; ui b: 1; } Rd; + struct { ui _: 22; ui b: 5; } Rn; + struct { ui _: 17; ui b: 5; } Rt2; + struct { ui _: 17; ui b: 5; } Ra; + struct { ui _: 24; ui b: 3; } op2; + struct { ui _: 20; ui b: 4; } CRm; + struct { ui _: 16; ui b: 4; } CRn; + struct { ui _: 13; ui b: 3; } op1; + struct { ui _: 11; ui b: 2; } op0; + struct { ui _: 19; ui b: 3; } imm3; + struct { ui _: 16; ui b: 4; } cond; + struct { ui _: 16; ui b: 4; } opcode; + struct { ui _: 16; ui b: 4; } cmode; + struct { ui _: 16; ui b: 3; } asisdlso_opcode; + struct { ui _: 17; ui b: 2; } len; + struct { ui _: 11; ui b: 5; } Rm; + struct { ui _: 11; ui b: 5; } Rs; + struct { ui _: 16; ui b: 3; } option; + struct { ui _: 19; ui b: 1; } S; + struct { ui _: 9; ui b: 2; } hw; + struct { ui _: 8; ui b: 2; } opc; + struct { ui _: 8; ui b: 1; } opc1; + struct { ui _: 8; ui b: 2; } shift; + struct { ui _: 8; ui b: 2; } type; + struct { ui b: 2; } ldst_size; + struct { ui _: 16; ui b: 6; } imm6; + struct { ui _: 17; ui b: 4; } imm4; + struct { ui _: 11; ui b: 5; } imm5; + struct { ui _: 10; ui b: 7; } imm7; + struct { ui _: 11; ui b: 8; } imm8; + struct { ui _: 11; ui b: 9; } imm9; + struct { ui _: 10; ui b: 12; } imm12; + struct { ui _: 13; ui b: 14; } imm14; + struct { ui _: 11; ui b: 16; } imm16; + struct { ui _: 6; ui b: 26; } imm26; + struct { ui _: 16; ui b: 6; } imms; + struct { ui _: 10; ui b: 6; } immr; + struct { ui _: 13; ui b: 3; } immb; + struct { ui _: 9; ui b: 4; } immh; + struct { ui _: 9; ui b: 1; } N; + struct { ui _: 20; ui b: 1; } index; + struct { ui _: 7; ui b: 1; } index2; + struct { ui b: 1; } sf; + struct { ui _: 20; ui b: 1; } H; + struct { ui _: 10; ui b: 1; } L; + struct { ui _: 11; ui b: 1; } M; + struct { ui b: 1; } b5; + struct { ui _: 8; ui b: 5; } b40; + struct { ui _: 16; ui b: 6; } scale; +# endif + jit_int32_t w; +# undef ui +} instr_t; +# define stack_framesize 160 +# define ii(i) *_jit->pc.ui++ = i +# define ldr(r0,r1) ldr_l(r0,r1) +# define ldxr(r0,r1,r2) ldxr_l(r0,r1,r2) +# define ldxi(r0,r1,i0) ldxi_l(r0,r1,i0) +# define stxi(i0,r0,r1) stxi_l(i0,r0,r1) +# define FP_REGNO 0x1d +# define LR_REGNO 0x1e +# define SP_REGNO 0x1f +# define XZR_REGNO 0x1f +# define WZR_REGNO XZR_REGNO +# define LSL_12 0x00400000 +# define MOVI_LSL_16 0x00200000 +# define MOVI_LSL_32 0x00400000 +# define MOVI_LSL_48 0x00600000 +# define XS 0x80000000 /* Wn -> Xn */ +# define DS 0x00400000 /* Sn -> Dn */ +# define CC_NE 0x0 +# define CC_EQ 0x1 +# define CC_CC 0x2 +# define CC_LO CC_CC +# define CC_CS 0x3 +# define CC_HS CC_CS +# define CC_PL 0x4 +# define CC_MI 0x5 +# define CC_VC 0x6 +# define CC_VS 0x7 +# define CC_LS 0x8 +# define CC_HI 0x9 +# define CC_LT 0xa +# define CC_GE 0xb +# define CC_LE 0xc +# define CC_GT 0xd +# define CC_NV 0xe +# define CC_AL 0xf +/* Branches need inverted condition */ +# define BCC_EQ 0x0 +# define BCC_NE 0x1 +# define BCC_CS 0x2 +# define BCC_HS BCC_CS +# define BCC_CC 0x3 +# define BCC_LO BCC_CC +# define BCC_MI 0x4 +# define BCC_PL 0x5 +# define BCC_VS 0x6 +# define BCC_VC 0x7 +# define BCC_HI 0x8 +# define BCC_LS 0x9 +# define BCC_GE 0xa +# define BCC_LT 0xb +# define BCC_GT 0xc +# define BCC_LE 0xd +# define BCC_AL 0xe +# define BCC_NV 0xf +/* adapted and cut down to only tested and required by lightning, + * from data in binutils/aarch64-tbl.h */ +# define A64_ADCS 0x3a000000 +# define A64_SBCS 0x7a000000 +# define A64_ADDI 0x11000000 +# define A64_ADDSI 0xb1000000 +# define A64_SUBI 0x51000000 +# define A64_SUBSI 0x71000000 +# define A64_ADD 0x0b000000 +# define A64_ADDS 0x2b000000 +# define A64_SUB 0x4b000000 +# define A64_NEG 0x4b0003e0 +# define A64_SUBS 0x6b000000 +# define A64_CMP 0x6b00001f +# define A64_SBFM 0x93400000 +# define A64_UBFM 0x53400000 +# define A64_UBFX 0x53000000 +# define A64_B 0x14000000 +# define A64_BL 0x94000000 +# define A64_BR 0xd61f0000 +# define A64_BLR 0xd63f0000 +# define A64_RET 0xd65f0000 +# define A64_CBZ 0x34000000 +# define A64_CBNZ 0x35000000 +# define A64_B_C 0x54000000 +# define A64_CSINC 0x1a800400 +# define A64_REV 0xdac00c00 +# define A64_UDIV 0x1ac00800 +# define A64_SDIV 0x1ac00c00 +# define A64_LSL 0x1ac02000 +# define A64_LSR 0x1ac02400 +# define A64_ASR 0x1ac02800 +# define A64_MUL 0x1b007c00 +# define A64_SMULL 0x9b207c00 +# define A64_SMULH 0x9b407c00 +# define A64_UMULL 0x9ba07c00 +# define A64_UMULH 0x9bc07c00 +# define A64_STRBI 0x39000000 +# define A64_LDRBI 0x39400000 +# define A64_LDRSBI 0x39800000 +# define A64_STRI 0xf9000000 +# define A64_LDRI 0xf9400000 +# define A64_STRHI 0x79000000 +# define A64_LDRHI 0x79400000 +# define A64_LDRSHI 0x79800000 +# define A64_STRWI 0xb9000000 +# define A64_LDRWI 0xb9400000 +# define A64_LDRSWI 0xb9800000 +# define A64_STRB 0x38206800 +# define A64_LDRB 0x38606800 +# define A64_LDRSB 0x38e06800 +# define A64_STR 0xf8206800 +# define A64_LDR 0xf8606800 +# define A64_STRH 0x78206800 +# define A64_LDRH 0x78606800 +# define A64_LDRSH 0x78a06800 +# define A64_STRW 0xb8206800 +# define A64_LDRW 0xb8606800 +# define A64_LDRSW 0xb8a06800 +# define A64_STURB 0x38000000 +# define A64_LDURB 0x38400000 +# define A64_LDURSB 0x38800000 +# define A64_STUR 0xf8000000 +# define A64_LDUR 0xf8400000 +# define A64_STURH 0x78000000 +# define A64_LDURH 0x78400000 +# define A64_LDURSH 0x78800000 +# define A64_STURW 0xb8000000 +# define A64_LDURW 0xb8400000 +# define A64_LDURSW 0xb8800000 +# define A64_STP 0x29000000 +# define A64_LDP 0x29400000 +# define A64_STP_POS 0x29800000 +# define A64_LDP_PRE 0x28c00000 +# define A64_ANDI 0x12400000 +# define A64_ORRI 0x32400000 +# define A64_EORI 0x52400000 +# define A64_ANDSI 0x72000000 +# define A64_AND 0x0a000000 +# define A64_ORR 0x2a000000 +# define A64_MOV 0x2a0003e0 /* AKA orr Rd,xzr,Rm */ +# define A64_MVN 0x2a2003e0 +# define A64_UXTW 0x2a0003e0 /* AKA MOV */ +# define A64_EOR 0x4a000000 +# define A64_ANDS 0x6a000000 +# define A64_MOVN 0x12800000 +# define A64_MOVZ 0x52800000 +# define A64_MOVK 0x72800000 +# define SBFM(Rd,Rn,ImmR,ImmS) oxxrs(A64_SBFM|XS,Rd,Rn,ImmR,ImmS) +# define UBFM(Rd,Rn,ImmR,ImmS) oxxrs(A64_UBFM|XS,Rd,Rn,ImmR,ImmS) +# define UBFX(Rd,Rn,ImmR,ImmS) oxxrs(A64_UBFX,Rd,Rn,ImmR,ImmS) +# define CMP(Rn,Rm) oxx_(A64_CMP|XS,Rn,Rm) +# define CMPI(Rn,Imm12) oxxi(A64_SUBSI|XS,XZR_REGNO,Rn,Imm12) +# define CMPI_12(Rn,Imm12) oxxi(A64_SUBSI|XS|LSL_12,XZR_REGNO,Rn,Imm12) +# define CMNI(Rn,Imm12) oxxi(A64_ADDSI|XS,XZR_REGNO,Rn,Imm12) +# define CMNI_12(Rn,Imm12) oxxi(A64_ADDSI|XS|LSL_12,XZR_REGNO,Rn,Imm12) +# define CSINC(Rd,Rn,Rm,Cc) oxxxc(A64_CSINC|XS,Rd,Rn,Rm,Cc) +# define TST(Rn,Rm) oxxx(A64_ANDS|XS,XZR_REGNO,Rn,Rm) +/* actually should use oxxrs but logical_immediate returns proper encoding */ +# define TSTI(Rn,Imm12) oxxi(A64_ANDSI,XZR_REGNO,Rn,Imm12) +# define MOV(Rd,Rm) ox_x(A64_MOV|XS,Rd,Rm) +# define MVN(Rd,Rm) ox_x(A64_MVN|XS,Rd,Rm) +# define NEG(Rd,Rm) ox_x(A64_NEG|XS,Rd,Rm) +# define MOVN(Rd,Imm16) ox_h(A64_MOVN|XS,Rd,Imm16) +# define MOVN_16(Rd,Imm16) ox_h(A64_MOVN|XS|MOVI_LSL_16,Rd,Imm16) +# define MOVN_32(Rd,Imm16) ox_h(A64_MOVN|XS|MOVI_LSL_32,Rd,Imm16) +# define MOVN_48(Rd,Imm16) ox_h(A64_MOVN|XS|MOVI_LSL_48,Rd,Imm16) +# define MOVZ(Rd,Imm16) ox_h(A64_MOVZ|XS,Rd,Imm16) +# define MOVZ_16(Rd,Imm16) ox_h(A64_MOVZ|XS|MOVI_LSL_16,Rd,Imm16) +# define MOVZ_32(Rd,Imm16) ox_h(A64_MOVZ|XS|MOVI_LSL_32,Rd,Imm16) +# define MOVZ_48(Rd,Imm16) ox_h(A64_MOVZ|XS|MOVI_LSL_48,Rd,Imm16) +# define MOVK(Rd,Imm16) ox_h(A64_MOVK|XS,Rd,Imm16) +# define MOVK_16(Rd,Imm16) ox_h(A64_MOVK|XS|MOVI_LSL_16,Rd,Imm16) +# define MOVK_32(Rd,Imm16) ox_h(A64_MOVK|XS|MOVI_LSL_32,Rd,Imm16) +# define MOVK_48(Rd,Imm16) ox_h(A64_MOVK|XS|MOVI_LSL_48,Rd,Imm16) +# define ADD(Rd,Rn,Rm) oxxx(A64_ADD|XS,Rd,Rn,Rm) +# define ADDI(Rd,Rn,Imm12) oxxi(A64_ADDI|XS,Rd,Rn,Imm12) +# define ADDI_12(Rd,Rn,Imm12) oxxi(A64_ADDI|XS|LSL_12,Rd,Rn,Imm12) +# define MOV_XSP(Rd,Rn) ADDI(Rd,Rn,0) +# define ADDS(Rd,Rn,Rm) oxxx(A64_ADDS|XS,Rd,Rn,Rm) +# define ADDSI(Rd,Rn,Imm12) oxxi(A64_ADDSI|XS,Rd,Rn,Imm12) +# define ADDSI_12(Rd,Rn,Imm12) oxxi(A64_ADDSI|XS|LSL_12,Rd,Rn,Imm12) +# define ADCS(Rd,Rn,Rm) oxxx(A64_ADCS|XS,Rd,Rn,Rm) +# define SUB(Rd,Rn,Rm) oxxx(A64_SUB|XS,Rd,Rn,Rm) +# define SUBI(Rd,Rn,Imm12) oxxi(A64_SUBI|XS,Rd,Rn,Imm12) +# define SUBI_12(Rd,Rn,Imm12) oxxi(A64_SUBI|XS|LSL_12,Rd,Rn,Imm12) +# define SUBS(Rd,Rn,Rm) oxxx(A64_SUBS|XS,Rd,Rn,Rm) +# define SUBSI(Rd,Rn,Imm12) oxxi(A64_SUBSI|XS,Rd,Rn,Imm12) +# define SUBSI_12(Rd,Rn,Imm12) oxxi(A64_SUBSI|XS|LSL_12,Rd,Rn,Imm12) +# define SBCS(Rd,Rn,Rm) oxxx(A64_SBCS|XS,Rd,Rn,Rm) +# define MUL(Rd,Rn,Rm) oxxx(A64_MUL|XS,Rd,Rn,Rm) +# define SMULL(Rd,Rn,Rm) oxxx(A64_SMULL,Rd,Rn,Rm) +# define SMULH(Rd,Rn,Rm) oxxx(A64_SMULH,Rd,Rn,Rm) +# define UMULL(Rd,Rn,Rm) oxxx(A64_UMULL,Rd,Rn,Rm) +# define UMULH(Rd,Rn,Rm) oxxx(A64_UMULH,Rd,Rn,Rm) +# define SDIV(Rd,Rn,Rm) oxxx(A64_SDIV|XS,Rd,Rn,Rm) +# define UDIV(Rd,Rn,Rm) oxxx(A64_UDIV|XS,Rd,Rn,Rm) +# define LSL(Rd,Rn,Rm) oxxx(A64_LSL|XS,Rd,Rn,Rm) +# define LSLI(r0,r1,i0) UBFM(r0,r1,(64-i0)&63,63-i0) +# define ASR(Rd,Rn,Rm) oxxx(A64_ASR|XS,Rd,Rn,Rm) +# define ASRI(r0,r1,i0) SBFM(r0,r1,i0,63) +# define LSR(Rd,Rn,Rm) oxxx(A64_LSR|XS,Rd,Rn,Rm) +# define LSRI(r0,r1,i0) UBFM(r0,r1,i0,63) +# define AND(Rd,Rn,Rm) oxxx(A64_AND|XS,Rd,Rn,Rm) +/* actually should use oxxrs but logical_immediate returns proper encoding */ +# define ANDI(Rd,Rn,Imm12) oxxi(A64_ANDI|XS,Rd,Rn,Imm12) +# define ORR(Rd,Rn,Rm) oxxx(A64_ORR|XS,Rd,Rn,Rm) +/* actually should use oxxrs but logical_immediate returns proper encoding */ +# define ORRI(Rd,Rn,Imm12) oxxi(A64_ORRI|XS,Rd,Rn,Imm12) +# define EOR(Rd,Rn,Rm) oxxx(A64_EOR|XS,Rd,Rn,Rm) +/* actually should use oxxrs but logical_immediate returns proper encoding */ +# define EORI(Rd,Rn,Imm12) oxxi(A64_EORI|XS,Rd,Rn,Imm12) +# define SXTB(Rd,Rn) SBFM(Rd,Rn,0,7) +# define SXTH(Rd,Rn) SBFM(Rd,Rn,0,15) +# define SXTW(Rd,Rn) SBFM(Rd,Rn,0,31) +# define UXTB(Rd,Rn) UBFX(Rd,Rn,0,7) +# define UXTH(Rd,Rn) UBFX(Rd,Rn,0,15) +# define UXTW(Rd,Rm) ox_x(A64_UXTW,Rd,Rm) +# define REV(Rd,Rn) o_xx(A64_REV,Rd,Rn) +# define LDRSB(Rt,Rn,Rm) oxxx(A64_LDRSB,Rt,Rn,Rm) +# define LDRSBI(Rt,Rn,Imm12) oxxi(A64_LDRSBI,Rt,Rn,Imm12) +# define LDURSB(Rt,Rn,Imm9) oxx9(A64_LDURSB,Rt,Rn,Imm9) +# define LDRB(Rt,Rn,Rm) oxxx(A64_LDRB,Rt,Rn,Rm) +# define LDRBI(Rt,Rn,Imm12) oxxi(A64_LDRBI,Rt,Rn,Imm12) +# define LDURB(Rt,Rn,Imm9) oxx9(A64_LDURB,Rt,Rn,Imm9) +# define LDRSH(Rt,Rn,Rm) oxxx(A64_LDRSH,Rt,Rn,Rm) +# define LDRSHI(Rt,Rn,Imm12) oxxi(A64_LDRSHI,Rt,Rn,Imm12) +# define LDURSH(Rt,Rn,Imm9) oxx9(A64_LDURSH,Rt,Rn,Imm9) +# define LDRH(Rt,Rn,Rm) oxxx(A64_LDRH,Rt,Rn,Rm) +# define LDRHI(Rt,Rn,Imm12) oxxi(A64_LDRHI,Rt,Rn,Imm12) +# define LDURH(Rt,Rn,Imm9) oxx9(A64_LDURH,Rt,Rn,Imm9) +# define LDRSW(Rt,Rn,Rm) oxxx(A64_LDRSW,Rt,Rn,Rm) +# define LDRSWI(Rt,Rn,Imm12) oxxi(A64_LDRSWI,Rt,Rn,Imm12) +# define LDURSW(Rt,Rn,Imm9) oxx9(A64_LDURSW,Rt,Rn,Imm9) +# define LDRW(Rt,Rn,Rm) oxxx(A64_LDRW,Rt,Rn,Rm) +# define LDRWI(Rt,Rn,Imm12) oxxi(A64_LDRWI,Rt,Rn,Imm12) +# define LDURW(Rt,Rn,Imm9) oxx9(A64_LDURW,Rt,Rn,Imm9) +# define LDR(Rt,Rn,Rm) oxxx(A64_LDR,Rt,Rn,Rm) +# define LDRI(Rt,Rn,Imm12) oxxi(A64_LDRI,Rt,Rn,Imm12) +# define LDUR(Rt,Rn,Imm9) oxx9(A64_LDUR,Rt,Rn,Imm9) +# define STRB(Rt,Rn,Rm) oxxx(A64_STRB,Rt,Rn,Rm) +# define STRBI(Rt,Rn,Imm12) oxxi(A64_STRBI,Rt,Rn,Imm12) +# define STURB(Rt,Rn,Imm9) oxx9(A64_STURB,Rt,Rn,Imm9) +# define STRH(Rt,Rn,Rm) oxxx(A64_STRH,Rt,Rn,Rm) +# define STRHI(Rt,Rn,Imm12) oxxi(A64_STRHI,Rt,Rn,Imm12) +# define STURH(Rt,Rn,Imm9) oxx9(A64_STURH,Rt,Rn,Imm9) +# define STRW(Rt,Rn,Rm) oxxx(A64_STRW,Rt,Rn,Rm) +# define STRWI(Rt,Rn,Imm12) oxxi(A64_STRWI,Rt,Rn,Imm12) +# define STURW(Rt,Rn,Imm9) oxx9(A64_STURW,Rt,Rn,Imm9) +# define STR(Rt,Rn,Rm) oxxx(A64_STR,Rt,Rn,Rm) +# define STRI(Rt,Rn,Imm12) oxxi(A64_STRI,Rt,Rn,Imm12) +# define STUR(Rt,Rn,Imm9) oxx9(A64_STUR,Rt,Rn,Imm9) +# define LDPI(Rt,Rt2,Rn,Simm7) oxxx7(A64_LDP|XS,Rt,Rt2,Rn,Simm7) +# define STPI(Rt,Rt2,Rn,Simm7) oxxx7(A64_STP|XS,Rt,Rt2,Rn,Simm7) +# define LDPI_PRE(Rt,Rt2,Rn,Simm7) oxxx7(A64_LDP_PRE|XS,Rt,Rt2,Rn,Simm7) +# define STPI_POS(Rt,Rt2,Rn,Simm7) oxxx7(A64_STP_POS|XS,Rt,Rt2,Rn,Simm7) +# define CSET(Rd,Cc) CSINC(Rd,XZR_REGNO,XZR_REGNO,Cc) +# define B(Simm26) o26(A64_B,Simm26) +# define BL(Simm26) o26(A64_BL,Simm26) +# define BR(Rn) o_x_(A64_BR,Rn) +# define BLR(Rn) o_x_(A64_BLR,Rn) +# define RET() o_x_(A64_RET,LR_REGNO) +# define B_C(Cc,Simm19) oc19(A64_B_C,Cc,Simm19) +# define CBZ(Rd,Simm19) ox19(A64_CBZ|XS,Rd,Simm19) +# define CBNZ(Rd,Simm19) ox19(A64_CBNZ|XS,Rd,Simm19) +# define NOP() ii(0xd503201f) +static jit_int32_t logical_immediate(jit_word_t); +# define oxxx(Op,Rd,Rn,Rm) _oxxx(_jit,Op,Rd,Rn,Rm) +static void _oxxx(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define oxxi(Op,Rd,Rn,Imm12) _oxxi(_jit,Op,Rd,Rn,Imm12) +static void _oxxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define oxx9(Op,Rd,Rn,Imm9) _oxx9(_jit,Op,Rd,Rn,Imm9) +static void _oxx9(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define ox19(Op,Rd,Simm19) _ox19(_jit,Op,Rd,Simm19) +static void _ox19(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define oc19(Op,Cc,Simm19) _oc19(_jit,Op,Cc,Simm19) +static void _oc19(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define o26(Op,Simm26) _o26(_jit,Op,Simm26) +static void _oc26(jit_state_t*,jit_int32_t,jit_int32_t); +# define ox_x(Op,Rd,Rn) _ox_x(_jit,Op,Rd,Rn) +static void _ox_x(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define o_xx(Op,Rd,Rn) _o_xx(_jit,Op,Rd,Rn) +static void _o_xx(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define oxx_(Op,Rn,Rm) _oxx_(_jit,Op,Rn,Rm) +static void _oxx_(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define o_x_(Op,Rn) _o_x_(_jit,Op,Rn) +static void _o_x_(jit_state_t*,jit_int32_t,jit_int32_t); +# define ox_h(Op,Rd,Imm16) _ox_h(_jit,Op,Rd,Imm16) +static void _ox_h(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define oxxrs(Op,Rd,Rn,R,S) _oxxrs(_jit,Op,Rd,Rn,R,S) +static void _oxxrs(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define oxxxc(Op,Rd,Rn,Rm,Cc) _oxxxc(_jit,Op,Rd,Rn,Rm,Cc) +static void _oxxxc(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define oxxx7(Op,Rt,Rt2,Rn,Simm7) _oxxx7(_jit,Op,Rt,Rt2,Rn,Simm7) +static void _oxxx7(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define nop(i0) _nop(_jit,i0) +static void _nop(jit_state_t*,jit_int32_t); +# define addr(r0,r1,r2) ADD(r0,r1,r2) +# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0) +static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addcr(r0,r1,r2) ADDS(r0,r1,r2) +# define addci(r0,r1,i0) _addci(_jit,r0,r1,i0) +static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addxr(r0,r1,r2) ADCS(r0,r1,r2) +# define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0) +static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subr(r0,r1,r2) SUB(r0,r1,r2) +# define subi(r0,r1,i0) _subi(_jit,r0,r1,i0) +static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subcr(r0,r1,r2) SUBS(r0,r1,r2) +# define subci(r0,r1,i0) _subci(_jit,r0,r1,i0) +static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subxr(r0,r1,r2) SBCS(r0,r1,r2) +# define subxi(r0,r1,i0) _subxi(_jit,r0,r1,i0) +static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0) +static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define mulr(r0,r1,r2) MUL(r0,r1,r2) +# define muli(r0,r1,i0) _muli(_jit,r0,r1,i0) +static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr(r0,r1,r2,r3) _qmulr(_jit,r0,r1,r2,r3) +static void _qmulr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qmuli(r0,r1,r2,i0) _qmuli(_jit,r0,r1,r2,i0) +static void _qmuli(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr_u(r0,r1,r2,r3) _qmulr_u(_jit,r0,r1,r2,r3) +static void _qmulr_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qmuli_u(r0,r1,r2,i0) _qmuli_u(_jit,r0,r1,r2,i0) +static void _qmuli_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define divr(r0,r1,r2) SDIV(r0,r1,r2) +# define divi(r0,r1,i0) _divi(_jit,r0,r1,i0) +static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define divr_u(r0,r1,r2) UDIV(r0,r1,r2) +# define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0) +static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qdivr(r0,r1,r2,r3) _iqdivr(_jit,1,r0,r1,r2,r3) +# define qdivr_u(r0,r1,r2,r3) _iqdivr(_jit,0,r0,r1,r2,r3) +static void _iqdivr(jit_state_t*,jit_bool_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define qdivi(r0,r1,r2,i0) _qdivi(_jit,r0,r1,r2,i0) +static void _qdivi(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define qdivi_u(r0,r1,r2,i0) _qdivi_u(_jit,r0,r1,r2,i0) +static void _qdivi_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define remr(r0,r1,r2) _remr(_jit,r0,r1,r2) +static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi(r0,r1,i0) _remi(_jit,r0,r1,i0) +static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2) +static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0) +static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define lshr(r0,r1,r2) LSL(r0,r1,r2) +# define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0) +static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr(r0,r1,r2) ASR(r0,r1,r2) +# define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0) +static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr_u(r0,r1,r2) LSR(r0,r1,r2) +# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0) +static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define negr(r0,r1) NEG(r0,r1) +# define comr(r0,r1) MVN(r0,r1) +# define andr(r0,r1,r2) AND(r0,r1,r2) +# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0) +static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define orr(r0,r1,r2) ORR(r0,r1,r2) +# define ori(r0,r1,i0) _ori(_jit,r0,r1,i0) +static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define xorr(r0,r1,r2) EOR(r0,r1,r2) +# define xori(r0,r1,i0) _xori(_jit,r0,r1,i0) +static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_c(r0,r1) LDRSBI(r0,r1,0) +# define ldi_c(r0,i0) _ldi_c(_jit,r0,i0) +static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_uc(r0,r1) _ldr_uc(_jit,r0,r1) +static void _ldr_uc(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0) +static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_s(r0,r1) LDRSHI(r0,r1,0) +# define ldi_s(r0,i0) _ldi_s(_jit,r0,i0) +static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_us(r0,r1) _ldr_us(_jit,r0,r1) +static void _ldr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_us(r0,i0) _ldi_us(_jit,r0,i0) +static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_i(r0,r1) LDRSWI(r0,r1,0) +# define ldi_i(r0,i0) _ldi_i(_jit,r0,i0) +static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_ui(r0,r1) _ldr_ui(_jit,r0,r1) +static void _ldr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_ui(r0,i0) _ldi_ui(_jit,r0,i0) +static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_l(r0,r1) LDRI(r0,r1,0) +static void _ldr_l(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_l(r0,i0) _ldi_l(_jit,r0,i0) +static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_c(r0,r1,r2) _ldxr_c(_jit,r0,r1,r2) +static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0) +static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_uc(r0,r1,r2) _ldxr_uc(_jit,r0,r1,r2) +static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0) +static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_s(r0,r1,r2) LDRSH(r0,r1,r2) +# define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0) +static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_us(r0,r1,r2) _ldxr_us(_jit,r0,r1,r2) +static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0) +static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_i(r0,r1,r2) LDRSW(r0,r1,r2) +# define ldxi_i(r0,r1,i0) _ldxi_i(_jit,r0,r1,i0) +static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_ui(r0,r1,r2) _ldxr_ui(_jit,r0,r1,r2) +static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_ui(r0,r1,i0) _ldxi_ui(_jit,r0,r1,i0) +static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_l(r0,r1,r2) LDR(r0,r1,r2) +# define ldxi_l(r0,r1,i0) _ldxi_l(_jit,r0,r1,i0) +static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_c(r0,r1) STRBI(r1,r0,0) +# define sti_c(i0,r0) _sti_c(_jit,i0,r0) +static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t); +# define str_s(r0,r1) STRHI(r1,r0,0) +# define sti_s(i0,r0) _sti_s(_jit,i0,r0) +static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t); +# define str_i(r0,r1) STRWI(r1,r0,0) +# define sti_i(i0,r0) _sti_i(_jit,i0,r0) +static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); +# define str_l(r0,r1) STRI(r1,r0,0) +# define sti_l(i0,r0) _sti_l(_jit,i0,r0) +static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_c(r0,r1,r2) STRB(r2,r1,r0) +# define stxi_c(i0,r0,r1) _stxi_c(_jit,i0,r0,r1) +static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_s(r0,r1,r2) STRH(r2,r1,r0) +# define stxi_s(i0,r0,r1) _stxi_s(_jit,i0,r0,r1) +static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_i(r0,r1,r2) STRW(r2,r1,r0) +# define stxi_i(i0,r0,r1) _stxi_i(_jit,i0,r0,r1) +static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_l(r0,r1,r2) STR(r2,r1,r0) +# define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1) +static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1) +static void _htonr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1) +static void _htonr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# define htonr_ul(r0,r1) REV(r0,r1) +# else +# define htonr_us(r0,r1) extr_us(r0,r1) +# define htonr_ui(r0,r1) extr_ui(r0,r1) +# define htonr_ul(r0,r1) movr(r0,r1) +# endif +# define extr_c(r0,r1) SXTB(r0,r1) +# define extr_uc(r0,r1) UXTB(r0,r1) +# define extr_s(r0,r1) SXTH(r0,r1) +# define extr_us(r0,r1) UXTH(r0,r1) +# define extr_i(r0,r1) SXTW(r0,r1) +# define extr_ui(r0,r1) UXTW(r0,r1) +# define movr(r0,r1) _movr(_jit,r0,r1) +static void _movr(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi(r0,i0) _movi(_jit,r0,i0) +static void _movi(jit_state_t*,jit_int32_t,jit_word_t); +# define movi_p(r0,i0) _movi_p(_jit,r0,i0) +static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t); +# define ccr(cc,r0,r1,r2) _ccr(_jit,cc,r0,r1,r2) +static void _ccr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define cci(cc,r0,r1,i0) _cci(_jit,cc,r0,r1,i0) +static void _cci(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +# define ltr(r0,r1,r2) ccr(CC_LT,r0,r1,r2) +# define lti(r0,r1,i0) cci(CC_LT,r0,r1,i0) +# define ltr_u(r0,r1,r2) ccr(CC_CC,r0,r1,r2) +# define lti_u(r0,r1,i0) cci(CC_CC,r0,r1,i0) +# define ler(r0,r1,r2) ccr(CC_LE,r0,r1,r2) +# define lei(r0,r1,i0) cci(CC_LE,r0,r1,i0) +# define ler_u(r0,r1,r2) ccr(CC_LS,r0,r1,r2) +# define lei_u(r0,r1,i0) cci(CC_LS,r0,r1,i0) +# define eqr(r0,r1,r2) ccr(CC_EQ,r0,r1,r2) +# define eqi(r0,r1,i0) cci(CC_EQ,r0,r1,i0) +# define ger(r0,r1,r2) ccr(CC_GE,r0,r1,r2) +# define gei(r0,r1,i0) cci(CC_GE,r0,r1,i0) +# define ger_u(r0,r1,r2) ccr(CC_CS,r0,r1,r2) +# define gei_u(r0,r1,i0) cci(CC_CS,r0,r1,i0) +# define gtr(r0,r1,r2) ccr(CC_GT,r0,r1,r2) +# define gti(r0,r1,i0) cci(CC_GT,r0,r1,i0) +# define gtr_u(r0,r1,r2) ccr(CC_HI,r0,r1,r2) +# define gti_u(r0,r1,i0) cci(CC_HI,r0,r1,i0) +# define ner(r0,r1,r2) ccr(CC_NE,r0,r1,r2) +# define nei(r0,r1,i0) cci(CC_NE,r0,r1,i0) +# define bccr(cc,i0,r0,r1) _bccr(_jit,cc,i0,r0,r1) +static jit_word_t +_bccr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t); +# define bcci(cc,i0,r0,i1) _bcci(_jit,cc,i0,r0,i1) +static jit_word_t +_bcci(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_word_t); +# define bltr(i0,r0,r1) bccr(BCC_LT,i0,r0,r1) +# define blti(i0,r0,i1) bcci(BCC_LT,i0,r0,i1) +# define bltr_u(i0,r0,r1) bccr(BCC_CC,i0,r0,r1) +# define blti_u(i0,r0,i1) bcci(BCC_CC,i0,r0,i1) +# define bler(i0,r0,r1) bccr(BCC_LE,i0,r0,r1) +# define blei(i0,r0,i1) bcci(BCC_LE,i0,r0,i1) +# define bler_u(i0,r0,r1) bccr(BCC_LS,i0,r0,r1) +# define blei_u(i0,r0,i1) bcci(BCC_LS,i0,r0,i1) +# define beqr(i0,r0,r1) bccr(BCC_EQ,i0,r0,r1) +# define beqi(i0,r0,i1) _beqi(_jit,i0,r0,i1) +static jit_word_t _beqi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bger(i0,r0,r1) bccr(BCC_GE,i0,r0,r1) +# define bgei(i0,r0,i1) bcci(BCC_GE,i0,r0,i1) +# define bger_u(i0,r0,r1) bccr(BCC_CS,i0,r0,r1) +# define bgei_u(i0,r0,i1) bcci(BCC_CS,i0,r0,i1) +# define bgtr(i0,r0,r1) bccr(BCC_GT,i0,r0,r1) +# define bgti(i0,r0,i1) bcci(BCC_GT,i0,r0,i1) +# define bgtr_u(i0,r0,r1) bccr(BCC_HI,i0,r0,r1) +# define bgti_u(i0,r0,i1) bcci(BCC_HI,i0,r0,i1) +# define bner(i0,r0,r1) bccr(BCC_NE,i0,r0,r1) +# define bnei(i0,r0,i1) _bnei(_jit,i0,r0,i1) +static jit_word_t _bnei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define baddr(cc,i0,r0,r1) _baddr(_jit,cc,i0,r0,r1) +static jit_word_t +_baddr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t); +# define baddi(cc,i0,r0,i1) _baddi(_jit,cc,i0,r0,i1) +static jit_word_t +_baddi(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_word_t); +# define boaddr(i0,r0,r1) baddr(BCC_VS,i0,r0,r1) +# define boaddi(i0,r0,i1) baddi(BCC_VS,i0,r0,i1) +# define boaddr_u(i0,r0,r1) baddr(BCC_HS,i0,r0,r1) +# define boaddi_u(i0,r0,i1) baddi(BCC_HS,i0,r0,i1) +# define bxaddr(i0,r0,r1) baddr(BCC_VC,i0,r0,r1) +# define bxaddi(i0,r0,i1) baddi(BCC_VC,i0,r0,i1) +# define bxaddr_u(i0,r0,r1) baddr(BCC_LO,i0,r0,r1) +# define bxaddi_u(i0,r0,i1) baddi(BCC_LO,i0,r0,i1) +# define bsubr(cc,i0,r0,r1) _bsubr(_jit,cc,i0,r0,r1) +static jit_word_t +_bsubr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t); +# define bsubi(cc,i0,r0,i1) _bsubi(_jit,cc,i0,r0,i1) +static jit_word_t +_bsubi(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_word_t); +# define bosubr(i0,r0,r1) bsubr(BCC_VS,i0,r0,r1) +# define bosubi(i0,r0,i1) bsubi(BCC_VS,i0,r0,i1) +# define bosubr_u(i0,r0,r1) bsubr(BCC_LO,i0,r0,r1) +# define bosubi_u(i0,r0,i1) bsubi(BCC_LO,i0,r0,i1) +# define bxsubr(i0,r0,r1) bsubr(BCC_VC,i0,r0,r1) +# define bxsubi(i0,r0,i1) bsubi(BCC_VC,i0,r0,i1) +# define bxsubr_u(i0,r0,r1) bsubr(BCC_HS,i0,r0,r1) +# define bxsubi_u(i0,r0,i1) bsubi(BCC_HS,i0,r0,i1) +# define bmxr(cc,i0,r0,r1) _bmxr(_jit,cc,i0,r0,r1) +static jit_word_t +_bmxr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t); +# define bmxi(cc,i0,r0,r1) _bmxi(_jit,cc,i0,r0,r1) +static jit_word_t +_bmxi(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_word_t); +# define bmsr(i0,r0,r1) bmxr(BCC_NE,i0,r0,r1) +# define bmsi(i0,r0,i1) bmxi(BCC_NE,i0,r0,i1) +# define bmcr(i0,r0,r1) bmxr(BCC_EQ,i0,r0,r1) +# define bmci(i0,r0,i1) bmxi(BCC_EQ,i0,r0,i1) +# define jmpr(r0) BR(r0) +# define jmpi(i0) _jmpi(_jit,i0) +static void _jmpi(jit_state_t*,jit_word_t); +# define jmpi_p(i0) _jmpi_p(_jit,i0) +static jit_word_t _jmpi_p(jit_state_t*,jit_word_t); +# define callr(r0) BLR(r0) +# define calli(i0) _calli(_jit,i0) +static void _calli(jit_state_t*,jit_word_t); +# define calli_p(i0) _calli_p(_jit,i0) +static jit_word_t _calli_p(jit_state_t*,jit_word_t); +# define prolog(i0) _prolog(_jit,i0) +static void _prolog(jit_state_t*,jit_node_t*); +# define epilog(i0) _epilog(_jit,i0) +static void _epilog(jit_state_t*,jit_node_t*); +# define vastart(r0) _vastart(_jit, r0) +static void _vastart(jit_state_t*, jit_int32_t); +# define vaarg(r0, r1) _vaarg(_jit, r0, r1) +static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t); +# define patch_at(jump,label) _patch_at(_jit,jump,label) +static void _patch_at(jit_state_t*,jit_word_t,jit_word_t); +#endif + +#if CODE +static jit_int32_t +logical_immediate(jit_word_t imm) +{ + /* There are 5334 possible immediate values, but to avoid the + * need of either too complex code or large lookup tables, + * only check for (simply) encodable common/small values */ + switch (imm) { + case -16: return (0xf3b); + case -15: return (0xf3c); + case -13: return (0xf3d); + case -9: return (0xf3e); + case -8: return (0xf7c); + case -7: return (0xf7d); + case -5: return (0xf7e); + case -4: return (0xfbd); + case -3: return (0xfbe); + case -2: return (0xffe); + case 1: return (0x000); + case 2: return (0xfc0); + case 3: return (0x001); + case 4: return (0xf80); + case 6: return (0xfc1); + case 7: return (0x002); + case 8: return (0xf40); + case 12: return (0xf81); + case 14: return (0xfc2); + case 15: return (0x003); + case 16: return (0xf00); + default: return (-1); + } +} + +static void +_oxxx(jit_state_t *_jit, jit_int32_t Op, + jit_int32_t Rd, jit_int32_t Rn, jit_int32_t Rm) +{ + instr_t i; + assert(!(Rd & ~0x1f)); + assert(!(Rn & ~0x1f)); + assert(!(Rm & ~0x1f)); + assert(!(Op & ~0xffe0fc00)); + i.w = Op; + i.Rd.b = Rd; + i.Rn.b = Rn; + i.Rm.b = Rm; + ii(i.w); +} + +static void +_oxxi(jit_state_t *_jit, jit_int32_t Op, + jit_int32_t Rd, jit_int32_t Rn, jit_int32_t Imm12) +{ + instr_t i; + assert(!(Rd & ~0x1f)); + assert(!(Rn & ~0x1f)); + assert(!(Imm12 & ~0xfff)); + assert(!(Op & ~0xffe00000)); + i.w = Op; + i.Rd.b = Rd; + i.Rn.b = Rn; + i.imm12.b = Imm12; + ii(i.w); +} + +static void +_oxx9(jit_state_t *_jit, jit_int32_t Op, + jit_int32_t Rd, jit_int32_t Rn, jit_int32_t Imm9) +{ + instr_t i; + assert(!(Rd & ~0x1f)); + assert(!(Rn & ~0x1f)); + assert(!(Imm9 & ~0x1ff)); + assert(!(Op & ~0xffe00000)); + i.w = Op; + i.Rd.b = Rd; + i.Rn.b = Rn; + i.imm9.b = Imm9; + ii(i.w); +} + +static void +_ox19(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Rd, jit_int32_t Simm19) +{ + instr_t i; + assert(!(Rd & ~0x1f)); + assert(Simm19 >= -262148 && Simm19 <= 262143); + assert(!(Op & ~0xff000000)); + i.w = Op; + i.Rd.b = Rd; + i.imm19.b = Simm19; + ii(i.w); +} + +static void +_oc19(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Cc, jit_int32_t Simm19) +{ + instr_t i; + assert(!(Cc & ~0xf)); + assert(Simm19 >= -262148 && Simm19 <= 262143); + assert(!(Op & ~0xff000000)); + i.w = Op; + i.cond2.b = Cc; + i.imm19.b = Simm19; + ii(i.w); +} + +static void +_o26(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Simm26) +{ + instr_t i; + assert(Simm26 >= -33554432 && Simm26 <= 33554431); + assert(!(Op & ~0xfc000000)); + i.w = Op; + i.imm26.b = Simm26; + ii(i.w); +} + +static void +_ox_x(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Rd, jit_int32_t Rm) +{ + instr_t i; + assert(!(Rd & ~0x1f)); + assert(!(Rm & ~0x1f)); + assert(!(Op & ~0xffe0ffe0)); + i.w = Op; + i.Rd.b = Rd; + i.Rm.b = Rm; + ii(i.w); +} + +static void +_o_xx(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Rd, jit_int32_t Rn) +{ + instr_t i; + assert(!(Rd & ~0x1f)); + assert(!(Rn & ~0x1f)); + assert(!(Op & ~0xfffffc00)); + i.w = Op; + i.Rd.b = Rd; + i.Rn.b = Rn; + ii(i.w); +} + +static void +_oxx_(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Rn, jit_int32_t Rm) +{ + instr_t i; + assert(!(Rn & ~0x1f)); + assert(!(Rm & ~0x1f)); + assert(!(Op & ~0xffc0fc1f)); + i.w = Op; + i.Rn.b = Rn; + i.Rm.b = Rm; + ii(i.w); +} + +static void +_o_x_(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Rn) +{ + instr_t i; + assert(!(Rn & ~0x1f)); + assert(!(Op & 0x3e0)); + i.w = Op; + i.Rn.b = Rn; + ii(i.w); +} + +static void +_ox_h(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Rd, jit_int32_t Imm16) +{ + instr_t i; + assert(!(Rd & ~0x1f)); + assert(!(Imm16 & ~0xffff)); + assert(!(Op & ~0xffe00000)); + i.w = Op; + i.Rd.b = Rd; + i.imm16.b = Imm16; + ii(i.w); +} + +static void +_oxxrs(jit_state_t *_jit, jit_int32_t Op, + jit_int32_t Rd, jit_int32_t Rn, jit_int32_t R, jit_int32_t S) +{ + instr_t i; + assert(!(Rd & ~0x1f)); + assert(!(Rn & ~0x1f)); + assert(!(R & ~0x3f)); + assert(!(S & ~0x3f)); + assert(!(Op & ~0xffc00000)); + i.w = Op; + i.Rd.b = Rd; + i.Rn.b = Rn; + i.immr.b = R; + i.imms.b = S; + ii(i.w); +} + +static void +_oxxxc(jit_state_t *_jit, jit_int32_t Op, + jit_int32_t Rd, jit_int32_t Rn, jit_int32_t Rm, jit_int32_t Cc) +{ + instr_t i; + assert(!(Rd & ~0x1f)); + assert(!(Rn & ~0x1f)); + assert(!(Rm & ~0x1f)); + assert(!(Cc & ~0xf)); + assert(!(Op & ~0xffc00c00)); + i.w = Op; + i.Rd.b = Rd; + i.Rn.b = Rn; + i.Rm.b = Rm; + i.cond.b = Cc; + ii(i.w); +} + +static void +_oxxx7(jit_state_t *_jit, jit_int32_t Op, + jit_int32_t Rt, jit_int32_t Rt2, jit_int32_t Rn, jit_int32_t Simm7) +{ + instr_t i; + assert(!(Rt & ~0x1f)); + assert(!(Rt2 & ~0x1f)); + assert(!(Rn & ~0x1f)); + assert(Simm7 >= -128 && Simm7 <= 127); + assert(!(Op & ~0xffc003e0)); + i.w = Op; + i.Rt.b = Rt; + i.Rt2.b = Rt2; + i.Rn.b = Rn; + i.imm7.b = Simm7; + ii(i.w); +} + +static void +_nop(jit_state_t *_jit, jit_int32_t i0) +{ + for (; i0 > 0; i0 -= 4) + NOP(); + assert(i0 == 0); +} + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + jit_word_t is = i0 >> 12; + jit_word_t in = -i0; + jit_word_t iS = in >> 12; + if ( i0 >= 0 && i0 <= 0xfff) + ADDI (r0, r1, i0); + else if ((is << 12) == i0 && is >= 0 && is <= 0xfff) + ADDI_12(r0, r1, is); + else if ( in >= 0 && in <= 0xfff) + SUBI (r0, r1, in); + else if ((iS << 12) == is && iS >= 0 && iS <= 0xfff) + SUBI_12(r0, r1, iS); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + jit_word_t is = i0 >> 12; + jit_word_t in = -i0; + jit_word_t iS = in >> 12; + if ( i0 >= 0 && i0 <= 0xfff) + ADDSI (r0, r1, i0); + else if ((is << 12) == i0 && is >= 0 && is <= 0xfff) + ADDSI_12(r0, r1, is); + else if ( in >= 0 && in <= 0xfff) + SUBSI (r0, r1, in); + else if ((iS << 12) == is && iS >= 0 && iS <= 0xfff) + SUBSI_12(r0, r1, iS); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addcr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addxr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + jit_word_t is = i0 >> 12; + if ( i0 >= 0 && i0 <= 0xfff) + SUBI (r0, r1, i0); + else if ((is << 12) == i0 && is >= 0 && is <= 0xfff) + SUBI_12(r0, r1, is); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + jit_word_t is = i0 >> 12; + if ( i0 >= 0 && i0 <= 0xfff) + SUBSI (r0, r1, i0); + else if ((is << 12) == i0 && is >= 0 && is <= 0xfff) + SUBSI_12(r0, r1, is); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subcr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subxr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + subi(r0, r1, i0); + negr(r0, r0); +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + mulr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_qmulr(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t reg; + if (r0 == r2 || r0 == r3) { + reg = jit_get_reg(jit_class_gpr); + mulr(rn(reg), r2, r3); + } + else + mulr(r0, r2, r3); + SMULH(r1, r2, r3); + if (r0 == r2 || r0 == r3) { + movr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_qmuli(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + qmulr(r0, r1, r2, rn(reg)); + jit_unget_reg(reg); +} + +static void +_qmulr_u(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t reg; + if (r0 == r2 || r0 == r3) { + reg = jit_get_reg(jit_class_gpr); + mulr(rn(reg), r2, r3); + } + else + mulr(r0, r2, r3); + UMULH(r1, r2, r3); + if (r0 == r2 || r0 == r3) { + movr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_qmuli_u(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + qmulr_u(r0, r1, r2, rn(reg)); + jit_unget_reg(reg); +} + +static void +_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + divr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + divr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_iqdivr(jit_state_t *_jit, jit_bool_t sign, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t sv0, rg0; + jit_int32_t sv1, rg1; + if (r0 == r2 || r0 == r3) { + sv0 = jit_get_reg(jit_class_gpr); + rg0 = rn(sv0); + } + else + rg0 = r0; + if (r1 == r2 || r1 == r3) { + sv1 = jit_get_reg(jit_class_gpr); + rg1 = rn(sv1); + } + else + rg1 = r1; + if (sign) + divr(rg0, r2, r3); + else + divr_u(rg0, r2, r3); + mulr(rg1, r3, rg0); + subr(rg1, r2, rg1); + if (rg0 != r0) { + movr(r0, rg0); + jit_unget_reg(sv0); + } + if (rg1 != r1) { + movr(r1, rg1); + jit_unget_reg(sv1); + } +} + +static void +_qdivi(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + qdivr(r0, r1, r2, rn(reg)); + jit_unget_reg(reg); +} + +static void +_qdivi_u(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + qdivr_u(r0, r1, r2, rn(reg)); + jit_unget_reg(reg); +} + +static void +_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r1 || r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + divr(rn(reg), r1, r2); + mulr(rn(reg), r2, rn(reg)); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + else { + divr(r0, r1, r2); + mulr(r0, r2, r0); + subr(r0, r1, r0); + } +} + +static void +_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r1 || r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + divr_u(rn(reg), r1, r2); + mulr(rn(reg), r2, rn(reg)); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + else { + divr_u(r0, r1, r2); + mulr(r0, r2, r0); + subr(r0, r1, r0); + } +} + +static void +_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0 == 0) + movr(r0, r1); + else { + assert(i0 > 0 && i0 < 64); + LSLI(r0, r1, i0); + } +} + +static void +_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0 == 0) + movr(r0, r1); + else { + assert(i0 > 0 && i0 < 64); + ASRI(r0, r1, i0); + } +} + +static void +_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0 == 0) + movr(r0, r1); + else { + assert(i0 > 0 && i0 < 64); + LSRI(r0, r1, i0); + } +} + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + jit_int32_t imm; + if (i0 == 0) + movi(r0, 0); + else if (i0 == -1) + movr(r0, r1); + else { + imm = logical_immediate(i0); + if (imm != -1) + ANDI(r0, r1, imm); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + andr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + jit_int32_t imm; + if (i0 == 0) + movr(r0, r1); + else if (i0 == -1) + movi(r0, -1); + else { + imm = logical_immediate(i0); + if (imm != -1) + ORRI(r0, r1, imm); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + orr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + jit_int32_t imm; + if (i0 == 0) + movr(r0, r1); + else if (i0 == -1) + comr(r0, r1); + else { + imm = logical_immediate(i0); + if (imm != -1) + EORI(r0, r1, imm); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + xorr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +#if __BYTE_ORDER == __LITTLE_ENDIAN +static void +_htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + htonr_ul(r0, r1); + rshi_u(r0, r0, 48); +} + +static void +_htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + htonr_ul(r0, r1); + rshi_u(r0, r0, 32); +} +#endif + +static void +_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + LDRBI(r0, r1, 0); +#if 0 + extr_uc(r0, r0); +#endif +} + +static void +_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + LDRHI(r0, r1, 0); +#if 0 + extr_us(r0, r0); +#endif +} + +static void +_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + LDRWI(r0, r1, 0); +#if 0 + extr_ui(r0, r0); +#endif +} + +static void +_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + LDRSB(r0, r1, r2); + extr_c(r0, r0); +} + +static void +_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= 0 && i0 <= 4095) + LDRSBI(r0, r1, i0); + else if (i0 > -256 && i0 < 0) + LDURSB(r0, r1, i0 & 0x1ff); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDRSB(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + extr_c(r0, r0); +} + +static void +_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + LDRB(r0, r1, r2); +#if 0 + extr_uc(r0, r0); +#endif +} + +static void +_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= 0 && i0 <= 4095) + LDRBI(r0, r1, i0); + else if (i0 > -256 && i0 < 0) + LDURB(r0, r1, i0 & 0x1ff); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); + } +#if 0 + extr_uc(r0, r0); +#endif +} + +static void +_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + assert(!(i0 & 1)); + if (i0 >= 0 && i0 <= 8191) + LDRSHI(r0, r1, i0 >> 1); + else if (i0 > -256 && i0 < 0) + LDURSH(r0, r1, i0 & 0x1ff); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDRSH(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + LDRH(r0, r1, r2); +#if 0 + extr_us(r0, r0); +#endif +} + +static void +_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + assert(!(i0 & 1)); + if (i0 >= 0 && i0 <= 8191) + LDRHI(r0, r1, i0 >> 1); + else if (i0 > -256 && i0 < 0) + LDURH(r0, r1, i0 & 0x1ff); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDRH(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +#if 0 + extr_us(r0, r0); +#endif +} + +static void +_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + assert(!(i0 & 3)); + if (i0 >= 0 && i0 <= 16383) + LDRSWI(r0, r1, i0 >> 2); + else if (i0 > -256 && i0 < 0) + LDURSW(r0, r1, i0 & 0x1ff); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + LDRW(r0, r1, r2); +#if 0 + extr_ui(r0, r0); +#endif +} + +static void +_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + assert(!(i0 & 3)); + if (i0 >= 0 && i0 <= 16383) + LDRWI(r0, r1, i0 >> 2); + else if (i0 > -256 && i0 < 0) + LDURW(r0, r1, i0 & 0x1ff); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDRW(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +#if 0 + extr_ui(r0, r0); +#endif +} + +static void +_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + assert(!(i0 & 7)); + if (i0 >= 0 && i0 <= 32767) + LDRI(r0, r1, i0 >> 3); + else if (i0 > -256 && i0 < 0) + LDUR(r0, r1, i0 & 0x1ff); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_c(rn(reg), r0); + jit_unget_reg(reg); +} + +static void +_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_s(rn(reg), r0); + jit_unget_reg(reg); +} + +static void +_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_i(rn(reg), r0); + jit_unget_reg(reg); +} + +static void +_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_l(rn(reg), r0); + jit_unget_reg(reg); +} + +static void +_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0 >= 0 && i0 <= 4095) + STRBI(r1, r0, i0); + else if (i0 > -256 && i0 < 0) + STURB(r1, r0, i0 & 0x1ff); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_c(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + assert(!(i0 & 1)); + if (i0 >= 0 && i0 <= 8191) + STRHI(r1, r0, i0 >> 1); + else if (i0 > -256 && i0 < 0) + STURH(r1, r0, i0 & 0x1ff); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_s(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + assert(!(i0 & 3)); + if (i0 >= 0 && i0 <= 16383) + STRWI(r1, r0, i0 >> 2); + else if (i0 > -256 && i0 < 0) + STURW(r1, r0, i0 & 0x1ff); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_i(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + assert(!(i0 & 7)); + if (i0 >= 0 && i0 <= 32767) + STRI(r1, r0, i0 >> 3); + else if (i0 > -256 && i0 < 0) + STUR(r1, r0, i0 & 0x1ff); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_l(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + MOV(r0, r1); +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t n0, ibit, nbit; + n0 = ~i0; + ibit = nbit = 0; + if (i0 & 0x000000000000ffffL) ibit |= 1; + if (i0 & 0x00000000ffff0000L) ibit |= 2; + if (i0 & 0x0000ffff00000000L) ibit |= 4; + if (i0 & 0xffff000000000000L) ibit |= 8; + if (n0 & 0x000000000000ffffL) nbit |= 1; + if (n0 & 0x00000000ffff0000L) nbit |= 2; + if (n0 & 0x0000ffff00000000L) nbit |= 4; + if (n0 & 0xffff000000000000L) nbit |= 8; + switch (ibit) { + case 0: + MOVZ (r0, 0); + break; + case 1: + MOVZ (r0, i0 & 0xffff); + break; + case 2: + MOVZ_16(r0, (i0 >> 16) & 0xffff); + break; + case 3: + MOVZ (r0, i0 & 0xffff); + MOVK_16(r0, (i0 >> 16) & 0xffff); + break; + case 4: + MOVZ_32(r0, (i0 >> 32) & 0xffff); + break; + case 5: + MOVZ (r0, i0 & 0xffff); + MOVK_32(r0, (i0 >> 32) & 0xffff); + break; + case 6: + MOVZ_16(r0, (i0 >> 16) & 0xffff); + MOVK_32(r0, (i0 >> 32) & 0xffff); + break; + case 7: + if (nbit == 8) + MOVN_48(r0, (n0 >> 48) & 0xffff); + else { + MOVZ (r0, i0 & 0xffff); + MOVK_16(r0, (i0 >> 16) & 0xffff); + MOVK_32(r0, (i0 >> 32) & 0xffff); + } + break; + case 8: + MOVZ_48(r0, (i0 >> 48) & 0xffff); + break; + case 9: + MOVZ (r0, i0 & 0xffff); + MOVK_48(r0, (i0 >> 48) & 0xffff); + break; + case 10: + MOVZ_16(r0, (i0 >> 16) & 0xffff); + MOVK_48(r0, (i0 >> 48) & 0xffff); + break; + case 11: + if (nbit == 4) + MOVN_32(r0, (n0 >> 32) & 0xffff); + else { + MOVZ (r0, i0 & 0xffff); + MOVK_16(r0, (i0 >> 16) & 0xffff); + MOVK_48(r0, (i0 >> 48) & 0xffff); + } + break; + case 12: + MOVZ_32(r0, (i0 >> 32) & 0xffff); + MOVK_48(r0, (i0 >> 48) & 0xffff); + break; + case 13: + if (nbit == 2) + MOVN_16(r0, (n0 >> 16) & 0xffff); + else { + MOVZ (r0, i0 & 0xffff); + MOVK_32(r0, (i0 >> 32) & 0xffff); + MOVK_48(r0, (i0 >> 48) & 0xffff); + } + break; + case 14: + if (nbit == 1) + MOVN (r0, (n0) & 0xffff); + else { + MOVZ_16(r0, (i0 >> 16) & 0xffff); + MOVK_32(r0, (i0 >> 32) & 0xffff); + MOVK_48(r0, (i0 >> 48) & 0xffff); + } + break; + case 15: + if (nbit == 0) + MOVN (r0, 0); + else if (nbit == 1) + MOVN (r0, n0 & 0xffff); + else if (nbit == 8) + MOVN_48(r0, (n0 >> 48) & 0xffff); + else { + MOVZ (r0, i0 & 0xffff); + MOVK_16(r0, (i0 >> 16) & 0xffff); + MOVK_32(r0, (i0 >> 32) & 0xffff); + MOVK_48(r0, (i0 >> 48) & 0xffff); + } + break; + default: + abort(); + } +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + w = _jit->pc.w; + MOVZ (r0, i0 & 0xffff); + MOVK_16(r0, (i0 >> 16) & 0xffff); + MOVK_32(r0, (i0 >> 32) & 0xffff); + MOVK_48(r0, (i0 >> 48) & 0xffff); + return (w); +} + +static void +_ccr(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMP(r1, r2); + CSET(r0, cc); +} + +static void +_cci(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + jit_word_t is = i0 >> 12; + jit_word_t in = -i0; + jit_word_t iS = in >> 12; + if ( i0 >= 0 && i0 <= 0xfff) + CMPI (r1, i0); + else if ((is << 12) == i0 && is >= 0 && is <= 0xfff) + CMPI_12(r1, is); + else if ( in >= 0 && in <= 0xfff) + CMNI (r1, in); + else if ((iS << 12) == is && iS >= 0 && iS <= 0xfff) + CMNI_12(r1, iS); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMP(r1, rn(reg)); + jit_unget_reg(reg); + } + CSET(r0, cc); +} + +static jit_word_t +_bccr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, d; + CMP(r0, r1); + w = _jit->pc.w; + d = (i0 - w) >> 2; + B_C(cc, d); + return (w); +} + +static jit_word_t +_bcci(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + jit_word_t w, d; + jit_word_t is = i1 >> 12; + jit_word_t in = -i1; + jit_word_t iS = in >> 12; + if ( i1 >= 0 && i1 <= 0xfff) + CMPI (r0, i1); + else if ((is << 12) == i1 && is >= 0 && is <= 0xfff) + CMPI_12(r0, is); + else if ( in >= 0 && in <= 0xfff) + CMNI (r0, in); + else if ((iS << 12) == is && iS >= 0 && iS <= 0xfff) + CMNI_12(r0, iS); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMP(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = (i0 - w) >> 2; + B_C(cc, d); + return (w); +} + +static jit_word_t +_beqi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + if (i1 == 0) { + w = _jit->pc.w; + CBZ(r0, (i0 - w) >> 2); + } + else + w = bcci(BCC_EQ, i0, r0, i1); + return (w); +} + +static jit_word_t +_bnei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + if (i1 == 0) { + w = _jit->pc.w; + CBNZ(r0, (i0 - w) >> 2); + } + else + w = bcci(BCC_NE, i0, r0, i1); + return (w); +} + +static jit_word_t +_baddr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + addcr(r0, r0, r1); + w = _jit->pc.w; + B_C(cc, (i0 - w) >> 2); + return (w); +} + +static jit_word_t +_baddi(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + addci(r0, r0, i1); + w = _jit->pc.w; + B_C(cc, (i0 - w) >> 2); + return (w); +} + +static jit_word_t +_bsubr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + subcr(r0, r0, r1); + w = _jit->pc.w; + B_C(cc, (i0 - w) >> 2); + return (w); +} + +static jit_word_t +_bsubi(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + subci(r0, r0, i1); + w = _jit->pc.w; + B_C(cc, (i0 - w) >> 2); + return (w); +} + +static jit_word_t +_bmxr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + TST(r0, r1); + w = _jit->pc.w; + B_C(cc, (i0 - w) >> 2); + return (w); +} + +static jit_word_t +_bmxi(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + jit_int32_t imm; + imm = logical_immediate(i1); + if (imm != -1) + TSTI(r0, imm); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + TST(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + B_C(cc, (i0 - w) >> 2); + return (w); +} + +static void +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + w = (i0 - _jit->pc.w) >> 2; + if (w >= -33554432 && w <= 33554431) + B(w); + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + } +} + +static jit_word_t +_jmpi_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + w = movi_p(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_calli(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + w = (i0 - _jit->pc.w) >> 2; + if (w >= -33554432 && w <= 33554431) + BL(w); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + callr(rn(reg)); + jit_unget_reg(reg); + } +} + +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + w = movi_p(rn(reg), i0); + callr(rn(reg)); + jit_unget_reg(reg); + return (w); +} + +/* + * prolog and epilog not as "optimized" as one would like, but the + * problem of overallocating stack space to save callee save registers + * exists on all ports, and is still a todo to use a variable + * stack_framesize + * value, what would cause needing to patch some calls, most likely + * the offset of jit_arg* of stack arguments. + */ +static void +_prolog(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t reg; + if (_jitc->function->define_frame || _jitc->function->assume_frame) { + jit_int32_t frame = -_jitc->function->frame; + assert(_jitc->function->self.aoff >= frame); + if (_jitc->function->assume_frame) + return; + _jitc->function->self.aoff = frame; + } + if (_jitc->function->allocar) + _jitc->function->self.aoff &= -16; + _jitc->function->stack = ((_jitc->function->self.alen - + /* align stack at 16 bytes */ + _jitc->function->self.aoff) + 15) & -16; + STPI_POS(FP_REGNO, LR_REGNO, SP_REGNO, -(stack_framesize >> 3)); + MOV_XSP(FP_REGNO, SP_REGNO); +#define SPILL(L, R, O) \ + do { \ + if (jit_regset_tstbit(&_jitc->function->regset, _R##L)) { \ + if (jit_regset_tstbit(&_jitc->function->regset, _R##R)) \ + STPI(L, R, SP_REGNO, O); \ + else \ + STRI(L, SP_REGNO, O); \ + } \ + else if (jit_regset_tstbit(&_jitc->function->regset, _R##R)) \ + STRI(R, SP_REGNO, O + 1); \ + } while (0) + SPILL(19, 20, 2); + SPILL(21, 22, 4); + SPILL(23, 24, 6); + SPILL(25, 26, 8); + SPILL(27, 28, 10); +#undef SPILL +#define SPILL(R, O) \ + do { \ + if (jit_regset_tstbit(&_jitc->function->regset, _V##R)) \ + stxi_d(O, SP_REGNO, R); \ + } while (0) + SPILL( 8, 96); + SPILL( 9, 104); + SPILL(10, 112); + SPILL(11, 120); + SPILL(12, 128); + SPILL(13, 136); + SPILL(14, 144); + SPILL(15, 152); +#undef SPILL + if (_jitc->function->stack) + subi(SP_REGNO, SP_REGNO, _jitc->function->stack); + if (_jitc->function->allocar) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), _jitc->function->self.aoff); + stxi_i(_jitc->function->aoffoff, FP_REGNO, rn(reg)); + jit_unget_reg(reg); + } + + if (_jitc->function->self.call & jit_call_varargs) { + /* Save gp registers in the save area, if any is a vararg */ + for (reg = 8 - _jitc->function->vagp / -8; + jit_arg_reg_p(reg); ++reg) + stxi(_jitc->function->vaoff + offsetof(jit_va_list_t, x0) + + reg * 8, FP_REGNO, rn(JIT_RA0 - reg)); + + for (reg = 8 - _jitc->function->vafp / -16; + jit_arg_f_reg_p(reg); ++reg) + /* Save fp registers in the save area, if any is a vararg */ + /* Note that the full 16 byte register is not saved, because + * lightning only handles float and double, and, while + * attempting to provide a va_list compatible pointer as + * jit_va_start return, does not guarantee it (on all ports). */ + stxi_d(_jitc->function->vaoff + offsetof(jit_va_list_t, q0) + + reg * 16 + offsetof(jit_qreg_t, l), FP_REGNO, rn(_V0 - reg)); + } +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *node) +{ + if (_jitc->function->assume_frame) + return; + if (_jitc->function->stack) + MOV_XSP(SP_REGNO, FP_REGNO); +#define LOAD(L, R, O) \ + do { \ + if (jit_regset_tstbit(&_jitc->function->regset, _R##L)) { \ + if (jit_regset_tstbit(&_jitc->function->regset, _R##R)) \ + LDPI(L, R, SP_REGNO, O); \ + else \ + LDRI(L, SP_REGNO, O); \ + } \ + else if (jit_regset_tstbit(&_jitc->function->regset, _R##R)) \ + LDRI(R, SP_REGNO, O + 1); \ + } while (0) + LOAD(19, 20, 2); + LOAD(21, 22, 4); + LOAD(23, 24, 6); + LOAD(25, 26, 8); + LOAD(27, 28, 10); +#undef LOAD +#define LOAD(R, O) \ + do { \ + if (jit_regset_tstbit(&_jitc->function->regset, _V##R)) \ + ldxi_d(R, SP_REGNO, O); \ + } while (0) + LOAD( 8, 96); + LOAD( 9, 104); + LOAD(10, 112); + LOAD(11, 120); + LOAD(12, 128); + LOAD(13, 136); + LOAD(14, 144); + LOAD(15, 152); +#undef LOAD + LDPI_PRE(FP_REGNO, LR_REGNO, SP_REGNO, stack_framesize >> 3); + RET(); +} + +static void +_vastart(jit_state_t *_jit, jit_int32_t r0) +{ + jit_int32_t reg; + + assert(_jitc->function->self.call & jit_call_varargs); + + /* Return jit_va_list_t in the register argument */ + addi(r0, FP_REGNO, _jitc->function->vaoff); + + reg = jit_get_reg(jit_class_gpr); + + /* Initialize stack pointer to the first stack argument. */ + addi(rn(reg), FP_REGNO, _jitc->function->self.size); + stxi(offsetof(jit_va_list_t, stack), r0, rn(reg)); + + /* Initialize gp top pointer to the first stack argument. */ + addi(rn(reg), r0, va_gp_top_offset); + stxi(offsetof(jit_va_list_t, gptop), r0, rn(reg)); + + /* Initialize fp top pointer to the first stack argument. */ + addi(rn(reg), r0, va_fp_top_offset); + stxi(offsetof(jit_va_list_t, fptop), r0, rn(reg)); + + /* Initialize gp offset in the save area. */ + movi(rn(reg), _jitc->function->vagp); + stxi_i(offsetof(jit_va_list_t, gpoff), r0, rn(reg)); + + /* Initialize fp offset in the save area. */ + movi(rn(reg), _jitc->function->vafp); + stxi_i(offsetof(jit_va_list_t, fpoff), r0, rn(reg)); + + jit_unget_reg(reg); +} + +static void +_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t ge_code; + jit_word_t lt_code; + jit_int32_t rg0, rg1; + + assert(_jitc->function->self.call & jit_call_varargs); + + rg0 = jit_get_reg(jit_class_gpr); + rg1 = jit_get_reg(jit_class_gpr); + + /* Load the gp offset in save area in the first temporary. */ + ldxi_i(rn(rg0), r1, offsetof(jit_va_list_t, gpoff)); + + /* Jump over if there are no remaining arguments in the save area. */ + ge_code = bgei(_jit->pc.w, rn(rg0), 0); + + /* Load the gp save pointer in the second temporary. */ + ldxi(rn(rg1), r1, offsetof(jit_va_list_t, gptop)); + + /* Load the vararg argument in the first argument. */ + ldxr(r0, rn(rg1), rn(rg0)); + + /* Update the gp offset. */ + addi(rn(rg0), rn(rg0), 8); + stxi_i(offsetof(jit_va_list_t, gpoff), r1, rn(rg0)); + + /* Will only need one temporary register below. */ + jit_unget_reg(rg1); + + /* Jump over overflow code. */ + lt_code = jmpi_p(_jit->pc.w); + + /* Where to land if argument is in overflow area. */ + patch_at(ge_code, _jit->pc.w); + + /* Load stack pointer. */ + ldxi(rn(rg0), r1, offsetof(jit_va_list_t, stack)); + + /* Load argument. */ + ldr(r0, rn(rg0)); + + /* Update stack pointer. */ + addi(rn(rg0), rn(rg0), 8); + stxi(offsetof(jit_va_list_t, stack), r1, rn(rg0)); + + /* Where to land if argument is in gp save area. */ + patch_at(lt_code, _jit->pc.w); + + jit_unget_reg(rg0); +} + +static void +_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label) +{ + instr_t i; + jit_word_t d; + jit_int32_t fc, ff, ffc; + union { + jit_int32_t *i; + jit_word_t w; + } u; + u.w = instr; + i.w = u.i[0]; + fc = i.w & 0xfc000000; + ff = i.w & 0xff000000; + ffc = i.w & 0xffc00000; + if (fc == A64_B || fc == A64_BL) { + d = (label - instr) >> 2; + assert(d >= -33554432 && d <= 33554431); + i.imm26.b = d; + u.i[0] = i.w; + } + else if (ff == A64_B_C || ff == (A64_CBZ|XS) || ff == (A64_CBNZ|XS)) { + d = (label - instr) >> 2; + assert(d >= -262148 && d <= 262143); + i.imm19.b = d; + u.i[0] = i.w; + } + else if (ffc == (A64_MOVZ|XS)) { + i.imm16.b = label; + u.i[0] = i.w; + i.w = u.i[1]; + assert((i.w & 0xffe00000) == (A64_MOVK|XS|MOVI_LSL_16)); + i.imm16.b = label >> 16; + u.i[1] = i.w; + i.w = u.i[2]; + assert((i.w & 0xffe00000) == (A64_MOVK|XS|MOVI_LSL_32)); + i.imm16.b = label >> 32; + u.i[2] = i.w; + i.w = u.i[3]; + assert((i.w & 0xffe00000) == (A64_MOVK|XS|MOVI_LSL_48)); + i.imm16.b = label >> 48; + u.i[3] = i.w; + } + else + abort(); +} +#endif diff --git a/deps/lightning/lib/jit_aarch64-fpu.c b/deps/lightning/lib/jit_aarch64-fpu.c new file mode 100644 index 0000000..871ba7e --- /dev/null +++ b/deps/lightning/lib/jit_aarch64-fpu.c @@ -0,0 +1,914 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# define A64_SCVTF 0x1e220000 +# define A64_FMOVWV 0x1e260000 +# define A64_FMOVVW 0x1e270000 +# define A64_FMOVXV 0x9e260000 +# define A64_FMOVVX 0x9e270000 +# define A64_FCVTZS 0x1e380000 +# define A64_FCMPE 0x1e202010 +# define A64_FMOV 0x1e204000 +# define A64_FABS 0x1e20c000 +# define A64_FNEG 0x1e214000 +# define A64_FSQRT 0x1e21c000 +# define A64_FCVTS 0x1e224000 +# define A64_FCVTD 0x1e22c000 +# define A64_FMUL 0x1e200800 +# define A64_FDIV 0x1e201800 +# define A64_FADD 0x1e202800 +# define A64_FSUB 0x1e203800 +# define FCMPES(Rn,Rm) os_vv(A64_FCMPE,0,Rn,Rm) +# define FCMPED(Rn,Rm) os_vv(A64_FCMPE,1,Rn,Rm) +# define FMOVS(Rd,Rn) osvv_(A64_FMOV,0,Rd,Rn) +# define FMOVD(Rd,Rn) osvv_(A64_FMOV,1,Rd,Rn) +# define FMOVWS(Rd,Rn) osvv_(A64_FMOVWV,0,Rd,Rn) +# define FMOVSW(Rd,Rn) osvv_(A64_FMOVVW,0,Rd,Rn) +# define FMOVXD(Rd,Rn) osvv_(A64_FMOVXV,1,Rd,Rn) +# define FMOVDX(Rd,Rn) osvv_(A64_FMOVVX,1,Rd,Rn) +# define FCVT_SD(Rd,Rn) osvv_(A64_FCVTS,1,Rd,Rn) +# define FCVT_DS(Rd,Rn) osvv_(A64_FCVTD,0,Rd,Rn) +# define SCVTFS(Rd,Rn) osvv_(A64_SCVTF|XS,0,Rd,Rn) +# define SCVTFD(Rd,Rn) osvv_(A64_SCVTF|XS,1,Rd,Rn) +# define FCVTSZ_WS(Rd,Rn) osvv_(A64_FCVTZS,0,Rd,Rn) +# define FCVTSZ_WD(Rd,Rn) osvv_(A64_FCVTZS,1,Rd,Rn) +# define FCVTSZ_XS(Rd,Rn) osvv_(A64_FCVTZS|XS,0,Rd,Rn) +# define FCVTSZ_XD(Rd,Rn) osvv_(A64_FCVTZS|XS,1,Rd,Rn) +# define FABSS(Rd,Rn) osvv_(A64_FABS,0,Rd,Rn) +# define FABSD(Rd,Rn) osvv_(A64_FABS,1,Rd,Rn) +# define FNEGS(Rd,Rn) osvv_(A64_FNEG,0,Rd,Rn) +# define FNEGD(Rd,Rn) osvv_(A64_FNEG,1,Rd,Rn) +# define FSQRTS(Rd,Rn) osvv_(A64_FSQRT,0,Rd,Rn) +# define FSQRTD(Rd,Rn) osvv_(A64_FSQRT,1,Rd,Rn) +# define FADDS(Rd,Rn,Rm) osvvv(A64_FADD,0,Rd,Rn,Rm) +# define FADDD(Rd,Rn,Rm) osvvv(A64_FADD,1,Rd,Rn,Rm) +# define FSUBS(Rd,Rn,Rm) osvvv(A64_FSUB,0,Rd,Rn,Rm) +# define FSUBD(Rd,Rn,Rm) osvvv(A64_FSUB,1,Rd,Rn,Rm) +# define FMULS(Rd,Rn,Rm) osvvv(A64_FMUL,0,Rd,Rn,Rm) +# define FMULD(Rd,Rn,Rm) osvvv(A64_FMUL,1,Rd,Rn,Rm) +# define FDIVS(Rd,Rn,Rm) osvvv(A64_FDIV,0,Rd,Rn,Rm) +# define FDIVD(Rd,Rn,Rm) osvvv(A64_FDIV,1,Rd,Rn,Rm) +# define osvvv(Op,Sz,Rd,Rn,Rm) _osvvv(_jit,Op,Sz,Rd,Rn,Rm) +static void _osvvv(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define osvv_(Op,Sz,Rd,Rn) _osvv_(_jit,Op,Sz,Rd,Rn) +static void _osvv_(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define os_vv(Op,Sz,Rn,Rm) _os_vv(_jit,Op,Sz,Rn,Rm) +static void _os_vv(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define truncr_f_i(r0,r1) _truncr_f_i(_jit,r0,r1) +static void _truncr_f_i(jit_state_t*,jit_int32_t,jit_int32_t); +# define truncr_f_l(r0,r1) FCVTSZ_XS(r0,r1) +# define truncr_d_i(r0,r1) _truncr_d_i(_jit,r0,r1) +static void _truncr_d_i(jit_state_t*,jit_int32_t,jit_int32_t); +# define truncr_d_l(r0,r1) FCVTSZ_XD(r0,r1) +# define addr_f(r0,r1,r2) FADDS(r0,r1,r2) +# define addi_f(r0,r1,i0) _addi_f(_jit,r0,r1,i0) +static void _addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define subr_f(r0,r1,r2) FSUBS(r0,r1,r2) +# define subi_f(r0,r1,i0) _subi_f(_jit,r0,r1,i0) +static void _subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define rsbr_f(r0, r1, r2) subr_f(r0, r2, r1) +# define rsbi_f(r0, r1, i0) _rsbi_f(_jit, r0, r1, i0) +static void _rsbi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define mulr_f(r0,r1,r2) FMULS(r0,r1,r2) +# define muli_f(r0,r1,i0) _muli_f(_jit,r0,r1,i0) +static void _muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define divr_f(r0,r1,r2) FDIVS(r0,r1,r2) +# define divi_f(r0,r1,i0) _divi_f(_jit,r0,r1,i0) +static void _divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define absr_f(r0,r1) FABSS(r0,r1) +# define negr_f(r0,r1) FNEGS(r0,r1) +# define sqrtr_f(r0,r1) FSQRTS(r0,r1) +# define extr_f(r0,r1) SCVTFS(r0,r1) +# define ldr_f(r0,r1) _ldr_f(_jit,r0,r1) +static void _ldr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_f(r0,i0) _ldi_f(_jit,r0,i0) +static void _ldi_f(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_f(r0,r1,r2) _ldxr_f(_jit,r0,r1,r2) +static void _ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_f(r0,r1,i0) _ldxi_f(_jit,r0,r1,i0) +static void _ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_f(r0,r1) _str_f(_jit,r0,r1) +static void _str_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define sti_f(i0,r0) _sti_f(_jit,i0,r0) +static void _sti_f(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_f(r0,r1,r2) _stxr_f(_jit,r0,r1,r2) +static void _stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_f(i0,r0,r1) _stxi_f(_jit,i0,r0,r1) +static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define movr_f(r0,r1) _movr_f(_jit,r0,r1) +static void _movr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi_f(r0,i0) _movi_f(_jit,r0,i0) +static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t); +# define extr_d_f(r0,r1) FCVT_SD(r0,r1) +# define fccr(cc,r0,r1,r2) _fccr(_jit,cc,r0,r1,r2) +static void _fccr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define fcci(cc,r0,r1,i0) _fcci(_jit,cc,r0,r1,i0) +static void _fcci(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_float32_t); +# define ltr_f(r0,r1,r2) fccr(CC_MI,r0,r1,r2) +# define lti_f(r0,r1,i0) fcci(CC_MI,r0,r1,i0) +# define ler_f(r0,r1,r2) fccr(CC_LS,r0,r1,r2) +# define lei_f(r0,r1,i0) fcci(CC_LS,r0,r1,i0) +# define eqr_f(r0,r1,r2) fccr(CC_EQ,r0,r1,r2) +# define eqi_f(r0,r1,i0) fcci(CC_EQ,r0,r1,i0) +# define ger_f(r0,r1,r2) fccr(CC_GE,r0,r1,r2) +# define gei_f(r0,r1,i0) fcci(CC_GE,r0,r1,i0) +# define gtr_f(r0,r1,r2) fccr(CC_GT,r0,r1,r2) +# define gti_f(r0,r1,i0) fcci(CC_GT,r0,r1,i0) +# define ner_f(r0,r1,r2) fccr(CC_NE,r0,r1,r2) +# define nei_f(r0,r1,i0) fcci(CC_NE,r0,r1,i0) +# define unltr_f(r0,r1,r2) fccr(CC_LT,r0,r1,r2) +# define unlti_f(r0,r1,i0) fcci(CC_LT,r0,r1,i0) +# define unler_f(r0,r1,r2) fccr(CC_LE,r0,r1,r2) +# define unlei_f(r0,r1,i0) fcci(CC_LE,r0,r1,i0) +# define uneqr_f(r0,r1,r2) _uneqr_f(_jit,r0,r1,r2) +static void _uneqr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define uneqi_f(r0,r1,i0) _uneqi_f(_jit,r0,r1,i0) +static void _uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define unger_f(r0,r1,r2) fccr(CC_PL,r0,r1,r2) +# define ungei_f(r0,r1,i0) fcci(CC_PL,r0,r1,i0) +# define ungtr_f(r0,r1,r2) fccr(CC_HI,r0,r1,r2) +# define ungti_f(r0,r1,i0) fcci(CC_HI,r0,r1,i0) +# define ltgtr_f(r0,r1,r2) _ltgtr_f(_jit,r0,r1,r2) +static void _ltgtr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ltgti_f(r0,r1,i0) _ltgti_f(_jit,r0,r1,i0) +static void _ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define ordr_f(r0,r1,r2) fccr(CC_VC,r0,r1,r2) +# define ordi_f(r0,r1,i0) fcci(CC_VC,r0,r1,i0) +# define unordr_f(r0,r1,r2) fccr(CC_VS,r0,r1,r2) +# define unordi_f(r0,r1,i0) fcci(CC_VS,r0,r1,i0) +#define fbccr(cc,i0,r0,r1) _fbccr(_jit,cc,i0,r0,r1) +static jit_word_t +_fbccr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t); +#define fbcci(cc,i0,r0,i1) _fbcci(_jit,cc,i0,r0,i1) +static jit_word_t +_fbcci(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_float32_t); +# define bltr_f(i0,r0,r1) fbccr(BCC_MI,i0,r0,r1) +# define blti_f(i0,r0,i1) fbcci(BCC_MI,i0,r0,i1) +# define bler_f(i0,r0,r1) fbccr(BCC_LS,i0,r0,r1) +# define blei_f(i0,r0,i1) fbcci(BCC_LS,i0,r0,i1) +# define beqr_f(i0,r0,r1) fbccr(BCC_EQ,i0,r0,r1) +# define beqi_f(i0,r0,i1) fbcci(BCC_EQ,i0,r0,i1) +# define bger_f(i0,r0,r1) fbccr(BCC_GE,i0,r0,r1) +# define bgei_f(i0,r0,i1) fbcci(BCC_GE,i0,r0,i1) +# define bgtr_f(i0,r0,r1) fbccr(BCC_GT,i0,r0,r1) +# define bgti_f(i0,r0,i1) fbcci(BCC_GT,i0,r0,i1) +# define bner_f(i0,r0,r1) fbccr(BCC_NE,i0,r0,r1) +# define bnei_f(i0,r0,i1) fbcci(BCC_NE,i0,r0,i1) +# define bunltr_f(i0,r0,r1) fbccr(BCC_LT,i0,r0,r1) +# define bunlti_f(i0,r0,i1) fbcci(BCC_LT,i0,r0,i1) +# define bunler_f(i0,r0,r1) fbccr(BCC_LE,i0,r0,r1) +# define bunlei_f(i0,r0,i1) fbcci(BCC_LE,i0,r0,i1) +# define buneqr_f(i0,r0,r1) _buneqr_f(_jit,i0,r0,r1) +static jit_word_t _buneqr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define buneqi_f(i0,r0,i1) _buneqi_f(_jit,i0,r0,i1) +static jit_word_t _buneqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define bunger_f(i0,r0,r1) fbccr(BCC_PL,i0,r0,r1) +# define bungei_f(i0,r0,i1) fbcci(BCC_PL,i0,r0,i1) +# define bungtr_f(i0,r0,r1) fbccr(BCC_HI,i0,r0,r1) +# define bungti_f(i0,r0,i1) fbcci(BCC_HI,i0,r0,i1) +# define bltgtr_f(i0,r0,r1) _bltgtr_f(_jit,i0,r0,r1) +static jit_word_t _bltgtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bltgti_f(i0,r0,i1) _bltgti_f(_jit,i0,r0,i1) +static jit_word_t _bltgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define bordr_f(i0,r0,r1) fbccr(BCC_VC,i0,r0,r1) +# define bordi_f(i0,r0,i1) fbcci(BCC_VC,i0,r0,i1) +# define bunordr_f(i0,r0,r1) fbccr(BCC_VS,i0,r0,r1) +# define bunordi_f(i0,r0,i1) fbcci(BCC_VS,i0,r0,i1) +# define addr_d(r0,r1,r2) FADDD(r0,r1,r2) +# define addi_d(r0,r1,i0) _addi_d(_jit,r0,r1,i0) +static void _addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define subr_d(r0,r1,r2) FSUBD(r0,r1,r2) +# define subi_d(r0,r1,i0) _subi_d(_jit,r0,r1,i0) +static void _subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define rsbr_d(r0, r1, r2) subr_d(r0, r2, r1) +# define rsbi_d(r0, r1, i0) _rsbi_d(_jit, r0, r1, i0) +static void _rsbi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define mulr_d(r0,r1,r2) FMULD(r0,r1,r2) +# define muli_d(r0,r1,i0) _muli_d(_jit,r0,r1,i0) +static void _muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define divr_d(r0,r1,r2) FDIVD(r0,r1,r2) +# define divi_d(r0,r1,i0) _divi_d(_jit,r0,r1,i0) +static void _divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define absr_d(r0,r1) FABSD(r0,r1) +# define negr_d(r0,r1) FNEGD(r0,r1) +# define sqrtr_d(r0,r1) FSQRTD(r0,r1) +# define extr_d(r0,r1) SCVTFD(r0,r1) +# define ldr_d(r0,r1) _ldr_d(_jit,r0,r1) +static void _ldr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_d(r0,i0) _ldi_d(_jit,r0,i0) +static void _ldi_d(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_d(r0,r1,r2) _ldxr_d(_jit,r0,r1,r2) +static void _ldxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_d(r0,r1,i0) _ldxi_d(_jit,r0,r1,i0) +static void _ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_d(r0,r1) _str_d(_jit,r0,r1) +static void _str_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define sti_d(i0,r0) _sti_d(_jit,i0,r0) +static void _sti_d(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_d(r0,r1,r2) _stxr_d(_jit,r0,r1,r2) +static void _stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_d(i0,r0,r1) _stxi_d(_jit,i0,r0,r1) +static void _stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define movr_d(r0,r1) _movr_d(_jit,r0,r1) +static void _movr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi_d(r0,i0) _movi_d(_jit,r0,i0) +static void _movi_d(jit_state_t*,jit_int32_t,jit_float64_t); +# define extr_f_d(r0,r1) FCVT_DS(r0,r1) +# define dccr(cc,r0,r1,r2) _dccr(_jit,cc,r0,r1,r2) +static void _dccr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define dcci(cc,r0,r1,i0) _dcci(_jit,cc,r0,r1,i0) +static void _dcci(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_float64_t); +# define ltr_d(r0,r1,r2) dccr(CC_MI,r0,r1,r2) +# define lti_d(r0,r1,i0) dcci(CC_MI,r0,r1,i0) +# define ler_d(r0,r1,r2) dccr(CC_LS,r0,r1,r2) +# define lei_d(r0,r1,i0) dcci(CC_LS,r0,r1,i0) +# define eqr_d(r0,r1,r2) dccr(CC_EQ,r0,r1,r2) +# define eqi_d(r0,r1,i0) dcci(CC_EQ,r0,r1,i0) +# define ger_d(r0,r1,r2) dccr(CC_GE,r0,r1,r2) +# define gei_d(r0,r1,i0) dcci(CC_GE,r0,r1,i0) +# define gtr_d(r0,r1,r2) dccr(CC_GT,r0,r1,r2) +# define gti_d(r0,r1,i0) dcci(CC_GT,r0,r1,i0) +# define ner_d(r0,r1,r2) dccr(CC_NE,r0,r1,r2) +# define nei_d(r0,r1,i0) dcci(CC_NE,r0,r1,i0) +# define unltr_d(r0,r1,r2) dccr(CC_LT,r0,r1,r2) +# define unlti_d(r0,r1,i0) dcci(CC_LT,r0,r1,i0) +# define unler_d(r0,r1,r2) dccr(CC_LE,r0,r1,r2) +# define unlei_d(r0,r1,i0) dcci(CC_LE,r0,r1,i0) +# define uneqr_d(r0,r1,r2) _uneqr_d(_jit,r0,r1,r2) +static void _uneqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define uneqi_d(r0,r1,i0) _uneqi_d(_jit,r0,r1,i0) +static void _uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define unger_d(r0,r1,r2) dccr(CC_PL,r0,r1,r2) +# define ungei_d(r0,r1,i0) dcci(CC_PL,r0,r1,i0) +# define ungtr_d(r0,r1,r2) dccr(CC_HI,r0,r1,r2) +# define ungti_d(r0,r1,i0) dcci(CC_HI,r0,r1,i0) +# define ltgtr_d(r0,r1,r2) _ltgtr_d(_jit,r0,r1,r2) +static void _ltgtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ltgti_d(r0,r1,i0) _ltgti_d(_jit,r0,r1,i0) +static void _ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define ordr_d(r0,r1,r2) dccr(CC_VC,r0,r1,r2) +# define ordi_d(r0,r1,i0) dcci(CC_VC,r0,r1,i0) +# define unordr_d(r0,r1,r2) dccr(CC_VS,r0,r1,r2) +# define unordi_d(r0,r1,i0) dcci(CC_VS,r0,r1,i0) +#define dbccr(cc,i0,r0,r1) _dbccr(_jit,cc,i0,r0,r1) +static jit_word_t +_dbccr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t); +#define dbcci(cc,i0,r0,i1) _dbcci(_jit,cc,i0,r0,i1) +static jit_word_t +_dbcci(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_float64_t); +# define bltr_d(i0,r0,r1) dbccr(BCC_MI,i0,r0,r1) +# define blti_d(i0,r0,i1) dbcci(BCC_MI,i0,r0,i1) +# define bler_d(i0,r0,r1) dbccr(BCC_LS,i0,r0,r1) +# define blei_d(i0,r0,i1) dbcci(BCC_LS,i0,r0,i1) +# define beqr_d(i0,r0,r1) dbccr(BCC_EQ,i0,r0,r1) +# define beqi_d(i0,r0,i1) dbcci(BCC_EQ,i0,r0,i1) +# define bger_d(i0,r0,r1) dbccr(BCC_GE,i0,r0,r1) +# define bgei_d(i0,r0,i1) dbcci(BCC_GE,i0,r0,i1) +# define bgtr_d(i0,r0,r1) dbccr(BCC_GT,i0,r0,r1) +# define bgti_d(i0,r0,i1) dbcci(BCC_GT,i0,r0,i1) +# define bner_d(i0,r0,r1) dbccr(BCC_NE,i0,r0,r1) +# define bnei_d(i0,r0,i1) dbcci(BCC_NE,i0,r0,i1) +# define bunltr_d(i0,r0,r1) dbccr(BCC_LT,i0,r0,r1) +# define bunlti_d(i0,r0,i1) dbcci(BCC_LT,i0,r0,i1) +# define bunler_d(i0,r0,r1) dbccr(BCC_LE,i0,r0,r1) +# define bunlei_d(i0,r0,i1) dbcci(BCC_LE,i0,r0,i1) +# define buneqr_d(i0,r0,r1) _buneqr_d(_jit,i0,r0,r1) +static jit_word_t _buneqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define buneqi_d(i0,r0,i1) _buneqi_d(_jit,i0,r0,i1) +static jit_word_t _buneqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define bunger_d(i0,r0,r1) dbccr(BCC_PL,i0,r0,r1) +# define bungei_d(i0,r0,i1) dbcci(BCC_PL,i0,r0,i1) +# define bungtr_d(i0,r0,r1) dbccr(BCC_HI,i0,r0,r1) +# define bungti_d(i0,r0,i1) dbcci(BCC_HI,i0,r0,i1) +# define bltgtr_d(i0,r0,r1) _bltgtr_d(_jit,i0,r0,r1) +static jit_word_t _bltgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bltgti_d(i0,r0,i1) _bltgti_d(_jit,i0,r0,i1) +static jit_word_t _bltgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define bordr_d(i0,r0,r1) dbccr(BCC_VC,i0,r0,r1) +# define bordi_d(i0,r0,i1) dbcci(BCC_VC,i0,r0,i1) +# define bunordr_d(i0,r0,r1) dbccr(BCC_VS,i0,r0,r1) +# define bunordi_d(i0,r0,i1) dbcci(BCC_VS,i0,r0,i1) +# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1) +static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t); +#endif + +#if CODE +static void +_osvvv(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Sz, + jit_int32_t Rd, jit_int32_t Rn, jit_int32_t Rm) +{ + instr_t i; + assert(!(Rd & ~0x1f)); + assert(!(Rn & ~0x1f)); + assert(!(Rm & ~0x1f)); + assert(!(Sz & ~0x3)); + assert(!(Op & ~0xffe0fc00)); + i.w = Op; + i.size.b = Sz; + i.Rd.b = Rd; + i.Rn.b = Rn; + i.Rm.b = Rm; + ii(i.w); +} + +static void +_osvv_(jit_state_t *_jit, jit_int32_t Op, + jit_int32_t Sz, jit_int32_t Rd, jit_int32_t Rn) +{ + instr_t i; + assert(!(Rd & ~0x1f)); + assert(!(Rn & ~0x1f)); + assert(!(Sz & ~0x3)); + assert(!(Op & ~0xfffffc00)); + i.w = Op; + i.size.b = Sz; + i.Rd.b = Rd; + i.Rn.b = Rn; + ii(i.w); +} + +static void +_os_vv(jit_state_t *_jit, jit_int32_t Op, + jit_int32_t Sz, jit_int32_t Rn, jit_int32_t Rm) +{ + instr_t i; + assert(!(Rn & ~0x1f)); + assert(!(Rm & ~0x1f)); + assert(!(Sz & ~0x3)); + assert(!(Op & ~0xff20fc1f)); + i.w = Op; + i.size.b = Sz; + i.Rn.b = Rn; + i.Rm.b = Rm; + ii(i.w); +} + +#define fopi(name) \ +static void \ +_##name##i_f(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, jit_float32_t i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr); \ + movi_f(rn(reg), i0); \ + name##r_f(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +#define dopi(name) \ +static void \ +_##name##i_d(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, jit_float64_t i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr); \ + movi_d(rn(reg), i0); \ + name##r_d(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +#define fbopi(name) \ +static jit_word_t \ +_b##name##i_f(jit_state_t *_jit, \ + jit_word_t i0, jit_int32_t r0, jit_float32_t i1) \ +{ \ + jit_word_t word; \ + jit_int32_t reg = jit_get_reg(jit_class_fpr| \ + jit_class_nospill); \ + movi_f(rn(reg), i1); \ + word = b##name##r_f(i0, r0, rn(reg)); \ + jit_unget_reg(reg); \ + return (word); \ +} +#define dbopi(name) \ +static jit_word_t \ +_b##name##i_d(jit_state_t *_jit, \ + jit_word_t i0, jit_int32_t r0, jit_float64_t i1) \ +{ \ + jit_word_t word; \ + jit_int32_t reg = jit_get_reg(jit_class_fpr| \ + jit_class_nospill); \ + movi_d(rn(reg), i1); \ + word = b##name##r_d(i0, r0, rn(reg)); \ + jit_unget_reg(reg); \ + return (word); \ +} + +static void +_truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + FCVTSZ_WS(r0, r1); + extr_i(r0, r0); +} + +static void +_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + FCVTSZ_WD(r0, r1); + extr_i(r0, r0); +} + +fopi(add) +fopi(sub) +fopi(rsb) +fopi(mul) +fopi(div) + +static void +_ldr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + ldr_i(rn(reg), r1); + FMOVSW(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + ldi_i(rn(reg), i0); + FMOVSW(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + ldxr_i(rn(reg), r1, r2); + FMOVSW(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + ldxi_i(rn(reg), r1, i0); + FMOVSW(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_str_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + FMOVWS(rn(reg), r1); + str_i(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + FMOVWS(rn(reg), r0); + sti_i(i0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + FMOVWS(rn(reg), r2); + stxr_i(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + FMOVWS(rn(reg), r1); + stxi_i(i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_movr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + FMOVS(r0, r1); +} + +static void +_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } u; + jit_int32_t reg; + u.f = i0; + if (u.i == 0) + FMOVSW(r0, WZR_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + /* prevent generating unused top 32 bits */ + movi(rn(reg), ((jit_word_t)u.i) & 0xffffffff); + FMOVSW(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_fccr(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPES(r1, r2); + CSET(r0, cc); +} + +static void +_fcci(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_float32_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + movi_f(rn(reg), i0); + fccr(cc, r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_uneqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMPES(r1, r2); + CSET(r0, CC_VS); + w = _jit->pc.w; + B_C(BCC_VS, 1); /* unordered satisfies condition */ + CSET(r0, CC_EQ); /* equal satisfies condition */ + patch_at(w, _jit->pc.w); +} +fopi(uneq) + +static void +_ltgtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMPES(r1, r2); + CSET(r0, CC_VC); /* set to 1 if ordered */ + w = _jit->pc.w; + B_C(BCC_VS, 1); /* unordered does not satisfy condition */ + CSET(r0, CC_NE); /* set to 1 if not equal */ + patch_at(w, _jit->pc.w); +} +fopi(ltgt) + +static jit_word_t +_fbccr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, d; + FCMPES(r0, r1); + w = _jit->pc.w; + d = (i0 - w) >> 2; + B_C(cc, d); + return (w); +} + +static jit_word_t +_fbcci(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_float32_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi_f(rn(reg), i1); + w = fbccr(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_buneqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t u, v, w; + FCMPES(r0, r1); + u = _jit->pc.w; + B_C(BCC_VS, 1); /* unordered satisfies condition */ + v = _jit->pc.w; + B_C(BCC_NE, 1); /* not equal (or unordered) does not satisfy */ + patch_at(u, _jit->pc.w); + w = _jit->pc.w; + B((i0 - w) >> 2); + patch_at(v, _jit->pc.w); + return (w); +} +fbopi(uneq) + +static jit_word_t +_bltgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t u, v, w; + FCMPES(r0, r1); + u = _jit->pc.w; + B_C(BCC_VS, 2); /* jump over if unordered */ + v = _jit->pc.w; + B_C(BCC_EQ, 1); /* jump over if equal */ + w = _jit->pc.w; + B((i0 - w) >> 2); + patch_at(u, _jit->pc.w); + patch_at(v, _jit->pc.w); + return (w); +} +fbopi(ltgt) + +dopi(add) +dopi(sub) +dopi(rsb) +dopi(mul) +dopi(div) + +static void +_ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + ldr_l(rn(reg), r1); + FMOVDX(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + ldi_l(rn(reg), i0); + FMOVDX(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + ldxr_l(rn(reg), r1, r2); + FMOVDX(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + ldxi_l(rn(reg), r1, i0); + FMOVDX(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_str_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + FMOVXD(rn(reg), r1); + str_l(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + FMOVXD(rn(reg), r0); + sti_l(i0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + FMOVXD(rn(reg), r2); + stxr_l(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + FMOVXD(rn(reg), r1); + stxi_l(i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + FMOVD(r0, r1); +} + +static void +_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0) +{ + union { + jit_int64_t l; + jit_float64_t d; + } u; + jit_int32_t reg; + u.d = i0; + if (u.l == 0) + FMOVDX(r0, XZR_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), u.l); + FMOVDX(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_dccr(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPED(r1, r2); + CSET(r0, cc); +} + +static void +_dcci(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_float64_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + movi_d(rn(reg), i0); + dccr(cc, r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMPED(r1, r2); + CSET(r0, CC_VS); + w = _jit->pc.w; + B_C(BCC_VS, 1); /* unordered satisfies condition */ + CSET(r0, CC_EQ); /* equal satisfies condition */ + patch_at(w, _jit->pc.w); +} +dopi(uneq) + +static void +_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMPED(r1, r2); + CSET(r0, CC_VC); /* set to 1 if ordered */ + w = _jit->pc.w; + B_C(BCC_VS, 1); /* unordered does not satisfy condition */ + CSET(r0, CC_NE); /* set to 1 if not equal */ + patch_at(w, _jit->pc.w); +} +dopi(ltgt) + +static jit_word_t +_dbccr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, d; + FCMPED(r0, r1); + w = _jit->pc.w; + d = (i0 - w) >> 2; + B_C(cc, d); + return (w); +} + +static jit_word_t +_dbcci(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_float64_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi_d(rn(reg), i1); + w = dbccr(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_buneqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t u, v, w; + FCMPED(r0, r1); + u = _jit->pc.w; + B_C(BCC_VS, 1); /* unordered satisfies condition */ + v = _jit->pc.w; + B_C(BCC_NE, 1); /* not equal (or unordered) does not satisfy */ + patch_at(u, _jit->pc.w); + w = _jit->pc.w; + B((i0 - w) >> 2); + patch_at(v, _jit->pc.w); + return (w); +} +dbopi(uneq) + +static jit_word_t +_bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t u, v, w; + FCMPED(r0, r1); + u = _jit->pc.w; + B_C(BCC_VS, 2); /* jump over if unordered */ + v = _jit->pc.w; + B_C(BCC_EQ, 1); /* jump over if equal */ + w = _jit->pc.w; + B((i0 - w) >> 2); + patch_at(u, _jit->pc.w); + patch_at(v, _jit->pc.w); + return (w); +} +dbopi(ltgt) + +static void +_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t ge_code; + jit_word_t lt_code; + jit_int32_t rg0, rg1; + + assert(_jitc->function->self.call & jit_call_varargs); + + rg0 = jit_get_reg(jit_class_gpr); + rg1 = jit_get_reg(jit_class_gpr); + + /* Load the fp offset in save area in the first temporary. */ + ldxi_i(rn(rg0), r1, offsetof(jit_va_list_t, fpoff)); + + /* Jump over if there are no remaining arguments in the save area. */ + ge_code = bgei(_jit->pc.w, rn(rg0), 0); + + /* Load the gp save pointer in the second temporary. */ + ldxi(rn(rg1), r1, offsetof(jit_va_list_t, fptop)); + + /* Load the vararg argument in the first argument. */ + ldxr_d(r0, rn(rg1), rn(rg0)); + + /* Update the fp offset. */ + addi(rn(rg0), rn(rg0), 16); + stxi_i(offsetof(jit_va_list_t, fpoff), r1, rn(rg0)); + + /* Will only need one temporary register below. */ + jit_unget_reg(rg1); + + /* Jump over overflow code. */ + lt_code = jmpi_p(_jit->pc.w); + + /* Where to land if argument is in overflow area. */ + patch_at(ge_code, _jit->pc.w); + + /* Load stack pointer. */ + ldxi(rn(rg0), r1, offsetof(jit_va_list_t, stack)); + + /* Load argument. */ + ldr_d(r0, rn(rg0)); + + /* Update stack pointer. */ + addi(rn(rg0), rn(rg0), 8); + stxi(offsetof(jit_va_list_t, stack), r1, rn(rg0)); + + /* Where to land if argument is in gp save area. */ + patch_at(lt_code, _jit->pc.w); + + jit_unget_reg(rg0); +} +#endif diff --git a/deps/lightning/lib/jit_aarch64-sz.c b/deps/lightning/lib/jit_aarch64-sz.c new file mode 100644 index 0000000..7e22e0e --- /dev/null +++ b/deps/lightning/lib/jit_aarch64-sz.c @@ -0,0 +1,402 @@ + +#if __WORDSIZE == 64 +#define JIT_INSTR_MAX 120 + 0, /* data */ + 0, /* live */ + 4, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 120, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 44, /* va_start */ + 64, /* va_arg */ + 72, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 20, /* addi */ + 4, /* addcr */ + 12, /* addci */ + 4, /* addxr */ + 8, /* addxi */ + 4, /* subr */ + 20, /* subi */ + 4, /* subcr */ + 12, /* subci */ + 4, /* subxr */ + 8, /* subxi */ + 24, /* rsbi */ + 4, /* mulr */ + 20, /* muli */ + 12, /* qmulr */ + 20, /* qmuli */ + 12, /* qmulr_u */ + 20, /* qmuli_u */ + 4, /* divr */ + 20, /* divi */ + 4, /* divr_u */ + 12, /* divi_u */ + 20, /* qdivr */ + 16, /* qdivi */ + 20, /* qdivr_u */ + 16, /* qdivi_u */ + 12, /* remr */ + 28, /* remi */ + 12, /* remr_u */ + 20, /* remi_u */ + 4, /* andr */ + 20, /* andi */ + 4, /* orr */ + 20, /* ori */ + 4, /* xorr */ + 20, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 8, /* ltr */ + 8, /* lti */ + 8, /* ltr_u */ + 8, /* lti_u */ + 8, /* ler */ + 8, /* lei */ + 8, /* ler_u */ + 8, /* lei_u */ + 8, /* eqr */ + 8, /* eqi */ + 8, /* ger */ + 8, /* gei */ + 8, /* ger_u */ + 8, /* gei_u */ + 8, /* gtr */ + 8, /* gti */ + 8, /* gtr_u */ + 8, /* gti_u */ + 8, /* ner */ + 8, /* nei */ + 4, /* movr */ + 16, /* movi */ + 4, /* extr_c */ + 4, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 4, /* extr_i */ + 4, /* extr_ui */ + 8, /* htonr_us */ + 8, /* htonr_ui */ + 4, /* htonr_ul */ + 4, /* ldr_c */ + 12, /* ldi_c */ + 4, /* ldr_uc */ + 12, /* ldi_uc */ + 4, /* ldr_s */ + 12, /* ldi_s */ + 4, /* ldr_us */ + 12, /* ldi_us */ + 4, /* ldr_i */ + 12, /* ldi_i */ + 4, /* ldr_ui */ + 12, /* ldi_ui */ + 4, /* ldr_l */ + 12, /* ldi_l */ + 8, /* ldxr_c */ + 20, /* ldxi_c */ + 4, /* ldxr_uc */ + 20, /* ldxi_uc */ + 4, /* ldxr_s */ + 16, /* ldxi_s */ + 4, /* ldxr_us */ + 16, /* ldxi_us */ + 4, /* ldxr_i */ + 20, /* ldxi_i */ + 4, /* ldxr_ui */ + 16, /* ldxi_ui */ + 4, /* ldxr_l */ + 20, /* ldxi_l */ + 4, /* str_c */ + 12, /* sti_c */ + 4, /* str_s */ + 12, /* sti_s */ + 4, /* str_i */ + 12, /* sti_i */ + 4, /* str_l */ + 12, /* sti_l */ + 4, /* stxr_c */ + 20, /* stxi_c */ + 4, /* stxr_s */ + 20, /* stxi_s */ + 4, /* stxr_i */ + 20, /* stxi_i */ + 4, /* stxr_l */ + 20, /* stxi_l */ + 8, /* bltr */ + 8, /* blti */ + 8, /* bltr_u */ + 8, /* blti_u */ + 8, /* bler */ + 8, /* blei */ + 8, /* bler_u */ + 8, /* blei_u */ + 8, /* beqr */ + 24, /* beqi */ + 8, /* bger */ + 8, /* bgei */ + 8, /* bger_u */ + 8, /* bgei_u */ + 8, /* bgtr */ + 8, /* bgti */ + 8, /* bgtr_u */ + 8, /* bgti_u */ + 8, /* bner */ + 24, /* bnei */ + 8, /* bmsr */ + 8, /* bmsi */ + 8, /* bmcr */ + 8, /* bmci */ + 8, /* boaddr */ + 8, /* boaddi */ + 8, /* boaddr_u */ + 8, /* boaddi_u */ + 8, /* bxaddr */ + 8, /* bxaddi */ + 8, /* bxaddr_u */ + 8, /* bxaddi_u */ + 8, /* bosubr */ + 8, /* bosubi */ + 8, /* bosubr_u */ + 8, /* bosubi_u */ + 8, /* bxsubr */ + 8, /* bxsubi */ + 8, /* bxsubr_u */ + 8, /* bxsubi_u */ + 4, /* jmpr */ + 20, /* jmpi */ + 4, /* callr */ + 20, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 96, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 12, /* addi_f */ + 4, /* subr_f */ + 12, /* subi_f */ + 12, /* rsbi_f */ + 4, /* mulr_f */ + 12, /* muli_f */ + 4, /* divr_f */ + 12, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 8, /* ltr_f */ + 16, /* lti_f */ + 8, /* ler_f */ + 16, /* lei_f */ + 8, /* eqr_f */ + 16, /* eqi_f */ + 8, /* ger_f */ + 16, /* gei_f */ + 8, /* gtr_f */ + 16, /* gti_f */ + 8, /* ner_f */ + 16, /* nei_f */ + 8, /* unltr_f */ + 16, /* unlti_f */ + 8, /* unler_f */ + 16, /* unlei_f */ + 16, /* uneqr_f */ + 24, /* uneqi_f */ + 8, /* unger_f */ + 16, /* ungei_f */ + 8, /* ungtr_f */ + 16, /* ungti_f */ + 16, /* ltgtr_f */ + 24, /* ltgti_f */ + 8, /* ordr_f */ + 16, /* ordi_f */ + 8, /* unordr_f */ + 16, /* unordi_f */ + 8, /* truncr_f_i */ + 4, /* truncr_f_l */ + 4, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 8, /* movi_f */ + 8, /* ldr_f */ + 16, /* ldi_f */ + 8, /* ldxr_f */ + 24, /* ldxi_f */ + 8, /* str_f */ + 16, /* sti_f */ + 8, /* stxr_f */ + 24, /* stxi_f */ + 8, /* bltr_f */ + 16, /* blti_f */ + 8, /* bler_f */ + 16, /* blei_f */ + 8, /* beqr_f */ + 16, /* beqi_f */ + 8, /* bger_f */ + 16, /* bgei_f */ + 8, /* bgtr_f */ + 16, /* bgti_f */ + 8, /* bner_f */ + 16, /* bnei_f */ + 8, /* bunltr_f */ + 16, /* bunlti_f */ + 8, /* bunler_f */ + 16, /* bunlei_f */ + 16, /* buneqr_f */ + 24, /* buneqi_f */ + 8, /* bunger_f */ + 16, /* bungei_f */ + 8, /* bungtr_f */ + 16, /* bungti_f */ + 16, /* bltgtr_f */ + 24, /* bltgti_f */ + 8, /* bordr_f */ + 16, /* bordi_f */ + 8, /* bunordr_f */ + 16, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 12, /* addi_d */ + 4, /* subr_d */ + 12, /* subi_d */ + 12, /* rsbi_d */ + 4, /* mulr_d */ + 12, /* muli_d */ + 4, /* divr_d */ + 12, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 8, /* ltr_d */ + 16, /* lti_d */ + 8, /* ler_d */ + 16, /* lei_d */ + 8, /* eqr_d */ + 16, /* eqi_d */ + 8, /* ger_d */ + 16, /* gei_d */ + 8, /* gtr_d */ + 16, /* gti_d */ + 8, /* ner_d */ + 16, /* nei_d */ + 8, /* unltr_d */ + 16, /* unlti_d */ + 8, /* unler_d */ + 16, /* unlei_d */ + 16, /* uneqr_d */ + 24, /* uneqi_d */ + 8, /* unger_d */ + 16, /* ungei_d */ + 8, /* ungtr_d */ + 16, /* ungti_d */ + 16, /* ltgtr_d */ + 24, /* ltgti_d */ + 8, /* ordr_d */ + 16, /* ordi_d */ + 8, /* unordr_d */ + 16, /* unordi_d */ + 8, /* truncr_d_i */ + 4, /* truncr_d_l */ + 4, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 12, /* movi_d */ + 8, /* ldr_d */ + 16, /* ldi_d */ + 8, /* ldxr_d */ + 24, /* ldxi_d */ + 8, /* str_d */ + 16, /* sti_d */ + 8, /* stxr_d */ + 24, /* stxi_d */ + 8, /* bltr_d */ + 16, /* blti_d */ + 8, /* bler_d */ + 16, /* blei_d */ + 8, /* beqr_d */ + 20, /* beqi_d */ + 8, /* bger_d */ + 16, /* bgei_d */ + 8, /* bgtr_d */ + 16, /* bgti_d */ + 8, /* bner_d */ + 16, /* bnei_d */ + 8, /* bunltr_d */ + 16, /* bunlti_d */ + 8, /* bunler_d */ + 16, /* bunlei_d */ + 16, /* buneqr_d */ + 24, /* buneqi_d */ + 8, /* bunger_d */ + 16, /* bungei_d */ + 8, /* bungtr_d */ + 16, /* bungti_d */ + 16, /* bltgtr_d */ + 24, /* bltgti_d */ + 8, /* bordr_d */ + 16, /* bordi_d */ + 8, /* bunordr_d */ + 16, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __WORDSIZE */ diff --git a/deps/lightning/lib/jit_aarch64.c b/deps/lightning/lib/jit_aarch64.c new file mode 100644 index 0000000..5b2ff49 --- /dev/null +++ b/deps/lightning/lib/jit_aarch64.c @@ -0,0 +1,1582 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 8) +#define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 8) + +typedef struct jit_qreg { + jit_float64_t l; + jit_float64_t h; +} jit_qreg_t; + +#define va_gp_top_offset offsetof(jit_va_list_t, q0) +#define va_fp_top_offset sizeof(jit_va_list_t) +typedef struct jit_va_list { + jit_pointer_t stack; + jit_pointer_t gptop; + jit_pointer_t fptop; + jit_int32_t gpoff; + jit_int32_t fpoff; + + jit_int64_t x0; + jit_int64_t x1; + jit_int64_t x2; + jit_int64_t x3; + jit_int64_t x4; + jit_int64_t x5; + jit_int64_t x6; + jit_int64_t x7; + + jit_qreg_t q0; + jit_qreg_t q1; + jit_qreg_t q2; + jit_qreg_t q3; + jit_qreg_t q4; + jit_qreg_t q5; + jit_qreg_t q6; + jit_qreg_t q7; +} jit_va_list_t; + +/* + * Prototypes + */ +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); + +/* libgcc */ +extern void __clear_cache(void *, void *); + +#define PROTO 1 +# include "jit_aarch64-cpu.c" +# include "jit_aarch64-fpu.c" +#undef PROTO + +/* + * Initialization + */ +jit_register_t _rvs[] = { + { rc(gpr) | 0x08, "x8" }, + { rc(gpr) | 0x12, "x18" }, + { rc(gpr) | 0x11, "x17" }, + { rc(gpr) | 0x10, "x16" }, + { rc(gpr) | 0x09, "x9" }, + { rc(gpr) | 0x0a, "x10" }, + { rc(gpr) | 0x0b, "x11" }, + { rc(gpr) | 0x0c, "x12" }, + { rc(gpr) | 0x0d, "x13" }, + { rc(gpr) | 0x0e, "x14" }, + { rc(gpr) | 0x0f, "x15" }, + { rc(sav) | rc(gpr) | 0x13, "x19" }, + { rc(sav) | rc(gpr) | 0x14, "x20" }, + { rc(sav) | rc(gpr) | 0x15, "x21" }, + { rc(sav) | rc(gpr) | 0x16, "x22" }, + { rc(sav) | rc(gpr) | 0x17, "x23" }, + { rc(sav) | rc(gpr) | 0x18, "x24" }, + { rc(sav) | rc(gpr) | 0x19, "x25" }, + { rc(sav) | rc(gpr) | 0x1a, "x26" }, + { rc(sav) | rc(gpr) | 0x1b, "x27" }, + { rc(sav) | rc(gpr) | 0x1c, "x28" }, + { 0x1f, "sp" }, + { 0x1e, "lr" }, + { 0x1d, "fp" }, + { rc(arg) | rc(gpr) | 0x07, "x7" }, + { rc(arg) | rc(gpr) | 0x06, "x6" }, + { rc(arg) | rc(gpr) | 0x05, "x5" }, + { rc(arg) | rc(gpr) | 0x04, "x4" }, + { rc(arg) | rc(gpr) | 0x03, "x3" }, + { rc(arg) | rc(gpr) | 0x02, "x2" }, + { rc(arg) | rc(gpr) | 0x01, "x1" }, + { rc(arg) | rc(gpr) | 0x00, "x0" }, + { rc(fpr) | 0x1f, "v31" }, + { rc(fpr) | 0x1e, "v30" }, + { rc(fpr) | 0x1d, "v29" }, + { rc(fpr) | 0x1c, "v28" }, + { rc(fpr) | 0x1b, "v27" }, + { rc(fpr) | 0x1a, "v26" }, + { rc(fpr) | 0x19, "v25" }, + { rc(fpr) | 0x18, "v24" }, + { rc(fpr) | 0x17, "v23" }, + { rc(fpr) | 0x16, "v22" }, + { rc(fpr) | 0x15, "v21" }, + { rc(fpr) | 0x14, "v20" }, + { rc(fpr) | 0x13, "v19" }, + { rc(fpr) | 0x12, "v18" }, + { rc(fpr) | 0x11, "v17" }, + { rc(fpr) | 0x10, "v16" }, + { rc(sav) | rc(fpr) | 0x08, "v8" }, + { rc(sav) | rc(fpr) | 0x09, "v9" }, + { rc(sav) | rc(fpr) | 0x0a, "v10" }, + { rc(sav) | rc(fpr) | 0x0b, "v11" }, + { rc(sav) | rc(fpr) | 0x0c, "v12" }, + { rc(sav) | rc(fpr) | 0x0d, "v13" }, + { rc(sav) | rc(fpr) | 0x0e, "v14" }, + { rc(sav) | rc(fpr) | 0x0f, "v15" }, + { rc(arg) | rc(fpr) | 0x07, "v7" }, + { rc(arg) | rc(fpr) | 0x06, "v6" }, + { rc(arg) | rc(fpr) | 0x05, "v5" }, + { rc(arg) | rc(fpr) | 0x04, "v4" }, + { rc(arg) | rc(fpr) | 0x03, "v3" }, + { rc(arg) | rc(fpr) | 0x02, "v2" }, + { rc(arg) | rc(fpr) | 0x01, "v1" }, + { rc(arg) | rc(fpr) | 0x00, "v0" }, + { _NOREG, "<none>" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ +} + +void +_jit_init(jit_state_t *_jit) +{ + _jitc->reglen = jit_size(_rvs) - 1; +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + _jitc->function->self.size = stack_framesize; + _jitc->function->self.argi = _jitc->function->self.argf = + _jitc->function->self.alen = 0; + _jitc->function->self.aoff = 0; + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + assert(_jitc->function); + switch (length) { + case 0: case 1: break; + case 2: _jitc->function->self.aoff &= -2; break; + case 3: case 4: _jitc->function->self.aoff &= -4; break; + default: _jitc->function->self.aoff &= -8; break; + } + _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } + return (_jitc->function->self.aoff); +} + +void +_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) +{ + jit_int32_t r0, r1; + assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); + if (!_jitc->function->allocar) { + _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); + _jitc->function->allocar = 1; + } + r0 = jit_get_reg(jit_class_gpr); + jit_negr(r0, v); + jit_andi(r0, r0, -16); + jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); + jit_addr(u, u, r0); + /* Cannot "addr sp, sp, reg" because in this context "sp" is "[w|x]zr", + * the zero register */ +#if 0 + jit_addr(JIT_SP, JIT_SP, r0); +#else + r1 = jit_get_reg(jit_class_gpr); + /* note that "mov r1, sp" does not work, but the proper encoding + * can be triggered before actually emiting with "add r1, sp, 0" */ + jit_addi(r1, JIT_SP, 0); + jit_addr(r1, r1, r0); + jit_addi(JIT_SP, r1, 0); + jit_unget_reg(r1); +#endif + jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); + jit_unget_reg(r0); + jit_dec_synth(); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + assert(_jitc->function); + jit_inc_synth(ret); + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr, u); + if (JIT_RET != u) + jit_movr(JIT_RET, u); + jit_live(JIT_RET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti(jit_state_t *_jit, jit_word_t u) +{ + jit_inc_synth_w(reti, u); + jit_movi(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_f, u); + if (u != JIT_FRET) + jit_movr_f(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_inc_synth_f(reti_f, u); + jit_movi_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_d, u); + if (u != JIT_FRET) + jit_movr_d(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_inc_synth_d(reti_d, u); + jit_movi_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_epilog(jit_state_t *_jit) +{ + assert(_jitc->function); + assert(_jitc->function->epilog->next == NULL); + jit_link(_jitc->function->epilog); + _jitc->function = NULL; +} + +jit_bool_t +_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) +{ + if (u->code == jit_code_arg) + return (jit_arg_reg_p(u->u.w)); + assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d); + return (jit_arg_f_reg_p(u->u.w)); +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + jit_inc_synth(ellipsis); + if (_jitc->prepare) { + jit_link_prepare(); + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; + } + else { + jit_link_prolog(); + assert(!(_jitc->function->self.call & jit_call_varargs)); + _jitc->function->self.call |= jit_call_varargs; + + /* Allocate va_list like object in the stack, + * with enough space to save all argument + * registers, and use fixed offsets for them. */ + _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t)); + + /* Initialize gp offset in save area. */ + if (jit_arg_reg_p(_jitc->function->self.argi)) + _jitc->function->vagp = (8 - _jitc->function->self.argi) * -8; + else + _jitc->function->vagp = 0; + + /* Initialize fp offset in save area. */ + if (jit_arg_f_reg_p(_jitc->function->self.argf)) + _jitc->function->vafp = (8 - _jitc->function->self.argf) * -16; + else + _jitc->function->vafp = 0; + } + jit_dec_synth(); +} + +void +_jit_va_push(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(va_push, u); + jit_pushargr(u); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + assert(!(_jitc->function->self.call & jit_call_varargs)); + if (jit_arg_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + assert(!(_jitc->function->self.call & jit_call_varargs)); + if (jit_arg_f_reg_p(_jitc->function->self.argf)) + offset = _jitc->function->self.argf++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + assert(!(_jitc->function->self.call & jit_call_varargs)); + if (jit_arg_f_reg_p(_jitc->function->self.argf)) + offset = _jitc->function->self.argf++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +void +_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_c(u, JIT_RA0 - v->u.w); + else + jit_ldxi_c(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_uc(u, JIT_RA0 - v->u.w); + else + jit_ldxi_uc(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_s(u, JIT_RA0 - v->u.w); + else + jit_ldxi_s(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_us(u, JIT_RA0 - v->u.w); + else + jit_ldxi_us(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_i(u, JIT_RA0 - v->u.w); + else + jit_ldxi_i(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_ui(u, JIT_RA0 - v->u.w); + else + jit_ldxi_ui(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(u, JIT_RA0 - v->u.w); + else + jit_ldxi_l(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(JIT_RA0 - v->u.w, u); + else + jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movi(JIT_RA0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr_f(u, JIT_FA0 - v->u.w); + else + jit_ldxi_f(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_f(JIT_FA0 - v->u.w, u); + else + jit_stxi_f(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movi_f(JIT_FA0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(u, JIT_FA0 - v->u.w); + else + jit_ldxi_d(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr_d(JIT_FA0 - v->u.w, u); + else + jit_stxi_d(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movi_d(JIT_FA0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi(jit_state_t *_jit, jit_word_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else { + jit_stxi_f(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_movi_f(JIT_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else { + jit_stxi_d(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + jit_int32_t spec; + spec = jit_class(_rvs[regno].spec); + if (spec & jit_class_arg) { + regno = JIT_RA0 - regno; + if (regno >= 0 && regno < node->v.w) + return (1); + if (spec & jit_class_fpr) { + regno = JIT_FA0 - regno; + if (regno >= 0 && regno < node->w.w) + return (1); + } + } + + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishr, r0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_callr(r0); + node->v.w = _jitc->function->self.argi; + node->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_calli(i0); + node->v.w = _jitc->function->call.argi; + node->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); + return (node); +} + +void +_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_c, r0); + jit_extr_c(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_uc, r0); + jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_s, r0); + jit_extr_s(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_us, r0); + jit_extr_us(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_i, r0); + jit_extr_i(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_ui, r0); + jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_l, r0); + if (r0 != JIT_RET) + jit_movr(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_f, r0); + if (r0 != JIT_FRET) + jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_d, r0); + if (r0 != JIT_FRET) + jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_word_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_uint8_t *data; + jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + jit_int32_t const_offset; + jit_int32_t patch_offset; + } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + + _jitc->function = NULL; + + jit_reglive_setup(); + + undo.word = 0; + undo.node = NULL; + undo.const_offset = undo.patch_offset = 0; +# define assert_data(node) /**/ +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_rrf(name) \ + case jit_code_##name##i_f: \ + assert_data(node); \ + name##i_f(rn(node->u.w), rn(node->v.w), node->w.f); \ + break +#define case_rrd(name) \ + case jit_code_##name##i_d: \ + assert_data(node); \ + name##i_d(rn(node->u.w), rn(node->v.w), node->w.d); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type(_jit->pc.w, \ + rn(node->v.w), rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break; +#define case_brf(name) \ + case jit_code_##name##i_f: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i_f(temp->u.w, rn(node->v.w), node->w.f); \ + else { \ + word = name##i_f(_jit->pc.w, rn(node->v.w), \ + node->w.f); \ + patch(word, node); \ + } \ + break +#define case_brd(name) \ + case jit_code_##name##i_d: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i_d(temp->u.w, rn(node->v.w), node->w.d); \ + else { \ + word = name##i_d(_jit->pc.w, rn(node->v.w), \ + node->w.d); \ + patch(word, node); \ + } \ + break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end) + return (NULL); + +#if DEVEL_DISASSEMBLER + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; +#endif + value = jit_classify(node->code); + jit_regarg_set(node, value); + switch (node->code) { + case jit_code_align: + assert(!(node->u.w & (node->u.w - 1)) && + node->u.w <= sizeof(jit_word_t)); + if (node->u.w == sizeof(jit_word_t) && + (word = _jit->pc.w & (sizeof(jit_word_t) - 1))) + nop(sizeof(jit_word_t) - word); + break; + case jit_code_note: case jit_code_name: + node->u.w = _jit->pc.w; + break; + case jit_code_label: + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + break; + case_rrr(add,); + case_rrw(add,); + case_rrr(addc,); + case_rrw(addc,); + case_rrr(addx,); + case_rrw(addx,); + case_rrr(sub,); + case_rrw(sub,); + case_rrr(subc,); + case_rrw(subc,); + case_rrr(subx,); + case_rrw(subx,); + case_rrw(rsb,); + case_rrr(mul,); + case_rrw(mul,); + case_rrrr(qmul,); + case_rrrw(qmul,); + case_rrrr(qmul, _u); + case_rrrw(qmul, _u); + case_rrr(div,); + case_rrw(div,); + case_rrr(div, _u); + case_rrw(div, _u); + case_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rr(neg,); + case_rr(com,); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_rr(trunc, _f_i); + case_rr(trunc, _d_i); + case_rr(trunc, _f_l); + case_rr(trunc, _d_l); + case_rr(ld, _c); + case_rw(ld, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rr(ld, _i); + case_rw(ld, _i); + case_rr(ld, _ui); + case_rw(ld, _ui); + case_rr(ld, _l); + case_rw(ld, _l); + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rrr(ldx, _i); + case_rrw(ldx, _i); + case_rrr(ldx, _ui); + case_rrw(ldx, _ui); + case_rrr(ldx, _l); + case_rrw(ldx, _l); + case_rr(st, _c); + case_wr(st, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rr(st, _i); + case_wr(st, _i); + case_rr(st, _l); + case_wr(st, _l); + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rrr(stx, _i); + case_wrr(stx, _i); + case_rrr(stx, _l); + case_wrr(stx, _l); + case_rr(hton, _us); + case_rr(hton, _ui); + case_rr(hton, _ul); + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); + case_rr(ext, _i); + case_rr(ext, _ui); + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), temp->u.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_rrr(add, _f); + case_rrf(add); + case_rrr(sub, _f); + case_rrf(sub); + case_rrf(rsb); + case_rrr(mul, _f); + case_rrf(mul); + case_rrr(div, _f); + case_rrf(div); + case_rr(abs, _f); + case_rr(neg, _f); + case_rr(sqrt, _f); + case_rr(ext, _f); + case_rr(ld, _f); + case_rw(ld, _f); + case_rrr(ldx, _f); + case_rrw(ldx, _f); + case_rr(st, _f); + case_wr(st, _f); + case_rrr(stx, _f); + case_wrr(stx, _f); + case_rr(mov, _f); + case jit_code_movi_f: + assert_data(node); + movi_f(rn(node->u.w), node->v.f); + break; + case_rr(ext, _d_f); + case_rrr(lt, _f); + case_rrf(lt); + case_rrr(le, _f); + case_rrf(le); + case_rrr(eq, _f); + case_rrf(eq); + case_rrr(ge, _f); + case_rrf(ge); + case_rrr(gt, _f); + case_rrf(gt); + case_rrr(ne, _f); + case_rrf(ne); + case_rrr(unlt, _f); + case_rrf(unlt); + case_rrr(unle, _f); + case_rrf(unle); + case_rrr(uneq, _f); + case_rrf(uneq); + case_rrr(unge, _f); + case_rrf(unge); + case_rrr(ungt, _f); + case_rrf(ungt); + case_rrr(ltgt, _f); + case_rrf(ltgt); + case_rrr(ord, _f); + case_rrf(ord); + case_rrr(unord, _f); + case_rrf(unord); + case_brr(blt, _f); + case_brf(blt); + case_brr(ble, _f); + case_brf(ble); + case_brr(beq, _f); + case_brf(beq); + case_brr(bge, _f); + case_brf(bge); + case_brr(bgt, _f); + case_brf(bgt); + case_brr(bne, _f); + case_brf(bne); + case_brr(bunlt, _f); + case_brf(bunlt); + case_brr(bunle, _f); + case_brf(bunle); + case_brr(buneq, _f); + case_brf(buneq); + case_brr(bunge, _f); + case_brf(bunge); + case_brr(bungt, _f); + case_brf(bungt); + case_brr(bltgt, _f); + case_brf(bltgt); + case_brr(bord, _f); + case_brf(bord); + case_brr(bunord, _f); + case_brf(bunord); + case_rrr(add, _d); + case_rrd(add); + case_rrr(sub, _d); + case_rrd(sub); + case_rrd(rsb); + case_rrr(mul, _d); + case_rrd(mul); + case_rrr(div, _d); + case_rrd(div); + case_rr(abs, _d); + case_rr(neg, _d); + case_rr(sqrt, _d); + case_rr(ext, _d); + case_rr(ld, _d); + case_rw(ld, _d); + case_rrr(ldx, _d); + case_rrw(ldx, _d); + case_rr(st, _d); + case_wr(st, _d); + case_rrr(stx, _d); + case_wrr(stx, _d); + case_rr(mov, _d); + case jit_code_movi_d: + assert_data(node); + movi_d(rn(node->u.w), node->v.d); + break; + case_rr(ext, _f_d); + case_rrr(lt, _d); + case_rrd(lt); + case_rrr(le, _d); + case_rrd(le); + case_rrr(eq, _d); + case_rrd(eq); + case_rrr(ge, _d); + case_rrd(ge); + case_rrr(gt, _d); + case_rrd(gt); + case_rrr(ne, _d); + case_rrd(ne); + case_rrr(unlt, _d); + case_rrd(unlt); + case_rrr(unle, _d); + case_rrd(unle); + case_rrr(uneq, _d); + case_rrd(uneq); + case_rrr(unge, _d); + case_rrd(unge); + case_rrr(ungt, _d); + case_rrd(ungt); + case_rrr(ltgt, _d); + case_rrd(ltgt); + case_rrr(ord, _d); + case_rrd(ord); + case_rrr(unord, _d); + case_rrd(unord); + case_brr(blt, _d); + case_brd(blt); + case_brr(ble, _d); + case_brd(ble); + case_brr(beq, _d); + case_brd(beq); + case_brr(bge, _d); + case_brd(bge); + case_brr(bgt, _d); + case_brd(bgt); + case_brr(bne, _d); + case_brd(bne); + case_brr(bunlt, _d); + case_brd(bunlt); + case_brr(bunle, _d); + case_brd(bunle); + case_brr(buneq, _d); + case_brd(buneq); + case_brr(bunge, _d); + case_brd(bunge); + case_brr(bungt, _d); + case_brd(bungt); + case_brr(bltgt, _d); + case_brd(bltgt); + case_brr(bord, _d); + case_brd(bord); + case_brr(bunord, _d); + case_brd(bunord); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + break; + case jit_code_jmpi: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } + } + else + jmpi(node->u.w); + break; + case jit_code_callr: + callr(rn(node->u.w)); + break; + case jit_code_calli: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + calli(temp->u.w); + else { + word = calli_p(_jit->pc.w); + patch(word, node); + } + } + else + calli(node->u.w); + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif + undo.patch_offset = _jitc->patches.offset; + restart_function: + _jitc->again = 0; + prolog(node); + break; + case jit_code_epilog: + assert(_jitc->function == _jitc->functions.ptr + node->w.w); + if (_jitc->again) { + for (temp = undo.node->next; + temp != node; temp = temp->next) { + if (temp->code == jit_code_label || + temp->code == jit_code_epilog) + temp->flag &= ~jit_flag_patch; + } + temp->flag &= ~jit_flag_patch; + node = undo.node; + _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif + _jitc->patches.offset = undo.patch_offset; + goto restart_function; + } + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + epilog(node); + _jitc->function = NULL; + break; + case jit_code_va_start: + vastart(rn(node->u.w)); + break; + case jit_code_va_arg: + vaarg(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_va_arg_d: + vaarg_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_live: case jit_code_ellipsis: + case jit_code_va_push: + case jit_code_allocai: case jit_code_allocar: + case jit_code_arg: + case jit_code_arg_f: case jit_code_arg_d: + case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: case jit_code_getarg_ui: + case jit_code_getarg_l: + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: + case jit_code_retval_ui: case jit_code_retval_l: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: + break; + default: + abort(); + } + jit_regarg_clr(node, value); + assert(_jitc->regarg == 0 && _jitc->synth == 0); + /* update register live state */ + jit_reglive(node); + } +#undef case_brw +#undef case_brr +#undef case_wrr +#undef case_rrw +#undef case_rrr +#undef case_wr +#undef case_rw +#undef case_rr + + for (offset = 0; offset < _jitc->patches.offset; offset++) { + node = _jitc->patches.ptr[offset].node; + word = _jitc->patches.ptr[offset].inst; + value = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(word, value); + } + + jit_flush(_jit->code.ptr, _jit->pc.uc); + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_aarch64-cpu.c" +# include "jit_aarch64-fpu.c" +#undef CODE + +void +jit_flush(void *fptr, void *tptr) +{ +#if defined(__GNUC__) + jit_word_t f, t, s; + + s = sysconf(_SC_PAGE_SIZE); + f = (jit_word_t)fptr & -s; + t = (((jit_word_t)tptr) + s - 1) & -s; + __clear_cache((void *)f, (void *)t); +#endif +} + +void +_emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi(rn(r0), rn(r1), i0); +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi(i0, rn(r0), rn(r1)); +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi_d(rn(r0), rn(r1), i0); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi_d(i0, rn(r0), rn(r1)); +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) + flag = node->v.n->flag; + else + flag = node->u.n->flag; + assert(!(flag & jit_flag_patch)); + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} diff --git a/deps/lightning/lib/jit_alpha-cpu.c b/deps/lightning/lib/jit_alpha-cpu.c new file mode 100644 index 0000000..8bfef9c --- /dev/null +++ b/deps/lightning/lib/jit_alpha-cpu.c @@ -0,0 +1,2792 @@ +/* + * Copyright (C) 2014-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# define _u2(v) ((v) & 0x3) +# define _s2_p(v) ((v) >= -0x2 && (v) <= 0x1) +# define _u2_p(v) ((v) >= 0 && (v) <= 0x3) +# define _u5(v) ((v) & 0x1f) +# define _s5_p(v) ((v) >= -0x10 && (v) <= 0xf) +# define _u5_p(v) ((v) >= 0 && (v) <= 0x1f) +# define _u6(v) ((v) & 0x3f) +# define _s6_p(v) ((v) >= -0x20 && (v) <= 0x1f) +# define _u6_p(v) ((v) >= 0 && (v) <= 0x3f) +# define _u7(v) ((v) & 0x7f) +# define _s7_p(v) ((v) >= -0x40 && (v) <= 0x3f) +# define _u7_p(v) ((v) >= 0 && (v) <= 0x7f) +# define _u8(v) ((v) & 0xff) +# define _s8_p(v) ((v) >= -0x80 && (v) <= 0x7f) +# define _u8_p(v) ((v) >= 0 && (v) <= 0xff) +# define _u11(v) ((v) & 0x7ff) +# define _s11_p(v) ((v) >= -0x400 && (v) <= 0x3ff) +# define _u11_p(v) ((v) >= 0 && (v) <= 0x7ff) +# define _u14(v) ((v) & 0x3fff) +# define _s14_p(v) ((v) >= -0x2000 && (v) <= 0x1fff) +# define _u14_p(v) ((v) >= 0 && (v) <= 0x3fff) +# define _u16(v) ((v) & 0xffff) +# define _s16_p(v) ((v) >= -0x8000 && (v) <= 0x7fff) +# define _u16_p(v) ((v) >= 0 && (v) <= 0xffff) +# define _u21(v) ((v) & 0x1fffff) +# define _s21_p(v) ((v) >= -0x100000 && (v) <= 0xfffff) +# define _u21_p(v) ((v) >= 0 && (v) <= 0x1fffff) +# define _u26(v) ((v) & 0x3ffffff) +# define _s26_p(v) ((v) >= -0x2000000 && (v) <= 0x1ffffff) +# define _u26_p(v) ((v) >= 0 && (v) <= 0x3ffffff) +# define _u32(v) ((v) & 0xffffffff) +# define _s32_p(v) ((v) >= -0x80000000 && (v) <= 0x7fffffff) +# define _u32_p(v) ((v) >= 0 && (v) <= 0xffffffff) +# define ii(i) *_jit->pc.ui++ = i +# define stack_framesize 224 +# define _S0_REGNO 0x09 +# define _S1_REGNO 0x0a +# define _S2_REGNO 0x0b +# define _S3_REGNO 0x0c +# define _S4_REGNO 0x0d +# define _S5_REGNO 0x0e +# define _FP_REGNO 0x0f +# define _A0_REGNO 0x10 +# define _A1_REGNO 0x11 +# define _A2_REGNO 0x12 +# define _V0_REGNO 0x00 +# define _T0_REGNO 0x01 +# define _T1_REGNO 0x02 +# define _RA_REGNO 0x1a +# define _PV_REGNO 0x1b +# define _GP_REGNO 0x1d +# define _SP_REGNO 0x1e +# define _R31_REGNO 0x1f +# define Pcd(o,n) _Pcd(_jit,o,n) +static void _Pcd(jit_state_t*,int,unsigned int) maybe_unused; +# define Bra(o,ra,d) _Bra(_jit,o,ra,d) +static void _Bra(jit_state_t*,int,int,int); +# define Mem(o,ra,rb,d) _Mem(_jit,o,ra,rb,d) +static void _Mem(jit_state_t*,int,int,int,unsigned int); +# define Mbr(o,ra,rb,h,d) _Mbr(_jit,o,ra,rb,h,d) +static void _Mbr(jit_state_t*,int,int,int,int,int); +# define Opr(o,ra,rb,f,rc) _Opr(_jit,o,ra,rb,f,rc) +static void _Opr(jit_state_t*,int,int,int,unsigned int,int); +# define Opi(o,ra,i,f,rc) _Opi(_jit,o,ra,i,f,rc) +static void _Opi(jit_state_t*,int,int,unsigned int,unsigned int,int); +# define ADDL(ra,rb,rc) Opr(0x10,ra,rb,0x00,rc) +# define ADDLi(ra,im,rc) Opi(0x10,ra,im,0x00,rc) +# define ADDL_V(ra,rb,rc) Opr(0x10,ra,rb,0x40,rc) +# define ADDL_Vi(ra,im,rc) Opi(0x10,ra,im,0x40,rc) +# define ADDQ(ra,rb,rc) Opr(0x10,ra,rb,0x20,rc) +# define ADDQi(ra,im,rc) Opi(0x10,ra,im,0x20,rc) +# define ADDQ_V(ra,rb,rc) Opr(0x10,ra,rb,0x60,rc) +# define ADDQ_Vi(ra,im,rc) Opi(0x10,ra,im,0x60,rc) +# define AMASK(rb,rc) Opr(0x11,_R31_REGNO,rb,0x61,rc) +# define AND(ra,rb,rc) Opr(0x11,ra,rb,0x00,rc) +# define ANDi(ra,im,rc) Opi(0x11,ra,im,0x00,rc) +# define BEQ(ra,d) Bra(0x39,ra,d) +# define BGE(ra,d) Bra(0x3e,ra,d) +# define BGT(ra,d) Bra(0x3f,ra,d) +# define BIC(ra,rb,rc) Opr(0x11,ra,rb,0x08,rc) +# define ANDNOT(ra,rb,rc) BIC(ra,rb,rc) +# define BICi(ra,im,rc) Opi(0x11,ra,im,0x08,rc) +# define ANDNOTi(ra,im,rc) BICi(ra,im,rc) +# define BIS(ra,rb,rc) Opr(0x11,ra,rb,0x20,rc) +# define BISi(ra,im,rc) Opi(0x11,ra,im,0x20,rc) +# define OR(ra,rb,rc) BIS(ra,rb,rc) +# define ORi(ra,im,rc) BISi(ra,im,rc) +# define BLBC(ra,d) Bra(0x38,ra,d) +# define BLBS(ra,d) Bra(0x3c,ra,d) +# define BLE(ra,d) Bra(0x3b,ra,d) +# define BLT(ra,d) Bra(0x3a,ra,d) +# define BNE(ra,d) Bra(0x3d,ra,d) +# define BR(ra,d) Bra(0x30,ra,d) +# define BSR(ra,d) Bra(0x34,ra,d) +# define CALL_PAL(c) Pcd(0x00,c) +# define CMOVEQ(ra,rb,rc) Opr(0x11,ra,rb,0x24,rc) +# define CMOVEQi(ra,im,rc) Opi(0x11,ra,im,0x24,rc) +# define CMOVGE(ra,rb,rc) Opr(0x11,ra,rb,0x46,rc) +# define CMOVGEi(ra,im,rc) Opi(0x11,ra,im,0x46,rc) +# define CMOVGT(ra,rb,rc) Opr(0x11,ra,rb,0x66,rc) +# define CMOVGTi(ra,im,rc) Opi(0x11,ra,im,0x66,rc) +# define CMOVLBC(ra,rb,rc) Opr(0x11,ra,rb,0x16,rc) +# define CMOVLBCi(ra,im,rc) Opi(0x11,ra,im,0x16,rc) +# define CMOVLBS(ra,rb,rc) Opr(0x11,ra,rb,0x14,rc) +# define CMOVLBSi(ra,im,rc) Opi(0x11,ra,im,0x14,rc) +# define CMOVLE(ra,rb,rc) Opr(0x11,ra,rb,0x64,rc) +# define CMOVLEi(ra,im,rc) Opi(0x11,ra,im,0x64,rc) +# define CMOVLT(ra,rb,rc) Opr(0x11,ra,rb,0x44,rc) +# define CMOVLTi(ra,im,rc) Opi(0x11,ra,im,0x44,rc) +# define CMOVNE(ra,rb,rc) Opr(0x11,ra,rb,0x26,rc) +# define CMOVNEi(ra,im,rc) Opi(0x11,ra,im,0x26,rc) +# define CMPBGE(ra,rb,rc) Opr(0x10,ra,rb,0x0f,rc) +# define CMPBGEi(ra,im,rc) Opi(0x10,ra,im,0x0f,rc) +# define CMPEQ(ra,rb,rc) Opr(0x10,ra,rb,0x2d,rc) +# define CMPEQi(ra,im,rc) Opi(0x10,ra,im,0x2d,rc) +# define CMPLE(ra,rb,rc) Opr(0x10,ra,rb,0x6d,rc) +# define CMPLEi(ra,im,rc) Opi(0x10,ra,im,0x6d,rc) +# define CMPLT(ra,rb,rc) Opr(0x10,ra,rb,0x4d,rc) +# define CMPLTi(ra,im,rc) Opi(0x10,ra,im,0x4d,rc) +# define CMPULE(ra,rb,rc) Opr(0x10,ra,rb,0x3d,rc) +# define CMPULEi(ra,im,rc) Opi(0x10,ra,im,0x3d,rc) +# define CMPULT(ra,rb,rc) Opr(0x10,ra,rb,0x1d,rc) +# define CMPULTi(ra,im,rc) Opi(0x10,ra,im,0x1d,rc) +# define CTLZ(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x32,rc) +# define CTPOP(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x30,rc) +# define CTTZ(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x33,rc) +# define ECB(rb,d) Mem(0x18,_R31_REGNO,rb,0xe800) +# define EQV(ra,rb,rc) Opr(0x11,ra,rb,0x48,rc) +# define XORNOT(ra,rb,rc) EQV(ra,rb,rc) +# define EQVi(ra,im,rc) Opi(0x11,ra,im,0x48,rc) +# define XORNOTi(ra,im,rc) EQVi(ra,im,rc) +# define EXCB() Mem(0x18,0,0,0x0400) +# define EXTBL(ra,rb,rc) Opr(0x12,ra,rb,0x06,rc) +# define EXTBLi(ra,im,rc) Opi(0x12,ra,im,0x06,rc) +# define EXTLH(ra,rb,rc) Opr(0x12,ra,rb,0x6a,rc) +# define EXTLHi(ra,im,rc) Opi(0x12,ra,im,0x6a,rc) +# define EXTLL(ra,rb,rc) Opr(0x12,ra,rb,0x26,rc) +# define EXTLLi(ra,im,rc) Opi(0x12,ra,im,0x26,rc) +# define EXTQH(ra,rb,rc) Opr(0x12,ra,rb,0x7a,rc) +# define EXTQHi(ra,im,rc) Opi(0x12,ra,im,0x7a,rc) +# define EXTQL(ra,rb,rc) Opr(0x12,ra,rb,0x36,rc) +# define EXTQLi(ra,im,rc) Opi(0x12,ra,im,0x36,rc) +# define EXTWH(ra,rb,rc) Opr(0x12,ra,rb,0x5a,rc) +# define EXTWHi(ra,im,rc) Opi(0x12,ra,im,0x5a,rc) +# define EXTWL(ra,rb,rc) Opr(0x12,ra,rb,0x16,rc) +# define EXTWLi(ra,im,rc) Opi(0x12,ra,im,0x16,rc) +# define FETCH(rb,d) Mem(0x18,_R31_REGNO,rb,0x8000) +# define FETCH_Mem(rb,d) Mem(0x18,_R31_REGNO,rb,0xa000) +/* FIXME IMPLVER not disassembled */ +# define IMPLVER(rc) Opr(0x11,_R31_REGNO,1,0x6c,rc) +# define INSBL(ra,rb,rc) Opr(0x12,ra,rb,0x0b,rc) +# define INSBLi(ra,im,rc) Opi(0x12,ra,im,0x0b,rc) +# define INSLH(ra,rb,rc) Opr(0x12,ra,rb,0x67,rc) +# define INSLHi(ra,im,rc) Opi(0x12,ra,im,0x67,rc) +# define INSLL(ra,rb,rc) Opr(0x12,ra,rb,0x2b,rc) +# define INSLLi(ra,im,rc) Opi(0x12,ra,im,0x2b,rc) +# define INSQH(ra,rb,rc) Opr(0x12,ra,rb,0x77,rc) +# define INSQHi(ra,im,rc) Opi(0x12,ra,im,0x77,rc) +# define INSQL(ra,rb,rc) Opr(0x12,ra,rb,0x3b,rc) +# define INSQLi(ra,im,rc) Opi(0x12,ra,im,0x3b,rc) +# define INSWH(ra,rb,rc) Opr(0x12,ra,rb,0x57,rc) +# define INSWHi(ra,im,rc) Opi(0x12,ra,im,0x57,rc) +# define INSWL(ra,rb,rc) Opr(0x12,ra,rb,0x1b,rc) +# define INSWLi(ra,im,rc) Opi(0x12,ra,im,0x1b,rc) +# define JMP(ra,rb,d) Mbr(0x1a,ra,rb,0,d) +# define JSR(ra,rb,d) Mbr(0x1a,ra,rb,1,d) +# define JSR_COROUTINE(ra,rb,d) Mbr(0x1a,ra,rb,3,d) +# define JCR(ra,rb,rd) JSR_COROUTINE(ra,rb,d) +# define LDA(ra,rb,d) Mem(0x08,ra,rb,d) +# define LDAH(ra,rb,d) Mem(0x09,ra,rb,d) +# define LDBU(ra,rb,d) Mem(0x0a,ra,rb,d) +# define LDWU(ra,rb,d) Mem(0x0c,ra,rb,d) +# define LDL(ra,rb,d) Mem(0x28,ra,rb,d) +# define LDL_L(ra,rb,d) Mem(0x2a,ra,rb,d) +# define LDQ(ra,rb,d) Mem(0x29,ra,rb,d) +# define LDQ_L(ra,rb,d) Mem(0x2b,ra,rb,d) +# define LDQ_U(ra,rb,d) Mem(0x0b,ra,rb,d) +# define MAXSB8(ra,rb,rc) Opr(0x1c,ra,rb,0x3e,rc) +# define MAXSW4(ra,rb,rc) Opr(0x1c,ra,rb,0x3f,rc) +# define MAXSUB8(ra,rb,rc) Opr(0x1c,ra,rb,0x3c,rc) +# define MAXSUW4(ra,rb,rc) Opr(0x1c,ra,rb,0x3d,rc) +# define MB() Mem(0x18,_R31_REGNO,_R31_REGNO,0x4000) +# define MINSB8(ra,rb,rc) Opr(0x1c,ra,rb,0x38,rc) +# define MINSW4(ra,rb,rc) Opr(0x1c,ra,rb,0x39,rc) +# define MINSUB8(ra,rb,rc) Opr(0x1c,ra,rb,0x3a,rc) +# define MINSUW4(ra,rb,rc) Opr(0x1c,ra,rb,0x3b,rc) +# define MSKBL(ra,rb,rc) Opr(0x12,ra,rb,0x02,rc) +# define MSKBLi(ra,im,rc) Opi(0x12,ra,im,0x02,rc) +# define MSKLH(ra,rb,rc) Opr(0x12,ra,rb,0x62,rc) +# define MSKLHi(ra,im,rc) Opi(0x12,ra,im,0x62,rc) +# define MSKLL(ra,rb,rc) Opr(0x12,ra,rb,0x22,rc) +# define MSKLLi(ra,im,rc) Opi(0x12,ra,im,0x22,rc) +# define MSKQH(ra,rb,rc) Opr(0x12,ra,rb,0x72,rc) +# define MSKQHi(ra,im,rc) Opi(0x12,ra,im,0x72,rc) +# define MSKQL(ra,rb,rc) Opr(0x12,ra,rb,0x32,rc) +# define MSKQLi(ra,im,rc) Opi(0x12,ra,im,0x32,rc) +# define MSKWH(ra,rb,rc) Opr(0x12,ra,rb,0x52,rc) +# define MSKWHi(ra,im,rc) Opi(0x12,ra,im,0x52,rc) +# define MSKWL(ra,rb,rc) Opr(0x12,ra,rb,0x12,rc) +# define MSKWLi(ra,im,rc) Opi(0x12,ra,im,0x12,rc) +# define MULL(ra,rb,rc) Opr(0x13,ra,rb,0x00,rc) +# define MULLi(ra,im,rc) Opi(0x13,ra,im,0x00,rc) +# define MULL_V(ra,rb,rc) Opr(0x13,ra,rb,0x40,rc) +# define MULL_Vi(ra,im,rc) Opi(0x13,ra,im,0x40,rc) +# define MULQ(ra,rb,rc) Opr(0x13,ra,rb,0x20,rc) +# define MULQi(ra,im,rc) Opi(0x13,ra,im,0x20,rc) +# define MULQ_V(ra,rb,rc) Opr(0x13,ra,rb,0x60,rc) +# define MULQ_Vi(ra,im,rc) Opi(0x13,ra,im,0x60,rc) +# define ORNOT(ra,rb,rc) Opr(0x11,ra,rb,0x28,rc) +# define ORNOTi(ra,im,rc) Opi(0x11,ra,im,0x28,rc) +# define PERR(ra,rb,rc) Opr(0x1c,ra,rb,0x31,rc) +# define PKLB(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x37,rc) +# define PKWB(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x36,rc) +/* FIXME PREFETCH* not disassembled */ +# define PREFETCH(rb,d) Mem(0x28,_R31_REGNO,rb,d) +# define PREFETCH_EN(rb,d) Mem(0x29,_R31_REGNO,rb,d) +# define PREFETCH_M(rb,d) Mem(0x22,_R31_REGNO,rb,d) +# define PREFETCH_MEN(rb,d) Mem(0x23,_R31_REGNO,rb,d) +# define RC(ra) Mem(0x18,ra,_R31_REGNO,0xe000) +# define RET(ra,rb,d) Mbr(0x1a,ra,rb,2,d) +# define RPCC(ra) Mem(0x18,ra,_R31_REGNO,0xc000) +# define RS(ra) Mem(0x18,ra,_R31_REGNO,0xf000) +# define S4ADDL(ra,rb,rc) Opr(0x10,ra,rb,0x02,rc) +# define S4ADDi(ra,im,rc) Opi(0x10,ra,im,0x02,rc) +# define S4ADDQ(ra,rb,rc) Opr(0x10,ra,rb,0x22,rc) +# define S4ADDQi(ra,im,rc) Opi(0x10,ra,im,0x22,rc) +# define S4SUBL(ra,rb,rc) Opr(0x10,ra,rb,0x0b,rc) +# define S4SUBLi(ra,im,rc) Opi(0x10,ra,im,0x0b,rc) +# define S4SUBQ(ra,rb,rc) Opr(0x10,ra,rb,0x2b,rc) +# define S4SUBQi(ra,im,rc) Opi(0x10,ra,im,0x2b,rc) +# define S8ADDL(ra,rb,rc) Opr(0x10,ra,rb,0x12,rc) +# define S8ADDLi(ra,im,rc) Opi(0x10,ra,im,0x12,rc) +# define S8ADDQ(ra,rb,rc) Opr(0x10,ra,rb,0x32,rc) +# define S8ADDQi(ra,im,rc) Opi(0x10,ra,im,0x32,rc) +# define S8SUBL(ra,rb,rc) Opr(0x10,ra,rb,0x1b,rc) +# define S8SUBLi(ra,im,rc) Opi(0x10,ra,im,0x1b,rc) +# define S8SUBQ(ra,rb,rc) Opr(0x10,ra,rb,0x3b,rc) +# define S8SUBQi(ra,im,rc) Opi(0x10,ra,im,0x3b,rc) +# define SEXTB(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x00,rc) +/* FIXME not disassembled */ +# define SEXTBi(im,rc) Opi(0x1c,_R31_REGNO,im,0x00,rc) +# define SEXTW(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x01,rc) +/* FIXME not disassembled */ +# define SEXTWi(im,rc) Opi(0x1c,_R31_REGNO,im,0x01,rc) +# define SLL(ra,rb,rc) Opr(0x12,ra,rb,0x39,rc) +# define SLLi(ra,im,rc) Opi(0x12,ra,im,0x39,rc) +# define SRA(ra,rb,rc) Opr(0x12,ra,rb,0x3c,rc) +# define SRAi(ra,im,rc) Opi(0x12,ra,im,0x3c,rc) +# define SRL(ra,rb,rc) Opr(0x12,ra,rb,0x34,rc) +# define SRLi(ra,im,rc) Opi(0x12,ra,im,0x34,rc) +# define STB(ra,rb,d) Mem(0x0e,ra,rb,d) +# define STL(ra,rb,d) Mem(0x2c,ra,rb,d) +# define STL_C(ra,rb,d) Mem(0x2e,ra,rb,d) +# define STQ(ra,rb,d) Mem(0x2d,ra,rb,d) +# define STQ_C(ra,rb,d) Mem(0x2f,ra,rb,d) +# define STQ_U(ra,rb,d) Mem(0x0f,ra,rb,d) +# define STW(ra,rb,d) Mem(0x0d,ra,rb,d) +# define SUBL(ra,rb,rc) Opr(0x10,ra,rb,0x09,rc) +# define SUBLi(ra,im,rc) Opi(0x10,ra,im,0x09,rc) +# define SUBL_V(ra,rb,rc) Opr(0x10,ra,rb,0x49,rc) +# define SUBL_Vi(ra,im,rc) Opi(0x10,ra,im,0x49,rc) +# define SUBQ(ra,rb,rc) Opr(0x10,ra,rb,0x29,rc) +# define SUBQi(ra,im,rc) Opi(0x10,ra,im,0x29,rc) +# define SUBQ_V(ra,rb,rc) Opr(0x10,ra,rb,0x69,rc) +# define SUBQ_Vi(ra,im,rc) Opi(0x10,ra,im,0x69,rc) +# define TRAPB() Mem(0x18,_R31_REGNO,_R31_REGNO,0x0000) +# define UMULH(ra,rb,rc) Opr(0x13,ra,rb,0x30,rc) +# define UMULHi(ra,im,rc) Opi(0x13,ra,im,0x30,rc) +# define UNPKBL(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x35,rc) +# define UNPKBW(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x34,rc) +# define WH64(ra) Mem(0x18,ra,_R31_REGNO,0xf800) +# define WH64EN(ra) Mem(0x18,ra,_R31_REGNO,0xfc00) +# define WMB() Mem(0x18,_R31_REGNO,_R31_REGNO,0x4400) +# define XOR(ra,rb,rc) Opr(0x11,ra,rb,0x40,rc) +# define XORi(ra,im,rc) Opi(0x11,ra,im,0x40,rc) +# define ZAP(ra,rb,rc) Opr(0x12,ra,rb,0x30,rc) +# define ZAPi(ra,im,rc) Opi(0x12,ra,im,0x30,rc) +# define ZAPNOT(ra,rb,rc) Opr(0x12,ra,rb,0x31,rc) +# define ZAPNOTi(ra,im,rc) Opi(0x12,ra,im,0x31,rc) +# define NOP() BIS(_R31_REGNO,_R31_REGNO,_R31_REGNO) +# define MOV(ra,rc) BIS(ra,ra,rc) +# define MOVi(im,rc) BISi(_R31_REGNO,im,rc) +# define NEGL(ra,rc) SUBL(_R31_REGNO,ra,rc) +# define NEGQ(ra,rc) SUBQ(_R31_REGNO,ra,rc) +# define NOT(ra,rc) ORNOT(_R31_REGNO,ra,rc) +# define nop(i0) _nop(_jit,i0) +static void _nop(jit_state_t*,jit_int32_t); +# define movr(r0,r1) _movr(_jit,r0,r1) +static void _movr(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi(r0,i0) _movi(_jit,r0,i0) +static void _movi(jit_state_t*,jit_int32_t,jit_word_t); +# define movi_p(r0,i0) _movi_p(_jit,r0,i0) +static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t); +# define negr(r0,r1) NEGQ(r1,r0) +# define comr(r0,r1) NOT(r1,r0) +# define addr(r0,r1,r2) ADDQ(r1,r2,r0) +# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0) +static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addcr(r0,r1,i0) _addcr(_jit,r0,r1,i0) +static void _addcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addci(r0,r1,i0) _addci(_jit,r0,r1,i0) +static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addxr(r0,r1,i0) _addxr(_jit,r0,r1,i0) +static void _addxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0) +static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subr(r0,r1,r2) SUBQ(r1,r2,r0) +# define subi(r0,r1,i0) _subi(_jit,r0,r1,i0) +static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subcr(r0,r1,i0) _subcr(_jit,r0,r1,i0) +static void _subcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subci(r0,r1,i0) _subci(_jit,r0,r1,i0) +static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subxr(r0,r1,i0) _subxr(_jit,r0,r1,i0) +static void _subxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subxi(r0,r1,i0) _subxi(_jit,r0,r1,i0) +static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0) +static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t, jit_word_t); +# define mulr(r0,r1,r2) MULQ(r1,r2,r0) +# define muli(r0,r1,i0) _muli(_jit,r0,r1,i0) +static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr(r0,r1,r2,r3) _qmulr(_jit,r0,r1,r2,r3) +static void _qmulr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qmuli(r0,r1,r2,i0) _qmuli(_jit,r0,r1,r2,i0) +static void _qmuli(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr_u(r0,r1,r2,r3) _qmulr_u(_jit,r0,r1,r2,r3) +static void _qmulr_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qmuli_u(r0,r1,r2,i0) _qmuli_u(_jit,r0,r1,r2,i0) +static void _qmuli_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +static jit_word_t __idiv(jit_word_t, jit_word_t); +# define divr(r0,r1,r2) _divr(_jit,r0,r1,r2) +static void _divr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi(r0,r1,i0) _divi(_jit,r0,r1,i0) +static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +static jit_uword_t __udiv(jit_uword_t, jit_uword_t); +# define divr_u(r0,r1,r2) _divr_u(_jit,r0,r1,r2) +static void _divr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0) +static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +static jit_word_t __irem(jit_word_t, jit_word_t); +# define remr(r0,r1,r2) _remr(_jit,r0,r1,r2) +static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi(r0,r1,i0) _remi(_jit,r0,r1,i0) +static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +static jit_uword_t __urem(jit_uword_t, jit_uword_t); +# define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2) +static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0) +static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +static jit_word_t __idivrem(jit_word_t, jit_word_t, jit_word_t*); +# define qdivr(r0,r1,r2,r3) _qdivr(_jit,r0,r1,r2,r3) +static void _qdivr(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define qdivi(r0,r1,r2,i0) _qdivi(_jit,r0,r1,r2,i0) +static void _qdivi(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +static jit_word_t __udivrem(jit_uword_t, jit_uword_t, jit_uword_t*); +# define qdivr_u(r0,r1,r2,r3) _qdivr_u(_jit,r0,r1,r2,r3) +static void _qdivr_u(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define qdivi_u(r0,r1,r2,i0) _qdivi_u(_jit,r0,r1,r2,i0) +static void _qdivi_u(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +# define lshr(r0,r1,r2) SLL(r1,r2,r0) +# define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0) +static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr(r0,r1,r2) SRA(r1,r2,r0) +# define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0) +static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr_u(r0,r1,r2) SRL(r1,r2,r0) +# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0) +static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define andr(r0,r1,r2) AND(r1,r2,r0) +# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0) +static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define orr(r0,r1,r2) OR(r1,r2,r0) +# define ori(r0,r1,i0) _ori(_jit,r0,r1,i0) +static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define xorr(r0,r1,r2) XOR(r1,r2,r0) +# define xori(r0,r1,i0) _xori(_jit,r0,r1,i0) +static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ltr(r0,r1,r2) CMPLT(r1,r2,r0) +# define lti(r0,r1,i0) _lti(_jit,r0,r1,i0) +static void _lti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ltr_u(r0,r1,r2) CMPULT(r1,r2,r0) +# define lti_u(r0,r1,i0) _lti_u(_jit,r0,r1,i0) +static void _lti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ler(r0,r1,r2) CMPLE(r1,r2,r0) +# define lei(r0,r1,i0) _lei(_jit,r0,r1,i0) +static void _lei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ler_u(r0,r1,r2) CMPULE(r1,r2,r0) +# define lei_u(r0,r1,i0) _lei_u(_jit,r0,r1,i0) +static void _lei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define eqr(r0,r1,r2) CMPEQ(r1,r2,r0) +# define eqi(r0,r1,i0) _eqi(_jit,r0,r1,i0) +static void _eqi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ger(r0,r1,r2) CMPLE(r2,r1,r0) +# define gei(r0,r1,i0) _gei(_jit,r0,r1,i0) +static void _gei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ger_u(r0,r1,r2) CMPULE(r2,r1,r0) +# define gei_u(r0,r1,i0) _gei_u(_jit,r0,r1,i0) +static void _gei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define gtr(r0,r1,r2) CMPLT(r2,r1,r0) +# define gti(r0,r1,i0) _gti(_jit,r0,r1,i0) +static void _gti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define gtr_u(r0,r1,r2) CMPULT(r2,r1,r0) +# define gti_u(r0,r1,i0) _gti_u(_jit,r0,r1,i0) +static void _gti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ner(r0,r1,r2) _ner(_jit,r0,r1,r2) +static void _ner(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define nei(r0,r1,i0) _nei(_jit,r0,r1,i0) +static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define bltr(i0,r0,r1) _bltr(_jit,i0,r0,r1) +static jit_word_t _bltr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blti(i0,r0,i1) _blti(_jit,i0,r0,i1) +static jit_word_t _blti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bltr_u(i0,r0,r1) _bltr_u(_jit,i0,r0,r1) +static jit_word_t _bltr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blti_u(i0,r0,i1) _blti_u(_jit,i0,r0,i1) +static jit_word_t _blti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bler(i0,r0,r1) _bler(_jit,i0,r0,r1) +static jit_word_t _bler(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blei(i0,r0,i1) _blei(_jit,i0,r0,i1) +static jit_word_t _blei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bler_u(i0,r0,r1) _bler_u(_jit,i0,r0,r1) +static jit_word_t _bler_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blei_u(i0,r0,i1) _blei_u(_jit,i0,r0,i1) +static jit_word_t _blei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define beqr(i0,r0,r1) _beqr(_jit,i0,r0,r1) +static jit_word_t _beqr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define beqi(i0,r0,i1) _beqi(_jit,i0,r0,i1) +static jit_word_t _beqi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bger(i0,r0,r1) _bger(_jit,i0,r0,r1) +static jit_word_t _bger(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgei(i0,r0,i1) _bgei(_jit,i0,r0,i1) +static jit_word_t _bgei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bger_u(i0,r0,r1) _bger_u(_jit,i0,r0,r1) +static jit_word_t _bger_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgei_u(i0,r0,i1) _bgei_u(_jit,i0,r0,i1) +static jit_word_t _bgei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bgtr(i0,r0,r1) _bgtr(_jit,i0,r0,r1) +static jit_word_t _bgtr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgti(i0,r0,i1) _bgti(_jit,i0,r0,i1) +static jit_word_t _bgti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bgtr_u(i0,r0,r1) _bgtr_u(_jit,i0,r0,r1) +static jit_word_t _bgtr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgti_u(i0,r0,i1) _bgti_u(_jit,i0,r0,i1) +static jit_word_t _bgti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bner(i0,r0,r1) _bner(_jit,i0,r0,r1) +static jit_word_t _bner(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bnei(i0,r0,i1) _bnei(_jit,i0,r0,i1) +static jit_word_t _bnei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define baddr(i0,r0,r1,cc) _baddr(_jit,i0,r0,r1,cc) +static jit_word_t _baddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t, + jit_bool_t); +# define baddi(i0,r0,i1,cc) _baddi(_jit,i0,r0,i1,cc) +static jit_word_t _baddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t, + jit_bool_t); +# define baddr_u(i0,r0,r1,cc) _baddr_u(_jit,i0,r0,r1,cc) +static jit_word_t _baddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t, + jit_bool_t); +# define baddi_u(i0,r0,i1,cc) _baddi_u(_jit,i0,r0,i1,cc) +static jit_word_t _baddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t, + jit_bool_t); +# define boaddr(i0,r0,r1) baddr(i0,r0,r1,1) +# define boaddi(i0,r0,i1) baddi(i0,r0,i1,1) +# define boaddr_u(i0,r0,r1) baddr_u(i0,r0,r1,1) +# define boaddi_u(i0,r0,i1) baddi_u(i0,r0,i1,1) +# define bxaddr(i0,r0,r1) baddr(i0,r0,r1,0) +# define bxaddi(i0,r0,i1) baddi(i0,r0,i1,0) +# define bxaddr_u(i0,r0,r1) baddr_u(i0,r0,r1,0) +# define bxaddi_u(i0,r0,i1) baddi_u(i0,r0,i1,0) +# define bsubr(i0,r0,r1,cc) _bsubr(_jit,i0,r0,r1,cc) +static jit_word_t _bsubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t, + jit_bool_t); +# define bsubi(i0,r0,i1,cc) _bsubi(_jit,i0,r0,i1,cc) +static jit_word_t _bsubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t, + jit_bool_t); +# define bsubr_u(i0,r0,r1,cc) _bsubr_u(_jit,i0,r0,r1,cc) +static jit_word_t _bsubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t, + jit_bool_t); +# define bsubi_u(i0,r0,i1,cc) _bsubi_u(_jit,i0,r0,i1,cc) +static jit_word_t _bsubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t, + jit_bool_t); +# define bosubr(i0,r0,r1) bsubr(i0,r0,r1,1) +# define bosubi(i0,r0,i1) bsubi(i0,r0,i1,1) +# define bosubr_u(i0,r0,r1) bsubr_u(i0,r0,r1,1) +# define bosubi_u(i0,r0,i1) bsubi_u(i0,r0,i1,1) +# define bxsubr(i0,r0,r1) bsubr(i0,r0,r1,0) +# define bxsubi(i0,r0,i1) bsubi(i0,r0,i1,0) +# define bxsubr_u(i0,r0,r1) bsubr_u(i0,r0,r1,0) +# define bxsubi_u(i0,r0,i1) bsubi_u(i0,r0,i1,0) +# define bmxr(i0,r0,r1,cc) _bmxr(_jit,i0,r0,r1,cc) +static jit_word_t _bmxr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t, + jit_bool_t); +# define bmxi(i0,r0,i1,cc) _bmxi(_jit,i0,r0,i1,cc) +static jit_word_t _bmxi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t, + jit_bool_t); +# define bmsr(i0,r0,r1) bmxr(i0,r0,r1,1) +# define bmsi(i0,r0,i1) bmxi(i0,r0,i1,1) +# define bmcr(i0,r0,r1) bmxr(i0,r0,r1,0) +# define bmci(i0,r0,i1) bmxi(i0,r0,i1,0) +# define ldr_c(r0,r1) _ldr_c(_jit,r0,r1) +static void _ldr_c(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_c(r0,i0) _ldi_c(_jit,r0,i0) +static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_uc(r0,r1) LDBU(r0,r1,0) +# define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0) +static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_s(r0,r1) _ldr_s(_jit,r0,r1) +static void _ldr_s(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_s(r0,i0) _ldi_s(_jit,r0,i0) +static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_us(r0,r1) LDWU(r0,r1,0) +# define ldi_us(r0,i0) _ldi_us(_jit,r0,i0) +static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_i(r0,r1) LDL(r0,r1,0) +# define ldi_i(r0,i0) _ldi_i(_jit,r0,i0) +static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_ui(r0,r1) _ldr_ui(_jit,r0,r1) +static void _ldr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_ui(r0,i0) _ldi_ui(_jit,r0,i0) +static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr(r0,r1) ldr_l(r0,r1) +# define ldr_l(r0,r1) LDQ(r0,r1,0) +# define ldi_l(r0,i0) _ldi_l(_jit,r0,i0) +static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_c(r0,r1,r2) _ldxr_c(_jit,r0,r1,r2) +static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0) +static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_uc(r0,r1,r2) _ldxr_uc(_jit,r0,r1,r2) +static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0) +static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_s(r0,r1,r2) _ldxr_s(_jit,r0,r1,r2) +static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0) +static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_us(r0,r1,r2) _ldxr_us(_jit,r0,r1,r2) +static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0) +static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_i(r0,r1,r2) _ldxr_i(_jit,r0,r1,r2) +static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_i(r0,r1,i0) _ldxi_i(_jit,r0,r1,i0) +static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_ui(r0,r1,r2) _ldxr_ui(_jit,r0,r1,r2) +static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_ui(r0,r1,i0) _ldxi_ui(_jit,r0,r1,i0) +static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr(r0,r1,r2) ldxr_l(r0,r1,r2) +# define ldxr_l(r0,r1,r2) _ldxr_l(_jit,r0,r1,r2) +static void _ldxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi(r0,r1,i0) ldxi_l(r0,r1,i0) +# define ldxi_l(r0,r1,i0) _ldxi_l(_jit,r0,r1,i0) +static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_c(r0,r1) STB(r1,r0,0) +# define sti_c(i0,r0) _sti_c(_jit,i0,r0) +static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t); +# define str_s(r0,r1) STW(r1,r0,0) +# define sti_s(i0,r0) _sti_s(_jit,i0,r0) +static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t); +# define str_i(r0,r1) STL(r1,r0,0) +# define sti_i(i0,r0) _sti_i(_jit,i0,r0) +static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); +# define str(r0,r1) str_l(r0,r1) +# define str_l(r0,r1) STQ(r1,r0,0) +# define sti_l(i0,r0) _sti_l(_jit,i0,r0) +static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_c(r0,r1,r2) _stxr_c(_jit,r0,r1,r2) +static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_c(i0,r0,r1) _stxi_c(_jit,i0,r0,r1) +static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_s(r0,r1,r2) _stxr_s(_jit,r0,r1,r2) +static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_s(i0,r0,r1) _stxi_s(_jit,i0,r0,r1) +static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_i(r0,r1,r2) _stxr_i(_jit,r0,r1,r2) +static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_i(i0,r0,r1) _stxi_i(_jit,i0,r0,r1) +static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_l(r0,r1,r2) _stxr_l(_jit,r0,r1,r2) +static void _stxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi(i0,r0,r1) stxi_l(i0,r0,r1) +# define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1) +static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define extr_c(r0,r1) _extr_c(_jit,r0,r1) +static void _extr_c(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_uc(r0,r1) _extr_uc(_jit,r0,r1) +static void _extr_uc(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_s(r0,r1) _extr_s(_jit,r0,r1) +static void _extr_s(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_us(r0,r1) _extr_us(_jit,r0,r1) +static void _extr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_i(r0,r1) _extr_i(_jit,r0,r1) +static void _extr_i(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_ui(r0,r1) _extr_ui(_jit,r0,r1) +static void _extr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1) +static void _htonr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1) +static void _htonr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# define htonr_ul(r0,r1) _htonr_ul(_jit,r0,r1) +static void _htonr_ul(jit_state_t*,jit_int32_t,jit_int32_t); +# else +# define htonr_us(r0,r1) extr_us(r0,r1) +# define htonr_ui(r0,r1) extr_ui(r0,r1) +# define htonr_ul(r0,r1) movr(r0,r1) +# endif +# define jmpr(r0) JMP(_R31_REGNO,r0,0) +# define jmpi(i0) _jmpi(_jit,i0) +static void _jmpi(jit_state_t*, jit_word_t); +# define jmpi_p(i0) _jmpi_p(_jit,i0) +static jit_word_t _jmpi_p(jit_state_t*, jit_word_t); +#define callr(r0) _callr(_jit,r0) +static void _callr(jit_state_t*, jit_int32_t); +# define calli(i0) _calli(_jit,i0) +static void _calli(jit_state_t*, jit_word_t); +# define calli_p(i0) _calli_p(_jit,i0) +static jit_word_t _calli_p(jit_state_t*, jit_word_t); +# define prolog(node) _prolog(_jit,node) +static void _prolog(jit_state_t*,jit_node_t*); +# define epilog(node) _epilog(_jit,node) +static void _epilog(jit_state_t*,jit_node_t*); +# define vastart(r0) _vastart(_jit, r0) +static void _vastart(jit_state_t*, jit_int32_t); +# define vaarg(r0, r1) _vaarg(_jit, r0, r1) +static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t); +# define patch_at(jump,label) _patch_at(_jit,jump,label) +static void _patch_at(jit_state_t*,jit_word_t,jit_word_t); +#endif + +#if CODE +static void +_Pcd(jit_state_t *_jit, int o, unsigned int n) +{ + assert(_u6_p(o)); + assert(_u26_p(n)); + ii((o<<26)|_u26(n)); +} + +static void +_Bra(jit_state_t *_jit, int o, int ra, int d) +{ + assert(_u6_p(o)); + assert(_u5_p(ra)); + assert(_s21_p(d)); + ii((o<<26)|(ra<<21)|_u21(d)); +} + +static void +_Mem(jit_state_t *_jit, int o, int ra, int rb, unsigned int d) +{ + assert(_u6_p(o)); + assert(_u5_p(ra)); + assert(_u5_p(rb)); + assert(_u16_p(d)); + ii((o<<26)|(ra<<21)|(rb<<16)|_u16(d)); +} + +static void +_Mbr(jit_state_t *_jit, int o, int ra, int rb, int h, int d) +{ + assert(_u6_p(o)); + assert(_u5_p(ra)); + assert(_u5_p(rb)); + assert(_u2_p(h)); + assert(_s14_p(d)); + ii((o<<26)|(ra<<21)|(rb<<16)|(h<<14)|_u14(d)); +} + +static void +_Opr(jit_state_t *_jit, int o, int ra, int rb, unsigned int f, int rc) +{ + assert(_u6_p(o)); + assert(_u5_p(ra)); + assert(_u5_p(rb)); + assert(_u5_p(rc)); + assert(_u11_p(f)); + ii((o<<26)|(ra<<21)|(rb<<16)|(_u11(f)<<5)|rc); +} + +static void +_Opi(jit_state_t *_jit, int o, int ra, unsigned int i, unsigned int f, int rc) +{ + assert(_u6_p(o)); + assert(_u5_p(ra)); + assert(_u8_p(i)); + assert(_u5_p(rc)); + assert(_u7_p(f)); + ii((o<<26)|(ra<<21)|(_u8(i)<<13)|(1<<12)|(_u7(f)<<5)|rc); +} + +static void +_nop(jit_state_t *_jit, jit_int32_t i0) +{ + for (; i0 > 0; i0 -= 4) + NOP(); + assert(i0 == 0); +} + +static void +_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + MOV(r1, r0); +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + jit_int16_t s0, s1, s2, s3; + s0 = i0; + s1 = i0 >> 16; + s2 = i0 >> 32; + s3 = i0 >> 48; + if (s0 < 0) + ++s1; + if (s2 < 0) + ++s3; + if (_u8_p(i0)) + MOVi(_u8(i0), r0); + else if (_s16_p(i0)) + LDA(r0, _R31_REGNO, _u16(s0)); + else if (_s32_p(i0)) { + LDA(r0, _R31_REGNO, _u16(s0)); + LDAH(r0, r0, _u16(s1)); + } + else if (_u32_p(i0)) { + LDA(r0, _R31_REGNO, _u16(s0)); + if (s1) + LDAH(r0, r0, _u16(s1)); + lshi(r0, r0, 32); + rshi_u(r0, r0, 32); + } + else if (_u32(i0) == 0) { + LDA(r0, _R31_REGNO, _u16(s2)); + if (s3) + LDAH(r0, r0, _u16(s3)); + lshi(r0, r0, 32); + } + else { + reg = jit_get_reg(jit_class_gpr); + LDA(r0, _R31_REGNO, _u16(s0)); + LDA(rn(reg), _R31_REGNO, _u16(s2)); + if (s1) + LDAH(r0, r0, _u16(s1)); + if (s3) + LDAH(rn(reg), rn(reg), _u16(s3)); + lshi(r0, r0, 32); + rshi_u(r0, r0, 32); + lshi(rn(reg), rn(reg), 32); + orr(r0, r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + jit_int16_t s0, s1, s2, s3; + w = _jit->pc.w; + reg = jit_get_reg(jit_class_gpr); + s0 = i0; + s1 = i0 >> 16; + s2 = i0 >> 32; + s3 = i0 >> 48; + if (s0 < 0) + ++s1; + if (s2 < 0) + ++s3; + LDA(r0, _R31_REGNO, _u16(s0)); + LDA(rn(reg), _R31_REGNO, _u16(s2)); + LDAH(r0, r0, _u16(s1)); + LDAH(rn(reg), rn(reg), _u16(s3)); + lshi(r0, r0, 32); + rshi_u(r0, r0, 32); + lshi(rn(reg), rn(reg), 32); + orr(r0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + ADDQi(r1, i0, r0); + else if (_s16_p(i0)) + LDA(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ltr_u(rn(jit_carry), rn(reg), r1); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + addr(r0, r1, r2); + ltr_u(rn(jit_carry), r0, r1); + } +} + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ltr_u(rn(jit_carry), rn(reg), r1); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + addi(r0, r1, i0); + ltr_u(rn(jit_carry), r0, r1); + } +} + +static void +_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + addcr(r0, r1, r2); + addcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + addci(r0, r1, i0); + addcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + SUBQi(r1, i0, r0); + else if (_s16_p(-i0)) + LDA(r0, r1, _u16(-i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + subr(rn(reg), r1, r2); + ltr_u(rn(jit_carry), r1, rn(reg)); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + subr(r0, r1, r2); + ltr_u(rn(jit_carry), r1, r0); + } +} + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, -i0); + ltr_u(rn(jit_carry), r1, rn(reg)); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + addi(r0, r1, -i0); + ltr_u(rn(jit_carry), r1, r0); + } +} + +static void +_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + subcr(r0, r1, r2); + subcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + subci(r0, r1, i0); + subcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + subi(r0, r1, i0); + negr(r0, r0); +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + MULQi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + mulr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_qmulr(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t reg; + /* The only invalid condition is r0 == r1 */ + jit_int32_t t2, t3, s2, s3; + if (r2 == r0 || r2 == r1) { + s2 = jit_get_reg(jit_class_gpr); + t2 = rn(s2); + movr(t2, r2); + } + else + t2 = r2; + if (r3 == r0 || r3 == r1) { + s3 = jit_get_reg(jit_class_gpr); + t3 = rn(s3); + movr(t3, r3); + } + else + t3 = r3; + qmulr_u(r0, r1, r2, r3); + reg = jit_get_reg(jit_class_gpr); + /**/ + rshi(rn(reg), t2, 63); + mulr(rn(reg), rn(reg), t3); + addr(r1, r1, rn(reg)); + /**/ + rshi(rn(reg), t3, 63); + mulr(rn(reg), rn(reg), t2); + addr(r1, r1, rn(reg)); + jit_unget_reg(reg); + if (t2 != r2) + jit_unget_reg(s2); + if (t3 != r3) + jit_unget_reg(s3); +} + +static void +_qmuli(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + qmulr(r0, r1, r2, rn(reg)); + jit_unget_reg(reg); +} + +static void +_qmulr_u(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t reg; + if (r0 == r2 || r0 == r3) { + reg = jit_get_reg(jit_class_gpr); + mulr(rn(reg), r2, r3); + } + else + mulr(r0, r2, r3); + UMULH(r2, r3, r1); + if (r0 == r2 || r0 == r3) { + movr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_qmuli_u(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) { + if (r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + muli(rn(reg), r2, i0); + } + else + muli(r0, r2, i0); + UMULHi(r2, i0, r1); + if (r0 == r2) { + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + qmulr_u(r0, r1, r2, rn(reg)); + jit_unget_reg(reg); + } +} + +static jit_word_t +__idiv(jit_word_t u, jit_word_t v) +{ + return (u / v); +} + +static void +_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + movr(_A0_REGNO, r1); + movr(_A1_REGNO, r2); + calli((jit_word_t)__idiv); + movr(r0, _V0_REGNO); +} + +static void +_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(_A0_REGNO, r1); + movi(_A1_REGNO, i0); + calli((jit_word_t)__idiv); + movr(r0, _V0_REGNO); +} + +static jit_uword_t +__udiv(jit_uword_t u, jit_uword_t v) +{ + return (u / v); +} + +static void +_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + movr(_A0_REGNO, r1); + movr(_A1_REGNO, r2); + calli((jit_word_t)__udiv); + movr(r0, _V0_REGNO); +} + +static void +_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(_A0_REGNO, r1); + movi(_A1_REGNO, i0); + calli((jit_word_t)__udiv); + movr(r0, _V0_REGNO); +} + +static jit_word_t +__irem(jit_word_t u, jit_word_t v) +{ + return (u % v); +} + +static void +_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + movr(_A0_REGNO, r1); + movr(_A1_REGNO, r2); + calli((jit_word_t)__irem); + movr(r0, _V0_REGNO); +} + +static void +_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(_A0_REGNO, r1); + movi(_A1_REGNO, i0); + calli((jit_word_t)__irem); + movr(r0, _V0_REGNO); +} + +static jit_uword_t +__urem(jit_uword_t u, jit_uword_t v) +{ + return (u % v); +} + +static void +_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + movr(_A0_REGNO, r1); + movr(_A1_REGNO, r2); + calli((jit_word_t)__urem); + movr(r0, _V0_REGNO); +} + +static void +_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(_A0_REGNO, r1); + movi(_A1_REGNO, i0); + calli((jit_word_t)__urem); + movr(r0, _V0_REGNO); +} + +static jit_word_t +__idivrem(jit_word_t u, jit_word_t v, jit_word_t *rem) +{ + *rem = u % v; + return (u / v); +} + +static void +_qdivr(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + movr(_A0_REGNO, r2); + movr(_A1_REGNO, r3); + subi(_A2_REGNO, _FP_REGNO, 8); + calli((jit_word_t)__idivrem); + movr(r0, _V0_REGNO); + ldxi(r1, _FP_REGNO, -8); +} + +static void +_qdivi(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + movr(_A0_REGNO, r2); + movi(_A1_REGNO, i0); + subi(_A2_REGNO, _FP_REGNO, 8); + calli((jit_word_t)__idivrem); + movr(r0, _V0_REGNO); + ldxi(r1, _FP_REGNO, -8); +} + +static jit_word_t +__udivrem(jit_uword_t u, jit_uword_t v, jit_uword_t *rem) +{ + *rem = u % v; + return (u / v); +} + +static void +_qdivr_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + movr(_A0_REGNO, r2); + movr(_A1_REGNO, r3); + subi(_A2_REGNO, _FP_REGNO, 8); + calli((jit_word_t)__udivrem); + movr(r0, _V0_REGNO); + ldxi(r1, _FP_REGNO, -8); +} + +static void +_qdivi_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + movr(_A0_REGNO, r2); + movi(_A1_REGNO, i0); + subi(_A2_REGNO, _FP_REGNO, 8); + calli((jit_word_t)__udivrem); + movr(r0, _V0_REGNO); + ldxi(r1, _FP_REGNO, -8); +} + +static void +_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + assert(i0 >= 0 && i0 < 64); + SLLi(r1, i0, r0); +} + +static void +_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + assert(i0 >= 0 && i0 < 64); + SRAi(r1, i0, r0); +} + +static void +_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + assert(i0 >= 0 && i0 < 64); + SRLi(r1, i0, r0); +} + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + ANDi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + andr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + ORi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + orr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + XORi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + xorr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_lti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + CMPLTi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ltr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_lti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + CMPULTi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ltr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_lei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + CMPLEi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ler(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_lei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + jit_word_t ni0; + ni0 = -i0; + if (_u8_p(i0)) + CMPULEi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ler_u(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_eqi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + CMPEQi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + eqr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_gei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ger(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_gei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ger_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_gti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + gtr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_gti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + gtr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMPEQ(r1, r2, r0); + CMPEQi(r0, 0, r0); +} + +static void +_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) { + CMPEQi(r1, i0, r0); + CMPEQi(r0, 0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ner(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static jit_word_t +_bltr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + ltr(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_blti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BLT(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + lti(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bltr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + ltr_u(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_blti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + /* FIXME cannot optimize zero because need to return a patcheable address */ + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + lti_u(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bler(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + ler(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_blei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BLE(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + lei(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bler_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + ler_u(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_blei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BEQ(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + lei_u(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_beqr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + eqr(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_beqi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BEQ(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + eqi(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bger(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + ger(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bgei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BGE(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + gei(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bger_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + ger_u(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bgei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + /* always true if i1 == 0 */ + if (i0 == 0) { + w = _jit->pc.w; + BR(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + gei_u(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bgtr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + gtr(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bgti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BGT(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + gti(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bgtr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + gtr_u(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bgti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + gti_u(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bner(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + eqr(rn(reg), r0, r1); + w = _jit->pc.w; + BEQ(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bnei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BNE(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + eqi(rn(reg), r0, i1); + w = _jit->pc.w; + BEQ(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_baddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + jit_int32_t t3; + /* t0 = r0 + r1; overflow = r1 < 0 ? r0 < t0 : t0 < r0 */ + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr); + t2 = jit_get_reg(jit_class_gpr); + t3 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addr(rn(t0), r0, r1); /* t0 = r0 + r1 */ + ltr(rn(t1), r1, _R31_REGNO); /* t1 = r1 < 0 */ + ltr(rn(t2), r0, rn(t0)); /* t2 = r0 < t0 */ + ltr(rn(t3), rn(t0), r0); /* t3 = t0 < r0 */ + movr(r0, rn(t0)); /* r0 += r1 */ + CMOVNE(rn(t1), rn(t2), rn(t3)); /* if (t1 == 0) t3 = t2; */ + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + w = _jit->pc.w; + if (carry) + BNE(rn(t3), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t3), ((i0 - w) >> 2) - 1); + jit_unget_reg(t3); + return (w); +} + +static jit_word_t +_baddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = baddr(i0, r0, rn(reg), carry); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_baddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addr(rn(t0), r0, r1); + ltr_u(rn(t1), rn(t0), r0); + movr(r0, rn(t0)); + jit_unget_reg(t0); + w = _jit->pc.w; + if (carry) + BNE(rn(t1), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t1), ((i0 - w) >> 2) - 1); + jit_unget_reg(t1); + return (w); +} + +static jit_word_t +_baddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addi(rn(t0), r0, i1); + ltr_u(rn(t1), rn(t0), r0); + movr(r0, rn(t0)); + jit_unget_reg(t0); + w = _jit->pc.w; + if (carry) + BNE(rn(t1), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t1), ((i0 - w) >> 2) - 1); + jit_unget_reg(t1); + return (w); +} + +static jit_word_t +_bsubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + jit_int32_t t3; + /* t0 = r0 - r1; overflow = 0 < r1 ? r0 < t0 : t0 < r0 */ + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr); + t2 = jit_get_reg(jit_class_gpr); + t3 = jit_get_reg(jit_class_gpr|jit_class_nospill); + subr(rn(t0), r0, r1); /* r0 = r0 - r1 */ + ltr(rn(t1), _R31_REGNO, r1); /* t1 = 0 < r1 */ + ltr(rn(t2), r0, rn(t0)); /* t2 = r0 < t0 */ + ltr(rn(t3), rn(t0), r0); /* t3 = t0 < r0 */ + movr(r0, rn(t0)); /* r0 -= r1 */ + CMOVNE(rn(t1), rn(t2), rn(t3)); /* if (t1 == 0) t3 = t2; */ + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + w = _jit->pc.w; + if (carry) + BNE(rn(t3), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t3), ((i0 - w) >> 2) - 1); + jit_unget_reg(t3); + return (w); +} + +static jit_word_t +_bsubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bsubr(i0, r0, rn(reg), carry); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bsubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + subr(rn(t0), r0, r1); + ltr_u(rn(t1), r0, rn(t0)); + movr(r0, rn(t0)); + jit_unget_reg(t0); + w = _jit->pc.w; + if (carry) + BNE(rn(t1), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t1), ((i0 - w) >> 2) - 1); + jit_unget_reg(t1); + return (w); +} + +static jit_word_t +_bsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + subi(rn(t0), r0, i1); + ltr_u(rn(t1), r0, rn(t0)); + movr(r0, rn(t0)); + jit_unget_reg(t0); + w = _jit->pc.w; + if (carry) + BNE(rn(t1), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t1), ((i0 - w) >> 2) - 1); + jit_unget_reg(t1); + return (w); +} + +static jit_word_t +_bmxr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t set) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + andr(rn(t0), r0, r1); + w = _jit->pc.w; + if (set) + BNE(rn(t0), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t0), ((i0 - w) >> 2) - 1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bmxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t set) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + andi(rn(t0), r0, i1); + w = _jit->pc.w; + if (set) + BNE(rn(t0), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t0), ((i0 - w) >> 2) - 1); + jit_unget_reg(t0); + return (w); +} + +static void +_ldr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + ldr_uc(r0, r1); + extr_c(r0, r0); +} + +static void +_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) { + LDBU(r0, _R31_REGNO, _u16(i0)); + extr_c(r0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDBU(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + ldr_us(r0, r1); + extr_s(r0, r0); +} + +static void +_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) { + LDWU(r0, _R31_REGNO, _u16(i0)); + extr_s(r0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDWU(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDL(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + ldr_i(r0, r1); + extr_ui(r0, r0); +} + +static void +_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) { + LDL(r0, _R31_REGNO, _u16(i0)); + extr_ui(r0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDQ(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) { + LDBU(r0, r1, _u16(i0)); + extr_c(r0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDBU(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) { + LDWU(r0, r1, _u16(i0)); + extr_s(r0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDWU(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDL(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) { + LDL(r0, r1, _u16(i0)); + extr_ui(r0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDQ(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STB(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_c(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STW(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_s(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STL(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_i(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STQ(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_l(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_c(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STB(r1, r0, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_c(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_s(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STW(r1, r0, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_s(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_i(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STL(r1, r0, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_i(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_l(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STQ(r1, r0, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_l(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_extr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 56); + rshi(r0, r0, 56); +} + +static void +_extr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 56); + rshi_u(r0, r0, 56); +} + +static void +_extr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 48); + rshi(r0, r0, 48); +} + +static void +_extr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 48); + rshi_u(r0, r0, 48); +} + +static void +_extr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 32); + rshi(r0, r0, 32); +} + +static void +_extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 32); + rshi_u(r0, r0, 32); +} + +static void +_htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + EXTBLi(r1, 0, rn(t0)); + EXTBLi(r1, 1, r0); + SLLi(rn(t0), 8, rn(t0)); + OR(r0, rn(t0), r0); + jit_unget_reg(t0); +} + +static void +_htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + jit_int32_t t3; + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr); + t2 = jit_get_reg(jit_class_gpr); + t3 = jit_get_reg(jit_class_gpr); + EXTBLi(r1, 3, rn(t0)); + INSBLi(r1, 3, rn(t1)); + SLLi(r1, 8, rn(t2)); + ZAPNOTi(rn(t2), 4, rn(t2)); + SRLi(r1, 8, rn(t3)); + OR(rn(t0), rn(t1), r0); + OR(rn(t2), r0, r0); + ZAPNOTi(rn(t3), 2, rn(t3)); + OR(rn(t3), r0, r0); + jit_unget_reg(t3); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); +} + +static void +_htonr_ul(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + assert(_jitc->function != NULL); + t0 = jit_get_reg(jit_class_fpr); + t1 = jit_get_reg(jit_class_gpr); + t2 = jit_get_reg(jit_class_gpr); + stxi(-8, _FP_REGNO, r1); /* r1 = ABCD EFGH */ + LDG(rn(t0), _FP_REGNO, _u16(-8)); /* t0 = GHEF CDAB */ + STT(rn(t0), _FP_REGNO, _u16(-8)); + ldxi(rn(t1), _FP_REGNO, -8); /* t1 = GHEF CDAB */ + lshi(rn(t2), rn(t1), 8); /* t2 = HEFC DAB. */ + rshi_u(rn(t1), rn(t1), 8); /* t1 = .GHE FCDA */ + ZAPi(rn(t2), 0x55, rn(t2)); /* t2 = H.F. D.B. */ + ZAPi(rn(t1), 0xaa, rn(t1)); /* t1 = .G.E .C.A */ + orr(r0, rn(t1), rn(t2)); /* r0 = HGFE DCBA */ + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); +} + +static void +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_word_t d; + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 1; + if (_s21_p(d)) + BR(_R31_REGNO, d); + else + (void)jmpi_p(i0); +} + +static jit_word_t +_jmpi_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + w = movi_p(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_callr(jit_state_t *_jit, jit_int32_t r0) +{ + if (r0 != _PV_REGNO) + MOV(r0, _PV_REGNO); + JSR(_RA_REGNO, _PV_REGNO, 0); +} + +static void +_calli(jit_state_t *_jit, jit_word_t i0) +{ + /* FIXME use a small buffer to load constants - using gp */ +#if 0 + jit_word_t w; + jit_word_t d; + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 1; + if (_s21_p(d)) + BSR(_RA_REGNO, d); + else + (void)calli_p(i0); +#else + movi(_PV_REGNO, i0); + callr(_PV_REGNO); +#endif +} + +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + w = movi_p(_PV_REGNO, i0); + callr(_PV_REGNO); + return (w); +} + +static void +_prolog(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t reg; + if (_jitc->function->define_frame || _jitc->function->assume_frame) { + jit_int32_t frame = -_jitc->function->frame; + assert(_jitc->function->self.aoff >= frame); + if (_jitc->function->assume_frame) + return; + _jitc->function->self.aoff = frame; + } + if (_jitc->function->allocar) + _jitc->function->self.aoff &= -8; + _jitc->function->stack = ((_jitc->function->self.alen - + _jitc->function->self.aoff) + 7) & -8; + /* ldgp gp, 0(pv) */ + LDAH(_PV_REGNO, _GP_REGNO, 0); + LDA(_GP_REGNO, _GP_REGNO, 0); + /* callee save registers */ + subi(_SP_REGNO, _SP_REGNO, stack_framesize); + stxi(0, _SP_REGNO, _RA_REGNO); + stxi(8, _SP_REGNO, _FP_REGNO); +# define SPILL(N, O) \ + if (jit_regset_tstbit(&_jitc->function->regset, N)) \ + stxi(O, _SP_REGNO, N##_REGNO) +# define SPILLD(N, O) \ + if (jit_regset_tstbit(&_jitc->function->regset, N)) \ + stxi_d(O, _SP_REGNO, N##_REGNO) + SPILL(_S0, 16); + SPILL(_S1, 24); + SPILL(_S2, 32); + SPILL(_S3, 40); + SPILL(_S4, 48); + SPILL(_S5, 56); + SPILLD(_F2, 64); + SPILLD(_F3, 72); + SPILLD(_F4, 80); + SPILLD(_F5, 88); + SPILLD(_F6, 96); + SPILLD(_F7, 104); + SPILLD(_F8, 112); + SPILLD(_F9, 120); +# undef SPILLD +# undef SPILL + movr(_FP_REGNO, _SP_REGNO); + /* alloca */ + if (_jitc->function->stack) + subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack); + if (_jitc->function->allocar) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), _jitc->function->self.aoff); + stxi_i(_jitc->function->aoffoff, _FP_REGNO, rn(reg)); + jit_unget_reg(reg); + } + + if (_jitc->function->self.call & jit_call_varargs) { + for (reg = _jitc->function->self.argi; jit_arg_reg_p(reg); ++reg) + stxi(stack_framesize - 48 + reg * 8, _FP_REGNO, rn(_A0 - reg)); + for (reg = _jitc->function->self.argi; jit_arg_reg_p(reg); ++reg) + stxi_d(stack_framesize - 96 + reg * 8, _FP_REGNO, rn(_F16 - reg)); + } +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *node) +{ + if (_jitc->function->assume_frame) + return; + movr(_SP_REGNO, _FP_REGNO); + ldxi(_RA_REGNO, _SP_REGNO, 0); + ldxi(_FP_REGNO, _SP_REGNO, 8); +# define LOAD(N, O) \ + if (jit_regset_tstbit(&_jitc->function->regset, N)) \ + ldxi(N##_REGNO, _SP_REGNO, O) +# define LOADD(N, O) \ + if (jit_regset_tstbit(&_jitc->function->regset, N)) \ + ldxi_d(N##_REGNO, _SP_REGNO, O) + LOAD(_S0, 16); + LOAD(_S1, 24); + LOAD(_S2, 32); + LOAD(_S3, 40); + LOAD(_S4, 48); + LOAD(_S5, 56); + LOADD(_F2, 64); + LOADD(_F3, 72); + LOADD(_F4, 80); + LOADD(_F5, 88); + LOADD(_F6, 96); + LOADD(_F7, 104); + LOADD(_F8, 112); + LOADD(_F9, 120); +# undef LOADD +# undef LOAD + addi(_SP_REGNO, _SP_REGNO, stack_framesize); + RET(_R31_REGNO, _RA_REGNO, 1); /* 1 means procedure return + * 0 means no procedure return + * other values are reserved */ +} + +static void +_vastart(jit_state_t *_jit, jit_int32_t r0) +{ + jit_int32_t reg; + + /* Return jit_va_list_t in the register argument */ + addi(r0, _FP_REGNO, _jitc->function->vaoff); + + reg = jit_get_reg(jit_class_gpr); + + /* The base field is constant. */ + addi(rn(reg), _FP_REGNO, stack_framesize - 48); + stxi(offsetof(jit_va_list_t, base), r0, rn(reg)); + + /* Initialize the offset field */ + if (_jitc->function->vagp < 6) + movi(rn(reg), _jitc->function->vagp * 8); + else + movi(rn(reg), _jitc->function->self.size - (stack_framesize - 48)); + stxi(offsetof(jit_va_list_t, offset), r0, rn(reg)); + + jit_unget_reg(reg); +} + +static void +_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t rg0, rg1; + + assert(_jitc->function->self.call & jit_call_varargs); + + rg0 = jit_get_reg(jit_class_gpr); + rg1 = jit_get_reg(jit_class_gpr); + + /* Load the base in first temporary. */ + ldxi(rn(rg0), r1, offsetof(jit_va_list_t, base)); + + /* Load the offset in the second temporary. */ + ldxi(rn(rg1), r1, offsetof(jit_va_list_t, offset)); + + /* Load the argument */ + ldxr(r0, rn(rg0), rn(rg1)); + + /* No longer needed. */ + jit_unget_reg(rg0); + + /* Update offset. */ + addi(rn(rg1), rn(rg1), 8); + stxi(offsetof(jit_va_list_t, offset), r1, rn(rg1)); + jit_unget_reg(rg1); +} + +static void +_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label) +{ + union { + jit_int32_t *i; + jit_word_t w; + } u; + jit_word_t d; + jit_int16_t s0, s1, s2, s3; + u.w = instr; + switch (_u6(u.i[0] >> 26)) { + /* BLT BLE BEQ BGE */ + case 0x3a: case 0x3b: case 0x39: case 0x3e: + /* BGT BNE BLBC BLBS */ + case 0x3f: case 0x3d: case 0x38: case 0x3c: + /* BR BSR */ + case 0x30: case 0x34: + /* FBLT FBLE FBEQ FBGE */ + case 0x32: case 0x33: case 0x31: case 0x36: + /* FBGT FBNE */ + case 0x37: case 0x35: + d = ((label - instr) >> 2) - 1; + assert(_s21_p(d)); + u.i[0] &= ~0x1fffff; + u.i[0] |= _u21(d); + break; + /* LDA */ + case 0x08: /* movi_p */ + s0 = label; + s1 = label >> 16; + s2 = label >> 32; + s3 = label >> 48; + if (s0 < 0) + ++s1; + if (s2 < 0) + ++s3; + u.i[0] &= ~0xffff; + u.i[0] |= _u16(s0); + /* LDA */ + assert(_u6(u.i[1] >> 26) == 0x08); + u.i[1] &= ~0xffff; + u.i[1] |= _u16(s2); + /* LDAH */ + assert(_u6(u.i[2] >> 26) == 0x09); + u.i[2] &= ~0xffff; + u.i[2] |= _u16(s1); + /* LDAH */ + assert(_u6(u.i[3] >> 26) == 0x09); + u.i[3] &= ~0xffff; + u.i[3] |= _u16(s3); + /* SLL */ + assert(_u6(u.i[4] >> 26) == 0x12 && _u7(u.i[4] >> 5) == 0x39); + /* SRL */ + assert(_u6(u.i[5] >> 26) == 0x12 && _u7(u.i[5] >> 5) == 0x34); + /* SLL */ + assert(_u6(u.i[6] >> 26) == 0x12 && _u7(u.i[6] >> 5) == 0x39); + /* BIS */ + assert(_u6(u.i[7] >> 26) == 0x11 && _u7(u.i[7] >> 5) == 0x20); + break; + default: + abort(); + } +} +#endif diff --git a/deps/lightning/lib/jit_alpha-fpu.c b/deps/lightning/lib/jit_alpha-fpu.c new file mode 100644 index 0000000..ea5c746 --- /dev/null +++ b/deps/lightning/lib/jit_alpha-fpu.c @@ -0,0 +1,1588 @@ +/* + * Copyright (C) 2014-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# define _F2_REGNO 0x02 +# define _F3_REGNO 0x03 +# define _F4_REGNO 0x04 +# define _F5_REGNO 0x05 +# define _F6_REGNO 0x06 +# define _F7_REGNO 0x07 +# define _F8_REGNO 0x08 +# define _F9_REGNO 0x09 +# define F_P(o,ra,rb,f,rc) _Opr(_jit,o,ra,rb,f,rc) +static void _Opr(jit_state_t*,int,int,int,unsigned int,int); +# define ADDF(ra,rb,rc) F_P(0x15,ra,rb,0x080,rc) +# define ADDG(ra,rb,rc) F_P(0x15,ra,rb,0x0a0,rc) +# define ADDS(ra,rb,rc) F_P(0x16,ra,rb,0x080,rc) +# define ADDS_C(ra,rb,rc) F_P(0x16,ra,rb,0x000,rc) +# define ADDS_M(ra,rb,rc) F_P(0x16,ra,rb,0x040,rc) +# define ADDS_D(ra,rb,rc) F_P(0x16,ra,rb,0x0c0,rc) +# define ADDS_U(ra,rb,rc) F_P(0x16,ra,rb,0x180,rc) +# define ADDS_UC(ra,rb,rc) F_P(0x16,ra,rb,0x100,rc) +# define ADDS_UM(ra,rb,rc) F_P(0x16,ra,rb,0x140,rc) +# define ADDS_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1c0,rc) +# define ADDS_SU(ra,rb,rc) F_P(0x16,ra,rb,0x580,rc) +# define ADDS_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x500,rc) +# define ADDS_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x540,rc) +# define ADDS_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5c0,rc) +# define ADDS_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x780,rc) +# define ADDS_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x700,rc) +# define ADDS_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x740,rc) +# define ADDS_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7c0,rc) +# define ADDT(ra,rb,rc) F_P(0x16,ra,rb,0x0a0,rc) +# define ADDT_C(ra,rb,rc) F_P(0x16,ra,rb,0x020,rc) +# define ADDT_M(ra,rb,rc) F_P(0x16,ra,rb,0x060,rc) +# define ADDT_D(ra,rb,rc) F_P(0x16,ra,rb,0x0e0,rc) +# define ADDT_U(ra,rb,rc) F_P(0x16,ra,rb,0x1a0,rc) +# define ADDT_UC(ra,rb,rc) F_P(0x16,ra,rb,0x120,rc) +# define ADDT_UM(ra,rb,rc) F_P(0x16,ra,rb,0x160,rc) +# define ADDT_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1e0,rc) +# define ADDT_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a0,rc) +# define ADDT_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x520,rc) +# define ADDT_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x560,rc) +# define ADDT_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5e0,rc) +# define ADDT_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x7a0,rc) +# define ADDT_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x720,rc) +# define ADDT_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x760,rc) +# define ADDT_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7e0,rc) +# define CMPGEQ(ra,rb,rc) F_P(0x15,ra,rb,0x0a5,rc) +# define CMPGLE(ra,rb,rc) F_P(0x15,ra,rb,0x0a7,rc) +# define CMPTEQ(ra,rb,rc) F_P(0x16,ra,rb,0x0a5,rc) +# define CMPTEQ_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a5,rc) +# define CMPTLE(ra,rb,rc) F_P(0x16,ra,rb,0x0a7,rc) +# define CMPTLE_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a7,rc) +# define CMPTLT(ra,rb,rc) F_P(0x16,ra,rb,0x0a6,rc) +# define CMPTLT_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a6,rc) +# define CMPTUN(ra,rb,rc) F_P(0x16,ra,rb,0x0a4,rc) +# define CMPTUN_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a4,rc) +# define CPYS(ra,rb,rc) F_P(0x17,ra,rb,0x020,rc) +# define CPYSE(ra,rb,rc) F_P(0x17,ra,rb,0x022,rc) +# define CPYSN(ra,rb,rc) F_P(0x17,ra,rb,0x021,rc) +# define DIVF(ra,rb,rc) F_P(0x15,ra,rb,0x083,rc) +# define DIVG(ra,rb,rc) F_P(0x15,ra,rb,0x0a3,rc) +# define DIVS(ra,rb,rc) F_P(0x16,ra,rb,0x083,rc) +# define DIVS_C(ra,rb,rc) F_P(0x16,ra,rb,0x003,rc) +# define DIVS_M(ra,rb,rc) F_P(0x16,ra,rb,0x043,rc) +# define DIVS_D(ra,rb,rc) F_P(0x16,ra,rb,0x0c3,rc) +# define DIVS_U(ra,rb,rc) F_P(0x16,ra,rb,0x183,rc) +# define DIVS_UC(ra,rb,rc) F_P(0x16,ra,rb,0x103,rc) +# define DIVS_UM(ra,rb,rc) F_P(0x16,ra,rb,0x143,rc) +# define DIVS_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1c3,rc) +# define DIVS_SU(ra,rb,rc) F_P(0x16,ra,rb,0x583,rc) +# define DIVS_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x503,rc) +# define DIVS_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x543,rc) +# define DIVS_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5c3,rc) +# define DIVS_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x783,rc) +# define DIVS_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x703,rc) +# define DIVS_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x743,rc) +# define DIVS_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7c3,rc) +# define DIVT(ra,rb,rc) F_P(0x16,ra,rb,0x0a3,rc) +# define DIVT_C(ra,rb,rc) F_P(0x16,ra,rb,0x023,rc) +# define DIVT_M(ra,rb,rc) F_P(0x16,ra,rb,0x063,rc) +# define DIVT_D(ra,rb,rc) F_P(0x16,ra,rb,0x0e3,rc) +# define DIVT_U(ra,rb,rc) F_P(0x16,ra,rb,0x1a3,rc) +# define DIVT_UC(ra,rb,rc) F_P(0x16,ra,rb,0x123,rc) +# define DIVT_UM(ra,rb,rc) F_P(0x16,ra,rb,0x163,rc) +# define DIVT_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1e3,rc) +# define DIVT_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a3,rc) +# define DIVT_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x523,rc) +# define DIVT_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x563,rc) +# define DIVT_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5e3,rc) +# define DIVT_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x7a3,rc) +# define DIVT_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x723,rc) +# define DIVT_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x7a3,rc) +# define DIVT_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7e3,rc) +# define CVTDG(rb,rc) F_P(0x15,_R31_REGNO,rb,0x09e,rc) +# define CVTGD(rb,rc) F_P(0x15,_R31_REGNO,rb,0x0ad,rc) +# define CVTGF(rb,rc) F_P(0x15,_R31_REGNO,rb,0x0ac,rc) +# define CVTGQ(rb,rc) F_P(0x15,_R31_REGNO,rb,0x0af,rc) +# define CVTLQ(rb,rc) F_P(0x17,_R31_REGNO,rb,0x010,rc) +# define CVTQF(rb,rc) F_P(0x15,_R31_REGNO,rb,0x0bc,rc) +# define CVTQG(rb,rc) F_P(0x15,_R31_REGNO,rb,0x0be,rc) +# define CVTQL(rb,rc) F_P(0x17,_R31_REGNO,rb,0x030,rc) +# define CVTQS(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0bc,rc) +# define CVTQS_C(rb,rc) F_P(0x16,_R31_REGNO,rb,0x03c,rc) +# define CVTQS_M(rb,rc) F_P(0x16,_R31_REGNO,rb,0x07c,rc) +# define CVTQS_D(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0fc,rc) +# define CVTQS_SUI(rb,rc) F_P(0x16,_R31_REGNO,rb,0x7bc,rc) +# define CVTQS_SUIC(rb,rc) F_P(0x16,_R31_REGNO,rb,0x73c,rc) +# define CVTQS_SUIM(rb,rc) F_P(0x16,_R31_REGNO,rb,0x77c,rc) +# define CVTQS_SUID(rb,rc) F_P(0x16,_R31_REGNO,rb,0x7fc,rc) +# define CVTQT(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0be,rc) +# define CVTQT_C(rb,rc) F_P(0x16,_R31_REGNO,rb,0x03e,rc) +# define CVTQT_M(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0te,rc) +# define CVTQT_D(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0fe,rc) +# define CVTQT_SUI(rb,rc) F_P(0x16,_R31_REGNO,rb,0x7be,rc) +# define CVTQT_SUIC(rb,rc) F_P(0x16,_R31_REGNO,rb,0x73e,rc) +# define CVTQT_SUIM(rb,rc) F_P(0x16,_R31_REGNO,rb,0x77e,rc) +# define CVTQT_SUID(rb,rc) F_P(0x16,_R31_REGNO,rb,0x7fe,rc) +# define CVTST(rb,rc) F_P(0x16,_R31_REGNO,rb,0x2ac,rc) +# define CVTST_S(rb,rc) F_P(0x16,_R31_REGNO,rb,0x6ac,rc) +# define CVTTQ(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0af,rc) +# define CVTTQ_C(rb,rc) F_P(0x16,_R31_REGNO,rb,0x02f,rc) +# define CVTTQ_V(rb,rc) F_P(0x16,_R31_REGNO,rb,0x1af,rc) +# define CVTTQ_VC(rb,rc) F_P(0x16,_R31_REGNO,rb,0x12f,rc) +# define CVTTQ_SV(rb,rc) F_P(0x16,_R31_REGNO,rb,0x5af,rc) +# define CVTTQ_SVC(rb,rc) F_P(0x16,_R31_REGNO,rb,0x52f,rc) +# define CVTTQ_SVI(rb,rc) F_P(0x16,_R31_REGNO,rb,0x7af,rc) +# define CVTTQ_SVIC(rb,rc) F_P(0x16,_R31_REGNO,rb,0x72f,rc) +# define CVTTQ_D(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0ef,rc) +# define CVTTQ_VD(rb,rc) F_P(0x16,_R31_REGNO,rb,0x1ef,rc) +# define CVTTQ_SVD(rb,rc) F_P(0x16,_R31_REGNO,rb,0x5ef,rc) +# define CVTTQ_SVID(rb,rc) F_P(0x16,_R31_REGNO,rb,0x7ef,rc) +# define CVTTQ_M(rb,rc) F_P(0x16,_R31_REGNO,rb,0x06f,rc) +# define CVTTQ_VM(rb,rc) F_P(0x16,_R31_REGNO,rb,0x16f,rc) +# define CVTTQ_SVM(rb,rc) F_P(0x16,_R31_REGNO,rb,0x56f,rc) +# define CVTTQ_SVIM(rb,rc) F_P(0x16,_R31_REGNO,rb,0x76f,rc) +# define CVTTS(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0ac,rc) +# define CVTTS_C(rb,rc) F_P(0x16,_R31_REGNO,rb,0x02c,rc) +# define CVTTS_M(rb,rc) F_P(0x16,_R31_REGNO,rb,0x06c,rc) +# define CVTTS_D(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0ec,rc) +# define CVTTS_U(rb,rc) F_P(0x16,_R31_REGNO,rb,0x1ac,rc) +# define CVTTS_UC(rb,rc) F_P(0x16,_R31_REGNO,rb,0x12c,rc) +# define CVTTS_UM(rb,rc) F_P(0x16,_R31_REGNO,rb,0x16c,rc) +# define CVTTS_UD(rb,rc) F_P(0x16,_R31_REGNO,rb,0x1ec,rc) +# define FBEQ(ra,d) Bra(0x31,ra,d) +# define FBGE(ra,d) Bra(0x36,ra,d) +# define FBGT(ra,d) Bra(0x37,ra,d) +# define FBLE(ra,d) Bra(0x33,ra,d) +# define FBLT(ra,d) Bra(0x32,ra,d) +# define FBNE(ra,d) Bra(0x35,ra,d) +# define FCMOVEQ(ra,rb,rc) F_P(0x17,ra,rb,0x02a,rc) +# define FCMOVGE(ra,rb,rc) F_P(0x17,ra,rb,0x02d,rc) +# define FCMOVGT(ra,rb,rc) F_P(0x17,ra,rb,0x02f,rc) +# define FCMOVLE(ra,rb,rc) F_P(0x17,ra,rb,0x02e,rc) +# define FCMOVLT(ra,rb,rc) F_P(0x17,ra,rb,0x02c,rc) +# define FCMOVNE(ra,rb,rc) F_P(0x17,ra,rb,0x02b,rc) +# define FTOIS(ra,rc) F_P(0x1c,ra,_R31_REGNO,0x078,rc) +# define FTOIT(ra,rc) F_P(0x1c,ra,_R31_REGNO,0x070,rc) +# define ITOFF(ra,rc) F_P(0x14,ra,_R31_REGNO,0x014,rc) +# define ITOFS(ra,rc) F_P(0x14,ra,_R31_REGNO,0x004,rc) +# define ITOFT(ra,rc) F_P(0x14,ra,_R31_REGNO,0x024,rc) +# define LDF(ra,rb,d) Mem(0x20,ra,rb,d) +# define LDG(ra,rb,d) Mem(0x21,ra,rb,d) +# define LDS(ra,rb,d) Mem(0x22,ra,rb,d) +# define LDT(ra,rb,d) Mem(0x23,ra,rb,d) +# define MF_FPCR(ra) F_P(0x17,ra,ra,0x025,ra) +# define MT_FPCR(ra) F_P(0x17,ra,ra,0x024,ra) +# define MULF(ra,rb,rc) F_P(0x15,ra,rb,0x082,rc) +# define MULG(ra,rb,rc) F_P(0x15,ra,rb,0x0a2,rc) +# define MULS(ra,rb,rc) F_P(0x16,ra,rb,0x082,rc) +# define MULS_C(ra,rb,rc) F_P(0x16,ra,rb,0x002,rc) +# define MULS_M(ra,rb,rc) F_P(0x16,ra,rb,0x042,rc) +# define MULS_D(ra,rb,rc) F_P(0x16,ra,rb,0x0c2,rc) +# define MULS_U(ra,rb,rc) F_P(0x16,ra,rb,0x182,rc) +# define MULS_UC(ra,rb,rc) F_P(0x16,ra,rb,0x102,rc) +# define MULS_UM(ra,rb,rc) F_P(0x16,ra,rb,0x142,rc) +# define MULS_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1c2,rc) +# define MULS_SU(ra,rb,rc) F_P(0x16,ra,rb,0x582,rc) +# define MULS_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x502,rc) +# define MULS_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x642,rc) +# define MULS_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5c2,rc) +# define MULS_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x782,rc) +# define MULS_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x702,rc) +# define MULS_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x742,rc) +# define MULS_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7c2,rc) +# define MULT(ra,rb,rc) F_P(0x16,ra,rb,0x0a2,rc) +# define MULT_C(ra,rb,rc) F_P(0x16,ra,rb,0x022,rc) +# define MULT_M(ra,rb,rc) F_P(0x16,ra,rb,0x062,rc) +# define MULT_D(ra,rb,rc) F_P(0x16,ra,rb,0x0e2,rc) +# define MULT_U(ra,rb,rc) F_P(0x16,ra,rb,0x1a2,rc) +# define MULT_UC(ra,rb,rc) F_P(0x16,ra,rb,0x122,rc) +# define MULT_UM(ra,rb,rc) F_P(0x16,ra,rb,0x162,rc) +# define MULT_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1e2,rc) +# define MULT_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a2,rc) +# define MULT_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x522,rc) +# define MULT_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x562,rc) +# define MULT_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5e2,rc) +# define MULT_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x7a2,rc) +# define MULT_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x722,rc) +# define MULT_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x762,rc) +# define MULT_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7e2,rc) +# define SQRTF(rb,rc) F_P(0x14,_R31_REGNO,rb,0x08a,rc) +# define SQRTG(rb,rc) F_P(0x14,_R31_REGNO,rb,0x0aa,rc) +# define SQRTS(rb,rc) F_P(0x14,_R31_REGNO,rb,0x08b,rc) +# define SQRTS_C(rb,rc) F_P(0x14,_R31_REGNO,rb,0x00b,rc) +# define SQRTS_M(rb,rc) F_P(0x14,_R31_REGNO,rb,0x04b,rc) +# define SQRTS_D(rb,rc) F_P(0x14,_R31_REGNO,rb,0x0cb,rc) +# define SQRTS_U(rb,rc) F_P(0x14,_R31_REGNO,rb,0x18b,rc) +# define SQRTS_UC(rb,rc) F_P(0x14,_R31_REGNO,rb,0x10b,rc) +# define SQRTS_UM(rb,rc) F_P(0x14,_R31_REGNO,rb,0x14b,rc) +# define SQRTS_UD(rb,rc) F_P(0x14,_R31_REGNO,rb,0x1cb,rc) +# define SQRTS_SU(rb,rc) F_P(0x14,_R31_REGNO,rb,0x58b,rc) +# define SQRTS_SUC(rb,rc) F_P(0x14,_R31_REGNO,rb,0x50b,rc) +# define SQRTS_SUM(rb,rc) F_P(0x14,_R31_REGNO,rb,0x54b,rc) +# define SQRTS_SUD(rb,rc) F_P(0x14,_R31_REGNO,rb,0x5cb,rc) +# define SQRTS_SUI(rb,rc) F_P(0x14,_R31_REGNO,rb,0x78b,rc) +# define SQRTS_SUIC(rb,rc) F_P(0x14,_R31_REGNO,rb,0x70b,rc) +# define SQRTS_SUIM(rb,rc) F_P(0x14,_R31_REGNO,rb,0x74b,rc) +# define SQRTS_SUID(rb,rc) F_P(0x14,_R31_REGNO,rb,0x7cb,rc) +# define SQRTT(rb,rc) F_P(0x14,_R31_REGNO,rb,0x0ab,rc) +# define SQRTT_C(rb,rc) F_P(0x14,_R31_REGNO,rb,0x02b,rc) +# define SQRTT_M(rb,rc) F_P(0x14,_R31_REGNO,rb,0x06b,rc) +# define SQRTT_D(rb,rc) F_P(0x14,_R31_REGNO,rb,0x0eb,rc) +# define SQRTT_U(rb,rc) F_P(0x14,_R31_REGNO,rb,0x1ab,rc) +# define SQRTT_UC(rb,rc) F_P(0x14,_R31_REGNO,rb,0x12b,rc) +# define SQRTT_UM(rb,rc) F_P(0x14,_R31_REGNO,rb,0x16b,rc) +# define SQRTT_UD(rb,rc) F_P(0x14,_R31_REGNO,rb,0x1eb,rc) +# define SQRTT_SU(rb,rc) F_P(0x14,_R31_REGNO,rb,0x5ab,rc) +# define SQRTT_SUC(rb,rc) F_P(0x14,_R31_REGNO,rb,0x52b,rc) +# define SQRTT_SUM(rb,rc) F_P(0x14,_R31_REGNO,rb,0x56b,rc) +# define SQRTT_SUD(rb,rc) F_P(0x14,_R31_REGNO,rb,0x5eb,rc) +# define SQRTT_SUI(rb,rc) F_P(0x14,_R31_REGNO,rb,0x7ab,rc) +# define SQRTT_SUIC(rb,rc) F_P(0x14,_R31_REGNO,rb,0x72b,rc) +# define SQRTT_SUIM(rb,rc) F_P(0x14,_R31_REGNO,rb,0x76b,rc) +# define SQRTT_SUID(rb,rc) F_P(0x14,_R31_REGNO,rb,0x7eb,rc) +# define STF(ra,rb,d) Mem(0x24,ra,rb,d) +# define STG(ra,rb,d) Mem(0x25,ra,rb,d) +# define STS(ra,rb,d) Mem(0x26,ra,rb,d) +# define STT(ra,rb,d) Mem(0x27,ra,rb,d) +# define SUBF(ra,rb,rc) F_P(0x15,ra,rb,0x081,rc) +# define SUBG(ra,rb,rc) F_P(0x15,ra,rb,0x0a1,rc) +# define SUBS(ra,rb,rc) F_P(0x16,ra,rb,0x081,rc) +# define SUBS_C(ra,rb,rc) F_P(0x16,ra,rb,0x001,rc) +# define SUBS_M(ra,rb,rc) F_P(0x16,ra,rb,0x041,rc) +# define SUBS_D(ra,rb,rc) F_P(0x16,ra,rb,0x0c1,rc) +# define SUBS_U(ra,rb,rc) F_P(0x16,ra,rb,0x181,rc) +# define SUBS_UC(ra,rb,rc) F_P(0x16,ra,rb,0x101,rc) +# define SUBS_UM(ra,rb,rc) F_P(0x16,ra,rb,0x141,rc) +# define SUBS_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1c1,rc) +# define SUBS_SU(ra,rb,rc) F_P(0x16,ra,rb,0x581,rc) +# define SUBS_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x501,rc) +# define SUBS_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x541,rc) +# define SUBS_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5c1,rc) +# define SUBS_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x781,rc) +# define SUBS_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x701,rc) +# define SUBS_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x741,rc) +# define SUBS_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7c1,rc) +# define SUBT(ra,rb,rc) F_P(0x16,ra,rb,0x0a1,rc) +# define SUBT_C(ra,rb,rc) F_P(0x16,ra,rb,0x021,rc) +# define SUBT_M(ra,rb,rc) F_P(0x16,ra,rb,0x061,rc) +# define SUBT_D(ra,rb,rc) F_P(0x16,ra,rb,0x0e1,rc) +# define SUBT_U(ra,rb,rc) F_P(0x16,ra,rb,0x1a1,rc) +# define SUBT_UC(ra,rb,rc) F_P(0x16,ra,rb,0x121,rc) +# define SUBT_UM(ra,rb,rc) F_P(0x16,ra,rb,0x161,rc) +# define SUBT_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1e1,rc) +# define SUBT_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a1,rc) +# define SUBT_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x521,rc) +# define SUBT_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x561,rc) +# define SUBT_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5e1,rc) +# define SUBT_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x7a1,rc) +# define SUBT_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x721,rc) +# define SUBT_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x761,rc) +# define SUBT_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7e1,rc) +# define FABS(ra,rc) CPYS(_R31_REGNO,ra,rc) +# define FMOV(ra,rc) CPYS(ra,ra,rc) +# define NEGF(ra,rc) SUBF(_R31_REGNO,ra,rc) +# define NEGG(ra,rc) SUBG(_R31_REGNO,ra,rc) +# define NEGS(ra,rc) SUBS(_R31_REGNO,ra,rc) +# define NEGT(ra,rc) SUBT(_R31_REGNO,ra,rc) +# define FNEGF(ra,rc) CPYSN(ra,ra,rc) +# define FNEGG(ra,rc) CPYSN(ra,ra,rc) +# define FNEGS(ra,rc) CPYSN(ra,ra,rc) +# define FNEGT(ra,rc) CPYSN(ra,ra,rc) +# define movr_f(r0,r1) movr_d(r0,r1) +# define movr_d(r0,r1) _movr_d(_jit,r0,r1) +static void _movr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi_f(r0,i0) _movi_f(_jit,r0,i0) +static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*); +# define movi_d(r0,i0) _movi_d(_jit,r0,i0) +static void _movi_d(jit_state_t*,jit_int32_t,jit_float64_t*); +# define absr_f(r0,r1) FABS(r1,r0) +# define absr_d(r0,r1) FABS(r1,r0) +# define negr_f(r0,r1) FNEGS(r1,r0) +# define negr_d(r0,r1) FNEGT(r1,r0) +# define sqrtr_f(r0,r1) _sqrtr_f(_jit,r0,r1) +static void _sqrtr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define sqrtr_d(r0,r1) _sqrtr_d(_jit,r0,r1) +static void _sqrtr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_f_d(r0,r1) movr_d(r0,r1) +# define extr_d_f(r0,r1) movr_f(r0,r1) +# define truncr_f_i(r0,r1) truncr_d_i(r0,r1) +# define truncr_f_l(r0,r1) truncr_d_l(r0,r1) +# define truncr_d_i(r0,r1) truncr_d_l(r0,r1) +# define truncr_d_l(r0,r1) _truncr_d_l(_jit,r0,r1) +static void _truncr_d_l(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_f(r0,r1) _extr_f(_jit,r0,r1) +static void _extr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_d(r0,r1) _extr_d(_jit,r0,r1) +static void _extr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define addr_f(r0,r1,r2) _addr_f(_jit,r0,r1,r2) +static void _addr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addi_f(r0,r1,i0) _addi_f(_jit,r0,r1,i0) +static void _addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define addr_d(r0,r1,r2) _addr_d(_jit,r0,r1,r2) +static void _addr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addi_d(r0,r1,i0) _addi_d(_jit,r0,r1,i0) +static void _addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define subr_f(r0,r1,r2) _subr_f(_jit,r0,r1,r2) +static void _subr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subi_f(r0,r1,i0) _subi_f(_jit,r0,r1,i0) +static void _subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define subr_d(r0,r1,r2) _subr_d(_jit,r0,r1,r2) +static void _subr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subi_d(r0,r1,i0) _subi_d(_jit,r0,r1,i0) +static void _subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define rsbr_f(r0, r1, r2) subr_f(r0, r2, r1) +# define rsbi_f(r0, r1, i0) _rsbi_f(_jit, r0, r1, i0) +static void _rsbi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define rsbr_d(r0, r1, r2) subr_d(r0, r2, r1) +# define rsbi_d(r0, r1, i0) _rsbi_d(_jit, r0, r1, i0) +static void _rsbi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define mulr_f(r0,r1,r2) _mulr_f(_jit,r0,r1,r2) +static void _mulr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define muli_f(r0,r1,i0) _muli_f(_jit,r0,r1,i0) +static void _muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define mulr_d(r0,r1,r2) _mulr_d(_jit,r0,r1,r2) +static void _mulr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define muli_d(r0,r1,i0) _muli_d(_jit,r0,r1,i0) +static void _muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define divr_f(r0,r1,r2) _divr_f(_jit,r0,r1,r2) +static void _divr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_f(r0,r1,i0) _divi_f(_jit,r0,r1,i0) +static void _divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define divr_d(r0,r1,r2) _divr_d(_jit,r0,r1,r2) +static void _divr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_d(r0,r1,i0) _divi_d(_jit,r0,r1,i0) +static void _divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ltr_f(r0,r1,r2) ltr_d(r0,r1,r2) +# define ltr_d(r0,r1,r2) _ltr_d(_jit,r0,r1,r2) +static void _ltr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lti_f(r0,r1,i0) _lti_f(_jit,r0,r1,i0) +static void _lti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define lti_d(r0,r1,i0) _lti_d(_jit,r0,r1,i0) +static void _lti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ler_f(r0,r1,r2) ler_d(r0,r1,r2) +# define ler_d(r0,r1,r2) _ler_d(_jit,r0,r1,r2) +static void _ler_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lei_f(r0,r1,i0) _lei_f(_jit,r0,r1,i0) +static void _lei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define lei_d(r0,r1,i0) _lei_d(_jit,r0,r1,i0) +static void _lei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define eqr_f(r0,r1,r2) eqr_d(r0,r1,r2) +# define eqr_d(r0,r1,r2) _eqr_d(_jit,r0,r1,r2) +static void _eqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define eqi_f(r0,r1,i0) _eqi_f(_jit,r0,r1,i0) +static void _eqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define eqi_d(r0,r1,i0) _eqi_d(_jit,r0,r1,i0) +static void _eqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ger_f(r0,r1,r2) ger_d(r0,r1,r2) +# define ger_d(r0,r1,r2) _ger_d(_jit,r0,r1,r2) +static void _ger_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gei_f(r0,r1,i0) _gei_f(_jit,r0,r1,i0) +static void _gei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define gei_d(r0,r1,i0) _gei_d(_jit,r0,r1,i0) +static void _gei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define gtr_f(r0,r1,r2) gtr_d(r0,r1,r2) +# define gtr_d(r0,r1,r2) _gtr_d(_jit,r0,r1,r2) +static void _gtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gti_f(r0,r1,i0) _gti_f(_jit,r0,r1,i0) +static void _gti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define gti_d(r0,r1,i0) _gti_d(_jit,r0,r1,i0) +static void _gti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ner_f(r0,r1,r2) ner_d(r0,r1,r2) +# define ner_d(r0,r1,r2) _ner_d(_jit,r0,r1,r2) +static void _ner_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define nei_f(r0,r1,i0) _nei_f(_jit,r0,r1,i0) +static void _nei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define nei_d(r0,r1,i0) _nei_d(_jit,r0,r1,i0) +static void _nei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unltr_f(r0,r1,r2) unltr_d(r0,r1,r2) +# define unltr_d(r0,r1,r2) _unltr_d(_jit,r0,r1,r2) +static void _unltr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unlti_f(r0,r1,i0) _unlti_f(_jit,r0,r1,i0) +static void _unlti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define unlti_d(r0,r1,i0) _unlti_d(_jit,r0,r1,i0) +static void _unlti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unler_f(r0,r1,r2) unler_d(r0,r1,r2) +# define unler_d(r0,r1,r2) _unler_d(_jit,r0,r1,r2) +static void _unler_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unlei_f(r0,r1,i0) _unlei_f(_jit,r0,r1,i0) +static void _unlei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define unlei_d(r0,r1,i0) _unlei_d(_jit,r0,r1,i0) +static void _unlei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define uneqr_f(r0,r1,r2) uneqr_d(r0,r1,r2) +# define uneqr_d(r0,r1,r2) _uneqr_d(_jit,r0,r1,r2) +static void _uneqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define uneqi_f(r0,r1,i0) _uneqi_f(_jit,r0,r1,i0) +static void _uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define uneqi_d(r0,r1,i0) _uneqi_d(_jit,r0,r1,i0) +static void _uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unger_f(r0,r1,r2) unger_d(r0,r1,r2) +# define unger_d(r0,r1,r2) _unger_d(_jit,r0,r1,r2) +static void _unger_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ungei_f(r0,r1,i0) _ungei_f(_jit,r0,r1,i0) +static void _ungei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ungei_d(r0,r1,i0) _ungei_d(_jit,r0,r1,i0) +static void _ungei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ungtr_f(r0,r1,r2) ungtr_d(r0,r1,r2) +# define ungtr_d(r0,r1,r2) _ungtr_d(_jit,r0,r1,r2) +static void _ungtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ungti_f(r0,r1,i0) _ungti_f(_jit,r0,r1,i0) +static void _ungti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ungti_d(r0,r1,i0) _ungti_d(_jit,r0,r1,i0) +static void _ungti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ltgtr_f(r0,r1,r2) ltgtr_d(r0,r1,r2) +# define ltgtr_d(r0,r1,r2) _ltgtr_d(_jit,r0,r1,r2) +static void _ltgtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ltgti_f(r0,r1,i0) _ltgti_f(_jit,r0,r1,i0) +static void _ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ltgti_d(r0,r1,i0) _ltgti_d(_jit,r0,r1,i0) +static void _ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ordr_f(r0,r1,r2) ordr_d(r0,r1,r2) +# define ordr_d(r0,r1,r2) _ordr_d(_jit,r0,r1,r2) +static void _ordr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ordi_f(r0,r1,i0) _ordi_f(_jit,r0,r1,i0) +static void _ordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ordi_d(r0,r1,i0) _ordi_d(_jit,r0,r1,i0) +static void _ordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unordr_f(r0,r1,r2) unordr_d(r0,r1,r2) +# define unordr_d(r0,r1,r2) _unordr_d(_jit,r0,r1,r2) +static void _unordr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unordi_f(r0,r1,i0) _unordi_f(_jit,r0,r1,i0) +static void _unordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define unordi_d(r0,r1,i0) _unordi_d(_jit,r0,r1,i0) +static void _unordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define bltr_f(i0,r0,r1) bltr_d(i0,r0,r1) +# define bltr_d(i0,r0,r1) _bltr_d(_jit,i0,r0,r1) +static jit_word_t _bltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blti_f(i0,r0,i1) _blti_f(_jit,i0,r0,i1) +static jit_word_t _blti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define blti_d(i0,r0,i1) _blti_d(_jit,i0,r0,i1) +static jit_word_t _blti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bler_f(i0,r0,r1) bler_d(i0,r0,r1) +# define bler_d(i0,r0,r1) _bler_d(_jit,i0,r0,r1) +static jit_word_t _bler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blei_f(i0,r0,i1) _blei_f(_jit,i0,r0,i1) +static jit_word_t _blei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define blei_d(i0,r0,i1) _blei_d(_jit,i0,r0,i1) +static jit_word_t _blei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define beqr_f(i0,r0,r1) beqr_d(i0,r0,r1) +# define beqr_d(i0,r0,r1) _beqr_d(_jit,i0,r0,r1) +static jit_word_t _beqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define beqi_f(i0,r0,i1) _beqi_f(_jit,i0,r0,i1) +static jit_word_t _beqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define beqi_d(i0,r0,i1) _beqi_d(_jit,i0,r0,i1) +static jit_word_t _beqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bger_f(i0,r0,r1) bger_d(i0,r0,r1) +# define bger_d(i0,r0,r1) _bger_d(_jit,i0,r0,r1) +static jit_word_t _bger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgei_f(i0,r0,i1) _bgei_f(_jit,i0,r0,i1) +static jit_word_t _bgei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bgei_d(i0,r0,i1) _bgei_d(_jit,i0,r0,i1) +static jit_word_t _bgei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bgtr_f(i0,r0,r1) bgtr_d(i0,r0,r1) +# define bgtr_d(i0,r0,r1) _bgtr_d(_jit,i0,r0,r1) +static jit_word_t _bgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgti_f(i0,r0,i1) _bgti_f(_jit,i0,r0,i1) +static jit_word_t _bgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bgti_d(i0,r0,i1) _bgti_d(_jit,i0,r0,i1) +static jit_word_t _bgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bner_f(i0,r0,r1) bner_d(i0,r0,r1) +# define bner_d(i0,r0,r1) _bner_d(_jit,i0,r0,r1) +static jit_word_t _bner_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bnei_f(i0,r0,i1) _bnei_f(_jit,i0,r0,i1) +static jit_word_t _bnei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bnei_d(i0,r0,i1) _bnei_d(_jit,i0,r0,i1) +static jit_word_t _bnei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bunltr_f(i0,r0,r1) bunltr_d(i0,r0,r1) +# define bunltr_d(i0,r0,r1) _bunltr_d(_jit,i0,r0,r1) +static jit_word_t _bunltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlti_f(i0,r0,i1) _bunlti_f(_jit,i0,r0,i1) +static jit_word_t _bunlti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bunlti_d(i0,r0,i1) _bunlti_d(_jit,i0,r0,i1) +static jit_word_t _bunlti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bunler_f(i0,r0,r1) bunler_d(i0,r0,r1) +# define bunler_d(i0,r0,r1) _bunler_d(_jit,i0,r0,r1) +static jit_word_t _bunler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlei_f(i0,r0,i1) _bunlei_f(_jit,i0,r0,i1) +static jit_word_t _bunlei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bunlei_d(i0,r0,i1) _bunlei_d(_jit,i0,r0,i1) +static jit_word_t _bunlei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define buneqr_f(i0,r0,r1) buneqr_d(i0,r0,r1) +# define buneqr_d(i0,r0,r1) _buneqr_d(_jit,i0,r0,r1) +static jit_word_t _buneqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define buneqi_f(i0,r0,i1) _buneqi_f(_jit,i0,r0,i1) +static jit_word_t _buneqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define buneqi_d(i0,r0,i1) _buneqi_d(_jit,i0,r0,i1) +static jit_word_t _buneqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bunger_f(i0,r0,r1) bunger_d(i0,r0,r1) +# define bunger_d(i0,r0,r1) _bunger_d(_jit,i0,r0,r1) +static jit_word_t _bunger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungei_f(i0,r0,i1) _bungei_f(_jit,i0,r0,i1) +static jit_word_t _bungei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bungei_d(i0,r0,i1) _bungei_d(_jit,i0,r0,i1) +static jit_word_t _bungei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bungtr_f(i0,r0,r1) bungtr_d(i0,r0,r1) +# define bungtr_d(i0,r0,r1) _bungtr_d(_jit,i0,r0,r1) +static jit_word_t _bungtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungti_f(i0,r0,i1) _bungti_f(_jit,i0,r0,i1) +static jit_word_t _bungti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bungti_d(i0,r0,i1) _bungti_d(_jit,i0,r0,i1) +static jit_word_t _bungti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bltgtr_f(i0,r0,r1) bltgtr_d(i0,r0,r1) +# define bltgtr_d(i0,r0,r1) _bltgtr_d(_jit,i0,r0,r1) +static jit_word_t _bltgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bltgti_f(i0,r0,i1) _bltgti_f(_jit,i0,r0,i1) +static jit_word_t _bltgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bltgti_d(i0,r0,i1) _bltgti_d(_jit,i0,r0,i1) +static jit_word_t _bltgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bordr_f(i0,r0,r1) bordr_d(i0,r0,r1) +# define bordr_d(i0,r0,r1) _bordr_d(_jit,i0,r0,r1) +static jit_word_t _bordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bordi_f(i0,r0,i1) _bordi_f(_jit,i0,r0,i1) +static jit_word_t _bordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bordi_d(i0,r0,i1) _bordi_d(_jit,i0,r0,i1) +static jit_word_t _bordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bunordr_f(i0,r0,r1) bunordr_d(i0,r0,r1) +# define bunordr_d(i0,r0,r1) _bunordr_d(_jit,i0,r0,r1) +static jit_word_t _bunordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunordi_f(i0,r0,i1) _bunordi_f(_jit,i0,r0,i1) +static jit_word_t _bunordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bunordi_d(i0,r0,i1) _bunordi_d(_jit,i0,r0,i1) +static jit_word_t _bunordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define ldr_f(r0,r1) LDS(r0,r1,0) +# define ldi_f(r0,i0) _ldi_f(_jit,r0,i0) +static void _ldi_f(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_d(r0,r1) LDT(r0,r1,0) +# define ldi_d(r0,i0) _ldi_d(_jit,r0,i0) +static void _ldi_d(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_f(r0,r1,r2) _ldxr_f(_jit,r0,r1,r2) +static void _ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_f(r0,r1,i0) _ldxi_f(_jit,r0,r1,i0) +static void _ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_d(r0,r1,r2) _ldxr_d(_jit,r0,r1,r2) +static void _ldxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_d(r0,r1,i0) _ldxi_d(_jit,r0,r1,i0) +static void _ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_f(r0,r1) STS(r1,r0,0) +# define sti_f(i0,r0) _sti_f(_jit,i0,r0) +static void _sti_f(jit_state_t*,jit_word_t,jit_int32_t); +# define str_d(r0,r1) STT(r1,r0,0) +# define sti_d(i0,r0) _sti_d(_jit,i0,r0) +static void _sti_d(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_f(r0,r1,r2) _stxr_f(_jit,r0,r1,r2) +static void _stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_f(i0,r0,r1) _stxi_f(_jit,i0,r0,r1) +static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_d(r0,r1,r2) _stxr_d(_jit,r0,r1,r2) +static void _stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_d(i0,r0,r1) _stxi_d(_jit,i0,r0,r1) +static void _stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1) +static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t); +#endif + +#if CODE +# define fpr_opi(name, type, size) \ +static void \ +_##name##i_##type(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, \ + jit_float##size##_t *i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr); \ + movi_##type(rn(reg), i0); \ + name##r_##type(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +# define fpr_bopi(name, type, size) \ +static jit_word_t \ +_b##name##i_##type(jit_state_t *_jit, \ + jit_word_t i0, jit_int32_t r0, \ + jit_float##size##_t *i1) \ +{ \ + jit_word_t word; \ + jit_int32_t reg = jit_get_reg(jit_class_fpr|jit_class_nospill);\ + movi_##type(rn(reg), i1); \ + word = b##name##r_##type(i0, r0, rn(reg)); \ + jit_unget_reg(reg); \ + return (word); \ +} +# define fopi(name) fpr_opi(name, f, 32) +# define fbopi(name) fpr_bopi(name, f, 32) +# define dopi(name) fpr_opi(name, d, 64) +# define dbopi(name) fpr_bopi(name, d, 64) + +static void +_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + FMOV(r1, r0); +} + +static void +_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_int32_t reg; + + if (_jitc->no_data) { + data.f = *i0; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.i & 0xffffffff); + stxi_i(-8, _FP_REGNO, rn(reg)); + jit_unget_reg(reg); + ldxi_f(r0, _FP_REGNO, -8); + } + else + ldi_f(r0, (jit_word_t)i0); +} + +static void +_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + union { + jit_word_t w; + jit_float64_t d; + } data; + jit_int32_t reg; + + if (_jitc->no_data) { + data.d = *i0; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.w); + stxi_l(-8, _FP_REGNO, rn(reg)); + jit_unget_reg(reg); + ldxi_d(r0, _FP_REGNO, -8); + } + else + ldi_d(r0, (jit_word_t)i0); +} + +static void +_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + CVTTQ_SVC(r1, rn(reg)); + TRAPB(); + stxi_d(-8, _FP_REGNO, rn(reg)); + ldxi(r0, _FP_REGNO, -8); + jit_unget_reg(reg); +} + +static void +_sqrtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + SQRTS_SU(r1, r0); + TRAPB(); +} + +static void +_sqrtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + SQRTT_SU(r1, r0); + TRAPB(); +} + +static void +_extr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + stxi_l(-8, _FP_REGNO, r1); + ldxi_d(r0, _FP_REGNO, -8); + CVTQS(r0, r0); +} + +static void +_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + stxi_l(-8, _FP_REGNO, r1); + ldxi_d(r0, _FP_REGNO, -8); + CVTQT(r0, r0); +} + +static void +_addr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + ADDS_SU(r1, r2, r0); + TRAPB(); +} +fopi(add) + +static void +_addr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + ADDT_SU(r1, r2, r0); + TRAPB(); +} +dopi(add) + +static void +_subr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SUBS_SU(r1, r2, r0); + TRAPB(); +} +fopi(sub) +fopi(rsb) + +static void +_subr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SUBT_SU(r1, r2, r0); + TRAPB(); +} +dopi(sub) +dopi(rsb) + +static void +_mulr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + MULS_SU(r1, r2, r0); + TRAPB(); +} +fopi(mul) + +static void +_mulr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + MULT_SU(r1, r2, r0); + TRAPB(); +} +dopi(mul) + +static void +_divr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + DIVS_SU(r1, r2, r0); + TRAPB(); +} +fopi(div) + +static void +_divr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + DIVT_SU(r1, r2, r0); + TRAPB(); +} +dopi(div) + +static void +_ltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLT_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), 1); + movi(r0, 1); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(lt); +dopi(lt); + +static void +_ler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLE_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), 1); + movi(r0, 1); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(le); +dopi(le); + +static void +_eqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTEQ_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), 1); + movi(r0, 1); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(eq); +dopi(eq); + +static void +_ger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLT_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 1); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(ge); +dopi(ge); + +static void +_gtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLE_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 1); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(gt); +dopi(gt); + +static void +_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 3); + CMPTEQ_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), 1); + movi(r0, 0); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(ne); +dopi(ne); + +static void +_unltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLT_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 0); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(unlt); +dopi(unlt); + +static void +_unler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLE_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 0); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(unle); +dopi(unle); + +static void +_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTEQ_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 0); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(uneq); +dopi(uneq); + +static void +_unger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLT_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), 1); + movi(r0, 0); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(unge); +dopi(unge); + +static void +_ungtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLE_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), 1); + movi(r0, 0); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(ungt); +dopi(ungt); + +static void +_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTEQ_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 1); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(ltgt); +dopi(ltgt); + +static void +_ordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 1); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(ord); +dopi(ord); + +static void +_unordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + jit_unget_reg(reg); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(unord); +dopi(unord); + +static jit_word_t +_bltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 3); + CMPTLT_SU(r0, r1, rn(reg)); /* lt satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(lt); +dbopi(lt); + +static jit_word_t +_bler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 3); + CMPTLE_SU(r0, r1, rn(reg)); /* le satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(le); +dbopi(le); + +static jit_word_t +_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 3); + CMPTEQ_SU(r0, r1, rn(reg)); /* eq satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(eq); +dbopi(eq); + +static jit_word_t +_bger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 3); + CMPTLT_SU(r0, r1, rn(reg)); /* ge satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(ge); +dbopi(ge); + +static jit_word_t +_bgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 3); + CMPTLE_SU(r0, r1, rn(reg)); /* gt satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(gt); +dbopi(gt); + +static jit_word_t +_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t u, v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTEQ_SU(r0, r1, rn(reg)); /* ne satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 1); + patch_at(u, _jit->pc.w); + w = _jit->pc.w; + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(ne); +dbopi(ne); + +static jit_word_t +_bunltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t u, v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLT_SU(r0, r1, rn(reg)); /* lt satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBEQ(rn(reg), 1); + w = _jit->pc.w; + patch_at(u, _jit->pc.w); + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(unlt); +dbopi(unlt); + +static jit_word_t +_bunler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t u, v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLE_SU(r0, r1, rn(reg)); /* le satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBEQ(rn(reg), 1); + w = _jit->pc.w; + patch_at(u, _jit->pc.w); + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(unle); +dbopi(unle); + +static jit_word_t +_buneqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t u, v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTEQ_SU(r0, r1, rn(reg)); /* eq satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBEQ(rn(reg), 1); + w = _jit->pc.w; + patch_at(u, _jit->pc.w); + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(uneq); +dbopi(uneq); + +static jit_word_t +_bunger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t u, v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLT_SU(r0, r1, rn(reg)); /* ge satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 1); + w = _jit->pc.w; + patch_at(u, _jit->pc.w); + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(unge); +dbopi(unge); + +static jit_word_t +_bungtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t u, v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLE_SU(r0, r1, rn(reg)); /* gt does satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 1); + w = _jit->pc.w; + patch_at(u, _jit->pc.w); + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(ungt); +dbopi(ungt); + +static jit_word_t +_bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t u, v, w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTEQ_SU(r1, r0, rn(reg)); + TRAPB(); + v = _jit->pc.w; /* eq does not satisfy condition */ + FBNE(rn(reg), 1); + w = _jit->pc.w; + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(u, _jit->pc.w); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(ltgt); +dbopi(ltgt); + +static jit_word_t +_bordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} +fbopi(ord); +dbopi(ord); + +static jit_word_t +_bunordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} +fbopi(unord); +dbopi(unord); + +static void +_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t reg; + if (_s16_p(i0)) + LDS(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t reg; + if (_s16_p(i0)) + LDT(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_word_t reg; + if (_s16_p(i0)) + LDS(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_word_t reg; + if (_s16_p(i0)) + LDT(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_word_t reg; + if (_s16_p(i0)) + STS(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_f(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_word_t reg; + if (_s16_p(i0)) + STT(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_d(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_f(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t reg; + if (_s16_p(i0)) + STS(r1, r0, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_f(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_d(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t reg; + if (_s16_p(i0)) + STT(r1, r0, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_d(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t ge_code; + jit_int32_t rg0, rg1, rg2; + + assert(_jitc->function->self.call & jit_call_varargs); + + rg0 = jit_get_reg(jit_class_gpr); + rg1 = jit_get_reg(jit_class_gpr); + rg2 = jit_get_reg(jit_class_gpr); + + /* Load the base in first temporary. */ + ldxi(rn(rg0), r1, offsetof(jit_va_list_t, base)); + + /* Load the offset in the second temporary. */ + ldxi(rn(rg1), r1, offsetof(jit_va_list_t, offset)); + + /* Remember absolute offset */ + movr(rn(rg2), rn(rg1)); + + /* Jump if overflowed register saved area. */ + ge_code = bgei(_jit->pc.w, rn(rg1), 48); + /* Otherwise load from the float registers save area. */ + subi(rn(rg1), rn(rg1), 48); + patch_at(ge_code, _jit->pc.w); + + /* Load the argument */ + ldxr_d(r0, rn(rg0), rn(rg1)); + + /* No longer needed. */ + jit_unget_reg(rg1); + jit_unget_reg(rg0); + + /* Update offset. */ + addi(rn(rg2), rn(rg2), 8); + stxi(offsetof(jit_va_list_t, offset), r1, rn(rg2)); + jit_unget_reg(rg2); +} +#endif diff --git a/deps/lightning/lib/jit_alpha-sz.c b/deps/lightning/lib/jit_alpha-sz.c new file mode 100644 index 0000000..e1a572a --- /dev/null +++ b/deps/lightning/lib/jit_alpha-sz.c @@ -0,0 +1,402 @@ + +#if __WORDSIZE == 64 +#define JIT_INSTR_MAX 76 + 0, /* data */ + 0, /* live */ + 4, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 76, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 0, /* va_start */ + 0, /* va_arg */ + 0, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 32, /* addi */ + 12, /* addcr */ + 40, /* addci */ + 28, /* addxr */ + 28, /* addxi */ + 4, /* subr */ + 32, /* subi */ + 12, /* subcr */ + 40, /* subci */ + 28, /* subxr */ + 28, /* subxi */ + 36, /* rsbi */ + 4, /* mulr */ + 32, /* muli */ + 44, /* qmulr */ + 56, /* qmuli */ + 12, /* qmulr_u */ + 32, /* qmuli_u */ + 48, /* divr */ + 72, /* divi */ + 48, /* divr_u */ + 72, /* divi_u */ + 56, /* qdivr */ + 56, /* qdivi */ + 56, /* qdivr_u */ + 56, /* qdivi_u */ + 48, /* remr */ + 72, /* remi */ + 48, /* remr_u */ + 72, /* remi_u */ + 4, /* andr */ + 32, /* andi */ + 4, /* orr */ + 32, /* ori */ + 4, /* xorr */ + 32, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 4, /* ltr */ + 4, /* lti */ + 4, /* ltr_u */ + 8, /* lti_u */ + 4, /* ler */ + 8, /* lei */ + 4, /* ler_u */ + 4, /* lei_u */ + 4, /* eqr */ + 4, /* eqi */ + 4, /* ger */ + 8, /* gei */ + 4, /* ger_u */ + 8, /* gei_u */ + 4, /* gtr */ + 8, /* gti */ + 4, /* gtr_u */ + 8, /* gti_u */ + 8, /* ner */ + 12, /* nei */ + 4, /* movr */ + 32, /* movi */ + 8, /* extr_c */ + 8, /* extr_uc */ + 8, /* extr_s */ + 8, /* extr_us */ + 8, /* extr_i */ + 8, /* extr_ui */ + 16, /* htonr_us */ + 36, /* htonr_ui */ + 36, /* htonr_ul */ + 12, /* ldr_c */ + 40, /* ldi_c */ + 4, /* ldr_uc */ + 32, /* ldi_uc */ + 12, /* ldr_s */ + 40, /* ldi_s */ + 4, /* ldr_us */ + 32, /* ldi_us */ + 4, /* ldr_i */ + 32, /* ldi_i */ + 12, /* ldr_ui */ + 40, /* ldi_ui */ + 4, /* ldr_l */ + 32, /* ldi_l */ + 16, /* ldxr_c */ + 12, /* ldxi_c */ + 8, /* ldxr_uc */ + 4, /* ldxi_uc */ + 16, /* ldxr_s */ + 12, /* ldxi_s */ + 8, /* ldxr_us */ + 4, /* ldxi_us */ + 8, /* ldxr_i */ + 4, /* ldxi_i */ + 16, /* ldxr_ui */ + 12, /* ldxi_ui */ + 8, /* ldxr_l */ + 4, /* ldxi_l */ + 4, /* str_c */ + 32, /* sti_c */ + 4, /* str_s */ + 32, /* sti_s */ + 4, /* str_i */ + 32, /* sti_i */ + 4, /* str_l */ + 32, /* sti_l */ + 8, /* stxr_c */ + 4, /* stxi_c */ + 8, /* stxr_s */ + 4, /* stxi_s */ + 8, /* stxr_i */ + 4, /* stxi_i */ + 8, /* stxr_l */ + 4, /* stxi_l */ + 8, /* bltr */ + 8, /* blti */ + 8, /* bltr_u */ + 12, /* blti_u */ + 8, /* bler */ + 12, /* blei */ + 8, /* bler_u */ + 12, /* blei_u */ + 8, /* beqr */ + 40, /* beqi */ + 8, /* bger */ + 12, /* bgei */ + 8, /* bger_u */ + 12, /* bgei_u */ + 8, /* bgtr */ + 12, /* bgti */ + 8, /* bgtr_u */ + 12, /* bgti_u */ + 8, /* bner */ + 36, /* bnei */ + 8, /* bmsr */ + 8, /* bmsi */ + 8, /* bmcr */ + 8, /* bmci */ + 28, /* boaddr */ + 32, /* boaddi */ + 16, /* boaddr_u */ + 16, /* boaddi_u */ + 28, /* bxaddr */ + 32, /* bxaddi */ + 16, /* bxaddr_u */ + 16, /* bxaddi_u */ + 28, /* bosubr */ + 32, /* bosubi */ + 16, /* bosubr_u */ + 16, /* bosubi_u */ + 28, /* bxsubr */ + 32, /* bxsubi */ + 16, /* bxsubr_u */ + 16, /* bxsubi_u */ + 0, /* jmpr */ + 36, /* jmpi */ + 8, /* callr */ + 36, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 68, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 8, /* addr_f */ + 32, /* addi_f */ + 8, /* subr_f */ + 32, /* subi_f */ + 32, /* rsbi_f */ + 8, /* mulr_f */ + 32, /* muli_f */ + 8, /* divr_f */ + 32, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 8, /* sqrtr_f */ + 32, /* ltr_f */ + 56, /* lti_f */ + 32, /* ler_f */ + 56, /* lei_f */ + 32, /* eqr_f */ + 56, /* eqi_f */ + 32, /* ger_f */ + 56, /* gei_f */ + 32, /* gtr_f */ + 56, /* gti_f */ + 32, /* ner_f */ + 56, /* nei_f */ + 32, /* unltr_f */ + 56, /* unlti_f */ + 32, /* unler_f */ + 56, /* unlei_f */ + 32, /* uneqr_f */ + 56, /* uneqi_f */ + 32, /* unger_f */ + 56, /* ungei_f */ + 32, /* ungtr_f */ + 56, /* ungti_f */ + 32, /* ltgtr_f */ + 56, /* ltgti_f */ + 20, /* ordr_f */ + 44, /* ordi_f */ + 20, /* unordr_f */ + 44, /* unordi_f */ + 16, /* truncr_f_i */ + 16, /* truncr_f_l */ + 12, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 24, /* movi_f */ + 4, /* ldr_f */ + 32, /* ldi_f */ + 8, /* ldxr_f */ + 4, /* ldxi_f */ + 4, /* str_f */ + 32, /* sti_f */ + 8, /* stxr_f */ + 4, /* stxi_f */ + 24, /* bltr_f */ + 48, /* blti_f */ + 24, /* bler_f */ + 48, /* blei_f */ + 24, /* beqr_f */ + 48, /* beqi_f */ + 24, /* bger_f */ + 48, /* bgei_f */ + 24, /* bgtr_f */ + 48, /* bgti_f */ + 28, /* bner_f */ + 52, /* bnei_f */ + 28, /* bunltr_f */ + 52, /* bunlti_f */ + 28, /* bunler_f */ + 52, /* bunlei_f */ + 28, /* buneqr_f */ + 52, /* buneqi_f */ + 28, /* bunger_f */ + 52, /* bungei_f */ + 28, /* bungtr_f */ + 52, /* bungti_f */ + 28, /* bltgtr_f */ + 52, /* bltgti_f */ + 12, /* bordr_f */ + 36, /* bordi_f */ + 12, /* bunordr_f */ + 36, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 8, /* addr_d */ + 28, /* addi_d */ + 8, /* subr_d */ + 28, /* subi_d */ + 28, /* rsbi_d */ + 8, /* mulr_d */ + 28, /* muli_d */ + 8, /* divr_d */ + 28, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 8, /* sqrtr_d */ + 32, /* ltr_d */ + 52, /* lti_d */ + 32, /* ler_d */ + 52, /* lei_d */ + 32, /* eqr_d */ + 52, /* eqi_d */ + 32, /* ger_d */ + 52, /* gei_d */ + 32, /* gtr_d */ + 52, /* gti_d */ + 32, /* ner_d */ + 52, /* nei_d */ + 32, /* unltr_d */ + 52, /* unlti_d */ + 32, /* unler_d */ + 52, /* unlei_d */ + 32, /* uneqr_d */ + 52, /* uneqi_d */ + 32, /* unger_d */ + 52, /* ungei_d */ + 32, /* ungtr_d */ + 52, /* ungti_d */ + 32, /* ltgtr_d */ + 52, /* ltgti_d */ + 20, /* ordr_d */ + 40, /* ordi_d */ + 20, /* unordr_d */ + 40, /* unordi_d */ + 16, /* truncr_d_i */ + 16, /* truncr_d_l */ + 12, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 20, /* movi_d */ + 4, /* ldr_d */ + 32, /* ldi_d */ + 8, /* ldxr_d */ + 4, /* ldxi_d */ + 4, /* str_d */ + 32, /* sti_d */ + 8, /* stxr_d */ + 4, /* stxi_d */ + 24, /* bltr_d */ + 44, /* blti_d */ + 24, /* bler_d */ + 44, /* blei_d */ + 24, /* beqr_d */ + 44, /* beqi_d */ + 24, /* bger_d */ + 44, /* bgei_d */ + 24, /* bgtr_d */ + 44, /* bgti_d */ + 28, /* bner_d */ + 48, /* bnei_d */ + 28, /* bunltr_d */ + 48, /* bunlti_d */ + 28, /* bunler_d */ + 48, /* bunlei_d */ + 28, /* buneqr_d */ + 48, /* buneqi_d */ + 28, /* bunger_d */ + 48, /* bungei_d */ + 28, /* bungtr_d */ + 48, /* bungti_d */ + 28, /* bltgtr_d */ + 48, /* bltgti_d */ + 12, /* bordr_d */ + 32, /* bordi_d */ + 12, /* bunordr_d */ + 32, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __WORDSIZE */ diff --git a/deps/lightning/lib/jit_alpha.c b/deps/lightning/lib/jit_alpha.c new file mode 100644 index 0000000..9a067aa --- /dev/null +++ b/deps/lightning/lib/jit_alpha.c @@ -0,0 +1,1552 @@ +/* + * Copyright (C) 2014-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 6) +#define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 6) +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define C_DISP 0 +# define S_DISP 0 +# define I_DISP 0 +# define F_DISP 0 +#else +# define C_DISP 8 - sizeof(jit_int8_t) +# define S_DISP 8 - sizeof(jit_int16_t) +# define I_DISP 8 - sizeof(jit_int32_t) +# define F_DISP 8 - sizeof(jit_float32_t) +#endif + +/* + * Types + */ +/* + * What I could understand from gcc/config/alpha/alpha.c:alpha_build_builtin_va_list() + * and other helpers, as well as objdump of simple test programs; could not + * get gdb working on the test system I had access... + * + * base-48 to base is where up to 6 float registers are saved. + * base to base+48 is where up to 6 integer registers are saved. + * base+48... is where varargs arguments are stored. + * + * if (offset < 48) { + * if (type == double) + * offset -= 48; + * } + * load(reg, base, offset); + * offset += 8; + */ +typedef struct jit_va_list { + jit_pointer_t base; + jit_word_t offset; +} jit_va_list_t; + +/* + * Prototypes + */ +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); + +#define PROTO 1 +# include "jit_alpha-cpu.c" +# include "jit_alpha-fpu.c" +#undef PROTO + +/* + * Initialization + */ +jit_register_t _rvs[] = { + { rc(gpr) | 0x1c, "at" }, + { rc(gpr) | 0x00, "v0" }, + { rc(gpr) | 0x01, "t0" }, + { rc(gpr) | 0x02, "t1" }, + { rc(gpr) | 0x03, "t2" }, + { rc(gpr) | 0x04, "t3" }, + { rc(gpr) | 0x05, "t4" }, + { rc(gpr) | 0x06, "t5" }, + { rc(gpr) | 0x07, "t6" }, + { rc(gpr) | 0x08, "t7" }, + { rc(gpr) | 0x16, "t8" }, + { rc(gpr) | 0x17, "t9" }, + { rc(gpr) | 0x18, "t10" }, + { rc(gpr) | 0x19, "t11" }, + { rc(sav) | rc(gpr) | 0x09, "s0" }, + { rc(sav) | rc(gpr) | 0x0a, "s1" }, + { rc(sav) | rc(gpr) | 0x0b, "s2" }, + { rc(sav) | rc(gpr) | 0x0c, "s3" }, + { rc(sav) | rc(gpr) | 0x0d, "s4" }, + { rc(sav) | rc(gpr) | 0x0e, "s5" }, + { 0x0f, "fp" }, + { rc(arg) | rc(gpr) | 0x15, "a5" }, + { rc(arg) | rc(gpr) | 0x14, "a4" }, + { rc(arg) | rc(gpr) | 0x13, "a3" }, + { rc(arg) | rc(gpr) | 0x12, "a2" }, + { rc(arg) | rc(gpr) | 0x11, "a1" }, + { rc(arg) | rc(gpr) | 0x10, "a0" }, + { 0x1a, "ra" }, + { 0x1b, "pv" }, + { 0x1d, "gp" }, + { 0x1e, "sp" }, + { 0x1f, "zero" }, + { rc(fpr) | 0x00, "$f0" }, + { rc(fpr) | 0x01, "$f1" }, + { rc(sav) | rc(fpr) | 0x02, "$f2" }, + { rc(sav) | rc(fpr) | 0x03, "$f3" }, + { rc(sav) | rc(fpr) | 0x04, "$f4" }, + { rc(sav) | rc(fpr) | 0x05, "$f5" }, + { rc(sav) | rc(fpr) | 0x06, "$f6" }, + { rc(sav) | rc(fpr) | 0x07, "$f7" }, + { rc(sav) | rc(fpr) | 0x08, "$f8" }, + { rc(sav) | rc(fpr) | 0x09, "$f9" }, + { rc(fpr) | 0x0a, "$f10" }, + { rc(fpr) | 0x0b, "$f11" }, + { rc(fpr) | 0x0c, "$f12" }, + { rc(fpr) | 0x0d, "$f13" }, + { rc(fpr) | 0x0e, "$f14" }, + { rc(fpr) | 0x0f, "$f15" }, + { rc(arg) | rc(fpr) | 0x15, "$f21" }, + { rc(arg) | rc(fpr) | 0x14, "$f20" }, + { rc(arg) | rc(fpr) | 0x13, "$f19" }, + { rc(arg) | rc(fpr) | 0x12, "$f18" }, + { rc(arg) | rc(fpr) | 0x11, "$f17" }, + { rc(arg) | rc(fpr) | 0x10, "$f16" }, + { rc(fpr) | 0x16, "$f22" }, + { rc(fpr) | 0x17, "$f23" }, + { rc(fpr) | 0x18, "$f24" }, + { rc(fpr) | 0x19, "$f25" }, + { rc(fpr) | 0x1a, "$f26" }, + { rc(fpr) | 0x1b, "$f27" }, + { rc(fpr) | 0x1c, "$f28" }, + { rc(fpr) | 0x1d, "$f29" }, + { rc(fpr) | 0x1e, "$f30" }, + { 0x1f, "$f31" }, + { _NOREG, "<none>" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ +} + +void +_jit_init(jit_state_t *_jit) +{ + _jitc->reglen = jit_size(_rvs) - 1; + jit_carry = _NOREG; +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + _jitc->function->self.size = stack_framesize; + _jitc->function->self.argi = _jitc->function->self.alen = 0; + /* float conversion */ + _jitc->function->self.aoff = -8; + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + assert(_jitc->function != NULL); + switch (length) { + case 0: case 1: break; + case 2: _jitc->function->self.aoff &= -2; break; + case 3: case 4: _jitc->function->self.aoff &= -4; break; + default: _jitc->function->self.aoff &= -8; break; + } + _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } + return (_jitc->function->self.aoff); +} + +void +_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) +{ + jit_int32_t reg; + assert(_jitc->function != NULL); + jit_inc_synth_ww(allocar, u, v); + if (!_jitc->function->allocar) { + _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); + _jitc->function->allocar = 1; + } + reg = jit_get_reg(jit_class_gpr); + jit_negr(reg, v); + jit_andi(reg, reg, -8); + jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); + jit_addr(u, u, reg); + jit_addr(JIT_SP, JIT_SP, reg); + jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); + jit_unget_reg(reg); + jit_dec_synth(); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + assert(_jitc->function != NULL); + jit_inc_synth(ret); + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr, u); + if (JIT_RET != u) + jit_movr(JIT_RET, u); + jit_live(JIT_RET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti(jit_state_t *_jit, jit_word_t u) +{ + jit_inc_synth_w(reti, u); + jit_movi(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_f, u); + if (u != JIT_FRET) + jit_movr_f(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_inc_synth_f(reti_f, u); + jit_movi_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_d, u); + if (u != JIT_FRET) + jit_movr_d(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_inc_synth_d(reti_d, u); + jit_movi_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_epilog(jit_state_t *_jit) +{ + assert(_jitc->function != NULL); + assert(_jitc->function->epilog->next == NULL); + jit_link(_jitc->function->epilog); + _jitc->function = NULL; +} + +jit_bool_t +_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) +{ + if (u->code == jit_code_arg) + return (jit_arg_reg_p(u->u.w)); + assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d); + return (jit_arg_f_reg_p(u->u.w)); +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + jit_inc_synth(ellipsis); + if (_jitc->prepare) { + jit_link_prepare(); + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; + } + else { + jit_link_prolog(); + assert(!(_jitc->function->self.call & jit_call_varargs)); + _jitc->function->self.call |= jit_call_varargs; + + /* Allocate va_list like object in the stack */ + _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t)); + _jitc->function->vagp = _jitc->function->self.argi; + } + jit_dec_synth(); +} + +void +_jit_va_push(jit_state_t *_jit, jit_int32_t u) +{ + jit_int32_t reg; + jit_inc_synth_w(va_push, u); + reg = jit_get_reg(jit_class_gpr); + jit_ldxi(reg, u, offsetof(jit_va_list_t, base)); + jit_pushargr(reg); + jit_ldxi(reg, u, offsetof(jit_va_list_t, offset)); + jit_pushargr(reg); + jit_unget_reg(reg); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function != NULL); + if (jit_arg_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += 8; + } + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function != NULL); + if (jit_arg_f_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += 8; + } + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function != NULL); + if (jit_arg_f_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += 8; + } + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +void +_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_c(u, _A0 - v->u.w); + else + jit_ldxi_c(u, _FP, v->u.w + C_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_uc(u, _A0 - v->u.w); + else + jit_ldxi_uc(u, _FP, v->u.w + C_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_s(u, _A0 - v->u.w); + else + jit_ldxi_s(u, _FP, v->u.w + S_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_us(u, _A0 - v->u.w); + else + jit_ldxi_us(u, _FP, v->u.w + S_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_i(u, _A0 - v->u.w); + else + jit_ldxi_i(u, _FP, v->u.w + I_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_ui(u, _A0 - v->u.w); + else + jit_ldxi_ui(u, _FP, v->u.w + I_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(u, _A0 - v->u.w); + else + jit_ldxi_l(u, _FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(_A0 - v->u.w, u); + else + jit_stxi(v->u.w, _FP, u); + jit_dec_synth(); +} + +void +_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movi(_A0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(v->u.w, _FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_f(u, _F16 - v->u.w); + else + jit_ldxi_f(u, _FP, v->u.w + F_DISP); + jit_dec_synth(); +} + +void +_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_f(_F16 - v->u.w, u); + else + jit_stxi_f(v->u.w, _FP, u + F_DISP); + jit_dec_synth(); +} + +void +_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movi_f(_F16 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(v->u.w, _FP, regno + F_DISP); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(u, _F16 - v->u.w); + else + jit_ldxi_d(u, _FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(_F16 - v->u.w, u); + else + jit_stxi_d(v->u.w, _FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movi_d(_F16 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(v->u.w, _FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function != NULL); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += 8; + } + jit_dec_synth(); +} + +void +_jit_pushargi(jit_state_t *_jit, jit_int64_t u) +{ + jit_int32_t regno; + assert(_jitc->function != NULL); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size, JIT_SP, regno); + _jitc->function->call.size += 8; + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function != NULL); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argi)) { + jit_movr_f(_F16 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi_f(_jitc->function->call.size + F_DISP, JIT_SP, u); + _jitc->function->call.size += 8; + } + jit_dec_synth(); +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_int32_t regno; + assert(_jitc->function != NULL); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argi)) { + jit_movi_f(_F16 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(_jitc->function->call.size + F_DISP, JIT_SP, regno); + _jitc->function->call.size += 8; + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function != NULL); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argi)) { + jit_movr_d(_F16 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi_d(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += 8; + } + jit_dec_synth(); +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; + assert(_jitc->function != NULL); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argi)) { + jit_movi_d(_F16 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(_jitc->function->call.size, JIT_SP, regno); + _jitc->function->call.size += 8; + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + jit_int32_t spec; + + spec = jit_class(_rvs[regno].spec); + if (spec & jit_class_arg) { + if (spec & jit_class_gpr) { + regno = _A0 - regno; + if (regno >= 0 && regno < node->v.w) + return (1); + } + else if (spec & jit_class_fpr) { + regno = _F16 - regno; + if (regno >= 0 && regno < node->w.w) + return (1); + } + } + + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_node_t *call; + assert(_jitc->function != NULL); + jit_inc_synth_w(finishr, r0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + call = jit_callr(r0); + call->v.w = call->w.w = _jitc->function->self.argi; + _jitc->function->call.argi = _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ + jit_node_t *call; + assert(_jitc->function != NULL); + jit_inc_synth_w(finishi, (jit_word_t)i0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + call = jit_calli(i0); + call->v.w = call->w.w = _jitc->function->self.argf; + _jitc->function->call.argi = _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); + return (call); +} + +void +_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_c, r0); + jit_extr_c(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_uc, r0); + jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_s, r0); + jit_extr_s(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_us, r0); + jit_extr_us(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_i, r0); + jit_extr_i(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_ui, r0); + jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_l, r0); + if (r0 != JIT_RET) + jit_movr(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_f, r0); + if (r0 != JIT_FRET) + jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_d, r0); + if (r0 != JIT_FRET) + jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_word_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_uint8_t *data; + jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + jit_int32_t const_offset; + jit_int32_t patch_offset; + } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + + _jitc->function = NULL; + + jit_reglive_setup(); + + undo.word = 0; + undo.node = NULL; + undo.const_offset = undo.patch_offset = 0; +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \ + break +#define case_rrf(name, type, size) \ + case jit_code_##name##i##type: \ + assert(node->flag & jit_flag_data); \ + name##i##type(rn(node->u.w), rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type(_jit->pc.w, \ + rn(node->v.w), rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break +#define case_brf(name, type, size) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + else { \ + word = name##i##type(_jit->pc.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + patch(word, node); \ + } \ + break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end) + return (NULL); + +#if DEVEL_DISASSEMBLER + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; +#endif + value = jit_classify(node->code); + jit_regarg_set(node, value); + switch (node->code) { + case jit_code_align: + assert(!(node->u.w & (node->u.w - 1)) && + node->u.w <= sizeof(jit_word_t)); + if (node->u.w == sizeof(jit_word_t) && + (word = _jit->pc.w & (sizeof(jit_word_t) - 1))) + nop(sizeof(jit_word_t) - word); + break; + case jit_code_note: case jit_code_name: + node->u.w = _jit->pc.w; + break; + case jit_code_label: + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + break; + case_rrr(add,); + case_rrw(add,); + case_rrr(addc,); + case_rrw(addc,); + case_rrr(addx,); + case_rrw(addx,); + case_rrr(sub,); + case_rrw(sub,); + case_rrr(subc,); + case_rrw(subc,); + case_rrr(subx,); + case_rrw(subx,); + case_rrw(rsb,); + case_rrr(mul,); + case_rrw(mul,); + case_rrrr(qmul,); + case_rrrw(qmul,); + case_rrrr(qmul, _u); + case_rrrw(qmul, _u); + case_rrr(div,); + case_rrw(div,); + case_rrr(div, _u); + case_rrw(div, _u); + case_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_rr(trunc, _f_i); + case_rr(trunc, _d_i); + case_rr(trunc, _f_l); + case_rr(trunc, _d_l); + case_rr(ld, _c); + case_rw(ld, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rr(ld, _i); + case_rw(ld, _i); + case_rr(ld, _ui); + case_rw(ld, _ui); + case_rr(ld, _l); + case_rw(ld, _l); + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rrr(ldx, _i); + case_rrw(ldx, _i); + case_rrr(ldx, _ui); + case_rrw(ldx, _ui); + case_rrr(ldx, _l); + case_rrw(ldx, _l); + case_rr(st, _c); + case_wr(st, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rr(st, _i); + case_wr(st, _i); + case_rr(st, _l); + case_wr(st, _l); + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rrr(stx, _i); + case_wrr(stx, _i); + case_rrr(stx, _l); + case_wrr(stx, _l); + case_rr(hton, _us); + case_rr(hton, _ui); + case_rr(hton, _ul); + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); + case_rr(ext, _i); + case_rr(ext, _ui); + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), node->v.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rr(neg,); + case_rr(com,); + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_rrr(add, _f); + case_rrf(add, _f, 32); + case_rrr(sub, _f); + case_rrf(sub, _f, 32); + case_rrf(rsb, _f, 32); + case_rrr(mul, _f); + case_rrf(mul, _f, 32); + case_rrr(div, _f); + case_rrf(div, _f, 32); + case_rr(abs, _f); + case_rr(neg, _f); + case_rr(sqrt, _f); + case_rr(ext, _f); + case_rr(ld, _f); + case_rw(ld, _f); + case_rrr(ldx, _f); + case_rrw(ldx, _f); + case_rr(st, _f); + case_wr(st, _f); + case_rrr(stx, _f); + case_wrr(stx, _f); + case_rr(mov, _f); + case jit_code_movi_f: + assert(node->flag & jit_flag_data); + movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); + break; + case_rr(ext, _d_f); + case_rrr(lt, _f); + case_rrf(lt, _f, 32); + case_rrr(le, _f); + case_rrf(le, _f, 32); + case_rrr(eq, _f); + case_rrf(eq, _f, 32); + case_rrr(ge, _f); + case_rrf(ge, _f, 32); + case_rrr(gt, _f); + case_rrf(gt, _f, 32); + case_rrr(ne, _f); + case_rrf(ne, _f, 32); + case_rrr(unlt, _f); + case_rrf(unlt, _f, 32); + case_rrr(unle, _f); + case_rrf(unle, _f, 32); + case_rrr(uneq, _f); + case_rrf(uneq, _f, 32); + case_rrr(unge, _f); + case_rrf(unge, _f, 32); + case_rrr(ungt, _f); + case_rrf(ungt, _f, 32); + case_rrr(ltgt, _f); + case_rrf(ltgt, _f, 32); + case_rrr(ord, _f); + case_rrf(ord, _f, 32); + case_rrr(unord, _f); + case_rrf(unord, _f, 32); + case_brr(blt, _f); + case_brf(blt, _f, 32); + case_brr(ble, _f); + case_brf(ble, _f, 32); + case_brr(beq, _f); + case_brf(beq, _f, 32); + case_brr(bge, _f); + case_brf(bge, _f, 32); + case_brr(bgt, _f); + case_brf(bgt, _f, 32); + case_brr(bne, _f); + case_brf(bne, _f, 32); + case_brr(bunlt, _f); + case_brf(bunlt, _f, 32); + case_brr(bunle, _f); + case_brf(bunle, _f, 32); + case_brr(buneq, _f); + case_brf(buneq, _f, 32); + case_brr(bunge, _f); + case_brf(bunge, _f, 32); + case_brr(bungt, _f); + case_brf(bungt, _f, 32); + case_brr(bltgt, _f); + case_brf(bltgt, _f, 32); + case_brr(bord, _f); + case_brf(bord, _f, 32); + case_brr(bunord, _f); + case_brf(bunord, _f, 32); + case_rrr(add, _d); + case_rrf(add, _d, 64); + case_rrr(sub, _d); + case_rrf(sub, _d, 64); + case_rrf(rsb, _d, 64); + case_rrr(mul, _d); + case_rrf(mul, _d, 64); + case_rrr(div, _d); + case_rrf(div, _d, 64); + case_rr(abs, _d); + case_rr(neg, _d); + case_rr(sqrt, _d); + case_rr(ext, _d); + case_rr(ld, _d); + case_rw(ld, _d); + case_rrr(ldx, _d); + case_rrw(ldx, _d); + case_rr(st, _d); + case_wr(st, _d); + case_rrr(stx, _d); + case_wrr(stx, _d); + case_rr(mov, _d); + case jit_code_movi_d: + assert(node->flag & jit_flag_data); + movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w); + break; + case_rr(ext, _f_d); + case_rrr(lt, _d); + case_rrf(lt, _d, 64); + case_rrr(le, _d); + case_rrf(le, _d, 64); + case_rrr(eq, _d); + case_rrf(eq, _d, 64); + case_rrr(ge, _d); + case_rrf(ge, _d, 64); + case_rrr(gt, _d); + case_rrf(gt, _d, 64); + case_rrr(ne, _d); + case_rrf(ne, _d, 64); + case_rrr(unlt, _d); + case_rrf(unlt, _d, 64); + case_rrr(unle, _d); + case_rrf(unle, _d, 64); + case_rrr(uneq, _d); + case_rrf(uneq, _d, 64); + case_rrr(unge, _d); + case_rrf(unge, _d, 64); + case_rrr(ungt, _d); + case_rrf(ungt, _d, 64); + case_rrr(ltgt, _d); + case_rrf(ltgt, _d, 64); + case_rrr(ord, _d); + case_rrf(ord, _d, 64); + case_rrr(unord, _d); + case_rrf(unord, _d, 64); + case_brr(blt, _d); + case_brf(blt, _d, 64); + case_brr(ble, _d); + case_brf(ble, _d, 64); + case_brr(beq, _d); + case_brf(beq, _d, 64); + case_brr(bge, _d); + case_brf(bge, _d, 64); + case_brr(bgt, _d); + case_brf(bgt, _d, 64); + case_brr(bne, _d); + case_brf(bne, _d, 64); + case_brr(bunlt, _d); + case_brf(bunlt, _d, 64); + case_brr(bunle, _d); + case_brf(bunle, _d, 64); + case_brr(buneq, _d); + case_brf(buneq, _d, 64); + case_brr(bunge, _d); + case_brf(bunge, _d, 64); + case_brr(bungt, _d); + case_brf(bungt, _d, 64); + case_brr(bltgt, _d); + case_brf(bltgt, _d, 64); + case_brr(bord, _d); + case_brf(bord, _d, 64); + case_brr(bunord, _d); + case_brf(bunord, _d, 64); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + break; + case jit_code_jmpi: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } + } + else + jmpi(node->u.w); + break; + case jit_code_callr: + callr(rn(node->u.w)); + break; + case jit_code_calli: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (!(temp->flag & jit_flag_patch)) { + word = calli_p(temp->u.w); + patch(word, node); + } + else + calli(temp->u.w); + } + else + calli(node->u.w); + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif + undo.patch_offset = _jitc->patches.offset; + restart_function: + _jitc->again = 0; + prolog(node); + break; + case jit_code_epilog: + assert(_jitc->function == _jitc->functions.ptr + node->w.w); + if (_jitc->again) { + for (temp = undo.node->next; + temp != node; temp = temp->next) { + if (temp->code == jit_code_label || + temp->code == jit_code_epilog) + temp->flag &= ~jit_flag_patch; + } + temp->flag &= ~jit_flag_patch; + node = undo.node; + _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif + _jitc->patches.offset = undo.patch_offset; + goto restart_function; + } + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + epilog(node); + _jitc->function = NULL; + break; + case jit_code_va_start: + vastart(rn(node->u.w)); + break; + case jit_code_va_arg: + vaarg(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_va_arg_d: + vaarg_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_live: case jit_code_ellipsis: + case jit_code_va_push: + case jit_code_allocai: case jit_code_allocar: + case jit_code_arg: + case jit_code_arg_f: case jit_code_arg_d: + case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: case jit_code_getarg_ui: + case jit_code_getarg_l: + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: + case jit_code_retval_ui: case jit_code_retval_l: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: + break; + default: + abort(); + } + if (jit_carry != _NOREG) { + switch (node->code) { + case jit_code_note: + case jit_code_addcr: case jit_code_addci: + case jit_code_addxr: case jit_code_addxi: + case jit_code_subcr: case jit_code_subci: + case jit_code_subxr: case jit_code_subxi: + break; + default: + jit_unget_reg(jit_carry); + jit_carry = _NOREG; + break; + } + } + jit_regarg_clr(node, value); + assert(_jitc->regarg == 0 || + (jit_carry != _NOREG && _jitc->regarg == (1 << jit_carry))); + assert(_jitc->synth == 0); + /* update register live state */ + jit_reglive(node); + } +#undef case_brf +#undef case_brw +#undef case_brr +#undef case_wrr +#undef case_rrrw +#undef case_rrrr +#undef case_rrf +#undef case_rrw +#undef case_rrr +#undef case_wr +#undef case_rw +#undef case_rr + for (offset = 0; offset < _jitc->patches.offset; offset++) { + node = _jitc->patches.ptr[offset].node; + word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(_jitc->patches.ptr[offset].inst, word); + } + + jit_flush(_jit->code.ptr, _jit->pc.uc); + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_alpha-cpu.c" +# include "jit_alpha-fpu.c" +#undef CODE + +void +jit_flush(void *fptr, void *tptr) +{ +} + +void +_emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi(rn(r0), rn(r1), i0); +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi(i0, rn(r0), rn(r1)); +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi_d(rn(r0), rn(r1), i0); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi_d(i0, rn(r0), rn(r1)); +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) + flag = node->v.n->flag; + else + flag = node->u.n->flag; + assert(!(flag & jit_flag_patch)); + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} diff --git a/deps/lightning/lib/jit_arm-cpu.c b/deps/lightning/lib/jit_arm-cpu.c new file mode 100644 index 0000000..b6ee260 --- /dev/null +++ b/deps/lightning/lib/jit_arm-cpu.c @@ -0,0 +1,3955 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# define stxi(i0,r0,r1) stxi_i(i0,r0,r1) +# define ldxi(r0,r1,i0) ldxi_i(r0,r1,i0) +# define ldr(r0,r1) ldr_i(r0,r1) +# define _s20P(d) ((d) >= -(int)0x80000 && d <= 0x7ffff) +# define _s24P(d) ((d) >= -(int)0x800000 && d <= 0x7fffff) +# define _u3(v) ((v) & 0x7) +# define _u4(v) ((v) & 0xf) +# define _u5(v) ((v) & 0x1f) +# define _u8(v) ((v) & 0xff) +# define _u12(v) ((v) & 0xfff) +# define _u13(v) ((v) & 0x1fff) +# define _u16(v) ((v) & 0xffff) +# define _u24(v) ((v) & 0xffffff) +# define jit_thumb_p() jit_cpu.thumb +# define jit_no_set_flags() _jitc->no_set_flags +# define jit_armv5_p() (jit_cpu.version >= 5) +# define jit_armv5e_p() (jit_cpu.version > 5 || (jit_cpu.version == 5 && jit_cpu.extend)) +# define jit_armv6_p() (jit_cpu.version >= 6) +# define jit_armv7r_p() 0 +# define stack_framesize 48 +extern int __aeabi_idivmod(int, int); +extern unsigned __aeabi_uidivmod(unsigned, unsigned); +# define _R0_REGNO 0x00 +# define _R1_REGNO 0x01 +# define _R2_REGNO 0x02 +# define _R3_REGNO 0x03 +# define _R4_REGNO 0x04 +# define _R5_REGNO 0x05 +# define _R6_REGNO 0x06 +# define _R7_REGNO 0x07 +# define _R8_REGNO 0x08 +# define _R9_REGNO 0x09 +# define _R10_REGNO 0x0a +# define _R11_REGNO 0x0b +# define _R12_REGNO 0x0c +# define _R13_REGNO 0x0d +# define _R14_REGNO 0x0e +# define _R15_REGNO 0x0f +# define _FP_REGNO _R11_REGNO +# define _SP_REGNO _R13_REGNO +# define _LR_REGNO _R14_REGNO +# define _PC_REGNO _R15_REGNO +# define ARM_CC_EQ 0x00000000 /* Z=1 */ +# define ARM_CC_NE 0x10000000 /* Z=0 */ +# define ARM_CC_HS 0x20000000 /* C=1 */ +# define ARM_CC_CS ARM_CC_HS +# define ARM_CC_LO 0x30000000 /* C=0 */ +# define ARM_CC_CC ARM_CC_LO +# define ARM_CC_MI 0x40000000 /* N=1 */ +# define ARM_CC_PL 0x50000000 /* N=0 */ +# define ARM_CC_VS 0x60000000 /* V=1 */ +# define ARM_CC_VC 0x70000000 /* V=0 */ +# define ARM_CC_HI 0x80000000 /* C=1 && Z=0 */ +# define ARM_CC_LS 0x90000000 /* C=0 || Z=1 */ +# define ARM_CC_GE 0xa0000000 /* N=V */ +# define ARM_CC_LT 0xb0000000 /* N!=V */ +# define ARM_CC_GT 0xc0000000 /* Z=0 && N=V */ +# define ARM_CC_LE 0xd0000000 /* Z=1 || N!=V */ +# define ARM_CC_AL 0xe0000000 /* always */ +# define ARM_CC_NV 0xf0000000 /* reserved */ +# define THUMB2_IT 0 +# define THUMB2_ITT 1 +# define THUMB2_ITE 2 +# define THUMB2_ITTT 3 +# define THUMB2_ITET 4 +# define THUMB2_ITTE 5 +# define THUMB2_ITEE 6 +# define THUMB2_ITTTT 7 +# define THUMB2_ITETT 8 +# define THUMB2_ITTET 9 +# define THUMB2_ITEET 10 +# define THUMB2_ITTTE 11 +# define THUMB2_ITETE 12 +# define THUMB2_ITTEE 13 +# define THUMB2_ITEEE 14 +# define ARM_MOV 0x01a00000 +# define THUMB_MOV 0x4600 +# define ARM_MOVWI 0x03000000 /* v6t2, v7 */ +# define THUMB_MOVI 0x2000 +# define THUMB2_MOVI 0xf0400000 +# define THUMB2_MOVWI 0xf2400000 +# define ARM_MOVTI 0x03400000 +# define THUMB2_MOVTI 0xf2c00000 +# define ARM_MVN 0x01e00000 +# define THUMB_MVN 0x43c0 +# define THUMB2_MVN 0xea600000 +# define THUMB2_MVNI 0xf0600000 +# define ARM_I 0x02000000 /* immediate */ +# define ARM_S 0x00100000 /* set flags */ +# define ARM_ADD 0x00800000 +# define THUMB_ADD 0x1800 +# define THUMB_ADDX 0x4400 +# define THUMB2_ADD 0xeb000000 +# define THUMB_ADDI3 0x1c00 +# define THUMB_ADDI8 0x3000 +# define THUMB2_ADDI 0xf1000000 +# define THUMB2_ADDWI 0xf2000000 +# define ARM_ADC 0x00a00000 +# define THUMB_ADC 0x4140 +# define THUMB2_ADC 0xeb400000 +# define THUMB2_ADCI 0xf1400000 +# define ARM_SUB 0x00400000 +# define THUMB_SUB 0x1a00 +# define THUMB2_SUB 0xeba00000 +# define THUMB_SUBI3 0x1e00 +# define THUMB_SUBI8 0x3800 +# define THUMB2_SUBI 0xf1a00000 +# define THUMB2_SUBWI 0xf2a00000 +# define ARM_SBC 0x00c00000 +# define THUMB_SBC 0x4180 +# define THUMB2_SBC 0xeb600000 +# define THUMB2_SBCI 0xf1600000 +# define ARM_RSB 0x00600000 +# define THUMB_RSBI 0x4240 +# define THUMB2_RSBI 0xf1c00000 +# define ARM_MUL 0x00000090 +# define THUMB_MUL 0x4340 +# define THUMB2_MUL 0xfb00f000 +# define ARM_UMULL 0x00800090 +# define THUMB2_UMULL 0xfba00000 +# define ARM_SMULL 0x00c00090 +# define THUMB2_SMULL 0xfb800000 +# define THUMB2_SDIV 0xfb90f0f0 +# define THUMB2_UDIV 0xfbb0f0f0 +# define ARM_AND 0x00000000 +# define THUMB_AND 0x4000 +# define THUMB2_AND 0xea000000 +# define THUMB2_ANDI 0xf0000000 +# define ARM_BIC 0x01c00000 +# define THUMB2_BIC 0xea200000 +# define THUMB2_BICI 0xf0200000 +# define ARM_ORR 0x01800000 +# define THUMB_ORR 0x4300 +# define THUMB2_ORR 0xea400000 +# define THUMB2_ORRI 0xf0400000 +# define ARM_EOR 0x00200000 +# define THUMB_EOR 0x4040 +# define THUMB2_EOR 0xea800000 +# define THUMB2_EORI 0xf0800000 +/* >> ARMv6* */ +# define ARM_REV 0x06bf0f30 +# define THUMB_REV 0xba00 +# define THUMB2_REV 0xfa90f080 +# define ARM_REV16 0x06bf0fb0 +# define THUMB_REV16 0xba40 +# define THUMB2_REV16 0xfa90f090 +# define ARM_SXTB 0x06af0070 +# define THUMB_SXTB 0xb240 +# define THUMB2_SXTB 0xfa40f080 +# define ARM_UXTB 0x06ef0070 +# define THUMB_UXTB 0xb2c0 +# define THUMB2_UXTB 0xfa50f080 +# define ARM_SXTH 0x06bf0070 +# define THUMB_SXTH 0xb200 +# define THUMB2_SXTH 0xfa00f080 +# define ARM_UXTH 0x06ff0070 +# define THUMB_UXTH 0xb280 +# define THUMB2_UXTH 0xfa10f080 +# define ARM_XTR8 0x00000400 /* ?xt? rotate 8 bits */ +# define ARM_XTR16 0x00000800 /* ?xt? rotate 16 bits */ +# define ARM_XTR24 0x00000c00 /* ?xt? rotate 24 bits */ +/* << ARMv6* */ +# define ARM_SHIFT 0x01a00000 +# define ARM_R 0x00000010 /* register shift */ +# define ARM_LSL 0x00000000 +# define THUMB_LSL 0x4080 +# define THUMB2_LSL 0xfa00f000 +# define THUMB_LSLI 0x0000 +# define THUMB2_LSLI 0xea4f0000 +# define ARM_LSR 0x00000020 +# define THUMB_LSR 0x40c0 +# define THUMB2_LSR 0xfa20f000 +# define THUMB_LSRI 0x0800 +# define THUMB2_LSRI 0xea4f0010 +# define ARM_ASR 0x00000040 +# define THUMB_ASR 0x4100 +# define THUMB2_ASR 0xfa40f000 +# define THUMB_ASRI 0x1000 +# define THUMB2_ASRI 0xea4f0020 +# define ARM_ROR 0x00000060 +# define ARM_CMP 0x01500000 +# define THUMB_CMP 0x4280 +# define THUMB_CMPX 0x4500 +# define THUMB2_CMP 0xebb00000 +# define THUMB_CMPI 0x2800 +# define THUMB2_CMPI 0xf1b00000 +# define ARM_CMN 0x01700000 +# define THUMB_CMN 0x42c0 +# define THUMB2_CMN 0xeb100000 +# define THUMB2_CMNI 0xf1100000 +# define ARM_TST 0x01100000 +# define THUMB_TST 0x4200 +# define THUMB2_TST 0xea100000 +# define THUMB2_TSTI 0xf0100000 +# define ARM_TEQ 0x01300000 +/* branch */ +# define ARM_BX 0x012fff10 +# define ARM_BLX 0x012fff30 +# define THUMB_BLX 0x4780 +# define ARM_BLXI 0xfa000000 +# define THUMB2_BLXI 0xf000c000 +# define ARM_B 0x0a000000 +# define THUMB_CC_B 0xd000 +# define THUMB_B 0xe000 +# define THUMB2_CC_B 0xf0008000 +# define THUMB2_B 0xf0009000 +# define ARM_BLI 0x0b000000 +# define THUMB2_BLI 0xf000d000 +/* ldr/str */ +# define ARM_P 0x00800000 /* positive offset */ +# define THUMB2_P 0x00000400 +# define THUMB2_U 0x00000200 +# define THUMB2_W 0x00000100 +# define ARM_LDRSB 0x011000d0 +# define THUMB_LDRSB 0x5600 +# define THUMB2_LDRSB 0xf9100000 +# define ARM_LDRSBI 0x015000d0 +# define THUMB2_LDRSBI 0xf9100c00 +# define THUMB2_LDRSBWI 0xf9900000 +# define ARM_LDRB 0x07500000 +# define THUMB_LDRB 0x5c00 +# define THUMB2_LDRB 0xf8100000 +# define ARM_LDRBI 0x05500000 +# define THUMB_LDRBI 0x7800 +# define THUMB2_LDRBI 0xf8100c00 +# define THUMB2_LDRBWI 0xf8900000 +# define ARM_LDRSH 0x011000f0 +# define THUMB_LDRSH 0x5e00 +# define THUMB2_LDRSH 0xf9300000 +# define ARM_LDRSHI 0x015000f0 +# define THUMB2_LDRSHI 0xf9300c00 +# define THUMB2_LDRSHWI 0xf9b00000 +# define ARM_LDRH 0x011000b0 +# define THUMB_LDRH 0x5a00 +# define THUMB2_LDRH 0xf8300000 +# define ARM_LDRHI 0x015000b0 +# define THUMB_LDRHI 0x8800 +# define THUMB2_LDRHI 0xf8300c00 +# define THUMB2_LDRHWI 0xf8b00000 +# define ARM_LDR 0x07100000 +# define THUMB_LDR 0x5800 +# define THUMB2_LDR 0xf8500000 +# define ARM_LDRI 0x05100000 +# define THUMB_LDRI 0x6800 +# define THUMB_LDRISP 0x9800 +# define THUMB2_LDRI 0xf8500c00 +# define THUMB2_LDRWI 0xf8d00000 +# define ARM_LDRD 0x010000d0 +# define ARM_LDRDI 0x014000d0 +# define THUMB2_LDRDI 0xe8500000 +# define ARM_STRB 0x07400000 +# define THUMB_STRB 0x5400 +# define THUMB2_STRB 0xf8000000 +# define ARM_STRBI 0x05400000 +# define THUMB_STRBI 0x7000 +# define THUMB2_STRBI 0xf8000c00 +# define THUMB2_STRBWI 0xf8800000 +# define ARM_STRH 0x010000b0 +# define THUMB_STRH 0x5200 +# define THUMB2_STRH 0xf8200000 +# define ARM_STRHI 0x014000b0 +# define THUMB_STRHI 0x8000 +# define THUMB2_STRHI 0xf8200c00 +# define THUMB2_STRHWI 0xf8a00000 +# define ARM_STR 0x07000000 +# define THUMB_STR 0x5000 +# define THUMB2_STR 0xf8400000 +# define ARM_STRI 0x05000000 +# define THUMB_STRI 0x6000 +# define THUMB2_STRWI 0xf8c00000 +# define THUMB_STRISP 0x9000 +# define THUMB2_STRI 0xf8400c00 +# define ARM_STRD 0x010000f0 +# define ARM_STRDI 0x014000f0 +# define THUMB2_STRDI 0xe8400000 +/* ldm/stm */ +# define ARM_M 0x08000000 +# define ARM_M_L 0x00100000 /* load; store if not set */ +# define ARM_M_I 0x00800000 /* inc; dec if not set */ +# define ARM_M_B 0x01000000 /* before; after if not set */ +# define ARM_M_U 0x00200000 /* update Rn */ +# define THUMB2_LDM_W 0x00200000 +# define THUMB2_LDM_P 0x00008000 +# define THUMB2_LDM_M 0x00004000 +# define THUMB_LDMIA 0xc800 +# define THUMB2_LDMIA 0xe8900000 +# define THUMB2_LDMB 0xe9100000 +# define THUMB_PUSH 0xb400 +# define THUMB2_PUSH 0xe92d0000 +# define THUMB_POP 0xbc00 +# define THUMB2_POP 0xe8bd0000 +# define ii(i) *_jit->pc.ui++ = i +# define is(i) *_jit->pc.us++ = i +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define iss(i, j) do { is(j); is(i); } while (0) +# define code2thumb(t0, t1, c0, c1) do { t1 = c0; t0 = c1; } while (0) +# define thumb2code(t0, t1, c0, c1) do { c0 = t1; c1 = t0; } while (0) +# else +# define iss(i, j) do { is(i); is(j); } while (0) +# define code2thumb(t0, t1, c0, c1) do { t0 = c0; t1 = c1; } while (0) +# define thumb2code(t0, t1, c0, c1) do { c0 = t0; c1 = t1; } while (0) +# endif +static int encode_arm_immediate(unsigned int v); +static int encode_thumb_immediate(unsigned int v); +static int encode_thumb_word_immediate(unsigned int v); +static int encode_thumb_jump(int v); +static int encode_thumb_cc_jump(int v); +static int encode_thumb_shift(int v, int type) maybe_unused; +# define corrr(cc,o,rn,rd,rm) _corrr(_jit,cc,o,rn,rd,rm) +static void _corrr(jit_state_t*,int,int,int,int,int); +# define corri(cc,o,rn,rd,im) _corri(_jit,cc,o,rn,rd,im) +static void _corri(jit_state_t*,int,int,int,int,int); +#define corri8(cc,o,rn,rt,im) _corri8(_jit,cc,o,rn,rt,im) +static void _corri8(jit_state_t*,int,int,int,int,int); +# define torrr(o,rn,rd,rm) _torrr(_jit,o,rn,rd,rm) +static void _torrr(jit_state_t*,int,int,int,int); +# define torrrs(o,rn,rd,rm,im) _torrrs(_jit,o,rn,rd,rm,im) +static void _torrrs(jit_state_t*,int,int,int,int,int) maybe_unused; +# define torxr(o,rn,rt,rm) _torxr(_jit,o,rn,rt,rm) +static void _torxr(jit_state_t*,int,int,int,int); +# define torrrr(o,rn,rl,rh,rm) _torrrr(_jit,o,rn,rl,rh,rm) +static void _torrrr(jit_state_t*,int,int,int,int,int) maybe_unused; +# define torrri8(o,rn,rt,rt2,im) _torrri8(_jit,o,rn,rt,rt2,im) +static void _torrri8(jit_state_t*,int,int,int,int,int) maybe_unused; +# define coriw(cc,o,rd,im) _coriw(_jit,cc,o,rd,im) +static void _coriw(jit_state_t*,int,int,int,int); +# define torri(o,rd,rn,im) _torri(_jit,o,rd,rn,im) +static void _torri(jit_state_t*,int,int,int,int); +# define torri8(o,rn,rt,im) _torri8(_jit,o,rn,rt,im) +static void _torri8(jit_state_t*,int,int,int,int); +# define torri12(o,rn,rt,im) _torri12(_jit,o,rn,rt,im) +static void _torri12(jit_state_t*,int,int,int,int); +# define tshift(o,rd,rm,im) _tshift(_jit,o,rd,rm,im) +static void _tshift(jit_state_t*,int,int,int,int); +# define toriw(o,rd,im) _toriw(_jit,o,rd,im) +static void _toriw(jit_state_t*,int,int,int); +# define tc8(cc,im) _tc8(_jit,cc,im) +static void _tc8(jit_state_t*,int,int) maybe_unused; +# define t11(im) _t11(_jit,im) +static void _t11(jit_state_t*,int); +# define tcb(cc,im) _tcb(_jit,cc,im) +static void _tcb(jit_state_t*,int,int); +# define blxi(im) _blxi(_jit,im) +static void _blxi(jit_state_t*,int) maybe_unused; +# define tb(o,im) _tb(_jit,o,im) +static void _tb(jit_state_t*,int,int); +# define corrrr(cc,o,rh,rl,rm,rn) _corrrr(_jit,cc,o,rh,rl,rm,rn) +static void _corrrr(jit_state_t*,int,int,int,int,int,int); +# define corrrs(cc,o,rn,rd,rm,im) _corrrs(_jit,cc,o,rn,rd,rm,im) +static void _corrrs(jit_state_t*,int,int,int,int,int,int); +# define cshift(cc,o,rd,rm,rn,im) _cshift(_jit,cc,o,rd,rm,rn,im) +static void _cshift(jit_state_t*,int,int,int,int,int,int); +# define cb(cc,o,im) _cb(_jit,cc,o,im) +static void _cb(jit_state_t*,int,int,int); +# define cbx(cc,o,rm) _cbx(_jit,cc,o,rm) +static void _cbx(jit_state_t*,int,int,int); +# define corl(cc,o,r0,i0) _corl(_jit,cc,o,r0,i0) +static void _corl(jit_state_t*,int,int,int,int); +# define c6orr(cc,o,r0,r1) _c6orr(_jit,cc,o,r0,r1) +static void _c6orr(jit_state_t*,int,int,int,int); +# define tcit(cc,it) _tcit(_jit,cc,it) +static void _tcit(jit_state_t*,unsigned int,int); +# define IT(cc) tcit(cc,THUMB2_IT) +# define ITT(cc) tcit(cc,THUMB2_ITT) +# define ITE(cc) tcit(cc,THUMB2_ITE) +# define ITTT(cc) tcit(cc,THUMB2_ITTT) +# define ITTE(cc) tcit(cc,THUMB2_ITTE) +# define ITET(cc) tcit(cc,THUMB2_ITET) +# define ITEE(cc) tcit(cc,THUMB2_ITEE) +# define ITTTT(cc) tcit(cc,THUMB2_ITTTT) +# define ITETT(cc) tcit(cc,THUMB2_ITETT) +# define ITTET(cc) tcit(cc,THUMB2_ITTET) +# define ITEET(cc) tcit(cc,THUMB2_ITEET) +# define ITTTE(cc) tcit(cc,THUMB2_ITTTE) +# define ITETE(cc) tcit(cc,THUMB2_ITETE) +# define ITTEE(cc) tcit(cc,THUMB2_ITTEE) +# define ITEEE(cc) tcit(cc,THUMB2_ITEEE) +# define tpp(o,im) _tpp(_jit,o,im) +static void _tpp(jit_state_t*,int,int); +# define torl(o,rn,im) _torl(_jit,o,rn,im) +static void _torl(jit_state_t*,int,int,int) maybe_unused; +# define CC_MOV(cc,rd,rm) corrr(cc,ARM_MOV,0,rd,rm) +# define MOV(rd,rm) CC_MOV(ARM_CC_AL,rd,rm) +# define T1_MOV(rd,rm) is(THUMB_MOV|((_u4(rd)&8)<<4)|(_u4(rm)<<3)|(rd&7)) +# define T2_MOV(rd,rm) T2_ORR(rd,_R15_REGNO,rm) +# define CC_MOVI(cc,rd,im) corri(cc,ARM_MOV|ARM_I,0,rd,im) +# define MOVI(rd,im) CC_MOVI(ARM_CC_AL,rd,im) +# define CC_MOVWI(cc,rd,im) coriw(cc,ARM_MOVWI,rd,im) +# define MOVWI(rd,im) CC_MOVWI(ARM_CC_AL,rd,im) +# define T1_MOVI(rd,im) is(THUMB_MOVI|(_u3(rd)<<8)|_u8(im)) +# define T2_MOVI(rd,im) torri(THUMB2_MOVI,_R15_REGNO,rd,im) +# define T2_MOVWI(rd,im) toriw(THUMB2_MOVWI,rd,im) +# define CC_MOVTI(cc,rd,im) coriw(cc,ARM_MOVTI,rd,im) +# define MOVTI(rd,im) CC_MOVTI(ARM_CC_AL,rd,im) +# define T2_MOVTI(rd,im) toriw(THUMB2_MOVTI,rd,im) +# define CC_MVN(cc,rd,rm) corrr(cc,ARM_MVN,0,rd,rm) +# define MVN(rd,rm) CC_MVN(ARM_CC_AL,rd,rm) +# define T1_MVN(rd,rm) is(THUMB_MVN|(_u3(rm)<<3)|_u3(rd)) +# define T2_MVN(rd,rm) torrr(THUMB2_MVN,_R15_REGNO,rd,rm) +# define CC_MVNI(cc,rd,im) corri(cc,ARM_MVN|ARM_I,0,rd,im) +# define MVNI(rd,im) CC_MVNI(ARM_CC_AL,rd,im) +# define T2_MVNI(rd,im) torri(THUMB2_MVNI,_R15_REGNO,rd,im) +# define CC_NOT(cc,rd,rm) CC_MVN(cc,rd,rm) +# define NOT(rd,rm) CC_NOT(ARM_CC_AL,rd,rm) +# define T1_NOT(rd,rm) T1_MVN(rd,rm) +# define T2_NOT(rd,rm) T2_MVN(rd,rm) +# define NOP() MOV(_R0_REGNO, _R0_REGNO) +# define T1_NOP() is(0xbf00) +# define CC_ADD(cc,rd,rn,rm) corrr(cc,ARM_ADD,rn,rd,rm) +# define ADD(rd,rn,rm) CC_ADD(ARM_CC_AL,rd,rn,rm) +# define T1_ADD(rd,rn,rm) is(THUMB_ADD|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rd)) +# define T1_ADDX(rdn,rm) is(THUMB_ADDX|((_u4(rdn)&8)<<4)|(_u4(rm)<<3)|(rdn&7)) +# define T2_ADD(rd,rn,rm) torrr(THUMB2_ADD,rn,rd,rm) +# define CC_ADDI(cc,rd,rn,im) corri(cc,ARM_ADD|ARM_I,rn,rd,im) +# define ADDI(rd,rn,im) CC_ADDI(ARM_CC_AL,rd,rn,im) +# define T1_ADDI3(rd,rn,im) is(THUMB_ADDI3|(_u3(im)<<6)|(_u3(rn)<<3)|_u3(rd)) +# define T1_ADDI8(rdn,im) is(THUMB_ADDI8|(_u3(rdn)<<8)|_u8(im)) +# define T2_ADDI(rd,rn,im) torri(THUMB2_ADDI,rn,rd,im) +# define T2_ADDWI(rd,rn,im) torri(THUMB2_ADDWI,rn,rd,im) +# define CC_ADDS(cc,rd,rn,rm) corrr(cc,ARM_ADD|ARM_S,rn,rd,rm) +# define ADDS(rd,rn,rm) CC_ADDS(ARM_CC_AL,rd,rn,rm) +# define T2_ADDS(rd,rn,rm) torrr(THUMB2_ADD|ARM_S,rn,rd,rm) +# define ADDSI(rd,rn,im) corri(ARM_CC_AL,ARM_ADD|ARM_S|ARM_I,rn,rd,im) +# define T2_ADDSI(rd,rn,im) torri(THUMB2_ADDI|ARM_S,rn,rd,im) +# define CC_ADC(cc,rd,rn,rm) corrr(cc,ARM_ADC,rn,rd,rm) +# define ADC(rd,rn,rm) CC_ADC(ARM_CC_AL,rd,rn,rm) +# define T1_ADC(rdn,rm) is(THUMB_ADC|(_u3(rm)<<3)|_u3(rdn)) +# define T2_ADC(rd,rn,rm) torrr(THUMB2_ADC,rn,rd,rm) +# define CC_ADCI(cc,rd,rn,im) corri(cc,ARM_ADC|ARM_I,rn,rd,im) +# define ADCI(rd,rn,im) CC_ADCI(ARM_CC_AL,rd,rn,im) +# define T2_ADCI(rd,rn,im) torri(THUMB2_ADCI,rn,rd,im) +# define CC_ADCS(cc,rd,rn,rm) corrr(cc,ARM_ADC|ARM_S,rn,rd,rm) +# define ADCS(rd,rn,rm) CC_ADCS(ARM_CC_AL,rd,rn,rm) +# define T2_ADCS(rd,rn,rm) torrr(THUMB2_ADC|ARM_S,rn,rd,rm) +# define CC_ADCSI(cc,rd,rn,im) corri(cc,ARM_ADC|ARM_S|ARM_I,rn,rd,im) +# define ADCSI(rd,rn,im) CC_ADCSI(ARM_CC_AL,rd,rn,im) +# define T2_ADCSI(rd,rn,im) torri(THUMB2_ADCI|ARM_S,rn,rd,im) +# define CC_SUB(cc,rd,rn,rm) corrr(cc,ARM_SUB,rn,rd,rm) +# define SUB(rd,rn,rm) CC_SUB(ARM_CC_AL,rd,rn,rm) +# define T1_SUB(rd,rn,rm) is(THUMB_SUB|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rd)) +# define T2_SUB(rd,rn,rm) torrr(THUMB2_SUB,rn,rd,rm) +# define CC_SUBI(cc,rd,rn,im) corri(cc,ARM_SUB|ARM_I,rn,rd,im) +# define SUBI(rd,rn,im) CC_SUBI(ARM_CC_AL,rd,rn,im) +# define T1_SUBI3(rd,rn,im) is(THUMB_SUBI3|(_u3(im)<<6)|(_u3(rn)<<3)|_u3(rd)) +# define T1_SUBI8(rdn,im) is(THUMB_SUBI8|(_u3(rdn)<<8)|_u8(im)) +# define T2_SUBI(rd,rn,im) torri(THUMB2_SUBI,rn,rd,im) +# define T2_SUBWI(rd,rn,im) torri(THUMB2_SUBWI,rn,rd,im) +# define CC_SUBS(cc,rd,rn,rm) corrr(cc,ARM_SUB|ARM_S,rn,rd,rm) +# define SUBS(rd,rn,rm) CC_SUBS(ARM_CC_AL,rd,rn,rm) +# define T2_SUBS(rd,rn,rm) torrr(THUMB2_SUB|ARM_S,rn,rd,rm) +# define CC_SUBSI(cc,rd,rn,im) corri(cc,ARM_SUB|ARM_S|ARM_I,rn,rd,im) +# define SUBSI(rd,rn,im) CC_SUBSI(ARM_CC_AL,rd,rn,im) +# define T2_SUBSI(rd,rn,im) torri(THUMB2_SUBI|ARM_S,rn,rd,im) +# define CC_SBC(cc,rd,rn,rm) corrr(cc,ARM_SBC,rn,rd,rm) +# define SBC(rd,rn,rm) CC_SBC(ARM_CC_AL,rd,rn,rm) +# define T1_SBC(rdn,rm) is(THUMB_SBC|(_u3(rm)<<3)|_u3(rdn)) +# define T2_SBC(rd,rn,rm) torrr(THUMB2_SBC,rn,rd,rm) +# define CC_SBCI(cc,rd,rn,im) corri(cc,ARM_SBC|ARM_I,rn,rd,im) +# define SBCI(rd,rn,im) CC_SBCI(ARM_CC_AL,rd,rn,im) +# define T2_SBCI(rd,rn,im) torri(THUMB2_SBCI,rn,rd,im) +# define CC_SBCS(cc,rd,rn,rm) corrr(cc,ARM_SBC|ARM_S,rn,rd,rm) +# define SBCS(rd,rn,rm) CC_SBCS(ARM_CC_AL,rd,rn,rm) +# define T2_SBCS(rd,rn,rm) torrr(THUMB2_SBC|ARM_S,rn,rd,rm) +# define CC_SBCSI(cc,rd,rn,im) corri(cc,ARM_SBC|ARM_S|ARM_I,rn,rd,im) +# define SBCSI(rd,rn,im) CC_SBCSI(ARM_CC_AL,rd,rn,im) +# define T2_SBCSI(rd,rn,im) torri(THUMB2_SBCI|ARM_S,rn,rd,im) +# define CC_RSB(cc,rd,rn,rm) corrr(cc,ARM_RSB,rn,rd,rm) +# define RSB(rd,rn,rm) CC_RSB(ARM_CC_AL,rd,rn,rm) +# define T2_RSB(rd,rn,rm) torrr(THUMB2_RSB,rn,rd,rm) +# define CC_RSBI(cc,rd,rn,im) corri(cc,ARM_RSB|ARM_I,rn,rd,im) +# define RSBI(rd,rn,im) CC_RSBI(ARM_CC_AL,rd,rn,im) +# define T1_RSBI(rd,rn) is(THUMB_RSBI|(_u3(rn)<<3)|_u3(rd)) +# define T2_RSBI(rd,rn,im) torri(THUMB2_RSBI,rn,rd,im) +# define CC_MUL(cc,rl,rn,rm) corrrr(cc,ARM_MUL,rl,0,rm,rn) +# define MUL(rl,rn,rm) CC_MUL(ARM_CC_AL,rl,rn,rm) +# define T1_MUL(rdm,rn) is(THUMB_MUL|(_u3(rn)<<3)|_u3(rdm)) +# define T2_MUL(rd,rn,rm) torrr(THUMB2_MUL,rn,rd,rm) +# define CC_SMULL(cc,rl,rh,rn,rm) corrrr(cc,ARM_SMULL,rh,rl,rm,rn) +# define SMULL(rl,rh,rn,rm) CC_SMULL(ARM_CC_AL,rl,rh,rn,rm) +# define T2_SMULL(rl,rh,rn,rm) torrrr(THUMB2_SMULL,rn,rl,rh,rm) +# define CC_UMULL(cc,rl,rh,rn,rm) corrrr(cc,ARM_UMULL,rh,rl,rm,rn) +# define UMULL(rl,rh,rn,rm) CC_UMULL(ARM_CC_AL,rl,rh,rn,rm) +# define T2_UMULL(rl,rh,rn,rm) torrrr(THUMB2_UMULL,rn,rl,rh,rm) +# define T2_SDIV(rd,rn,rm) torrr(THUMB2_SDIV,rn,rd,rm) +# define T2_UDIV(rd,rn,rm) torrr(THUMB2_UDIV,rn,rd,rm) +# define CC_AND(cc,rd,rn,rm) corrr(cc,ARM_AND,rn,rd,rm) +# define AND(rd,rn,rm) CC_AND(ARM_CC_AL,rd,rn,rm) +# define T1_AND(rdn,rm) is(THUMB_AND|(_u3(rm)<<3)|_u3(rdn)) +# define T2_AND(rd,rn,rm) torrr(THUMB2_AND,rn,rd,rm) +# define CC_ANDI(cc,rd,rn,im) corri(cc,ARM_AND|ARM_I,rn,rd,im) +# define ANDI(rd,rn,im) CC_ANDI(ARM_CC_AL,rd,rn,im) +# define T2_ANDI(rd,rn,im) torri(THUMB2_ANDI,rn,rd,im) +# define CC_ANDS(cc,rd,rn,rm) corrr(cc,ARM_AND|ARM_S,rn,rd,rm) +# define ANDS(rd,rn,rm) CC_ANDS(ARM_CC_AL,rd,rn,rm) +# define T2_ANDS(rd,rn,rm) torrr(THUMB2_AND|ARM_S,rn,rd,rm) +# define CC_ANDSI(cc,rd,rn,im) corri(cc,ARM_AND|ARM_S|ARM_I,rn,rd,im) +# define ANDSI(rd,rn,im) CC_ANDSI(ARM_CC_AL,rd,rn,im) +# define T2_ANDSI(rd,rn,im) torri(ARM_CC_AL,THUMB2_ANDI|ARM_S,rn,rd,im) +# define CC_BIC(cc,rd,rn,rm) corrr(cc,ARM_BIC,rn,rd,rm) +# define BIC(rd,rn,rm) CC_BIC(ARM_CC_AL,rd,rn,rm) +# define T2_BIC(rd,rn,rm) torrr(THUMB2_BIC,rn,rd,rm) +# define CC_BICI(cc,rd,rn,im) corri(cc,ARM_BIC|ARM_I,rn,rd,im) +# define BICI(rd,rn,im) CC_BICI(ARM_CC_AL,rd,rn,im) +# define T2_BICI(rd,rn,im) torri(THUMB2_BICI,rn,rd,im) +# define CC_BICS(cc,rd,rn,rm) corrr(cc,ARM_BIC|ARM_S,rn,rd,rm) +# define BICS(rd,rn,rm) CC_BICS(ARM_CC_AL,rd,rn,rm) +# define T2_BICS(rd,rn,rm) torrr(THUMB2_BIC|ARM_S,rn,rd,rm) +# define CC_BICSI(cc,rd,rn,im) corri(cc,ARM_BIC|ARM_S|ARM_I,rn,rd,im) +# define BICSI(rd,rn,im) CC_BICSI(ARM_CC_AL,rd,rn,im) +# define T2_BICSI(rd,rn,im) torri(ARM_CC_AL,THUMB2_BICI|ARM_S,rn,rd,im) +# define CC_ORR(cc,rd,rn,rm) corrr(cc,ARM_ORR,rn,rd,rm) +# define ORR(rd,rn,rm) CC_ORR(ARM_CC_AL,rd,rn,rm) +# define T1_ORR(rdn,rm) is(THUMB_ORR|(_u3(rm)<<3)|_u3(rdn)) +# define T2_ORR(rd,rn,rm) torrr(THUMB2_ORR,rn,rd,rm) +# define CC_ORR_SI(cc,rd,rn,rt,sh,im) corrrs(cc,ARM_ORR|sh,rn,rd,rm,im) +# define ORR_SI(r0,r1,r2,sh,im) CC_ORR_SI(ARM_CC_AL,r0,r1,r2,sh,im) +# define CC_ORRI(cc,rd,rn,im) corri(cc,ARM_ORR|ARM_I,rn,rd,im) +# define ORRI(rd,rn,im) CC_ORRI(ARM_CC_AL,rd,rn,im) +# define T2_ORRI(rd,rn,im) torri(THUMB2_ORRI,rn,rd,im) +# define CC_EOR(cc,rd,rn,rm) corrr(cc,ARM_EOR,rn,rd,rm) +# define EOR(rd,rn,rm) CC_EOR(ARM_CC_AL,rd,rn,rm) +# define T1_EOR(rdn,rm) is(THUMB_EOR|(_u3(rm)<<3)|_u3(rdn)) +# define T2_EOR(rd,rn,rm) torrr(THUMB2_EOR,rn,rd,rm) +# define CC_EOR_SI(cc,rd,rn,rm,sh,im) corrrs(cc,ARM_EOR|sh,rn,rd,rm,im) +# define EOR_SI(r0,r1,r2,sh,im) CC_EOR_SI(ARM_CC_AL,r0,r1,r2,sh,im) +# define CC_EORI(cc,rd,rn,im) corri(cc,ARM_EOR|ARM_I,rn,rd,im) +# define EORI(rd,rn,im) CC_EORI(ARM_CC_AL,rd,rn,im) +# define T2_EORI(rd,rn,im) torri(THUMB2_EORI,rn,rd,im) +# define CC_REV(cc,rd,rm) c6orr(cc,ARM_REV,rd,rm) +# define REV(rd,rm) CC_REV(ARM_CC_AL,rd,rm) +# define T1_REV(rd,rm) is(THUMB_REV|(_u3(rm)<<3)|_u3(rd)) +# define T2_REV(rd,rm) torrr(THUMB2_REV,rm,rd,rm) +# define CC_REV16(cc,rd,rm) c6orr(cc,ARM_REV16,rd,rm) +# define REV16(rd,rm) CC_REV16(ARM_CC_AL,rd,rm) +# define T1_REV16(rd,rm) is(THUMB_REV16|(_u3(rm)<<3)|_u3(rd)) +# define T2_REV16(rd,rm) torrr(THUMB2_REV16,rm,rd,rm) +# define CC_SXTB(cc,rd,rm) c6orr(cc,ARM_SXTB,rd,rm) +# define SXTB(rd,rm) CC_SXTB(ARM_CC_AL,rd,rm) +# define T1_SXTB(rd,rm) is(THUMB_SXTB|(_u3(rm)<<3)|_u3(rd)) +# define T2_SXTB(rd,rm) torrr(THUMB2_SXTB,_R15_REGNO,rd,rm) +# define CC_UXTB(cc,rd,rm) c6orr(cc,ARM_UXTB,rd,rm) +# define UXTB(rd,rm) CC_UXTB(ARM_CC_AL,rd,rm) +# define T1_UXTB(rd,rm) is(THUMB_UXTB|(_u3(rm)<<3)|_u3(rd)) +# define T2_UXTB(rd,rm) torrr(THUMB2_UXTB,_R15_REGNO,rd,rm) +# define CC_SXTH(cc,rd,rm) c6orr(cc,ARM_SXTH,rd,rm) +# define SXTH(rd,rm) CC_SXTH(ARM_CC_AL,rd,rm) +# define T1_SXTH(rd,rm) is(THUMB_SXTH|(_u3(rm)<<3)|_u3(rd)) +# define T2_SXTH(rd,rm) torrr(THUMB2_SXTH,_R15_REGNO,rd,rm) +# define CC_UXTH(cc,rd,rm) c6orr(cc,ARM_UXTH,rd,rm) +# define UXTH(rd,rm) CC_UXTH(ARM_CC_AL,rd,rm) +# define T1_UXTH(rd,rm) is(THUMB_UXTH|(_u3(rm)<<3)|_u3(rd)) +# define T2_UXTH(rd,rm) torrr(THUMB2_UXTH,_R15_REGNO,rd,rm) +# define CC_SHIFT(cc,o,rd,rm,rn,im) cshift(cc,o,rd,rm,rn,im) +# define CC_LSL(cc,rd,rn,rm) CC_SHIFT(cc,ARM_LSL|ARM_R,rd,rm,rn,0) +# define LSL(rd,rn,rm) CC_LSL(ARM_CC_AL,rd,rn,rm) +# define T1_LSL(rdn,rm) is(THUMB_LSL|(_u3(rm)<<3)|_u3(rdn)) +# define T2_LSL(rd,rn,rm) torrr(THUMB2_LSL,rn,rd,rm) +# define CC_LSLI(cc,rd,rn,im) CC_SHIFT(cc,ARM_LSL,rd,0,rn,im) +# define LSLI(rd,rn,im) CC_LSLI(ARM_CC_AL,rd,rn,im) +# define T1_LSLI(rd,rm,im) is(THUMB_LSLI|(_u5(im)<<6)|(_u3(rm)<<3)|_u3(rd)) +# define T2_LSLI(rd,rm,im) tshift(THUMB2_LSLI,rd,rm,im) +# define CC_LSR(cc,rd,rn,rm) CC_SHIFT(cc,ARM_LSR|ARM_R,rd,rm,rn,0) +# define LSR(rd,rn,rm) CC_LSR(ARM_CC_AL,rd,rn,rm) +# define T1_LSR(rdn,rm) is(THUMB_LSR|(_u3(rm)<<3)|_u3(rdn)) +# define T2_LSR(rd,rn,rm) torrr(THUMB2_LSR,rn,rd,rm) +# define CC_LSRI(cc,rd,rn,im) CC_SHIFT(cc,ARM_LSR,rd,0,rn,im) +# define LSRI(rd,rn,im) CC_LSRI(ARM_CC_AL,rd,rn,im) +# define T1_LSRI(rd,rm,im) is(THUMB_LSRI|(_u5(im)<<6)|(_u3(rm)<<3)|_u3(rd)) +# define T2_LSRI(rd,rm,im) tshift(THUMB2_LSRI,rd,rm,im) +# define CC_ASR(cc,rd,rn,rm) CC_SHIFT(cc,ARM_ASR|ARM_R,rd,rm,rn,0) +# define ASR(rd,rn,rm) CC_ASR(ARM_CC_AL,rd,rn,rm) +# define T1_ASR(rdn,rm) is(THUMB_ASR|(_u3(rm)<<3)|_u3(rdn)) +# define T2_ASR(rd,rn,rm) torrr(THUMB2_ASR,rn,rd,rm) +# define CC_ASRI(cc,rd,rn,im) CC_SHIFT(cc,ARM_ASR,rd,0,rn,im) +# define ASRI(rd,rn,im) CC_ASRI(ARM_CC_AL,rd,rn,im) +# define T1_ASRI(rd,rm,im) is(THUMB_ASRI|(_u5(im)<<6)|(_u3(rm)<<3)|_u3(rd)) +# define T2_ASRI(rd,rm,im) tshift(THUMB2_ASRI,rd,rm,im) +# define CC_CMP(cc,rn,rm) corrr(cc,ARM_CMP,rn,0,rm) +# define CMP(rn,rm) CC_CMP(ARM_CC_AL,rn,rm) +# define T1_CMP(rn,rm) is(THUMB_CMP|(_u3(rm)<<3)|_u3(rn)) +# define T1_CMPX(rn,rm) is(THUMB_CMPX|((_u4(rn)&8)<<4)|(_u4(rm)<<3)|(rn&7)) +# define T2_CMP(rn,rm) torrr(THUMB2_CMP,rn,_R15_REGNO,rm) +# define CC_CMPI(cc,rn,im) corri(cc,ARM_CMP|ARM_I,rn,0,im) +# define CMPI(rn,im) CC_CMPI(ARM_CC_AL,rn,im) +# define T1_CMPI(rn,im) is(THUMB_CMPI|(_u3(rn)<<8)|_u8(im)) +# define T2_CMPI(rn,im) torri(THUMB2_CMPI,rn,_R15_REGNO,im) +# define CC_CMN(cc,rn,rm) corrr(cc,ARM_CMN,rn,0,rm) +# define CMN(rn,rm) CC_CMN(ARM_CC_AL,rn,rm) +# define T1_CMN(rn,rm) is(THUMB_CMN|(_u3(rm)<<3)|_u3(rm)) +# define T2_CMN(rn,rm) torrr(THUMB2_CMN,rn,_R15_REGNO,rm) +# define CC_CMNI(cc,rn,im) corri(cc,ARM_CMN|ARM_I,rn,0,im) +# define CMNI(rn,im) CC_CMNI(ARM_CC_AL,rn,im) +# define T2_CMNI(rn,im) torri(THUMB2_CMNI,rn,_R15_REGNO,im) +# define CC_TST(cc,rn,rm) corrr(cc,ARM_TST,rn,r0,rm) +# define TST(rn,rm) CC_TST(ARM_CC_AL,rn,rm) +# define T1_TST(rn,rm) is(THUMB_TST|(_u3(rm)<<3)|_u3(rn)) +# define T2_TST(rn,rm) torrr(THUMB2_TST,rn,_R15_REGNO,rm) +# define CC_TSTI(cc,rn,im) corri(cc,ARM_TST|ARM_I,rn,0,im) +# define TSTI(rn,im) CC_TSTI(ARM_CC_AL,rn,im) +# define T2_TSTI(rn,im) torri(THUMB2_TSTI,rn,_R15_REGNO,im) +# define CC_TEQ(cc,rn,rm) corrr(cc,ARM_TEQ,rn,0,rm) +# define TEQ(rn,rm) CC_TEQ(ARM_CC_AL,rn,rm) +# define CC_TEQI(cc,rm,im) corri(cc,ARM_TEQ|ARM_I,rn,0,im) +# define TEQI(rn,im) CC_TEQI(ARM_CC_AL,rn,im) +# define CC_BX(cc,rm) cbx(cc,ARM_BX,rm) +# define BX(rm) CC_BX(ARM_CC_AL,rm) +# define T1_BX(rm) is(0x4700|(_u4(rm)<<3)) +# define CC_BLX(cc,rm) cbx(cc,ARM_BLX,rm) +# define BLX(rm) CC_BLX(ARM_CC_AL,rm) +# define T1_BLX(rm) is(THUMB_BLX|(_u4(rm)<<3)) +# define BLXI(im) blxi(im) +# define T2_BLXI(im) tb(THUMB2_BLXI,im) +# define CC_B(cc,im) cb(cc,ARM_B,im) +# define B(im) CC_B(ARM_CC_AL,im) +# define T1_CC_B(cc,im) tc8(cc,im) +# define T1_B(im) t11(im) +# define T2_CC_B(cc,im) tcb(cc,im) +# define T2_B(im) tb(THUMB2_B,im) +# define CC_BLI(cc,im) cb(cc,ARM_BLI,im) +# define BLI(im) CC_BLI(ARM_CC_AL,im) +# define T2_BLI(im) tb(THUMB2_BLI,im) +# define CC_LDRSB(cc,rt,rn,rm) corrr(cc,ARM_LDRSB|ARM_P,rn,rt,rm) +# define LDRSB(rt,rn,rm) CC_LDRSB(ARM_CC_AL,rt,rn,rm) +# define T1_LDRSB(rt,rn,rm) is(THUMB_LDRSB|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T2_LDRSB(rt,rn,rm) torxr(THUMB2_LDRSB,rn,rt,rm) +# define CC_LDRSBN(cc,rt,rn,rm) corrr(cc,ARM_LDRSB,rn,rt,rm) +# define LDRSBN(rt,rn,rm) CC_LDRSBN(ARM_CC_AL,rt,rn,rm) +# define CC_LDRSBI(cc,rt,rn,im) corri8(cc,ARM_LDRSBI|ARM_P,rn,rt,im) +# define LDRSBI(rt,rn,im) CC_LDRSBI(ARM_CC_AL,rt,rn,im) +# define T2_LDRSBI(rt,rn,im) torri8(THUMB2_LDRSBI|THUMB2_U,rn,rt,im) +# define T2_LDRSBWI(rt,rn,im) torri12(THUMB2_LDRSBWI,rn,rt,im) +# define CC_LDRSBIN(cc,rt,rn,im) corri8(cc,ARM_LDRSBI,rn,rt,im) +# define LDRSBIN(rt,rn,im) CC_LDRSBIN(ARM_CC_AL,rt,rn,im) +# define T2_LDRSBIN(rt,rn,im) torri8(THUMB2_LDRSBI,rn,rt,im) +# define CC_LDRB(cc,rt,rn,rm) corrr(cc,ARM_LDRB|ARM_P,rn,rt,rm) +# define LDRB(rt,rn,rm) CC_LDRB(ARM_CC_AL,rt,rn,rm) +# define T1_LDRB(rt,rn,rm) is(THUMB_LDRB|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T2_LDRB(rt,rn,rm) torxr(THUMB2_LDRB,rn,rt,rm) +# define CC_LDRBN(cc,rt,rn,rm) corrr(cc,ARM_LDRB,rn,rt,rm) +# define LDRBN(rt,rn,rm) CC_LDRBN(ARM_CC_AL,rt,rn,rm) +# define CC_LDRBI(cc,rt,rn,im) corri(cc,ARM_LDRBI|ARM_P,rn,rt,im) +# define LDRBI(rt,rn,im) CC_LDRBI(ARM_CC_AL,rt,rn,im) +# define T1_LDRBI(rt,rn,im) is(THUMB_LDRBI|(_u5(im)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T2_LDRBI(rt,rn,im) torri8(THUMB2_LDRBI|THUMB2_U,rn,rt,im) +# define T2_LDRBWI(rt,rn,im) torri12(THUMB2_LDRBWI,rn,rt,im) +# define CC_LDRBIN(cc,rt,rn,im) corri(cc,ARM_LDRBI,rn,rt,im) +# define LDRBIN(rt,rn,im) CC_LDRBIN(ARM_CC_AL,rt,rn,im) +# define T2_LDRBIN(rt,rn,im) torri8(THUMB2_LDRBI,rn,rt,im) +# define CC_LDRSH(cc,rt,rn,rm) corrr(cc,ARM_LDRSH|ARM_P,rn,rt,rm) +# define LDRSH(rt,rn,rm) CC_LDRSH(ARM_CC_AL,rt,rn,rm) +# define T1_LDRSH(rt,rn,rm) is(THUMB_LDRSH|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T2_LDRSH(rt,rn,rm) torxr(THUMB2_LDRSH,rn,rt,rm) +# define CC_LDRSHN(cc,rt,rn,rm) corrr(cc,ARM_LDRSH,rn,rt,rm) +# define LDRSHN(rt,rn,rm) CC_LDRSHN(ARM_CC_AL,rt,rn,rm) +# define CC_LDRSHI(cc,rt,rn,im) corri8(cc,ARM_LDRSHI|ARM_P,rn,rt,im) +# define LDRSHI(rt,rn,im) CC_LDRSHI(ARM_CC_AL,rt,rn,im) +# define T2_LDRSHI(rt,rn,im) torri8(THUMB2_LDRSHI|THUMB2_U,rn,rt,im) +# define T2_LDRSHWI(rt,rn,im) torri12(THUMB2_LDRSHWI,rn,rt,im) +# define CC_LDRSHIN(cc,rt,rn,im) corri8(cc,ARM_LDRSHI,rn,rt,im) +# define LDRSHIN(rt,rn,im) CC_LDRSHIN(ARM_CC_AL,rt,rn,im) +# define T2_LDRSHIN(rt,rn,im) torri8(THUMB2_LDRSHI,rn,rt,im) +# define CC_LDRH(cc,rt,rn,rm) corrr(cc,ARM_LDRH|ARM_P,rn,rt,rm) +# define LDRH(rt,rn,rm) CC_LDRH(ARM_CC_AL,rt,rn,rm) +# define T1_LDRH(rt,rn,rm) is(THUMB_LDRH|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T2_LDRH(rt,rn,rm) torxr(THUMB2_LDRH,rn,rt,rm) +# define CC_LDRHN(cc,rt,rn,rm) corrr(cc,ARM_LDRH,rn,rt,rm) +# define LDRHN(rt,rn,rm) CC_LDRHN(ARM_CC_AL,rt,rn,rm) +# define CC_LDRHI(cc,rt,rn,im) corri8(cc,ARM_LDRHI|ARM_P,rn,rt,im) +# define LDRHI(rt,rn,im) CC_LDRHI(ARM_CC_AL,rt,rn,im) +# define T1_LDRHI(rt,rn,im) is(THUMB_LDRHI|(_u5(im)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T2_LDRHI(rt,rn,im) torri8(THUMB2_LDRHI|THUMB2_U,rn,rt,im) +# define T2_LDRHWI(rt,rn,im) torri12(THUMB2_LDRHWI,rn,rt,im) +# define CC_LDRHIN(cc,rt,rn,im) corri8(cc,ARM_LDRHI,rn,rt,im) +# define LDRHIN(rt,rn,im) CC_LDRHIN(ARM_CC_AL,rt,rn,im) +# define T2_LDRHIN(rt,rn,im) torri8(THUMB2_LDRHI,rn,rt,im) +# define CC_LDR(cc,rt,rn,rm) corrr(cc,ARM_LDR|ARM_P,rn,rt,rm) +# define LDR(rt,rn,rm) CC_LDR(ARM_CC_AL,rt,rn,rm) +# define T1_LDR(rt,rn,rm) is(THUMB_LDR|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T2_LDR(rt,rn,rm) torxr(THUMB2_LDR,rn,rt,rm) +# define CC_LDRN(cc,rt,rn,rm) corrr(cc,ARM_LDR,rn,rt,rm) +# define LDRN(rt,rn,rm) CC_LDRN(ARM_CC_AL,rt,rn,rm) +# define CC_LDRI(cc,rt,rn,im) corri(cc,ARM_LDRI|ARM_P,rn,rt,im) +# define LDRI(rt,rn,im) CC_LDRI(ARM_CC_AL,rt,rn,im) +# define T1_LDRI(rt,rn,im) is(THUMB_LDRI|(_u5(im)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T1_LDRISP(rt,im) is(THUMB_LDRISP|(_u3(rt)<<8)|_u8(im)) +# define T2_LDRI(rt,rn,im) torri8(THUMB2_LDRI|THUMB2_U,rn,rt,im) +# define T2_LDRWI(rt,rn,im) torri12(THUMB2_LDRWI,rn,rt,im) +# define CC_LDRIN(cc,rt,rn,im) corri(cc,ARM_LDRI,rn,rt,im) +# define LDRIN(rt,rn,im) CC_LDRIN(ARM_CC_AL,rt,rn,im) +# define T2_LDRIN(rt,rn,im) torri8(THUMB2_LDRI,rn,rt,im) +# define CC_LDRD(cc,rt,rn,rm) corrr(cc,ARM_LDRD|ARM_P,rn,rt,rm) +# define LDRD(rt,rn,rm) CC_LDRD(ARM_CC_AL,rt,rn,rm) +# define T2_LDRDI(rt,rt2,rn,im) torrri8(THUMB2_LDRDI|ARM_P,rn,rt,rt2,im) +# define CC_LDRDN(cc,rt,rn,rm) corrr(cc,ARM_LDRD,rn,rt,rm) +# define LDRDN(rd,rn,rm) CC_LDRDN(ARM_CC_AL,rt,rn,rm) +# define CC_LDRDI(cc,rt,rn,im) corri8(cc,ARM_LDRDI|ARM_P,rn,rt,im) +# define LDRDI(rt,rn,im) CC_LDRDI(ARM_CC_AL,rt,rn,im) +# define CC_LDRDIN(cc,rt,rn,im) corri8(cc,ARM_LDRDI,rn,rt,im) +# define LDRDIN(rt,rn,im) CC_LDRDIN(ARM_CC_AL,rt,rn,im) +# define T2_LDRDIN(rt,rt2,rn,im) torrri8(THUMB2_LDRDI,rn,rt,rt2,im) +# define CC_STRB(cc,rt,rn,rm) corrr(cc,ARM_STRB|ARM_P,rn,rt,rm) +# define STRB(rt,rn,rm) CC_STRB(ARM_CC_AL,rt,rn,rm) +# define T1_STRB(rt,rn,rm) is(THUMB_STRB|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T2_STRB(rt,rn,rm) torxr(THUMB2_STRB,rn,rt,rm) +# define CC_STRBN(cc,rt,rn,rm) corrr(cc,ARM_STRB,rn,rt,rm) +# define STRBN(rt,rn,rm) CC_STRBN(ARM_CC_AL,rt,rn,rm) +# define CC_STRBI(cc,rt,rn,im) corri(cc,ARM_STRBI|ARM_P,rn,rt,im) +# define STRBI(rt,rn,im) CC_STRBI(ARM_CC_AL,rt,rn,im) +# define T1_STRBI(rt,rn,im) is(THUMB_STRBI|(_u5(im)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T2_STRBI(rt,rn,im) torri8(THUMB2_STRBI|THUMB2_U,rn,rt,im) +# define T2_STRBWI(rt,rn,im) torri12(THUMB2_STRBWI,rn,rt,im) +# define CC_STRBIN(cc,rt,rn,im) corri(cc,ARM_STRBI,rn,rt,im) +# define STRBIN(rt,rn,im) CC_STRBIN(ARM_CC_AL,rt,rn,im) +# define T2_STRBIN(rt,rn,im) torri8(THUMB2_STRBI,rn,rt,im) +# define CC_STRH(cc,rt,rn,rm) corrr(cc,ARM_STRH|ARM_P,rn,rt,rm) +# define STRH(rt,rn,rm) CC_STRH(ARM_CC_AL,rt,rn,rm) +# define T1_STRH(rt,rn,rm) is(THUMB_STRH|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T2_STRH(rt,rn,rm) torxr(THUMB2_STRH,rn,rt,rm) +# define CC_STRHN(cc,rt,rn,rm) corrr(cc,ARM_STRH,rn,rt,rm) +# define STRHN(rt,rn,rm) CC_STRHN(ARM_CC_AL,rt,rn,rm) +# define CC_STRHI(cc,rt,rn,im) corri8(cc,ARM_STRHI|ARM_P,rn,rt,im) +# define STRHI(rt,rn,im) CC_STRHI(ARM_CC_AL,rt,rn,im) +# define T1_STRHI(rt,rn,im) is(THUMB_STRHI|(_u5(im)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T2_STRHI(rt,rn,im) torri8(THUMB2_STRHI|THUMB2_U,rn,rt,im) +# define T2_STRHWI(rt,rn,im) torri12(THUMB2_STRHWI,rn,rt,im) +# define CC_STRHIN(cc,rt,rn,im) corri8(cc,ARM_STRHI,rn,rt,im) +# define STRHIN(rt,rn,im) CC_STRHIN(ARM_CC_AL,rt,rn,im) +# define T2_STRHIN(rt,rn,im) torri8(THUMB2_STRHI,rn,rt,im) +# define CC_STR(cc,rt,rn,rm) corrr(cc,ARM_STR|ARM_P,rn,rt,rm) +# define STR(rt,rn,rm) CC_STR(ARM_CC_AL,rt,rn,rm) +# define T1_STR(rt,rn,rm) is(THUMB_STR|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T2_STR(rt,rn,rm) torxr(THUMB2_STR,rn,rt,rm) +# define CC_STRN(cc,rt,rn,rm) corrr(cc,ARM_STR,rn,rt,rm) +# define STRN(rt,rn,rm) CC_STRN(ARM_CC_AL,rt,rn,rm) +# define CC_STRI(cc,rt,rn,im) corri(cc,ARM_STRI|ARM_P,rn,rt,im) +# define STRI(rt,rn,im) CC_STRI(ARM_CC_AL,rt,rn,im) +# define T1_STRI(rt,rn,im) is(THUMB_STRI|(_u5(im)<<6)|(_u3(rn)<<3)|_u3(rt)) +# define T1_STRISP(rt,im) is(THUMB_STRISP|(_u3(rt)<<8)|(_u8(im))) +# define T2_STRI(rt,rn,im) torri8(THUMB2_STRI|THUMB2_U,rn,rt,im) +# define T2_STRWI(rt,rn,im) torri12(THUMB2_STRWI,rn,rt,im) +# define CC_STRIN(cc,rt,rn,im) corri(cc,ARM_STRI,rn,rt,im) +# define STRIN(rt,rn,im) CC_STRIN(ARM_CC_AL,rt,rn,im) +# define T2_STRIN(rt,rn,im) torri8(THUMB2_STRI,rn,rt,im) +# define CC_STRD(cc,rt,rn,rm) corrr(cc,ARM_STRD|ARM_P,rn,rt,rm) +# define STRD(rt,rn,rm) CC_STRD(ARM_CC_AL,rt,rn,rm) +# define CC_STRDN(cc,rt,rn,rm) corrr(cc,ARM_STRD,rn,rt,rm) +# define STRDN(rt,rn,rm) CC_STRDN(ARM_CC_AL,rt,rn,rm) +# define CC_STRDI(cc,rt,rn,im) corri8(cc,ARM_STRDI|ARM_P,rn,rt,im) +# define STRDI(rt,rn,im) CC_STRDI(ARM_CC_AL,rt,rn,im) +# define T2_STRDI(rt,rt2,rn,im) torrri8(THUMB2_STRDI|ARM_P,rn,rt,rt2,im) +# define CC_STRDIN(cc,rt,rn,im) corri8(cc,ARM_STRDI,rn,rt,im) +# define STRDIN(rt,rn,im) CC_STRDIN(ARM_CC_AL,rt,rn,im) +# define T2_STRDIN(rt,rt2,rn,im) torrri8(THUMB2_STRDI,rn,rt,rt2,im) +# define CC_LDMIA(cc,rn,im) corl(cc,ARM_M|ARM_M_L|ARM_M_I,rn,im) +# define LDMIA(rn,im) CC_LDMIA(ARM_CC_AL,rn,im) +# define CC_LDM(cc,rn,im) CC_LDMIA(cc,rn,im) +# define LDM(rn,im) LDMIA(rn,im) +# define T1_LDMIA(rn,im) is(THUMB_LDMIA|(_u3(rn)<<8)|im) +# define T2_LDMIA(rn,im) torl(THUMB2_LDMIA,rn,im) +# define CC_LDMIA_U(cc,rn,im) corl(cc,ARM_M|ARM_M_L|ARM_M_I|ARM_M_U,rn,im) +# define LDMIA_U(rn,im) CC_LDMIA_U(ARM_CC_AL,rn,im) +# define LDM_U(r0,i0) LDMIA_U(r0,i0) +# define CC_LDMIB(cc,rn,im) corl(cc,ARM_M|ARM_M_L|ARM_M_I|ARM_M_B,rn,im) +# define LDMIB(rn,im) CC_LDMIB(ARM_CC_AL,rn,im) +# define CC_LDMIB_U(cc,rn,im) corl(cc,ARM_M|ARM_M_L|ARM_M_I|ARM_M_B|ARM_M_U,rn,im) +# define LDMIB_U(rn,im) CC_LDMIB_U(ARM_CC_AL,rn,im) +# define CC_LDMDA(cc,rn,im) corl(cc,ARM_M|ARM_M_L,rn,im) +# define LDMDA(rn,im) CC_LDMDA(ARM_CC_AL,rn,im) +# define CC_LDMDA_U(cc,rn,im) corl(cc,ARM_M|ARM_M_L|ARM_M_U,rn,im) +# define LDMDA_U(rn,im) CC_LDMDA_U(ARM_CC_AL,rn,im) +# define CC_LDMDB(cc,rn,im) corl(cc,ARM_M|ARM_M_L|ARM_M_B,rn,im) +# define LDMDB(rn,im) CC_LDMDB(ARM_CC_AL,rn,im) +# define T2_LDMDB(rn,im) torl(THUMB2_LDMDB,rn,im) +# define CC_LDMDB_U(cc,rn,im) corl(cc,ARM_M|ARM_M_L|ARM_M_B|ARM_M_U,rn,im) +# define LDMDB_U(rn,im) CC_LDMDB_U(ARM_CC_AL,rn,im) +# define CC_STMIA(cc,rn,im) corl(cc,ARM_M|ARM_M_I,rn,im) +# define STMIA(rn,im) CC_STMIA(ARM_CC_AL,rn,im) +# define CC_STM(cc,rn,im) CC_STMIA(cc,rn,im) +# define STM(rn,im) STMIA(rn,im) +# define CC_STMIA_U(cc,rn,im) corl(cc,ARM_M|ARM_M_I|ARM_M_U,rn,im) +# define STMIA_U(rn,im) CC_STMIA_U(ARM_CC_AL,rn,im) +# define CC_STM_U(cc,rn,im) CC_STMIA_U(cc,rn,im) +# define STM_U(rn,im) STMIA_U(rn,im) +# define CC_STMIB(cc,rn,im) corl(cc,ARM_M|ARM_M_I|ARM_M_B,rn,im) +# define STMIB(rn,im) CC_STMIB(ARM_CC_AL,rn,im) +# define CC_STMIB_U(cc,rn,im) corl(cc,ARM_M|ARM_M_I|ARM_M_B|ARM_M_U,rn,im) +# define STMIB_U(rn,im) CC_STMIB_U(ARM_CC_AL,rn,im) +# define CC_STMDA(cc,rn,im) corl(cc,ARM_M,rn,im) +# define STMDA(rn,im) CC_STMDA(ARM_CC_AL,rn,im) +# define CC_STMDA_U(cc,rn,im) corl(cc,ARM_M|ARM_M_U,rn,im) +# define STMDA_U(rn,im) CC_STMDA_U(ARM_CC_AL,rn,im) +# define CC_STMDB(cc,rn,im) corl(cc,ARM_M|ARM_M_B,rn,im) +# define STMDB(rn,im) CC_STMDB(ARM_CC_AL,rn,im) +# define CC_STMDB_U(cc,rn,im) corl(cc,ARM_M|ARM_M_B|ARM_M_U,rn,im) +# define STMDB_U(rn,im) CC_STMDB_U(ARM_CC_AL,rn,im) +# define CC_PUSH(cc,im) CC_STMDB_U(cc,_SP_REGNO,im) +# define PUSH(im) STMDB_U(_SP_REGNO,im) +# define T1_PUSH(im) is(THUMB_PUSH|((im&0x4000)>>6)|(im&0xff)) +# define T2_PUSH(im) tpp(THUMB2_PUSH,im) +# define CC_POP(cc,im) LDMIA_U(cc,_SP_REGNO,im) +# define POP(im) LDMIA_U(_SP_REGNO,im) +# define T1_POP(im) is(THUMB_POP|((im&0x8000)>>7)|(im&0xff)) +# define T2_POP(im) tpp(THUMB2_POP,im) +# define jit_get_reg_args() \ + do { \ + (void)jit_get_reg(_R0|jit_class_named|jit_class_gpr); \ + (void)jit_get_reg(_R1|jit_class_named|jit_class_gpr); \ + (void)jit_get_reg(_R2|jit_class_named|jit_class_gpr); \ + (void)jit_get_reg(_R3|jit_class_named|jit_class_gpr); \ + } while (0) +# define jit_unget_reg_args() \ + do { \ + jit_unget_reg(_R3); \ + jit_unget_reg(_R2); \ + jit_unget_reg(_R1); \ + jit_unget_reg(_R0); \ + } while (0) +# define nop(i0) _nop(_jit,i0) +static void _nop(jit_state_t*,jit_int32_t); +# define movr(r0,r1) _movr(_jit,r0,r1) +static void _movr(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi(r0,i0) _movi(_jit,r0,i0) +static void _movi(jit_state_t*,jit_int32_t,jit_word_t); +# define movi_p(r0,i0) _movi_p(_jit,r0,i0) +static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t); +# define comr(r0,r1) _comr(_jit,r0,r1) +static void _comr(jit_state_t*,jit_int32_t,jit_int32_t); +# define negr(r0,r1) _negr(_jit,r0,r1) +static void _negr(jit_state_t*,jit_int32_t,jit_int32_t); +# define addr(r0,r1,r2) _addr(_jit,r0,r1,r2) +static void _addr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0) +static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addcr(r0,r1,r2) _addcr(_jit,r0,r1,r2) +static void _addcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addci(r0,r1,i0) _addci(_jit,r0,r1,i0) +static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addxr(r0,r1,r2) _addxr(_jit,r0,r1,r2) +static void _addxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0) +static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subr(r0,r1,r2) _subr(_jit,r0,r1,r2) +static void _subr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subi(r0,r1,i0) _subi(_jit,r0,r1,i0) +static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subcr(r0,r1,r2) _subcr(_jit,r0,r1,r2) +static void _subcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subci(r0,r1,i0) _subci(_jit,r0,r1,i0) +static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subxr(r0,r1,r2) _subxr(_jit,r0,r1,r2) +static void _subxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subxi(r0,r1,i0) _subxi(_jit,r0,r1,i0) +static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0) +static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define mulr(r0,r1,r2) _mulr(_jit,r0,r1,r2) +static void _mulr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define muli(r0,r1,i0) _muli(_jit,r0,r1,i0) +static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,1) +# define qmulr_u(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,0) +# define iqmulr(r0,r1,r2,r3,cc) _iqmulr(_jit,r0,r1,r2,r3,cc) +static void _iqmulr(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_bool_t); +# define qmuli(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,1) +# define qmuli_u(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,0) +# define iqmuli(r0,r1,r2,i0,cc) _iqmuli(_jit,r0,r1,r2,i0,cc) +static void _iqmuli(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_word_t,jit_bool_t); +# define divrem(d,s,r0,r1,r2) _divrem(_jit,d,s,r0,r1,r2) +static void _divrem(jit_state_t*,int,int,jit_int32_t,jit_int32_t,jit_int32_t); +# define divr(r0,r1,r2) _divr(_jit,r0,r1,r2) +static void _divr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi(r0,r1,i0) _divi(_jit,r0,r1,i0) +static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define divr_u(r0,r1,r2) _divr_u(_jit,r0,r1,r2) +static void _divr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0) +static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qdivr(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,1) +# define qdivr_u(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,0) +# define iqdivr(r0,r1,r2,r3,cc) _iqdivr(_jit,r0,r1,r2,r3,cc) +static void _iqdivr(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_bool_t); +# define qdivi(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,1) +# define qdivi_u(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,0) +# define iqdivi(r0,r1,r2,i0,cc) _iqdivi(_jit,r0,r1,r2,i0,cc) +static void _iqdivi(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_word_t,jit_bool_t); +# define remr(r0,r1,r2) _remr(_jit,r0,r1,r2) +static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi(r0,r1,i0) _remi(_jit,r0,r1,i0) +static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2) +static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0) +static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define andr(r0,r1,r2) _andr(_jit,r0,r1,r2) +static void _andr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0) +static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define orr(r0,r1,r2) _orr(_jit,r0,r1,r2) +static void _orr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ori(r0,r1,i0) _ori(_jit,r0,r1,i0) +static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define xorr(r0,r1,r2) _xorr(_jit,r0,r1,r2) +static void _xorr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define xori(r0,r1,i0) _xori(_jit,r0,r1,i0) +static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define lshr(r0,r1,r2) _lshr(_jit,r0,r1,r2) +static void _lshr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0) +static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr(r0,r1,r2) _rshr(_jit,r0,r1,r2) +static void _rshr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0) +static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr_u(r0,r1,r2) _rshr_u(_jit,r0,r1,r2) +static void _rshr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0) +static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ccr(ct,cf,r0,r1,r2) _ccr(_jit,ct,cf,r0,r1,r2) +static void _ccr(jit_state_t*,int,int,jit_int32_t,jit_int32_t,jit_int32_t); +# define cci(ct,cf,r0,r1,i0) _cci(_jit,ct,cf,r0,r1,i0) +static void _cci(jit_state_t*,int,int,jit_int32_t,jit_int32_t,jit_word_t); +# define ltr(r0, r1, r2) ccr(ARM_CC_LT,ARM_CC_GE,r0,r1,r2) +# define lti(r0, r1, i0) cci(ARM_CC_LT,ARM_CC_GE,r0,r1,i0) +# define ltr_u(r0, r1, r2) ccr(ARM_CC_LO,ARM_CC_HS,r0,r1,r2) +# define lti_u(r0, r1, i0) cci(ARM_CC_LO,ARM_CC_HS,r0,r1,i0) +# define ler(r0, r1, r2) ccr(ARM_CC_LE,ARM_CC_GT,r0,r1,r2) +# define lei(r0, r1, i0) cci(ARM_CC_LE,ARM_CC_GT,r0,r1,i0) +# define ler_u(r0, r1, r2) ccr(ARM_CC_LS,ARM_CC_HI,r0,r1,r2) +# define lei_u(r0, r1, i0) cci(ARM_CC_LS,ARM_CC_HI,r0,r1,i0) +# define eqr(r0, r1, r2) ccr(ARM_CC_EQ,ARM_CC_NE,r0,r1,r2) +# define eqi(r0, r1, i0) cci(ARM_CC_EQ,ARM_CC_NE,r0,r1,i0) +# define ger(r0, r1, r2) ccr(ARM_CC_GE,ARM_CC_LT,r0,r1,r2) +# define gei(r0, r1, i0) cci(ARM_CC_GE,ARM_CC_LT,r0,r1,i0) +# define ger_u(r0, r1, r2) ccr(ARM_CC_HS,ARM_CC_LO,r0,r1,r2) +# define gei_u(r0, r1, i0) cci(ARM_CC_HS,ARM_CC_LO,r0,r1,i0) +# define gtr(r0, r1, r2) ccr(ARM_CC_GT,ARM_CC_LE,r0,r1,r2) +# define gti(r0, r1, i0) cci(ARM_CC_GT,ARM_CC_LE,r0,r1,i0) +# define gtr_u(r0, r1, r2) ccr(ARM_CC_HI,ARM_CC_LS,r0,r1,r2) +# define gti_u(r0, r1, i0) cci(ARM_CC_HI,ARM_CC_LS,r0,r1,i0) +# define ner(r0,r1,r2) _ner(_jit,r0,r1,r2) +static void _ner(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define nei(r0,r1,i0) _nei(_jit,r0,r1,i0) +static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define jmpr(r0) _jmpr(_jit,r0) +static void _jmpr(jit_state_t*,jit_int32_t); +# define jmpi(i0) _jmpi(_jit,i0) +static void _jmpi(jit_state_t*,jit_word_t); +# define jmpi_p(i0, i1) _jmpi_p(_jit,i0, i1) +static jit_word_t _jmpi_p(jit_state_t*,jit_word_t,jit_bool_t); +# define bccr(cc,i0,r0,r1) _bccr(_jit,cc,i0,r0,r1) +static jit_word_t _bccr(jit_state_t*,int,jit_word_t,jit_int32_t,jit_int32_t); +# define bcci(cc,i0,r0,i1) _bcci(_jit,cc,i0,r0,i1) +static jit_word_t _bcci(jit_state_t*,int,jit_word_t,jit_int32_t,jit_word_t); +# define bltr(i0, r0, r1) bccr(ARM_CC_LT,i0,r0,r1) +# define blti(i0, r0, i1) bcci(ARM_CC_LT,i0,r0,i1) +# define bltr_u(i0, r0, r1) bccr(ARM_CC_LO,i0,r0,r1) +# define blti_u(i0, r0, i1) bcci(ARM_CC_LO,i0,r0,i1) +# define bler(i0, r0, r1) bccr(ARM_CC_LE,i0,r0,r1) +# define blei(i0, r0, i1) bcci(ARM_CC_LE,i0,r0,i1) +# define bler_u(i0, r0, r1) bccr(ARM_CC_LS,i0,r0,r1) +# define blei_u(i0, r0, i1) bcci(ARM_CC_LS,i0,r0,i1) +# define beqr(i0, r0, r1) bccr(ARM_CC_EQ,i0,r0,r1) +# define beqi(i0, r0, i1) bcci(ARM_CC_EQ,i0,r0,i1) +# define bger(i0, r0, r1) bccr(ARM_CC_GE,i0,r0,r1) +# define bgei(i0, r0, i1) bcci(ARM_CC_GE,i0,r0,i1) +# define bger_u(i0, r0, r1) bccr(ARM_CC_HS,i0,r0,r1) +# define bgei_u(i0, r0, i1) bcci(ARM_CC_HS,i0,r0,i1) +# define bgtr(i0, r0, r1) bccr(ARM_CC_GT,i0,r0,r1) +# define bgti(i0, r0, i1) bcci(ARM_CC_GT,i0,r0,i1) +# define bgtr_u(i0, r0, r1) bccr(ARM_CC_HI,i0,r0,r1) +# define bgti_u(i0, r0, i1) bcci(ARM_CC_HI,i0,r0,i1) +# define bner(i0, r0, r1) bccr(ARM_CC_NE,i0,r0,r1) +# define bnei(i0, r0, i1) bcci(ARM_CC_NE,i0,r0,i1) +# define baddr(cc,i0,r0,r1) _baddr(_jit,cc,i0,r0,r1) +static jit_word_t _baddr(jit_state_t*,int,jit_word_t,jit_int32_t,jit_int32_t); +# define baddi(cc,i0,r0,r1) _baddi(_jit,cc,i0,r0,r1) +static jit_word_t _baddi(jit_state_t*,int,jit_word_t,jit_int32_t,jit_word_t); +# define boaddr(i0,r0,r1) baddr(ARM_CC_VS,i0,r0,r1) +# define boaddi(i0,r0,i1) baddi(ARM_CC_VS,i0,r0,i1) +# define boaddr_u(i0,r0,r1) baddr(ARM_CC_HS,i0,r0,r1) +# define boaddi_u(i0,r0,i1) baddi(ARM_CC_HS,i0,r0,i1) +# define bxaddr(i0,r0,r1) baddr(ARM_CC_VC,i0,r0,r1) +# define bxaddi(i0,r0,i1) baddi(ARM_CC_VC,i0,r0,i1) +# define bxaddr_u(i0,r0,r1) baddr(ARM_CC_LO,i0,r0,r1) +# define bxaddi_u(i0,r0,i1) baddi(ARM_CC_LO,i0,r0,i1) +# define bsubr(cc,i0,r0,r1) _bsubr(_jit,cc,i0,r0,r1) +static jit_word_t _bsubr(jit_state_t*,int,jit_word_t,jit_int32_t,jit_int32_t); +# define bsubi(cc,i0,r0,r1) _bsubi(_jit,cc,i0,r0,r1) +static jit_word_t _bsubi(jit_state_t*,int,jit_word_t,jit_int32_t,jit_word_t); +# define bosubr(i0,r0,r1) bsubr(ARM_CC_VS,i0,r0,r1) +# define bosubi(i0,r0,i1) bsubi(ARM_CC_VS,i0,r0,i1) +# define bosubr_u(i0,r0,r1) bsubr(ARM_CC_LO,i0,r0,r1) +# define bosubi_u(i0,r0,i1) bsubi(ARM_CC_LO,i0,r0,i1) +# define bxsubr(i0,r0,r1) bsubr(ARM_CC_VC,i0,r0,r1) +# define bxsubi(i0,r0,i1) bsubi(ARM_CC_VC,i0,r0,i1) +# define bxsubr_u(i0,r0,r1) bsubr(ARM_CC_HS,i0,r0,r1) +# define bxsubi_u(i0,r0,i1) bsubi(ARM_CC_HS,i0,r0,i1) +# define bmxr(cc,i0,r0,r1) _bmxr(_jit,cc,i0,r0,r1) +static jit_word_t _bmxr(jit_state_t*,int,jit_word_t,jit_int32_t,jit_int32_t); +# define bmxi(cc,i0,r0,r1) _bmxi(_jit,cc,i0,r0,r1) +static jit_word_t _bmxi(jit_state_t*,int,jit_word_t,jit_int32_t,jit_word_t); +# define bmsr(i0,r0,r1) bmxr(ARM_CC_NE,i0,r0,r1) +# define bmsi(i0,r0,i1) bmxi(ARM_CC_NE,i0,r0,i1) +# define bmcr(i0,r0,r1) bmxr(ARM_CC_EQ,i0,r0,r1) +# define bmci(i0,r0,i1) bmxi(ARM_CC_EQ,i0,r0,i1) +# define ldr_c(r0,r1) _ldr_c(_jit,r0,r1) +static void _ldr_c(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_c(r0,i0) _ldi_c(_jit,r0,i0) +static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_c(r0,r1,r2) _ldxr_c(_jit,r0,r1,r2) +static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0) +static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_uc(r0,r1) _ldr_uc(_jit,r0,r1) +static void _ldr_uc(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0) +static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_uc(r0,r1,r2) _ldxr_uc(_jit,r0,r1,r2) +static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0) +static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_s(r0,r1) _ldr_s(_jit,r0,r1) +static void _ldr_s(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_s(r0,i0) _ldi_s(_jit,r0,i0) +static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_s(r0,r1,r2) _ldxr_s(_jit,r0,r1,r2) +static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0) +static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_us(r0,r1) _ldr_us(_jit,r0,r1) +static void _ldr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_us(r0,i0) _ldi_us(_jit,r0,i0) +static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_us(r0,r1,r2) _ldxr_us(_jit,r0,r1,r2) +static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0) +static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_i(r0,r1) _ldr_i(_jit,r0,r1) +static void _ldr_i(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_i(r0,i0) _ldi_i(_jit,r0,i0) +static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_i(r0,r1,r2) _ldxr_i(_jit,r0,r1,r2) +static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_i(r0,r1,i0) _ldxi_i(_jit,r0,r1,i0) +static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_c(r0,r1) _str_c(_jit,r0,r1) +static void _str_c(jit_state_t*,jit_int32_t,jit_int32_t); +# define sti_c(i0,r0) _sti_c(_jit,i0,r0) +static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_c(r0,r1,r2) _stxr_c(_jit,r0,r1,r2) +static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_c(r0,r1,i0) _stxi_c(_jit,r0,r1,i0) +static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define str_s(r0,r1) _str_s(_jit,r0,r1) +static void _str_s(jit_state_t*,jit_int32_t,jit_int32_t); +# define sti_s(i0,r0) _sti_s(_jit,i0,r0) +static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_s(r0,r1,r2) _stxr_s(_jit,r0,r1,r2) +static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_s(r0,r1,i0) _stxi_s(_jit,r0,r1,i0) +static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define str_i(r0,r1) _str_i(_jit,r0,r1) +static void _str_i(jit_state_t*,jit_int32_t,jit_int32_t); +# define sti_i(i0,r0) _sti_i(_jit,i0,r0) +static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_i(r0,r1,r2) _stxr_i(_jit,r0,r1,r2) +static void _stxr_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxi_i(r0,r1,i0) _stxi_i(_jit,r0,r1,i0) +static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1) +static void _htonr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1) +static void _htonr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# else +# define htonr_us(r0,r1) extr_us(r0,r1) +# define htonr(r0,r1) movr(r0,r1) +# endif +# define extr_c(r0,r1) _extr_c(_jit,r0,r1) +static void _extr_c(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_uc(r0,r1) _extr_uc(_jit,r0,r1) +static void _extr_uc(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_s(r0,r1) _extr_s(_jit,r0,r1) +static void _extr_s(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_us(r0,r1) _extr_us(_jit,r0,r1) +static void _extr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define prolog(i0) _prolog(_jit,i0) +static void _prolog(jit_state_t*,jit_node_t*); +# define epilog(i0) _epilog(_jit,i0) +static void _epilog(jit_state_t*,jit_node_t*); +# define callr(r0) _callr(_jit,r0) +static void _callr(jit_state_t*,jit_int32_t); +# define calli(i0) _calli(_jit,i0) +static void _calli(jit_state_t*,jit_word_t); +# define calli_p(i0) _calli_p(_jit,i0) +static jit_word_t _calli_p(jit_state_t*,jit_word_t); +# define vastart(r0) _vastart(_jit, r0) +static void _vastart(jit_state_t*, jit_int32_t); +# define vaarg(r0, r1) _vaarg(_jit, r0, r1) +static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t); +# define patch_at(kind,jump,label) _patch_at(_jit,kind,jump,label) +static void _patch_at(jit_state_t*,jit_int32_t,jit_word_t,jit_word_t); +#endif + +#if CODE +/* from binutils */ +# define rotate_left(v, n) (v << n | v >> (32 - n)) +static int +encode_arm_immediate(unsigned int v) +{ + unsigned int a, i; + + for (i = 0; i < 32; i += 2) + if ((a = rotate_left(v, i)) <= 0xff) + return (a | (i << 7)); + + return (-1); +} + +static int +encode_thumb_immediate(unsigned int v) +{ + int i; + unsigned int m; + unsigned int n; + /* 00000000 00000000 00000000 abcdefgh */ + if ((v & 0xff) == v) + return (v); + /* 00000000 abcdefgh 00000000 abcdefgh */ + if ((v & 0xff00ff) == v && ((v & 0xff0000) >> 16) == (v & 0xff)) + return ((v & 0xff) | (1 << 12)); + /* abcdefgh 00000000 abcdefgh 00000000 */ + if (((v & 0xffff0000) >> 16) == (v & 0xffff) && (v & 0xff) == 0) + return ((v & 0x000000ff) | (2 << 12)); + /* abcdefgh abcdefgh abcdefgh abcdefgh */ + if ( (v & 0xff) == ((v & 0xff00) >> 8) && + ((v & 0xff00) >> 8) == ((v & 0xff0000) >> 16) && + ((v & 0xff0000) << 8) == (v & 0xff000000)) + return ((v & 0xff) | (3 << 12)); + /* 1bcdefgh << 24 ... 1bcdefgh << 1 */ + for (i = 8, m = 0xff000000, n = 0x80000000; + i < 23; i++, m >>= 1, n >>= 1) { + if ((v & m) == v && (v & n)) { + v >>= 32 - i; + if (!(i & 1)) + v &= 0x7f; + i >>= 1; + return (((i & 7) << 12) | ((i & 8) << 23) | v); + } + } + return (-1); +} + +static int +encode_thumb_word_immediate(unsigned int v) +{ + if ((v & 0xfffff000) == 0) + return (((v & 0x800) << 15) | ((v & 0x700) << 4) | (v & 0xff)); + return (-1); +} + +static int +encode_thumb_jump(int v) +{ + int s, i1, i2, j1, j2; + if (v >= (int)-0x800000 && v <= 0x7fffff) { + s = !!(v & 0x800000); + i1 = !!(v & 0x400000); + i2 = !!(v & 0x200000); + j1 = s ? i1 : !i1; + j2 = s ? i2 : !i2; + return ((s<<26)|((v&0x1ff800)<<5)|(j1<<13)|(j2<<11)|(v&0x7ff)); + } + return (-1); +} + +static int +encode_thumb_cc_jump(int v) +{ + int s, j1, j2; + if (v >= (int)-0x80000 && v <= 0x7ffff) { + s = !!(v & 0x80000); + j1 = !!(v & 0x20000); + j2 = !!(v & 0x40000); + return ((s<<26)|((v&0x1f800)<<5)|(j1<<13)|(j2<<11)|(v&0x7ff)); + } + return (-1); +} + +static int +encode_thumb_shift(int v, int type) +{ + switch (type) { + case ARM_ASR: + case ARM_LSL: + case ARM_LSR: type >>= 1; break; + default: assert(!"handled shift"); + } + assert(v >= 0 && v <= 31); + return (((v & 0x1c) << 10) | ((v & 3) << 6) | type); +} + +static void +_tcit(jit_state_t *_jit, unsigned int tc, int it) +{ + int c; + int m; + c = (tc >> 28) & 1; + assert(!(tc & 0xfffffff) && tc != ARM_CC_NV); + switch (it) { + case THUMB2_IT: m = 1<<3; break; + case THUMB2_ITT: m = (c<<3)| (1<<2); break; + case THUMB2_ITE: m = (!c<<3)| (1<<2); break; + case THUMB2_ITTT: m = (c<<3)| (c<<2)| (1<<1); break; + case THUMB2_ITET: m = (!c<<3)| (c<<2)| (1<<1); break; + case THUMB2_ITTE: m = (c<<3)|(!c<<2)| (1<<1); break; + case THUMB2_ITEE: m = (!c<<3)|(!c<<2)| (1<<1); break; + case THUMB2_ITTTT: m = (c<<3)| (c<<2)| (c<<1)|1; break; + case THUMB2_ITETT: m = (!c<<3)| (c<<2)| (c<<1)|1; break; + case THUMB2_ITTET: m = (c<<3)|(!c<<2)| (c<<1)|1; break; + case THUMB2_ITEET: m = (!c<<3)|(!c<<2)| (c<<1)|1; break; + case THUMB2_ITTTE: m = (c<<3)| (c<<2)|(!c<<1)|1; break; + case THUMB2_ITETE: m = (!c<<3)| (c<<2)|(!c<<1)|1; break; + case THUMB2_ITTEE: m = (c<<3)|(!c<<2)|(!c<<1)|1; break; + case THUMB2_ITEEE: m = (!c<<3)|(!c<<2)|(!c<<1)|1; break; + default: abort(); + } + assert(m && (tc != ARM_CC_AL || !(m & (m - 1)))); + is(0xbf00 | (tc >> 24) | m); +} + +static void +_corrr(jit_state_t *_jit, int cc, int o, int rn, int rd, int rm) +{ + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00fff0f)); + ii(cc|o|(_u4(rn)<<16)|(_u4(rd)<<12)|_u4(rm)); +} + +static void +_corri(jit_state_t *_jit, int cc, int o, int rn, int rd, int im) +{ + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00fffff)); + assert(!(im & 0xfffff000)); + ii(cc|o|(_u4(rn)<<16)|(_u4(rd)<<12)|_u12(im)); +} + +static void +_corri8(jit_state_t *_jit, int cc, int o, int rn, int rt, int im) +{ + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00fff0f)); + assert(!(im & 0xffffff00)); + ii(cc|o|(_u4(rn)<<16)|(_u4(rt)<<12)|((im&0xf0)<<4)|(im&0x0f)); +} + +static void +_coriw(jit_state_t *_jit, int cc, int o, int rd, int im) +{ + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00fffff)); + assert(!(im & 0xffff0000)); + ii(cc|o|((im&0xf000)<<4)|(_u4(rd)<<12)|(im&0xfff)); +} + +static void +_torrr(jit_state_t *_jit, int o, int rn, int rd, int rm) +{ + jit_thumb_t thumb; + assert(!(o & 0xf0f0f)); + thumb.i = o|(_u4(rn)<<16)|(_u4(rd)<<8)|_u4(rm); + iss(thumb.s[0], thumb.s[1]); +} + +static void +_torrrs(jit_state_t *_jit, int o, int rn, int rd, int rm, int im) +{ + jit_thumb_t thumb; + assert(!(o & 0x000f0f0f)); + assert(!(im & 0xffff8f0f)); + thumb.i = o|(_u4(rn)<<16)|(_u4(rd)<<8)|im|_u4(rm); + iss(thumb.s[0], thumb.s[1]); +} + +static void +_torxr(jit_state_t *_jit, int o, int rn, int rt, int rm) +{ + jit_thumb_t thumb; + assert(!(o & 0xf0f0f)); + thumb.i = o|(_u4(rn)<<16)|(_u4(rt)<<12)|_u4(rm); + iss(thumb.s[0], thumb.s[1]); +} + +static void +_torrrr(jit_state_t *_jit, int o, int rn, int rl, int rh, int rm) +{ + jit_thumb_t thumb; + assert(!(o & 0x000fff0f)); + thumb.i = o|(_u4(rn)<<16)|(_u4(rl)<<12)|(_u4(rh)<<8)|_u4(rm); + iss(thumb.s[0], thumb.s[1]); +} + +static void +_torrri8(jit_state_t *_jit, int o, int rn, int rt, int rt2, int im) +{ + jit_thumb_t thumb; + assert(!(o & 0x000fffff)); + assert(!(im & 0xffffff00)); + thumb.i = o|(_u4(rn)<<16)|(_u4(rt)<<12)|(_u4(rt2)<<8)|im; + iss(thumb.s[0], thumb.s[1]); +} + +static void +_torri(jit_state_t *_jit, int o, int rn, int rd, int im) +{ + jit_thumb_t thumb; + assert(!(o & 0x0c0f7fff)); + assert(!(im & 0xfbff8f00)); + thumb.i = o|(_u4(rn)<<16)|(_u4(rd)<<8)|im; + iss(thumb.s[0], thumb.s[1]); +} + +static void +_torri8(jit_state_t *_jit, int o, int rn, int rt, int im) +{ + jit_thumb_t thumb; + assert(!(o & 0x000ff0ff)); + assert(!(im & 0xffffff00)); + thumb.i = o|(_u4(rn)<<16)|(_u4(rt)<<12)|im; + iss(thumb.s[0], thumb.s[1]); +} + +static void +_torri12(jit_state_t *_jit, int o, int rn, int rt, int im) +{ + jit_thumb_t thumb; + assert(!(o & 0x000fffff)); + assert(!(im & 0xfffff000)); + thumb.i = o|(_u4(rn)<<16)|(_u4(rt)<<12)|im; + iss(thumb.s[0], thumb.s[1]); +} + +static void +_tshift(jit_state_t *_jit, int o, int rd, int rm, int im) +{ + jit_thumb_t thumb; + assert(!(o & 0x7fcf)); + assert(im >= 0 && im < 32); + thumb.i = o|((im&0x1c)<<10)|(_u4(rd)<<8)|((im&3)<<6)|_u4(rm); + iss(thumb.s[0], thumb.s[1]); +} + +static void +_toriw(jit_state_t *_jit, int o, int rd, int im) +{ + jit_thumb_t thumb; + assert(!(im & 0xffff0000)); + thumb.i = o|((im&0xf000)<<4)|((im&0x800)<<15)|((im&0x700)<<4)|(_u4(rd)<<8)|(im&0xff); + iss(thumb.s[0], thumb.s[1]); +} + +static void +_tc8(jit_state_t *_jit, int cc, int im) +{ + assert(!(cc & 0x0fffffff)); + assert(cc != ARM_CC_AL && cc != ARM_CC_NV); + assert(im >= -128 && im <= 127); + is(THUMB_CC_B|(cc>>20)|(im&0xff)); +} + +static void +_t11(jit_state_t *_jit, int im) +{ + assert(!(im & 0xfffff800)); + is(THUMB_B|im); +} + +static void +_tcb(jit_state_t *_jit, int cc, int im) +{ + jit_thumb_t thumb; + assert(!(cc & 0xfffffff)); + assert(cc != ARM_CC_AL && cc != ARM_CC_NV); + cc = ((jit_uint32_t)cc) >> 6; + assert(!(im & (THUMB2_CC_B|cc))); + thumb.i = THUMB2_CC_B|cc|im; + iss(thumb.s[0], thumb.s[1]); +} + +static void +_blxi(jit_state_t *_jit, int im) +{ + assert(!(im & 0xfe000000)); + ii(ARM_BLXI|im); +} + +static void +_tb(jit_state_t *_jit, int o, int im) +{ + jit_thumb_t thumb; + assert(!(o & 0x07ff2fff)); + assert(!(o & im)); + thumb.i = o|im; + iss(thumb.s[0], thumb.s[1]); +} + +static void +_corrrr(jit_state_t *_jit, int cc, int o, int rh, int rl, int rm, int rn) +{ + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00fff0f)); + ii(cc|o|(_u4(rh)<<16)|(_u4(rl)<<12)|(_u4(rm)<<8)|_u4(rn)); +} + +static void +_corrrs(jit_state_t *_jit, int cc, int o, int rn, int rd, int rm, int im) +{ + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf000ff8f)); + ii(cc|o|(_u4(rd)<<12)|(_u4(rn)<<16)|(im<<7)|_u4(rm)); +} + +static void +_cshift(jit_state_t *_jit, int cc, int o, int rd, int rm, int rn, int im) +{ + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xffe0ff8f)); + assert(((_u4(rm)<<8)&(im<<7)) == 0); + ii(cc|ARM_SHIFT|o|(_u4(rd)<<12)|(_u4(rm)<<8)|(im<<7)|_u4(rn)); +} + +static void +_cb(jit_state_t *_jit, int cc, int o, int im) +{ + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf0ffffff)); + ii(cc|o|_u24(im)); +} + +static void +_cbx(jit_state_t *_jit, int cc, int o, int rm) +{ + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf000000f)); + ii(cc|o|_u4(rm)); +} + +static void +_corl(jit_state_t *_jit, int cc, int o, int r0, int i0) +{ + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00fffff)); + ii(cc|o|(_u4(r0)<<16)|_u16(i0)); +} + +static void +_c6orr(jit_state_t *_jit, int cc, int o, int rd, int rm) +{ + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf000f00f)); + ii(cc|o|(_u4(rd)<<12)|_u4(rm)); +} + +static void +_tpp(jit_state_t *_jit, int o, int im) +{ + jit_thumb_t thumb; + assert(!(o & 0x0000ffff)); + if (o == THUMB2_PUSH) + assert(!(im & 0x8000)); + assert(__builtin_popcount(im & 0x1fff) > 1); + thumb.i = o|im; + iss(thumb.s[0], thumb.s[1]); +} + +static void +_torl(jit_state_t *_jit, int o, int rn, int im) +{ + jit_thumb_t thumb; + assert(!(o & 0xf1fff)); + assert(rn != _R15 || !im || ((o & 0xc000) == 0xc000)); + assert(!(o & THUMB2_LDM_W) || !(im & (1 << rn))); + thumb.i = o | (_u4(rn)<<16)|_u13(im); + iss(thumb.s[0], thumb.s[1]); +} + +static void +_nop(jit_state_t *_jit, jit_int32_t i0) +{ + if (jit_thumb_p()) { + for (; i0 > 0; i0 -= 2) + T1_NOP(); + } + else { + for (; i0 > 0; i0 -= 4) + NOP(); + } + assert(i0 == 0); +} + +static void +_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) { + if (jit_thumb_p()) + T1_MOV(r0, r1); + else + MOV(r0, r1); + } +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + int i; + if (jit_thumb_p()) { + if (!jit_no_set_flags() && r0 < 8 && !(i0 & 0xffffff80)) + T1_MOVI(r0, i0); + else if ((i = encode_thumb_immediate(i0)) != -1) + T2_MOVI(r0, i); + else if ((i = encode_thumb_immediate(~i0)) != -1) + T2_MVNI(r0, i); + else { + T2_MOVWI(r0, (jit_uint16_t)i0); + if (i0 & 0xffff0000) + T2_MOVTI(r0, (jit_uint16_t)((unsigned)i0 >> 16)); + } + } + else { + if (jit_armv6_p() && !(i0 & 0xffff0000)) + MOVWI(r0, i0); + else if ((i = encode_arm_immediate(i0)) != -1) + MOVI(r0, i); + else if ((i = encode_arm_immediate(~i0)) != -1) + MVNI(r0, i); + else if (jit_armv6_p()) { + MOVWI(r0, (jit_uint16_t)(i0)); + if ((i0 & 0xffff0000)) + MOVTI(r0, (jit_uint16_t)((unsigned)i0 >> 16)); + } + else + load_const(0, r0, i0); + } +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + w = _jit->pc.w; + if (jit_thumb_p()) { + T2_MOVWI(r0, (jit_uint16_t)(i0)); + T2_MOVTI(r0, (jit_uint16_t)((unsigned)i0 >> 16)); + } + else + load_const(1, r0, 0); + return (w); +} + +static void +_comr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1) < 8) + T1_NOT(r0, r1); + else + T2_NOT(r0, r1); + } + else + NOT(r0, r1); +} + +static void +_negr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1) < 8) + T1_RSBI(r0, r1); + else + T2_RSBI(r0, r1, 0); + } + else + RSBI(r0, r1, 0); +} + +static void +_addr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1|r2) < 8) + T1_ADD(r0, r1, r2); + else if (r0 == r1 || r0 == r2) + T1_ADDX(r0, r0 == r1 ? r2 : r1); + else + T2_ADD(r0, r1, r2); + } + else + ADD(r0, r1, r2); +} + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + int i; + jit_int32_t reg; + if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1) < 8 && !(i0 & ~7)) + T1_ADDI3(r0, r1, i0); + else if (!jit_no_set_flags() && (r0|r1) < 8 && !(-i0 & ~7)) + T1_SUBI3(r0, r1, -i0); + else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(i0 & ~0xff)) + T1_ADDI8(r0, i0); + else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(-i0 & ~0xff)) + T1_SUBI8(r0, -i0); + else if ((i = encode_thumb_immediate(i0)) != -1) + T2_ADDI(r0, r1, i); + else if ((i = encode_thumb_immediate(-i0)) != -1) + T2_SUBI(r0, r1, i); + else if ((i = encode_thumb_word_immediate(i0)) != -1) + T2_ADDWI(r0, r1, i); + else if ((i = encode_thumb_word_immediate(-i0)) != -1) + T2_SUBWI(r0, r1, i); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + T2_ADD(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if ((i = encode_arm_immediate(i0)) != -1) + ADDI(r0, r1, i); + else if ((i = encode_arm_immediate(-i0)) != -1) + SUBI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + ADD(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ADD(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + /* thumb auto set carry if not inside IT block */ + if ((r0|r1|r2) < 8) + T1_ADD(r0, r1, r2); + else + T2_ADDS(r0, r1, r2); + } + else + ADDS(r0, r1, r2); +} + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + int i; + jit_int32_t reg; + if (jit_thumb_p()) { + if ((r0|r1) < 8 && !(i0 & ~7)) + T1_ADDI3(r0, r1, i0); + else if ((r0|r1) < 8 && !(-i0 & ~7)) + T1_SUBI3(r0, r1, -i0); + else if (r0 < 8 && r0 == r1 && !(i0 & ~0xff)) + T1_ADDI8(r0, i0); + else if (r0 < 8 && r0 == r1 && !(-i0 & ~0xff)) + T1_SUBI8(r0, -i0); + else if ((i = encode_thumb_immediate(i0)) != -1) + T2_ADDSI(r0, r1, i); + else if ((i = encode_thumb_immediate(-i0)) != -1) + T2_SUBSI(r0, r1, i); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + T2_ADDS(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if ((i = encode_arm_immediate(i0)) != -1) + ADDSI(r0, r1, i); + else if ((i = encode_arm_immediate(-i0)) != -1) + SUBSI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + ADDS(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ADDS(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + /* keep setting carry because don't know last ADC */ + if (jit_thumb_p()) { + /* thumb auto set carry if not inside IT block */ + if ((r0|r1|r2) < 8 && (r0 == r1 || r0 == r2)) + T1_ADC(r0, r0 == r1 ? r2 : r1); + else + T2_ADCS(r0, r1, r2); + } + else + ADCS(r0, r1, r2); +} + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + int i; + jit_int32_t reg; + int no_set_flags; + if (jit_thumb_p()) { + no_set_flags = jit_no_set_flags(); + jit_no_set_flags() = 1; + if ((i = encode_thumb_immediate(i0)) != -1) + T2_ADCSI(r0, r1, i); + else if ((i = encode_thumb_immediate(-i0)) != -1) + T2_SBCSI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + T2_ADCS(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + T2_ADCS(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + jit_no_set_flags() = no_set_flags; + } + else { + if ((i = encode_arm_immediate(i0)) != -1) + ADCSI(r0, r1, i); + else if ((i = encode_arm_immediate(-i0)) != -1) + SBCSI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + ADCS(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ADCS(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_subr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1|r2) < 8) + T1_SUB(r0, r1, r2); + else + T2_SUB(r0, r1, r2); + } + else + SUB(r0, r1, r2); +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + int i; + jit_int32_t reg; + if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1) < 8 && !(i0 & ~7)) + T1_SUBI3(r0, r1, i0); + else if (!jit_no_set_flags() && (r0|r1) < 8 && !(-i0 & ~7)) + T1_ADDI3(r0, r1, -i0); + else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(i0 & ~0xff)) + T1_SUBI8(r0, i0); + else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(-i0 & ~0xff)) + T1_ADDI8(r0, -i0); + else if ((i = encode_thumb_immediate(i0)) != -1) + T2_SUBI(r0, r1, i); + else if ((i = encode_thumb_immediate(-i0)) != -1) + T2_ADDI(r0, r1, i); + else if ((i = encode_thumb_word_immediate(i0)) != -1) + T2_SUBWI(r0, r1, i); + else if ((i = encode_thumb_word_immediate(-i0)) != -1) + T2_ADDWI(r0, r1, i); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + T2_SUB(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if ((i = encode_arm_immediate(i0)) != -1) + SUBI(r0, r1, i); + else if ((i = encode_arm_immediate(-i0)) != -1) + ADDI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + SUB(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + SUB(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + /* thumb auto set carry if not inside IT block */ + if ((r0|r1|r2) < 8) + T1_SUB(r0, r1, r2); + else + T2_SUBS(r0, r1, r2); + } + else + SUBS(r0, r1, r2); +} + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + int i; + jit_int32_t reg; + if (jit_thumb_p()) { + if ((r0|r1) < 8 && !(i0 & ~7)) + T1_SUBI3(r0, r1, i0); + else if ((r0|r1) < 8 && !(-i0 & ~7)) + T1_ADDI3(r0, r1, -i0); + else if (r0 < 8 && r0 == r1 && !(i0 & ~0xff)) + T1_SUBI8(r0, i0); + else if (r0 < 8 && r0 == r1 && !(-i0 & ~0xff)) + T1_ADDI8(r0, -i0); + else if ((i = encode_thumb_immediate(i0)) != -1) + T2_SUBSI(r0, r1, i); + else if ((i = encode_thumb_immediate(-i0)) != -1) + T2_ADDSI(r0, r1, i); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + T2_SUBS(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if ((i = encode_arm_immediate(i0)) != -1) + SUBSI(r0, r1, i); + else if ((i = encode_arm_immediate(-i0)) != -1) + ADDSI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + SUBS(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + SUBS(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + /* keep setting carry because don't know last SBC */ + if (jit_thumb_p()) { + /* thumb auto set carry if not inside IT block */ + if ((r0|r1|r2) < 8 && r0 == r1) + T1_SBC(r0, r2); + else + T2_SBCS(r0, r1, r2); + } + else + SBCS(r0, r1, r2); +} + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + int i; + jit_int32_t reg; + int no_set_flags; + if (jit_thumb_p()) { + no_set_flags = jit_no_set_flags(); + jit_no_set_flags() = 1; + if ((i = encode_arm_immediate(i0)) != -1) + T2_SBCSI(r0, r1, i); + else if ((i = encode_arm_immediate(-i0)) != -1) + T2_ADCSI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + T2_SBCS(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + SBCS(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + jit_no_set_flags() = no_set_flags; + } + else { + if ((i = encode_arm_immediate(i0)) != -1) + SBCSI(r0, r1, i); + else if ((i = encode_arm_immediate(-i0)) != -1) + ADCSI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + SBCS(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + SBCS(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + subi(r0, r1, i0); + negr(r0, r0); +} + +static void +_mulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (jit_thumb_p()) { + if (!jit_no_set_flags() && r0 == r2 && (r0|r1) < 8) + T1_MUL(r0, r1); + else if (!jit_no_set_flags() && r0 == r1 && (r0|r2) < 8) + T1_MUL(r0, r2); + else + T2_MUL(r0, r1, r2); + } + else { + if (r0 == r1 && !jit_armv6_p()) { + if (r0 != r2) + MUL(r0, r2, r1); + else { + reg = jit_get_reg(jit_class_gpr); + MOV(rn(reg), r1); + MUL(r0, rn(reg), r2); + jit_unget_reg(reg); + } + } + else + MUL(r0, r1, r2); + } +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + mulr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_iqmulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + jit_int32_t reg; + if (jit_thumb_p()) { + if (r2 == r3) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r2); + if (sign) + T2_SMULL(r0, r1, rn(reg), r2); + else + T2_UMULL(r0, r1, rn(reg), r2); + jit_unget_reg(reg); + } + else if (r0 != r2 && r1 != r2) { + if (sign) + T2_SMULL(r0, r1, r2, r3); + else + T2_UMULL(r0, r1, r2, r3); + } + else { + if (sign) + T2_SMULL(r0, r1, r3, r2); + else + T2_UMULL(r0, r1, r3, r2); + } + } + else { + if (r2 == r3) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r2); + if (sign) + SMULL(r0, r1, rn(reg), r2); + else + UMULL(r0, r1, rn(reg), r2); + jit_unget_reg(reg); + } + else if (r0 != r2 && r1 != r2) { + if (sign) + SMULL(r0, r1, r2, r3); + else + UMULL(r0, r1, r2, r3); + } + else { + if (sign) + SMULL(r0, r1, r3, r2); + else + UMULL(r0, r1, r3, r2); + } + } +} + +static void +_iqmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iqmulr(r0, r1, r2, rn(reg), sign); + jit_unget_reg(reg); +} + +static void +_divrem(jit_state_t *_jit, int div, int sign, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t d; + jit_word_t w; + jit_get_reg_args(); + movr(_R0_REGNO, r1); + movr(_R1_REGNO, r2); + if (sign) w = (jit_word_t)__aeabi_idivmod; + else w = (jit_word_t)__aeabi_uidivmod; + if (!jit_exchange_p()) { + if (jit_thumb_p()) d = ((w - _jit->pc.w) >> 1) - 2; + else d = ((w - _jit->pc.w) >> 2) - 2; + if (_s24P(d)) { + if (jit_thumb_p()) T2_BLI(encode_thumb_jump(d)); + else BLI(d & 0x00ffffff); + } + else goto fallback; + } + else { + fallback: + movi(_R2_REGNO, w); + if (jit_thumb_p()) T1_BLX(_R2_REGNO); + else BLX(_R2_REGNO); + } + if (div) movr(r0, _R0_REGNO); + else movr(r0, _R1_REGNO); + jit_unget_reg_args(); +} + +static void +_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_armv7r_p() && jit_thumb_p()) + T2_SDIV(r0, r1, r2); + else + divrem(1, 1, r0, r1, r2); +} + +static void +_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + divr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_armv7r_p() && jit_thumb_p()) + T2_UDIV(r0, r1, r2); + else + divrem(1, 0, r0, r1, r2); +} + +static void +_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + divr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_iqdivr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + jit_word_t d; + jit_word_t w; + jit_get_reg_args(); + movr(_R0_REGNO, r2); + movr(_R1_REGNO, r3); + if (sign) w = (jit_word_t)__aeabi_idivmod; + else w = (jit_word_t)__aeabi_uidivmod; + if (!jit_exchange_p()) { + if (jit_thumb_p()) d = ((w - _jit->pc.w) >> 1) - 2; + else d = ((w - _jit->pc.w) >> 2) - 2; + if (_s24P(d)) { + if (jit_thumb_p()) T2_BLI(encode_thumb_jump(d)); + else BLI(d & 0x00ffffff); + } + else goto fallback; + } + else { + fallback: + movi(_R2_REGNO, w); + if (jit_thumb_p()) T1_BLX(_R2_REGNO); + else BLX(_R2_REGNO); + } + movr(r0, _R0_REGNO); + movr(r1, _R1_REGNO); + jit_unget_reg_args(); +} + +static void +_iqdivi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iqdivr(r0, r1, r2, rn(reg), sign); + jit_unget_reg(reg); +} + +static void +_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + divrem(0, 1, r0, r1, r2); +} + +static void +_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + divrem(0, 0, r0, r1, r2); +} + +static void +_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr_u(r0, r1,rn(reg)); + jit_unget_reg(reg); +} + +static void +_andr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1|r2) < 8 && (r0 == r1 || r0 == r2)) + T1_AND(r0, r0 == r1 ? r2 : r1); + else + T2_AND(r0, r1, r2); + } + else + AND(r0, r1, r2); +} + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + int i; + jit_int32_t reg; + if (jit_thumb_p()) { + if ((i = encode_thumb_immediate(i0)) != -1) + T2_ANDI(r0, r1, i); + else if ((i = encode_thumb_immediate(~i0)) != -1) + T2_BICI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + T2_AND(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + T2_AND(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if ((i = encode_arm_immediate(i0)) != -1) + ANDI(r0, r1, i); + else if ((i = encode_arm_immediate(~i0)) != -1) + BICI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + AND(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + AND(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_orr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1|r2) < 8 && (r0 == r1 || r0 == r2)) + T1_ORR(r0, r0 == r1 ? r2 : r1); + else + T2_ORR(r0, r1, r2); + } + else + ORR(r0, r1, r2); +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + int i; + jit_int32_t reg; + if (jit_thumb_p()) { + if ((i = encode_thumb_immediate(i0)) != -1) + T2_ORRI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + T2_ORR(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + T2_ORR(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if ((i = encode_arm_immediate(i0)) != -1) + ORRI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + ORR(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ORR(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_xorr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1|r2) < 8 && (r0 == r1 || r0 == r2)) + T1_EOR(r0, r0 == r1 ? r2 : r1); + else + T2_EOR(r0, r1, r2); + } + else + EOR(r0, r1, r2); +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + int i; + jit_int32_t reg; + if (jit_thumb_p()) { + if ((i = encode_thumb_immediate(i0)) != -1) + T2_EORI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + T2_EOR(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + T2_EOR(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if ((i = encode_arm_immediate(i0)) != -1) + EORI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + EOR(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + EOR(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_lshr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1|r2) < 8 && r0 == r1) + T1_LSL(r0, r2); + else + T2_LSL(r0, r1, r2); + } + else + LSL(r0, r1, r2); +} + +static void +_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + assert(i0 >= 0 && i0 <= 31); + if (i0 == 0) + movr(r0, r1); + else if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1) < 8) + T1_LSLI(r0, r1, i0); + else + T2_LSLI(r0, r1, i0); + } + else + LSLI(r0, r1, i0); +} + +static void +_rshr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1|r2) < 8 && r0 == r1) + T1_ASR(r0, r2); + else + T2_ASR(r0, r1, r2); + } + else + ASR(r0, r1, r2); +} + +static void +_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + assert(i0 >= 0 && i0 <= 31); + if (i0 == 0) + movr(r0, r1); + else if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1) < 8) + T1_ASRI(r0, r1, i0); + else + T2_ASRI(r0, r1, i0); + } + else + ASRI(r0, r1, i0); +} + +static void +_rshr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1|r2) < 8 && r0 == r1) + T1_LSR(r0, r2); + else + T2_LSR(r0, r1, r2); + } + else + LSR(r0, r1, r2); +} + +static void +_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + assert(i0 >= 0 && i0 <= 31); + if (i0 == 0) + movr(r0, r1); + else if (jit_thumb_p()) { + if (!jit_no_set_flags() && (r0|r1) < 8) + T1_LSRI(r0, r1, i0); + else + T2_LSRI(r0, r1, i0); + } + else + LSRI(r0, r1, i0); +} + +static void +_ccr(jit_state_t *_jit, int ct, int cf, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + assert((ct ^ cf) >> 28 == 1); + if ((r1|r2) < 8) + T1_CMP(r1, r2); + else if ((r1&r2) & 8) + T1_CMPX(r1, r2); + else + T2_CMP(r1, r2); + ITE(ct); + if (r0 < 8) { + T1_MOVI(r0, 1); + T1_MOVI(r0, 0); + } + else { + T2_MOVI(r0, 1); + T2_MOVI(r0, 0); + } + } + else { + CMP(r1, r2); + CC_MOVI(ct, r0, 1); + CC_MOVI(cf, r0, 0); + } +} + +static void +_cci(jit_state_t *_jit, int ct, int cf, + jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + int i; + jit_int32_t reg; + if (jit_thumb_p()) { + if (r1 < 7 && !(i0 & 0xffffff00)) + T1_CMPI(r1, i0); + else if ((i = encode_thumb_immediate(i0)) != -1) + T2_CMPI(r1, i); + else if ((i = encode_thumb_immediate(-i0)) != -1) + T2_CMNI(r1, i); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ccr(ct, cf, r0, r1, rn(reg)); + jit_unget_reg(reg); + return; + } + ITE(ct); + if (r0 < 8) { + T1_MOVI(r0, 1); + T1_MOVI(r0, 0); + } + else { + T2_MOVI(r0, 1); + T2_MOVI(r0, 0); + } + } + else { + if ((i = encode_arm_immediate(i0)) != -1) + CMPI(r1, i); + else if ((i = encode_arm_immediate(-i0)) != -1) + CMNI(r1, i); + else if (r0 != r1) { + movi(r0, i0); + CMP(r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMP(r1, rn(reg)); + jit_unget_reg(reg); + } + CC_MOVI(ct, r0, 1); + CC_MOVI(cf, r0, 0); + } +} + +static void +_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) + ccr(ARM_CC_NE, ARM_CC_EQ, r0, r1, r2); + else { + SUBS(r0, r1, r2); + CC_MOVI(ARM_CC_NE, r0, 1); + } +} + +static void +_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + int i; + jit_int32_t reg; + if (jit_thumb_p()) + cci(ARM_CC_NE, ARM_CC_EQ, r0, r1, i0); + else { + if ((i = encode_arm_immediate(i0)) != -1) + SUBSI(r0, r1, i); + else if ((i = encode_arm_immediate(-i0)) != -1) + ADDSI(r0, r1, i); + else if (r0 != r1) { + movi(r0, i0); + SUBS(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + SUBS(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + CC_MOVI(ARM_CC_NE, r0, 1); + } +} + +static void +_jmpr(jit_state_t *_jit, jit_int32_t r0) +{ + if (jit_thumb_p()) + T1_MOV(_R15_REGNO, r0); + else + MOV(_R15_REGNO, r0); +} + +static void +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_word_t d; + jit_int32_t reg; + w = _jit->pc.w; + /* if thumb and in thumb mode */ + if (jit_thumb_p() && _jitc->thumb) { + d = ((i0 - w) >> 1) - 2; + if (d >= -1024 && d <= 1023) + T1_B(d & 0x7ff); + else if (_s24P(d)) + T2_B(encode_thumb_jump(d)); + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + } + } + else { + d = ((i0 - w) >> 2) - 2; + if (_s24P(d)) + B(d & 0x00ffffff); + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + } + } +} + +static jit_word_t +_jmpi_p(jit_state_t *_jit, jit_word_t i0, jit_bool_t i1) +{ + jit_word_t w; + jit_word_t d; + jit_int32_t reg; + if (i1) { + /* Assume jump is not longer than 23 bits if inside jit */ + w = _jit->pc.w; + /* if thumb and in thumb mode */ + if (jit_thumb_p() && _jitc->thumb) { + d = ((i0 - w) >> 1) - 2; + assert(_s24P(d)); + T2_B(encode_thumb_jump(d)); + } + else { + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + B(d & 0x00ffffff); + } + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + w = movi_p(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bccr(jit_state_t *_jit, int cc, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_word_t d; + if (jit_thumb_p()) { + if ((r0|r1) < 8) + T1_CMP(r0, r1); + else if ((r0&r1) & 8) + T1_CMPX(r0, r1); + else + T2_CMP(r0, r1); + /* use only thumb2 conditional as does not know if will be patched */ + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(cc, encode_thumb_cc_jump(d)); + } + else { + CMP(r0, r1); + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(cc, d & 0x00ffffff); + } + return (w); +} + +static jit_word_t +_bcci(jit_state_t *_jit, int cc, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_word_t d; + int i; + jit_int32_t reg; + if (jit_thumb_p()) { + if (r0 < 7 && !(i1 & 0xffffff00)) + T1_CMPI(r0, i1); + else if ((i = encode_thumb_immediate(i1)) != -1) + T2_CMPI(r0, i); + else if ((i = encode_thumb_immediate(-i1)) != -1) + T2_CMNI(r0, i); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + T2_CMP(r0, rn(reg)); + jit_unget_reg(reg); + } + /* use only thumb2 conditional as does not know if will be patched */ + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(cc, encode_thumb_cc_jump(d)); + } + else { + if ((i = encode_arm_immediate(i1)) != -1) + CMPI(r0, i); + else if ((i = encode_arm_immediate(-i1)) != -1) + CMNI(r0, i); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMP(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(cc, d & 0x00ffffff); + } + return (w); +} + +static jit_word_t +_baddr(jit_state_t *_jit, int cc, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_word_t d; + if (jit_thumb_p()) { + if ((r0|r1) < 8) + T1_ADD(r0, r0, r1); + else + T2_ADDS(r0, r0, r1); + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(cc, encode_thumb_cc_jump(d)); + } + else { + ADDS(r0, r0, r1); + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(cc, d & 0x00ffffff); + } + return (w); +} + +static jit_word_t +_baddi(jit_state_t *_jit, int cc, jit_word_t i0, jit_int32_t r0, int i1) +{ + int i; + jit_word_t w; + jit_word_t d; + jit_int32_t reg; + if (jit_thumb_p()) { + if (r0 < 8 && !(i1 & ~7)) + T1_ADDI3(r0, r0, i1); + else if (r0 < 8 && !(-i1 & ~7)) + T1_SUBI3(r0, r0, -i1); + else if (r0 < 8 && !(i1 & ~0xff)) + T1_ADDI8(r0, i1); + else if (r0 < 8 && !(-i1 & ~0xff)) + T1_SUBI8(r0, -i1); + else if ((i = encode_thumb_immediate(i1)) != -1) + T2_ADDSI(r0, r0, i); + else if ((i = encode_thumb_immediate(-i1)) != -1) + T2_SUBSI(r0, r0, i); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + T2_ADDS(r0, r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(cc, encode_thumb_cc_jump(d)); + } + else { + if ((i = encode_arm_immediate(i1)) != -1) + ADDSI(r0, r0, i); + else if ((i = encode_arm_immediate(-i1)) != -1) + SUBSI(r0, r0, i); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + ADDS(r0, r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(cc, d & 0x00ffffff); + } + return (w); +} + +static jit_word_t +_bsubr(jit_state_t *_jit, int cc, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_word_t d; + if (jit_thumb_p()) { + if ((r0|r1) < 8) + T1_SUB(r0, r0, r1); + else + T2_SUBS(r0, r0, r1); + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(cc, encode_thumb_cc_jump(d)); + } + else { + SUBS(r0, r0, r1); + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(cc, d & 0x00ffffff); + } + return (w); +} + +static jit_word_t +_bsubi(jit_state_t *_jit, int cc, jit_word_t i0, jit_int32_t r0, int i1) +{ + int i; + jit_word_t w; + jit_word_t d; + jit_int32_t reg; + if (jit_thumb_p()) { + if (r0 < 8 && !(i1 & ~7)) + T1_SUBI3(r0, r0, i1); + else if (r0 < 8 && !(-i1 & ~7)) + T1_ADDI3(r0, r0, -i1); + else if (r0 < 8 && !(i1 & ~0xff)) + T1_SUBI8(r0, i1); + else if (r0 < 8 && !(-i1 & ~0xff)) + T1_ADDI8(r0, -i1); + else if ((i = encode_thumb_immediate(i1)) != -1) + T2_SUBSI(r0, r0, i); + else if ((i = encode_thumb_immediate(-i1)) != -1) + T2_SUBSI(r0, r0, i); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + T2_SUBS(r0, r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(cc, encode_thumb_cc_jump(d)); + } + else { + if ((i = encode_arm_immediate(i1)) != -1) + SUBSI(r0, r0, i); + else if ((i = encode_arm_immediate(-i1)) != -1) + ADDSI(r0, r0, i); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + SUBS(r0, r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(cc, d & 0x00ffffff); + } + return (w); +} + +static jit_word_t +_bmxr(jit_state_t *_jit, int cc, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_word_t d; + jit_int32_t reg; + if (jit_thumb_p()) { + if ((r0|r1) < 8) + T1_TST(r0, r1); + else + T2_TST(r0, r1); + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(cc, encode_thumb_cc_jump(d)); + } + else { + if (jit_armv5_p()) + TST(r0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + ANDS(rn(reg), r0, r1); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(cc, d & 0x00ffffff); + } + return (w); +} + +static jit_word_t +_bmxi(jit_state_t *_jit, int cc, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + int i; + jit_word_t w; + jit_word_t d; + jit_int32_t reg; + if (jit_thumb_p()) { + if ((i = encode_thumb_immediate(i1)) != -1) + T2_TSTI(r0, i); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + T2_TST(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(cc, encode_thumb_cc_jump(d)); + } + else { + if (jit_armv5_p()) { + if ((i = encode_arm_immediate(i1)) != -1) + TSTI(r0, i); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + TST(r0, rn(reg)); + jit_unget_reg(reg); + } + } + else { + reg = jit_get_reg(jit_class_gpr); + if ((i = encode_arm_immediate(i1)) != -1) + ANDSI(rn(reg), r0, i); + else if ((i = encode_arm_immediate(~i1)) != -1) + BICSI(rn(reg), r0, i); + else { + movi(rn(reg), i1); + ANDS(rn(reg), r0, rn(reg)); + } + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(cc, d & 0x00ffffff); + } + return (w); +} + +static void +_ldr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) + T2_LDRSBI(r0, r1, 0); + else + LDRSBI(r0, r1, 0); +} + +static void +_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if (jit_thumb_p()) + T2_LDRSBI(r0, rn(reg), 0); + else + LDRSBI(r0, rn(reg), 0); + jit_unget_reg(reg); +} + +static void +_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if ((r0|r1|r2) < 8) + T1_LDRSB(r0, r1, r2); + else + T2_LDRSB(r0, r1, r2); + } + else + LDRSB(r0, r1, r2); +} + +static void +_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_thumb_p()) { + if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255) + T2_LDRSBI(r0, r1, i0); + else if (i0 < 0 && i0 >= -255) + T2_LDRSBIN(r0, r1, -i0); + else if (i0 >= 0 && i0 <= 4095) + T2_LDRSBWI(r0, r1, i0); + else if (r0 != r1) { + movi(r0, i0); + if ((r0|r1) < 8) + T1_LDRSB(r0, r1, r0); + else + T2_LDRSB(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if ((r0|r1|rn(reg)) < 8) + T1_LDRSB(r0, r1, rn(reg)); + else + T2_LDRSB(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if (i0 >= 0 && i0 <= 255) + LDRSBI(r0, r1, i0); + else if (i0 < 0 && i0 >= -255) + LDRSBIN(r0, r1, -i0); + else if (r0 != r1) { + movi(r0, i0); + LDRSB(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDRSB(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_ldr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) + T2_LDRBI(r0, r1, 0); + else + LDRBI(r0, r1, 0); +} + +static void +_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if (jit_thumb_p()) + T2_LDRBI(r0, rn(reg), 0); + else + LDRBI(r0, rn(reg), 0); + jit_unget_reg(reg); +} + +static void +_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if ((r0|r1|r2) < 8) + T1_LDRB(r0, r1, r2); + else + T2_LDRB(r0, r1, r2); + } + else + LDRB(r0, r1, r2); +} + +static void +_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_thumb_p()) { + if ((r0|r1) < 8 && i0 >= 0 && i0 < 0x20) + T1_LDRBI(r0, r1, i0); + else if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255) + T2_LDRBI(r0, r1, i0); + else if (i0 < 0 && i0 >= -255) + T2_LDRBIN(r0, r1, -i0); + else if (i0 >= 0 && i0 <= 4095) + T2_LDRBWI(r0, r1, i0); + else if (r0 != r1) { + movi(r0, i0); + if ((r0|r1) < 8) + T1_LDRB(r0, r1, r0); + else + T2_LDRB(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if ((r0|r1|rn(reg)) < 8) + T1_LDRB(r0, r1, rn(reg)); + else + T2_LDRB(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if (i0 >= 0 && i0 <= 4095) + LDRBI(r0, r1, i0); + else if (i0 < 0 && i0 >= -4095) + LDRBIN(r0, r1, -i0); + else if (r0 != r1) { + movi(r0, i0); + LDRB(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDRB(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_ldr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) + T2_LDRSHI(r0, r1, 0); + else + LDRSHI(r0, r1, 0); +} + +static void +_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if (jit_thumb_p()) + T2_LDRSHI(r0, rn(reg), 0); + else + LDRSHI(r0, rn(reg), 0); + jit_unget_reg(reg); +} + +static void +_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if ((r0|r1|r2) < 8) + T1_LDRSH(r0, r1, r2); + else + T2_LDRSH(r0, r1, r2); + } + else + LDRSH(r0, r1, r2); +} + +static void +_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_thumb_p()) { + if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255) + T2_LDRSHI(r0, r1, i0); + else if (i0 < 0 && i0 >= -255) + T2_LDRSHIN(r0, r1, -i0); + else if (i0 >= 0 && i0 <= 4095) + T2_LDRSHWI(r0, r1, i0); + else if (r0 != r1) { + movi(r0, i0); + if ((r0|r1) < 8) + T1_LDRSH(r0, r1, r0); + else + T2_LDRSH(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if ((r0|r1|rn(reg)) < 8) + T1_LDRSH(r0, r1, rn(reg)); + else + T2_LDRSH(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if (i0 >= 0 && i0 <= 255) + LDRSHI(r0, r1, i0); + else if (i0 < 0 && i0 >= -255) + LDRSHIN(r0, r1, -i0); + else if (r0 != r1) { + movi(r0, i0); + LDRSH(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDRSH(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_ldr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) + T2_LDRHI(r0, r1, 0); + else + LDRHI(r0, r1, 0); +} + +static void +_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if (jit_thumb_p()) + T2_LDRHI(r0, rn(reg), 0); + else + LDRHI(r0, rn(reg), 0); + jit_unget_reg(reg); +} + +static void +_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if ((r0|r1|r2) < 8) + T1_LDRH(r0, r1, r2); + else + T2_LDRH(r0, r1, r2); + } + else + LDRH(r0, r1, r2); +} + +static void +_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_thumb_p()) { + if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 1) && (i0 >> 1) < 0x20) + T1_LDRHI(r0, r1, i0 >> 1); + else if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255) + T2_LDRHI(r0, r1, i0); + else if (i0 < 0 && i0 >= -255) + T2_LDRHIN(r0, r1, -i0); + else if (i0 >= 0 && i0 <= 4095) + T2_LDRHWI(r0, r1, i0); + else if (r0 != r1) { + movi(r0, i0); + if ((r0|r1) < 8) + T1_LDRH(r0, r1, r0); + else + T2_LDRH(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if ((r0|r1|rn(reg)) < 8) + T1_LDRH(r0, r1, rn(reg)); + else + T2_LDRH(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if (i0 >= 0 && i0 <= 255) + LDRHI(r0, r1, i0); + else if (i0 < 0 && i0 >= -255) + LDRHIN(r0, r1, -i0); + else if (r0 != r1) { + movi(r0, i0); + LDRH(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDRH(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_ldr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) + T2_LDRI(r0, r1, 0); + else + LDRI(r0, r1, 0); +} + +static void +_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if (jit_thumb_p()) + T2_LDRI(r0, rn(reg), 0); + else + LDRI(r0, rn(reg), 0); + jit_unget_reg(reg); +} + +static void +_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if ((r0|r1|r2) < 8) + T1_LDR(r0, r1, r2); + else + T2_LDR(r0, r1, r2); + } + else + LDR(r0, r1, r2); +} + +static void +_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_thumb_p()) { + if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 3) && (i0 >> 2) < 0x20) + T1_LDRI(r0, r1, i0 >> 2); + else if (r1 == _R13_REGNO && r0 < 8 && + i0 >= 0 && !(i0 & 3) && (i0 >> 2) <= 255) + T1_LDRISP(r0, i0 >> 2); + else if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255) + T2_LDRI(r0, r1, i0); + else if (i0 < 0 && i0 > -255) + T2_LDRIN(r0, r1, -i0); + else if (i0 >= 0 && i0 <= 4095) + T2_LDRWI(r0, r1, i0); + else if (r0 != r1) { + movi(r0, i0); + if ((r0|r1) < 8) + T1_LDR(r0, r1, r0); + else + T2_LDR(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if ((r0|r1|rn(reg)) < 8) + T1_LDR(r0, r1, rn(reg)); + else + T2_LDR(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if (i0 >= 0 && i0 <= 4095) + LDRI(r0, r1, i0); + else if (i0 < 0 && i0 >= -4095) + LDRIN(r0, r1, -i0); + else if (r0 != r1) { + movi(r0, i0); + LDR(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDR(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_str_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) + T2_STRBI(r1, r0, 0); + else + STRBI(r1, r0, 0); +} + +static void +_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if (jit_thumb_p()) + T2_STRBI(r0, rn(reg), 0); + else + STRBI(r0, rn(reg), 0); + jit_unget_reg(reg); +} + +static void +_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if ((r0|r1|r2) < 8) + T1_STRB(r2, r1, r0); + else + T2_STRB(r2, r1, r0); + } + else + STRB(r2, r1, r0); +} + +static void +_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_thumb_p()) { + if ((r0|r1) < 8 && i0 >= 0 && i0 < 0x20) + T1_STRBI(r1, r0, i0); + else if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255) + T2_STRBI(r1, r0, i0); + else if (i0 < 0 && i0 >= -255) + T2_STRBIN(r1, r0, -i0); + else if (i0 >= 0 && i0 <= 4095) + T2_STRBWI(r1, r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if ((r0|r1|rn(reg)) < 8) + T1_STRB(r1, r0, rn(reg)); + else + T2_STRB(r1, r0, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if (i0 >= 0 && i0 <= 4095) + STRBI(r1, r0, i0); + else if (i0 < 0 && i0 >= -4095) + STRBIN(r1, r0, -i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + STRB(r1, r0, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_str_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) + T2_STRHI(r1, r0, 0); + else + STRHI(r1, r0, 0); +} + +static void +_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if (jit_thumb_p()) + T2_STRHI(r0, rn(reg), 0); + else + STRHI(r0, rn(reg), 0); + jit_unget_reg(reg); +} + +static void +_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if ((r0|r1|r2) < 8) + T1_STRH(r2, r1, r0); + else + T2_STRH(r2, r1, r0); + } + else + STRH(r2, r1, r0); +} + +static void +_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_thumb_p()) { + if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 1) && (i0 >> 1) < 0x20) + T1_STRHI(r1, r0, i0 >> 1); + else if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255) + T2_STRHI(r1, r0, i0); + else if (i0 < 0 && i0 >= -255) + T2_STRHIN(r1, r0, -i0); + else if (i0 >= 0 && i0 <= 4095) + T2_STRHWI(r1, r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if ((r0|r1|rn(reg)) < 8) + T1_STRH(r1, r0, rn(reg)); + else + T2_STRH(r1, r0, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if (i0 >= 0 && i0 <= 255) + STRHI(r1, r0, i0); + else if (i0 < 0 && i0 >= -255) + STRHIN(r1, r0, -i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + STRH(r1, r0, rn(reg)); + jit_unget_reg(reg); + } + } +} + +static void +_str_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) + T2_STRI(r1, r0, 0); + else + STRI(r1, r0, 0); +} + +static void +_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if (jit_thumb_p()) + T2_STRI(r0, rn(reg), 0); + else + STRI(r0, rn(reg), 0); + jit_unget_reg(reg); +} + +static void +_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (jit_thumb_p()) { + if ((r0|r1|r2) < 8) + T1_STR(r2, r1, r0); + else + T2_STR(r2, r1, r0); + } + else + STR(r2, r1, r0); +} + +static void +_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_thumb_p()) { + if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 3) && (i0 >> 2) < 0x20) + T1_STRI(r1, r0, i0 >> 2); + else if (r0 == _R13_REGNO && r1 < 8 && + i0 >= 0 && !(i0 & 3) && (i0 >> 2) <= 255) + T1_STRISP(r1, i0 >> 2); + else if (jit_ldrt_strt_p() && i0 >= 0 && i0 <= 255) + T2_STRI(r1, r0, i0); + else if (i0 < 0 && i0 >= -255) + T2_STRIN(r1, r0, -i0); + else if (i0 >= 0 && i0 <= 4095) + T2_STRWI(r1, r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if ((r0|r1|rn(reg)) < 8) + T1_STR(r1, r0, rn(reg)); + else + T2_STR(r1, r0, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if (i0 >= 0 && i0 <= 4095) + STRI(r1, r0, i0); + else if (i0 < 0 && i0 >= -4095) + STRIN(r1, r0, -i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + STR(r1, r0, rn(reg)); + jit_unget_reg(reg); + } + } +} + +# if __BYTE_ORDER == __LITTLE_ENDIAN +static void +_htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + if (jit_thumb_p()) { + if ((r0|r1) < 8) + T1_REV(r0, r1); + else + T2_REV(r0, r1); + rshi_u(r0, r0, 16); + } + else { + if (jit_armv6_p()) { + REV(r0, r1); + rshi_u(r0, r0, 16); + } + else { + t0 = jit_get_reg(jit_class_gpr); + rshi(rn(t0), r1, 8); + andi(r0, r1, 0xff); + andi(rn(t0), rn(t0), 0xff); + lshi(r0, r0, 8); + orr(r0, r0, rn(t0)); + jit_unget_reg(t0); + } + } +} + +/* inline glibc htonl (without register clobber) */ +static void +_htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_thumb_p()) { + if ((r0|r1) < 8) + T1_REV(r0, r1); + else + T2_REV(r0, r1); + } + else { + if (jit_armv6_p()) + REV(r0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + EOR_SI(rn(reg), r1, r1, ARM_ROR, 16); + LSRI(rn(reg), rn(reg), 8); + BICI(rn(reg), rn(reg), encode_arm_immediate(0xff00)); + EOR_SI(r0, rn(reg), r1, ARM_ROR, 8); + jit_unget_reg(reg); + } + } +} +#endif + +static void +_extr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) { + if ((r0|r1) < 8) + T1_SXTB(r0, r1); + else + T2_SXTB(r0, r1); + } + else { + if (jit_armv6_p()) + SXTB(r0, r1); + else { + LSLI(r0, r1, 24); + ASRI(r0, r0, 24); + } + } +} + +static void +_extr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) { + if ((r0|r1) < 8) + T1_UXTB(r0, r1); + else + T2_UXTB(r0, r1); + } + else { + if (jit_armv6_p()) + UXTB(r0, r1); + else + ANDI(r0, r1, 0xff); + } +} + +static void +_extr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) { + if ((r0|r1) < 8) + T1_SXTH(r0, r1); + else + T2_SXTH(r0, r1); + } + else { + if (jit_armv6_p()) + SXTH(r0, r1); + else { + LSLI(r0, r1, 16); + ASRI(r0, r0, 16); + } + } +} + +static void +_extr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_thumb_p()) { + if ((r0|r1) < 8) + T1_UXTH(r0, r1); + else + T2_UXTH(r0, r1); + } + else { + if (jit_armv6_p()) + UXTH(r0, r1); + else { + LSLI(r0, r1, 16); + LSRI(r0, r0, 16); + } + } +} + +static void +_callr(jit_state_t *_jit, jit_int32_t r0) +{ + if (jit_thumb_p()) + T1_BLX(r0); + else + BLX(r0); +} + +static void +_calli(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t d; + jit_int32_t reg; + d = ((i0 - _jit->pc.w) >> 2) - 2; + if (!jit_exchange_p() && !jit_thumb_p() && _s24P(d)) + BLI(d & 0x00ffffff); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if (jit_thumb_p()) + T1_BLX(rn(reg)); + else + BLX(rn(reg)); + jit_unget_reg(reg); + } +} + +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + w = _jit->pc.w; + movi_p(rn(reg), i0); + if (jit_thumb_p()) + T1_BLX(rn(reg)); + else + BLX(rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_prolog(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t reg; + if (_jitc->function->define_frame || _jitc->function->assume_frame) { + jit_int32_t frame = -_jitc->function->frame; + assert(_jitc->function->self.aoff >= frame); + if (_jitc->function->assume_frame) { + if (jit_thumb_p() && !_jitc->thumb) + _jitc->thumb = _jit->pc.w; + return; + } + _jitc->function->self.aoff = frame; + } + if (_jitc->function->allocar) + _jitc->function->self.aoff &= -8; + _jitc->function->stack = ((_jitc->function->self.alen - + /* align stack at 8 bytes */ + _jitc->function->self.aoff) + 7) & -8; + + if (jit_thumb_p()) { + /* switch to thumb mode (better approach would be to + * ORR 1 address being called, but no clear distinction + * of what is a pointer to a jit function, or if patching + * a pointer to a jit function) */ + ADDI(_R12_REGNO, _R15_REGNO, 1); + BX(_R12_REGNO); + if (!_jitc->thumb) + _jitc->thumb = _jit->pc.w; + if (jit_cpu.abi) { + T2_PUSH(0xf); + T2_PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO)); + VPUSH_F64(_D8_REGNO, 8); + } + else { + T2_PUSH(0xf); + T2_PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO)); + } + } + else { + if (jit_cpu.abi) { + PUSH(0xf); + PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO)); + VPUSH_F64(_D8_REGNO, 8); + } + else { + PUSH(0xf); + PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO)); + } + } + movr(_FP_REGNO, _SP_REGNO); + if (_jitc->function->stack) + subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack); + if (_jitc->function->allocar) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), _jitc->function->self.aoff); + stxi_i(_jitc->function->aoffoff, _FP_REGNO, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *node) +{ + if (_jitc->function->assume_frame) + return; + + movr(_SP_REGNO, _FP_REGNO); + if (jit_cpu.abi) + VPOP_F64(_D8_REGNO, 8); + if (jit_thumb_p()) + T2_POP(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO)); + else + POP(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO)); + addi(_SP_REGNO, _SP_REGNO, 16); + if (jit_thumb_p()) + T1_BX(_LR_REGNO); + else + BX(_LR_REGNO); + if (jit_thumb_p() && (_jit->pc.w & 2)) + T1_NOP(); +} + +static void +_vastart(jit_state_t *_jit, jit_int32_t r0) +{ + assert(_jitc->function->self.call & jit_call_varargs); + + /* Initialize stack pointer to the first stack argument. + * The -16 is to account for the 4 argument registers + * always saved, and _jitc->function->vagp is to account + * for declared arguments. */ + addi(r0, _FP_REGNO, _jitc->function->self.size - + 16 + _jitc->function->vagp); +} + +static void +_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(_jitc->function->self.call & jit_call_varargs); + + /* Load argument. */ + ldr(r0, r1); + + /* Update stack pointer. */ + addi(r1, r1, sizeof(jit_word_t)); +} + +static void +_patch_at(jit_state_t *_jit, + jit_int32_t kind, jit_word_t instr, jit_word_t label) +{ + jit_word_t d; + jit_thumb_t thumb; + union { + jit_int16_t *s; + jit_int32_t *i; + jit_word_t w; + } u; + u.w = instr; + if (kind == arm_patch_jump) { + if (jit_thumb_p() && (jit_uword_t)instr >= _jitc->thumb) { + code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + if ((thumb.i & THUMB2_B) == THUMB2_B) { + d = ((label - instr) >> 1) - 2; + assert(_s24P(d)); + thumb.i = THUMB2_B | encode_thumb_jump(d); + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + } + else if ((thumb.i & THUMB2_B) == THUMB2_CC_B) { + d = ((label - instr) >> 1) - 2; + assert(_s20P(d)); + thumb.i = THUMB2_CC_B | (thumb.i & 0x3c00000) | + encode_thumb_cc_jump(d); + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + } + else { + /* for the sake of simplicity in case choose to + * movw+movt+[bx|blx], e.g. if changing to instead + * of asserting target is reachable, load constant + * and do indirect jump if not reachable */ + if ((thumb.i & 0xfbf00000) == THUMB2_MOVWI) + goto indirect_jump; + assert(!"handled branch opcode"); + } + } + else { + thumb.i = u.i[0]; + /* 0x0e000000 because 0x01000000 is (branch&) link modifier */ + assert((thumb.i & 0x0e000000) == ARM_B); + d = ((label - instr) >> 2) - 2; + assert(_s24P(d)); + u.i[0] = (thumb.i & 0xff000000) | (d & 0x00ffffff); + } + } + else if (kind == arm_patch_load) { + /* offset may be negative for a forward patch because it + * is relative to pc + 8, for example: + * ldr r0, [pc, #-4] + * bx r0 ;; [pc, #-8] + * .data ... ;; [pc, #-4] + * ... ;; [pc] + */ + assert(!jit_thumb_p()); + thumb.i = u.i[0]; + assert((thumb.i & 0x0f700000) == ARM_LDRI); + d = label - (instr + 8); + if (d < 0) { + thumb.i &= ~ARM_P; + d = -d; + } + else + thumb.i |= ARM_P; + assert(!(d & 0xfffff000)); + u.i[0] = (thumb.i & 0xfffff000) | d; + } + else if (kind == arm_patch_word) { + if (jit_thumb_p()) { + code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + assert((thumb.i & 0xfbf00000) == THUMB2_MOVWI); + indirect_jump: + thumb.i = ((thumb.i & 0xfbf00f00) | + ( (label & 0x0000f000) << 4) | + ( (label & 0x00000800) << 15) | + ( (label & 0x00000700) << 4) | + ( label & 0x000000ff)); + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + label >>= 16; + code2thumb(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); + assert((thumb.i & 0xfbf00000) == THUMB2_MOVTI); + thumb.i = ((thumb.i & 0xfbf00f00) | + ( (label & 0x0000f000) << 4) | + ( (label & 0x00000800) << 15) | + ( (label & 0x00000700) << 4) | + ( label & 0x000000ff)); + thumb2code(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); + } + else + u.i[0] = label; + } + else + assert(!"handled patch"); +} +#endif diff --git a/deps/lightning/lib/jit_arm-swf.c b/deps/lightning/lib/jit_arm-swf.c new file mode 100644 index 0000000..bf86ca1 --- /dev/null +++ b/deps/lightning/lib/jit_arm-swf.c @@ -0,0 +1,2640 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +/* match vfpv3 result */ +#define NAN_TO_INT_IS_ZERO 1 +extern float sqrtf(float); +extern double sqrt(double); +extern float __addsf3(float, float); +extern double __adddf3(double, double); +extern float __aeabi_fsub(float, float); +extern double __aeabi_dsub(double, double); +extern float __aeabi_fmul(float, float); +extern double __aeabi_dmul(double, double); +extern float __aeabi_fdiv(float, float); +extern double __aeabi_ddiv(double, double); +extern float __aeabi_i2f(int); +extern double __aeabi_i2d(int); +extern float __aeabi_d2f(double); +extern double __aeabi_f2d(float); +extern int __aeabi_f2iz(float); +extern int __aeabi_d2iz(double); +extern int __aeabi_fcmplt(float, float); +extern int __aeabi_dcmplt(double, double); +extern int __aeabi_fcmple(float, float); +extern int __aeabi_dcmple(double, double); +extern int __aeabi_fcmpeq(float, float); +extern int __aeabi_dcmpeq(double, double); +extern int __aeabi_fcmpge(float, float); +extern int __aeabi_dcmpge(double, double); +extern int __aeabi_fcmpgt(float, float); +extern int __aeabi_dcmpgt(double, double); +extern int __aeabi_fcmpun(float, float); +extern int __aeabi_dcmpun(double, double); +# define swf_ff(i0,r0,r1) _swf_ff(_jit,i0,r0,r1) +static void +_swf_ff(jit_state_t*,float(*)(float),jit_int32_t,jit_int32_t) maybe_unused; +# define swf_dd(i0,r0,r1) _swf_dd(_jit,i0,r0,r1) +static void +_swf_dd(jit_state_t*,double(*)(double),jit_int32_t,jit_int32_t) maybe_unused; +# define swf_fff(i0,r0,r1,r2) _swf_fff(_jit,i0,r0,r1,r2) +static void _swf_fff(jit_state_t*,float(*)(float,float), + jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_ddd(i0,r0,r1,r2) _swf_ddd(_jit,i0,r0,r1,r2) +static void _swf_ddd(jit_state_t*,double(*)(double,double), + jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_fff_(i0,r0,r1,i1) _swf_fff_(_jit,i0,r0,r1,i1) +static void _swf_fff_(jit_state_t*,float(*)(float,float), + jit_int32_t,jit_int32_t,jit_float32_t); +# define swf_ddd_(i0,r0,r1,i1) _swf_ddd_(_jit,i0,r0,r1,i1) +static void _swf_ddd_(jit_state_t*,double(*)(double,double), + jit_int32_t,jit_int32_t,jit_float64_t); +# define swf_iff(i0,r0,r1,r2) _swf_iff(_jit,i0,r0,r1,r2) +static void _swf_iff(jit_state_t*,int(*)(float,float), + jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_idd(i0,r0,r1,r2) _swf_idd(_jit,i0,r0,r1,r2) +static void _swf_idd(jit_state_t*,int(*)(double,double), + jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_iff_(i0,r0,r1,r2) _swf_iff_(_jit,i0,r0,r1,r2) +static void _swf_iff_(jit_state_t*,int(*)(float,float), + jit_int32_t,jit_int32_t,jit_float32_t); +# define swf_idd_(i0,r0,r1,r2) _swf_idd_(_jit,i0,r0,r1,r2) +static void _swf_idd_(jit_state_t*,int(*)(double,double), + jit_int32_t,jit_int32_t,jit_float64_t); +# define swf_iunff(i0,r0,r1,r2) _swf_iunff(_jit,i0,r0,r1,r2) +static void _swf_iunff(jit_state_t*,int(*)(float,float), + jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_iundd(i0,r0,r1,r2) _swf_iundd(_jit,i0,r0,r1,r2) +static void _swf_iundd(jit_state_t*,int(*)(double,double), + jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_iunff_(i0,r0,r1,i1) _swf_iunff_(_jit,i0,r0,r1,i1) +static void _swf_iunff_(jit_state_t*,int(*)(float,float), + jit_int32_t,jit_int32_t,jit_float32_t); +# define swf_iundd_(i0,r0,r1,i1) _swf_iundd_(_jit,i0,r0,r1,i1) +static void _swf_iundd_(jit_state_t*,int(*)(double,double), + jit_int32_t,jit_int32_t,jit_float64_t); +# define swf_bff(i0,cc,i1,r0,r1) _swf_bff(_jit,i0,cc,i1,r0,r1) +static jit_word_t _swf_bff(jit_state_t*,int(*)(float,float),int, + jit_word_t,jit_int32_t,jit_int32_t); +# define swf_bdd(i0,cc,i1,r0,r1) _swf_bdd(_jit,i0,cc,i1,r0,r1) +static jit_word_t _swf_bdd(jit_state_t*,int(*)(double,double),int, + jit_word_t,jit_int32_t,jit_int32_t); +# define swf_bff_(i0,cc,i1,r0,i2) _swf_bff_(_jit,i0,cc,i1,r0,i2) +static jit_word_t _swf_bff_(jit_state_t*,int(*)(float,float),int, + jit_word_t,jit_int32_t,jit_float32_t); +# define swf_bdd_(i0,cc,i1,r0,i2) _swf_bdd_(_jit,i0,cc,i1,r0,i2) +static jit_word_t _swf_bdd_(jit_state_t*,int(*)(double,double),int, + jit_word_t,jit_int32_t,jit_float64_t); +# define swf_bunff(eq,i0,r0,r1) _swf_bunff(_jit,eq,i0,r0,r1) +static jit_word_t _swf_bunff(jit_state_t*,int, + jit_word_t,jit_int32_t,jit_int32_t); +# define swf_bundd(eq,i0,r0,r1) _swf_bundd(_jit,eq,i0,r0,r1) +static jit_word_t _swf_bundd(jit_state_t*,int, + jit_word_t,jit_int32_t,jit_int32_t); +# define swf_bunff_(eq,i0,r0,i1) _swf_bunff_(_jit,eq,i0,r0,i1) +static jit_word_t _swf_bunff_(jit_state_t*,int, + jit_word_t,jit_int32_t,jit_float32_t); +# define swf_bundd_(eq,i0,r0,i1) _swf_bundd_(_jit,eq,i0,r0,i1) +static jit_word_t _swf_bundd_(jit_state_t*,int, + jit_word_t,jit_int32_t,jit_float64_t); +# define swf_extr_f(r0,r1) _swf_extr_f(_jit,r0,r1) +static void _swf_extr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_extr_d(r0,r1) _swf_extr_d(_jit,r0,r1) +static void _swf_extr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_extr_d_f(r0,r1) _swf_extr_d_f(_jit,r0,r1) +static void _swf_extr_d_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_extr_f_d(r0,r1) _swf_extr_f_d(_jit,r0,r1) +static void _swf_extr_f_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_truncr_f_i(r0,r1) _swf_truncr_f_i(_jit,r0,r1) +static void _swf_truncr_f_i(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_truncr_d_i(r0,r1) _swf_truncr_d_i(_jit,r0,r1) +static void _swf_truncr_d_i(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_movr_f(r0,r1) _swf_movr_f(_jit,r0,r1) +static void _swf_movr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_movr_d(r0,r1) _swf_movr_d(_jit,r0,r1) +static void _swf_movr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_movi_f(r0,i0) _swf_movi_f(_jit,r0,i0) +static void _swf_movi_f(jit_state_t*,jit_int32_t,jit_float32_t); +# define swf_movi_d(r0,i0) _swf_movi_d(_jit,r0,i0) +static void _swf_movi_d(jit_state_t*,jit_int32_t,jit_float64_t); +# define swf_absr_f(r0,r1) _swf_absr_f(_jit,r0,r1) +static void _swf_absr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_absr_d(r0,r1) _swf_absr_d(_jit,r0,r1) +static void _swf_absr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_negr_f(r0,r1) _swf_negr_f(_jit,r0,r1) +static void _swf_negr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_negr_d(r0,r1) _swf_negr_d(_jit,r0,r1) +static void _swf_negr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_sqrtr_f(r0,r1) swf_ff(sqrtf,r0,r1) +# define swf_sqrtr_d(r0,r1) swf_dd(sqrt,r0,r1) +# define swf_addr_f(r0,r1,r2) swf_fff(__addsf3,r0,r1,r2) +# define swf_addi_f(r0,r1,i0) swf_fff_(__addsf3,r0,r1,i0) +# define swf_addr_d(r0,r1,r2) swf_ddd(__adddf3,r0,r1,r2) +# define swf_addi_d(r0,r1,i0) swf_ddd_(__adddf3,r0,r1,i0) +# define swf_subr_f(r0,r1,r2) swf_fff(__aeabi_fsub,r0,r1,r2) +# define swf_subi_f(r0,r1,i0) swf_fff_(__aeabi_fsub,r0,r1,i0) +# define swf_subr_d(r0,r1,r2) swf_ddd(__aeabi_dsub,r0,r1,r2) +# define swf_subi_d(r0,r1,i0) swf_ddd_(__aeabi_dsub,r0,r1,i0) +# define swf_rsbr_f(r0, r1, r2) swf_subr_f(r0, r2, r1) +# define swf_rsbi_f(r0, r1, i0) _swf_rsbi_f(_jit, r0, r1, i0) +static void _swf_rsbi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define swf_rsbr_d(r0, r1, r2) swf_subr_d(r0, r2, r1) +# define swf_rsbi_d(r0, r1, i0) _swf_rsbi_d(_jit, r0, r1, i0) +static void _swf_rsbi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define swf_mulr_f(r0,r1,r2) swf_fff(__aeabi_fmul,r0,r1,r2) +# define swf_muli_f(r0,r1,i0) swf_fff_(__aeabi_fmul,r0,r1,i0) +# define swf_mulr_d(r0,r1,r2) swf_ddd(__aeabi_dmul,r0,r1,r2) +# define swf_muli_d(r0,r1,i0) swf_ddd_(__aeabi_dmul,r0,r1,i0) +# define swf_divr_f(r0,r1,r2) swf_fff(__aeabi_fdiv,r0,r1,r2) +# define swf_divi_f(r0,r1,i0) swf_fff_(__aeabi_fdiv,r0,r1,i0) +# define swf_divr_d(r0,r1,r2) swf_ddd(__aeabi_ddiv,r0,r1,r2) +# define swf_divi_d(r0,r1,i0) swf_ddd_(__aeabi_ddiv,r0,r1,i0) +# define swf_ltr_f(r0,r1,r2) swf_iff(__aeabi_fcmplt,r0,r1,r2) +# define swf_lti_f(r0,r1,i0) swf_iff_(__aeabi_fcmplt,r0,r1,i0) +# define swf_ltr_d(r0,r1,r2) swf_idd(__aeabi_dcmplt,r0,r1,r2) +# define swf_lti_d(r0,r1,i0) swf_idd_(__aeabi_dcmplt,r0,r1,i0) +# define swf_ler_f(r0,r1,r2) swf_iff(__aeabi_fcmple,r0,r1,r2) +# define swf_lei_f(r0,r1,i0) swf_iff_(__aeabi_fcmple,r0,r1,i0) +# define swf_ler_d(r0,r1,r2) swf_idd(__aeabi_dcmple,r0,r1,r2) +# define swf_lei_d(r0,r1,i0) swf_idd_(__aeabi_dcmple,r0,r1,i0) +# define swf_eqr_f(r0,r1,r2) swf_iff(__aeabi_fcmpeq,r0,r1,r2) +# define swf_eqi_f(r0,r1,i0) swf_iff_(__aeabi_fcmpeq,r0,r1,i0) +# define swf_eqr_d(r0,r1,r2) swf_idd(__aeabi_dcmpeq,r0,r1,r2) +# define swf_eqi_d(r0,r1,i0) swf_idd_(__aeabi_dcmpeq,r0,r1,i0) +# define swf_ger_f(r0,r1,r2) swf_iff(__aeabi_fcmpge,r0,r1,r2) +# define swf_gei_f(r0,r1,i0) swf_iff_(__aeabi_fcmpge,r0,r1,i0) +# define swf_ger_d(r0,r1,r2) swf_idd(__aeabi_dcmpge,r0,r1,r2) +# define swf_gei_d(r0,r1,i0) swf_idd_(__aeabi_dcmpge,r0,r1,i0) +# define swf_gtr_f(r0,r1,r2) swf_iff(__aeabi_fcmpgt,r0,r1,r2) +# define swf_gti_f(r0,r1,i0) swf_iff_(__aeabi_fcmpgt,r0,r1,i0) +# define swf_gtr_d(r0,r1,r2) swf_idd(__aeabi_dcmpgt,r0,r1,r2) +# define swf_gti_d(r0,r1,i0) swf_idd_(__aeabi_dcmpgt,r0,r1,i0) +# define swf_ner_f(r0,r1,r2) _swf_ner_f(_jit,r0,r1,r2) +static void _swf_ner_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_nei_f(r0,r1,i0) _swf_nei_f(_jit,r0,r1,i0) +static void _swf_nei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define swf_ner_d(r0,r1,r2) _swf_ner_d(_jit,r0,r1,r2) +static void _swf_ner_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_nei_d(r0,r1,i0) _swf_nei_d(_jit,r0,r1,i0) +static void _swf_nei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define swf_unltr_f(r0,r1,r2) swf_iunff(__aeabi_fcmplt,r0,r1,r2) +# define swf_unlti_f(r0,r1,i0) swf_iunff_(__aeabi_fcmplt,r0,r1,i0) +# define swf_unltr_d(r0,r1,r2) swf_iundd(__aeabi_dcmplt,r0,r1,r2) +# define swf_unlti_d(r0,r1,i0) swf_iundd_(__aeabi_dcmplt,r0,r1,i0) +# define swf_unler_f(r0,r1,r2) swf_iunff(__aeabi_fcmple,r0,r1,r2) +# define swf_unlei_f(r0,r1,i0) swf_iunff_(__aeabi_fcmple,r0,r1,i0) +# define swf_unler_d(r0,r1,r2) swf_iundd(__aeabi_dcmple,r0,r1,r2) +# define swf_unlei_d(r0,r1,i0) swf_iundd_(__aeabi_dcmple,r0,r1,i0) +# define swf_uneqr_f(r0,r1,r2) swf_iunff(__aeabi_fcmpeq,r0,r1,r2) +# define swf_uneqi_f(r0,r1,i0) swf_iunff_(__aeabi_fcmpeq,r0,r1,i0) +# define swf_uneqr_d(r0,r1,r2) swf_iundd(__aeabi_dcmpeq,r0,r1,r2) +# define swf_uneqi_d(r0,r1,i0) swf_iundd_(__aeabi_dcmpeq,r0,r1,i0) +# define swf_unger_f(r0,r1,r2) swf_iunff(__aeabi_fcmpge,r0,r1,r2) +# define swf_ungei_f(r0,r1,i0) swf_iunff_(__aeabi_fcmpge,r0,r1,i0) +# define swf_unger_d(r0,r1,r2) swf_iundd(__aeabi_dcmpge,r0,r1,r2) +# define swf_ungei_d(r0,r1,i0) swf_iundd_(__aeabi_dcmpge,r0,r1,i0) +# define swf_ungtr_f(r0,r1,r2) swf_iunff(__aeabi_fcmpgt,r0,r1,r2) +# define swf_ungti_f(r0,r1,i0) swf_iunff_(__aeabi_fcmpgt,r0,r1,i0) +# define swf_ungtr_d(r0,r1,r2) swf_iundd(__aeabi_dcmpgt,r0,r1,r2) +# define swf_ungti_d(r0,r1,i0) swf_iundd_(__aeabi_dcmpgt,r0,r1,i0) +# define swf_ltgtr_f(r0,r1,r2) _swf_ltgtr_f(_jit,r0,r1,r2) +static void _swf_ltgtr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_ltgti_f(r0,r1,i0) _swf_ltgti_f(_jit,r0,r1,i0) +static void _swf_ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define swf_ltgtr_d(r0,r1,r2) _swf_ltgtr_d(_jit,r0,r1,r2) +static void _swf_ltgtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_ltgti_d(r0,r1,i0) _swf_ltgti_d(_jit,r0,r1,i0) +static void _swf_ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define swf_ordr_f(r0,r1,r2) _swf_ordr_f(_jit,r0,r1,r2) +static void _swf_ordr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_ordi_f(r0,r1,i0) _swf_ordi_f(_jit,r0,r1,i0) +static void _swf_ordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define swf_ordr_d(r0,r1,r2) _swf_ordr_d(_jit,r0,r1,r2) +static void _swf_ordr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_ordi_d(r0,r1,i0) _swf_ordi_d(_jit,r0,r1,i0) +static void _swf_ordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define swf_unordr_f(r0,r1,r2) swf_iunff(__aeabi_fcmpun,r0,r1,r2) +# define swf_unordi_f(r0,r1,i0) swf_iunff_(__aeabi_fcmpun,r0,r1,i0) +# define swf_unordr_d(r0,r1,r2) swf_iundd(__aeabi_dcmpun,r0,r1,r2) +# define swf_unordi_d(r0,r1,i0) swf_iundd_(__aeabi_dcmpun,r0,r1,i0) +# define swf_bltr_f(i0,r0,r1) swf_bff(__aeabi_fcmplt,ARM_CC_NE,i0,r0,r1) +# define swf_blti_f(i0,r0,i1) swf_bff_(__aeabi_fcmplt,ARM_CC_NE,i0,r0,i1) +# define swf_bltr_d(i0,r0,r1) swf_bdd(__aeabi_dcmplt,ARM_CC_NE,i0,r0,r1) +# define swf_blti_d(i0,r0,i1) swf_bdd_(__aeabi_dcmplt,ARM_CC_NE,i0,r0,i1) +# define swf_bler_f(i0,r0,r1) swf_bff(__aeabi_fcmple,ARM_CC_NE,i0,r0,r1) +# define swf_blei_f(i0,r0,i1) swf_bff_(__aeabi_fcmple,ARM_CC_NE,i0,r0,i1) +# define swf_bler_d(i0,r0,r1) swf_bdd(__aeabi_dcmple,ARM_CC_NE,i0,r0,r1) +# define swf_blei_d(i0,r0,i1) swf_bdd_(__aeabi_dcmple,ARM_CC_NE,i0,r0,i1) +# define swf_beqr_f(i0,r0,r1) swf_bff(__aeabi_fcmpeq,ARM_CC_NE,i0,r0,r1) +# define swf_beqi_f(i0,r0,i1) swf_bff_(__aeabi_fcmpeq,ARM_CC_NE,i0,r0,i1) +# define swf_beqr_d(i0,r0,r1) swf_bdd(__aeabi_dcmpeq,ARM_CC_NE,i0,r0,r1) +# define swf_beqi_d(i0,r0,i1) swf_bdd_(__aeabi_dcmpeq,ARM_CC_NE,i0,r0,i1) +# define swf_bger_f(i0,r0,r1) swf_bff(__aeabi_fcmpge,ARM_CC_NE,i0,r0,r1) +# define swf_bgei_f(i0,r0,i1) swf_bff_(__aeabi_fcmpge,ARM_CC_NE,i0,r0,i1) +# define swf_bger_d(i0,r0,r1) swf_bdd(__aeabi_dcmpge,ARM_CC_NE,i0,r0,r1) +# define swf_bgei_d(i0,r0,i1) swf_bdd_(__aeabi_dcmpge,ARM_CC_NE,i0,r0,i1) +# define swf_bgtr_f(i0,r0,r1) swf_bff(__aeabi_fcmpgt,ARM_CC_NE,i0,r0,r1) +# define swf_bgti_f(i0,r0,i1) swf_bff_(__aeabi_fcmpgt,ARM_CC_NE,i0,r0,i1) +# define swf_bgtr_d(i0,r0,r1) swf_bdd(__aeabi_dcmpgt,ARM_CC_NE,i0,r0,r1) +# define swf_bgti_d(i0,r0,i1) swf_bdd_(__aeabi_dcmpgt,ARM_CC_NE,i0,r0,i1) +# define swf_bner_f(i0,r0,r1) swf_bff(__aeabi_fcmpeq,ARM_CC_EQ,i0,r0,r1) +# define swf_bnei_f(i0,r0,i1) swf_bff_(__aeabi_fcmpeq,ARM_CC_EQ,i0,r0,i1) +# define swf_bner_d(i0,r0,r1) swf_bdd(__aeabi_dcmpeq,ARM_CC_EQ,i0,r0,r1) +# define swf_bnei_d(i0,r0,i1) swf_bdd_(__aeabi_dcmpeq,ARM_CC_EQ,i0,r0,i1) +# define swf_bunltr_f(i0,r0,r1) swf_bff(__aeabi_fcmpge,ARM_CC_EQ,i0,r0,r1) +# define swf_bunlti_f(i0,r0,i1) swf_bff_(__aeabi_fcmpge,ARM_CC_EQ,i0,r0,i1) +# define swf_bunltr_d(i0,r0,r1) swf_bdd(__aeabi_dcmpge,ARM_CC_EQ,i0,r0,r1) +# define swf_bunlti_d(i0,r0,i1) swf_bdd_(__aeabi_dcmpge,ARM_CC_EQ,i0,r0,i1) +# define swf_bunler_f(i0,r0,r1) swf_bff(__aeabi_fcmpgt,ARM_CC_EQ,i0,r0,r1) +# define swf_bunlei_f(i0,r0,i1) swf_bff_(__aeabi_fcmpgt,ARM_CC_EQ,i0,r0,i1) +# define swf_bunler_d(i0,r0,r1) swf_bdd(__aeabi_dcmpgt,ARM_CC_EQ,i0,r0,r1) +# define swf_bunlei_d(i0,r0,i1) swf_bdd_(__aeabi_dcmpgt,ARM_CC_EQ,i0,r0,i1) +# define swf_buneqr_f(i0,r0,r1) swf_bunff(1,i0,r0,r1) +# define swf_buneqi_f(i0,r0,i1) swf_bunff_(1,i0,r0,i1) +# define swf_buneqr_d(i0,r0,r1) swf_bundd(1,i0,r0,r1) +# define swf_buneqi_d(i0,r0,i1) swf_bundd_(1,i0,r0,i1) +# define swf_bunger_f(i0,r0,r1) swf_bff(__aeabi_fcmplt,ARM_CC_EQ,i0,r0,r1) +# define swf_bungei_f(i0,r0,i1) swf_bff_(__aeabi_fcmplt,ARM_CC_EQ,i0,r0,i1) +# define swf_bunger_d(i0,r0,r1) swf_bdd(__aeabi_dcmplt,ARM_CC_EQ,i0,r0,r1) +# define swf_bungei_d(i0,r0,i1) swf_bdd_(__aeabi_dcmplt,ARM_CC_EQ,i0,r0,i1) +# define swf_bungtr_f(i0,r0,r1) swf_bff(__aeabi_fcmple,ARM_CC_EQ,i0,r0,r1) +# define swf_bungti_f(i0,r0,i1) swf_bff_(__aeabi_fcmple,ARM_CC_EQ,i0,r0,i1) +# define swf_bungtr_d(i0,r0,r1) swf_bdd(__aeabi_dcmple,ARM_CC_EQ,i0,r0,r1) +# define swf_bungti_d(i0,r0,i1) swf_bdd_(__aeabi_dcmple,ARM_CC_EQ,i0,r0,i1) +# define swf_bltgtr_f(i0,r0,r1) swf_bunff(0,i0,r0,r1) +# define swf_bltgti_f(i0,r0,i1) swf_bunff_(0,i0,r0,i1) +# define swf_bltgtr_d(i0,r0,r1) swf_bundd(0,i0,r0,r1) +# define swf_bltgti_d(i0,r0,i1) swf_bundd_(0,i0,r0,i1) +# define swf_bordr_f(i0,r0,r1) swf_bff(__aeabi_fcmpun,ARM_CC_EQ,i0,r0,r1) +# define swf_bordi_f(i0,r0,i1) swf_bff_(__aeabi_fcmpun,ARM_CC_EQ,i0,r0,i1) +# define swf_bordr_d(i0,r0,r1) swf_bdd(__aeabi_dcmpun,ARM_CC_EQ,i0,r0,r1) +# define swf_bordi_d(i0,r0,i1) swf_bdd_(__aeabi_dcmpun,ARM_CC_EQ,i0,r0,i1) +# define swf_bunordr_f(i0,r0,r1) swf_bff(__aeabi_fcmpun,ARM_CC_NE,i0,r0,r1) +# define swf_bunordi_f(i0,r0,i1) swf_bff_(__aeabi_fcmpun,ARM_CC_NE,i0,r0,i1) +# define swf_bunordr_d(i0,r0,r1) swf_bdd(__aeabi_dcmpun,ARM_CC_NE,i0,r0,r1) +# define swf_bunordi_d(i0,r0,i1) swf_bdd_(__aeabi_dcmpun,ARM_CC_NE,i0,r0,i1) +# define swf_ldr_f(r0,r1) _swf_ldr_f(_jit,r0,r1) +static void _swf_ldr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_ldr_d(r0,r1) _swf_ldr_d(_jit,r0,r1) +static void _swf_ldr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_ldi_f(r0,i0) _swf_ldi_f(_jit,r0,i0) +static void _swf_ldi_f(jit_state_t*,jit_int32_t,jit_word_t); +# define swf_ldi_d(r0,i0) _swf_ldi_d(_jit,r0,i0) +static void _swf_ldi_d(jit_state_t*,jit_int32_t,jit_word_t); +# define swf_ldxr_f(r0,r1,r2) _swf_ldxr_f(_jit,r0,r1,r2) +static void _swf_ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_ldxr_d(r0,r1,r2) _swf_ldxr_d(_jit,r0,r1,r2) +static void _swf_ldxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_ldxi_f(r0,r1,i0) _swf_ldxi_f(_jit,r0,r1,i0) +static void _swf_ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define swf_ldxi_d(r0,r1,i0) _swf_ldxi_d(_jit,r0,r1,i0) +static void _swf_ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define swf_str_f(r0,r1) _swf_str_f(_jit,r0,r1) +static void _swf_str_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_str_d(r0,r1) _swf_str_d(_jit,r0,r1) +static void _swf_str_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define swf_sti_f(r0,i0) _swf_sti_f(_jit,r0,i0) +static void _swf_sti_f(jit_state_t*,jit_word_t,jit_int32_t); +# define swf_sti_d(r0,i0) _swf_sti_d(_jit,r0,i0) +static void _swf_sti_d(jit_state_t*,jit_word_t,jit_int32_t); +# define swf_stxr_f(r0,r1,r2) _swf_stxr_f(_jit,r0,r1,r2) +static void _swf_stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_stxr_d(r0,r1,r2) _swf_stxr_d(_jit,r0,r1,r2) +static void _swf_stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define swf_stxi_f(r0,r1,i0) _swf_stxi_f(_jit,r0,r1,i0) +static void _swf_stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define swf_stxi_d(r0,r1,i0) _swf_stxi_d(_jit,r0,r1,i0) +static void _swf_stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define swf_vaarg_d(r0, r1) _swf_vaarg_d(_jit, r0, r1) +static void _swf_vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t); +#endif + +#if CODE +#define swf_off(rn) ((rn - 16) << 2) + +#define swf_call(function, label, regno) \ + do { \ + jit_word_t d; \ + if (!jit_exchange_p()) { \ + if (jit_thumb_p()) \ + d = (((jit_word_t)function - _jit->pc.w) >> 1) - 2; \ + else \ + d = (((jit_word_t)function - _jit->pc.w) >> 2) - 2; \ + if (_s24P(d)) { \ + if (jit_thumb_p()) \ + T2_BLI(encode_thumb_jump(d)); \ + else \ + BLI(d & 0x00ffffff); \ + } \ + else \ + goto label; \ + } \ + else { \ + label: \ + movi(regno, (jit_word_t)function); \ + if (jit_thumb_p()) \ + T1_BLX(regno); \ + else \ + BLX(regno); \ + } \ + } while (0) +#define swf_call_with_get_reg(function, label) \ + do { \ + jit_word_t d; \ + jit_int32_t reg; \ + if (!jit_exchange_p()) { \ + if (jit_thumb_p()) \ + d = (((jit_word_t)function - _jit->pc.w) >> 1) - 2; \ + else \ + d = (((jit_word_t)function - _jit->pc.w) >> 2) - 2; \ + if (_s24P(d)) { \ + if (jit_thumb_p()) \ + T2_BLI(encode_thumb_jump(d)); \ + else \ + BLI(d & 0x00ffffff); \ + } \ + else \ + goto label; \ + } \ + else { \ + label: \ + reg = jit_get_reg(jit_class_gpr); \ + movi(rn(reg), (jit_word_t)function); \ + if (jit_thumb_p()) \ + T1_BLX(rn(reg)); \ + else \ + BLX(rn(reg)); \ + jit_unget_reg(reg); \ + } \ + } while (0) +#define swf_ldrin(rt, rn, im) \ + do { \ + if (jit_thumb_p()) T2_LDRIN(rt, rn, im); \ + else LDRIN(rt, rn, im); \ + } while (0) +#define swf_strin(rt, rn, im) \ + do { \ + if (jit_thumb_p()) T2_STRIN(rt, rn, im); \ + else STRIN(rt, rn, im); \ + } while (0) +#define swf_bici(rt, rn, im) \ + do { \ + if (jit_thumb_p()) \ + T2_BICI(rt, rn, encode_thumb_immediate(im)); \ + else \ + BICI(rt, rn, encode_arm_immediate(im)); \ + } while (0) + +#if !defined(__GNUC__) +float __addsf3(float u, float v) +{ + return (u + v); +} + +double +__adddf3(double u, double v) +{ + return (u + v); +} + +float +__aeabi_fsub(float u, float v) +{ + return (u - v); +} + +double +__aeabi_dsub(double u, double v) +{ + return (u - v); +} + +float +__aeabi_fmul(float u, float v) +{ + return (u * v); +} + +double +__aeabi_dmul(double u, double v) +{ + return (u * v); +} + +float +__aeabi_fdiv(float u, float v) +{ + return (u / v); +} + +double +__aeabi_ddiv(double u, double v) +{ + return (u / v); +} + +float +__aeabi_i2f(int u) +{ + return (u); +} + +double +__aeabi_i2d(int u) +{ + return (u); +} + +float +__aeabi_d2f(double u) +{ + return (u); +} + +double +__aeabi_f2d(float u) +{ + return (u); +} + +extern int +__aeabi_f2iz(float u) +{ + return (u); +} + +int +__aeabi_d2iz(double u) +{ + return (u); +} + +int +__aeabi_fcmplt(float u, float v) +{ + return (u < v); +} + +int +__aeabi_dcmplt(double u, double v) +{ + return (u < v); +} + +int +__aeabi_fcmple(float u, float v) +{ + return (u <= v); +} + +int +__aeabi_dcmple(double u, double v) +{ + return (u <= v); +} + +int +__aeabi_fcmpeq(float u, float v) +{ + return (u == v); +} + +int +__aeabi_dcmpeq(double u, double v) +{ + return (u == v); +} + +int +__aeabi_fcmpge(float u, float v) +{ + return (u >= v); +} + +int +__aeabi_dcmpge(double u, double v) +{ + return (u >= v); +} + +int +__aeabi_fcmpgt(float u, float v) +{ + return (u > v); +} + +int +__aeabi_dcmpgt(double u, double v) +{ + return (u > v); +} + +int +__aeabi_fcmpun(float u, float v) +{ + return ((u != u) || (v != v)); +} + +int +__aeabi_dcmpun(double u, double v) +{ + return ((u != u) || (v != v)); +} +#endif + +static void +_swf_ff(jit_state_t *_jit, float(*i0)(float), + jit_int32_t r0, jit_int32_t r1) +{ + jit_get_reg_args(); + if (jit_fpr_p(r1)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R0_REGNO, r1); + swf_call(i0, fallback, _R1_REGNO); + if (jit_fpr_p(r0)) + swf_strin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else + movr(r0, _R0_REGNO); + jit_unget_reg_args(); +} + +static void +_swf_dd(jit_state_t *_jit, double (*i0)(double), + jit_int32_t r0, jit_int32_t r1) +{ + jit_get_reg_args(); + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R0_REGNO, r1); + movr(_R1_REGNO, r1 + 1); + } + swf_call(i0, fallback, _R2_REGNO); + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p()) + STRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else { + swf_strin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + swf_strin(_R1_REGNO, _FP_REGNO, swf_off(r0) + 4); + } + } + else { + movr(r0, _R0_REGNO); + movr(r0 + 1, _R1_REGNO); + } + jit_unget_reg_args(); +} + +static void +_swf_fff(jit_state_t *_jit, float (*i0)(float, float), + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_get_reg_args(); + if (jit_fpr_p(r1)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R0_REGNO, r1); + if (jit_fpr_p(r2)) + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r2) + 8); + else + movr(_R1_REGNO, r1); + swf_call(i0, fallback, _R3_REGNO); + if (jit_fpr_p(r0)) + swf_strin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else + movr(r0, _R0_REGNO); + jit_unget_reg_args(); +} + +static void +_swf_ddd(jit_state_t *_jit, double (*i0)(double, double), + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_get_reg_args(); + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R0_REGNO, r1); + movr(_R1_REGNO, r1 + 1); + } + if (jit_fpr_p(r2)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R2_REGNO, _FP_REGNO, swf_off(r2) + 8); + else { + swf_ldrin(_R2_REGNO, _FP_REGNO, swf_off(r2) + 8); + swf_ldrin(_R3_REGNO, _FP_REGNO, swf_off(r2) + 4); + } + } + else { + movr(_R2_REGNO, r2); + movr(_R3_REGNO, r2 + 1); + } + swf_call_with_get_reg(i0, fallback); + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p()) + STRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else { + swf_strin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + swf_strin(_R1_REGNO, _FP_REGNO, swf_off(r0) + 4); + } + } + else { + movr(r0, _R0_REGNO); + movr(r0 + 1, _R1_REGNO); + } + jit_unget_reg_args(); +} + +static void +_swf_fff_(jit_state_t *_jit, float (*i0)(float, float), + jit_int32_t r0, jit_int32_t r1, jit_float32_t i1) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_get_reg_args(); + data.f = i1; + if (jit_fpr_p(r1)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R0_REGNO, r1); + movi(_R1_REGNO, data.i); + swf_call(i0, fallback, _R3_REGNO); + if (jit_fpr_p(r0)) + swf_strin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else + movr(r0, _R0_REGNO); + jit_unget_reg_args(); +} + +static void +_swf_rsbi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_float32_t i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_get_reg_args(); + data.f = i0; + movi(_R0_REGNO, data.i); + if (jit_fpr_p(r1)) + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R1_REGNO, r1); + swf_call(__aeabi_fsub, fallback, _R3_REGNO); + if (jit_fpr_p(r0)) + swf_strin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else + movr(r0, _R0_REGNO); + jit_unget_reg_args(); +} + +static void +_swf_ddd_(jit_state_t *_jit, double (*i0)(double, double), + jit_int32_t r0, jit_int32_t r1, jit_float64_t i1) +{ + union { + jit_int32_t i[2]; + jit_float64_t d; + } data; + jit_get_reg_args(); + + data.d = i1; + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R0_REGNO, r1); + movr(_R1_REGNO, r1 + 1); + } + movi(_R2_REGNO, data.i[0]); + movi(_R3_REGNO, data.i[1]); + swf_call_with_get_reg(i0, fallback); + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p()) + STRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else { + swf_strin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + swf_strin(_R1_REGNO, _FP_REGNO, swf_off(r0) + 4); + } + } + else { + movr(r0, _R0_REGNO); + movr(r0 + 1, _R1_REGNO); + } + jit_unget_reg_args(); +} + +static void +_swf_rsbi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_float64_t i0) +{ + union { + jit_int32_t i[2]; + jit_float64_t d; + } data; + jit_get_reg_args(); + data.d = i0; + movi(_R0_REGNO, data.i[0]); + movi(_R1_REGNO, data.i[1]); + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R2_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R2_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R3_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R2_REGNO, r1); + movr(_R3_REGNO, r1 + 1); + } + swf_call_with_get_reg(__aeabi_dsub, fallback); + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p()) + STRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else { + swf_strin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + swf_strin(_R1_REGNO, _FP_REGNO, swf_off(r0) + 4); + } + } + else { + movr(r0, _R0_REGNO); + movr(r0 + 1, _R1_REGNO); + } + jit_unget_reg_args(); +} + +static void +_swf_iff(jit_state_t *_jit, int (*i0)(float, float), + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_get_reg_args(); + if (jit_fpr_p(r1)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R0_REGNO, r1); + if (jit_fpr_p(r2)) + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r2) + 8); + else + movr(_R1_REGNO, r2); + swf_call(i0, fallback, _R2_REGNO); + movr(r0, _R0_REGNO); + jit_unget_reg_args(); +} + +static void +_swf_idd(jit_state_t *_jit, int (*i0)(double, double), + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_get_reg_args(); + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R0_REGNO, r1); + movr(_R1_REGNO, r1 + 1); + } + if (jit_fpr_p(r2)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R2_REGNO, _FP_REGNO, swf_off(r2) + 8); + else { + swf_ldrin(_R2_REGNO, _FP_REGNO, swf_off(r2) + 8); + swf_ldrin(_R3_REGNO, _FP_REGNO, swf_off(r2) + 4); + } + } + else { + movr(_R2_REGNO, r2); + movr(_R3_REGNO, r2 + 1); + } + swf_call_with_get_reg(i0, fallback); + movr(r0, _R0_REGNO); + jit_unget_reg_args(); +} + +static void +_swf_iff_(jit_state_t *_jit, int (*i0)(float, float), + jit_int32_t r0, jit_int32_t r1, jit_float32_t i1) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_get_reg_args(); + data.f = i1; + if (jit_fpr_p(r1)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R0_REGNO, r1); + movi(_R1_REGNO, data.i); + swf_call(i0, fallback, _R2_REGNO); + movr(r0, _R0_REGNO); + jit_unget_reg_args(); +} + +static void +_swf_idd_(jit_state_t *_jit, int (*i0)(double, double), + jit_int32_t r0, jit_int32_t r1, jit_float64_t i1) +{ + union { + jit_int32_t i[2]; + jit_float64_t d; + } data; + jit_get_reg_args(); + data.d = i1; + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R0_REGNO, r1); + movr(_R1_REGNO, r1 + 1); + } + movi(_R2_REGNO, data.i[0]); + movi(_R3_REGNO, data.i[1]); + swf_call_with_get_reg(i0, fallback); + movr(r0, _R0_REGNO); + jit_unget_reg_args(); +} + +static void +_swf_iunff(jit_state_t *_jit, int (*i0)(float, float), + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t instr; + jit_get_reg_args(); + if (jit_fpr_p(r1)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R0_REGNO, r1); + if (jit_fpr_p(r2)) + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r2) + 8); + else + movr(_R1_REGNO, r2); + swf_call(__aeabi_fcmpun, fcmpun, _R2_REGNO); + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + IT(ARM_CC_NE); + if (r0 < 8) + T1_MOVI(r0, 1); + else + T2_MOVI(r0, 1); + instr = _jit->pc.w; + T2_CC_B(ARM_CC_NE, 0); + } + else { + CMPI(_R0_REGNO, 0); + CC_MOVI(ARM_CC_NE, r0, 1); + instr = _jit->pc.w; + CC_B(ARM_CC_NE, 0); + } + if (jit_fpr_p(r1)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R0_REGNO, r1); + if (jit_fpr_p(r2)) + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r2) + 8); + else + movr(_R1_REGNO, r2); + swf_call(i0, fallback, _R2_REGNO); + movr(r0, _R0_REGNO); + patch_at(arm_patch_jump, instr, _jit->pc.w); + jit_unget_reg_args(); +} + +static void +_swf_iundd(jit_state_t *_jit, int (*i0)(double, double), + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t instr; + jit_get_reg_args(); + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R0_REGNO, r1); + movr(_R1_REGNO, r1 + 1); + } + if (jit_fpr_p(r2)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R2_REGNO, _FP_REGNO, swf_off(r2) + 8); + else { + swf_ldrin(_R2_REGNO, _FP_REGNO, swf_off(r2) + 8); + swf_ldrin(_R3_REGNO, _FP_REGNO, swf_off(r2) + 4); + } + } + else { + movr(_R2_REGNO, r2); + movr(_R3_REGNO, r2 + 1); + } + swf_call_with_get_reg(__aeabi_dcmpun, dcmpun); + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + IT(ARM_CC_NE); + if (r0 < 8) + T1_MOVI(r0, 1); + else + T2_MOVI(r0, 1); + instr = _jit->pc.w; + T2_CC_B(ARM_CC_NE, 0); + } + else { + CMPI(_R0_REGNO, 0); + CC_MOVI(ARM_CC_NE, r0, 1); + instr = _jit->pc.w; + CC_B(ARM_CC_NE, 0); + } + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R0_REGNO, r1); + movr(_R1_REGNO, r1 + 1); + } + if (jit_fpr_p(r2)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R2_REGNO, _FP_REGNO, swf_off(r2) + 8); + else { + swf_ldrin(_R2_REGNO, _FP_REGNO, swf_off(r2) + 8); + swf_ldrin(_R3_REGNO, _FP_REGNO, swf_off(r2) + 4); + } + } + else { + movr(_R2_REGNO, r2); + movr(_R3_REGNO, r2 + 1); + } + swf_call_with_get_reg(i0, fallback); + movr(r0, _R0_REGNO); + patch_at(arm_patch_jump, instr, _jit->pc.w); + jit_unget_reg_args(); +} + +static void +_swf_iunff_(jit_state_t *_jit, int (*i0)(float, float), + jit_int32_t r0, jit_int32_t r1, jit_float32_t i1) +{ + jit_word_t instr; + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_get_reg_args(); + data.f = i1; + if (jit_fpr_p(r1)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R0_REGNO, r1); + movi(_R1_REGNO, data.i); + swf_call(__aeabi_fcmpun, fcmpun, _R2_REGNO); + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + IT(ARM_CC_NE); + if (r0 < 8) + T1_MOVI(r0, 1); + else + T2_MOVI(r0, 1); + instr = _jit->pc.w; + T2_CC_B(ARM_CC_NE, 0); + } + else { + CMPI(_R0_REGNO, 0); + CC_MOVI(ARM_CC_NE, r0, 1); + instr = _jit->pc.w; + CC_B(ARM_CC_NE, 0); + } + if (jit_fpr_p(r1)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R0_REGNO, r1); + movi(_R1_REGNO, data.i); + swf_call(i0, fallback, _R2_REGNO); + movr(r0, _R0_REGNO); + patch_at(arm_patch_jump, instr, _jit->pc.w); + jit_unget_reg_args(); +} + +static void +_swf_iundd_(jit_state_t *_jit, int (*i0)(double, double), + jit_int32_t r0, jit_int32_t r1, jit_float64_t i1) +{ + jit_word_t instr; + union { + jit_int32_t i[2]; + jit_float64_t d; + } data; + jit_get_reg_args(); + data.d = i1; + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R0_REGNO, r1); + movr(_R1_REGNO, r1 + 1); + } + movi(_R2_REGNO, data.i[0]); + movi(_R3_REGNO, data.i[1]); + swf_call_with_get_reg(__aeabi_dcmpun, dcmpun); + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + IT(ARM_CC_NE); + if (r0 < 8) + T1_MOVI(r0, 1); + else + T2_MOVI(r0, 1); + instr = _jit->pc.w; + T2_CC_B(ARM_CC_NE, 0); + } + else { + CMPI(_R0_REGNO, 0); + CC_MOVI(ARM_CC_NE, r0, 1); + instr = _jit->pc.w; + CC_B(ARM_CC_NE, 0); + } + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R0_REGNO, r1); + movr(_R1_REGNO, r1 + 1); + } + movi(_R2_REGNO, data.i[0]); + movi(_R3_REGNO, data.i[1]); + swf_call_with_get_reg(i0, fallback); + movr(r0, _R0_REGNO); + patch_at(arm_patch_jump, instr, _jit->pc.w); + jit_unget_reg_args(); +} + +static jit_word_t +_swf_bff(jit_state_t *_jit, int (*i0)(float, float), int cc, + jit_word_t i1, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, d; + jit_get_reg_args(); + if (jit_fpr_p(r0)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else + movr(_R0_REGNO, r0); + if (jit_fpr_p(r1)) + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R1_REGNO, r1); + swf_call(i0, fallback, _R2_REGNO); + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + w = _jit->pc.w; + d = ((i1 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(cc, encode_thumb_cc_jump(d)); + } + else { + CMPI(_R0_REGNO, 0); + w = _jit->pc.w; + d = ((i1 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(cc, d & 0x00ffffff); + } + jit_unget_reg_args(); + return (w); +} + +static jit_word_t +_swf_bdd(jit_state_t *_jit, int (*i0)(double, double), int cc, + jit_word_t i1, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, d; + jit_get_reg_args(); + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r0) + 4); + } + } + else { + movr(_R0_REGNO, r0); + movr(_R1_REGNO, r0 + 1); + } + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R2_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R2_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R3_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R2_REGNO, r1); + movr(_R3_REGNO, r1 + 1); + } + swf_call_with_get_reg(i0, fallback); + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + w = _jit->pc.w; + d = ((i1 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(cc, encode_thumb_cc_jump(d)); + } + else { + CMPI(_R0_REGNO, 0); + w = _jit->pc.w; + d = ((i1 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(cc, d & 0x00ffffff); + } + jit_unget_reg_args(); + return (w); +} + +static jit_word_t +_swf_bff_(jit_state_t *_jit, int (*i0)(float, float), int cc, + jit_word_t i1, jit_int32_t r0, jit_float32_t i2) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_word_t w, d; + jit_get_reg_args(); + data.f = i2; + if (jit_fpr_p(r0)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else + movr(_R0_REGNO, r0); + movi(_R1_REGNO, data.i); + swf_call(i0, fallback, _R2_REGNO); + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + w = _jit->pc.w; + d = ((i1 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(cc, encode_thumb_cc_jump(d)); + } + else { + CMPI(_R0_REGNO, 0); + w = _jit->pc.w; + d = ((i1 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(cc, d & 0x00ffffff); + } + jit_unget_reg_args(); + return (w); +} + +static jit_word_t +_swf_bdd_(jit_state_t *_jit, int (*i0)(double, double), int cc, + jit_word_t i1, jit_int32_t r0, jit_float64_t i2) +{ + jit_word_t w, d; + union { + jit_int32_t i[2]; + jit_float64_t d; + } data; + jit_get_reg_args(); + data.d = i2; + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r0) + 4); + } + } + else { + movr(_R0_REGNO, r0); + movr(_R1_REGNO, r0 + 1); + } + movi(_R2_REGNO, data.i[0]); + movi(_R3_REGNO, data.i[1]); + swf_call_with_get_reg(i0, fallback); + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + w = _jit->pc.w; + d = ((i1 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(cc, encode_thumb_cc_jump(d)); + } + else { + CMPI(_R0_REGNO, 0); + w = _jit->pc.w; + d = ((i1 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(cc, d & 0x00ffffff); + } + jit_unget_reg_args(); + return (w); +} + +static jit_word_t +_swf_bunff(jit_state_t *_jit, int eq, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, d, j0, j1; + jit_get_reg_args(); + if (jit_fpr_p(r0)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else + movr(_R0_REGNO, r0); + if (jit_fpr_p(r1)) + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R1_REGNO, r1); + swf_call(__aeabi_fcmpun, fcmpun, _R2_REGNO); + /* if unordered */ + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + j0 = _jit->pc.w; + T2_CC_B(ARM_CC_NE, 0); + } + else { + CMPI(_R0_REGNO, 0); + j0 = _jit->pc.w; + CC_B(ARM_CC_NE, 0); + } + if (jit_fpr_p(r0)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else + movr(_R0_REGNO, r0); + if (jit_fpr_p(r1)) + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R1_REGNO, r1); + swf_call(__aeabi_fcmpeq, fcmpeq, _R2_REGNO); + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + j1 = _jit->pc.w; + if (eq) { + T2_CC_B(ARM_CC_EQ, 0); + patch_at(arm_patch_jump, j0, _jit->pc.w); + } + else + T2_CC_B(ARM_CC_NE, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s24P(d)); + T2_B(encode_thumb_jump(d)); + } + else { + CMPI(_R0_REGNO, 0); + j1 = _jit->pc.w; + if (eq) { + CC_B(ARM_CC_EQ, 0); + patch_at(arm_patch_jump, j0, _jit->pc.w); + } + else + CC_B(ARM_CC_NE, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + B(d & 0x00ffffff); + } + if (!eq) + patch_at(arm_patch_jump, j0, _jit->pc.w); + patch_at(arm_patch_jump, j1, _jit->pc.w); + jit_unget_reg_args(); + return (w); +} + +static jit_word_t +_swf_bundd(jit_state_t *_jit, int eq, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, d, j0, j1; + jit_get_reg_args(); + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r0) + 4); + } + } + else { + movr(_R0_REGNO, r0); + movr(_R1_REGNO, r0 + 1); + } + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R2_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R2_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R3_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R2_REGNO, r0); + movr(_R3_REGNO, r0 + 1); + } + swf_call_with_get_reg(__aeabi_dcmpun, dcmpun); + /* if unordered */ + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + j0 = _jit->pc.w; + T2_CC_B(ARM_CC_NE, 0); + } + else { + CMPI(_R0_REGNO, 0); + j0 = _jit->pc.w; + CC_B(ARM_CC_NE, 0); + } + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r0) + 4); + } + } + else { + movr(_R0_REGNO, r0); + movr(_R1_REGNO, r0 + 1); + } + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R2_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R2_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R3_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R2_REGNO, r0); + movr(_R3_REGNO, r0 + 1); + } + swf_call_with_get_reg(__aeabi_dcmpeq, dcmpeq); + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + j1 = _jit->pc.w; + if (eq) { + T2_CC_B(ARM_CC_EQ, 0); + patch_at(arm_patch_jump, j0, _jit->pc.w); + } + else + T2_CC_B(ARM_CC_NE, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s24P(d)); + T2_B(encode_thumb_jump(d)); + } + else { + CMPI(_R0_REGNO, 0); + j1 = _jit->pc.w; + if (eq) { + CC_B(ARM_CC_EQ, 0); + patch_at(arm_patch_jump, j0, _jit->pc.w); + } + else + CC_B(ARM_CC_NE, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + B(d & 0x00ffffff); + } + if (!eq) + patch_at(arm_patch_jump, j0, _jit->pc.w); + patch_at(arm_patch_jump, j1, _jit->pc.w); + jit_unget_reg_args(); + return (w); +} + +static jit_word_t +_swf_bunff_(jit_state_t *_jit, int eq, + jit_word_t i0, jit_int32_t r0, jit_float32_t i1) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_word_t w, d, j0, j1; + data.f = i1; + jit_get_reg_args(); + if (jit_fpr_p(r0)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else + movr(_R0_REGNO, r0); + movi(_R1_REGNO, data.i); + swf_call(__aeabi_fcmpun, fcmpun, _R2_REGNO); + /* if unordered */ + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + j0 = _jit->pc.w; + T2_CC_B(ARM_CC_NE, 0); + } + else { + CMPI(_R0_REGNO, 0); + j0 = _jit->pc.w; + CC_B(ARM_CC_NE, 0); + } + if (jit_fpr_p(r0)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else + movr(_R0_REGNO, r0); + movi(_R1_REGNO, data.i); + swf_call(__aeabi_fcmpeq, fcmpeq, _R2_REGNO); + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + j1 = _jit->pc.w; + if (eq) { + T2_CC_B(ARM_CC_EQ, 0); + patch_at(arm_patch_jump, j0, _jit->pc.w); + } + else + T2_CC_B(ARM_CC_NE, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s24P(d)); + T2_B(encode_thumb_jump(d)); + } + else { + CMPI(_R0_REGNO, 0); + j1 = _jit->pc.w; + if (eq) { + CC_B(ARM_CC_EQ, 0); + patch_at(arm_patch_jump, j0, _jit->pc.w); + } + else + CC_B(ARM_CC_NE, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + B(d & 0x00ffffff); + } + if (!eq) + patch_at(arm_patch_jump, j0, _jit->pc.w); + patch_at(arm_patch_jump, j1, _jit->pc.w); + jit_unget_reg_args(); + return (w); +} + +static jit_word_t +_swf_bundd_(jit_state_t *_jit, int eq, + jit_word_t i0, jit_int32_t r0, jit_float64_t i1) +{ + jit_word_t w, d, j0, j1; + union { + jit_int32_t i[2]; + jit_float64_t d; + } data; + jit_get_reg_args(); + data.d = i1; + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r0) + 4); + } + } + else { + movr(_R0_REGNO, r0); + movr(_R1_REGNO, r0 + 1); + } + movi(_R2_REGNO, data.i[0]); + movi(_R3_REGNO, data.i[1]); + swf_call_with_get_reg(__aeabi_dcmpun, fcmpun); + /* if unordered */ + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + j0 = _jit->pc.w; + T2_CC_B(ARM_CC_NE, 0); + } + else { + CMPI(_R0_REGNO, 0); + j0 = _jit->pc.w; + CC_B(ARM_CC_NE, 0); + } + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r0) + 4); + } + } + else { + movr(_R0_REGNO, r0); + movr(_R1_REGNO, r0 + 1); + } + movi(_R2_REGNO, data.i[0]); + movi(_R3_REGNO, data.i[1]); + swf_call_with_get_reg(__aeabi_dcmpeq, fcmpeq); + if (jit_thumb_p()) { + T1_CMPI(_R0_REGNO, 0); + j1 = _jit->pc.w; + if (eq) { + T2_CC_B(ARM_CC_EQ, 0); + patch_at(arm_patch_jump, j0, _jit->pc.w); + } + else + T2_CC_B(ARM_CC_NE, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s24P(d)); + T2_B(encode_thumb_jump(d)); + } + else { + CMPI(_R0_REGNO, 0); + j1 = _jit->pc.w; + if (eq) { + CC_B(ARM_CC_EQ, 0); + patch_at(arm_patch_jump, j0, _jit->pc.w); + } + else + CC_B(ARM_CC_NE, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + B(d & 0x00ffffff); + } + if (!eq) + patch_at(arm_patch_jump, j0, _jit->pc.w); + patch_at(arm_patch_jump, j1, _jit->pc.w); + jit_unget_reg_args(); + return (w); +} + +static void +_swf_extr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_get_reg_args(); + movr(_R0_REGNO, r1); + swf_call(__aeabi_i2f, i2f, _R1_REGNO); + if (jit_fpr_p(r0)) + swf_strin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else + movr(r0, _R0_REGNO); + jit_unget_reg_args(); +} + +static void +_swf_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_get_reg_args(); + movr(_R0_REGNO, r1); + swf_call(__aeabi_i2d, i2d, _R2_REGNO); + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p()) + STRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else { + swf_strin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + swf_strin(_R1_REGNO, _FP_REGNO, swf_off(r0) + 4); + } + } + else { + movr(r0, _R0_REGNO); + movr(r0 + 1, _R1_REGNO); + } + jit_unget_reg_args(); +} + +static void +_swf_extr_d_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_get_reg_args(); + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R0_REGNO, r1); + movr(_R1_REGNO, r1 + 1); + } + swf_call(__aeabi_d2f, d2f, _R2_REGNO); + if (jit_fpr_p(r0)) + swf_strin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else + movr(r0, _R0_REGNO); + jit_unget_reg_args(); +} + +static void +_swf_extr_f_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_get_reg_args(); + if (jit_fpr_p(r1)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R0_REGNO, r1); + swf_call(__aeabi_f2d, f2d, _R1_REGNO); + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p()) + STRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + else { + swf_strin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8); + swf_strin(_R1_REGNO, _FP_REGNO, swf_off(r0) + 4); + } + } + else { + movr(r0, _R0_REGNO); + movr(r0 + 1, _R1_REGNO); + } + jit_unget_reg_args(); +} + +static void +_swf_truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ +#if !NAN_TO_INT_IS_ZERO + jit_word_t is_nan; + jit_word_t fast_not_nan; + jit_word_t slow_not_nan; +#endif + jit_get_reg_args(); + if (jit_fpr_p(r1)) + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else + movr(_R0_REGNO, r1); +#if !NAN_TO_INT_IS_ZERO + /* >> based on fragment of __aeabi_fcmpun */ + lshi(_R2_REGNO, _R0_REGNO, 1); + if (jit_thumb_p()) + torrrs(THUMB2_MVN|ARM_S, _R0_REGNO, _R3_REGNO, _R2_REGNO, + encode_thumb_shift(24, ARM_ASR)); + else + corrrs(ARM_CC_AL, ARM_MVN|ARM_S|ARM_ASR, + _R0_REGNO, _R3_REGNO, _R2_REGNO, 24); + fast_not_nan = _jit->pc.w; + if (jit_thumb_p()) { + T2_CC_B(ARM_CC_NE, 0); + tshift(THUMB2_LSLI|ARM_S, _R0_REGNO, _R3_REGNO, 9); + } + else { + CC_B(ARM_CC_NE, 0); + cshift(ARM_CC_AL, ARM_S|ARM_LSL, _R0_REGNO, _R3_REGNO, _R0_REGNO, 9); + } + slow_not_nan = _jit->pc.w; + if (jit_thumb_p()) + T2_CC_B(ARM_CC_EQ, 0); + else + CC_B(ARM_CC_EQ, 0); + movi(r0, 0x80000000); + is_nan = _jit->pc.w; + if (jit_thumb_p()) + T2_B(0); + else + B(0); + patch_at(arm_patch_jump, fast_not_nan, _jit->pc.w); + patch_at(arm_patch_jump, slow_not_nan, _jit->pc.w); + /* << based on fragment of __aeabi_fcmpun */ +#endif + swf_call(__aeabi_f2iz, f2iz, _R2_REGNO); + movr(r0, _R0_REGNO); +#if !NAN_TO_INT_IS_ZERO + patch_at(arm_patch_jump, is_nan, _jit->pc.w); +#endif + jit_unget_reg_args(); +} + +static void +_swf_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ +#if !NAN_TO_INT_IS_ZERO + jit_word_t is_nan; + jit_word_t fast_not_nan; + jit_word_t slow_not_nan; +#endif + jit_get_reg_args(); + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p()) + LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + else { + swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8); + swf_ldrin(_R1_REGNO, _FP_REGNO, swf_off(r1) + 4); + } + } + else { + movr(_R0_REGNO, r1); + movr(_R1_REGNO, r1 + 1); + } +#if !NAN_TO_INT_IS_ZERO + /* >> based on fragment of __aeabi_dcmpun */ + lshi(_R3_REGNO, _R1_REGNO, 1); + if (jit_thumb_p()) + torrrs(THUMB2_MVN|ARM_S, _R0_REGNO, _R3_REGNO, _R3_REGNO, + encode_thumb_shift(21, ARM_ASR)); + else + corrrs(ARM_CC_AL, ARM_MVN|ARM_S|ARM_ASR, + _R0_REGNO, _R3_REGNO, _R3_REGNO, 21); + fast_not_nan = _jit->pc.w; + if (jit_thumb_p()) { + T2_CC_B(ARM_CC_NE, 0); + torrrs(THUMB2_ORR|ARM_S, _R0_REGNO, _R3_REGNO, _R1_REGNO, + encode_thumb_shift(12, ARM_LSL)); + } + else { + CC_B(ARM_CC_NE, 0); + corrrs(ARM_CC_AL, ARM_ORR|ARM_S|ARM_LSL, + _R0_REGNO, _R3_REGNO, _R1_REGNO, 12); + } + slow_not_nan = _jit->pc.w; + if (jit_thumb_p()) + T2_CC_B(ARM_CC_EQ, 0); + else + CC_B(ARM_CC_EQ, 0); + movi(r0, 0x80000000); + is_nan = _jit->pc.w; + if (jit_thumb_p()) + T2_B(0); + else + B(0); + patch_at(arm_patch_jump, fast_not_nan, _jit->pc.w); + patch_at(arm_patch_jump, slow_not_nan, _jit->pc.w); + /* << based on fragment of __aeabi_dcmpun */ +#endif + swf_call(__aeabi_d2iz, d2iz, _R3_REGNO); + movr(r0, _R0_REGNO); +#if !NAN_TO_INT_IS_ZERO + patch_at(arm_patch_jump, is_nan, _jit->pc.w); +#endif + jit_unget_reg_args(); +} + +static void +_swf_movr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (r0 != r1) { + if (jit_fpr_p(r1)) { + reg = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8); + if (jit_fpr_p(r0)) + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + else + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else if (jit_fpr_p(r0)) + swf_strin(r1, _FP_REGNO, swf_off(r0) + 8); + else + movr(r0, r1); + } +} + +static void +_swf_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (r0 != r1) { + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p() && + (reg = jit_get_reg_pair()) != JIT_NOREG) { + LDRDIN(rn(reg), _FP_REGNO, swf_off(r1) + 8); + if (jit_fpr_p(r0)) + STRDIN(rn(reg), _FP_REGNO, swf_off(r0) + 8); + else { + movr(r0, rn(reg)); + movr(r0 + 1, rn(reg) + 1); + } + jit_unget_reg_pair(reg); + } + else { + reg = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8); + if (jit_fpr_p(r0)) + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + else + movr(r0, rn(reg)); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 4); + if (jit_fpr_p(r0)) + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4); + else + movr(r0 + 1, rn(reg)); + jit_unget_reg(reg); + } + } + else if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p() && !(r1 & 1)) + STRDIN(r1, _FP_REGNO, swf_off(r0) + 8); + else { + swf_strin(r1, _FP_REGNO, swf_off(r0) + 8); + swf_strin(r1 + 1, _FP_REGNO, swf_off(r0) + 4); + } + } + else { + movr(r0, r1); + movr(r0 + 1, r1 + 1); + } + } +} + +static void +_swf_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_int32_t reg; + data.f = i0; + if (jit_fpr_p(r0)) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.i); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg(reg); + } + else + movi(r0, data.i); +} + +static void +_swf_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0) +{ + jit_int32_t reg; + union { + jit_int32_t i[2]; + jit_float64_t d; + } data; + data.d = i0; + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p() && + (reg = jit_get_reg_pair()) != JIT_NOREG) { + movi(rn(reg), data.i[0]); + movi(rn(reg) + 1, data.i[1]); + STRDIN(rn(reg), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg_pair(reg); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.i[0]); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + movi(rn(reg), data.i[1]); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4); + jit_unget_reg(reg); + } + } + else { + movi(r0, data.i[0]); + movi(r0 + 1, data.i[1]); + } +} + +static void +_swf_absr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r1)) { + reg = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8); + swf_bici(rn(reg), rn(reg), 0x80000000); + if (jit_fpr_p(r0)) + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + else + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else if (jit_fpr_p(r0)) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + swf_bici(rn(reg), rn(reg), 0x80000000); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg(reg); + } + else + swf_bici(r0, r1, 0x80000000); +} + +static void +_swf_absr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r1)) { + if (jit_fpr_p(r0) && !jit_thumb_p() && jit_armv5e_p() && + r0 != r1 && (reg = jit_get_reg_pair()) != JIT_NOREG) { + LDRDIN(rn(reg), _FP_REGNO, swf_off(r1) + 8); + swf_bici(rn(reg) + 1, rn(reg) + 1, 0x80000000); + STRDIN(rn(reg), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg_pair(reg); + } + else { + reg = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 4); + swf_bici(rn(reg), rn(reg), 0x80000000); + if (jit_fpr_p(r0)) { + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4); + if (r0 != r1) { + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + } + } + else { + movr(r0, rn(reg)); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8); + movr(r0 + 1, rn(reg)); + } + jit_unget_reg(reg); + } + } + else if (jit_fpr_p(r0)) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + swf_bici(rn(reg), rn(reg), 0x80000000); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4); + movr(rn(reg), r1 + 1); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg(reg); + } + else { + swf_bici(r0, r1, 0x80000000); + if (r0 != r1) + movr(r0 + 1, r1 + 1); + } +} + +static void +_swf_negr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r1)) { + reg = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8); + xori(rn(reg), rn(reg), 0x80000000); + if (jit_fpr_p(r0)) + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + else + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else if (jit_fpr_p(r0)) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + xori(rn(reg), rn(reg), 0x80000000); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg(reg); + } + else + xori(r0, r1, 0x80000000); +} + +static void +_swf_negr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r1)) { + if (jit_fpr_p(r0) && !jit_thumb_p() && jit_armv5e_p() && + r0 != r1 && (reg = jit_get_reg_pair()) != JIT_NOREG) { + LDRDIN(rn(reg), _FP_REGNO, swf_off(r1) + 8); + EORI(rn(reg) + 1, rn(reg) + 1, encode_arm_immediate(0x80000000)); + STRDIN(rn(reg), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg_pair(reg); + } + else { + reg = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 4); + xori(rn(reg), rn(reg), 0x80000000); + if (jit_fpr_p(r0)) { + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4); + if (r0 != r1) { + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + } + } + else { + movr(r0, rn(reg)); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8); + movr(r0 + 1, rn(reg)); + } + jit_unget_reg(reg); + } + } + else if (jit_fpr_p(r0)) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + xori(rn(reg), rn(reg), 0x80000000); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4); + movr(rn(reg), r1 + 1); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg(reg); + } + else { + xori(r0, r1, 0x80000000); + if (r0 != r1) + movr(r0 + 1, r1 + 1); + } +} + +static void +_swf_ner_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + swf_iff(__aeabi_fcmpeq, r0, r1, r2); + xori(r0, r0, 1); +} + +static void +_swf_nei_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_float32_t i0) +{ + swf_iff_(__aeabi_fcmpeq, r0, r1, i0); + xori(r0, r0, 1); +} + +static void +_swf_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + swf_idd(__aeabi_dcmpeq, r0, r1, r2); + xori(r0, r0, 1); +} + +static void +_swf_nei_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_float64_t i0) +{ + swf_idd_(__aeabi_dcmpeq, r0, r1, i0); + xori(r0, r0, 1); +} + +static void +_swf_ltgtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + swf_iunff(__aeabi_fcmpeq, r0, r1, r2); + xori(r0, r0, 1); +} + +static void +_swf_ltgti_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_float32_t i0) +{ + swf_iunff_(__aeabi_fcmpeq, r0, r1, i0); + xori(r0, r0, 1); +} + +static void +_swf_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + swf_iundd(__aeabi_dcmpeq, r0, r1, r2); + xori(r0, r0, 1); +} + +static void +_swf_ltgti_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_float64_t i0) +{ + swf_iundd_(__aeabi_dcmpeq, r0, r1, i0); + xori(r0, r0, 1); +} + +static void +_swf_ordr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + swf_iff(__aeabi_fcmpun, r0, r1, r2); + xori(r0, r0, 1); +} + +static void +_swf_ordi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_float32_t i0) +{ + swf_iff_(__aeabi_fcmpun, r0, r1, i0); + xori(r0, r0, 1); +} + +static void +_swf_ordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + swf_idd(__aeabi_dcmpun, r0, r1, r2); + xori(r0, r0, 1); +} + +static void +_swf_ordi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_float64_t i0) +{ + swf_idd_(__aeabi_dcmpun, r0, r1, i0); + xori(r0, r0, 1); +} + +static void +_swf_ldr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r0)) { + reg = jit_get_reg(jit_class_gpr); + ldxi_i(rn(reg), r1, 0); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg(reg); + } + else + ldxi_i(r0, r1, 0); +} + +static void +_swf_ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p() && + (reg = jit_get_reg_pair()) != JIT_NOREG) { + LDRDI(rn(reg), r1, 0); + STRDIN(rn(reg), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg_pair(reg); + } + else { + reg = jit_get_reg(jit_class_gpr); + ldxi_i(rn(reg), r1, 0); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + ldxi_i(rn(reg), r1, 4); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4); + jit_unget_reg(reg); + } + } + else if (!jit_thumb_p() && jit_armv5e_p() && !(r0 & 1)) + LDRDI(r0, r1, 0); + else { + ldxi_i(r0, r1, 0); + ldxi_i(r0 + 1, r1, 4); + } +} + +static void +_swf_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_fpr_p(r0)) { + reg = jit_get_reg(jit_class_gpr); + ldi_i(rn(reg), i0); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg(reg); + } + else + ldi_i(r0, i0); +} + +static void +_swf_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t rg0, rg1; + if (jit_fpr_p(r0) && !jit_thumb_p() && jit_armv5e_p() && + (rg0 = jit_get_reg_pair()) != JIT_NOREG) { + movi(rn(rg0), i0); + LDRDI(rn(rg0), rn(rg0), 0); + STRDIN(rn(rg0), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg_pair(rg0); + } + else { + rg1 = jit_get_reg(jit_class_gpr); + movi(rn(rg1), i0); + if (jit_fpr_p(r0)) { + rg0 = jit_get_reg(jit_class_gpr); + ldxi_i(rn(rg0), rn(rg1), 0); + swf_strin(rn(rg0), _FP_REGNO, swf_off(r0) + 8); + ldxi_i(rn(rg0), rn(rg1), 4); + swf_strin(rn(rg0), _FP_REGNO, swf_off(r0) + 4); + jit_unget_reg(rg0); + } + else if (!jit_thumb_p() && jit_armv5e_p() && !(r0 & 1)) + LDRDI(r0, rn(rg1), 0); + else { + ldxi_i(r0, rn(rg1), 0); + ldxi_i(r0 + 1, rn(rg1), 0); + } + jit_unget_reg(rg1); + } +} + +static void +_swf_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (jit_fpr_p(r0)) { + reg = jit_get_reg(jit_class_gpr); + ldxr_i(rn(reg), r1, r2); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg(reg); + } + else + ldxr_i(r0, r1, r2); +} + +static void +_swf_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t rg0, rg1; + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p() && + (rg0 = jit_get_reg_pair()) != JIT_NOREG) { + LDRD(rn(rg0), r1, r2); + STRDIN(rn(rg0), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg_pair(rg0); + } + else { + rg1 = jit_get_reg(jit_class_gpr); + addr(rn(rg1), r1, r2); + rg0 = jit_get_reg(jit_class_gpr); + ldxi_i(rn(rg0), rn(rg1), 0); + swf_strin(rn(rg0), _FP_REGNO, swf_off(r0) + 8); + ldxi_i(rn(rg0), rn(rg1), 4); + swf_strin(rn(rg0), _FP_REGNO, swf_off(r0) + 4); + jit_unget_reg(rg0); + jit_unget_reg(rg1); + } + } + else { + if (!jit_thumb_p() && jit_armv5e_p() && !(r0 & 1)) + LDRD(r0, r1, r2); + else { + rg1 = jit_get_reg(jit_class_gpr); + addr(rn(rg1), r1, r2); + ldxi_i(r0, rn(rg1), 0); + ldxi_i(r0 + 1, rn(rg1), 4); + jit_unget_reg(rg1); + } + } +} + +static void +_swf_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_fpr_p(r0)) { + reg = jit_get_reg(jit_class_gpr); + ldxi_i(rn(reg), r1, i0); + swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg(reg); + } + else + ldxi_i(r0, r1, i0); +} + +static void +_swf_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t rg0, rg1; + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p() && + ((i0 >= 0 && i0 <= 255) || (i0 < 0 && i0 >= -255)) && + (rg0 = jit_get_reg_pair()) != JIT_NOREG) { + if (i0 >= 0) + LDRDI(rn(rg0), r1, i0); + else + LDRDIN(rn(rg0), r1, -i0); + STRDIN(rn(rg0), _FP_REGNO, swf_off(r0) + 8); + jit_unget_reg_pair(rg0); + } + else if (i0 >= 0 && i0 + 4 <= 4095) { + rg0 = jit_get_reg(jit_class_gpr); + ldxi_i(rn(rg0), r1, i0); + swf_strin(rn(rg0), _FP_REGNO, swf_off(r0) + 8); + ldxi_i(rn(rg0), r1, i0 + 4); + swf_strin(rn(rg0), _FP_REGNO, swf_off(r0) + 4); + jit_unget_reg(rg0); + } + else if (i0 < 0 && ((jit_thumb_p() && i0 >= -255) || + (!jit_thumb_p() && i0 >= -4095))) { + rg0 = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(rg0), r1, -i0); + swf_strin(rn(rg0), _FP_REGNO, swf_off(r0) + 8); + swf_ldrin(rn(rg0), r1, -(i0 + 4)); + swf_strin(rn(rg0), _FP_REGNO, swf_off(r0) + 4); + jit_unget_reg(rg0); + } + else { + rg0 = jit_get_reg(jit_class_gpr); + rg1 = jit_get_reg(jit_class_gpr); + addi(rn(rg1), r1, i0); + ldxi_i(rn(rg0), rn(rg1), 0); + swf_strin(rn(rg0), _FP_REGNO, swf_off(r0) + 8); + ldxi_i(rn(rg0), rn(rg1), 4); + swf_strin(rn(rg0), _FP_REGNO, swf_off(r0) + 4); + jit_unget_reg(rg1); + jit_unget_reg(rg0); + } + } + else { + if (!jit_thumb_p() && jit_armv5e_p() && + i0 >= 0 && i0 <= 255 && !(r0 & 1)) + LDRDI(r0, r1, i0); + else if (!jit_thumb_p() && jit_armv5e_p() && + i0 < 0 && i0 >= -255 && !(r0 & 1)) + LDRDIN(r0, r1, -i0); + else if (i0 >= 0 && i0 + 4 <= 4095) { + ldxi_i(r0, r1, i0); + ldxi_i(r0 + 1, r1, i0 + 4); + } + else if (i0 < 0 && i0 >= -4095) { + swf_ldrin(r0, r1, -i0); + swf_ldrin(r0 + 1, r1, -(i0 + 4)); + } + else { + rg0 = jit_get_reg(jit_class_gpr); + addi(rn(rg0), r1, i0); + ldxi_i(r0, rn(rg0), 0); + ldxi_i(r0 + 1, rn(rg0), 4); + jit_unget_reg(rg0); + } + } +} + +static void +_swf_str_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r1)) { + reg = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8); + stxi_i(0, r0, rn(reg)); + jit_unget_reg(reg); + } + else + str_i(r0, r1); +} + +static void +_swf_str_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p() && + (reg = jit_get_reg_pair()) != JIT_NOREG) { + LDRDIN(rn(reg), _FP_REGNO, swf_off(r1) + 8); + STRDI(rn(reg), r0, 0); + jit_unget_reg_pair(reg); + } + else { + reg = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8); + stxi_i(0, r0, rn(reg)); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 4); + stxi_i(4, r0, rn(reg)); + jit_unget_reg(reg); + } + } + else { + if (!jit_thumb_p() && jit_armv5e_p() && !(r1 & 1)) + STRDI(r1, r0, 0); + else { + stxi_i(0, r0, r1); + stxi_i(4, r0, r1 + 1); + } + } +} + +static void +_swf_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (jit_fpr_p(r0)) { + reg = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r0) + 8); + sti_i(i0, rn(reg)); + jit_unget_reg(reg); + } + else + sti_i(i0, r0); +} + +static void +_swf_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t rg0, rg1; + if (jit_fpr_p(r0)) { + if (!jit_thumb_p() && jit_armv5e_p() && + (rg0 = jit_get_reg_pair()) != JIT_NOREG) { + rg1 = jit_get_reg(jit_class_gpr); + movi(rn(rg1), i0); + LDRDIN(rn(rg0), _FP_REGNO, swf_off(r0) + 8); + STRDI(rn(rg0), rn(rg1), 0); + jit_unget_reg(rg1); + jit_unget_reg_pair(rg0); + } + else { + rg1 = jit_get_reg(jit_class_gpr); + movi(rn(rg1), i0); + rg0 = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(rg0), _FP_REGNO, swf_off(r0) + 8); + stxi_i(0, rn(rg1), rn(rg0)); + swf_ldrin(rn(rg0), _FP_REGNO, swf_off(r0) + 4); + stxi_i(4, rn(rg1), rn(rg0)); + jit_unget_reg(rg1); + jit_unget_reg(rg0); + } + } + else { + rg1 = jit_get_reg(jit_class_gpr); + movi(rn(rg1), i0); + if (!jit_thumb_p() && jit_armv5e_p() && !(r0 & 1)) + STRDI(r0, rn(rg1), 0); + else { + stxi_i(0, rn(rg1), r0); + stxi_i(4, rn(rg1), r0 + 1); + } + jit_unget_reg(rg1); + } +} + +static void +_swf_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (jit_fpr_p(r2)) { + reg = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r2) + 8); + stxr_i(r1, r0, rn(reg)); + jit_unget_reg(reg); + } + else + stxr_i(r0, r1, r2); +} + +static void +_swf_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t rg0, rg1; + if (jit_fpr_p(r2)) { + if (!jit_thumb_p() && jit_armv5e_p() && + (rg0 = jit_get_reg_pair()) != JIT_NOREG) { + LDRDIN(rn(rg0), _FP_REGNO, swf_off(r2) + 8); + STRD(rn(rg0), r0, r1); + jit_unget_reg_pair(rg0); + } + else { + rg1 = jit_get_reg(jit_class_gpr); + addr(rn(rg1), r0, r1); + rg0 = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(rg0), _FP_REGNO, swf_off(r2) + 8); + stxi_i(0, rn(rg1), rn(rg0)); + swf_ldrin(rn(rg0), _FP_REGNO, swf_off(r2) + 4); + stxi_i(4, rn(rg1), rn(rg0)); + jit_unget_reg(rg0); + jit_unget_reg(rg1); + } + } + else { + if (!jit_thumb_p() && jit_armv5e_p() && !(r2 & 1)) + STRD(r0, r1, r2); + else { + rg1 = jit_get_reg(jit_class_gpr); + addr(rn(rg1), r0, r1); + stxi_i(0, rn(rg1), r2); + stxi_i(4, rn(rg1), r2 + 1); + jit_unget_reg(rg1); + } + } +} + +static void +_swf_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r1)) { + reg = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8); + stxi_i(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + else + stxi_i(i0, r0, r1); +} + +static void +_swf_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t rg0, rg1; + if (jit_fpr_p(r1)) { + if (!jit_thumb_p() && jit_armv5e_p() && + ((i0 >= 0 && i0 <= 255) || (i0 < 0 && i0 >= -255)) && + (rg0 = jit_get_reg_pair()) != JIT_NOREG) { + LDRDIN(rn(rg0), _FP_REGNO, swf_off(r1) + 8); + if (i0 >= 0 && i0 <= 255) + STRDI(rn(rg0), r0, i0); + else + STRDIN(rn(rg0), r0, -i0); + jit_unget_reg_pair(rg0); + } + else if (i0 >= 0 && i0 + 4 <= 4095) { + rg0 = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(rg0), _FP_REGNO, swf_off(r1) + 8); + stxi_i(i0, r0, rn(rg0)); + swf_ldrin(rn(rg0), _FP_REGNO, swf_off(r1) + 4); + stxi_i(i0 + 4, r0, rn(rg0)); + jit_unget_reg(rg0); + } + else if (i0 < 0 && ((jit_thumb_p() && i0 >= -255) || + (!jit_thumb_p() && i0 >= -4095))) { + rg0 = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(rg0), _FP_REGNO, swf_off(r1) + 8); + swf_strin(rn(rg0), r0, -i0); + swf_ldrin(rn(rg0), _FP_REGNO, swf_off(r1) + 4); + swf_strin(rn(rg0), r0, -(i0 + 4)); + jit_unget_reg(rg0); + } + else { + rg1 = jit_get_reg(jit_class_gpr); + addi(rn(rg1), r0, i0); + rg0 = jit_get_reg(jit_class_gpr); + swf_ldrin(rn(rg0), _FP_REGNO, swf_off(r1) + 8); + stxi_i(0, rn(rg1), rn(rg0)); + swf_ldrin(rn(rg0), _FP_REGNO, swf_off(r1) + 4); + stxi_i(4, rn(rg1), rn(rg0)); + jit_unget_reg(rg0); + jit_unget_reg(rg1); + } + } + else { + if (!jit_thumb_p() && jit_armv5e_p() && + i0 >= 0 && i0 <= 255 && !(r1 & 1)) + STRDI(r1, r0, i0); + else if (!jit_thumb_p() && jit_armv5e_p() && + i0 < 0 && i0 >= -255 && !(r1 & 1)) + STRDIN(r1, r0, -i0); + else if (i0 >= 0 && i0 + 4 <= 4095) { + stxi_i(i0, r0, r1); + stxi_i(i0 + 4, r0, r1 + 1); + } + else if (i0 < 0 && ((jit_thumb_p() && i0 >= 255) || + (!jit_thumb_p() && i0 >= -4095))) { + swf_strin(r1, r0, -i0); + swf_strin(r1 + 1, r0, -(i0 + 4)); + } + else { + rg1 = jit_get_reg(jit_class_gpr); + addi(rn(rg1), r0, i0); + stxi_i(0, rn(rg1), r1); + stxi_i(4, rn(rg1), r1 + 1); + jit_unget_reg(rg1); + } + } +} + +static void +_swf_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + + assert(_jitc->function->self.call & jit_call_varargs); + + /* Adjust pointer. */ + reg = jit_get_reg(jit_class_gpr); + andi(rn(reg), r1, 7); + addr(r1, r1, rn(reg)); + jit_unget_reg(reg); + + /* Load argument. */ + swf_ldr_d(r0, r1); + + /* Update stack pointer. */ + addi(r1, r1, sizeof(jit_float64_t)); +} + +#endif diff --git a/deps/lightning/lib/jit_arm-sz.c b/deps/lightning/lib/jit_arm-sz.c new file mode 100644 index 0000000..9f0d012 --- /dev/null +++ b/deps/lightning/lib/jit_arm-sz.c @@ -0,0 +1,808 @@ + +#if __WORDSIZE == 32 +#if defined(__ARM_PCS_VFP) +#define JIT_INSTR_MAX 48 + 0, /* data */ + 0, /* live */ + 2, /* align */ + 0, /* save */ + 0, /* load */ + 2, /* #name */ + 0, /* #note */ + 0, /* label */ + 34, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 16, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 12, /* addi */ + 4, /* addcr */ + 8, /* addci */ + 4, /* addxr */ + 4, /* addxi */ + 4, /* subr */ + 12, /* subi */ + 4, /* subcr */ + 8, /* subci */ + 4, /* subxr */ + 4, /* subxi */ + 16, /* rsbi */ + 4, /* mulr */ + 12, /* muli */ + 4, /* qmulr */ + 12, /* qmuli */ + 4, /* qmulr_u */ + 8, /* qmuli_u */ + 40, /* divr */ + 48, /* divi */ + 40, /* divr_u */ + 44, /* divi_u */ + 34, /* qdivr */ + 38, /* qdivi */ + 34, /* qdivr_u */ + 38, /* qdivi_u */ + 40, /* remr */ + 48, /* remi */ + 40, /* remr_u */ + 44, /* remi_u */ + 4, /* andr */ + 12, /* andi */ + 4, /* orr */ + 12, /* ori */ + 4, /* xorr */ + 12, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 14, /* ltr */ + 14, /* lti */ + 14, /* ltr_u */ + 14, /* lti_u */ + 14, /* ler */ + 14, /* lei */ + 14, /* ler_u */ + 14, /* lei_u */ + 14, /* eqr */ + 14, /* eqi */ + 14, /* ger */ + 14, /* gei */ + 14, /* ger_u */ + 14, /* gei_u */ + 14, /* gtr */ + 14, /* gti */ + 14, /* gtr_u */ + 14, /* gti_u */ + 14, /* ner */ + 14, /* nei */ + 4, /* movr */ + 8, /* movi */ + 4, /* extr_c */ + 4, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 0, /* extr_i */ + 0, /* extr_ui */ + 8, /* htonr_us */ + 4, /* htonr_ui */ + 0, /* htonr_ul */ + 4, /* ldr_c */ + 12, /* ldi_c */ + 4, /* ldr_uc */ + 12, /* ldi_uc */ + 4, /* ldr_s */ + 12, /* ldi_s */ + 4, /* ldr_us */ + 12, /* ldi_us */ + 4, /* ldr_i */ + 12, /* ldi_i */ + 0, /* ldr_ui */ + 0, /* ldi_ui */ + 0, /* ldr_l */ + 0, /* ldi_l */ + 4, /* ldxr_c */ + 12, /* ldxi_c */ + 4, /* ldxr_uc */ + 12, /* ldxi_uc */ + 4, /* ldxr_s */ + 12, /* ldxi_s */ + 4, /* ldxr_us */ + 12, /* ldxi_us */ + 4, /* ldxr_i */ + 12, /* ldxi_i */ + 0, /* ldxr_ui */ + 0, /* ldxi_ui */ + 0, /* ldxr_l */ + 0, /* ldxi_l */ + 4, /* str_c */ + 12, /* sti_c */ + 4, /* str_s */ + 12, /* sti_s */ + 4, /* str_i */ + 12, /* sti_i */ + 0, /* str_l */ + 0, /* sti_l */ + 4, /* stxr_c */ + 12, /* stxi_c */ + 4, /* stxr_s */ + 12, /* stxi_s */ + 4, /* stxr_i */ + 12, /* stxi_i */ + 0, /* stxr_l */ + 0, /* stxi_l */ + 8, /* bltr */ + 8, /* blti */ + 8, /* bltr_u */ + 8, /* blti_u */ + 8, /* bler */ + 8, /* blei */ + 8, /* bler_u */ + 8, /* blei_u */ + 8, /* beqr */ + 16, /* beqi */ + 8, /* bger */ + 8, /* bgei */ + 8, /* bger_u */ + 8, /* bgei_u */ + 8, /* bgtr */ + 8, /* bgti */ + 8, /* bgtr_u */ + 8, /* bgti_u */ + 8, /* bner */ + 16, /* bnei */ + 8, /* bmsr */ + 8, /* bmsi */ + 8, /* bmcr */ + 8, /* bmci */ + 8, /* boaddr */ + 8, /* boaddi */ + 8, /* boaddr_u */ + 8, /* boaddi_u */ + 8, /* bxaddr */ + 8, /* bxaddi */ + 8, /* bxaddr_u */ + 8, /* bxaddi_u */ + 8, /* bosubr */ + 8, /* bosubi */ + 8, /* bosubr_u */ + 8, /* bosubi_u */ + 8, /* bxsubr */ + 8, /* bxsubi */ + 8, /* bxsubr_u */ + 8, /* bxsubi_u */ + 4, /* jmpr */ + 8, /* jmpi */ + 4, /* callr */ + 20, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 24, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 8, /* addi_f */ + 4, /* subr_f */ + 8, /* subi_f */ + 8, /* rsbi_f */ + 4, /* mulr_f */ + 8, /* muli_f */ + 4, /* divr_f */ + 8, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 18, /* ltr_f */ + 30, /* lti_f */ + 20, /* ler_f */ + 32, /* lei_f */ + 18, /* eqr_f */ + 30, /* eqi_f */ + 18, /* ger_f */ + 30, /* gei_f */ + 18, /* gtr_f */ + 30, /* gti_f */ + 18, /* ner_f */ + 30, /* nei_f */ + 18, /* unltr_f */ + 30, /* unlti_f */ + 18, /* unler_f */ + 30, /* unlei_f */ + 24, /* uneqr_f */ + 36, /* uneqi_f */ + 18, /* unger_f */ + 30, /* ungei_f */ + 18, /* ungtr_f */ + 30, /* ungti_f */ + 24, /* ltgtr_f */ + 36, /* ltgti_f */ + 18, /* ordr_f */ + 30, /* ordi_f */ + 18, /* unordr_f */ + 30, /* unordi_f */ + 8, /* truncr_f_i */ + 0, /* truncr_f_l */ + 8, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 12, /* movi_f */ + 4, /* ldr_f */ + 12, /* ldi_f */ + 8, /* ldxr_f */ + 16, /* ldxi_f */ + 4, /* str_f */ + 12, /* sti_f */ + 8, /* stxr_f */ + 16, /* stxi_f */ + 12, /* bltr_f */ + 24, /* blti_f */ + 12, /* bler_f */ + 24, /* blei_f */ + 12, /* beqr_f */ + 24, /* beqi_f */ + 12, /* bger_f */ + 24, /* bgei_f */ + 12, /* bgtr_f */ + 24, /* bgti_f */ + 12, /* bner_f */ + 24, /* bnei_f */ + 16, /* bunltr_f */ + 28, /* bunlti_f */ + 16, /* bunler_f */ + 28, /* bunlei_f */ + 20, /* buneqr_f */ + 32, /* buneqi_f */ + 16, /* bunger_f */ + 28, /* bungei_f */ + 12, /* bungtr_f */ + 24, /* bungti_f */ + 20, /* bltgtr_f */ + 32, /* bltgti_f */ + 12, /* bordr_f */ + 24, /* bordi_f */ + 12, /* bunordr_f */ + 24, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 20, /* addi_d */ + 4, /* subr_d */ + 20, /* subi_d */ + 20, /* rsbi_d */ + 4, /* mulr_d */ + 20, /* muli_d */ + 4, /* divr_d */ + 20, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 18, /* ltr_d */ + 34, /* lti_d */ + 20, /* ler_d */ + 36, /* lei_d */ + 18, /* eqr_d */ + 34, /* eqi_d */ + 18, /* ger_d */ + 34, /* gei_d */ + 18, /* gtr_d */ + 34, /* gti_d */ + 18, /* ner_d */ + 34, /* nei_d */ + 18, /* unltr_d */ + 34, /* unlti_d */ + 18, /* unler_d */ + 34, /* unlei_d */ + 24, /* uneqr_d */ + 40, /* uneqi_d */ + 18, /* unger_d */ + 34, /* ungei_d */ + 18, /* ungtr_d */ + 34, /* ungti_d */ + 24, /* ltgtr_d */ + 40, /* ltgti_d */ + 18, /* ordr_d */ + 34, /* ordi_d */ + 18, /* unordr_d */ + 34, /* unordi_d */ + 8, /* truncr_d_i */ + 0, /* truncr_d_l */ + 8, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 16, /* movi_d */ + 4, /* ldr_d */ + 12, /* ldi_d */ + 8, /* ldxr_d */ + 16, /* ldxi_d */ + 4, /* str_d */ + 12, /* sti_d */ + 8, /* stxr_d */ + 16, /* stxi_d */ + 12, /* bltr_d */ + 28, /* blti_d */ + 12, /* bler_d */ + 28, /* blei_d */ + 12, /* beqr_d */ + 28, /* beqi_d */ + 12, /* bger_d */ + 28, /* bgei_d */ + 12, /* bgtr_d */ + 28, /* bgti_d */ + 12, /* bner_d */ + 28, /* bnei_d */ + 16, /* bunltr_d */ + 32, /* bunlti_d */ + 16, /* bunler_d */ + 32, /* bunlei_d */ + 20, /* buneqr_d */ + 36, /* buneqi_d */ + 16, /* bunger_d */ + 32, /* bungei_d */ + 12, /* bungtr_d */ + 28, /* bungti_d */ + 20, /* bltgtr_d */ + 36, /* bltgti_d */ + 12, /* bordr_d */ + 28, /* bordi_d */ + 12, /* bunordr_d */ + 28, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 4, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 4, /* movr_d_ww */ + 12, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __ARM_PCS_VFP */ +#endif /* __WORDSIZE */ + +#if __WORDSIZE == 32 +#if !defined(__ARM_PCS_VFP) +#define JIT_INSTR_MAX 160 + 0, /* data */ + 0, /* live */ + 2, /* align */ + 0, /* save */ + 0, /* load */ + 2, /* #name */ + 0, /* #note */ + 0, /* label */ + 30, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 28, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 12, /* addi */ + 4, /* addcr */ + 8, /* addci */ + 4, /* addxr */ + 4, /* addxi */ + 4, /* subr */ + 12, /* subi */ + 4, /* subcr */ + 8, /* subci */ + 4, /* subxr */ + 4, /* subxi */ + 16, /* rsbi */ + 8, /* mulr */ + 12, /* muli */ + 4, /* qmulr */ + 12, /* qmuli */ + 4, /* qmulr_u */ + 8, /* qmuli_u */ + 40, /* divr */ + 48, /* divi */ + 40, /* divr_u */ + 44, /* divi_u */ + 34, /* qdivr */ + 38, /* qdivi */ + 34, /* qdivr_u */ + 38, /* qdivi_u */ + 40, /* remr */ + 48, /* remi */ + 40, /* remr_u */ + 44, /* remi_u */ + 4, /* andr */ + 12, /* andi */ + 4, /* orr */ + 12, /* ori */ + 4, /* xorr */ + 12, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 14, /* ltr */ + 14, /* lti */ + 14, /* ltr_u */ + 14, /* lti_u */ + 14, /* ler */ + 14, /* lei */ + 14, /* ler_u */ + 14, /* lei_u */ + 14, /* eqr */ + 14, /* eqi */ + 14, /* ger */ + 14, /* gei */ + 14, /* ger_u */ + 14, /* gei_u */ + 14, /* gtr */ + 14, /* gti */ + 14, /* gtr_u */ + 14, /* gti_u */ + 14, /* ner */ + 14, /* nei */ + 4, /* movr */ + 8, /* movi */ + 8, /* extr_c */ + 4, /* extr_uc */ + 8, /* extr_s */ + 8, /* extr_us */ + 0, /* extr_i */ + 0, /* extr_ui */ + 20, /* htonr_us */ + 16, /* htonr_ui */ + 0, /* htonr_ul */ + 4, /* ldr_c */ + 12, /* ldi_c */ + 4, /* ldr_uc */ + 12, /* ldi_uc */ + 4, /* ldr_s */ + 12, /* ldi_s */ + 4, /* ldr_us */ + 12, /* ldi_us */ + 4, /* ldr_i */ + 12, /* ldi_i */ + 0, /* ldr_ui */ + 0, /* ldi_ui */ + 0, /* ldr_l */ + 0, /* ldi_l */ + 4, /* ldxr_c */ + 12, /* ldxi_c */ + 4, /* ldxr_uc */ + 12, /* ldxi_uc */ + 4, /* ldxr_s */ + 12, /* ldxi_s */ + 4, /* ldxr_us */ + 12, /* ldxi_us */ + 4, /* ldxr_i */ + 12, /* ldxi_i */ + 0, /* ldxr_ui */ + 0, /* ldxi_ui */ + 0, /* ldxr_l */ + 0, /* ldxi_l */ + 4, /* str_c */ + 12, /* sti_c */ + 4, /* str_s */ + 12, /* sti_s */ + 4, /* str_i */ + 12, /* sti_i */ + 0, /* str_l */ + 0, /* sti_l */ + 4, /* stxr_c */ + 12, /* stxi_c */ + 4, /* stxr_s */ + 12, /* stxi_s */ + 4, /* stxr_i */ + 12, /* stxi_i */ + 0, /* stxr_l */ + 0, /* stxi_l */ + 8, /* bltr */ + 8, /* blti */ + 8, /* bltr_u */ + 8, /* blti_u */ + 8, /* bler */ + 8, /* blei */ + 8, /* bler_u */ + 8, /* blei_u */ + 8, /* beqr */ + 16, /* beqi */ + 8, /* bger */ + 8, /* bgei */ + 8, /* bger_u */ + 8, /* bgei_u */ + 8, /* bgtr */ + 8, /* bgti */ + 8, /* bgtr_u */ + 8, /* bgti_u */ + 8, /* bner */ + 16, /* bnei */ + 8, /* bmsr */ + 8, /* bmsi */ + 8, /* bmcr */ + 8, /* bmci */ + 8, /* boaddr */ + 8, /* boaddi */ + 8, /* boaddr_u */ + 8, /* boaddi_u */ + 8, /* bxaddr */ + 8, /* bxaddi */ + 8, /* bxaddr_u */ + 8, /* bxaddi_u */ + 8, /* bosubr */ + 8, /* bosubi */ + 8, /* bosubr_u */ + 8, /* bosubi_u */ + 8, /* bxsubr */ + 8, /* bxsubi */ + 8, /* bxsubr_u */ + 8, /* bxsubi_u */ + 12, /* jmpr */ + 72, /* jmpi */ + 4, /* callr */ + 20, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 160, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 40, /* addr_f */ + 40, /* addi_f */ + 40, /* subr_f */ + 40, /* subi_f */ + 40, /* rsbi_f */ + 40, /* mulr_f */ + 40, /* muli_f */ + 40, /* divr_f */ + 40, /* divi_f */ + 12, /* negr_f */ + 12, /* absr_f */ + 36, /* sqrtr_f */ + 40, /* ltr_f */ + 44, /* lti_f */ + 40, /* ler_f */ + 44, /* lei_f */ + 40, /* eqr_f */ + 44, /* eqi_f */ + 40, /* ger_f */ + 44, /* gei_f */ + 40, /* gtr_f */ + 44, /* gti_f */ + 44, /* ner_f */ + 48, /* nei_f */ + 72, /* unltr_f */ + 80, /* unlti_f */ + 72, /* unler_f */ + 80, /* unlei_f */ + 72, /* uneqr_f */ + 80, /* uneqi_f */ + 72, /* unger_f */ + 80, /* ungei_f */ + 72, /* ungtr_f */ + 80, /* ungti_f */ + 76, /* ltgtr_f */ + 84, /* ltgti_f */ + 44, /* ordr_f */ + 48, /* ordi_f */ + 72, /* unordr_f */ + 80, /* unordi_f */ + 36, /* truncr_f_i */ + 0, /* truncr_f_l */ + 36, /* extr_f */ + 38, /* extr_d_f */ + 8, /* movr_f */ + 12, /* movi_f */ + 8, /* ldr_f */ + 16, /* ldi_f */ + 8, /* ldxr_f */ + 16, /* ldxi_f */ + 8, /* str_f */ + 16, /* sti_f */ + 8, /* stxr_f */ + 16, /* stxi_f */ + 44, /* bltr_f */ + 48, /* blti_f */ + 44, /* bler_f */ + 48, /* blei_f */ + 44, /* beqr_f */ + 52, /* beqi_f */ + 44, /* bger_f */ + 48, /* bgei_f */ + 44, /* bgtr_f */ + 48, /* bgti_f */ + 44, /* bner_f */ + 48, /* bnei_f */ + 44, /* bunltr_f */ + 48, /* bunlti_f */ + 44, /* bunler_f */ + 48, /* bunlei_f */ + 76, /* buneqr_f */ + 84, /* buneqi_f */ + 44, /* bunger_f */ + 48, /* bungei_f */ + 44, /* bungtr_f */ + 48, /* bungti_f */ + 76, /* bltgtr_f */ + 84, /* bltgti_f */ + 44, /* bordr_f */ + 48, /* bordi_f */ + 44, /* bunordr_f */ + 48, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 50, /* addr_d */ + 52, /* addi_d */ + 50, /* subr_d */ + 52, /* subi_d */ + 52, /* rsbi_d */ + 50, /* mulr_d */ + 52, /* muli_d */ + 50, /* divr_d */ + 52, /* divi_d */ + 20, /* negr_d */ + 20, /* absr_d */ + 42, /* sqrtr_d */ + 44, /* ltr_d */ + 48, /* lti_d */ + 44, /* ler_d */ + 48, /* lei_d */ + 44, /* eqr_d */ + 48, /* eqi_d */ + 44, /* ger_d */ + 48, /* gei_d */ + 44, /* gtr_d */ + 48, /* gti_d */ + 48, /* ner_d */ + 52, /* nei_d */ + 82, /* unltr_d */ + 88, /* unlti_d */ + 82, /* unler_d */ + 88, /* unlei_d */ + 82, /* uneqr_d */ + 88, /* uneqi_d */ + 82, /* unger_d */ + 88, /* ungei_d */ + 82, /* ungtr_d */ + 88, /* ungti_d */ + 86, /* ltgtr_d */ + 92, /* ltgti_d */ + 48, /* ordr_d */ + 52, /* ordi_d */ + 82, /* unordr_d */ + 88, /* unordi_d */ + 36, /* truncr_d_i */ + 0, /* truncr_d_l */ + 36, /* extr_d */ + 38, /* extr_f_d */ + 16, /* movr_d */ + 20, /* movi_d */ + 16, /* ldr_d */ + 24, /* ldi_d */ + 20, /* ldxr_d */ + 28, /* ldxi_d */ + 16, /* str_d */ + 24, /* sti_d */ + 20, /* stxr_d */ + 28, /* stxi_d */ + 48, /* bltr_d */ + 52, /* blti_d */ + 48, /* bler_d */ + 52, /* blei_d */ + 48, /* beqr_d */ + 60, /* beqi_d */ + 48, /* bger_d */ + 52, /* bgei_d */ + 48, /* bgtr_d */ + 52, /* bgti_d */ + 48, /* bner_d */ + 52, /* bnei_d */ + 48, /* bunltr_d */ + 52, /* bunlti_d */ + 48, /* bunler_d */ + 52, /* bunlei_d */ + 84, /* buneqr_d */ + 92, /* buneqi_d */ + 48, /* bunger_d */ + 52, /* bungei_d */ + 48, /* bungtr_d */ + 52, /* bungti_d */ + 84, /* bltgtr_d */ + 92, /* bltgti_d */ + 48, /* bordr_d */ + 52, /* bordi_d */ + 48, /* bunordr_d */ + 52, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 4, /* movr_w_f */ + 8, /* movr_ww_d */ + 0, /* movr_w_d */ + 8, /* movr_f_w */ + 8, /* movi_f_w */ + 16, /* movr_d_ww */ + 12, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __ARM_PCS_VFP */ +#endif /* __WORDSIZE */ diff --git a/deps/lightning/lib/jit_arm-vfp.c b/deps/lightning/lib/jit_arm-vfp.c new file mode 100644 index 0000000..743a3ef --- /dev/null +++ b/deps/lightning/lib/jit_arm-vfp.c @@ -0,0 +1,2330 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +/* as per vfp_regno macro, required due to "support" to soft float registers + * or using integer registers as arguments to float operations */ +# define _D8_REGNO 32 +# define ARM_V_Q 0x00000040 +# define FPSCR_N 0x80000000 /* Negative flag */ +# define FPSCR_Z 0x40000000 /* Zero flag */ +# define FPSCR_C 0x20000000 /* Carry flag */ +# define FPSCR_V 0x10000000 /* Overflow flag */ +# define FPSCR_QC 0x08000000 /* Cumulative saturation */ +# define FPSCR_AHP 0x04000000 /* Alt. half-precision */ +# define FPSCR_DN 0x02000000 /* Default NaN mode */ +# define FPSCR_FZ 0x01000000 /* Flush to zero */ +# define FPSCR_RMASK 0x00c00000 +# define FPSCR_RN 0x00000000 /* Round to Nearest */ +# define FPSCR_RP 0x00400000 /* Round to Plus Infinity */ +# define FPSCR_RM 0x00800000 /* Round to Minus Infinity */ +# define FPSCR_RZ 0x00c00000 /* Round towards Zero */ +# define FPSCR_STRIDE 0x00300000 +# define FPSCR_RES1 0x00080000 /* Reserved, UNK/SBZP */ +# define FPSCR_LEN 0x00070000 +# define FPSCR_IDE 0x00008000 /* Input Denormal trap */ +# define FPSCR_IXE 0x00001000 /* Inexact trap */ +# define FPSCR_UFE 0x00000800 /* Underflow trap */ +# define FPSCR_OFE 0x00000400 /* Overflow trap */ +# define FPSCR_DZE 0x00000200 /* Division by zero trap */ +# define FPSCR_IOE 0x00000100 /* Invalid Operation trap */ +# define FPSCR_IDC 0x00000080 /* Input Denormal flag */ +# define FPSCR_RES0 0x00000060 /* Reserved, UNK/SBZP */ +# define FPSCR_IXC 0x00000010 /* Inexact flag */ +# define FPSCR_UFC 0x00000008 /* Underflow flag */ +# define FPSCR_OFC 0x00000004 /* Overflow flag */ +# define FPSCR_DZC 0x00000002 /* Division by zero flag */ +# define FPSCR_IOC 0x00000001 /* Invalid Operation flag */ +# define ARM_V_E 0x00000080 /* ARM_VCMP except if NaN */ +# define ARM_V_Z 0x00010000 /* ARM_VCMP with zero */ +# define ARM_V_F64 0x00000100 +# define ARM_VADD_F 0x0e300a00 +# define ARM_VSUB_F 0x0e300a40 +# define ARM_VMUL_F 0x0e200a00 +# define ARM_VDIV_F 0x0e800a00 +# define ARM_VABS_F 0x0eb00ac0 +# define ARM_VNEG_F 0x0eb10a40 +# define ARM_VSQRT_F 0x0eb10ac0 +# define ARM_VMOV_F 0x0eb00a40 +# define ARM_VMOV_A_S 0x0e100a10 /* vmov rn, sn */ +# define ARM_VMOV_S_A 0x0e000a10 /* vmov sn, rn */ +# define ARM_VMOV_AA_D 0x0c500b10 /* vmov rn,rn, dn */ +# define ARM_VMOV_D_AA 0x0c400b10 /* vmov dn, rn,rn */ +# define ARM_VCMP 0x0eb40a40 +# define ARM_VMRS 0x0ef10a10 +# define ARM_VMSR 0x0ee10a10 +# define ARM_VCVT_2I 0x00040000 /* to integer */ +# define ARM_VCVT_2S 0x00010000 /* to signed */ +# define ARM_VCVT_RS 0x00000080 /* round to zero or signed */ +# define ARM_VCVT 0x0eb80a40 +# define ARM_VCVT_S32_F32 ARM_VCVT|ARM_VCVT_2I|ARM_VCVT_2S|ARM_VCVT_RS +# define ARM_VCVT_U32_F32 ARM_VCVT|ARM_VCVT_2I|ARM_VCVT_RS +# define ARM_VCVT_S32_F64 ARM_VCVT|ARM_VCVT_2I|ARM_VCVT_2S|ARM_VCVT_RS|ARM_V_F64 +# define ARM_VCVT_U32_F64 ARM_VCVT|ARM_VCVT_2I|ARM_VCVT_RS|ARM_V_F64 +# define ARM_VCVT_F32_S32 ARM_VCVT|ARM_VCVT_RS +# define ARM_VCVT_F32_U32 ARM_VCVT +# define ARM_VCVT_F64_S32 ARM_VCVT|ARM_VCVT_RS|ARM_V_F64 +# define ARM_VCVT_F64_U32 ARM_VCVT|ARM_V_F64 +# define ARM_VCVT_F 0x0eb70ac0 +# define ARM_VCVT_F32_F64 ARM_VCVT_F +# define ARM_VCVT_F64_F32 ARM_VCVT_F|ARM_V_F64 +# define ARM_VCVTR_S32_F32 ARM_VCVT|ARM_VCVT_2I|ARM_VCVT_2S +# define ARM_VCVTR_U32_F32 ARM_VCVT|ARM_VCVT_2I +# define ARM_VCVTR_S32_F64 ARM_VCVT|ARM_VCVT_2I|ARM_VCVT_2S|ARM_V_F64 +# define ARM_VCVTR_U32_F64 ARM_VCVT|ARM_VCVT_2I|ARM_V_F64 +# define ARM_V_D 0x00400000 +# define ARM_V_N 0x00000080 +# define ARM_V_Q 0x00000040 +# define ARM_V_M 0x00000020 +# define ARM_V_U 0x01000000 +# define ARM_V_I16 0x00100000 +# define ARM_V_I32 0x00200000 +# define ARM_V_I64 0x00300000 +# define ARM_V_S16 0x00040000 +# define ARM_V_S32 0x00080000 +# define ARM_VADD_I 0x02000800 +# define ARM_VQADD_I 0x02000010 /* set flag on over/carry */ +# define ARM_VADDL_I 0x02800000 /* q=d+d */ +# define ARM_VADDW_I 0x02800100 /* q=q+d */ +# define ARM_VSUB_I 0x03000800 +# define ARM_VQSUB_I 0x02000210 /* set flag on over/carry */ +# define ARM_VSUBL_I 0x02800200 +# define ARM_VSUBW_I 0x02800300 +# define ARM_VMUL_I 0x02000910 +# define ARM_VMULL_I 0x02800c00 +# define ARM_VABS_I 0x03b10300 +# define ARM_VQABS_I 0x03b00700 /* sets flag on overflow */ +# define ARM_VNEG_I 0x03b10380 +# define ARM_VQNEG_I 0x03b00780 /* sets flag on overflow */ +# define ARM_VAND 0x02000110 +# define ARM_VBIC 0x02100110 +# define ARM_VORR 0x02200110 +# define ARM_VORN 0x02300110 +# define ARM_VEOR 0x03000110 +# define ARM_VMOVL_S8 0x00080000 +# define ARM_VMOVL_S16 0x00100000 +# define ARM_VMOVL_S32 0x00200000 +# define ARM_VMOVL_I 0x02800a10 +# define ARM_VMOVI 0x02800010 +# define ARM_VMVNI 0x02800030 +# define ARM_VLDR 0x0d100a00 +# define ARM_VSTR 0x0d000a00 +# define ARM_VM 0x0c000a00 +# define ARM_VMOV_ADV_U 0x00800000 /* zero extend */ +# define ARM_VMOV_ADV_8 0x00400000 +# define ARM_VMOV_ADV_16 0x00000020 +# define ARM_VMOV_A_D 0x0e100b10 +# define ARM_VMOV_D_A 0x0e000b10 + +# define vodi(oi,r0) _vodi(_jit,oi,r0) +static void _vodi(jit_state_t*,int,int) maybe_unused; +# define voqi(oi,r0) _voqi(_jit,oi,r0) +static void _voqi(jit_state_t*,int,int) maybe_unused; +# define vo_ss(o,r0,r1) _cc_vo_ss(_jit,ARM_CC_NV,o,r0,r1) +# define cc_vo_ss(cc,o,r0,r1) _cc_vo_ss(_jit,cc,o,r0,r1) +static void _cc_vo_ss(jit_state_t*,int,int,int,int); +# define vo_dd(o,r0,r1) _cc_vo_dd(_jit,ARM_CC_NV,o,r0,r1) +# define cc_vo_dd(cc,o,r0,r1) _cc_vo_dd(_jit,cc,o,r0,r1) +static void _cc_vo_dd(jit_state_t*,int,int,int,int); +# define vo_qd(o,r0,r1) _cc_vo_qd(_jit,ARM_CC_NV,o,r0,r1) +# define cc_vo_qd(cc,o,r0,r1) _cc_vo_qd(_jit,cc,o,r0,r1) +static void _cc_vo_qd(jit_state_t*,int,int,int,int) maybe_unused; +# define vo_qq(o,r0,r1) _cc_vo_qq(_jit,ARM_CC_NV,o,r0,r1) +# define cc_vo_qq(cc,o,r0,r1) _cc_vo_qq(_jit,cc,o,r0,r1) +static void _cc_vo_qq(jit_state_t*,int,int,int,int) maybe_unused; +# define vorr_(o,r0,r1) _cc_vorr_(_jit,ARM_CC_NV,o,r0,r1) +# define cc_vorr_(cc,o,r0,r1) _cc_vorr_(_jit,cc,o,r0,r1) +static void _cc_vorr_(jit_state_t*,int,int,int,int); +# define vors_(o,r0,r1) _cc_vors_(_jit,ARM_CC_NV,o,r0,r1) +# define cc_vors_(cc,o,r0,r1) _cc_vors_(_jit,cc,o,r0,r1) +static void _cc_vors_(jit_state_t*,int,int,int,int); +# define vorv_(o,r0,r1) _cc_vorv_(_jit,ARM_CC_NV,o,r0,r1) +# define cc_vorv_(cc,o,r0,r1) _cc_vorv_(_jit,cc,o,r0,r1) +static void _cc_vorv_(jit_state_t*,int,int,int,int) maybe_unused; +# define vori_(o,r0,r1) _cc_vori_(_jit,ARM_CC_NV,o,r0,r1) +# define cc_vori_(cc,o,r0,r1) _cc_vori_(_jit,cc,o,r0,r1) +static void _cc_vori_(jit_state_t*,int,int,int,int); +# define vorrd(o,r0,r1,r2) _cc_vorrd(_jit,ARM_CC_NV,o,r0,r1,r2) +# define cc_vorrd(cc,o,r0,r1,r2) _cc_vorrd(_jit,cc,o,r0,r1,r2) +static void _cc_vorrd(jit_state_t*,int,int,int,int,int); +# define vosss(o,r0,r1,r2) _cc_vosss(_jit,ARM_CC_NV,o,r0,r1,r2) +# define cc_vosss(cc,o,r0,r1,r2) _cc_vosss(_jit,cc,o,r0,r1,r2) +static void _cc_vosss(jit_state_t*,int,int,int,int,int); +# define voddd(o,r0,r1,r2) _cc_voddd(_jit,ARM_CC_NV,o,r0,r1,r2) +# define cc_voddd(cc,o,r0,r1,r2) _cc_voddd(_jit,cc,o,r0,r1,r2) +static void _cc_voddd(jit_state_t*,int,int,int,int,int); +# define voqdd(o,r0,r1,r2) _cc_voqdd(_jit,ARM_CC_NV,o,r0,r1,r2) +# define cc_voqdd(cc,o,r0,r1,r2) _cc_voqdd(_jit,cc,o,r0,r1,r2) +static void _cc_voqdd(jit_state_t*,int,int,int,int,int) maybe_unused; +# define voqqd(o,r0,r1,r2) _cc_voqqd(_jit,ARM_CC_NV,o,r0,r1,r2) +# define cc_voqqd(cc,o,r0,r1,r2) _cc_voqqd(_jit,cc,o,r0,r1,r2) +static void _cc_voqqd(jit_state_t*,int,int,int,int,int) maybe_unused; +# define voqqq(o,r0,r1,r2) _cc_voqqq(_jit,ARM_CC_NV,o,r0,r1,r2) +# define cc_voqqq(cc,o,r0,r1,r2) _cc_voqqq(_jit,cc,o,r0,r1,r2) +static void _cc_voqqq(jit_state_t*,int,int,int,int,int) maybe_unused; +# define cc_vldst(cc,o,r0,r1,i0) _cc_vldst(_jit,cc,o,r0,r1,i0) +static void _cc_vldst(jit_state_t*,int,int,int,int,int); +# define cc_vorsl(cc,o,r0,r1,i0) _cc_vorsl(_jit,cc,o,r0,r1,i0) +static void _cc_vorsl(jit_state_t*,int,int,int,int,int); +# define CC_VADD_F32(cc,r0,r1,r2) cc_vosss(cc,ARM_VADD_F,r0,r1,r2) +# define VADD_F32(r0,r1,r2) CC_VADD_F32(ARM_CC_AL,r0,r1,r2) +# define CC_VADD_F64(cc,r0,r1,r2) cc_voddd(cc,ARM_VADD_F|ARM_V_F64,r0,r1,r2) +# define VADD_F64(r0,r1,r2) CC_VADD_F64(ARM_CC_AL,r0,r1,r2) +# define CC_VSUB_F32(cc,r0,r1,r2) cc_vosss(cc,ARM_VSUB_F,r0,r1,r2) +# define VSUB_F32(r0,r1,r2) CC_VSUB_F32(ARM_CC_AL,r0,r1,r2) +# define CC_VSUB_F64(cc,r0,r1,r2) cc_voddd(cc,ARM_VSUB_F|ARM_V_F64,r0,r1,r2) +# define VSUB_F64(r0,r1,r2) CC_VSUB_F64(ARM_CC_AL,r0,r1,r2) +# define CC_VMUL_F32(cc,r0,r1,r2) cc_vosss(cc,ARM_VMUL_F,r0,r1,r2) +# define VMUL_F32(r0,r1,r2) CC_VMUL_F32(ARM_CC_AL,r0,r1,r2) +# define CC_VMUL_F64(cc,r0,r1,r2) cc_voddd(cc,ARM_VMUL_F|ARM_V_F64,r0,r1,r2) +# define VMUL_F64(r0,r1,r2) CC_VMUL_F64(ARM_CC_AL,r0,r1,r2) +# define CC_VDIV_F32(cc,r0,r1,r2) cc_vosss(cc,ARM_VDIV_F,r0,r1,r2) +# define VDIV_F32(r0,r1,r2) CC_VDIV_F32(ARM_CC_AL,r0,r1,r2) +# define CC_VDIV_F64(cc,r0,r1,r2) cc_voddd(cc,ARM_VDIV_F|ARM_V_F64,r0,r1,r2) +# define VDIV_F64(r0,r1,r2) CC_VDIV_F64(ARM_CC_AL,r0,r1,r2) +# define CC_VABS_F32(cc,r0,r1) cc_vo_ss(cc,ARM_VABS_F,r0,r1) +# define VABS_F32(r0,r1) CC_VABS_F32(ARM_CC_AL,r0,r1) +# define CC_VABS_F64(cc,r0,r1) cc_vo_dd(cc,ARM_VABS_F|ARM_V_F64,r0,r1) +# define VABS_F64(r0,r1) CC_VABS_F64(ARM_CC_AL,r0,r1) +# define CC_VNEG_F32(cc,r0,r1) cc_vo_ss(cc,ARM_VNEG_F,r0,r1) +# define VNEG_F32(r0,r1) CC_VNEG_F32(ARM_CC_AL,r0,r1) +# define CC_VNEG_F64(cc,r0,r1) cc_vo_dd(cc,ARM_VNEG_F|ARM_V_F64,r0,r1) +# define VNEG_F64(r0,r1) CC_VNEG_F64(ARM_CC_AL,r0,r1) +# define CC_VSQRT_F32(cc,r0,r1) cc_vo_ss(cc,ARM_VSQRT_F,r0,r1) +# define VSQRT_F32(r0,r1) CC_VSQRT_F32(ARM_CC_AL,r0,r1) +# define CC_VSQRT_F64(cc,r0,r1) cc_vo_dd(cc,ARM_VSQRT_F|ARM_V_F64,r0,r1) +# define VSQRT_F64(r0,r1) CC_VSQRT_F64(ARM_CC_AL,r0,r1) +# define CC_VMOV_F32(cc,r0,r1) cc_vo_ss(cc,ARM_VMOV_F,r0,r1) +# define VMOV_F32(r0,r1) CC_VMOV_F32(ARM_CC_AL,r0,r1) +# define CC_VMOV_F64(cc,r0,r1) cc_vo_dd(cc,ARM_VMOV_F|ARM_V_F64,r0,r1) +# define VMOV_F64(r0,r1) CC_VMOV_F64(ARM_CC_AL,r0,r1) +# define CC_VMOV_AA_D(cc,r0,r1,r2) cc_vorrd(cc,ARM_VMOV_AA_D,r0,r1,r2) +# define VMOV_AA_D(r0,r1,r2) CC_VMOV_AA_D(ARM_CC_AL,r0,r1,r2) +# define CC_VMOV_D_AA(cc,r0,r1,r2) cc_vorrd(cc,ARM_VMOV_D_AA,r1,r2,r0) +# define VMOV_D_AA(r0,r1,r2) CC_VMOV_D_AA(ARM_CC_AL,r0,r1,r2) +# define CC_VMOV_A_S(cc,r0,r1) cc_vors_(cc,ARM_VMOV_A_S,r0,r1) +# define VMOV_A_S(r0,r1) CC_VMOV_A_S(ARM_CC_AL,r0,r1) +# define CC_VMOV_S_A(cc,r0,r1) cc_vors_(cc,ARM_VMOV_S_A,r1,r0) +# define VMOV_S_A(r0,r1) CC_VMOV_S_A(ARM_CC_AL,r0,r1) +# define CC_VCMP_F32(cc,r0,r1) cc_vo_ss(cc,ARM_VCMP,r0,r1) +# define VCMP_F32(r0,r1) CC_VCMP_F32(ARM_CC_AL,r0,r1) +# define CC_VCMP_F64(cc,r0,r1) cc_vo_dd(cc,ARM_VCMP|ARM_V_F64,r0,r1) +# define VCMP_F64(r0,r1) CC_VCMP_F64(ARM_CC_AL,r0,r1) +# define CC_VCMPE_F32(cc,r0,r1) cc_vo_ss(cc,ARM_VCMP|ARM_V_E,r0,r1) +# define VCMPE_F32(r0,r1) CC_VCMPE_F32(ARM_CC_AL,r0,r1) +# define CC_VCMPE_F64(cc,r0,r1) cc_vo_dd(cc,ARM_VCMP|ARM_V_E|ARM_V_F64,r0,r1) +# define VCMPE_F64(r0,r1) CC_VCMPE_F64(ARM_CC_AL,r0,r1) +# define CC_VCMPZ_F32(cc,r0) cc_vo_ss(cc,ARM_VCMP|ARM_V_Z,r0,0) +# define VCMPZ_F32(r0) CC_VCMPZ_F32(ARM_CC_AL,r0) +# define CC_VCMPZ_F64(cc,r0) cc_vo_dd(cc,ARM_VCMP|ARM_V_Z|ARM_V_F64,r0,0) +# define VCMPZ_F64(r0) CC_VCMPZ_F64(ARM_CC_AL,r0) +# define CC_VCMPEZ_F32(cc,r0) cc_vo_ss(cc,ARM_VCMP|ARM_V_Z|ARM_V_E,r0,0) +# define VCMPEZ_F32(r0) CC_VCMPEZ_F32(ARM_CC_AL,r0) +# define CC_VCMPEZ_F64(cc,r0) cc_vo_dd(cc,ARM_VCMP|ARM_V_Z|ARM_V_E|ARM_V_F64,r0,0) +# define VCMPEZ_F64(r0) CC_VCMPEZ_F64(ARM_CC_AL,r0) +# define CC_VMRS(cc,r0) cc_vorr_(cc,ARM_VMRS,r0,0) +# define VMRS(r0) CC_VMRS(ARM_CC_AL,r0) +# define CC_VMSR(cc,r0) cc_vorr_(cc,ARM_VMSR,r0,0) +# define VMSR(r0) CC_VMSR(ARM_CC_AL,r0) +# define CC_VCVT_S32_F32(cc,r0,r1) cc_vo_ss(cc,ARM_VCVT_S32_F32,r0,r1) +# define VCVT_S32_F32(r0,r1) CC_VCVT_S32_F32(ARM_CC_AL,r0,r1) +# define CC_VCVT_U32_F32(cc,r0,r1) cc_vo_ss(cc,ARM_VCVT_U32_F32,r0,r1) +# define VCVT_U32_F32(r0,r1) CC_VCVT_U32_F32(ARM_CC_AL,r0,r1) +# define CC_VCVT_S32_F64(cc,r0,r1) cc_vo_ss(cc,ARM_VCVT_S32_F64,r0,r1) +# define VCVT_S32_F64(r0,r1) CC_VCVT_S32_F64(ARM_CC_AL,r0,r1) +# define CC_VCVT_U32_F64(cc,r0,r1) cc_vo_ss(cc,ARM_VCVT_U32_F64,r0,r1) +# define VCVT_U32_F64(r0,r1) CC_VCVT_U32_F64(ARM_CC_AL,r0,r1) +# define CC_VCVT_F32_S32(cc,r0,r1) cc_vo_ss(cc,ARM_VCVT_F32_S32,r0,r1) +# define VCVT_F32_S32(r0,r1) CC_VCVT_F32_S32(ARM_CC_AL,r0,r1) +# define CC_VCVT_F32_U32(cc,r0,r1) cc_vo_ss(cc,ARM_VCVT_F32_U32,r0,r1) +# define VCVT_F32_U32(r0,r1) CC_VCVT_F32_U32(ARM_CC_AL,r0,r1) +# define CC_VCVT_F64_S32(cc,r0,r1) cc_vo_ss(cc,ARM_VCVT_F64_S32,r0,r1) +# define VCVT_F64_S32(r0,r1) CC_VCVT_F64_S32(ARM_CC_AL,r0,r1) +# define CC_VCVT_F64_U32(cc,r0,r1) cc_vo_ss(cc,ARM_VCVT_F64_U32,r0,r1) +# define VCVT_F64_U32(r0,r1) CC_VCVT_F64_U32(ARM_CC_AL,r0,r1) +# define CC_VCVT_F32_F64(cc,r0,r1) cc_vo_ss(cc,ARM_VCVT_F32_F64,r0,r1) +# define VCVT_F32_F64(r0,r1) CC_VCVT_F32_F64(ARM_CC_AL,r0,r1) +# define CC_VCVT_F64_F32(cc,r0,r1) cc_vo_ss(cc,ARM_VCVT_F64_F32,r0,r1) +# define VCVT_F64_F32(r0,r1) CC_VCVT_F64_F32(ARM_CC_AL,r0,r1) +# define CC_VCVTR_S32_F32(cc,r0,r1) cc_vo_ss(cc,ARM_VCVTR_S32_F32,r0,r1) +# define VCVTR_S32_F32(r0,r1) CC_VCVTR_S32_F32(ARM_CC_AL,r0,r1) +# define CC_VCVTR_U32_F32(cc,r0,r1) cc_vo_ss(cc,ARM_VCVTR_U32_F32,r0,r1) +# define VCVTR_U32_F32(r0,r1) CC_VCVTR_U32_F32(ARM_CC_AL,r0,r1) +# define CC_VCVTR_S32_F64(cc,r0,r1) cc_vo_ss(cc,ARM_VCVTR_S32_F64,r0,r1) +# define VCVTR_S32_F64(r0,r1) CC_VCVTR_S32_F64(ARM_CC_AL,r0,r1) +# define CC_VCVTR_U32_F64(cc,r0,r1) cc_vo_ss(cc,ARM_VCVTR_U32_F64,r0,r1) +# define VCVTR_U32_F64(r0,r1) CC_VCVTR_U32_F64(ARM_CC_AL,r0,r1) +# define CC_VLDMIA_F32(cc,r0,r1,i0) cc_vorsl(cc,ARM_VM|ARM_M_L|ARM_M_I,r0,r1,i0) +# define VLDMIA_F32(r0,r1,i0) CC_VLDMIA_F32(ARM_CC_AL,r0,r1,i0) +# define CC_VLDMIA_F64(cc,r0,r1,i0) cc_vorsl(cc,ARM_VM|ARM_M_L|ARM_M_I|ARM_V_F64,r0,r1,i0) +# define VLDMIA_F64(r0,r1,i0) CC_VLDMIA_F64(ARM_CC_AL,r0,r1,i0) +# define CC_VSTMIA_F32(cc,r0,r1,i0) cc_vorsl(cc,ARM_VM|ARM_M_I,r0,r1,i0) +# define VSTMIA_F32(r0,r1,i0) CC_VSTMIA_F32(ARM_CC_AL,r0,r1,i0) +# define CC_VSTMIA_F64(cc,r0,r1,i0) cc_vorsl(cc,ARM_VM|ARM_M_I|ARM_V_F64,r0,r1,i0) +# define VSTMIA_F64(r0,r1,i0) CC_VSTMIA_F64(ARM_CC_AL,r0,r1,i0) +# define CC_VLDMIA_U_F32(cc,r0,r1,i0) cc_vorsl(cc,ARM_VM|ARM_M_L|ARM_M_I|ARM_M_U,r0,r1,i0) +# define VLDMIA_U_F32(r0,r1,i0) CC_VLDMIA_U_F32(ARM_CC_AL,r0,r1,i0) +# define CC_VLDMIA_U_F64(cc,r0,r1,i0) cc_vorsl(cc,ARM_VM|ARM_M_L|ARM_M_I|ARM_M_U|ARM_V_F64,r0,r1,i0) +# define VLDMIA_U_F64(r0,r1,i0) CC_VLDMIA_U_F64(ARM_CC_AL,r0,r1,i0) +# define CC_VSTMIA_U_F32(cc,r0,r1,i0) cc_vorsl(cc,ARM_VM|ARM_M_I|ARM_M_U,r0,r1,i0) +# define VSTMIA_U_F32(r0,r1,i0) CC_VSTMIA_U_F32(ARM_CC_AL,r0,r1,i0) +# define CC_VSTMIA_U_F64(cc,r0,r1,i0) cc_vorsl(cc,ARM_VM|ARM_M_I|ARM_M_U|ARM_V_F64,r0,r1,i0) +# define VSTMIA_U_F64(r0,r1,i0) CC_VSTMIA_U_F64(ARM_CC_AL,r0,r1,i0) +# define CC_VLDMDB_U_F32(cc,r0,r1,i0) cc_vorsl(cc,ARM_VM|ARM_M_L|ARM_M_B|ARM_M_U,r0,r1,i0) +# define VLDMDB_U_F32(r0,r1,i0) CC_VLDMDB_U_F32(ARM_CC_AL,r0,r1,i0) +# define CC_VLDMDB_U_F64(cc,r0,r1,i0) cc_vorsl(cc,ARM_VM|ARM_M_L|ARM_M_B|ARM_M_U|ARM_V_F64,r0,r1,i0) +# define VLDMDB_U_F64(r0,r1,i0) CC_VLDMDB_U_F64(ARM_CC_AL,r0,r1,i0) +# define CC_VSTMDB_U_F32(cc,r0,r1,i0) cc_vorsl(cc,ARM_VM|ARM_M_B|ARM_M_U,r0,r1,i0) +# define VSTMDB_U_F32(r0,r1,i0) CC_VSTMDB_U_F32(ARM_CC_AL,r0,r1,i0) +# define CC_VSTMDB_U_F64(cc,r0,r1,i0) cc_vorsl(cc,ARM_VM|ARM_M_B|ARM_M_U|ARM_V_F64,r0,r1,i0) +# define VSTMDB_U_F64(r0,r1,i0) CC_VSTMDB_U_F64(ARM_CC_AL,r0,r1,i0) +# define CC_VPUSH_F32(cc,r0,i0) CC_VSTMDB_U_F32(cc,_SP_REGNO,r0,i0) +# define VPUSH_F32(r0,i0) CC_VPUSH_F32(ARM_CC_AL,r0,i0) +# define CC_VPUSH_F64(cc,r0,i0) CC_VSTMDB_U_F64(cc,_SP_REGNO,r0,i0) +# define VPUSH_F64(r0,i0) CC_VPUSH_F64(ARM_CC_AL,r0,i0) +# define CC_VPOP_F32(cc,r0,i0) CC_VLDMIA_U_F32(cc,_SP_REGNO,r0,i0) +# define VPOP_F32(r0,i0) CC_VPOP_F32(ARM_CC_AL,r0,i0) +# define CC_VPOP_F64(cc,r0,i0) CC_VLDMIA_U_F64(cc,_SP_REGNO,r0,i0) +# define VPOP_F64(r0,i0) CC_VPOP_F64(ARM_CC_AL,r0,i0) +# define CC_VMOV_A_S8(cc,r0,r1) cc_vorv_(cc,ARM_VMOV_A_D|ARM_VMOV_ADV_8,r0,r1) +# define VMOV_A_S8(r0,r1) CC_VMOV_A_S8(ARM_CC_AL,r0,r1) +# define CC_VMOV_A_U8(cc,r0,r1) cc_vorv_(cc,ARM_VMOV_A_D|ARM_VMOV_ADV_8|ARM_VMOV_ADV_U,r0,r1) +# define VMOV_A_U8(r0,r1) CC_VMOV_A_U8(ARM_CC_AL,r0,r1) +# define CC_VMOV_A_S16(cc,r0,r1) cc_vorv_(cc,ARM_VMOV_A_D|ARM_VMOV_ADV_16,r0,r1) +# define VMOV_A_S16(r0,r1) CC_VMOV_A_S16(ARM_CC_AL,r0,r1) +# define CC_VMOV_A_U16(cc,r0,r1) cc_vorv_(cc,ARM_VMOV_A_D|ARM_VMOV_ADV_16|ARM_VMOV_ADV_U,r0,r1) +# define VMOV_A_U16(r0,r1) CC_VMOV_A_U16(ARM_CC_AL,r0,r1) +# define CC_VMOV_A_S32(cc,r0,r1) cc_vori_(cc,ARM_VMOV_A_D,r0,r1) +# define VMOV_A_S32(r0,r1) CC_VMOV_A_S32(ARM_CC_AL,r0,r1) +# define CC_VMOV_A_U32(cc,r0,r1) cc_vori_(cc,ARM_VMOV_A_D|ARM_VMOV_ADV_U,r0,r1) +# define VMOV_A_U32(r0,r1) CC_VMOV_A_U32(ARM_CC_AL,r0,r1) +# define CC_VMOV_V_I8(cc,r0,r1) cc_vorv_(cc,ARM_VMOV_D_A|ARM_VMOV_ADV_8,r1,r0) +# define VMOV_V_I8(r0,r1) CC_VMOV_V_I8(ARM_CC_AL,r0,r1) +# define CC_VMOV_V_I16(cc,r0,r1) cc_vorv_(cc,ARM_VMOV_D_A|ARM_VMOV_ADV_16,r1,r0) +# define VMOV_V_I16(r0,r1) CC_VMOV_V_I16(ARM_CC_AL,r0,r1) +# define CC_VMOV_V_I32(cc,r0,r1) cc_vori_(cc,ARM_VMOV_D_A,r1,r0) +# define VMOV_V_I32(r0,r1) CC_VMOV_V_I32(ARM_CC_AL,r0,r1) +# define VADD_I8(r0,r1,r2) voddd(ARM_VADD_I,r0,r1,r2) +# define VADDQ_I8(r0,r1,r2) voqqq(ARM_VADD_I|ARM_V_Q,r0,r1,r2) +# define VADD_I16(r0,r1,r2) voddd(ARM_VADD_I|ARM_V_I16,r0,r1,r2) +# define VADDQ_I16(r0,r1,r2) voqqq(ARM_VADD_I|ARM_V_I16|ARM_V_Q,r0,r1,r2) +# define VADD_I32(r0,r1,r2) voddd(ARM_VADD_I|ARM_V_I32,r0,r1,r2) +# define VADDQ_I32(r0,r1,r2) voqqq(ARM_VADD_I|ARM_V_I32|ARM_V_Q,r0,r1,r2) +# define VADD_I64(r0,r1,r2) voddd(ARM_VADD_I|ARM_V_I64,r0,r1,r2) +# define VADDQ_I64(r0,r1,r2) voqqq(ARM_VADD_I|ARM_V_I64|ARM_V_Q,r0,r1,r2) +# define VQADD_S8(r0,r1,r2) voddd(ARM_VQADD_I,r0,r1,r2) +# define VQADDQ_S8(r0,r1,r2) voqqq(ARM_VQADD_I|ARM_V_Q,r0,r1,r2) +# define VQADD_U8(r0,r1,r2) voddd(ARM_VQADD_I|ARM_V_U,r0,r1,r2) +# define VQADDQ_U8(r0,r1,r2) voqqq(ARM_VQADD_I|ARM_V_U|ARM_V_Q,r0,r1,r2) +# define VQADD_S16(r0,r1,r2) voddd(ARM_VQADD_I|ARM_V_I16,r0,r1,r2) +# define VQADDQ_S16(r0,r1,r2) voqqq(ARM_VQADD_I|ARM_V_I16|ARM_V_Q,r0,r1,r2) +# define VQADD_U16(r0,r1,r2) voddd(ARM_VQADD_I|ARM_V_I16|ARM_V_U,r0,r1,r2) +# define VQADDQ_U16(r0,r1,r2) voqqq(ARM_VQADD_I|ARM_V_I16|ARM_V_U|ARM_V_Q,r0,r1,r2) +# define VQADD_S32(r0,r1,r2) voddd(ARM_VQADD_I|ARM_V_I32,r0,r1,r2) +# define VQADDQ_S32(r0,r1,r2) voqqq(ARM_VQADD_I|ARM_V_I32|ARM_V_Q,r0,r1,r2) +# define VQADD_U32(r0,r1,r2) voddd(ARM_VQADD_I|ARM_V_I32|ARM_V_U,r0,r1,r2) +# define VQADDQ_U32(r0,r1,r2) voqqq(ARM_VQADD_I|ARM_V_I32|ARM_V_U|ARM_V_Q,r0,r1,r2) +# define VQADD_S64(r0,r1,r2) voddd(ARM_VQADD_I|ARM_V_I64,r0,r1,r2) +# define VQADDQ_S64(r0,r1,r2) voqqq(ARM_VQADD_I|ARM_V_I64|ARM_V_Q,r0,r1,r2) +# define VQADD_U64(r0,r1,r2) voddd(ARM_VQADD_I|ARM_V_I64|ARM_V_U,r0,r1,r2) +# define VQADDQ_U64(r0,r1,r2) voqqq(ARM_VQADD_I|ARM_V_I64|ARM_V_U|ARM_V_Q,r0,r1,r2) +# define VADDL_S8(r0,r1,r2) voqdd(ARM_VADDL_I,r0,r1,r2) +# define VADDL_U8(r0,r1,r2) voqdd(ARM_VADDL_I|ARM_V_U,r0,r1,r2) +# define VADDL_S16(r0,r1,r2) voqdd(ARM_VADDL_I|ARM_V_I16,r0,r1,r2) +# define VADDL_U16(r0,r1,r2) voqdd(ARM_VADDL_I|ARM_V_I16|ARM_V_U,r0,r1,r2) +# define VADDL_S32(r0,r1,r2) voqdd(ARM_VADDL_I|ARM_V_I32,r0,r1,r2) +# define VADDL_U32(r0,r1,r2) voqdd(ARM_VADDL_I|ARM_V_I32|ARM_V_U,r0,r1,r2) +# define VADDW_S8(r0,r1,r2) voqqd(ARM_VADDW_I,r0,r1,r2) +# define VADDW_U8(r0,r1,r2) voqqd(ARM_VADDW_I|ARM_V_U,r0,r1,r2) +# define VADDW_S16(r0,r1,r2) voqqd(ARM_VADDW_I|ARM_V_I16,r0,r1,r2) +# define VADDW_U16(r0,r1,r2) voqqd(ARM_VADDW_I|ARM_V_I16|ARM_V_U,r0,r1,r2) +# define VADDW_S32(r0,r1,r2) voqqd(ARM_VADDW_I|ARM_V_I32,r0,r1,r2) +# define VADDW_U32(r0,r1,r2) voqqd(ARM_VADDW_I|ARM_V_I32|ARM_V_U,r0,r1,r2) +# define VSUB_I8(r0,r1,r2) voddd(ARM_VSUB_I,r0,r1,r2) +# define VSUBQ_I8(r0,r1,r2) voqqq(ARM_VSUB_I|ARM_V_Q,r0,r1,r2) +# define VSUB_I16(r0,r1,r2) voddd(ARM_VSUB_I|ARM_V_I16,r0,r1,r2) +# define VSUBQ_I16(r0,r1,r2) voqqq(ARM_VSUB_I|ARM_V_I16|ARM_V_Q,r0,r1,r2) +# define VSUB_I32(r0,r1,r2) voddd(ARM_VSUB_I|ARM_V_I32,r0,r1,r2) +# define VSUBQ_I32(r0,r1,r2) voqqq(ARM_VSUB_I|ARM_V_I32|ARM_V_Q,r0,r1,r2) +# define VSUB_I64(r0,r1,r2) voddd(ARM_VSUB_I|ARM_V_I64,r0,r1,r2) +# define VSUBQ_I64(r0,r1,r2) voqqq(ARM_VSUB_I|ARM_V_I64|ARM_V_Q,r0,r1,r2) +# define VQSUB_S8(r0,r1,r2) voddd(ARM_VQSUB_I,r0,r1,r2) +# define VQSUBQ_S8(r0,r1,r2) voqqq(ARM_VQSUB_I|ARM_V_Q,r0,r1,r2) +# define VQSUB_U8(r0,r1,r2) voddd(ARM_VQSUB_I|ARM_V_U,r0,r1,r2) +# define VQSUBQ_U8(r0,r1,r2) voqqq(ARM_VQSUB_I|ARM_V_U|ARM_V_Q,r0,r1,r2) +# define VQSUB_S16(r0,r1,r2) voddd(ARM_VQSUB_I|ARM_V_I16,r0,r1,r2) +# define VQSUBQ_S16(r0,r1,r2) voqqq(ARM_VQSUB_I|ARM_V_I16|ARM_V_Q,r0,r1,r2) +# define VQSUB_U16(r0,r1,r2) voddd(ARM_VQSUB_I|ARM_V_I16|ARM_V_U,r0,r1,r2) +# define VQSUBQ_U16(r0,r1,r2) voqqq(ARM_VQSUB_I|ARM_V_I16|ARM_V_U|ARM_V_Q,r0,r1,r2) +# define VQSUB_S32(r0,r1,r2) voddd(ARM_VQSUB_I|ARM_V_I32,r0,r1,r2) +# define VQSUBQ_S32(r0,r1,r2) voqqq(ARM_VQSUB_I|ARM_V_I32|ARM_V_Q,r0,r1,r2) +# define VQSUB_U32(r0,r1,r2) voddd(ARM_VQSUB_I|ARM_V_I32|ARM_V_U,r0,r1,r2) +# define VQSUBQ_U32(r0,r1,r2) voqqq(ARM_VQSUB_I|ARM_V_I32|ARM_V_U|ARM_V_Q,r0,r1,r2) +# define VQSUB_S64(r0,r1,r2) voddd(ARM_VQSUB_I|ARM_V_I64,r0,r1,r2) +# define VQSUBQ_S64(r0,r1,r2) voqqq(ARM_VQSUB_I|ARM_V_I64|ARM_V_Q,r0,r1,r2) +# define VQSUB_U64(r0,r1,r2) voddd(ARM_VQSUB_I|ARM_V_I64|ARM_V_U,r0,r1,r2) +# define VQSUBQ_U64(r0,r1,r2) voqqq(ARM_VQSUB_I|ARM_V_I64|ARM_V_U|ARM_V_Q,r0,r1,r2) +# define VSUBL_S8(r0,r1,r2) voqdd(ARM_VSUBL_I,r0,r1,r2) +# define VSUBL_U8(r0,r1,r2) voqdd(ARM_VSUBL_I|ARM_V_U,r0,r1,r2) +# define VSUBL_S16(r0,r1,r2) voqdd(ARM_VSUBL_I|ARM_V_I16,r0,r1,r2) +# define VSUBL_U16(r0,r1,r2) voqdd(ARM_VSUBL_I|ARM_V_I16|ARM_V_U,r0,r1,r2) +# define VSUBL_S32(r0,r1,r2) voqdd(ARM_VSUBL_I|ARM_V_I32,r0,r1,r2) +# define VSUBL_U32(r0,r1,r2) voqdd(ARM_VSUBL_I|ARM_V_I32|ARM_V_U,r0,r1,r2) +# define VSUBW_S8(r0,r1,r2) voqqd(ARM_VSUBW_I,r0,r1,r2) +# define VSUBW_U8(r0,r1,r2) voqqd(ARM_VSUBW_I|ARM_V_U,r0,r1,r2) +# define VSUBW_S16(r0,r1,r2) voqqd(ARM_VSUBW_I|ARM_V_I16,r0,r1,r2) +# define VSUBW_U16(r0,r1,r2) voqqd(ARM_VSUBW_I|ARM_V_I16|ARM_V_U,r0,r1,r2) +# define VSUBW_S32(r0,r1,r2) voqqd(ARM_VSUBW_I|ARM_V_I32,r0,r1,r2) +# define VSUBW_U32(r0,r1,r2) voqqd(ARM_VSUBW_I|ARM_V_I32|ARM_V_U,r0,r1,r2) +# define VMUL_I8(r0,r1,r2) voddd(ARM_VMUL_I,r0,r1,r2) +# define VMULQ_I8(r0,r1,r2) voqqq(ARM_VMUL_I|ARM_V_Q,r0,r1,r2) +# define VMUL_I16(r0,r1,r2) voddd(ARM_VMUL_I|ARM_V_I16,r0,r1,r2) +# define VMULQ_I16(r0,r1,r2) voqqq(ARM_VMUL_I|ARM_V_Q|ARM_V_I16,r0,r1,r2) +# define VMUL_I32(r0,r1,r2) voddd(ARM_VMUL_I|ARM_V_I32,r0,r1,r2) +# define VMULQ_I32(r0,r1,r2) voqqq(ARM_VMUL_I|ARM_V_Q|ARM_V_I32,r0,r1,r2) +# define VMULL_S8(r0,r1,r2) voddd(ARM_VMULL_I,r0,r1,r2) +# define VMULL_U8(r0,r1,r2) voqqq(ARM_VMULL_I|ARM_V_U,r0,r1,r2) +# define VMULL_S16(r0,r1,r2) voddd(ARM_VMULL_I|ARM_V_I16,r0,r1,r2) +# define VMULL_U16(r0,r1,r2) voqqq(ARM_VMULL_I|ARM_V_U|ARM_V_I16,r0,r1,r2) +# define VMULL_S32(r0,r1,r2) voddd(ARM_VMULL_I|ARM_V_I32,r0,r1,r2) +# define VMULL_U32(r0,r1,r2) voqqq(ARM_VMULL_I|ARM_V_U|ARM_V_I32,r0,r1,r2) +# define VABS_S8(r0,r1) vo_dd(ARM_VABS_I,r0,r1) +# define VABSQ_S8(r0,r1) vo_qq(ARM_VABS_I|ARM_V_Q,r0,r1) +# define VABS_S16(r0,r1) vo_dd(ARM_VABS_I|ARM_V_S16,r0,r1) +# define VABSQ_S16(r0,r1) vo_qq(ARM_VABS_I|ARM_V_S16|ARM_V_Q,r0,r1) +# define VABS_S32(r0,r1) vo_dd(ARM_VABS_I|ARM_V_S32,r0,r1) +# define VABSQ_S32(r0,r1) vo_qq(ARM_VABS_I|ARM_V_S32|ARM_V_Q,r0,r1) +# define VQABS_S8(r0,r1) vo_dd(ARM_VQABS_I,r0,r1) +# define VQABSQ_S8(r0,r1) vo_qq(ARM_VQABS_I|ARM_V_Q,r0,r1) +# define VQABS_S16(r0,r1) vo_dd(ARM_VQABS_I|ARM_V_S16,r0,r1) +# define VQABSQ_S16(r0,r1) vo_qq(ARM_VQABS_I|ARM_V_S16|ARM_V_Q,r0,r1) +# define VQABS_S32(r0,r1) vo_dd(ARM_VQABS_I|ARM_V_S32,r0,r1) +# define VQABSQ_S32(r0,r1) vo_qq(ARM_VQABS_I|ARM_V_S32|ARM_V_Q,r0,r1) +# define VNEG_S8(r0,r1) vo_dd(ARM_VNEG_I,r0,r1) +# define VNEGQ_S8(r0,r1) vo_qq(ARM_VNEG_I|ARM_V_Q,r0,r1) +# define VNEG_S16(r0,r1) vo_dd(ARM_VNEG_I|ARM_V_S16,r0,r1) +# define VNEGQ_S16(r0,r1) vo_qq(ARM_VNEG_I|ARM_V_S16|ARM_V_Q,r0,r1) +# define VNEG_S32(r0,r1) vo_dd(ARM_VNEG_I|ARM_V_S32,r0,r1) +# define VNEGQ_S32(r0,r1) vo_qq(ARM_VNEG_I|ARM_V_S32|ARM_V_Q,r0,r1) +# define VQNEG_S8(r0,r1) vo_dd(ARM_VQNEG_I,r0,r1) +# define VQNEGQ_S8(r0,r1) vo_qq(ARM_VQNEG_I|ARM_V_Q,r0,r1) +# define VQNEG_S16(r0,r1) vo_dd(ARM_VQNEG_I|ARM_V_S16,r0,r1) +# define VQNEGQ_S16(r0,r1) vo_qq(ARM_VQNEG_I|ARM_V_S16|ARM_V_Q,r0,r1) +# define VQNEG_S32(r0,r1) vo_dd(ARM_VQNEG_I|ARM_V_S32,r0,r1) +# define VQNEGQ_S32(r0,r1) vo_qq(ARM_VQNEG_I|ARM_V_S32|ARM_V_Q,r0,r1) +# define VAND(r0,r1,r2) voddd(ARM_VAND,r0,r1,r2) +# define VANDQ(r0,r1,r2) voqqq(ARM_VAND|ARM_V_Q,r0,r1,r2) +# define VBIC(r0,r1,r2) voddd(ARM_VBIC,r0,r1,r2) +# define VBICQ(r0,r1,r2) voqqq(ARM_VBIC|ARM_V_Q,r0,r1,r2) +# define VORR(r0,r1,r2) voddd(ARM_VORR,r0,r1,r2) +# define VORRQ(r0,r1,r2) voqqq(ARM_VORR|ARM_V_Q,r0,r1,r2) +# define VORN(r0,r1,r2) voddd(ARM_VORN,r0,r1,r2) +# define VORNQ(r0,r1,r2) voqqq(ARM_VORN|ARM_V_Q,r0,r1,r2) +# define VEOR(r0,r1,r2) voddd(ARM_VEOR,r0,r1,r2) +# define VEORQ(r0,r1,r2) voqqq(ARM_VEOR|ARM_V_Q,r0,r1,r2) +# define VMOV(r0,r1) VORR(r0,r1,r1) +# define VMOVQ(r0,r1) VORRQ(r0,r1,r1) +# define VMOVL_S8(r0,r1) vo_qd(ARM_VMOVL_I|ARM_VMOVL_S8,r0,r1) +# define VMOVL_U8(r0,r1) vo_qd(ARM_VMOVL_I|ARM_V_U|ARM_VMOVL_S8,r0,r1) +# define VMOVL_S16(r0,r1) vo_qd(ARM_VMOVL_I|ARM_VMOVL_S16,r0,r1) +# define VMOVL_U16(r0,r1) vo_qd(ARM_VMOVL_I|ARM_V_U|ARM_VMOVL_S16,r0,r1) +# define VMOVL_S32(r0,r1) vo_qd(ARM_VMOVL_I|ARM_VMOVL_S32,r0,r1) +# define VMOVL_U32(r0,r1) vo_qd(ARM_VMOVL_I|ARM_V_U|ARM_VMOVL_S32,r0,r1) +/* "oi" should be the result of encode_vfp_double */ +# define VIMM(oi,r0) vodi(oi,r0) +# define VIMMQ(oi,r0) voqi(oi|ARM_V_Q,r0) +/* index is multipled by four */ +# define CC_VLDRN_F32(cc,r0,r1,i0) cc_vldst(cc,ARM_VLDR,r0,r1,i0) +# define VLDRN_F32(r0,r1,i0) CC_VLDRN_F32(ARM_CC_AL,r0,r1,i0) +# define CC_VLDR_F32(cc,r0,r1,i0) cc_vldst(cc,ARM_VLDR|ARM_P,r0,r1,i0) +# define VLDR_F32(r0,r1,i0) CC_VLDR_F32(ARM_CC_AL,r0,r1,i0) +# define CC_VLDRN_F64(cc,r0,r1,i0) cc_vldst(cc,ARM_VLDR|ARM_V_F64,r0,r1,i0) +# define VLDRN_F64(r0,r1,i0) CC_VLDRN_F64(ARM_CC_AL,r0,r1,i0) +# define CC_VLDR_F64(cc,r0,r1,i0) cc_vldst(cc,ARM_VLDR|ARM_V_F64|ARM_P,r0,r1,i0) +# define VLDR_F64(r0,r1,i0) CC_VLDR_F64(ARM_CC_AL,r0,r1,i0) +# define CC_VSTRN_F32(cc,r0,r1,i0) cc_vldst(cc,ARM_VSTR,r0,r1,i0) +# define VSTRN_F32(r0,r1,i0) CC_VSTRN_F32(ARM_CC_AL,r0,r1,i0) +# define CC_VSTR_F32(cc,r0,r1,i0) cc_vldst(cc,ARM_VSTR|ARM_P,r0,r1,i0) +# define VSTR_F32(r0,r1,i0) CC_VSTR_F32(ARM_CC_AL,r0,r1,i0) +# define CC_VSTRN_F64(cc,r0,r1,i0) cc_vldst(cc,ARM_VSTR|ARM_V_F64,r0,r1,i0) +# define VSTRN_F64(r0,r1,i0) CC_VSTRN_F64(ARM_CC_AL,r0,r1,i0) +# define CC_VSTR_F64(cc,r0,r1,i0) cc_vldst(cc,ARM_VSTR|ARM_V_F64|ARM_P,r0,r1,i0) +# define VSTR_F64(r0,r1,i0) CC_VSTR_F64(ARM_CC_AL,r0,r1,i0) +# define vfp_movr_f(r0,r1) _vfp_movr_f(_jit,r0,r1) +static void _vfp_movr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define vfp_movr_d(r0,r1) _vfp_movr_d(_jit,r0,r1) +static void _vfp_movr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define vfp_movi_f(r0,i0) _vfp_movi_f(_jit,r0,i0) +static void _vfp_movi_f(jit_state_t*,jit_int32_t,jit_float32_t); +# define vfp_movi_d(r0,i0) _vfp_movi_d(_jit,r0,i0) +static void _vfp_movi_d(jit_state_t*,jit_int32_t,jit_float64_t); +# define vfp_extr_f(r0,r1) _vfp_extr_f(_jit,r0,r1) +static void _vfp_extr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define vfp_extr_d(r0,r1) _vfp_extr_d(_jit,r0,r1) +static void _vfp_extr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define vfp_extr_d_f(r0,r1) _vfp_extr_d_f(_jit,r0,r1) +static void _vfp_extr_d_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define vfp_extr_f_d(r0,r1) _vfp_extr_f_d(_jit,r0,r1) +static void _vfp_extr_f_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define vfp_truncr_f_i(r0,r1) _vfp_truncr_f_i(_jit,r0,r1) +static void _vfp_truncr_f_i(jit_state_t*,jit_int32_t,jit_int32_t); +# define vfp_truncr_d_i(r0,r1) _vfp_truncr_d_i(_jit,r0,r1) +static void _vfp_truncr_d_i(jit_state_t*,jit_int32_t,jit_int32_t); +# define vfp_absr_f(r0,r1) VABS_F32(r0,r1) +# define vfp_absr_d(r0,r1) VABS_F64(r0,r1) +# define vfp_negr_f(r0,r1) VNEG_F32(r0,r1) +# define vfp_negr_d(r0,r1) VNEG_F64(r0,r1) +# define vfp_sqrtr_f(r0,r1) VSQRT_F32(r0,r1) +# define vfp_sqrtr_d(r0,r1) VSQRT_F64(r0,r1) +# define vfp_addr_f(r0,r1,r2) VADD_F32(r0,r1,r2) +# define vfp_addi_f(r0,r1,i0) _vfp_addi_f(_jit,r0,r1,i0) +static void _vfp_addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_addr_d(r0,r1,r2) VADD_F64(r0,r1,r2) +# define vfp_addi_d(r0,r1,i0) _vfp_addi_d(_jit,r0,r1,i0) +static void _vfp_addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_subr_f(r0,r1,r2) VSUB_F32(r0,r1,r2) +# define vfp_subi_f(r0,r1,i0) _vfp_subi_f(_jit,r0,r1,i0) +static void _vfp_subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_subr_d(r0,r1,r2) VSUB_F64(r0,r1,r2) +# define vfp_subi_d(r0,r1,i0) _vfp_subi_d(_jit,r0,r1,i0) +static void _vfp_subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_rsbr_f(r0,r1,r2) vfp_subr_f(r0,r2,r1) +# define vfp_rsbi_f(r0,r1,i0) _vfp_rsbi_f(_jit,r0,r1,i0) +static void _vfp_rsbi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_rsbr_d(r0,r1,r2) vfp_subr_d(r0,r2,r1) +# define vfp_rsbi_d(r0,r1,i0) _vfp_rsbi_d(_jit,r0,r1,i0) +static void _vfp_rsbi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_mulr_f(r0,r1,r2) VMUL_F32(r0,r1,r2) +# define vfp_muli_f(r0,r1,i0) _vfp_muli_f(_jit,r0,r1,i0) +static void _vfp_muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_mulr_d(r0,r1,r2) VMUL_F64(r0,r1,r2) +# define vfp_muli_d(r0,r1,i0) _vfp_muli_d(_jit,r0,r1,i0) +static void _vfp_muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_divr_f(r0,r1,r2) VDIV_F32(r0,r1,r2) +# define vfp_divi_f(r0,r1,i0) _vfp_divi_f(_jit,r0,r1,i0) +static void _vfp_divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_divr_d(r0,r1,r2) VDIV_F64(r0,r1,r2) +# define vfp_divi_d(r0,r1,i0) _vfp_divi_d(_jit,r0,r1,i0) +static void _vfp_divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_cmp_f(r0,r1) _vfp_cmp_f(_jit,r0,r1) +static void _vfp_cmp_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define vfp_cmp_d(r0,r1) _vfp_cmp_d(_jit,r0,r1) +static void _vfp_cmp_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define vcmp01_x(c0,c1,r0) _vcmp01_x(_jit,c0,c1,r0) +static void _vcmp01_x(jit_state_t*,int,int,jit_int32_t); +# define vcmp01_f(c0,c1,r0,r1,r2) _vcmp01_f(_jit,c0,c1,r0,r1,r2) +static void _vcmp01_f(jit_state_t*,int,int,jit_int32_t,jit_int32_t,jit_int32_t); +# define vcmp01_d(c0,c1,r0,r1,r2) _vcmp01_d(_jit,c0,c1,r0,r1,r2) +static void _vcmp01_d(jit_state_t*,int,int,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_ltr_f(r0,r1,r2) vcmp01_f(ARM_CC_PL,ARM_CC_MI,r0,r1,r2) +# define vfp_lti_f(r0,r1,i0) _vfp_lti_f(_jit,r0,r1,i0) +static void _vfp_lti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_ltr_d(r0,r1,r2) vcmp01_d(ARM_CC_PL,ARM_CC_MI,r0,r1,r2) +# define vfp_lti_d(r0,r1,i0) _vfp_lti_d(_jit,r0,r1,i0) +static void _vfp_lti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_ler_f(r0,r1,r2) vcmp01_f(ARM_CC_HS,ARM_CC_LS,r0,r1,r2) +# define vfp_lei_f(r0,r1,i0) _vfp_lei_f(_jit,r0,r1,i0) +static void _vfp_lei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_ler_d(r0,r1,r2) vcmp01_d(ARM_CC_HS,ARM_CC_LS,r0,r1,r2) +# define vfp_lei_d(r0,r1,i0) _vfp_lei_d(_jit,r0,r1,i0) +static void _vfp_lei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_eqr_f(r0,r1,r2) vcmp01_f(ARM_CC_NE,ARM_CC_EQ,r0,r1,r2) +# define vfp_eqi_f(r0,r1,i0) _vfp_eqi_f(_jit,r0,r1,i0) +static void _vfp_eqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_eqr_d(r0,r1,r2) vcmp01_d(ARM_CC_NE,ARM_CC_EQ,r0,r1,r2) +# define vfp_eqi_d(r0,r1,i0) _vfp_eqi_d(_jit,r0,r1,i0) +static void _vfp_eqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_ger_f(r0,r1,r2) vcmp01_f(ARM_CC_LT,ARM_CC_GE,r0,r1,r2) +# define vfp_gei_f(r0,r1,i0) _vfp_gei_f(_jit,r0,r1,i0) +static void _vfp_gei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_ger_d(r0,r1,r2) vcmp01_d(ARM_CC_LT,ARM_CC_GE,r0,r1,r2) +# define vfp_gei_d(r0,r1,i0) _vfp_gei_d(_jit,r0,r1,i0) +static void _vfp_gei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_gtr_f(r0,r1,r2) vcmp01_f(ARM_CC_LE,ARM_CC_GT,r0,r1,r2) +# define vfp_gti_f(r0,r1,i0) _vfp_gti_f(_jit,r0,r1,i0) +static void _vfp_gti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_gtr_d(r0,r1,r2) vcmp01_d(ARM_CC_LE,ARM_CC_GT,r0,r1,r2) +# define vfp_gti_d(r0,r1,i0) _vfp_gti_d(_jit,r0,r1,i0) +static void _vfp_gti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_ner_f(r0,r1,r2) vcmp01_f(ARM_CC_EQ,ARM_CC_NE,r0,r1,r2) +# define vfp_nei_f(r0,r1,i0) _vfp_nei_f(_jit,r0,r1,i0) +static void _vfp_nei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_ner_d(r0,r1,r2) vcmp01_d(ARM_CC_EQ,ARM_CC_NE,r0,r1,r2) +# define vfp_nei_d(r0,r1,i0) _vfp_nei_d(_jit,r0,r1,i0) +static void _vfp_nei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vcmp10_x(c0,r0) _vcmp10_x(_jit,c0,r0) +static void _vcmp10_x(jit_state_t*,int,jit_int32_t); +# define vcmp_10_f(c0,r0,r1,r2) _vcmp_10_f(_jit,c0,r0,r1,r2) +static void _vcmp_10_f(jit_state_t*,int,jit_int32_t,jit_int32_t,jit_int32_t); +# define vcmp_10_d(c0,r0,r1,r2) _vcmp_10_d(_jit,c0,r0,r1,r2) +static void _vcmp_10_d(jit_state_t*,int,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_unltr_f(r0,r1,r2) vcmp_10_f(ARM_CC_GE,r0,r1,r2) +# define vfp_unlti_f(r0,r1,i0) _vfp_unlti_f(_jit,r0,r1,i0) +static void _vfp_unlti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_unltr_d(r0,r1,r2) vcmp_10_d(ARM_CC_GE,r0,r1,r2) +# define vfp_unlti_d(r0,r1,i0) _vfp_unlti_d(_jit,r0,r1,i0) +static void _vfp_unlti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_unler_f(r0,r1,r2) vcmp_10_f(ARM_CC_GT,r0,r1,r2) +# define vfp_unlei_f(r0,r1,i0) _vfp_unlei_f(_jit,r0,r1,i0) +static void _vfp_unlei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_unler_d(r0,r1,r2) vcmp_10_d(ARM_CC_GT,r0,r1,r2) +# define vfp_unlei_d(r0,r1,i0) _vfp_unlei_d(_jit,r0,r1,i0) +static void _vfp_unlei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_uneqr_x(r0) _vfp_uneqr_x(_jit,r0) +static void _vfp_uneqr_x(jit_state_t*,jit_int32_t); +# define vfp_uneqr_f(r0,r1,r2) _vfp_uneqr_f(_jit,r0,r1,r2) +static void _vfp_uneqr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_uneqi_f(r0,r1,i0) _vfp_uneqi_f(_jit,r0,r1,i0) +static void _vfp_uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_uneqr_d(r0,r1,r2) _vfp_uneqr_d(_jit,r0,r1,r2) +static void _vfp_uneqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_uneqi_d(r0,r1,i0) _vfp_uneqi_d(_jit,r0,r1,i0) +static void _vfp_uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vcmp_01_x(c0,r0) _vcmp_01_x(_jit,c0,r0) +static void _vcmp_01_x(jit_state_t*,int,jit_int32_t); +# define vcmp_01_f(c0,r0,r1,r2) _vcmp_01_f(_jit,c0,r0,r1,r2) +static void _vcmp_01_f(jit_state_t*,int,jit_int32_t,jit_int32_t,jit_int32_t); +# define vcmp_01_d(c0,r0,r1,r2) _vcmp_01_d(_jit,c0,r0,r1,r2) +static void _vcmp_01_d(jit_state_t*,int,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_unger_f(r0,r1,r2) vcmp_01_f(ARM_CC_CS,r0,r1,r2) +# define vfp_ungei_f(r0,r1,i0) _vfp_ungei_f(_jit,r0,r1,i0) +static void _vfp_ungei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_unger_d(r0,r1,r2) vcmp_01_d(ARM_CC_CS,r0,r1,r2) +# define vfp_ungei_d(r0,r1,i0) _vfp_ungei_d(_jit,r0,r1,i0) +static void _vfp_ungei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_ungtr_f(r0,r1,r2) vcmp_01_f(ARM_CC_HI,r0,r1,r2) +# define vfp_ungti_f(r0,r1,i0) _vfp_ungti_f(_jit,r0,r1,i0) +static void _vfp_ungti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_ungtr_d(r0,r1,r2) vcmp_01_d(ARM_CC_HI,r0,r1,r2) +# define vfp_ungti_d(r0,r1,i0) _vfp_ungti_d(_jit,r0,r1,i0) +static void _vfp_ungti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_ltgtr_x(r0) _vfp_ltgtr_x(_jit,r0) +static void _vfp_ltgtr_x(jit_state_t*,jit_int32_t); +# define vfp_ltgtr_f(r0,r1,r2) _vfp_ltgtr_f(_jit,r0,r1,r2) +static void _vfp_ltgtr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_ltgti_f(r0,r1,i0) _vfp_ltgti_f(_jit,r0,r1,i0) +static void _vfp_ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_ltgtr_d(r0,r1,r2) _vfp_ltgtr_d(_jit,r0,r1,r2) +static void _vfp_ltgtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_ltgti_d(r0,r1,i0) _vfp_ltgti_d(_jit,r0,r1,i0) +static void _vfp_ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_ordr_f(r0,r1,r2) _vfp_ordr_f(_jit,r0,r1,r2) +static void _vfp_ordr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_ordi_f(r0,r1,i0) _vfp_ordi_f(_jit,r0,r1,i0) +static void _vfp_ordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_ordr_d(r0,r1,r2) _vfp_ordr_d(_jit,r0,r1,r2) +static void _vfp_ordr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_ordi_d(r0,r1,i0) _vfp_ordi_d(_jit,r0,r1,i0) +static void _vfp_ordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vfp_unordr_f(r0,r1,r2) _vfp_unordr_f(_jit,r0,r1,r2) +static void _vfp_unordr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_unordi_f(r0,r1,i0) _vfp_unordi_f(_jit,r0,r1,i0) +static void _vfp_unordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t); +# define vfp_unordr_d(r0,r1,r2) _vfp_unordr_d(_jit,r0,r1,r2) +static void _vfp_unordr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_unordi_d(r0,r1,i0) _vfp_unordi_d(_jit,r0,r1,i0) +static void _vfp_unordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t); +# define vbcmp_x(cc,i0) _vbcmp_x(_jit,cc,i0) +static jit_word_t _vbcmp_x(jit_state_t*,int,jit_word_t); +# define vbcmp_f(cc,i0,r0,r1) _vbcmp_f(_jit,cc,i0,r0,r1) +static jit_word_t +_vbcmp_f(jit_state_t*,int,jit_word_t,jit_int32_t,jit_int32_t); +# define vbcmp_x(cc,i0) _vbcmp_x(_jit,cc,i0) +static jit_word_t _vbcmp_x(jit_state_t*,int,jit_word_t); +# define vbcmp_d(cc,i0,r0,r1) _vbcmp_d(_jit,cc,i0,r0,r1) +static jit_word_t +_vbcmp_d(jit_state_t*,int,jit_word_t,jit_int32_t,jit_int32_t); +# define vfp_bltr_f(i0,r0,r1) vbcmp_f(ARM_CC_MI,i0,r0,r1) +# define vfp_blti_f(i0,r0,i1) _vfp_blti_f(_jit,i0,r0,i1) +static jit_word_t _vfp_blti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_bltr_d(i0,r0,r1) vbcmp_d(ARM_CC_MI,i0,r0,r1) +static jit_word_t _vfp_blti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vfp_blti_d(i0,r0,i1) _vfp_blti_d(_jit,i0,r0,i1) +# define vfp_bler_f(i0,r0,r1) vbcmp_f(ARM_CC_LS,i0,r0,r1) +# define vfp_blei_f(i0,r0,i1) _vfp_blei_f(_jit,i0,r0,i1) +static jit_word_t _vfp_blei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_bler_d(i0,r0,r1) vbcmp_d(ARM_CC_LS,i0,r0,r1) +# define vfp_blei_d(i0,r0,i1) _vfp_blei_d(_jit,i0,r0,i1) +static jit_word_t _vfp_blei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vfp_beqr_f(i0,r0,r1) vbcmp_f(ARM_CC_EQ,i0,r0,r1) +# define vfp_beqi_f(i0,r0,i1) _vfp_beqi_f(_jit,i0,r0,i1) +static jit_word_t _vfp_beqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_beqr_d(i0,r0,r1) vbcmp_d(ARM_CC_EQ,i0,r0,r1) +# define vfp_beqi_d(i0,r0,i1) _vfp_beqi_d(_jit,i0,r0,i1) +static jit_word_t _vfp_beqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vfp_bger_f(i0,r0,r1) vbcmp_f(ARM_CC_GE,i0,r0,r1) +# define vfp_bgei_f(i0,r0,i1) _vfp_bgei_f(_jit,i0,r0,i1) +static jit_word_t _vfp_bgei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_bger_d(i0,r0,r1) vbcmp_d(ARM_CC_GE,i0,r0,r1) +# define vfp_bgei_d(i0,r0,i1) _vfp_bgei_d(_jit,i0,r0,i1) +static jit_word_t _vfp_bgei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vfp_bgtr_f(i0,r0,r1) vbcmp_f(ARM_CC_GT,i0,r0,r1) +# define vfp_bgti_f(i0,r0,i1) _vfp_bgti_f(_jit,i0,r0,i1) +static jit_word_t _vfp_bgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_bgtr_d(i0,r0,r1) vbcmp_d(ARM_CC_GT,i0,r0,r1) +# define vfp_bgti_d(i0,r0,i1) _vfp_bgti_d(_jit,i0,r0,i1) +static jit_word_t _vfp_bgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vfp_bner_f(i0,r0,r1) vbcmp_f(ARM_CC_NE,i0,r0,r1) +# define vfp_bnei_f(i0,r0,i1) _vfp_bnei_f(_jit,i0,r0,i1) +static jit_word_t _vfp_bnei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_bner_d(i0,r0,r1) vbcmp_d(ARM_CC_NE,i0,r0,r1) +# define vfp_bnei_d(i0,r0,i1) _vfp_bnei_d(_jit,i0,r0,i1) +static jit_word_t _vfp_bnei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vbncmp_x(cc,i0) _vbncmp_x(_jit,cc,i0) +static jit_word_t _vbncmp_x(jit_state_t*,int,jit_word_t); +# define vbncmp_f(cc,i0,r0,r1) _vbncmp_f(_jit,cc,i0,r0,r1) +static jit_word_t +_vbncmp_f(jit_state_t*,int,jit_word_t,jit_int32_t,jit_int32_t); +# define vbncmp_d(cc,i0,r0,r1) _vbncmp_d(_jit,cc,i0,r0,r1) +static jit_word_t +_vbncmp_d(jit_state_t*,int,jit_word_t,jit_int32_t,jit_int32_t); +# define vfp_bunltr_f(i0,r0,r1) vbncmp_f(ARM_CC_GE,i0,r0,r1) +# define vfp_bunlti_f(i0,r0,i1) _vfp_bunlti_f(_jit,i0,r0,i1) +static jit_word_t +_vfp_bunlti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_bunltr_d(i0,r0,r1) vbncmp_d(ARM_CC_GE,i0,r0,r1) +# define vfp_bunlti_d(i0,r0,i1) _vfp_bunlti_d(_jit,i0,r0,i1) +static jit_word_t +_vfp_bunlti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vfp_bunler_f(i0,r0,r1) vbncmp_f(ARM_CC_GT,i0,r0,r1) +# define vfp_bunlei_f(i0,r0,i1) _vfp_bunlei_f(_jit,i0,r0,i1) +static jit_word_t +_vfp_bunlei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_bunler_d(i0,r0,r1) vbncmp_d(ARM_CC_GT,i0,r0,r1) +# define vfp_bunlei_d(i0,r0,i1) _vfp_bunlei_d(_jit,i0,r0,i1) +static jit_word_t +_vfp_bunlei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vfp_buneqr_x(i0) _vfp_buneqr_x(_jit,i0) +static jit_word_t _vfp_buneqr_x(jit_state_t*,jit_word_t); +# define vfp_buneqr_f(i0,r0,r1) _vfp_buneqr_f(_jit,i0,r0,r1) +static jit_word_t +_vfp_buneqr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define vfp_buneqi_f(i0,r0,i1) _vfp_buneqi_f(_jit,i0,r0,i1) +static jit_word_t +_vfp_buneqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_buneqr_d(i0,r0,r1) _vfp_buneqr_d(_jit,i0,r0,r1) +static jit_word_t +_vfp_buneqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define vfp_buneqi_d(i0,r0,i1) _vfp_buneqi_d(_jit,i0,r0,i1) +static jit_word_t +_vfp_buneqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vfp_bunger_x(i0) _vfp_bunger_x(_jit,i0) +static jit_word_t _vfp_bunger_x(jit_state_t*,jit_word_t); +# define vfp_bunger_f(i0,r0,r1) _vfp_bunger_f(_jit,i0,r0,r1) +static jit_word_t +_vfp_bunger_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define vfp_bungei_f(i0,r0,i1) _vfp_bungei_f(_jit,i0,r0,i1) +static jit_word_t +_vfp_bungei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_bunger_d(i0,r0,r1) _vfp_bunger_d(_jit,i0,r0,r1) +static jit_word_t +_vfp_bunger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define vfp_bungei_d(i0,r0,i1) _vfp_bungei_d(_jit,i0,r0,i1) +static jit_word_t +_vfp_bungei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vfp_bungtr_f(i0,r0,r1) vbcmp_f(ARM_CC_HI,i0,r0,r1) +# define vfp_bungti_f(i0,r0,i1) _vfp_bungti_f(_jit,i0,r0,i1) +static jit_word_t +_vfp_bungti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_bungtr_d(i0,r0,r1) vbcmp_d(ARM_CC_HI,i0,r0,r1) +# define vfp_bungti_d(i0,r0,i1) _vfp_bungti_d(_jit,i0,r0,i1) +static jit_word_t +_vfp_bungti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vfp_bltgtr_x(i0) _vfp_bltgtr_x(_jit,i0) +static jit_word_t _vfp_bltgtr_x(jit_state_t*,jit_word_t); +# define vfp_bltgtr_f(i0,r0,r1) _vfp_bltgtr_f(_jit,i0,r0,r1) +static jit_word_t +_vfp_bltgtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define vfp_bltgti_f(i0,r0,i1) _vfp_bltgti_f(_jit,i0,r0,i1) +static jit_word_t +_vfp_bltgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_bltgtr_d(i0,r0,r1) _vfp_bltgtr_d(_jit,i0,r0,r1) +static jit_word_t +_vfp_bltgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define vfp_bltgti_d(i0,r0,i1) _vfp_bltgti_d(_jit,i0,r0,i1) +static jit_word_t +_vfp_bltgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vfp_bordr_f(i0,r0,r1) vbcmp_f(ARM_CC_VC,i0,r0,r1) +# define vfp_bordi_f(i0,r0,i1) _vfp_bordi_f(_jit,i0,r0,i1) +static jit_word_t +_vfp_bordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_bordr_d(i0,r0,r1) vbcmp_d(ARM_CC_VC,i0,r0,r1) +# define vfp_bordi_d(i0,r0,i1) _vfp_bordi_d(_jit,i0,r0,i1) +static jit_word_t +_vfp_bordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vfp_bunordr_f(i0,r0,r1) vbcmp_f(ARM_CC_VS,i0,r0,r1) +# define vfp_bunordi_f(i0,r0,i1) _vfp_bunordi_f(_jit,i0,r0,i1) +static jit_word_t +_vfp_bunordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define vfp_bunordr_d(i0,r0,r1) vbcmp_d(ARM_CC_VS,i0,r0,r1) +# define vfp_bunordi_d(i0,r0,i1) _vfp_bunordi_d(_jit,i0,r0,i1) +static jit_word_t +_vfp_bunordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vfp_ldr_f(r0,r1) VLDR_F32(r0,r1,0) +# define vfp_ldr_d(r0,r1) VLDR_F64(r0,r1,0) +# define vfp_ldi_f(r0,i0) _vfp_ldi_f(_jit,r0,i0) +static void _vfp_ldi_f(jit_state_t*,jit_int32_t,jit_word_t); +# define vfp_ldi_d(r0,i0) _vfp_ldi_d(_jit,r0,i0) +static void _vfp_ldi_d(jit_state_t*,jit_int32_t,jit_word_t); +# define vfp_ldxr_f(r0,r1,r2) _vfp_ldxr_f(_jit,r0,r1,r2) +static void _vfp_ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_ldxr_d(r0,r1,r2) _vfp_ldxr_d(_jit,r0,r1,r2) +static void _vfp_ldxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_ldxi_f(r0,r1,i0) _vfp_ldxi_f(_jit,r0,r1,i0) +static void _vfp_ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define vfp_ldxi_d(r0,r1,i0) _vfp_ldxi_d(_jit,r0,r1,i0) +static void _vfp_ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define vfp_str_f(r0,r1) VSTR_F32(r1,r0,0) +# define vfp_str_d(r0,r1) VSTR_F64(r1,r0,0) +# define vfp_sti_f(i0,r0) _vfp_sti_f(_jit,i0,r0) +static void _vfp_sti_f(jit_state_t*,jit_word_t,jit_int32_t); +# define vfp_sti_d(i0,r0) _vfp_sti_d(_jit,i0,r0) +static void _vfp_sti_d(jit_state_t*,jit_word_t,jit_int32_t); +# define vfp_stxr_f(r0,r1,r2) _vfp_stxr_f(_jit,r0,r1,r2) +static void _vfp_stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_stxr_d(r0,r1,r2) _vfp_stxr_d(_jit,r0,r1,r2) +static void _vfp_stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define vfp_stxi_f(i0,r0,r1) _vfp_stxi_f(_jit,i0,r0,r1) +static void _vfp_stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define vfp_stxi_d(i0,r0,r1) _vfp_stxi_d(_jit,i0,r0,r1) +static void _vfp_stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define vfp_vaarg_d(r0, r1) _vfp_vaarg_d(_jit, r0, r1) +static void _vfp_vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t); +#endif + +#if CODE +# define vfp_regno(rn) (((rn) - 16) >> 1) + +static int +encode_vfp_double(int mov, int inv, unsigned lo, unsigned hi) +{ + int code, mode, imm, mask; + + if (hi != lo) { + if (mov && !inv) { + /* (I64) + * aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh + */ + for (mode = 0, mask = 0xff; mode < 4; mask <<= 8, mode++) { + imm = lo & mask; + if (imm != mask && imm != 0) + goto fail; + imm = hi & mask; + if (imm != mask && imm != 0) + goto fail; + } + mode = 0xe20; + imm = (((hi & 0x80000000) >> 24) | ((hi & 0x00800000) >> 17) | + ((hi & 0x00008000) >> 10) | ((hi & 0x00000080) >> 3) | + ((lo & 0x80000000) >> 28) | ((lo & 0x00800000) >> 21) | + ((lo & 0x00008000) >> 14) | ((lo & 0x00000080) >> 7)); + goto success; + } + goto fail; + } + /* (I32) + * 00000000 00000000 00000000 abcdefgh + * 00000000 00000000 abcdefgh 00000000 + * 00000000 abcdefgh 00000000 00000000 + * abcdefgh 00000000 00000000 00000000 */ + for (mode = 0, mask = 0xff; mode < 4; mask <<= 8, mode++) { + if ((lo & mask) == lo) { + imm = lo >> (mode << 3); + mode <<= 9; + goto success; + } + } + /* (I16) + * 00000000 abcdefgh 00000000 abcdefgh + * abcdefgh 00000000 abcdefgh 00000000 */ + for (mode = 0, mask = 0xff; mode < 2; mask <<= 8, mode++) { + if ((lo & mask) && ((lo & (mask << 16)) >> 16) == (lo & mask)) { + imm = lo >> (mode << 3); + mode = 0x800 | (mode << 9); + goto success; + } + } + if (mov) { + /* (I32) + * 00000000 00000000 abcdefgh 11111111 + * 00000000 abcdefgh 11111111 11111111 */ + for (mode = 0, mask = 0xff; mode < 2; + mask = (mask << 8) | 0xff, mode++) { + if ((lo & mask) == mask && + !((lo & ~mask) >> 8) && + (imm = lo >> (8 + (mode << 8)))) { + mode = 0xc00 | (mode << 8); + goto success; + } + } + if (!inv) { + /* (F32) + * aBbbbbbc defgh000 00000000 00000000 + * from the ARM Architecture Reference Manual: + * In this entry, B = NOT(b). The bit pattern represents the + * floating-point number (-1)^s* 2^exp * mantissa, where + * S = UInt(a), + * exp = UInt(NOT(b):c:d)-3 and + * mantissa = (16+UInt(e:f:g:h))/16. */ + if ((lo & 0x7ffff) == 0 && + (((lo & 0x7e000000) == 0x3e000000) || + ((lo & 0x7e000000) == 0x40000000))) { + mode = 0xf00; + imm = ((lo >> 24) & 0x80) | ((lo >> 19) & 0x7f); + goto success; + } + } + } + +fail: + /* need another approach (load from memory, move from arm register, etc) */ + return (-1); + +success: + code = inv ? ARM_VMVNI : ARM_VMOVI; + switch ((mode & 0xf00) >> 8) { + case 0x0: case 0x2: case 0x4: case 0x6: + case 0x8: case 0xa: + if (inv) mode |= 0x20; + if (!mov) mode |= 0x100; + break; + case 0x1: case 0x3: case 0x5: case 0x7: + /* should actually not reach here */ + assert(!inv); + case 0x9: case 0xb: + assert(!mov); + break; + case 0xc: case 0xd: + /* should actually not reach here */ + assert(inv); + case 0xe: + assert(mode & 0x20); + assert(mov && !inv); + break; + default: + assert(!(mode & 0x20)); + break; + } + imm = ((imm & 0x80) << 17) | ((imm & 0x70) << 12) | (imm & 0x0f); + code |= mode | imm; + if (jit_thumb_p()) { + if (code & 0x1000000) + code |= 0xff000000; + else + code |= 0xef000000; + } + else + code |= ARM_CC_NV; + return (code); +} + +static void +_vodi(jit_state_t *_jit, int oi, int r0) +{ + jit_thumb_t thumb; + assert(!(oi & 0x0000f000)); + assert(!(r0 & 1)); r0 = vfp_regno(r0); + thumb.i = oi|(_u4(r0)<<12); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_voqi(jit_state_t *_jit, int oi, int r0) +{ + jit_thumb_t thumb; + assert(!(oi & 0x0000f000)); + assert(!(r0 & 3)); r0 = vfp_regno(r0); + thumb.i = oi|(_u4(r0)<<12); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_vo_ss(jit_state_t *_jit, int cc, int o, int r0, int r1) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf000f00f)); + if (r0 & 1) o |= ARM_V_D; r0 = vfp_regno(r0); + if (r1 & 1) o |= ARM_V_M; r1 = vfp_regno(r1); + thumb.i = cc|o|(_u4(r0)<<12)|_u4(r1); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_vo_dd(jit_state_t *_jit, int cc, int o, int r0, int r1) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf000f00f)); + assert(!(r0 & 1) && !(r1 & 1)); + r0 = vfp_regno(r0); r1 = vfp_regno(r1); + thumb.i = cc|o|(_u4(r0)<<12)|_u4(r1); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_vo_qd(jit_state_t *_jit, int cc, int o, int r0, int r1) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf000f00f)); + assert(!(r0 & 3) && !(r1 & 1)); + r0 = vfp_regno(r0); r1 = vfp_regno(r1); + thumb.i = cc|o|(_u4(r0)<<12)|_u4(r1); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_vo_qq(jit_state_t *_jit, int cc, int o, int r0, int r1) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf000f00f)); + assert(!(r0 & 3) && !(r1 & 3)); + r0 = vfp_regno(r0); r1 = vfp_regno(r1); + thumb.i = cc|o|(_u4(r0)<<12)|_u4(r1); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_vorr_(jit_state_t *_jit, int cc, int o, int r0, int r1) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf000f00f)); + thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_vors_(jit_state_t *_jit, int cc, int o, int r0, int r1) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf000f00f)); + if (r1 & 1) o |= ARM_V_N; r1 = vfp_regno(r1); + thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_vorv_(jit_state_t *_jit, int cc, int o, int r0, int r1) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf000f00f)); + if (r1 & 1) o |= ARM_V_M; r1 = vfp_regno(r1); + thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_vori_(jit_state_t *_jit, int cc, int o, int r0, int r1) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf000f00f)); + /* use same bit pattern, to set opc1... */ + if (r1 & 1) o |= ARM_V_I32; r1 = vfp_regno(r1); + thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_vorrd(jit_state_t *_jit, int cc, int o, int r0, int r1, int r2) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00ff00f)); + assert(!(r2 & 1)); + r2 = vfp_regno(r2); + thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u4(r2); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_vosss(jit_state_t *_jit, int cc, int o, int r0, int r1, int r2) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00ff00f)); + if (r0 & 1) o |= ARM_V_D; r0 = vfp_regno(r0); + if (r1 & 1) o |= ARM_V_N; r1 = vfp_regno(r1); + if (r2 & 1) o |= ARM_V_M; r2 = vfp_regno(r2); + thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u4(r2); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_voddd(jit_state_t *_jit, int cc, int o, int r0, int r1, int r2) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00ff00f)); + assert(!(r0 & 1) && !(r1 & 1) && !(r2 & 1)); + r0 = vfp_regno(r0); r1 = vfp_regno(r1); r2 = vfp_regno(r2); + thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u4(r2); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_voqdd(jit_state_t *_jit, int cc, int o, int r0, int r1, int r2) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00ff00f)); + assert(!(r0 & 3) && !(r1 & 1) && !(r2 & 1)); + r0 = vfp_regno(r0); r1 = vfp_regno(r1); r2 = vfp_regno(r2); + thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u4(r2); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_voqqd(jit_state_t *_jit, int cc, int o, int r0, int r1, int r2) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00ff00f)); + assert(!(r0 & 3) && !(r1 & 3) && !(r2 & 1)); + r0 = vfp_regno(r0); r1 = vfp_regno(r1); r2 = vfp_regno(r2); + thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u4(r2); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_voqqq(jit_state_t *_jit, int cc, int o, int r0, int r1, int r2) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00ff00f)); + assert(!(r0 & 3) && !(r1 & 3) && !(r2 & 3)); + r0 = vfp_regno(r0); r1 = vfp_regno(r1); r2 = vfp_regno(r2); + thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u4(r2); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_vldst(jit_state_t *_jit, int cc, int o, int r0, int r1, int i0) +{ + jit_thumb_t thumb; + /* i0 << 2 is byte offset */ + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00ff0ff)); + if (r0 & 1) { + assert(!(o & ARM_V_F64)); + o |= ARM_V_D; + } + r0 = vfp_regno(r0); + thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u8(i0); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_cc_vorsl(jit_state_t *_jit, int cc, int o, int r0, int r1, int i0) +{ + jit_thumb_t thumb; + assert(!(cc & 0x0fffffff)); + assert(!(o & 0xf00ff0ff)); + /* save i0 double precision registers */ + if (o & ARM_V_F64) i0 <<= 1; + /* if (r1 & 1) cc & ARM_V_F64 must be false */ + if (r1 & 1) o |= ARM_V_D; r1 = vfp_regno(r1); + assert(i0 && !(i0 & 1) && r1 + i0 <= 32); + thumb.i = cc|o|(_u4(r0)<<16)|(_u4(r1)<<12)|_u8(i0); + if (jit_thumb_p()) + iss(thumb.s[0], thumb.s[1]); + else + ii(thumb.i); +} + +static void +_vfp_movr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) { + if (jit_fpr_p(r1)) { + if (jit_fpr_p(r0)) + VMOV_F32(r0, r1); + else + VMOV_A_S(r0, r1); + } + else if (jit_fpr_p(r0)) + VMOV_S_A(r0, r1); + else + movr(r0, r1); + } +} + +static void +_vfp_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) { + if (jit_fpr_p(r1)) { + if (jit_fpr_p(r0)) + VMOV_F64(r0, r1); + else + VMOV_AA_D(r0, r0 + 1, r1); + } + else if (jit_fpr_p(r0)) + VMOV_D_AA(r0, r1, r1 + 1); + else { + /* minor consistency check */ + assert(r0 + 1 != r1 && r0 -1 != r1); + movr(r0, r1); + movr(r0 + 1, r1 + 1); + } + } +} + +static void +_vfp_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } u; + jit_int32_t reg; + jit_int32_t code; + u.f = i0; + if (jit_fpr_p(r0)) { + /* float arguments are packed, for others, + * lightning only address even registers */ + if (!(r0 & 1) && (r0 - 16) >= 0 && + ((code = encode_vfp_double(1, 0, u.i, u.i)) != -1 || + (code = encode_vfp_double(1, 1, ~u.i, ~u.i)) != -1)) + VIMM(code, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), u.i); + VMOV_S_A(r0, rn(reg)); + jit_unget_reg(reg); + } + } + else + movi(r0, u.i); +} + +static void +_vfp_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0) +{ + union { + jit_int32_t i[2]; + jit_float64_t d; + } u; + jit_int32_t code; + jit_int32_t rg0, rg1; + u.d = i0; + if (jit_fpr_p(r0)) { + if ((code = encode_vfp_double(1, 0, u.i[0], u.i[1])) != -1 || + (code = encode_vfp_double(1, 1, ~u.i[0], ~u.i[1])) != -1) + VIMM(code, r0); + else { + rg0 = jit_get_reg(jit_class_gpr); + rg1 = jit_get_reg(jit_class_gpr); + movi(rn(rg0), u.i[0]); + movi(rn(rg1), u.i[1]); + VMOV_D_AA(r0, rn(rg0), rn(rg1)); + jit_unget_reg(rg1); + jit_unget_reg(rg0); + } + } + else { + movi(r0, u.i[0]); + movi(r0 + 1, u.i[1]); + } +} + +static void +_vfp_extr_d_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r1)) { + if (jit_fpr_p(r0)) + VCVT_F64_F32(r0, r1); + else { + reg = jit_get_reg(jit_class_fpr); + VCVT_F64_F32(rn(reg), r1); + VMOV_A_S(r0, rn(reg)); + jit_unget_reg(reg); + } + } + else { + reg = jit_get_reg(jit_class_fpr); + VMOV_S_A(rn(reg), r1); + VCVT_F64_F32(rn(reg), rn(reg)); + if (jit_fpr_p(r0)) + VMOV_F32(r0, rn(reg)); + else + VMOV_A_S(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_vfp_extr_f_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r1)) { + if (jit_fpr_p(r0)) + VCVT_F32_F64(r0, r1); + else { + reg = jit_get_reg(jit_class_fpr); + VCVT_F32_F64(rn(reg), r1); + VMOV_AA_D(r0, r0 + 1, rn(reg)); + jit_unget_reg(reg); + } + } + else { + reg = jit_get_reg(jit_class_fpr); + VMOV_D_AA(rn(reg), r1, r1 + 1); + VCVT_F32_F64(rn(reg), rn(reg)); + if (jit_fpr_p(r0)) + VMOV_F64(r0, rn(reg)); + else + VMOV_AA_D(r0, r0 + 1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_vfp_extr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r0)) { + VMOV_V_I32(r0, r1); + VCVT_F32_S32(r0, r0); + } + else { + reg = jit_get_reg(jit_class_fpr); + VMOV_V_I32(rn(reg), r1); + VCVT_F32_S32(rn(reg), rn(reg)); + VMOV_F32(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_vfp_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r0)) { + VMOV_V_I32(r0, r1); + VCVT_F64_S32(r0, r0); + } + else { + reg = jit_get_reg(jit_class_fpr); + VMOV_V_I32(rn(reg), r1); + VCVT_F64_S32(rn(reg), rn(reg)); + VMOV_F64(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_vfp_truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + if (jit_fpr_p(r1)) + VCVT_S32_F32(rn(reg), r1); + else { + VMOV_V_I32(rn(reg), r1); + VCVT_S32_F32(rn(reg), rn(reg)); + } + VMOV_A_S32(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_vfp_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + if (jit_fpr_p(r1)) + VCVT_S32_F64(rn(reg), r1); + else { + VMOV_V_I32(rn(reg), r1); + VCVT_S32_F64(rn(reg), rn(reg)); + } + VMOV_A_S32(r0, rn(reg)); + jit_unget_reg(reg); +} + +# define fopi(name) \ +static void \ +_vfp_##name##i_f(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, jit_float32_t i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr); \ + vfp_movi_f(rn(reg), i0); \ + vfp_##name##r_f(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +# define dopi(name) \ +static void \ +_vfp_##name##i_d(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, jit_float64_t i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr); \ + vfp_movi_d(rn(reg), i0); \ + vfp_##name##r_d(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +# define fbopi(name) \ +static jit_word_t \ +_vfp_b##name##i_f(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, jit_float32_t i0) \ +{ \ + jit_word_t word; \ + jit_int32_t reg = jit_get_reg(jit_class_fpr| \ + jit_class_nospill); \ + vfp_movi_f(rn(reg), i0); \ + word = vfp_b##name##r_f(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ + return (word); \ +} +# define dbopi(name) \ +static jit_word_t \ +_vfp_b##name##i_d(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, jit_float64_t i0) \ +{ \ + jit_word_t word; \ + jit_int32_t reg = jit_get_reg(jit_class_fpr| \ + jit_class_nospill); \ + vfp_movi_d(rn(reg), i0); \ + word = vfp_b##name##r_d(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ + return (word); \ +} + +fopi(add) +dopi(add) +fopi(sub) +fopi(rsb) +dopi(rsb) +dopi(sub) +fopi(mul) +dopi(mul) +fopi(div) +dopi(div) + +static void +_vfp_cmp_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t rg0, rg1; + if (jit_fpr_p(r0)) { + if (jit_fpr_p(r1)) + VCMP_F32(r0, r1); + else { + rg1 = jit_get_reg(jit_class_fpr); + VMOV_S_A(rn(rg1), r1); + VCMP_F32(r0, rn(rg1)); + jit_unget_reg(rg1); + } + } + else { + rg0 = jit_get_reg(jit_class_fpr); + VMOV_S_A(rn(rg0), r0); + if (jit_fpr_p(r1)) + VCMP_F32(rn(rg0), r1); + else { + rg1 = jit_get_reg(jit_class_fpr); + VMOV_S_A(rn(rg1), r1); + VCMP_F32(rn(rg0), rn(rg1)); + jit_unget_reg(rg1); + } + jit_unget_reg(rg0); + } +} + +static void +_vfp_cmp_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t rg0, rg1; + if (jit_fpr_p(r0)) { + if (jit_fpr_p(r1)) + VCMP_F64(r0, r1); + else { + rg1 = jit_get_reg(jit_class_fpr); + VMOV_D_AA(rn(rg1), r1, r1 + 1); + VCMP_F64(r0, rn(rg1)); + jit_unget_reg(rg1); + } + } + else { + rg0 = jit_get_reg(jit_class_fpr); + VMOV_D_AA(rn(rg0), r0, r0 + 1); + if (jit_fpr_p(r1)) + VCMP_F64(rn(rg0), r1); + else { + rg1 = jit_get_reg(jit_class_fpr); + VMOV_D_AA(rn(rg1), r1, r1 + 1); + VCMP_F64(rn(rg0), rn(rg1)); + jit_unget_reg(rg1); + } + jit_unget_reg(rg0); + } +} + +static void +_vcmp01_x(jit_state_t *_jit, int c0, int c1, jit_int32_t r0) +{ + VMRS(_R15_REGNO); + if (jit_thumb_p()) { + if ((c0 ^ c1) >> 28 == 1) { + ITE(c0); + if (r0 < 8) { + T1_MOVI(r0, 0); + T1_MOVI(r0, 1); + } + else { + T2_MOVI(r0, 0); + T2_MOVI(r0, 1); + } + } + else { + if (r0 < 8) { + IT(c0); + T1_MOVI(r0, 0); + IT(c1); + T1_MOVI(r0, 1); + } + else { + IT(c0); + T2_MOVI(r0, 0); + IT(c1); + T2_MOVI(r0, 1); + } + } + } + else { + CC_MOVI(c0, r0, 0); + CC_MOVI(c1, r0, 1); + } +} + +static void +_vcmp01_f(jit_state_t *_jit, int c0, int c1, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_f(r1, r2); + vcmp01_x(c0, c1, r0); +} + +static void +_vcmp01_d(jit_state_t *_jit, int c0, int c1, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_d(r1, r2); + vcmp01_x(c0, c1, r0); +} + +static void +_vcmp10_x(jit_state_t *_jit, int cc, jit_int32_t r0) +{ + if (jit_thumb_p()) { + if (r0 < 8) { + T1_MOVI(r0, 1); + VMRS(_R15_REGNO); + IT(cc); + T1_MOVI(r0, 0); + } + else { + T2_MOVI(r0, 1); + VMRS(_R15_REGNO); + IT(cc); + T2_MOVI(r0, 0); + } + } + else { + VMRS(_R15_REGNO); + MOVI(r0, 1); + CC_MOVI(cc, r0, 0); + } +} +static void +_vcmp_10_f(jit_state_t *_jit, int cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_f(r1, r2); + vcmp10_x(cc, r0); +} + +static void +_vcmp_10_d(jit_state_t *_jit, int cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_d(r1, r2); + vcmp10_x(cc, r0); +} + +fopi(lt) +dopi(lt) +fopi(le) +dopi(le) +fopi(eq) +dopi(eq) +fopi(ge) +dopi(ge) +fopi(gt) +dopi(gt) +fopi(ne) +dopi(ne) +fopi(unlt) +dopi(unlt) +fopi(unle) +dopi(unle) + +static void +_vfp_uneqr_x(jit_state_t *_jit, jit_int32_t r0) +{ + VMRS(_R15_REGNO); + if (jit_thumb_p()) { + ITE(ARM_CC_NE); + if (r0 < 8) { + T1_MOVI(r0, 0); + T1_MOVI(r0, 1); + IT(ARM_CC_VS); + T1_MOVI(r0, 1); + } + else { + T2_MOVI(r0, 0); + T2_MOVI(r0, 1); + IT(ARM_CC_VS); + T2_MOVI(r0, 1); + } + } + else { + CC_MOVI(ARM_CC_NE, r0, 0); + CC_MOVI(ARM_CC_EQ, r0, 1); + CC_MOVI(ARM_CC_VS, r0, 1); + } +} + +static void +_vfp_uneqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_f(r1, r2); + vfp_uneqr_x(r0); +} + +fopi(uneq) + +static void +_vfp_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_d(r1, r2); + vfp_uneqr_x(r0); +} + +dopi(uneq) + +static void +_vcmp_01_x(jit_state_t *_jit, int cc, jit_int32_t r0) +{ + if (jit_thumb_p()) { + if (r0 < 8) { + T1_MOVI(r0, 0); + VMRS(_R15_REGNO); + IT(cc); + T1_MOVI(r0, 1); + } + else { + T2_MOVI(r0, 0); + VMRS(_R15_REGNO); + IT(cc); + T2_MOVI(r0, 1); + } + } + else { + MOVI(r0, 0); + VMRS(_R15_REGNO); + CC_MOVI(cc, r0, 1); + } +} + +static void +_vcmp_01_f(jit_state_t *_jit, int cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_f(r1, r2); + vcmp_01_x(cc, r0); +} + +static void +_vcmp_01_d(jit_state_t *_jit, int cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_d(r1, r2); + vcmp_01_x(cc, r0); +} + +fopi(unge) +dopi(unge) +fopi(ungt) +dopi(ungt) + +static void +_vfp_ltgtr_x(jit_state_t *_jit, jit_int32_t r0) +{ + VMRS(_R15_REGNO); + if (jit_thumb_p()) { + ITE(ARM_CC_NE); + if (r0 < 8) { + T1_MOVI(r0, 1); + T1_MOVI(r0, 0); + IT(ARM_CC_VS); + T1_MOVI(r0, 0); + } + else { + T2_MOVI(r0, 1); + T2_MOVI(r0, 0); + IT(ARM_CC_VS); + T2_MOVI(r0, 0); + } + } + else { + CC_MOVI(ARM_CC_NE, r0, 1); + CC_MOVI(ARM_CC_EQ, r0, 0); + CC_MOVI(ARM_CC_VS, r0, 0); + } +} + +static void +_vfp_ltgtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_f(r1, r2); + vfp_ltgtr_x(r0); +} + +fopi(ltgt) + +static void +_vfp_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_d(r1, r2); + vfp_ltgtr_x(r0); +} + +dopi(ltgt) + +static void +_vfp_ordr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_f(r1, r2); + vcmp10_x(ARM_CC_VS, r0); +} + +fopi(ord) + +static void +_vfp_ordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_d(r1, r2); + vcmp10_x(ARM_CC_VS, r0); +} + +dopi(ord) + +static void +_vfp_unordr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_f(r1, r2); + vcmp_01_x(ARM_CC_VS, r0); +} + +fopi(unord) + +static void +_vfp_unordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + vfp_cmp_d(r1, r2); + vcmp_01_x(ARM_CC_VS, r0); +} + +dopi(unord) + +static jit_word_t +_vbcmp_x(jit_state_t *_jit, int cc, jit_word_t i0) +{ + jit_word_t d, w; + VMRS(_R15_REGNO); + w = _jit->pc.w; + if (jit_thumb_p()) { + d = ((i0 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(cc, encode_thumb_cc_jump(d)); + } + else { + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(cc, d & 0x00ffffff); + } + return (w); +} + + +static jit_word_t +_vbcmp_f(jit_state_t *_jit, int cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + vfp_cmp_f(r0, r1); + return (vbcmp_x(cc, i0)); +} + +static jit_word_t +_vbcmp_d(jit_state_t *_jit, int cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + vfp_cmp_d(r0, r1); + return (vbcmp_x(cc, i0)); +} + +static jit_word_t +_vbncmp_x(jit_state_t *_jit, int cc, jit_word_t i0) +{ + jit_word_t d, p, w; + VMRS(_R15_REGNO); + p = _jit->pc.w; + if (jit_thumb_p()) { + T2_CC_B(cc, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s20P(d)); + T2_B(encode_thumb_jump(d)); + } + else { + CC_B(cc, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + B(d & 0x00ffffff); + } + patch_at(arm_patch_jump, p, _jit->pc.w); + return (w); +} + +static jit_word_t +_vbncmp_f(jit_state_t *_jit, int cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + vfp_cmp_f(r0, r1); + return (vbncmp_x(cc, i0)); +} + +static jit_word_t +_vbncmp_d(jit_state_t *_jit, int cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + vfp_cmp_d(r0, r1); + return (vbncmp_x(cc, i0)); +} + +fbopi(lt) +dbopi(lt) +fbopi(le) +dbopi(le) +fbopi(eq) +dbopi(eq) +fbopi(ge) +dbopi(ge) +fbopi(gt) +dbopi(gt) +fbopi(ne) +dbopi(ne) +fbopi(unlt) +dbopi(unlt) +fbopi(unle) +dbopi(unle) + +static jit_word_t +_vfp_buneqr_x(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t d, p, q, w; + VMRS(_R15_REGNO); + p = _jit->pc.w; + if (jit_thumb_p()) { + T2_CC_B(ARM_CC_VS, 0); + q = _jit->pc.w; + T2_CC_B(ARM_CC_NE, 0); + patch_at(arm_patch_jump, p, _jit->pc.w); + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s20P(d)); + T2_B(encode_thumb_jump(d)); + } + else { + CC_B(ARM_CC_VS, 0); + q = _jit->pc.w; + CC_B(ARM_CC_NE, 0); + patch_at(arm_patch_jump, p, _jit->pc.w); + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + B(d & 0x00ffffff); + } + patch_at(arm_patch_jump, q, _jit->pc.w); + return (w); +} + +static jit_word_t +_vfp_buneqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + vfp_cmp_f(r0, r1); + return (vfp_buneqr_x(i0)); +} + +fbopi(uneq) + +static jit_word_t +_vfp_buneqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + vfp_cmp_d(r0, r1); + return (vfp_buneqr_x(i0)); +} + +dbopi(uneq) + +static jit_word_t +_vfp_bunger_x(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t d, p, w; + VMRS(_R15_REGNO); + p = _jit->pc.w; + if (jit_thumb_p()) { + T2_CC_B(ARM_CC_MI, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s20P(d)); + T2_CC_B(ARM_CC_HS, encode_thumb_cc_jump(d)); + } + else { + CC_B(ARM_CC_MI, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + CC_B(ARM_CC_HS, d & 0x00ffffff); + } + patch_at(arm_patch_jump, p, _jit->pc.w); + return (w); +} + +static jit_word_t +_vfp_bunger_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + vfp_cmp_f(r0, r1); + return (vfp_bunger_x(i0)); +} + +fbopi(unge) + +static jit_word_t +_vfp_bunger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + vfp_cmp_d(r0, r1); + return (vfp_bunger_x(i0)); +} + +dbopi(unge) + +static jit_word_t +_vfp_bltgtr_x(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t d, p, q, w; + VMRS(_R15_REGNO); + p = _jit->pc.w; + if (jit_thumb_p()) { + T2_CC_B(ARM_CC_VS, 0); + q = _jit->pc.w; + T2_CC_B(ARM_CC_EQ, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 1) - 2; + assert(_s20P(d)); + T2_B(encode_thumb_jump(d)); + } + else { + CC_B(ARM_CC_VS, 0); + q = _jit->pc.w; + CC_B(ARM_CC_EQ, 0); + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + B(d & 0x00ffffff); + } + patch_at(arm_patch_jump, p, _jit->pc.w); + patch_at(arm_patch_jump, q, _jit->pc.w); + return (w); +} + +static jit_word_t +_vfp_bltgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + vfp_cmp_f(r0, r1); + return (vfp_bltgtr_x(i0)); +} + +fbopi(ungt) +dbopi(ungt) +fbopi(ltgt) + +static jit_word_t +_vfp_bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + vfp_cmp_d(r0, r1); + return (vfp_bltgtr_x(i0)); +} + +dbopi(ltgt) +fbopi(ord) +dbopi(ord) +fbopi(unord) +dbopi(unord) + +static void +_vfp_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t gpr; + if (jit_fpr_p(r0)) { + gpr = jit_get_reg(jit_class_gpr); + movi(rn(gpr), i0); + VLDR_F32(r0, rn(gpr), 0); + jit_unget_reg(gpr); + } + else + ldi_i(r0, i0); +} + +static void +_vfp_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if (jit_fpr_p(r0)) + VLDR_F64(r0, rn(reg), 0); + else { + ldr_i(r0, rn(reg)); + ldxi_i(r0 + 1, rn(reg), 4); + } + jit_unget_reg(reg); +} + +static void +_vfp_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (jit_fpr_p(r0)) { + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + VLDR_F32(r0, rn(reg), 0); + jit_unget_reg(reg); + } + else + ldxr_i(r0, r1, r2); +} + +static void +_vfp_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + if (jit_fpr_p(r0)) + VLDR_F64(r0, rn(reg), 0); + else { + ldr_i(r0, rn(reg)); + ldxi_i(r0 + 1, rn(reg), 4); + } + jit_unget_reg(reg); +} + +static void +_vfp_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_fpr_p(r0)) { + if (i0 >= 0) { + assert(!(i0 & 3)); + if (i0 < 1024) + VLDR_F32(r0, r1, i0 >> 2); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + VLDR_F32(r0, rn(reg), 0); + jit_unget_reg(reg); + } + } + else { + i0 = -i0; + assert(!(i0 & 3)); + if (i0 < 1024) + VLDRN_F32(r0, r1, i0 >> 2); + else { + reg = jit_get_reg(jit_class_gpr); + subi(rn(reg), r1, i0); + VLDR_F32(r0, rn(reg), 0); + jit_unget_reg(reg); + } + } + } + else + ldxi_i(r0, r1, i0); +} + +static void +_vfp_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_fpr_p(r0)) { + if (i0 >= 0) { + assert(!(i0 & 3)); + if (i0 < 1024) + VLDR_F64(r0, r1, i0 >> 2); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + VLDR_F64(r0, rn(reg), 0); + jit_unget_reg(reg); + } + } + else { + i0 = -i0; + assert(!(i0 & 3)); + if (i0 < 1024) + VLDRN_F64(r0, r1, i0 >> 2); + else { + reg = jit_get_reg(jit_class_gpr); + subi(rn(reg), r1, i0); + VLDR_F64(r0, rn(reg), 0); + jit_unget_reg(reg); + } + } + } + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_i(r0, rn(reg)); + ldxi_i(r0 + 1, rn(reg), 4); + jit_unget_reg(reg); + } +} + +static void +_vfp_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (jit_fpr_p(r0)) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + VSTR_F32(r0, rn(reg), 0); + jit_unget_reg(reg); + } + else + sti_i(i0, r0); +} + +static void +_vfp_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if (jit_fpr_p(r0)) + VSTR_F64(r0, rn(reg), 0); + else { + str_i(rn(reg), r0); + stxi_i(4, rn(reg), r0 + 1); + } + jit_unget_reg(reg); +} + +static void +_vfp_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (jit_fpr_p(r2)) { + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + VSTR_F32(r2, rn(reg), 0); + jit_unget_reg(reg); + } + else + stxr_i(r0, r1, r2); +} + +static void +_vfp_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + if (jit_fpr_p(r2)) + VSTR_F64(r2, rn(reg), 0); + else { + str_i(rn(reg), r2); + stxi_i(4, rn(reg), r2 + 1); + } + jit_unget_reg(reg); +} + +static void +_vfp_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r1)) { + if (i0 >= 0) { + assert(!(i0 & 3)); + if (i0 < 1024) + VSTR_F32(r1, r0, i0 >> 2); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + VSTR_F32(r1, rn(reg), 0); + jit_unget_reg(reg); + } + } + else { + i0 = -i0; + assert(!(i0 & 3)); + if (i0 < 1024) + VSTRN_F32(r1, r0, i0 >> 2); + else { + reg = jit_get_reg(jit_class_gpr); + subi(rn(reg), r0, i0); + VSTR_F32(r1, rn(reg), 0); + jit_unget_reg(reg); + } + } + } + else + stxi_i(i0, r0, r1); +} + +static void +_vfp_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (jit_fpr_p(r1)) { + if (i0 >= 0) { + assert(!(i0 & 3)); + if (i0 < 0124) + VSTR_F64(r1, r0, i0 >> 2); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + VSTR_F64(r1, rn(reg), 0); + jit_unget_reg(reg); + } + } + else { + i0 = -i0; + assert(!(i0 & 3)); + if (i0 < 1024) + VSTRN_F64(r1, r0, i0 >> 2); + else { + reg = jit_get_reg(jit_class_gpr); + subi(rn(reg), r0, i0); + VSTR_F64(r1, rn(reg), 0); + jit_unget_reg(reg); + } + } + } + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_i(rn(reg), r1); + stxi_i(4, rn(reg), r1 + 1); + jit_unget_reg(reg); + } +} + +static void +_vfp_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + + assert(_jitc->function->self.call & jit_call_varargs); + + /* Adjust pointer. */ + reg = jit_get_reg(jit_class_gpr); + andi(rn(reg), r1, 7); + addr(r1, r1, rn(reg)); + jit_unget_reg(reg); + + /* Load argument. */ + vfp_ldr_d(r0, r1); + + /* Update stack pointer. */ + addi(r1, r1, sizeof(jit_float64_t)); +} +# undef dbopi +# undef fbopi +# undef dopi +# undef fopi +#endif diff --git a/deps/lightning/lib/jit_arm.c b/deps/lightning/lib/jit_arm.c new file mode 100644 index 0000000..783fa90 --- /dev/null +++ b/deps/lightning/lib/jit_arm.c @@ -0,0 +1,2274 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if defined(__linux__) +# include <stdio.h> +#endif + +#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 4) +#define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 16) +#define jit_arg_d_reg_p(i) ((i) >= 0 && (i) < 15) + +#define arm_patch_node 0x80000000 +#define arm_patch_word 0x40000000 +#define arm_patch_jump 0x20000000 +#define arm_patch_load 0x00000000 + +#define jit_fpr_p(rn) ((rn) > 15) + +#define arg_base() \ + (stack_framesize - 16 + (jit_cpu.abi ? 64 : 0)) +#define arg_offset(n) \ + ((n) < 4 ? arg_base() + ((n) << 2) : (n)) + +/* Assume functions called never match jit instruction set, that is + * libc, gmp, mpfr, etc functions are in thumb mode and jit is in + * arm mode, what may cause a crash upon return of that function + * if generating jit for a relative jump. + */ +#define jit_exchange_p() 1 + +/* FIXME is it really required to not touch _R10? */ + +/* + * Types + */ +typedef union _jit_thumb_t { + jit_int32_t i; + jit_int16_t s[2]; +} jit_thumb_t; + +typedef jit_pointer_t jit_va_list; + +/* + * Prototypes + */ +#define jit_make_arg(node) _jit_make_arg(_jit,node) +static jit_node_t *_jit_make_arg(jit_state_t*,jit_node_t*); +#define jit_make_arg_f(node) _jit_make_arg_f(_jit,node) +static jit_node_t *_jit_make_arg_f(jit_state_t*,jit_node_t*); +#define jit_make_arg_d(node) _jit_make_arg_d(_jit,node) +static jit_node_t *_jit_make_arg_d(jit_state_t*,jit_node_t*); +#define jit_get_reg_pair() _jit_get_reg_pair(_jit) +static jit_int32_t _jit_get_reg_pair(jit_state_t*); +#define jit_unget_reg_pair(rn) _jit_unget_reg_pair(_jit,rn) +static void _jit_unget_reg_pair(jit_state_t*,jit_int32_t); +# define must_align_p(node) _must_align_p(_jit, node) +static jit_bool_t _must_align_p(jit_state_t*,jit_node_t*); +#define load_const(uniq,r0,i0) _load_const(_jit,uniq,r0,i0) +static void _load_const(jit_state_t*,jit_bool_t,jit_int32_t,jit_word_t); +#define flush_consts() _flush_consts(_jit) +static void _flush_consts(jit_state_t*); +#define invalidate_consts() _invalidate_consts(_jit) +static void _invalidate_consts(jit_state_t*); +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); + +#if defined(__GNUC__) +/* libgcc */ +extern void __clear_cache(void *, void *); +#endif + +#define PROTO 1 +# include "jit_rewind.c" +# include "jit_arm-cpu.c" +# include "jit_arm-swf.c" +# include "jit_arm-vfp.c" +#undef PROTO + +/* + * Initialization + */ +jit_cpu_t jit_cpu; +jit_register_t _rvs[] = { + { rc(gpr) | 0x0c, "ip" }, + { rc(sav) | rc(gpr) | 0x04, "r4" }, + { rc(sav) | rc(gpr) | 0x05, "r5" }, + { rc(sav) | rc(gpr) | 0x06, "r6" }, + { rc(sav) | rc(gpr) | 0x07, "r7" }, + { rc(sav) | rc(gpr) | 0x08, "r8" }, + { rc(sav) | rc(gpr) | 0x09, "r9" }, + { rc(sav) | 0x0a, "sl" }, + { rc(sav) | 0x0b, "fp" }, + { rc(sav) | 0x0d, "sp" }, + { rc(sav) | 0x0e, "lr" }, + { 0x0f, "pc" }, + { rc(arg) | rc(gpr) | 0x03, "r3" }, + { rc(arg) | rc(gpr) | 0x02, "r2" }, + { rc(arg) | rc(gpr) | 0x01, "r1" }, + { rc(arg) | rc(gpr) | 0x00, "r0" }, + { rc(fpr) | 0x20, "d8" }, + { 0x21, "s17" }, + { rc(fpr) | 0x22, "d9" }, + { 0x23, "s19" }, + { rc(fpr) | 0x24, "d10" }, + { 0x25, "s21" }, + { rc(fpr) | 0x26, "d11" }, + { 0x27, "s23" }, + { rc(fpr) | 0x28, "d12" }, + { 0x29, "s25" }, + { rc(fpr) | 0x2a, "d13" }, + { 0x2b, "s27" }, + { rc(fpr) | 0x2c, "d14" }, + { 0x2d, "s29" }, + { rc(fpr) | 0x2e, "d15" }, + { 0x2f, "s31" }, + { rc(arg) | 0x1f, "s15" }, + { rc(arg)|rc(sft)|rc(fpr)|0x1e, "d7" }, + { rc(arg) | 0x1d, "s13" }, + { rc(arg)|rc(sft)|rc(fpr)|0x1c, "d6" }, + { rc(arg) | 0x1b, "s11" }, + { rc(arg)|rc(sft)|rc(fpr)|0x1a, "d5" }, + { rc(arg) | 0x19, "s9" }, + { rc(arg)|rc(sft)|rc(fpr)|0x18, "d4" }, + { rc(arg) | 0x17, "s7" }, + { rc(arg)|rc(sft)|rc(fpr)|0x16, "d3" }, + { rc(arg) | 0x15, "s5" }, + { rc(arg)|rc(sft)|rc(fpr)|0x14, "d2" }, + { rc(arg) | 0x13, "s3" }, + { rc(arg)|rc(sft)|rc(fpr)|0x12, "d1" }, + { rc(arg) | 0x11, "s1" }, + { rc(arg)|rc(sft)|rc(fpr)|0x10, "d0" }, + { _NOREG, "<none>" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ +#if defined(__linux__) + FILE *fp; + char *ptr; + char buf[128]; + + if ((fp = fopen("/proc/cpuinfo", "r")) != NULL) { + while (fgets(buf, sizeof(buf), fp)) { + if (strncmp(buf, "CPU architecture:", 17) == 0) { + jit_cpu.version = strtol(buf + 17, &ptr, 10); + while (*ptr) { + if (*ptr == 'T' || *ptr == 't') { + ++ptr; + jit_cpu.thumb = 1; + } + else if (*ptr == 'E' || *ptr == 'e') { + jit_cpu.extend = 1; + ++ptr; + } + else + ++ptr; + } + } + else if (strncmp(buf, "Features\t:", 10) == 0) { + if ((ptr = strstr(buf + 10, "vfpv"))) + jit_cpu.vfp = strtol(ptr + 4, NULL, 0); + if ((ptr = strstr(buf + 10, "neon"))) + jit_cpu.neon = 1; + if ((ptr = strstr(buf + 10, "thumb"))) + jit_cpu.thumb = 1; + } + } + fclose(fp); + } +#endif +#if defined(__ARM_PCS_VFP) + if (!jit_cpu.vfp) + jit_cpu.vfp = 3; + if (!jit_cpu.version) + jit_cpu.version = 7; + jit_cpu.abi = 1; +#endif +#if defined(__thumb2__) + jit_cpu.thumb = 1; +#endif + /* armv6t2 todo (software float and thumb2) */ + if (!jit_cpu.vfp && jit_cpu.thumb) + jit_cpu.thumb = 0; +} + +void +_jit_init(jit_state_t *_jit) +{ + jit_int32_t regno; + static jit_bool_t first = 1; + + _jitc->reglen = jit_size(_rvs) - 1; + if (first) { + /* jit_get_cpu() should have been already called, and only once */ + if (!jit_cpu.vfp) { + /* cause register to never be allocated, because simple + * software float only allocates stack space for 8 slots */ + for (regno = _D8; regno < _D7; regno++) + _rvs[regno].spec = 0; + } + if (!jit_cpu.abi) { + for (regno = _S15; regno <= _D0; regno++) + _rvs[regno].spec &= ~rc(arg); + } + first = 0; + } +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + _jitc->function->self.size = stack_framesize; + if (jit_cpu.abi) + _jitc->function->self.size += 64; + _jitc->function->self.argi = _jitc->function->self.argf = + _jitc->function->self.alen = 0; + if (jit_swf_p()) + /* 8 soft float registers */ + _jitc->function->self.aoff = -64; + else + _jitc->function->self.aoff = 0; + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + assert(_jitc->function); + switch (length) { + case 0: case 1: break; + case 2: _jitc->function->self.aoff &= -2; break; + case 3: case 4: _jitc->function->self.aoff &= -4; break; + default: _jitc->function->self.aoff &= -8; break; + } + _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } + return (_jitc->function->self.aoff); +} + +void +_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) +{ + jit_int32_t reg; + assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); + if (!_jitc->function->allocar) { + _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); + _jitc->function->allocar = 1; + } + reg = jit_get_reg(jit_class_gpr); + jit_negr(reg, v); + jit_andi(reg, reg, -8); + jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); + jit_addr(u, u, reg); + jit_addr(JIT_SP, JIT_SP, reg); + jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); + jit_unget_reg(reg); + jit_dec_synth(); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + assert(_jitc->function); + jit_inc_synth(ret); + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr, u); + if (JIT_RET != u) + jit_movr(JIT_RET, u); + jit_live(JIT_RET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti(jit_state_t *_jit, jit_word_t u) +{ + jit_inc_synth_w(reti, u); + jit_movi(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_f, u); + if (jit_cpu.abi) { + if (u != JIT_FRET) + jit_movr_f(JIT_FRET, u); + else + jit_live(JIT_FRET); + } + else { + if (u != JIT_RET) + jit_movr_f_w(JIT_RET, u); + else + jit_live(JIT_RET); + } + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_inc_synth_f(reti_f, u); + if (jit_cpu.abi) + jit_movi_f(JIT_FRET, u); + else + jit_movi_f_w(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_d, u); + if (jit_cpu.abi) { + if (u != JIT_FRET) + jit_movr_d(JIT_FRET, u); + else + jit_live(JIT_FRET); + } + else { + if (u != JIT_RET) + jit_movr_d_ww(JIT_RET, _R1, u); + else + jit_live(JIT_RET); + } + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_inc_synth_d(reti_d, u); + if (jit_cpu.abi) + jit_movi_d(JIT_FRET, u); + else + jit_movi_d_ww(JIT_RET, _R1, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_epilog(jit_state_t *_jit) +{ + assert(_jitc->function); + assert(_jitc->function->epilog->next == NULL); + jit_link(_jitc->function->epilog); + _jitc->function = NULL; +} + +jit_bool_t +_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) +{ + if (u->code != jit_code_arg) { + if (u->code == jit_code_arg_f) { + if (jit_cpu.abi) + return (jit_arg_f_reg_p(u->u.w)); + } + else { + assert(u->code == jit_code_arg_d); + if (jit_cpu.abi) + return (jit_arg_d_reg_p(u->u.w)); + } + } + return (jit_arg_reg_p(u->u.w)); +} + +static jit_node_t * +_jit_make_arg(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t offset; + if (jit_arg_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + if (node == (jit_node_t *)0) + node = jit_new_node(jit_code_arg); + else + link_node(node); + node->u.w = offset; + node->v.w = ++_jitc->function->self.argn; + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_make_arg_f(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t offset; + if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) { + if (jit_arg_f_reg_p(_jitc->function->self.argf)) { + offset = _jitc->function->self.argf++; + goto done; + } + } + else { + if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi++; + goto done; + } + } + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_float32_t); +done: + if (node == (jit_node_t *)0) + node = jit_new_node(jit_code_arg_f); + else + link_node(node); + node->u.w = offset; + node->v.w = ++_jitc->function->self.argn; + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_make_arg_d(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t offset; + if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) { + if (jit_arg_d_reg_p(_jitc->function->self.argf)) { + if (_jitc->function->self.argf & 1) + ++_jitc->function->self.argf; + offset = _jitc->function->self.argf; + _jitc->function->self.argf += 2; + goto done; + } + } + else { + if (_jitc->function->self.argi & 1) + ++_jitc->function->self.argi; + if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi; + _jitc->function->self.argi += 2; + goto done; + } + } + if (_jitc->function->self.size & 7) + _jitc->function->self.size += 4; + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_float64_t); +done: + if (node == (jit_node_t *)0) + node = jit_new_node(jit_code_arg_d); + else + link_node(node); + node->u.w = offset; + node->v.w = ++_jitc->function->self.argn; + jit_link_prolog(); + return (node); +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + if (_jitc->prepare) { + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; + if (jit_cpu.abi && _jitc->function->call.argf) + rewind_prepare(); + } + else { + assert(!(_jitc->function->self.call & jit_call_varargs)); + _jitc->function->self.call |= jit_call_varargs; + if (jit_cpu.abi && _jitc->function->self.argf) + rewind_prolog(); + /* First 4 stack addresses are always spilled r0-r3 */ + if (jit_arg_reg_p(_jitc->function->self.argi)) + _jitc->function->vagp = _jitc->function->self.argi * 4; + else + _jitc->function->vagp = 16; + } + jit_inc_synth(ellipsis); + if (_jitc->prepare) + jit_link_prepare(); + else + jit_link_prolog(); + jit_dec_synth(); +} + +void +_jit_va_push(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(va_push, u); + jit_pushargr(u); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + assert(_jitc->function); + return (jit_make_arg((jit_node_t*)0)); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + assert(_jitc->function); + return (jit_make_arg_f((jit_node_t*)0)); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + assert(_jitc->function); + return (jit_make_arg_d((jit_node_t*)0)); +} + +void +_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); + if (jit_swf_p()) + jit_ldxi_c(u, JIT_FP, arg_offset(v->u.w)); + else if (jit_arg_reg_p(v->u.w)) + jit_extr_c(u, JIT_RA0 - v->u.w); + else + jit_ldxi_c(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); + if (jit_swf_p()) + jit_ldxi_uc(u, JIT_FP, arg_offset(v->u.w)); + else if (jit_arg_reg_p(v->u.w)) + jit_extr_uc(u, JIT_RA0 - v->u.w); + else + jit_ldxi_uc(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); + if (jit_swf_p()) + jit_ldxi_s(u, JIT_FP, arg_offset(v->u.w)); + else if (jit_arg_reg_p(v->u.w)) + jit_extr_s(u, JIT_RA0 - v->u.w); + else + jit_ldxi_s(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); + if (jit_swf_p()) + jit_ldxi_us(u, JIT_FP, arg_offset(v->u.w)); + else if (jit_arg_reg_p(v->u.w)) + jit_extr_us(u, JIT_RA0 - v->u.w); + else + jit_ldxi_us(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); + if (jit_swf_p()) + jit_ldxi_i(u, JIT_FP, arg_offset(v->u.w)); + else if (jit_arg_reg_p(v->u.w)) + jit_movr(u, JIT_RA0 - v->u.w); + else + jit_ldxi_i(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); + if (jit_swf_p()) + jit_stxi(arg_offset(v->u.w), JIT_FP, u); + else if (jit_arg_reg_p(v->u.w)) + jit_movr(JIT_RA0 - v->u.w, u); + else + jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); + if (jit_swf_p()) { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(arg_offset(v->u.w), JIT_FP, regno); + jit_unget_reg(regno); + } + else if (jit_arg_reg_p(v->u.w)) + jit_movi(JIT_RA0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); + if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) { + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_f(u, JIT_FA0 - v->u.w); + else + jit_ldxi_f(u, JIT_FP, v->u.w); + } + else if (jit_swf_p()) + jit_ldxi_f(u, JIT_FP, arg_offset(v->u.w)); + else { + if (jit_arg_reg_p(v->u.w)) + jit_movr_w_f(u, JIT_RA0 - v->u.w); + else + jit_ldxi_f(u, JIT_FP, v->u.w); + } + jit_dec_synth(); +} + +void +_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); + if (jit_cpu.abi) { + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_f(JIT_FA0 - v->u.w, u); + else + jit_stxi_f(v->u.w, JIT_FP, u); + } + else if (jit_swf_p()) + jit_stxi_f(arg_offset(v->u.w), JIT_FP, u); + else { + if (jit_arg_reg_p(v->u.w)) + jit_movr_f_w(JIT_RA0 - v->u.w, u); + else + jit_stxi_f(v->u.w, JIT_FP, u); + } + jit_dec_synth(); +} + +void +_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); + if (jit_cpu.abi) { + if (jit_arg_f_reg_p(v->u.w)) + jit_movi_f(JIT_FA0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + } + else if (jit_swf_p()) { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(arg_offset(v->u.w), JIT_FP, regno); + jit_unget_reg(regno); + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + if (jit_arg_reg_p(v->u.w)) + jit_movr_f_w(JIT_RA0 - v->u.w, regno); + else + jit_stxi_f(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); + if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) { + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(u, JIT_FA0 - v->u.w); + else + jit_ldxi_d(u, JIT_FP, v->u.w); + } + else if (jit_swf_p()) + jit_ldxi_d(u, JIT_FP, arg_offset(v->u.w)); + else { + if (jit_arg_reg_p(v->u.w)) + jit_movr_ww_d(u, JIT_RA0 - v->u.w, JIT_RA0 - (v->u.w + 1)); + else + jit_ldxi_d(u, JIT_FP, v->u.w); + } + jit_dec_synth(); +} + +void +_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); + if (jit_cpu.abi) { + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(JIT_FA0 - v->u.w, u); + else + jit_stxi_d(v->u.w, JIT_FP, u); + } + else if (jit_swf_p()) + jit_stxi_d(arg_offset(v->u.w), JIT_FP, u); + else { + if (jit_arg_reg_p(v->u.w)) + jit_movr_d_ww(JIT_RA0 - v->u.w, JIT_RA0 - (v->u.w + 1), u); + else + jit_stxi_d(v->u.w, JIT_FP, u); + } + jit_dec_synth(); +} + +void +_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); + if (jit_cpu.abi) { + if (jit_arg_f_reg_p(v->u.w)) + jit_movi_d(JIT_FA0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + } + else if (jit_swf_p()) { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(arg_offset(v->u.w), JIT_FP, regno); + jit_unget_reg(regno); + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + if (jit_arg_reg_p(v->u.w)) + jit_movr_d_ww(JIT_RA0 - v->u.w, JIT_RA0 - (v->u.w + 1), regno); + else + jit_stxi_d(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi(jit_state_t *_jit, jit_word_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); + if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) { + if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + goto done; + } + } + else { + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr_f_w(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + goto done; + } + } + jit_stxi_f(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); +done: + jit_dec_synth(); +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); + if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) { + if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + /* cannot jit_movi_f in the argument register because + * float arguments are packed, and that would cause + * either an assertion in debug mode, or overwritting + * two registers */ + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_movr_f(JIT_FA0 - _jitc->function->call.argf, regno); + jit_unget_reg(regno); + ++_jitc->function->call.argf; + goto done; + } + } + else { + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi_f_w(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + goto done; + } + } + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); +done: + jit_dec_synth(); +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); + if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) { + if (jit_arg_d_reg_p(_jitc->function->call.argf)) { + if (_jitc->function->call.argf & 1) + ++_jitc->function->call.argf; + jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u); + _jitc->function->call.argf += 2; + goto done; + } + } + else { + if (_jitc->function->call.argi & 1) + ++_jitc->function->call.argi; + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr_d_ww(JIT_RA0 - _jitc->function->call.argi, + JIT_RA0 - (_jitc->function->call.argi + 1), + u); + _jitc->function->call.argi += 2; + goto done; + } + } + if (_jitc->function->call.size & 7) + _jitc->function->call.size += 4; + jit_stxi_d(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_float64_t); +done: + jit_dec_synth(); +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); + if (jit_cpu.abi && !(_jitc->function->call.call & jit_call_varargs)) { + if (jit_arg_d_reg_p(_jitc->function->call.argf)) { + if (_jitc->function->call.argf & 1) + ++_jitc->function->call.argf; + jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u); + _jitc->function->call.argf += 2; + goto done; + } + } + else { + if (_jitc->function->call.argi & 1) + ++_jitc->function->call.argi; + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi_d_ww(JIT_RA0 - _jitc->function->call.argi, + JIT_RA0 - (_jitc->function->call.argi + 1), + u); + _jitc->function->call.argi += 2; + goto done; + } + } + if (_jitc->function->call.size & 7) + _jitc->function->call.size += 4; + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_float64_t); +done: + jit_dec_synth(); +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + jit_int32_t spec; + spec = jit_class(_rvs[regno].spec); + if (spec & jit_class_arg) { + regno = JIT_RA0 - regno; + if (regno >= 0 && regno < node->v.w) + return (1); + if (jit_cpu.abi && spec & jit_class_fpr) { + regno = JIT_FA0 - regno; + if (regno >= 0 && regno < node->w.w) + return (1); + } + } + + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishr, r0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_callr(r0); + node->v.w = _jitc->function->self.argi; + node->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_calli(i0); + node->v.w = _jitc->function->call.argi; + node->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); + return (node); +} + +void +_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_c, r0); + jit_extr_c(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_uc, r0); + jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_s, r0); + jit_extr_s(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_us, r0); + jit_extr_us(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_i, r0); + if (r0 != JIT_RET) + jit_movr(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_f, r0); + if (jit_cpu.abi) { + if (r0 != JIT_FRET) + jit_movr_f(r0, JIT_FRET); + } + else if (r0 != JIT_RET) + jit_movr_w_f(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_d, r0); + if (jit_cpu.abi) { + if (r0 != JIT_FRET) + jit_movr_d(r0, JIT_FRET); + } + else if (r0 != JIT_RET) + jit_movr_ww_d(r0, JIT_RET, _R1); + jit_dec_synth(); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_int32_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_uint8_t *data; + jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + jit_uword_t thumb; +#if DISASSEMBLER + jit_int32_t info_offset; +#endif + jit_int32_t const_offset; + jit_int32_t patch_offset; + } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + + _jitc->function = NULL; + _jitc->thumb = 0; + + jit_reglive_setup(); + + _jitc->consts.data = NULL; + _jitc->consts.offset = _jitc->consts.length = 0; + + undo.word = 0; + undo.node = NULL; + undo.data = NULL; + undo.thumb = 0; +#if DISASSEMBLER + undo.info_offset = +#endif + undo.const_offset = undo.patch_offset = 0; +# define assert_data(node) /**/ +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_vv(name, type) \ + case jit_code_##name##r##type: \ + if (jit_swf_p()) \ + swf_##name##r##type(rn(node->u.w), rn(node->v.w)); \ + else \ + vfp_##name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_vw(name, type) \ + case jit_code_##name##i##type: \ + if (jit_swf_p()) \ + swf_##name##i##type(rn(node->u.w), node->v.w); \ + else \ + vfp_##name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_wv(name, type) \ + case jit_code_##name##i##type: \ + if (jit_swf_p()) \ + swf_##name##i##type(node->u.w, rn(node->v.w)); \ + else \ + vfp_##name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_vvv(name, type) \ + case jit_code_##name##r##type: \ + if (jit_swf_p()) \ + swf_##name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + else \ + vfp_##name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_vvw(name, type) \ + case jit_code_##name##i##type: \ + if (jit_swf_p()) \ + swf_##name##i##type(rn(node->u.w), \ + rn(node->v.w), node->w.w); \ + else \ + vfp_##name##i##type(rn(node->u.w), \ + rn(node->v.w), node->w.w); \ + break +#define case_vvf(name) \ + case jit_code_##name##i_f: \ + assert_data(node); \ + if (jit_swf_p()) \ + swf_##name##i_f(rn(node->u.w), rn(node->v.w), \ + node->w.f); \ + else \ + vfp_##name##i_f(rn(node->u.w), rn(node->v.w), \ + node->w.f); \ + break +#define case_vvd(name) \ + case jit_code_##name##i_d: \ + assert_data(node); \ + if (jit_swf_p()) \ + swf_##name##i_d(rn(node->u.w), rn(node->v.w), \ + node->w.d); \ + else \ + vfp_##name##i_d(rn(node->u.w), rn(node->v.w), \ + node->w.d); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \ + break +#define case_wvv(name, type) \ + case jit_code_##name##i##type: \ + if (jit_swf_p()) \ + swf_##name##i##type(node->u.w, \ + rn(node->v.w), rn(node->w.w)); \ + else \ + vfp_##name##i##type(node->u.w, \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type(_jit->pc.w, \ + rn(node->v.w), rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_bvv(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) { \ + if (jit_swf_p()) \ + swf_##name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else \ + vfp_##name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + } \ + else { \ + if (jit_swf_p()) \ + word = swf_##name##r##type(_jit->pc.w, \ + rn(node->v.w), \ + rn(node->w.w)); \ + else \ + word = vfp_##name##r##type(_jit->pc.w, \ + rn(node->v.w), \ + rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break; +#define case_bvf(name) \ + case jit_code_##name##i_f: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) { \ + if (jit_swf_p()) \ + swf_##name##i_f(temp->u.w, rn(node->v.w), \ + node->w.f); \ + else \ + vfp_##name##i_f(temp->u.w, rn(node->v.w), \ + node->w.f); \ + } \ + else { \ + if (jit_swf_p()) \ + word = swf_##name##i_f(_jit->pc.w, \ + rn(node->v.w), \ + node->w.f); \ + else \ + word = vfp_##name##i_f(_jit->pc.w, \ + rn(node->v.w), \ + node->w.f); \ + patch(word, node); \ + } \ + break +#define case_bvd(name) \ + case jit_code_##name##i_d: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) { \ + if (jit_swf_p()) \ + swf_##name##i_d(temp->u.w, rn(node->v.w), \ + node->w.d); \ + else \ + vfp_##name##i_d(temp->u.w, rn(node->v.w), \ + node->w.d); \ + } \ + else { \ + if (jit_swf_p()) \ + word = swf_##name##i_d(_jit->pc.w, \ + rn(node->v.w), \ + node->w.d); \ + else \ + word = vfp_##name##i_d(_jit->pc.w, \ + rn(node->v.w), \ + node->w.d); \ + patch(word, node); \ + } \ + break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end) + return (NULL); + +#if DEVEL_DISASSEMBLER + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; +#endif + value = jit_classify(node->code); + jit_regarg_set(node, value); + switch (node->code) { + case jit_code_align: + assert(!(node->u.w & (node->u.w - 1)) && + node->u.w <= sizeof(jit_word_t)); + if (node->u.w == sizeof(jit_word_t) && + (word = _jit->pc.w & (sizeof(jit_word_t) - 1))) + nop(sizeof(jit_word_t) - word); + break; + case jit_code_note: case jit_code_name: + if (must_align_p(node->next)) + nop(2); + node->u.w = _jit->pc.w; + break; + case jit_code_label: + if (must_align_p(node->next)) + nop(2); + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + break; + case_rrr(add,); + case_rrw(add,); + case_rrr(addc,); + case_rrw(addc,); + case_rrr(addx,); + case_rrw(addx,); + case_rrr(sub,); + case_rrw(sub,); + case_rrr(subc,); + case_rrw(subc,); + case_rrr(subx,); + case_rrw(subx,); + case_rrw(rsb,); + case_rrr(mul,); + case_rrw(mul,); + case_rrrr(qmul,); + case_rrrw(qmul,); + case_rrrr(qmul, _u); + case_rrrw(qmul, _u); + case_rrr(div,); + case_rrw(div,); + case_rrr(div, _u); + case_rrw(div, _u); + case_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rr(neg,); + case_rr(com,); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_vv(trunc, _f_i); + case_vv(trunc, _d_i); + case_rr(ld, _c); + case_rw(ld, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rr(ld, _i); + case_rw(ld, _i); + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rrr(ldx, _i); + case_rrw(ldx, _i); + case_rr(st, _c); + case_wr(st, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rr(st, _i); + case_wr(st, _i); + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rrr(stx, _i); + case_wrr(stx, _i); + case_rr(hton, _us); + case_rr(hton, _ui); + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), temp->u.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_vvv(add, _f); + case_vvf(add); + case_vvv(sub, _f); + case_vvf(sub); + case_vvf(rsb); + case_vvv(mul, _f); + case_vvf(mul); + case_vvv(div, _f); + case_vvf(div); + case_vv(abs, _f); + case_vv(neg, _f); + case_vv(sqrt, _f); + case_vv(ext, _f); + case_vv(ld, _f); + case_vw(ld, _f); + case_vvv(ldx, _f); + case_vvw(ldx, _f); + case_vv(st, _f); + case_wv(st, _f); + case_vvv(stx, _f); + case_wvv(stx, _f); + case_vv(mov, _f); + case jit_code_movi_f: + assert_data(node); + if (jit_swf_p()) + swf_movi_f(rn(node->u.w), node->v.f); + else + vfp_movi_f(rn(node->u.w), node->v.f); + break; + case_vv(ext, _d_f); + case_vvv(lt, _f); + case_vvf(lt); + case_vvv(le, _f); + case_vvf(le); + case_vvv(eq, _f); + case_vvf(eq); + case_vvv(ge, _f); + case_vvf(ge); + case_vvv(gt, _f); + case_vvf(gt); + case_vvv(ne, _f); + case_vvf(ne); + case_vvv(unlt, _f); + case_vvf(unlt); + case_vvv(unle, _f); + case_vvf(unle); + case_vvv(uneq, _f); + case_vvf(uneq); + case_vvv(unge, _f); + case_vvf(unge); + case_vvv(ungt, _f); + case_vvf(ungt); + case_vvv(ltgt, _f); + case_vvf(ltgt); + case_vvv(ord, _f); + case_vvf(ord); + case_vvv(unord, _f); + case_vvf(unord); + case_bvv(blt, _f); + case_bvf(blt); + case_bvv(ble, _f); + case_bvf(ble); + case_bvv(beq, _f); + case_bvf(beq); + case_bvv(bge, _f); + case_bvf(bge); + case_bvv(bgt, _f); + case_bvf(bgt); + case_bvv(bne, _f); + case_bvf(bne); + case_bvv(bunlt, _f); + case_bvf(bunlt); + case_bvv(bunle, _f); + case_bvf(bunle); + case_bvv(buneq, _f); + case_bvf(buneq); + case_bvv(bunge, _f); + case_bvf(bunge); + case_bvv(bungt, _f); + case_bvf(bungt); + case_bvv(bltgt, _f); + case_bvf(bltgt); + case_bvv(bord, _f); + case_bvf(bord); + case_bvv(bunord, _f); + case_bvf(bunord); + case_vvv(add, _d); + case_vvd(add); + case_vvv(sub, _d); + case_vvd(sub); + case_vvd(rsb); + case_vvv(mul, _d); + case_vvd(mul); + case_vvv(div, _d); + case_vvd(div); + case_vv(abs, _d); + case_vv(neg, _d); + case_vv(sqrt, _d); + case_vv(ext, _d); + case_vv(ld, _d); + case_vw(ld, _d); + case_vvv(ldx, _d); + case_vvw(ldx, _d); + case_vv(st, _d); + case_wv(st, _d); + case_vvv(stx, _d); + case_wvv(stx, _d); + case_vv(mov, _d); + case jit_code_movi_d: + assert_data(node); + if (jit_swf_p()) + swf_movi_d(rn(node->u.w), node->v.d); + else + vfp_movi_d(rn(node->u.w), node->v.d); + break; + case_vv(ext, _f_d); + case_vvv(lt, _d); + case_vvd(lt); + case_vvv(le, _d); + case_vvd(le); + case_vvv(eq, _d); + case_vvd(eq); + case_vvv(ge, _d); + case_vvd(ge); + case_vvv(gt, _d); + case_vvd(gt); + case_vvv(ne, _d); + case_vvd(ne); + case_vvv(unlt, _d); + case_vvd(unlt); + case_vvv(unle, _d); + case_vvd(unle); + case_vvv(uneq, _d); + case_vvd(uneq); + case_vvv(unge, _d); + case_vvd(unge); + case_vvv(ungt, _d); + case_vvd(ungt); + case_vvv(ltgt, _d); + case_vvd(ltgt); + case_vvv(ord, _d); + case_vvd(ord); + case_vvv(unord, _d); + case_vvd(unord); + case_bvv(blt, _d); + case_bvd(blt); + case_bvv(ble, _d); + case_bvd(ble); + case_bvv(beq, _d); + case_bvd(beq); + case_bvv(bge, _d); + case_bvd(bge); + case_bvv(bgt, _d); + case_bvd(bgt); + case_bvv(bne, _d); + case_bvd(bne); + case_bvv(bunlt, _d); + case_bvd(bunlt); + case_bvv(bunle, _d); + case_bvd(bunle); + case_bvv(buneq, _d); + case_bvd(buneq); + case_bvv(bunge, _d); + case_bvd(bunge); + case_bvv(bungt, _d); + case_bvd(bungt); + case_bvv(bltgt, _d); + case_bvd(bltgt); + case_bvv(bord, _d); + case_bvd(bord); + case_bvv(bunord, _d); + case_bvd(bunord); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + flush_consts(); + break; + case jit_code_jmpi: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w, 1); + patch(word, node); + } + } + else + jmpi(node->u.w); + flush_consts(); + break; + case jit_code_callr: + callr(rn(node->u.w)); + break; + case jit_code_calli: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + calli(temp->u.w); + else { + word = calli_p(_jit->pc.w); + patch(word, node); + } + } + else + calli(node->u.w); + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif + undo.data = _jitc->consts.data; + undo.thumb = _jitc->thumb; + undo.const_offset = _jitc->consts.offset; + undo.patch_offset = _jitc->patches.offset; +#if DISASSEMBLER + if (_jitc->data_info.ptr) + undo.info_offset = _jitc->data_info.offset; +#endif + restart_function: + _jitc->again = 0; + prolog(node); + break; + case jit_code_epilog: + assert(_jitc->function == _jitc->functions.ptr + node->w.w); + if (_jitc->again) { + for (temp = undo.node->next; + temp != node; temp = temp->next) { + if (temp->code == jit_code_label || + temp->code == jit_code_epilog) + temp->flag &= ~jit_flag_patch; + } + temp->flag &= ~jit_flag_patch; + node = undo.node; + _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif + invalidate_consts(); + _jitc->consts.data = undo.data; + _jitc->thumb = undo.thumb; + _jitc->consts.offset = undo.const_offset; + _jitc->patches.offset = undo.patch_offset; +#if DISASSEMBLER + if (_jitc->data_info.ptr) + _jitc->data_info.offset = undo.info_offset; +#endif + goto restart_function; + } + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + epilog(node); + _jitc->function = NULL; + flush_consts(); + break; + case jit_code_movr_w_f: + if (jit_swf_p()) + swf_movr_f(rn(node->u.w), rn(node->v.w)); + else + vfp_movr_f(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movr_f_w: + if (jit_swf_p()) + swf_movr_f(rn(node->u.w), rn(node->v.w)); + else + vfp_movr_f(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movi_f_w: + assert_data(node); + if (jit_swf_p()) + swf_movi_f(rn(node->u.w), node->v.f); + else + vfp_movi_f(rn(node->u.w), node->v.f); + break; + case jit_code_movr_ww_d: + if (jit_swf_p()) + swf_movr_d(rn(node->u.w), rn(node->v.w)); + else + vfp_movr_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movr_d_ww: + if (jit_swf_p()) + swf_movr_d(rn(node->u.w), rn(node->w.w)); + else + vfp_movr_d(rn(node->u.w), rn(node->w.w)); + break; + case jit_code_movi_d_ww: + assert_data(node); + if (jit_swf_p()) + swf_movi_d(rn(node->u.w), node->w.d); + else + vfp_movi_d(rn(node->u.w), node->w.d); + break; + case jit_code_va_start: + vastart(rn(node->u.w)); + break; + case jit_code_va_arg: + vaarg(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_va_arg_d: + if (jit_swf_p()) + swf_vaarg_d(rn(node->u.w), rn(node->v.w)); + else + vfp_vaarg_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_live: case jit_code_ellipsis: + case jit_code_va_push: + case jit_code_allocai: case jit_code_allocar: + case jit_code_arg: + case jit_code_arg_f: case jit_code_arg_d: + case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: + break; + default: + abort(); + } + jit_regarg_clr(node, value); + assert(_jitc->regarg == 0 && _jitc->synth == 0); + /* update register live state */ + jit_reglive(node); + + if (_jitc->consts.length && + (_jit->pc.uc - _jitc->consts.data >= 3968 || + (jit_uword_t)_jit->pc.uc - + (jit_uword_t)_jitc->consts.patches[0] >= 3968)) { + /* longest sequence should be 64 bytes, but preventively + * do not let it go past 128 remaining bytes before a flush */ + if (node->next && + node->next->code != jit_code_jmpi && + node->next->code != jit_code_jmpr && + node->next->code != jit_code_epilog) { + /* insert a jump, flush constants and continue */ + word = _jit->pc.w; + assert(!jit_thumb_p()); + B(0); + flush_consts(); + patch_at(arm_patch_jump, word, _jit->pc.w); + } + } + } +#undef case_bvd +#undef case_bvf +#undef case_brw +#undef case_bvv +#undef case_brr +#undef case_wvv +#undef case_wrr +#undef case_vvd +#undef case_vvf +#undef case_vvw +#undef case_rrw +#undef case_vvv +#undef case_rrr +#undef case_wv +#undef case_wr +#undef case_vw +#undef case_vv +#undef case_rw +#undef case_rr + + flush_consts(); + for (offset = 0; offset < _jitc->patches.offset; offset++) { + assert(_jitc->patches.ptr[offset].kind & arm_patch_node); + node = _jitc->patches.ptr[offset].node; + word = _jitc->patches.ptr[offset].inst; + if (!jit_thumb_p() && + (node->code == jit_code_movi || node->code == jit_code_calli)) { + /* calculate where to patch word */ + value = *(jit_int32_t *)word; + assert((value & 0x0f700000) == ARM_LDRI); + /* offset may become negative (-4) if last instruction + * before unconditional branch and data following + * FIXME can this cause issues in the preprocessor prefetch + * or something else? should not, as the constants are after + * an unconditional jump */ + if (value & ARM_P) value = value & 0x00000fff; + else value = -(value & 0x00000fff); + word = word + 8 + value; + } + value = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(_jitc->patches.ptr[offset].kind & ~arm_patch_node, word, value); + } + + jit_flush(_jit->code.ptr, _jit->pc.uc); + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_rewind.c" +# include "jit_arm-cpu.c" +# include "jit_arm-swf.c" +# include "jit_arm-vfp.c" +#undef CODE + +void +jit_flush(void *fptr, void *tptr) +{ +#if defined(__GNUC__) + jit_uword_t i, f, t, s; + + s = sysconf(_SC_PAGE_SIZE); + f = (jit_uword_t)fptr & -s; + t = (((jit_uword_t)tptr) + s - 1) & -s; + for (i = f; i < t; i += s) + __clear_cache((void *)i, (void *)(i + s)); +#endif +} + +void +_emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi_i(rn(r0), rn(r1), i0); +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi_i(i0, rn(r0), rn(r1)); +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (jit_swf_p()) + swf_ldxi_d(rn(r0), rn(r1), i0); + else + vfp_ldxi_d(rn(r0), rn(r1), i0); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_swf_p()) + swf_stxi_d(i0, rn(r0), rn(r1)); + else + vfp_stxi_d(i0, rn(r0), rn(r1)); +} + +static jit_int32_t +_jit_get_reg_pair(jit_state_t *_jit) +{ + /* bypass jit_get_reg() with argument or'ed with jit_class_chk + * and try to find an consecutive, even free register pair, or + * return JIT_NOREG if fail, as the cost of spills is greater + * than splitting a double load/store in two operations. */ + if (jit_reg_free_p(_R0) && jit_reg_free_p(_R1)) { + jit_regset_setbit(&_jitc->regarg, _R0); + jit_regset_setbit(&_jitc->regarg, _R1); + return (_R0); + } + if (jit_reg_free_p(_R2) && jit_reg_free_p(_R3)) { + jit_regset_setbit(&_jitc->regarg, _R2); + jit_regset_setbit(&_jitc->regarg, _R3); + return (_R2); + } + if (jit_reg_free_p(_R4) && jit_reg_free_p(_R5)) { + jit_regset_setbit(&_jitc->regarg, _R4); + jit_regset_setbit(&_jitc->regarg, _R5); + return (_R4); + } + if (jit_reg_free_p(_R6) && jit_reg_free_p(_R7)) { + jit_regset_setbit(&_jitc->regarg, _R6); + jit_regset_setbit(&_jitc->regarg, _R7); + return (_R6); + } + if (jit_reg_free_p(_R8) && jit_reg_free_p(_R9)) { + jit_regset_setbit(&_jitc->regarg, _R8); + jit_regset_setbit(&_jitc->regarg, _R9); + return (_R8); + } + return (JIT_NOREG); +} + +static void +_jit_unget_reg_pair(jit_state_t *_jit, jit_int32_t reg) +{ + jit_unget_reg(reg); + switch (reg) { + case _R0: jit_unget_reg(_R1); break; + case _R2: jit_unget_reg(_R3); break; + case _R4: jit_unget_reg(_R5); break; + case _R6: jit_unget_reg(_R7); break; + case _R8: jit_unget_reg(_R9); break; + default: abort(); + } +} + +/* A prolog must be aligned at mod 4 bytes boundary. + * This condition was not being required to be tested by + * accident previously, but with the jit_frame and jit_tramp + * code it is required */ +static jit_bool_t +_must_align_p(jit_state_t *_jit, jit_node_t *node) +{ + if (jit_thumb_p() && (_jit->pc.w & 3)) { + for (; node; node = node->next) { + switch (node->code) { + case jit_code_note: + case jit_code_name: + case jit_code_label: + break; + case jit_code_prolog: + return (1); + default: + return (0); + } + } + } + return (0); +} + +static void +_load_const(jit_state_t *_jit, jit_bool_t uniq, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_word_t d; + jit_word_t base; + jit_int32_t *data; + jit_int32_t size; + jit_int32_t offset; + + assert(!jit_thumb_p()); + if (!uniq) { + /* use zero, a valid directly encoded immediate, to avoid the + * need of a bitmask to know what offsets will be patched, so + * that comparison will always fail for constants that cannot + * be encoded */ + assert(i0 != 0); + + /* Actually, code is (currently at least) not self modifying, + * so, any value reachable backwards is valid as a constant. */ + + /* FIXME a quickly updateable/mutable hash table could be + * better here, but most times only a few comparisons + * should be done + */ + + /* search in previous constant pool */ + if ((data = (jit_int32_t *)_jitc->consts.data)) { + w = (jit_word_t)data; + /* maximum backwards offset */ + base = (_jit->pc.w + 8) - 4092; + if (base <= w) + /* can scan all possible available backward constants */ + base = 0; + else + base = (base - w) >> 2; + size = _jitc->consts.size >> 2; + for (offset = size - 1; offset >= base; offset--) { + if (data[offset] == i0) { + w = (jit_word_t)(data + offset); + d = (_jit->pc.w + 8) - w; + LDRIN(r0, _R15_REGNO, d); + return; + } + } + } + } + else + assert(i0 == 0); + + _jitc->consts.patches[_jitc->consts.offset++] = _jit->pc.w; + /* (probably) positive forward offset */ + LDRI(r0, _R15_REGNO, 0); + + if (!uniq) { + /* search already requested values */ + for (offset = 0; offset < _jitc->consts.length; offset++) { + if (_jitc->consts.values[offset] == i0) { + _jitc->consts.patches[_jitc->consts.offset++] = offset; + return; + } + } + } + +#if DEBUG + /* cannot run out of space because of limited range + * but assert anyway to catch logic errors */ + assert(_jitc->consts.length < 1024); + assert(_jitc->consts.offset < 2048); +#endif + _jitc->consts.patches[_jitc->consts.offset++] = _jitc->consts.length; + _jitc->consts.values[_jitc->consts.length++] = i0; +} + +static void +_flush_consts(jit_state_t *_jit) +{ + jit_word_t word; + jit_int32_t offset; + + /* if no forward constants */ + if (!_jitc->consts.length) + return; + assert(!jit_thumb_p()); + word = _jit->pc.w; + _jitc->consts.data = _jit->pc.uc; + _jitc->consts.size = _jitc->consts.length << 2; + /* FIXME check will not overrun, otherwise, need to reallocate + * code buffer and start over */ + jit_memcpy(_jitc->consts.data, _jitc->consts.values, _jitc->consts.size); + _jit->pc.w += _jitc->consts.size; + +#if DISASSEMBLER + if (_jitc->data_info.ptr) { + if (_jitc->data_info.offset >= _jitc->data_info.length) { + jit_realloc((jit_pointer_t *)&_jitc->data_info.ptr, + _jitc->data_info.length * sizeof(jit_data_info_t), + (_jitc->data_info.length + 1024) * + sizeof(jit_data_info_t)); + _jitc->data_info.length += 1024; + } + _jitc->data_info.ptr[_jitc->data_info.offset].code = word; + _jitc->data_info.ptr[_jitc->data_info.offset].length = _jitc->consts.size; + ++_jitc->data_info.offset; + } +#endif + + for (offset = 0; offset < _jitc->consts.offset; offset += 2) + patch_at(arm_patch_load, _jitc->consts.patches[offset], + word + (_jitc->consts.patches[offset + 1] << 2)); + _jitc->consts.length = _jitc->consts.offset = 0; +} + +/* to be called if needing to start over a function */ +static void +_invalidate_consts(jit_state_t *_jit) +{ + /* if no forward constants */ + if (_jitc->consts.length) + _jitc->consts.length = _jitc->consts.offset = 0; +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + jit_int32_t kind; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) { + flag = node->v.n->flag; + kind = arm_patch_word; + } + else { + flag = node->u.n->flag; + if (node->code == jit_code_calli || + (node->code == jit_code_jmpi && !(node->flag & jit_flag_node))) + kind = arm_patch_word; + else + kind = arm_patch_jump; + } + assert(!(flag & jit_flag_patch)); + kind |= arm_patch_node; + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].kind = kind; + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} diff --git a/deps/lightning/lib/jit_disasm.c b/deps/lightning/lib/jit_disasm.c new file mode 100644 index 0000000..15b91b9 --- /dev/null +++ b/deps/lightning/lib/jit_disasm.c @@ -0,0 +1,429 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include <lightning.h> +#include <lightning/jit_private.h> +#if DISASSEMBLER +# include <dis-asm.h> +#endif + +/* + * Prototypes + */ +#if DISASSEMBLER +static int +disasm_compare_symbols(const void *ap, const void *bp); + +static void +disasm_print_address(bfd_vma addr, struct disassemble_info *info); + +#define disassemble(u, v) _disassemble(_jit, u, v) +static void +_disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length); +#endif + +/* + * Initialization + */ +#if DISASSEMBLER +static bfd *disasm_bfd; +static disassemble_info disasm_info; +static disassembler_ftype disasm_print; +static asymbol **disasm_symbols; +static asymbol *disasm_synthetic; +static long disasm_num_symbols; +static long disasm_num_synthetic; +static jit_state_t *disasm_jit; +#define disasm_stream stdout +#endif + +/* + * Implementation + */ +void +jit_init_debug(const char *progname) +{ +#if DISASSEMBLER + bfd_init(); + + if (progname) + disasm_bfd = bfd_openr(progname, NULL); + if (disasm_bfd == NULL) { +#if defined(__linux__) + disasm_bfd = bfd_openr("/proc/self/exe", NULL); + if (disasm_bfd == NULL) +#endif + return; + } + bfd_check_format(disasm_bfd, bfd_object); + bfd_check_format(disasm_bfd, bfd_archive); + INIT_DISASSEMBLE_INFO(disasm_info, disasm_stream, fprintf); +# if defined(__i386__) || defined(__x86_64__) + disasm_info.arch = bfd_arch_i386; +# if defined(__x86_64__) +# if __WORDSIZE == 32 + disasm_info.mach = bfd_mach_x64_32; +# else + disasm_info.mach = bfd_mach_x86_64; +# endif +# else + disasm_info.mach = bfd_mach_i386_i386; +# endif +# endif +# if defined(__powerpc__) + disasm_info.arch = bfd_arch_powerpc; + disasm_info.mach = bfd_mach_ppc64; +# if HAVE_DISASSEMBLE_INIT_FOR_TARGET + disassemble_init_for_target(&disasm_info); +# elif HAVE_DISASSEMBLE_INIT_POWERPC + disassemble_init_powerpc(&disasm_info); +# endif +# if defined(__powerpc64__) + disasm_info.disassembler_options = "64"; +# endif +# if HAVE_DISASSEMBLE_INIT_FOR_TARGET + disassemble_init_for_target(&disasm_info); +# elif HAVE_DISASSEMBLE_INIT_POWERPC + disassemble_init_powerpc(&disasm_info); +# endif +# endif +# if defined(__sparc__) + disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG; +# endif +# if defined(__s390__) || defined(__s390x__) + disasm_info.arch = bfd_arch_s390; +# if __WORDSIZE == 32 + disasm_info.mach = bfd_mach_s390_31; +# else + disasm_info.mach = bfd_mach_s390_64; +# endif + disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG; + disasm_info.disassembler_options = "zarch"; +# endif +# if defined(__alpha__) + disasm_info.arch = bfd_arch_alpha; + disasm_info.mach = bfd_mach_alpha_ev6; +# endif +# if defined(__hppa__) + disasm_info.arch = bfd_arch_hppa; + disasm_info.mach = bfd_mach_hppa10; +# endif +# if defined(__riscv) + disasm_info.arch = bfd_arch_riscv; +# if __WORDSIZE == 32 + disasm_info.mach = bfd_mach_riscv32; +# else + disasm_info.mach = bfd_mach_riscv64; +# endif +# endif + disasm_info.print_address_func = disasm_print_address; + +# if BINUTILS_2_29 + disasm_print = disassembler(disasm_info.arch, __BYTE_ORDER == __BIG_ENDIAN, + disasm_info.mach, disasm_bfd); +# else + disasm_print = disassembler(disasm_bfd); +# endif + assert(disasm_print); + + if (bfd_get_file_flags(disasm_bfd) & HAS_SYMS) { + asymbol **in; + asymbol **out; + asymbol *symbol; + long offset; + long sym_count; + long dyn_count; + long sym_storage; + long dyn_storage; + + if ((sym_storage = bfd_get_symtab_upper_bound(disasm_bfd)) >= 0) { + + if (bfd_get_file_flags(disasm_bfd) & DYNAMIC) { + dyn_storage = bfd_get_dynamic_symtab_upper_bound(disasm_bfd); +# if defined(__alpha__) + /* XXX */ + if (dyn_storage < 0) + dyn_storage = 0; +# else + assert(dyn_storage >= 0); +# endif + } + else + dyn_storage = 0; + + jit_alloc((jit_pointer_t *)&disasm_symbols, + (sym_storage + dyn_storage) * sizeof(asymbol *)); + sym_count = bfd_canonicalize_symtab(disasm_bfd, disasm_symbols); + assert(sym_count >= 0); + if (dyn_storage) { + dyn_count = bfd_canonicalize_dynamic_symtab(disasm_bfd, + disasm_symbols + + sym_count); + assert(dyn_count >= 0); + } + else + dyn_count = 0; + disasm_num_symbols = sym_count + dyn_count; + + disasm_num_synthetic = bfd_get_synthetic_symtab(disasm_bfd, + sym_count, + disasm_symbols, + dyn_count, + disasm_symbols + + sym_count, + &disasm_synthetic); + if (disasm_num_synthetic > 0) { + jit_realloc((jit_pointer_t *)&disasm_symbols, + (sym_storage + dyn_storage) * sizeof(asymbol *), + (sym_storage + dyn_storage + disasm_num_synthetic) * + sizeof(asymbol *)); + for (offset = 0; offset < disasm_num_synthetic; offset++) + disasm_symbols[disasm_num_symbols++] = + disasm_synthetic + offset; + } + + /* remove symbols not useful for disassemble */ + in = out = disasm_symbols; + for (offset = 0; offset < disasm_num_symbols; offset++) { + symbol = *in++; + if (symbol->name && + symbol->name[0] != '\0' && + !(symbol->flags & (BSF_DEBUGGING | BSF_SECTION_SYM)) && + !bfd_is_und_section(symbol->section) && + !bfd_is_com_section(symbol->section)) + *out++ = symbol; + } + disasm_num_symbols = out - disasm_symbols; + qsort(disasm_symbols, disasm_num_symbols, + sizeof(asymbol *), disasm_compare_symbols); + } + } +#endif +} + +void +jit_finish_debug(void) +{ +#if DISASSEMBLER + if (disasm_synthetic) + jit_free((jit_pointer_t *)&disasm_synthetic); + if (disasm_symbols) + jit_free((jit_pointer_t *)&disasm_symbols); + if (disasm_bfd) + bfd_close (disasm_bfd); +#endif +} + +void +_jit_disassemble(jit_state_t *_jit) +{ +#if DISASSEMBLER + if (disasm_bfd) { +# if defined(__arm__) + /* FIXME add mapping for prolog switching to arm and possible jump + * before first prolog also in arm mode */ + disasm_info.disassembler_options = jit_cpu.thumb ? "force-thumb" : ""; +# endif + + disassemble(_jit->code.ptr, _jit->pc.uc - _jit->code.ptr); + } +#endif +} + +#if DISASSEMBLER +/* Based on objdump source */ +static int +disasm_compare_symbols(const void *ap, const void *bp) +{ + const asymbol *a = *(const asymbol **)ap; + const asymbol *b = *(const asymbol **)bp; + + if (bfd_asymbol_value(a) > bfd_asymbol_value(b)) + return (1); + if (bfd_asymbol_value(a) < bfd_asymbol_value(b)) + return (-1); + return (0); +} + +#if __WORDSIZE == 32 +# define address_buffer_length 16 +# define address_buffer_format "%llx" +#else +# define address_buffer_length 32 +# define address_buffer_format "%lx" +#endif +static void +disasm_print_address(bfd_vma addr, struct disassemble_info *info) +{ + char *name; + char *file; + int line; + char buffer[address_buffer_length]; + + sprintf(buffer, address_buffer_format, (long long)addr); + (*info->fprintf_func)(info->stream, "0x%s", buffer); + +# define _jit disasm_jit +# undef jit_pointer_p +# define jit_pointer_p(u) \ + ((u) >= _jit->code.ptr && (u) < _jit->pc.uc) + if (jit_pointer_p((jit_uint8_t *)(jit_word_t)addr)) { + if (jit_get_note((jit_uint8_t *)(jit_word_t)addr, &name, &file, &line)) + (*info->fprintf_func)(info->stream, " %s:%s:%d", + name ? name : "", + file ? file : "", + line); + } +# undef jit_pointer_p +# undef _jit + else if (disasm_num_symbols) { + long low; + long high; + long offset; + asymbol *symbol; + + low = 0; + high = disasm_num_symbols; + do { + offset = (low + high) >> 1; + symbol = disasm_symbols[offset]; + if (bfd_asymbol_value(symbol) > addr) + high = offset - 1; + else if (bfd_asymbol_value(symbol) < addr) + low = offset + 1; + else + break; + } while (low < high); + + if (offset >= 0 && offset < disasm_num_symbols) { + if (bfd_asymbol_value(symbol) < addr) { + while (++offset < disasm_num_symbols) { + symbol = disasm_symbols[offset]; + if (bfd_asymbol_value(symbol) >= addr) + break; + } + } + else if (bfd_asymbol_value(symbol) > addr) { + while (offset--) { + if (bfd_asymbol_value(disasm_symbols[offset]) < addr) + break; + symbol = disasm_symbols[offset]; + } + } + if (bfd_asymbol_value(symbol) == addr) + (*info->fprintf_func)(info->stream, " # %s", symbol->name); + } + } +} + +static void +_disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length) +{ + int bytes; + char *name, *old_name; + char *file, *old_file; + int line, old_line; +#if __arm__ + jit_int32_t offset; + jit_bool_t data_info; + jit_int32_t data_offset; +#endif + bfd_vma pc = (jit_uword_t)code; + bfd_vma end = (jit_uword_t)code + length; + char buffer[address_buffer_length]; +#if DEVEL_DISASSEMBLER + jit_node_t *node; + jit_uword_t prevw; +#endif + +#if __arm__ + data_info = _jitc && _jitc->data_info.ptr; + data_offset = 0; +#endif + disasm_info.buffer = code; + disasm_info.buffer_vma = (jit_uword_t)code; + disasm_info.buffer_length = length; + old_file = old_name = NULL; + old_line = 0; + disasm_jit = _jit; +#if DEVEL_DISASSEMBLER + node = _jitc->head; + prevw = pc; +#endif + while (pc < end) { +#if DEVEL_DISASSEMBLER + while (node && (jit_uword_t)(prevw + node->offset) < (jit_uword_t)pc) { + prevw += node->offset; + node = node->next; + } + while (node && (jit_uword_t)(prevw + node->offset) == (jit_uword_t)pc) { + jit_print_node(node); + fputc('\n', stdout); + prevw += node->offset; + node = node->next; + } +#endif +#if __arm__ + again: + if (data_info) { + while (_jitc->data_info.ptr[data_offset].code < pc) { + if (++data_offset >= _jitc->data_info.length) { + data_info = 0; + goto again; + } + } + if (pc == _jitc->data_info.ptr[data_offset].code) { + offset = _jitc->data_info.ptr[data_offset].length; + for (; offset >= 4; offset -= 4, pc += 4) { + bytes = sprintf(buffer, address_buffer_format, pc); + (*disasm_info.fprintf_func)(disasm_stream, + "%*c0x%s\t.data\t0x%08x\n", + 16 - bytes, ' ', buffer, + *(jit_uint32_t *) + (jit_uint32_t)pc); + } + /* reset disassemble information instead of attempting + * to hack the arm specific backend data structures to + * tell it to forward the required number of bytes. */ + disasm_info.buffer = (jit_pointer_t)(jit_uint32_t)pc; + disasm_info.buffer_vma = (jit_uword_t)pc; + if ((disasm_info.buffer_length = end - pc) <= 0) + break; + } + } +#endif + if (jit_get_note((jit_uint8_t *)(jit_word_t)pc, &name, &file, &line) && + (name != old_name || file != old_file || line != old_line)) { + (*disasm_info.fprintf_func)(disasm_stream, "# %s:%s:%d\n", + name ? name : "", + file ? file : "", + line); + old_name = name; + old_file = file; + old_line = line; + } + + bytes = sprintf(buffer, address_buffer_format, (long long)pc); + (*disasm_info.fprintf_func)(disasm_stream, "%*c0x%s\t", + 16 - bytes, ' ', buffer); + pc += (*disasm_print)(pc, &disasm_info); + putc('\n', disasm_stream); + } +} +#endif diff --git a/deps/lightning/lib/jit_hppa-cpu.c b/deps/lightning/lib/jit_hppa-cpu.c new file mode 100644 index 0000000..db5a36a --- /dev/null +++ b/deps/lightning/lib/jit_hppa-cpu.c @@ -0,0 +1,2796 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +typedef struct idiv { + int quo; + int rem; +} idiv_t; + +typedef struct udiv { + unsigned int quo; + unsigned int rem; +} udiv_t; + +/* 16 spill bytes; -52 for first actual stack argument */ +#define params_offset -32 +/* Assume all callee save registers may need to be spilled */ +#define alloca_offset 192 +#define _R0_REGNO 0 +#define _R1_REGNO 1 +#define _RP_REGNO 2 +#define _FP_REGNO 3 +#define _R19_REGNO 19 +#define _R23_REGNO 23 +#define _R24_REGNO 24 +#define _R25_REGNO 25 +#define _R26_REGNO 26 +#define _R28_REGNO 28 +#define _R29_REGNO 29 +#define _SP_REGNO 30 +#define _R31_REGNO 31 +#define _CR11_REGNO 11 +#define ii(v) *_jit->pc.ui++ = v +#define f1(o,b,t,i) _f1(_jit,o,b,t,i) +static void _f1(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +#define f2(o,b,r,i,j) _f2(_jit,o,b,r,i,j) +static void _f2(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f3(o,b,t,i,j) _f3(_jit,o,b,t,i,j) +static void _f3(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +#define f4(o,b,x,s,u,y,c,z,m,t) _f4(_jit,o,b,x,s,u,y,c,z,m,t) +static void _f4(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f5(o,b,i,s,a,y,c,z,m,t) _f5(_jit,o,b,i,s,a,y,c,z,m,t) +static void _f5(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f6(o,b,r,s,a,x,c,y,m,i) _f6(_jit,o,b,r,s,a,x,c,y,m,i) +static void _f6(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f7(o,r,i) _f7(_jit,o,r,i) +static void _f7(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define f8(o,r2,r1,cf,e1,x,e2,y,d,t) _f8(_jit,o,r2,r1,cf,e1,x,e2,y,d,t) +static void _f8(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +#define f9(o,r,t,cf,e1,im) _f9(_jit,o,r,t,cf,e1,im) +static void _f9(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +#define f10(o,r2,r1,u,v,w,x,sa,y,t) _f10(_jit,o,r2,r1,u,v,w,x,sa,y,t) +static void _f10(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f11(o,r2,r1,c,x,y,z,u,t) _f11(_jit,o,r2,r1,c,x,y,z,u,t) +static void _f11(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f12(o,r,t,c,x,se,y,c1,z,clen) _f12(_jit,o,r,t,c,x,se,y,c1,z,clen) +static void _f12(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f13(o,t,r,c,x,nz,c1,clen) _f13(_jit,o,t,r,c,x,nz,c1,clen) +static void _f13(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +#define f13x(o,t,i,c,x,nz,c1,clen) _f13x(_jit,o,t,i,c,x,nz,c1,clen) +static void _f13x(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f14(o,r2,r1,c,x,cp,y,cpos,t) _f14(_jit,o,r2,r1,c,x,cp,y,cpos,t) +static void _f14(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f15(o,r,t,c,c1,p,se,pos,clen) _f15(_jit,o,r,t,c,c1,p,se,pos,clen) +static void _f15(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f16(o,t,r,c,c1,cp,nz,cpos,clen) _f16(_jit,o,t,r,c,c1,cp,nz,cpos,clen) +static void _f16(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f16x(o,t,i,c,c1,cp,nz,cpos,clen) _f16x(_jit,o,t,i,c,c1,cp,nz,cpos,clen) +static void _f16x(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f17(o,r2,r1,c,i,n) _f17(_jit,o,r2,r1,c,i,n) +static void _f17(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f17x(o,r2,r1,c,i,n) _f17x(_jit,o,r2,r1,c,i,n) +static void _f17x(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f18(o,p,r,c,i,n) _f18(_jit,o,p,r,c,i,n) +static void _f18(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f19(o,b,s,i,n) _f19(_jit,o,b,s,i,n) +static void _f19(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f20(o,t,i,g,n) _f20(_jit,o,t,i,g,n) +static void _f20(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +#define f21(o,t,x,y,n) _f21(_jit,o,t,x,y,n) +static void _f21(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +#define f22(o,b,x,r,n,p) _f22(_jit,o,b,x,r,n,p) +static void _f22(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f23(o,a,b,c,d,e,f,g,h) _f23(_jit,o,a,b,c,d,e,f,g,h) +static void _f23(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f24(o,b,x,s,y,m,r) _f24(_jit,o,b,x,s,y,m,r) +static void _f24(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f25(o,b,i,s,y,m,r) _f25(_jit,o,b,i,s,y,m,r) +static void _f25(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f26(o,b,x,s,y,m,r) _f26(_jit,o,b,x,s,y,m,r) +static void _f26(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f27(o,i,j) _f27(_jit,o,i,j) +static void _f27(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f28(o,i) _f28(_jit,o,i) +static void _f28(jit_state_t*,jit_int32_t,jit_int32_t) maybe_unused; +#define f29(o,r,x,s,y,t) _f29(_jit,o,r,x,s,y,t) +static void _f29(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f30(o,b,r,s,x,y,t) _f30(_jit,o,b,r,s,x,y,t) +static void _f30(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f31(o,t,r,v,x,y) _f31(_jit,o,t,r,v,x,y) +static void _f31(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f33(o,x,r,y,z,u) _f33(_jit,o,x,r,y,z,u) +static void _f33(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f34(o,o1,x,sf,n,o2) _f34(_jit,o,o1,x,sf,n,o2) +static void _f34(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f35(o,op,x,sf,n,t) _f35(_jit,o,op,x,sf,n,t) +static void _f35(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f36(o,r,o1,x,sf,n,o2) _f36(_jit,o,r,o1,x,sf,n,o2) +static void _f36(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f37(o,r2,r1,o1,x,sf,n,o2) _f37(_jit,o,r2,r1,o1,x,sf,n,o2) +static void _f37(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f38(o,s,u,n) _f38(_jit,o,s,u,n) +static void _f38(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +/* nulify next instruction if condition is met with addition */ +#define ADD_CF_NV 0 /* never */ +#define ADD_CF_EQ 2 /* O1 == -O2 (word) */ +#define ADD_CF_LT 4 /* O1 < -O2 (signed)*/ +#define ADD_CF_LE 6 /* O1 <= -O2 (signed) */ +#define ADD_CF_NUV 8 /* O1 + O2 does not overflow (unsigned) */ +#define ADD_CF_ZNV 10 /* O1 + O2 is zero or no overflow (unsigned) */ +#define ADD_CF_SV 12 /* O1 + O2 overflows (signed) */ +#define ADD_CF_OD 14 /* O1 + O2 is odd */ +#define ADD_CF_TR 1 /* always */ +#define ADD_CF_NE 3 /* O1 != -O2 */ +#define ADD_CF_GE 5 /* O1 >= -O2 (signed) */ +#define ADD_CF_GT 7 /* O1 > -O2 (signed) */ +#define ADD_CF_UV 9 /* O1 + O2 overflows (unsigned) */ +#define ADD_CF_VNZ 11 /* O1 + O2 is nonzero and overflows (unsigned) */ +#define ADD_CF_NSV 13 /* O1 + O2 does not overflow (signed) */ +#define ADD_CF_EV 15 /* O1 + O2 is even */ +#define ADD_EN_NONE 6 /* none */ +#define ADD_EN_C 7 /* with carry */ +#define ADD_EN_L 10 /* logical */ +#define ADD_EN_TSV 12 /* trap on signed overflow */ +#define ADD_EN_C_TSV 13 /* with carry and trap on signed overflow */ +#define ADDI_OE_TC 0 /* trap on condition */ +#define ADDI_OE_TSV_TC 1 /* trap on signed overflow or condition */ +#define ADDI_OE_NONE 2 /* none */ +#define ADDI_OE_TSV 3 /* trap on signed overflow */ +#define ADD_(en,cf,r1,r2,t) f8(0x2,r2,r1,cf,en>>2,1,en&1,0,0,t) +#define ADD(r1,r2,t) ADD_(ADD_EN_NONE,ADD_CF_NV,r1,r2,t) +#define ADD_C(r1,r2,t) ADD_(ADD_EN_C,ADD_CF_NV,r1,r2,t) +#define ADD_L(r1,r2,t) ADD_(ADD_EN_L,ADD_CF_NV,r1,r2,t) +#define ADDB_(cc,r1,r2,t) f17(0x28|((cc&1)<<1),r2,r1,cc>>1,t,0) +#define ADDB(r1,r2,t) ADDB_(ADD_CF_NV,r1,r2,t) +#define ADDB_EQ(r1,r2,t) ADDB_(ADD_CF_EQ,r1,r2,t) +#define ADDB_LT(r1,r2,t) ADDB_(ADD_CF_LT,r1,r2,t) +#define ADDB_LE(r1,r2,t) ADDB_(ADD_CF_LE,r1,r2,t) +#define ADDB_NUV(r1,r2,t) ADDB_(ADD_CF_NUV,r1,r2,t) +#define ADDB_ZNV(r1,r2,t) ADDB_(ADD_CF_ZNV,r1,r2,t) +#define ADDB_SV(r1,r2,t) ADDB_(ADD_CF_SV,r1,r2,t) +#define ADDB_OD(r1,r2,t) ADDB_(ADD_CF_OD,r1,r2,t) +#define ADDB_TR(r1,r2,t) ADDB_(ADD_CF_TR,r1,r2,t) +#define ADDB_NE(r1,r2,t) ADDB_(ADD_CF_NE,r1,r2,t) +#define ADDB_GE(r1,r2,t) ADDB_(ADD_CF_GE,r1,r2,t) +#define ADDB_GT(r1,r2,t) ADDB_(ADD_CF_GT,r1,r2,t) +#define ADDB_UV(r1,r2,t) ADDB_(ADD_CF_UV,r1,r2,t) +#define ADDB_VNZ(r1,r2,t) ADDB_(ADD_CF_VNZ,r1,r2,t) +#define ADDB_NSV(r1,r2,t) ADDB_(ADD_CF_NSV,r1,r2,t) +#define ADDB_EV(r1,r2,t) ADDB_(ADD_CF_EV,r2,r1,t) +#define ADDB_N_(cc,r1,r2,t) f17(0x28|((cc&1)<<1),r2,r1,cc>>1,t,1) +#define ADDB_N(r1,r2,t) ADDB_N_(ADD_CF_NV,r1,r2,t) +#define ADDB_N_EQ(r1,r2,t) ADDB_N_(ADD_CF_EQ,r1,r2,t) +#define ADDB_N_LT(r1,r2,t) ADDB_N_(ADD_CF_LT,r1,r2,t) +#define ADDB_N_LE(r1,r2,t) ADDB_N_(ADD_CF_LE,r1,r2,t) +#define ADDB_N_NUV(r1,r2,t) ADDB_N_(ADD_CF_NUV,r1,r2,t) +#define ADDB_N_ZNV(r1,r2,t) ADDB_N_(ADD_CF_ZNV,r1,r2,t) +#define ADDB_N_SV(r1,r2,t) ADDB_N_(ADD_CF_SV,r1,r2,t) +#define ADDB_N_OD(r1,r2,t) ADDB_N_(ADD_CF_OD,r1,r2,t) +#define ADDB_N_TR(r1,r2,t) ADDB_N_(ADD_CF_TR,r1,r2,t) +#define ADDB_N_NE(r1,r2,t) ADDB_N_(ADD_CF_NE,r1,r2,t) +#define ADDB_N_GE(r1,r2,t) ADDB_N_(ADD_CF_GE,r1,r2,t) +#define ADDB_N_GT(r1,r2,t) ADDB_N_(ADD_CF_GT,r1,r2,t) +#define ADDB_N_UV(r1,r2,t) ADDB_N_(ADD_CF_UV,r1,r2,t) +#define ADDB_N_VNZ(r1,r2,t) ADDB_N_(ADD_CF_VNZ,r1,r2,t) +#define ADDB_N_NSV(r1,r2,t) ADDB_N_(ADD_CF_NSV,r1,r2,t) +#define ADDB_N_EV(r1,r2,t) ADDB_N_(ADD_CF_EV,r1,r2,t) +#define ADDI_(ec,cf,i,r,t) f9(0x2c|(ec>>1),r,t,cf,ec&1,i) +#define ADDI(i,r,t) ADDI_(ADDI_OE_NONE,ADD_CF_NV,i,r,t) +#define ADDIB_(cc,i,r,t) f17x(0x29|((cc&1)<<1),r,i,cc>>1,t,0) +#define ADDIB(i,r,t) ADDIB_(ADD_CF_NV,i,r,t) +#define ADDIB_EQ(i,r,t) ADDIB_(ADD_CF_EQ,i,r,t) +#define ADDIB_LT(i,r,t) ADDIB_(ADD_CF_LT,i,r,t) +#define ADDIB_LE(i,r,t) ADDIB_(ADD_CF_LE,i,r,t) +#define ADDIB_NUV(i,r,t) ADDIB_(ADD_CF_NUV,i,r,t) +#define ADDIB_ZNV(i,r,t) ADDIB_(ADD_CF_ZNV,i,r,t) +#define ADDIB_SV(i,r,t) ADDIB_(ADD_CF_SV,i,r,t) +#define ADDIB_OD(i,r,t) ADDIB_(ADD_CF_OD,i,r,t) +#define ADDIB_TR(i,r,t) ADDIB_(ADD_CF_TR,i,r,t) +#define ADDIB_NE(i,r,t) ADDIB_(ADD_CF_NE,i,r,t) +#define ADDIB_GE(i,r,t) ADDIB_(ADD_CF_GE,i,r,t) +#define ADDIB_GT(i,r,t) ADDIB_(ADD_CF_GT,i,r,t) +#define ADDIB_UV(i,r,t) ADDIB_(ADD_CF_UV,i,r,t) +#define ADDIB_VNZ(i,r,t) ADDIB_(ADD_CF_VNZ,i,r,t) +#define ADDIB_NSV(i,r,t) ADDIB_(ADD_CF_NSV,i,r,t) +#define ADDIB_EV(i,r,t) ADDIB_(ADD_CF_EV,i,r,t) +#define ADDIB_N_(cc,i,r,t) f17x(0x29|((cc&1)<<1),r,i,cc>>1,t,1) +#define ADDIB_N(i,r,t) ADDIB_N_(ADD_CF_NV,i,r,t) +#define ADDIB_N_EQ(i,r,t) ADDIB_N_(ADD_CF_EQ,i,r,t) +#define ADDIB_N_LT(i,r,t) ADDIB_N_(ADD_CF_LT,i,r,t) +#define ADDIB_N_LE(i,r,t) ADDIB_N_(ADD_CF_LE,i,r,t) +#define ADDIB_N_NUV(i,r,t) ADDIB_N_(ADD_CF_NUV,i,r,t) +#define ADDIB_N_ZNV(i,r,t) ADDIB_N_(ADD_CF_ZNV,i,r,t) +#define ADDIB_N_SV(i,r,t) ADDIB_N_(ADD_CF_SV,i,r,t) +#define ADDIB_N_OD(i,r,t) ADDIB_N_(ADD_CF_OD,i,r,t) +#define ADDIB_N_TR(i,r,t) ADDIB_N_(ADD_CF_TR,i,r,t) +#define ADDIB_N_NE(i,r,t) ADDIB_N_(ADD_CF_NE,i,r,t) +#define ADDIB_N_GE(i,r,t) ADDIB_N_(ADD_CF_GE,i,r,t) +#define ADDIB_N_GT(i,r,t) ADDIB_N_(ADD_CF_GT,i,r,t) +#define ADDIB_N_UV(i,r,t) ADDIB_N_(ADD_CF_UV,i,r,t) +#define ADDIB_N_VNZ(i,r,t) ADDIB_N_(ADD_CF_VNZ,i,r,t) +#define ADDIB_N_NSV(i,r,t) ADDIB_N_(ADD_CF_NSV,i,r,t) +#define ADDIB_N_EV(i,r,t) ADDIB_N_(ADD_CF_EV,0,i,r,t) +#define ADDIL(i,r) f7(0xa,r,i) +#define LOG_CC_NV 0 /* never */ +#define LOG_CC_EQ 1 /* all bits are 0 */ +#define LOG_CC_LT 2 /* leftmost bit is 1 */ +#define LOG_CC_LE 3 /* leftmost bit is 1 or all bits are 0 */ +#define LOG_CC_OD 7 /* rightmost bit is 1 */ +#define LOG_CC_TR 8 /* always */ +#define LOG_CC_NE 9 /* some bits are 1 */ +#define LOG_CC_GE 10 /* leftmost bit is 0 */ +#define LOG_CC_GT 11 /* leftmost bit is 0 or some bits are 1 */ +#define LOG_CC_EV 15 /* rightmost bit is 0 */ +#define AND_(cc,r1,r2,t) f8(0x2,r2,r1,cc,0,1,0,0,0,t) +#define AND(r1,r2,t) AND_(LOG_CC_NV,r1,r2,t) +#define ANDCM_(cc,r1,r2,t) f8(0x2,r2,r1,cc,0,0,0,0,0,t) +#define ANDCM(r1,r2,t) ANDCM_(LOG_CC_NV,r1,r2,t) +#define B_(n,i,t) f20(0x3a,t,i,0,n) +#define B(i,t) B_(0,i,t) +#define B_N(i,t) B_(1,i,t) +#define B_L(i) B_(0,i,_RP_REGNO) +#define B_L_N(i) B_(1,i,_RP_REGNO) +#define BB_CC_LT 0 /* leftmost bit in word is 1 */ +#define BB_CC_GE 1 /* leftmost bit in word is 0 */ +#define BB_(c,r,i) f18(0x30,0,r,c,i,0) +#define BB_N_(c,r,i) f18(0x30,0,r,c,i,1) +#define BBI_(c,r,p,i) f18(0x31,p,r,c,i,0) +#define BBI_N_(c,r,p,i) f18(0x31,p,r,c,i,1) +#define BB(c,r,i) BB_(c,r,i) +#define BBI_LT(r,p,i) BBI_(BB_CC_LT,r,p,i) +#define BBI_GE(r,p,i) BBI_(BB_CC_GE,r,p,i) +#define BB_N(c,r,i) BB_(c,r,i) +#define BBI_N_LT(r,p,i) BBI_N_(BB_CC_LT,r,p,i) +#define BBI_N_GE(r,p,i) BBI_N_(BB_CC_GE,r,p,i) +#define BE(i,s,b) f19(0x38,b,s,i,0) +#define BE_L(i,s,b) f19(0x39,b,s,i,0) +#define BE_L_N(i,s,b) f19(0x39,b,s,i,1) +#define BLR(x,t) f21(0x3a,t,x,2,0) +#define BLR_N(x,t) f21(0x3a,t,x,2,1) +#define BREAK(i,j) f27(0,j,i) +#define BV(x,b) f21(0x3a,b,x,6,0) +#define BV_N(x,b) f21(0x3a,b,x,6,1) +#define BVE(b) f22(0x3a,b,6,0,0,0) +#define BVE_N(b) f22(0x3a,b,6,0,1,0) +#define BVE_L(b) f22(0x3a,b,7,0,0,0) +#define BVE_L_N(b) f22(0x3a,b,7,0,0,1) +#define II_C_NONE 0 +#define II_C_M (1<<5) +#define II_C_S (1<<13) +#define II_C_SM (II_C_S|II_C_M) +#define II_AU_NONE 0 +#define II_AU_PRE ((1<<13)|II_C_M) +#define II_AU_POS II_C_M +#define LD_CC_H_NONE 0 /* No hint */ +#define LD_CC_H_SPL 2 /* Spatial Locality */ +#define CLRBTS() f23(0x3a,0,0,2,0,0,1,0,1) +#define CS_CC_NV 0 /* never */ +#define CS_CC_EQ 2 /* O1 = O2 */ +#define CS_CC_LT 4 /* O1 < O2 (signed) */ +#define CS_CC_LE 6 /* O1 <= O2 (signed) */ +#define CS_CC_ULT 8 /* O1 < O2 (unsigned) */ +#define CS_CC_ULE 10 /* O1 <= O2 (unsigned) */ +#define CS_CC_SV 12 /* O1 - O2 overflows (signed) */ +#define CS_CC_OD 14 /* O1 - O2 is odd */ +#define CS_CC_TR 1 /* always */ +#define CS_CC_NE 3 /* O1 != O2 */ +#define CS_CC_GE 5 /* O1 >= O2 (signed) */ +#define CS_CC_GT 7 /* O1 > O2 (signed) */ +#define CS_CC_UGE 9 /* O1 >= O2 (unsigned) */ +#define CS_CC_UGT 11 /* O1 > O2 (unsigned) */ +#define CS_CC_NSV 13 /* O1 - O2 does not overflows (signed) */ +#define CS_CC_EV 15 /* O1 - O2 is even */ +#define CMPB_(c,r1,r2,i) f17((c)&1?0x22:0x20,r2,r1,(c)>>1,i,0) +#define CMPB(r1,r2,i) CMPB_(CS_CC_NV,r1,r2,i) +#define CMPB_EQ(r1,r2,i) CMPB_(CS_CC_EQ,r1,r2,i) +#define CMPB_LT(r1,r2,i) CMPB_(CS_CC_LT,r1,r2,i) +#define CMPB_LE(r1,r2,i) CMPB_(CS_CC_LE,r1,r2,i) +#define CMPB_ULT(r1,r2,i) CMPB_(CS_CC_ULT,r1,r2,i) +#define CMPB_ULE(r1,r2,i) CMPB_(CS_CC_ULE,r1,r2,i) +#define CMPB_SV(r1,r2,i) CMPB_(CS_CC_SV,r1,r2,i) +#define CMPB_OD(r1,r2,i) CMPB_(CS_CC_OD,r1,r2,i) +#define CMPB_TR(r1,r2,i) CMPB_(CS_CC_TR,r1,r2,i) +#define CMPB_NE(r1,r2,i) CMPB_(CS_CC_NE,r1,r2,i) +#define CMPB_GE(r1,r2,i) CMPB_(CS_CC_GE,r1,r2,i) +#define CMPB_GT(r1,r2,i) CMPB_(CS_CC_GT,r1,r2,i) +#define CMPB_UGE(r1,r2,i) CMPB_(CS_CC_UGE,r1,r2,i) +#define CMPB_UGT(r1,r2,i) CMPB_(CS_CC_UGT,r1,r2,i) +#define CMPB_NSV(r1,r2,i) CMPB_(CS_CC_NSV,r1,r2,i) +#define CMPB_EV(r1,r2,i) CMPB_(CS_CC_EV,r1,r2,i) +#define CMPB_N_(c,r1,r2,i) f17((c)&1?0x22:0x20,r2,r1,(c)>>1,i,1) +#define CMPB_N(r1,r2,i) CMPB_N_(CS_CC_NV,r1,r2,i) +#define CMPB_EQ_N(r1,r2,i) CMPB_N_(CS_CC_EQ,r1,r2,i) +#define CMPB_LT_N(r1,r2,i) CMPB_N_(CS_CC_LT,r1,r2,i) +#define CMPB_LE_N(r1,r2,i) CMPB_N_(CS_CC_LE,r1,r2,i) +#define CMPB_ULT_N(r1,r2,i) CMPB_N_(CS_CC_ULT,r1,r2,i) +#define CMPB_ULE_N(r1,r2,i) CMPB_N_(CS_CC_ULE,r1,r2,i) +#define CMPB_SV_N(r1,r2,i) CMPB_N_(CS_CC_SV,r1,r2,i) +#define CMPB_OD_N(r1,r2,i) CMPB_N_(CS_CC_OD,r1,r2,i) +#define CMPB_TR_N(r1,r2,i) CMPB_N_(CS_CC_TR,r1,r2,i) +#define CMPB_NE_N(r1,r2,i) CMPB_N_(CS_CC_NE,r1,r2,i) +#define CMPB_GE_N(r1,r2,i) CMPB_N_(CS_CC_GE,r1,r2,i) +#define CMPB_GT_N(r1,r2,i) CMPB_N_(CS_CC_GT,r1,r2,i) +#define CMPB_UGE_N(r1,r2,i) CMPB_N_(CS_CC_UGE,r1,r2,i) +#define CMPB_UGT_N(r1,r2,i) CMPB_N_(CS_CC_UGT,r1,r2,i) +#define CMPB_NSV_N(r1,r2,i) CMPB_N_(CS_CC_NSV,r1,r2,i) +#define CMPB_EV_N(r1,r2,i) CMPB_N_(CS_CC_EV,r1,r2,i) +#define CMPCLR_(c,r1,r2,i) f8(0x2,r2,r1,c,2,0,0,2,0,i) +#define CMPCLR(r1,r2,i) CMPCLR_(CS_CC_NV,r1,r2,i) +#define CMPCLR_EQ(r1,r2,i) CMPCLR_(CS_CC_EQ,r1,r2,i) +#define CMPCLR_LT(r1,r2,i) CMPCLR_(CS_CC_LT,r1,r2,i) +#define CMPCLR_LE(r1,r2,i) CMPCLR_(CS_CC_LE,r1,r2,i) +#define CMPCLR_ULT(r1,r2,i) CMPCLR_(CS_CC_ULT,r1,r2,i) +#define CMPCLR_ULE(r1,r2,i) CMPCLR_(CS_CC_ULE,r1,r2,i) +#define CMPCLR_SV(r1,r2,i) CMPCLR_(CS_CC_SV,r1,r2,i) +#define CMPCLR_OD(r1,r2,i) CMPCLR_(CS_CC_OD,r1,r2,i) +#define CMPCLR_TR(r1,r2,i) CMPCLR_(CS_CC_TR,r1,r2,i) +#define CMPCLR_NE(r1,r2,i) CMPCLR_(CS_CC_NE,r1,r2,i) +#define CMPCLR_GE(r1,r2,i) CMPCLR_(CS_CC_GE,r1,r2,i) +#define CMPCLR_GT(r1,r2,i) CMPCLR_(CS_CC_GT,r1,r2,i) +#define CMPCLR_UGE(r1,r2,i) CMPCLR_(CS_CC_UGE,r1,r2,i) +#define CMPCLR_UGT(r1,r2,i) CMPCLR_(CS_CC_UGT,r1,r2,i) +#define CMPCLR_NSV(r1,r2,i) CMPCLR_(CS_CC_NSV,r1,r2,i) +#define CMPCLR_EV(r1,r2,i) CMPCLR_(CS_CC_EV,r1,r2,i) +#define CMPIB_(c,i,r,t) f17x((c)&1?0x23:0x21,r,i,(c)>>1,t,0) +#define CMPIB_NONE(i,r,t) CMPIB_(CS_CC_NV,i,r,t) +#define CMPIB_EQ(i,r,t) CMPIB_(CS_CC_EQ,i,r,t) +#define CMPIB_LT(i,r,t) CMPIB_(CS_CC_LT,i,r,t) +#define CMPIB_LE(i,r,t) CMPIB_(CS_CC_LE,i,r,t) +#define CMPIB_ULT(i,r,t) CMPIB_(CS_CC_ULT,i,r,t) +#define CMPIB_ULE(i,r,t) CMPIB_(CS_CC_ULE,i,r,t) +#define CMPIB_SV(i,r,t) CMPIB_(CS_CC_SV,i,r,t) +#define CMPIB_OD(i,r,t) CMPIB_(CS_CC_OD,i,r,t) +#define CMPIB(i,r,t) CMPIB_(CS_CC_TR,i,r,t) +#define CMPIB_NE(i,r,t) CMPIB_(CS_CC_NE,i,r,t) +#define CMPIB_GE(i,r,t) CMPIB_(CS_CC_GE,i,r,t) +#define CMPIB_GT(i,r,t) CMPIB_(CS_CC_GT,i,r,t) +#define CMPIB_UGE(i,r,t) CMPIB_(CS_CC_UGE,i,r,t) +#define CMPIB_UGT(i,r,t) CMPIB_(CS_CC_UGT,i,r,t) +#define CMPIB_NSV(i,r,t) CMPIB_(CS_CC_NSV,i,r,t) +#define CMPIB_EV(i,r,t) CMPIB_(CS_CC_EV,i,r,t) +#define CMPIB_N_(c,i,r,t) f17x((c)&1?0x23:0x21,r,i,(c)>>1,t,1) +#define CMPIB_NONE_N(i,r,t) CMPIB_N_(CS_CC_NV,i,r,t) +#define CMPIB_EQ_N(i,r,t) CMPIB_N_(CS_CC_EQ,i,r,t) +#define CMPIB_LT_N(i,r,t) CMPIB_N_(CS_CC_LT,i,r,t) +#define CMPIB_LE_N(i,r,t) CMPIB_N_(CS_CC_LE,i,r,t) +#define CMPIB_ULT_N(i,r,t) CMPIB_N_(CS_CC_ULT,i,r,t) +#define CMPIB_ULE_N(i,r,t) CMPIB_N_(CS_CC_ULE,i,r,t) +#define CMPIB_SV_N(i,r,t) CMPIB_N_(CS_CC_SV,i,r,t) +#define CMPIB_OD_N(i,r,t) CMPIB_N_(CS_CC_OD,i,r,t) +#define CMPIB_N(i,r,t) CMPIB_N_(CS_CC_TR,i,r,t) +#define CMPIB_NE_N(i,r,t) CMPIB_N_(CS_CC_NE,i,r,t) +#define CMPIB_GE_N(i,r,t) CMPIB_N_(CS_CC_GE,i,r,t) +#define CMPIB_GT_N(i,r,t) CMPIB_N_(CS_CC_GT,i,r,t) +#define CMPIB_UGE_N(i,r,t) CMPIB_N_(CS_CC_UGE,i,r,t) +#define CMPIB_UGT_N(i,r,t) CMPIB_N_(CS_CC_UGT,i,r,t) +#define CMPIB_NSV_N(i,r,t) CMPIB_N_(CS_CC_NSV,i,r,t) +#define CMPIB_EV_N(i,r,t) CMPIB_N_(CS_CC_EV,i,r,t) +#define CMPICLR_(c,i,r,t) f9(0x24,r,t,c,0,i) +#define CMPICLR(i,r,t) CMPICLR_(CS_CC_NV,i,r,t) +#define CMPICLR_EQ(i,r,t) CMPICLR_(CS_CC_EQ,i,r,t) +#define CMPICLR_LT(i,r,t) CMPICLR_(CS_CC_LT,i,r,t) +#define CMPICLR_LE(i,r,t) CMPICLR_(CS_CC_LE,i,r,t) +#define CMPICLR_ULT(i,r,t) CMPICLR_(CS_CC_ULT,i,r,t) +#define CMPICLR_ULE(i,r,t) CMPICLR_(CS_CC_ULE,i,r,t) +#define CMPICLR_SV(i,r,t) CMPICLR_(CS_CC_SV,i,r,t) +#define CMPICLR_OD(i,r,t) CMPICLR_(CS_CC_OD,i,r,t) +#define CMPICLR_TR(i,r,t) CMPICLR_(CS_CC_TR,i,r,t) +#define CMPICLR_NE(i,r,t) CMPICLR_(CS_CC_NE,i,r,t) +#define CMPICLR_GE(i,r,t) CMPICLR_(CS_CC_GE,i,r,t) +#define CMPICLR_GT(i,r,t) CMPICLR_(CS_CC_GT,i,r,t) +#define CMPICLR_UGE(i,r,t) CMPICLR_(CS_CC_UGE,i,r,t) +#define CMPICLR_UGT(i,r,t) CMPICLR_(CS_CC_UGT,i,r,t) +#define CMPICLR_NSV(i,r,t) CMPICLR_(CS_CC_NSV,i,r,t) +#define CMPICLR_EV(i,r,t) CMPICLR_(CS_CC_EV,i,r,t) +#define COPR(u,s) f38(0x0c,s,u,0) +#define UI_CF_NONE 0 /* never */ +#define UI_CF_SBZ 2 /* some byte zero */ +#define UI_CF_SHZ 3 /* some halfword zero */ +#define UI_CF_SDC 4 /* some digit carry */ +#define UI_CF_SBC 6 /* some byte carry */ +#define UI_CF_SHC 7 /* some halfword carry */ +#define UI_TR_SHC 8 /* always */ +#define UI_CF_NBZ 10 /* no byte zero */ +#define UI_CF_NHZ 11 /* no halfword zero */ +#define UI_CF_NDC 12 /* no digit carry */ +#define UI_CF_NBC 14 /* no byte carry */ +#define UI_CF_NHC 15 /* no halfword carry */ +#define DCOR_(e1,cf,r,t) f8(0x2,r,0,cf,2,1,1,e1,0,t) +#define DCOR(r,t) DCOR_(2,UI_CF_NONE,r,t) +#define DCOR_I(r,t) DCOR_(3,UI_CF_NONE,r,t) +#define SED_C_NEVER 0 /* never */ +#define SED_C_EQ 1 /* all bits 0 */ +#define SED_C_LT 2 /* lefmost bits 1 */ +#define SED_C_OD 3 /* rightmost bit 1 */ +#define SED_C_TR 4 /* always */ +#define SED_C_NE 5 /* some bit 1 */ +#define SED_C_GE 6 /* lefmost bits 1 */ +#define SED_C_EV 7 /* rightmost bit 0 */ +#define DEPW(r,len,t) f13(0x35,t,r,SED_C_NEVER,0,1,0,len) +#define DEPW_Z(r,len,t) f13(0x35,t,r,SED_C_NEVER,0,0,0,len) +#define DEPWR(r,pos,len,t) f16(0x35,t,r,SED_C_NEVER,0,1,1,31-(pos),len) +#define DEPWR_Z(r,pos,len,t) f16(0x35,t,r,SED_C_NEVER,0,1,0,31-(pos),len) +#define SHLWI(r,sa,t) DEPWR_Z(r,31-(sa),32-(sa),t) +#define DEPWI(i,len,t) f13x(0x35,t,i,SED_C_NEVER,2,1,0,len) +#define DEPWI_Z(i,len,t) f13x(0x35,t,i,SED_C_NEVER,2,0,0,len) +#define DEPWRI(i,pos,len,t) f16x(0x35,t,i,SED_C_NEVER,1,1,1,31-(pos),len) +#define DEPWRI_Z(i,pos,len,t) f16x(0x35,t,i,SED_C_NEVER,1,1,0,31-(pos),len) +#define DIAG(i) f28(0x5,i) +#define DS(r1,r2,t) f8(0x2,r2,r1,ADD_CF_NV,1,0,0,1,0,t) +#define EXTRW(r,len,t) f12(0x34,r,t,SED_C_NEVER,2,1,0,0,0,len) +#define EXTRW_U(r,len,t) f12(0x34,r,t,SED_C_NEVER,2,0,0,0,0,len) +#define EXTRWR(r,pos,len,t) f15(0x34,r,t,SED_C_NEVER,1,1,1,pos,len) +#define SHRWI(r,sa,t) EXTRWR(r,31-(sa),32-(sa),t) +#define EXTRWR_U(r,pos,len,t) f15(0x34,r,t,SED_C_NEVER,1,1,0,pos,len) +#define SHRWI_U(r,sa,t) EXTRWR_U(r,31-(sa),32-(sa),t) +#define FDC(x,s,b) f24(0x1,b,x,s,0x4a,0,0) +#define FDC_M(x,s,b) f24(0x1,b,x,s,0x4a,1,0) +#define FDCI(i,s,b) f25(0x1,b,i,s,0xca,0,0) +#define FDCE(x,s,b) f24(0x1,b,x,s,0x4b,0,0) +#define FDCE_M(x,s,b) f24(0x1,b,x,s,0x4b,1,0) +#define FIC(x,s,b) f26(0x1,b,x,s,0xa,0,0) +#define FIC_M(x,s,b) f26(0x1,b,x,s,0xa,1,0) +#define FICI(x,s,b) f25(0x1,b,x,s,0x4f,0,0) +#define FICI_M(x,s,b) f25(0x1,b,x,s,0x4f,1,0) +#define FICE(x,s,b) f26(0x1,b,x,s,0xb,0,0) +#define FICE_M(x,s,b) f26(0x1,b,x,s,0xb,1,0) +#define HADD_(c,r1,r2,t) f8(0x2,r2,r1,0,0,1,1,c,0,t) +#define HADD(r1,r2,t) HADD_(3,r1,r2,t) +#define HADD_SS(r1,r2,t) HADD_(1,r1,r2,t) +#define HADD_US(r1,r2,t) HADD_(0,r1,r2,t) +#define HAVG(r1,r2,t) f8(0x2,r2,r1,0,0,1,0,3,0,t) +#define HSHL(r,sa,t) f10(0x3e,0,r,1,0,0,2,sa,0,t) +#define HSHLADD(r1,sa,r2,t) f8(0x2,r2,r1,0,1,1,1,sa,0,t) +#define HSHR(r,sa,t) f10(0x3e,r,0,1,2,0,3,sa,0,t) +#define HSHR_U(r,sa,t) f10(0x3e,r,0,1,2,0,2,sa,0,t) +#define HSHRADD(r1,sa,r2,t) f8(0x2,r2,r1,0,1,0,1,sa,0,t) +#define HSUB_(c,r1,r2,t) f8(0x2,r2,r1,0,0,0,1,c,0,t) +#define HSUB(r1,r2,t) HSUB_(3,r1,r2,t) +#define HSUB_SS(r1,r2,t) HSUB_(1,r1,r2,t) +#define HSUB_US(r1,r2,t) HSUB_(0,r1,r2,t) +#define IDTLBT(r1,r2) f26(0x1,r2,r1,0,0x60,0,0) +#define IITLBT(r1,r2) f26(0x1,r2,r1,0,0x20,0,0) +#define LCI(x,s,b,t) f24(0x1,b,x,s,0x4c,0,t) +#define LDBL(i,b,t) f1(0x10,b,t,i) +#define LDB(x,b,t) f4(0x3,b,x,0,0,0,LD_CC_H_NONE,0,0,t) +#define LDBI(i,b,t) f5(0x3,b,i,0,0,1,LD_CC_H_NONE,0,0,t) +#define LDCD(x,b,t) f4(0x3,b,x,0,0,0,LD_CC_H_NONE,5,0,t) +#define LDCDI(i,b,t) f5(0x3,b,i,0,0,1,LD_CC_H_NONE,5,0,t) +#define LDCW(x,b,t) f4(0x3,b,x,0,0,0,LD_CC_H_NONE,7,0,t) +#define LDCWI(i,b,t) f5(0x3,b,i,0,0,1,LD_CC_H_NONE,7,0,t) +#define LDDL(i,b,t) f3(0x14,b,t,i,0) +#define LDD(x,b,t) f4(0x3,b,x,0,0,0,LD_CC_H_NONE,3,0,t) +#define LDDI(i,b,t) f5(0x3,b,i,0,0,1,LD_CC_H_NONE,3,0,t) +#define LDDA(x,b,t) f4(0x3,b,x,0,0,0,LD_CC_H_NONE,4,0,t) +#define LDDAI(i,b,t) f5(0x3,b,i,0,0,1,LD_CC_H_NONE,4,0,t) +#define LDHL(i,b,t) f1(0x11,b,t,i) +#define LDH(x,b,t) f4(0x3,b,x,0,0,0,LD_CC_H_NONE,1,0,t) +#define LDHI(i,b,t) f5(0x3,b,i,0,0,1,LD_CC_H_NONE,1,0,t) +#define LDIL(i,t) f7(0x8,t,i) +#define LDO(i,b,t) f1(0xd,b,t,i) +#define LDI(i,t) LDO(i,0,t) +#define LDSID(s,b,t) f30(0x0,b,0,s,0,0x85,t) +#define LDWL(i,b,t) f1(0x12,b,t,i) +#define LDWL_MB(i,b,t) f1(0x13,b,t,i) /* pre-dec or post-inc */ +#define LDWL_MA(i,b,t) f2(0x17,b,t,i,2)/* post-dec or pre-inc */ +#define LDW(x,b,t) f4(0x3,b,x,0,0,0,LD_CC_H_NONE,2,0,t) +#define LDWI(i,b,t) f5(0x3,b,i,0,0,1,LD_CC_H_NONE,2,0,t) +#define LDWA(x,b,t) f4(0x3,b,x,0,0,0,LD_CC_H_NONE,6,0,t) +#define LDWAI(i,b,t) f5(0x3,b,i,0,0,1,LD_CC_H_NONE,6,0,t) +#define LPA(x,s,b,t) f24(0x1,b,x,s,0x4d,0,t) +#define MFSP(s,t) f29(0x0,0,0,s,0x25,t) +#define MIXH_L(r1,r2,t) f10(0x3e,r2,r1,1,0,0,1,0,0,t) +#define MIXH_R(r1,r2,t) f10(0x3e,r2,r1,1,2,0,1,0,0,t) +#define MIXW_L(r1,r2,t) f10(0x3e,r2,r1,1,0,0,0,0,0,t) +#define MIXW_R(r1,r2,t) f10(0x3e,r2,r1,1,2,0,0,0,0,t) +#define MOVB_(c,r1,r2,i) f17(0x32,r2,r1,c,i,0) +#define MOVB(r1,r2,i) MOVB_(SED_C_NEVER,r1,r2,i) +#define MOVB_EQ(r1,r2,i) MOVB_(SED_C_EQ,r1,r2,i) +#define MOVB_LT(r1,r2,i) MOVB_(SED_C_LT,r1,r2,i) +#define MOVB_OD(r1,r2,i) MOVB_(SED_C_OD,r1,r2,i) +#define MOVB_TR(r1,r2,i) MOVB_(SED_C_TR,r1,r2,i) +#define MOVB_NE(r1,r2,i) MOVB_(SED_C_NE,r1,r2,i) +#define MOVB_GE(r1,r2,i) MOVB_(SED_C_GE,r1,r2,i) +#define MOVB_EV(r1,r2,i) MOVB_(SED_C_EV,r1,r2,i) +#define MOVIB_(c,r,i,t) f17x(0x33,r,i,c,t,0) +#define MOVIB(i,r,t) MOVIB_(SED_C_NEVER,i,r,t) +#define MOVIB_EQ(i,r,t) MOVIB_(SED_C_EQ,i,r,t) +#define MOVIB_LT(i,r,t) MOVIB_(SED_C_LT,i,r,t) +#define MOVIB_OD(i,r,t) MOVIB_(SED_C_OD,i,r,t) +#define MOVIB_TR(i,r,t) MOVIB_(SED_C_TR,i,r,t) +#define MOVIB_NE(i,r,t) MOVIB_(SED_C_NE,i,r,t) +#define MOVIB_GE(i,r,t) MOVIB_(SED_C_GE,i,r,t) +#define MOVIB_EV(i,r,t) MOVIB_(SED_C_EV,i,r,t) +#define MTCTL(r,t) f31(0x0,t,r,0,0xc2,0) +#define MTSAR(r) MTCTL(r,_CR11_REGNO) +#define MTSARCM(r) f31(0x0,0xb,r,0,0xc6,0) +#define MTSM(r) f33(0x0,0,r,0,0xc3,0) +#define MTSP(r,s) f29(0x0,0,r,s,0xc1,0) +#define OR_(c,r1,r2,t) f8(0x2,r2,r1,c,0,1,0,1,0,t) +#define OR(r1,r2,t) OR_(LOG_CC_NV,r1,r2,t) +#define NOP() OR(_R0_REGNO,_R0_REGNO,_R0_REGNO) +#define COPY(r,t) OR(r,0,t) +#define PDC(x,s,b) f24(0x1,b,x,s,0x4e,0,0) +#define PDTLB(x,s,b) f24(0x1,b,x,s,0x48,0,0) +#define PDTLB_L(x,s,b) f24(0x1,b,x,s,0x58,0,0) +#define PDTLBE(x,s,b) f24(0x1,b,x,s,0x49,0,0) +#define PERMH(c,r,t) f10(0x3e,r,r,0,(c)&3,0,((c)>>2)&3,(((c)>>2)&6)|(((c)>>6)&3),0,t) +#define PITBL(x,s,b) f26(0x1,b,x,s,0x08,0,0) +#define PITBL_L(x,s,b) f26(0x1,b,x,s,0x18,0,0) +#define PITBLE(x,s,b) f26(0x1,b,x,s,0x09,0,0) +#define POPBTS(i) f23(0x3a,0,0,2,0,i,1,0,1) +#define PROBE_R(s,b,r,t) f24(0x1,b,r,s,0x46,0,t) +#define PROBE_W(s,b,r,t) f24(0x1,b,r,s,0x47,0,t) +#define PROBEI_R(s,b,i,t) f24(0x1,b,i,s,0x46,0,t) +#define PROBEI_W(s,b,i,t) f24(0x1,b,i,s,0x47,0,t) +#define PUSHBTS(r) f23(0x3a,0,r,2,0,0,0,0,1) +#define PUSHNOM() f23(0x3a,0,0,2,0,0,0,0,1) +#define RFI() f33(0x0,0,0,0,0x60,0) +#define RFI_R() f33(0x0,0,0,0,0x65,0) +#define RSM(i,t) f33(0x0,((i)&0x3e0)>>5,(i)&0x1f,0,0x73,t) +#define SHLADD_(e,cf,r1,sa,r2,t) f8(0x2,r2,r1,cf,e,1,0,sa,0,t) +#define SHLADD(r1,sa,r2,t) SHLADD_(1,ADD_CF_NV,r1,sa,r2,t) +#define SHLADD_L(r1,sa,r2,t) SHLADD_(2,ADD_CF_NV,r1,sa,r2,t) +#define SHLADD_TSV(r1,sa,r2,t) SHLADD_(3,ADD_CF_NV,r1,sa,r2,t) +#define SHRPD(r1,r2,t) f11(0x34,r2,r1,SED_C_NEVER,0,0,1,0,t) +#define SHRPDI(r1,r2,sa,t) f14(0x34,r2,r1,SED_C_NEVER,0,(63-(sa))>>5,1,(63-(sa))&0x1f,t) +#define SHRPW(r1,r2,t) f11(0x34,r2,r1,SED_C_NEVER,0,0,0,0,t) +#define SHRPWI(r1,r2,sa,t) f14(0x34,r2,r1,SED_C_NEVER,0,1,0,31-(sa),t) +#define SPOP0(sf,so) f34(0x4,(so)>>5,0,sf,0,(so)&0x1f) +#define SPOP1(sf,so,t) f35(0x4,so,1,sf,0,t) +#define SPOP2(sf,so,r) f36(0x4,r,(so)>>5,2,sf,0,(so)&0x1f) +#define SPOP3(sf,so,r1,r2) f37(0x4,r2,r1,(so)>>5,3,sf,0,(so)&0x1f) +#define SSM(i,t) f33(0x00,(i)>>5,(i)&0x1f,0,0x6b,t) +#define STBL(r,i,b) f1(0x18,b,r,i) +#define STBI(r,i,b) f6(0x3,b,r,0,0,1,LD_CC_H_NONE,0x8,0,i) +#define STDL(r,i,b) f3(0x1c,b,r,i,0) +#define STDI(r,i,b) f6(0x3,b,r,0,0,1,LD_CC_H_NONE,0xc,0,i) +#define STDA(r,i,b) f6(0x3,b,r,0,0,1,LD_CC_H_NONE,0xf,0,i) +#define STHL(r,i,b) f1(0x19,b,r,i) +#define STHI(r,i,b) f6(0x3,b,r,0,0,1,LD_CC_H_NONE,0x9,0,i) +#define STWL(r,i,b) f1(0x1a,b,r,i) +#define STWL_MA(r,i,b) f1(0x1b,b,r,i) /* pre-dec or post-inc */ +#define STWL_MB(r,i,b) f2(0x1f,b,r,i,2)/* post-dec or pre-inc */ +#define STWI(r,i,b) f6(0x3,b,r,0,0,1,LD_CC_H_NONE,0xa,0,i) +#define STWA(r,i,b) f6(0x3,b,r,0,0,1,LD_CC_H_NONE,0xe,0,i) +#define SUB_(e1,e2,cf,r1,r2,t) f8(0x2,r2,r1,cf,e1,0,e2,0,0,t) +#define SUB(r1,r2,t) SUB_(1,0,CS_CC_NV,r1,r2,t) +#define SUB_B(r1,r2,t) SUB_(1,1,CS_CC_NV,r1,r2,t) +#define SUB_SV(r1,r2,t) SUB_(1,0,CS_CC_SV,r1,r2,t) +#define SUB_NSV(r1,r2,t) SUB_(1,0,CS_CC_NSV,r1,r2,t) +/* actually, rsbi */ +#define SUBI_(e1,cf,i,r,t) f9(0x25,r,t,cf,e1,i) +#define SUBI(i,r,t) SUBI_(0,ADD_CF_NV,i,r,t) +#define SYNC() f33(0x0,0,0,0,0x20,0) +#define SYNCDMA() f33(0x0,0,1<<4,0,0x20,0) +#define UADDCM(r1,r2,t) f8(0x2,r2,r1,ADD_CF_NV,2,0,1,2,0,t) +#define UXOR(r1,r2,t) f8(0x2,r2,r1,LOG_CC_NV,0,1,1,2,0,t) +#define XOR(r1,r2,t) f8(0x2,r2,r1,LOG_CC_NV,0,1,0,2,0,t) +# define nop(c) _nop(_jit,c) +static void _nop(jit_state_t*,jit_int32_t); +#define movr(r0,r1) _movr(_jit,r0,r1) +static void _movr(jit_state_t*,jit_int32_t,jit_int32_t); +#define movi(r0,i0) _movi(_jit,r0,i0) +static void _movi(jit_state_t*,jit_int32_t,jit_word_t); +#define movi_p(r0,i0) _movi_p(_jit,r0,i0) +static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t); +#define comr(r0,r1) UADDCM(_R0_REGNO,r1,r0) +#define negr(r0,r1) SUB(_R0_REGNO,r1,r0) +#define extr_c(r0,r1) EXTRWR(r1,31,8,r0) +#define extr_uc(r0,r1) EXTRWR_U(r1,31,8,r0) +#define extr_s(r0,r1) EXTRWR(r1,31,16,r0) +#define extr_us(r0,r1) EXTRWR_U(r1,31,16,r0) +#if __BYTE_ORDER == __BIG_ENDIAN +# define htonr_us(r0,r1) extr_us(r0,r1) +# define htonr_ui(r0,r1) movr(r0,r1) +#else +# error need htonr implementation +#endif +#define addr(r0,r1,r2) ADD(r1,r2,r0) +#define addi(r0,r1,i0) _addi(_jit,r0,r1,i0) +static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define addcr(r0,r1,r2) addr(r0,r1,r2) +#define addci(r0,r1,i0) _addci(_jit,r0,r1,i0) +static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define addxr(r0,r1,r2) ADD_C(r1,r2,r0) +#define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0) +static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define subr(r0,r1,r2) SUB(r1,r2,r0) +#define subi(r0,r1,i0) _subi(_jit,r0,r1,i0) +static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define subcr(r0,r1,r2) subr(r0,r1,r2) +#define subci(r0,r1,i0) _subci(_jit,r0,r1,i0) +static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define subxr(r0,r1,r2) SUB_B(r1,r2,r0) +#define subxi(r0,r1,i0) _subxi(_jit,r0,r1,i0) +static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0) +static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define mulr(r0,r1,r2) _mulr(_jit,r0,r1,r2) +static void _mulr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define muli(r0,r1,i0) _muli(_jit,r0,r1,i0) +static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +static long long __llmul(int, int); +#define qmulr(r0,r1,r2,r3) _qmulr(_jit,r0,r1,r2,r3) +static void _qmulr(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define qmuli(r0,r1,r2,i0) _qmuli(_jit,r0,r1,r2,i0) +static void _qmuli(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +#define qmulr_u(r0,r1,r2,r3) _qmulr_u(_jit,r0,r1,r2,r3) +static void _qmulr_u(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define qmuli_u(r0,r1,r2,i0) _qmuli_u(_jit,r0,r1,r2,i0) +static void _qmuli_u(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +static int __idiv(int, int); +#define divr(r0,r1,r2) _divr(_jit,r0,r1,r2) +static void _divr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define divi(r0,r1,i0) _divi(_jit,r0,r1,i0) +static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +static unsigned int __udiv(unsigned int, unsigned int); +#define divr_u(r0,r1,r2) _divr_u(_jit,r0,r1,r2) +static void _divr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0) +static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +static int __irem(int, int); +#define remr(r0,r1,r2) _remr(_jit,r0,r1,r2) +static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define remi(r0,r1,i0) _remi(_jit,r0,r1,i0) +static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +static unsigned int __urem(unsigned int, unsigned int); +#define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2) +static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0) +static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +static idiv_t __idivrem(int, int); +#define qdivr(r0,r1,r2,r3) _qdivr(_jit,r0,r1,r2,r3) +static void _qdivr(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define qdivi(r0,r1,r2,i0) _qdivi(_jit,r0,r1,r2,i0) +static void _qdivi(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +static udiv_t __udivrem(unsigned int, unsigned int); +#define qdivr_u(r0,r1,r2,r3) _qdivr_u(_jit,r0,r1,r2,r3) +static void _qdivr_u(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define qdivi_u(r0,r1,r2,i0) _qdivi_u(_jit,r0,r1,r2,i0) +static void _qdivi_u(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +#define andr(r0,r1,r2) AND(r1,r2,r0) +#define andi(r0,r1,i0) _andi(_jit,r0,r1,i0) +static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define orr(r0,r1,r2) OR(r1,r2,r0) +#define ori(r0,r1,i0) _ori(_jit,r0,r1,i0) +static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define xorr(r0,r1,r2) XOR(r1,r2,r0) +#define xori(r0,r1,i0) _xori(_jit,r0,r1,i0) +static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define lshr(r0,r1,r2) _lshr(_jit,r0,r1,r2) +static void _lshr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define lshi(r0,r1,i0) SHLWI(r1,i0,r0) +#define rshr(r0,r1,r2) _rshr(_jit,r0,r1,r2) +static void _rshr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define rshi(r0,r1,i0) SHRWI(r1,i0,r0) +#define rshr_u(r0,r1,r2) _rshr_u(_jit,r0,r1,r2) +static void _rshr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define rshi_u(r0,r1,i0) SHRWI_U(r1,i0,r0) +#define cmpr(c,r0,r1,r2) _cmpr(_jit,c,r0,r1,r2) +static void _cmpr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define cmpi(c,ci,r0,r1,i0) _cmpi(_jit,c,ci,r0,r1,i0) +static void _cmpi(jit_state_t*,jit_word_t,jit_word_t, + jit_int32_t,jit_int32_t,jit_word_t); +#define ltr(r0,r1,r2) cmpr(CS_CC_GE,r0,r1,r2) +#define lti(r0,r1,i0) cmpi(CS_CC_GE,CS_CC_LE,r0,r1,i0) +#define ltr_u(r0,r1,r2) cmpr(CS_CC_UGE,r0,r1,r2) +#define lti_u(r0,r1,i0) cmpi(CS_CC_UGE,CS_CC_ULE,r0,r1,i0) +#define ler(r0,r1,r2) cmpr(CS_CC_GT,r0,r1,r2) +#define lei(r0,r1,i0) cmpi(CS_CC_GT,CS_CC_LT,r0,r1,i0) +#define ler_u(r0,r1,r2) cmpr(CS_CC_UGT,r0,r1,r2) +#define lei_u(r0,r1,i0) cmpi(CS_CC_UGT,CS_CC_ULT,r0,r1,i0) +#define eqr(r0,r1,r2) cmpr(CS_CC_NE,r0,r1,r2) +#define eqi(r0,r1,i0) cmpi(CS_CC_NE,CS_CC_NE,r0,r1,i0) +#define ger(r0,r1,r2) cmpr(CS_CC_LT,r0,r1,r2) +#define gei(r0,r1,i0) cmpi(CS_CC_LT,CS_CC_GT,r0,r1,i0) +#define ger_u(r0,r1,r2) cmpr(CS_CC_ULT,r0,r1,r2) +#define gei_u(r0,r1,i0) cmpi(CS_CC_ULT,CS_CC_UGT,r0,r1,i0) +#define gtr(r0,r1,r2) cmpr(CS_CC_LE,r0,r1,r2) +#define gti(r0,r1,i0) cmpi(CS_CC_LE,CS_CC_GE,r0,r1,i0) +#define gtr_u(r0,r1,r2) cmpr(CS_CC_ULE,r0,r1,r2) +#define gti_u(r0,r1,i0) cmpi(CS_CC_ULE,CS_CC_UGE,r0,r1,i0) +#define ner(r0,r1,r2) cmpr(CS_CC_EQ,r0,r1,r2) +#define nei(r0,r1,i0) cmpi(CS_CC_EQ,CS_CC_EQ,r0,r1,i0) +#define ldr_c(r0,r1) _ldr_c(_jit,r0,r1) +static void _ldr_c(jit_state_t*,jit_int32_t,jit_int32_t); +#define ldi_c(r0,i0) _ldi_c(_jit,r0,i0) +static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t); +#define ldxr_c(r0,r1,r2) _ldxr_c(_jit,r0,r1,r2) +static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0) +static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ldr_uc(r0,r1) LDBI(_R0_REGNO,r1,r0) +#define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0) +static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t); +#define ldxr_uc(r0,r1,r2) LDB(r2,r1,r0) +#define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0) +static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ldr_s(r0,r1) _ldr_s(_jit,r0,r1) +static void _ldr_s(jit_state_t*,jit_int32_t,jit_int32_t); +#define ldi_s(r0,i0) _ldi_s(_jit,r0,i0) +static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t); +#define ldxr_s(r0,r1,r2) _ldxr_s(_jit,r0,r1,r2) +static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0) +static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ldr_us(r0,r1) LDHI(_R0_REGNO,r1,r0) +#define ldi_us(r0,i0) _ldi_us(_jit,r0,i0) +static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t); +#define ldxr_us(r0,r1,r2) LDH(r2,r1,r0) +#define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0) +static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ldr(r0,r1) ldr_ui(r0,r1) +#define ldr_i(r0,r1) ldr_ui(r0,r1) +#define ldr_ui(r0,r1) LDWI(_R0_REGNO,r1,r0) +#define ldi_i(r0,i0) ldi_ui(r0,i0) +#define ldi_ui(r0,i0) _ldi_ui(_jit,r0,i0) +static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t); +#define ldxr_i(r0,r1,r2) ldxr_ui(r0,r1,r2) +#define ldxr_ui(r0,r1,r2) LDW(r2,r1,r0) +#define ldxi(r0,r1,i0) ldxi_ui(r0,r1,i0) +#define ldxi_i(r0,r1,i0) ldxi_ui(r0,r1,i0) +#define ldxi_ui(r0,r1,i0) _ldxi_ui(_jit,r0,r1,i0) +static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define str_c(r0,r1) STBI(r1,_R0_REGNO,r0) +#define sti_c(i0,r0) _sti_c(_jit,i0,r0) +static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t); +#define stxr_c(r0,r1,r2) _stxr_c(_jit,r0,r1,r2) +static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define stxi_c(i0,r0,r1) _stxi_c(_jit,i0,r0,r1) +static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define str_s(r0,r1) STHI(r1,_R0_REGNO,r0) +#define sti_s(i0,r0) _sti_s(_jit,i0,r0) +static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t); +#define stxr_s(r0,r1,r2) _stxr_s(_jit,r0,r1,r2) +static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define stxi_s(i0,r0,r1) _stxi_s(_jit,i0,r0,r1) +static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define str_i(r0,r1) STWI(r1,_R0_REGNO,r0) +#define sti_i(i0,r0) _sti_i(_jit,i0,r0) +static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); +#define stxr_i(r0,r1,r2) _stxr_i(_jit,r0,r1,r2) +static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define stxi(i0,r0,r1) stxi_i(i0,r0,r1) +#define stxi_i(i0,r0,r1) _stxi_i(_jit,i0,r0,r1) +static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bcmpr(c,i0,r0,r1) _bcmpr(_jit,c,i0,r0,r1) +static jit_word_t _bcmpr(jit_state_t*,jit_word_t, + jit_word_t,jit_int32_t,jit_int32_t); +#define bcmpi(c,ci,i0,r0,i1) _bcmpi(_jit,c,ci,i0,r0,i1) +static jit_word_t _bcmpi(jit_state_t*,jit_word_t,jit_word_t, + jit_word_t,jit_int32_t,jit_word_t); +#define bltr(i0,r0,r1) bcmpr(CS_CC_LT,i0,r0,r1) +#define blti(i0,r0,r1) bcmpi(CS_CC_LT,CS_CC_GT,i0,r0,r1) +#define bltr_u(i0,r0,r1) bcmpr(CS_CC_ULT,i0,r0,r1) +#define blti_u(i0,r0,r1) bcmpi(CS_CC_ULT,CS_CC_UGT,i0,r0,r1) +#define bler(i0,r0,r1) bcmpr(CS_CC_LE,i0,r0,r1) +#define blei(i0,r0,r1) bcmpi(CS_CC_LE,CS_CC_GE,i0,r0,r1) +#define bler_u(i0,r0,r1) bcmpr(CS_CC_ULE,i0,r0,r1) +#define blei_u(i0,r0,r1) bcmpi(CS_CC_ULE,CS_CC_UGE,i0,r0,r1) +#define beqr(i0,r0,r1) bcmpr(CS_CC_EQ,i0,r0,r1) +#define beqi(i0,r0,r1) bcmpi(CS_CC_EQ,CS_CC_EQ,i0,r0,r1) +#define bger(i0,r0,r1) bcmpr(CS_CC_GE,i0,r0,r1) +#define bgei(i0,r0,r1) bcmpi(CS_CC_GE,CS_CC_LE,i0,r0,r1) +#define bger_u(i0,r0,r1) bcmpr(CS_CC_UGE,i0,r0,r1) +#define bgei_u(i0,r0,r1) bcmpi(CS_CC_UGE,CS_CC_ULE,i0,r0,r1) +#define bgtr(i0,r0,r1) bcmpr(CS_CC_GT,i0,r0,r1) +#define bgti(i0,r0,r1) bcmpi(CS_CC_GT,CS_CC_LT,i0,r0,r1) +#define bgtr_u(i0,r0,r1) bcmpr(CS_CC_UGT,i0,r0,r1) +#define bgti_u(i0,r0,r1) bcmpi(CS_CC_UGT,CS_CC_ULT,i0,r0,r1) +#define bner(i0,r0,r1) bcmpr(CS_CC_NE,i0,r0,r1) +#define bnei(i0,r0,r1) bcmpi(CS_CC_NE,CS_CC_NE,i0,r0,r1) +#define bmxr(c,i0,r0,r1) _bmxr(_jit,c,i0,r0,r1) +static jit_word_t _bmxr(jit_state_t*,jit_bool_t, + jit_word_t,jit_int32_t,jit_int32_t); +#define bmxi(c,i0,r0,i1) _bmxi(_jit,c,i0,r0,i1) +static jit_word_t _bmxi(jit_state_t*,jit_bool_t, + jit_word_t,jit_int32_t,jit_word_t); +#define bmcr(r0,r1,r2) bmxr(0,r0,r1,r2) +#define bmci(r0,r1,r2) bmxi(0,r0,r1,r2) +#define bmsr(r0,r1,r2) bmxr(1,r0,r1,r2) +#define bmsi(r0,r1,r2) bmxi(1,r0,r1,r2) +#define boaddr(i0,r0,r1) _boaddr(_jit,i0,r0,r1) +static jit_word_t _boaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define boaddi(i0,r0,i1) _boaddi(_jit,i0,r0,i1) +static jit_word_t _boaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define boaddr_u(i0,r0,r1) _boaddr_u(_jit,i0,r0,r1) +static jit_word_t _boaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define boaddi_u(i0,r0,i1) _boaddi_u(_jit,i0,r0,i1) +static jit_word_t _boaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bxaddr(i0,r0,r1) _bxaddr(_jit,i0,r0,r1) +static jit_word_t _bxaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bxaddi(i0,r0,i1) _bxaddi(_jit,i0,r0,i1) +static jit_word_t _bxaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bxaddr_u(i0,r0,r1) _bxaddr_u(_jit,i0,r0,r1) +static jit_word_t _bxaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bxaddi_u(i0,r0,i1) _bxaddi_u(_jit,i0,r0,i1) +static jit_word_t _bxaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bosubr(i0,r0,r1) _bosubr(_jit,i0,r0,r1) +static jit_word_t _bosubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bosubi(i0,r0,i1) _bosubi(_jit,i0,r0,i1) +static jit_word_t _bosubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bosubr_u(i0,r0,r1) _bosubr_u(_jit,i0,r0,r1) +static jit_word_t _bosubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bosubi_u(i0,r0,i1) _bosubi_u(_jit,i0,r0,i1) +static jit_word_t _bosubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bxsubr(i0,r0,r1) _bxsubr(_jit,i0,r0,r1) +static jit_word_t _bxsubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bxsubi(i0,r0,i1) _bxsubi(_jit,i0,r0,i1) +static jit_word_t _bxsubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bxsubr_u(i0,r0,r1) _bxsubr_u(_jit,i0,r0,r1) +static jit_word_t _bxsubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bxsubi_u(i0,r0,i1) _bxsubi_u(_jit,i0,r0,i1) +static jit_word_t _bxsubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define jmpr(r0) _jmpr(_jit,r0) +static void _jmpr(jit_state_t*,jit_int32_t); +#define jmpi(i0) _jmpi(_jit,i0) +static void _jmpi(jit_state_t*,jit_word_t); +#define jmpi_p(i0) _jmpi_p(_jit,i0) +static jit_word_t _jmpi_p(jit_state_t*,jit_word_t); +#define callr(r0) _callr(_jit,r0) +static void _callr(jit_state_t*,jit_int32_t); +#define calli(i0) _calli(_jit,i0) +static void _calli(jit_state_t*,jit_word_t); +#define calli_p(i0) _calli_p(_jit,i0) +static jit_word_t _calli_p(jit_state_t*,jit_word_t); +#define prolog(node) _prolog(_jit, node) +static void _prolog(jit_state_t*, jit_node_t*); +#define epilog(node) _epilog(_jit, node) +static void _epilog(jit_state_t*, jit_node_t*); +#define vastart(r0) _vastart(_jit, r0) +static void _vastart(jit_state_t*, jit_int32_t); +#define vaarg(r0, r1) _vaarg(_jit, r0, r1) +static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t); +#define patch_at(i,l) _patch_at(_jit,i,l) +static void _patch_at(jit_state_t*,jit_word_t,jit_word_t); +#endif + +#if CODE +/* from binutils bfd/libhppa.h */ +static inline int +sign_extend (int x, int len) +{ + int signbit = (1 << (len - 1)); + int mask = (signbit << 1) - 1; + return ((x & mask) ^ signbit) - signbit; +} + +static inline int +sign_unext (int x, int len) +{ + int len_ones; + + len_ones = (1 << len) - 1; + + return x & len_ones; +} + +static inline int +low_sign_unext (int x, int len) +{ + int temp; + int sign; + + sign = (x >> (len-1)) & 1; + + temp = sign_unext (x, len-1); + + return (temp << 1) | sign; +} + +static inline int +re_assemble_3 (int as3) +{ + return (( (as3 & 4) << (13-2)) + | ((as3 & 3) << (13+1))); +} + +static inline int +re_assemble_12 (int as12) +{ + return (( (as12 & 0x800) >> 11) + | ((as12 & 0x400) >> (10 - 2)) + | ((as12 & 0x3ff) << (1 + 2))); +} + +static inline int +re_assemble_16 (int as16) +{ + int s, t; + + /* Unusual 16-bit encoding, for wide mode only. */ + t = (as16 << 1) & 0xffff; + s = (as16 & 0x8000); + return (t ^ s ^ (s >> 1)) | (s >> 15); +} + +static inline int +re_assemble_17 (int as17) +{ + return (( (as17 & 0x10000) >> 16) + | ((as17 & 0x0f800) << (16 - 11)) + | ((as17 & 0x00400) >> (10 - 2)) + | ((as17 & 0x003ff) << (1 + 2))); +} + +static inline int +re_assemble_21 (int as21) +{ + return (( (as21 & 0x100000) >> 20) + | ((as21 & 0x0ffe00) >> 8) + | ((as21 & 0x000180) << 7) + | ((as21 & 0x00007c) << 14) + | ((as21 & 0x000003) << 12)); +} + +static inline int +re_assemble_22 (int as22) +{ + return (( (as22 & 0x200000) >> 21) + | ((as22 & 0x1f0000) << (21 - 16)) + | ((as22 & 0x00f800) << (16 - 11)) + | ((as22 & 0x000400) >> (10 - 2)) + | ((as22 & 0x0003ff) << (1 + 2))); +} + +static void +_f1(jit_state_t *_jit, jit_int32_t o, + jit_int32_t b, jit_int32_t t, jit_int32_t i) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(!(t & ~0x1f)); + assert(i >= -8192 && i <= 8191); + ii((o<<26)|(b<<21)|(t<<16)|(re_assemble_16(i))); +} + +static void +_f2(jit_state_t *_jit, jit_int32_t o, + jit_int32_t b, jit_int32_t t, jit_int32_t i, jit_int32_t j) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(!(t & ~0x1f)); + assert(i >= -32768 && i <= 32767); + assert(!(j & ~0x3)); + ii((o<<26)|(b<<21)|(t<<16)|(j<<1)|(re_assemble_16(i))); +} + +static void +_f3(jit_state_t *_jit, jit_int32_t o, + jit_int32_t b, jit_int32_t t, jit_int32_t i, jit_int32_t j) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(!(t & ~0x1f)); + assert(i >= -32768 && i <= 32767); + assert(!(j & ~0x1)); + ii((o<<26)|(b<<21)|(t<<16)|(j<<1)|(re_assemble_16(i))); +} + +static void +_f4(jit_state_t *_jit, jit_int32_t o, jit_int32_t b, + jit_int32_t x, jit_int32_t s, jit_int32_t u, jit_int32_t y, + jit_int32_t c, jit_int32_t z, jit_int32_t m, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(!(x & ~0x1f)); + assert(!(s & ~0x3)); + assert(!(u & ~0x1)); + assert(!(y & ~0x1)); + assert(!(c & ~0x3)); + assert(!(z & ~0xf)); + assert(!(m & ~0x1)); + assert(!(t & ~0x1f)); + ii((o<<26)|(b<<21)|(x<<16)|(s<<14)|(u<<13)|(y<<12)|(c<<10)|(z<<6)|(m<<5)|t); +} + +static void +_f5(jit_state_t *_jit, jit_int32_t o, jit_int32_t b, + jit_int32_t i, jit_int32_t s, jit_int32_t a, jit_int32_t y, + jit_int32_t c, jit_int32_t z, jit_int32_t m, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(!(s & ~0x3)); + assert(!(a & ~0x1)); + assert(!(y & ~0x1)); + assert(!(c & ~0x3)); + assert(!(z & ~0xf)); + assert(!(m & ~0x1)); + assert(i >= -16 && i <= 15); + ii((o<<26)|(b<<21)|(low_sign_unext(i,5)<<16)| + (s<<14)|(a<<13)|(y<<12)|(c<<10)|(z<<6)|(m<<5)|t); +} + +static void +_f6(jit_state_t *_jit, jit_int32_t o, jit_int32_t b, + jit_int32_t r, jit_int32_t s, jit_int32_t a, jit_int32_t x, + jit_int32_t c, jit_int32_t y, jit_int32_t m, jit_int32_t i) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(!(s & ~0x3)); + assert(!(a & ~0x1)); + assert(!(x & ~0x1)); + assert(!(c & ~0x3)); + assert(!(y & ~0xf)); + assert(!(m & ~0x1)); + assert(i >= -16 && i <= 15); + ii((o<<26)|(b<<21)|(r<<16)|(s<<14)|(a<<13)| + (x<<12)|(c<<10)|(y<<6)|(m<<5)|low_sign_unext(i,5)); +} + +static void +_f7(jit_state_t *_jit, jit_int32_t o, jit_int32_t r, jit_int32_t i) +{ + assert(!(o & ~0x3f)); + assert(!(r & ~0x1f)); + assert(!(i & 0x7ff)); + ii((o<<26)|(r<<21)|re_assemble_21(i>>11)); +} + +static void +_f8(jit_state_t *_jit, jit_int32_t o, + jit_int32_t r2, jit_int32_t r1, jit_int32_t cf, + jit_int32_t e1, jit_int32_t x, jit_int32_t e2, + jit_int32_t e3, jit_int32_t d, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(r2 & ~0x1f)); + assert(!(r1 & ~0x1f)); + assert(!(cf & ~0xf)); + assert(!(e1 & ~0x3)); + assert(!(x & ~0x1)); + assert(!(e2 & ~0x3)); + assert(!(e3 & ~0x3)); + assert(!(d & ~0x1)); + assert(!(t & ~0x1f)); + ii((o<<26)|(r2<<21)|(r1<<16)|(cf<<12)| + (e1<<10)|(x<<9)|(e2<<8)|(e3<<6)|(d<<5)|t); +} + +static void +_f9(jit_state_t *_jit, + jit_int32_t o, jit_int32_t r, jit_int32_t t, + jit_int32_t cf, jit_int32_t e1, jit_int32_t i) +{ + assert(!(o & ~0x3f)); + assert(!(r & ~0x1f)); + assert(!(t & ~0x1f)); + assert(!(cf & ~0xf)); + assert(!(e1 & ~0x1)); + assert(i >= -2048 && i <= 2047); + ii((o<<26)|(r<<21)|(t<<16)|(cf<<12)|(e1<<11)|low_sign_unext(i,11)); +} + +static void +_f10(jit_state_t *_jit, jit_int32_t o, jit_int32_t r2, + jit_int32_t r1, jit_int32_t u, jit_int32_t v, jit_int32_t w, + jit_int32_t x, jit_int32_t sa, jit_int32_t y, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(r2 & ~0x1f)); + assert(!(r1 & ~0x1f)); + assert(!(u & ~0x1)); + assert(!(v & ~0x3)); + assert(!(w & ~0x1)); + assert(!(x & ~0x3)); + assert(!(sa & ~0xf)); + assert(!(y & ~0x1)); + assert(!(t & ~0x1f)); + ii((o<<26)|(r2<<21)|(r1<<16)|(u<<15)| + (v<<13)|(w<<12)|(x<<10)|(sa<<6)|(y<<5)|t); +} + +static void +_f11(jit_state_t *_jit, jit_int32_t o, + jit_int32_t r2, jit_int32_t r1, jit_int32_t c, jit_int32_t x, + jit_int32_t y, jit_int32_t z, jit_int32_t u, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(r1 & ~0x1f)); + assert(!(r2 & ~0x1f)); + assert(!(c & ~0x7)); + assert(!(x & ~0x3)); + assert(!(y & ~0x1)); + assert(!(z & ~0x1)); + assert(!(u & ~0xf)); + assert(!(t & ~0x1f)); + ii((o<<26)|(r2<<21)|(r1<<16)|(c<<13)|(x<<11)|(y<<10)|(z<<9)|(u<<5)|t); +} + +static void +_f12(jit_state_t *_jit, jit_int32_t o, jit_int32_t r, + jit_int32_t t, jit_int32_t c, jit_int32_t x, jit_int32_t se, + jit_int32_t y, jit_int32_t c1, jit_int32_t z, jit_int32_t clen) +{ + assert(!(o & ~0x3f)); + assert(!(r & ~0x1f)); + assert(!(t & ~0x1f)); + assert(!(c & ~0x7)); + assert(!(x & ~0x3)); + assert(!(se & ~0x1)); + assert(!(y & ~0x1)); + assert(!(c1 & ~0x1)); + assert(!(z & ~0x7)); + assert(!((32-clen) & ~0x1f)); + ii((o<<26)|(r<<21)|(t<<16)|(c<<13)|(x<<11)| + (se<<10)|(y<<9)|(c1<<8)|(z<<5)|(32-clen)); +} + +static void +_f13(jit_state_t *_jit, jit_int32_t o, jit_int32_t t, + jit_int32_t r, jit_int32_t c, jit_int32_t x, + jit_int32_t nz, jit_int32_t c1, jit_int32_t clen) +{ + assert(!(o & ~0x3f)); + assert(!(t & ~0x1f)); + assert(!(r & ~0x1f)); + assert(!(c & ~0x7)); + assert(!(x & ~0x3)); + assert(!(nz & ~0x1)); + assert(!(c1 & ~0x1)); + assert(!((32-clen) & ~0x1f)); + ii((o<<26)|(t<<21)|(r<<16)|(c<<13)| + (x<<11)|(nz<<10)|(c1<<8)|(32-clen)); +} + +static void +_f13x(jit_state_t *_jit, jit_int32_t o, jit_int32_t t, + jit_int32_t i, jit_int32_t c, jit_int32_t x, + jit_int32_t nz, jit_int32_t c1, jit_int32_t clen) +{ + assert(!(o & ~0x3f)); + assert(!(t & ~0x1f)); + assert(i >= -16 && i <= 15); + assert(!(c & ~0x7)); + assert(!(x & ~0x3)); + assert(!(nz & ~0x1)); + assert(!((32-clen) & ~0x1f)); + ii((o<<26)|(t<<21)|(low_sign_unext(i,5)<<16)| + (c<<13)|(x<<11)|(nz<<10)|(c1<<8)|(32-clen)); +} + +static void +_f14(jit_state_t *_jit, jit_int32_t o, + jit_int32_t r2, jit_int32_t r1, jit_int32_t c, jit_int32_t x, + jit_int32_t cp, jit_int32_t y, jit_int32_t cpos, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(r1 & ~0x1f)); + assert(!(r2 & ~0x1f)); + assert(!(c & ~0x7)); + assert(!(x & ~0x3)); + assert(!(cp & ~0x1)); + assert(!(y & ~0x1)); + assert(!(cpos & ~0x1f)); + assert(!(t & ~0x1f)); + ii((o<<26)|(r2<<21)|(r1<<16)|(c<<13)|(x<<12)|(cp<<11)|(y<<10)|(cpos<<5)|t); +} + +static void +_f15(jit_state_t *_jit, jit_int32_t o, + jit_int32_t r, jit_int32_t t, jit_int32_t c, jit_int32_t c1, + jit_int32_t p, jit_int32_t se, jit_int32_t pos, jit_int32_t clen) +{ + assert(!(o & ~0x3f)); + assert(!(r & ~0x1f)); + assert(!(t & ~0x1f)); + assert(!(c & ~0x7)); + assert(!(c1 & ~0x1)); + assert(!(p & ~0x1)); + assert(!(se & ~0x1)); + assert(!(pos & ~0x1f)); + assert(!((32-clen) & ~0x1f)); + ii((o<<26)|(r<<21)|(t<<16)|(c<<13)|(c1<<12)| + (p<<11)|(se<<10)|(pos<<5)|(32-clen)); +} + +static void +_f16(jit_state_t *_jit, jit_int32_t o, + jit_int32_t t, jit_int32_t r, jit_int32_t c, jit_int32_t c1, + jit_int32_t cp, jit_int32_t nz, jit_int32_t cpos, jit_int32_t clen) +{ + assert(!(o & ~0x3f)); + assert(!(t & ~0x1f)); + assert(!(r & ~0x1f)); + assert(!(c & ~0x7)); + assert(!(c1 & ~0x1)); + assert(!(cp & ~0x1)); + assert(!(nz & ~0x1)); + assert(!(cpos & ~0x1f)); + assert(!((32-clen) & ~0x3f)); + ii((o<<26)|(t<<21)|(r<<16)|(c<<13)| + (c1<<12)|(cp<<11)|(nz<<10)|(cpos<<5)|(32-clen)); +} + +static void +_f16x(jit_state_t *_jit, jit_int32_t o, + jit_int32_t t, jit_int32_t i, jit_int32_t c, jit_int32_t c1, + jit_int32_t cp, jit_int32_t nz, jit_int32_t cpos, jit_int32_t clen) +{ + assert(!(o & ~0x3f)); + assert(!(t & ~0x1f)); + assert(i >= -16 && i <= 15); + assert(!(c & ~0x7)); + assert(!(c1 & ~0x1)); + assert(!(cp & ~0x1)); + assert(!(nz & ~0x1)); + assert(!(cpos & ~0x1f)); + assert(!((32-clen) & ~0x3f)); + ii((o<<26)|(t<<21)|(low_sign_unext(i,5)<<16)|(c<<13)| + (c1<<12)|(cp<<11)|(nz<<10)|(cpos<<5)|(32-clen)); +} + +static void +_f17(jit_state_t *_jit, jit_int32_t o, jit_int32_t r2, + jit_int32_t r1, jit_int32_t c, jit_int32_t i, jit_int32_t n) +{ + assert(!(o & ~0x3f)); + assert(!(r2 & ~0x1f)); + assert(!(r1 & ~0x1f)); + assert(!(c & ~0x7)); + assert(i >= -2048 && i <= 2047); + assert(!(n & ~0x1)); + ii((o<<26)|(r2<<21)|(r1<<16)|(c<<13)|re_assemble_12(i)|(n<<1)); +} + +static void +_f17x(jit_state_t *_jit, jit_int32_t o, jit_int32_t r, + jit_int32_t i, jit_int32_t c, jit_int32_t t, jit_int32_t n) +{ + assert(!(o & ~0x3f)); + assert(!(r & ~0x1f)); + assert(i >= -16 && i <= 15); + assert(!(c & ~0x7)); + assert(t >= -2048 && t <= 2047); + assert(!(n & ~0x1)); + ii((o<<26)|(r<<21)| + (low_sign_unext(i,5)<<16)|(c<<13)|re_assemble_12(t)|(n<<1)); +} + +static void +_f18(jit_state_t *_jit, jit_int32_t o, jit_int32_t p, + jit_int32_t r, jit_int32_t c, jit_int32_t i, jit_int32_t n) +{ + assert(!(o & ~0x3f)); + assert(!(p & ~0x1f)); + assert(!(r & ~0x1f)); + assert(!(c & ~0x1)); + assert(i >= -2048 && i <= 2047); + assert(!(n & ~0x1)); + ii((o<<26)|(p<<21)|(r<<16)|(c<<15)|(1<<14)|re_assemble_12(i)|(n<<1)); +} + +static void +_f19(jit_state_t *_jit, jit_int32_t o, jit_int32_t b, + jit_int32_t s, jit_int32_t i, jit_int32_t n) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(!(s & ~0x7)); + assert(i >= -65536 && i <= 65535); + assert(!(n & ~0x1)); + ii((o<<26)|(b<<21)|re_assemble_3(s)|re_assemble_17(i)|(n<<1)); +} + +static void +_f20(jit_state_t *_jit, jit_int32_t o, jit_int32_t t, + jit_int32_t i, jit_int32_t g, jit_int32_t n) +{ + assert(!(o & ~0x3f)); + assert(!(t & ~0x1f)); + assert(i >= -32768 && i <= 32767); + assert(!(g & ~0x7)); + assert(!(n & ~0x1)); + ii((o<<26)|(t<<21)|(g<<13)|re_assemble_17(i)|(n<<1)); +} + +static void +_f21(jit_state_t *_jit, jit_int32_t o, jit_int32_t t, + jit_int32_t x, jit_int32_t y, jit_int32_t n) +{ + assert(!(o & ~0x3f)); + assert(!(t & ~0x1f)); + assert(!(x & ~0x1f)); + assert(!(y & ~0x7)); + assert(!(n & ~0x1)); + ii((o<<26)|(t<<21)|(x<<16)|(y<<13)|(n<<1)); +} + +static void +_f22(jit_state_t *_jit, jit_int32_t o, jit_int32_t b, + jit_int32_t x, jit_int32_t r, jit_int32_t n, jit_int32_t p) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(!(x & ~0x7)); + assert(!(r & ~0x3f)); + assert(!(n & ~0x1)); + assert(!(p & ~0x1)); + ii((o<<26)|(b<<21)|(x<<13)|(1<<12)|(r<<2)|(n<<1)|p); +} + +static void +_f23(jit_state_t *_jit, jit_int32_t o, + jit_int32_t a, jit_int32_t b, jit_int32_t c, jit_int32_t d, + jit_int32_t e, jit_int32_t f, jit_int32_t g, jit_int32_t h) +{ + assert(!(o & ~0x3f)); + assert(!(a & ~0x1f)); + assert(!(b & ~0x1f)); + assert(!(c & ~0x7)); + assert(!(d & ~0x1)); + assert(!(e & ~0x1ff)); + assert(!(f & ~0x1)); + assert(!(g & ~0x1)); + assert(!(h & ~0x1)); + ii((o<<26)|(a<<21)|(b<<16)|(c<<13)|(d<<12)|(e<<3)|(f<<2)|(g<<1)|h); +} + +static void +_f24(jit_state_t *_jit, jit_int32_t o, + jit_int32_t b, jit_int32_t x, jit_int32_t s, + jit_int32_t y, jit_int32_t m,jit_int32_t r) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(!(x & ~0x1f)); + assert(!(s & ~0x3)); + assert(!(y & ~0xff)); + assert(!(m & ~0x1)); + assert(!(r & ~0x1f)); + ii((o<<26)|(b<<21)|(x<<16)|(s<<14)|(y<<6)|(m<<5)|r); +} + +static void +_f25(jit_state_t *_jit, jit_int32_t o, + jit_int32_t b, jit_int32_t i, jit_int32_t s, + jit_int32_t y, jit_int32_t m, jit_int32_t r) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(i >= -16 && i <= 15); + assert(!(s & ~0x3)); + assert(!(y & ~0xff)); + assert(!(m & ~0x1)); + assert(!(r & ~0x1f)); + ii((o<<26)|(b<<21)|(low_sign_unext(i,5)<<16)|(s<<14)|(y<<6)|(m<<5)|r); +} + +static void +_f26(jit_state_t *_jit, jit_int32_t o, + jit_int32_t b, jit_int32_t x, jit_int32_t s, + jit_int32_t y, jit_int32_t m,jit_int32_t r) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(!(x & ~0x1f)); + assert(!(s & ~0x7)); + assert(!(y & ~0x7f)); + assert(!(m & ~0x1)); + assert(!(r & ~0x1f)); + ii((o<<26)|(b<<21)|(x<<16)|(s<<13)|(y<<6)|(m<<5)|r); +} + +static void +_f27(jit_state_t *_jit, jit_int32_t o, jit_int32_t i, jit_int32_t j) +{ + assert(!(o & ~0x3f)); + assert(i >= -4096 && i < 4095); + assert(j >= -16 && j < 15); + ii((o<<26)|(i<<13)|j); +} + +static void +_f28(jit_state_t *_jit, jit_int32_t o, jit_int32_t i) +{ + assert(!(o & ~0x3f)); + assert(!(i & ~0x1ffffff)); + ii((o<<26)|i); +} + +static void +_f29(jit_state_t *_jit, jit_int32_t o, jit_int32_t r, + jit_int32_t x, jit_int32_t s, jit_int32_t y, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(r & ~0x1f)); + assert(!(x & ~0x1f)); + assert(!(s & ~0x7)); + assert(!(y & ~0xff)); + assert(!(t & ~0x1f)); + ii((o<<26)|(r<<21)|(x<<16)|re_assemble_3(s)|(y<<5)|t); +} + +static void +_f30(jit_state_t *_jit, jit_int32_t o, jit_int32_t b, jit_int32_t r, + jit_int32_t s, jit_int32_t x, jit_int32_t y, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(!(r & ~0x1f)); + assert(!(s & ~0x3)); + assert(!(x & ~0x1)); + assert(!(y & ~0xff)); + assert(!(t & ~0x1f)); + ii((o<<26)|(b<<21)|(r<<16)|(s<<14)|(x<<13)|(y<<5)|t); +} + +static void +_f31(jit_state_t *_jit, jit_int32_t o, jit_int32_t t, + jit_int32_t r, jit_int32_t v, jit_int32_t x, jit_int32_t y) +{ + assert(!(o & ~0x3f)); + assert(!(t & ~0x1f)); + assert(!(r & ~0x1f)); + assert(!(v & ~0x1f)); + assert(!(x & ~0xff)); + assert(!(y & ~0x1f)); + ii((o<<26)|(t<<21)|(r<<16)|(v<<14)|(x<<5)|y); +} + +static void +_f33(jit_state_t *_jit, jit_int32_t o, jit_int32_t x, + jit_int32_t r, jit_int32_t y, jit_int32_t z, jit_int32_t u) +{ + assert(!(o & ~0x3f)); + assert(!(x & ~0x1f)); + assert(!(r & ~0x1f)); + assert(!(y & ~0x7)); + assert(!(z & ~0xff)); + assert(!(u & ~0x1f)); + ii((o<<26)|(x<<21)|(r<<16)|(y<<13)|(z<<5)|u); +} + +static void +_f34(jit_state_t *_jit, jit_int32_t o, jit_int32_t o1, + jit_int32_t x, jit_int32_t sf, jit_int32_t n, jit_int32_t o2) +{ + assert(!(o & ~0x3f)); + assert(!(o1 & ~0x7fff)); + assert(!(x & ~0x3)); + assert(!(sf & ~0x7)); + assert(!(n & ~0x1)); + assert(!(o2 & ~0x1f)); + ii((o<<26)|(o1<<11)|(x<<9)|(sf<<6)|(n<<5)|o2); +} + +static void +_f35(jit_state_t *_jit, jit_int32_t o, jit_int32_t op, + jit_int32_t x, jit_int32_t sf, jit_int32_t n, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(op & ~0x7fff)); + assert(!(x & ~0x3)); + assert(!(sf & ~0x7)); + assert(!(n & ~0x1)); + assert(!(t & ~0x1f)); + ii((o<<26)|(op<<11)|(x<<9)|(sf<<6)|(n<<5)|t); +} + +static void +_f36(jit_state_t *_jit, jit_int32_t o, jit_int32_t r, jit_int32_t o1, + jit_int32_t x, jit_int32_t sf, jit_int32_t n, jit_int32_t o2) +{ + assert(!(o & ~0x3f)); + assert(!(r & ~0x1f)); + assert(!(o1 & ~0x3ff)); + assert(!(x & ~0x3)); + assert(!(sf & ~0x7)); + assert(!(n & ~0x1)); + assert(!(o2 & ~0x1f)); + ii((o<<26)|(r<<21)|(o1<<11)|(x<<9)|(sf<<6)|(n<<5)|o2); +} + +static void +_f37(jit_state_t *_jit, jit_int32_t o, jit_int32_t r2, + jit_int32_t r1, jit_int32_t o1, jit_int32_t x, + jit_int32_t sf, jit_int32_t n, jit_int32_t o2) +{ + assert(!(o & ~0x3f)); + assert(!(r2 & ~0x1f)); + assert(!(r1 & ~0x1f)); + assert(!(o1 & ~0x1f)); + assert(!(x & ~0x3)); + assert(!(sf & ~0x7)); + assert(!(n & ~0x1)); + assert(!(o2 & ~0x1f)); + ii((o<<26)|(r2<<21)|(r1<<16)|(o1<<11)|(x<<9)|(sf<<6)|(n<<5)|o2); +} + +static void +_f38(jit_state_t *_jit, jit_int32_t o, + jit_int32_t s, jit_int32_t u, jit_int32_t n) +{ + assert(!(o & ~0x3f)); + assert(!(s & ~0x3fffff)); + assert(!(u & ~0x7)); + assert(!(n & ~0x1)); + ii((o<<26)|((s>>5)<<9)|(u<<6)|(n<<1)|(s&0x1f)); +} + +static void +_nop(jit_state_t *_jit, jit_int32_t i0) +{ + for (; i0 > 0; i0 -= 4) + NOP(); + assert(i0 == 0); +} + +static void +_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + COPY(r1, r0); +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + if (i0 >= -8192 && i0 <= 8191) + LDI(i0, r0); + else if (!(i0 & 0x7ff)) + LDIL(i0, r0); + else { + LDIL(i0 & ~0x7ff, r0); + LDO(i0 & 0x7ff, r0, r0); + } +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + w = _jit->pc.w; + LDIL(i0 & ~0x7ff, r0); + LDO(i0 & 0x7ff, r0, r0); + return (w); +} + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -1024 && i0 <= 1023) + ADDI(i0, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addcr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addxr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -1023 && i0 <= 1024) + addi(r0, r1, -i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subcr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subxr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -1024 && i0 <= 1023) + SUBI(i0, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subr(r0, rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_mulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_fpr); + t1 = jit_get_reg(jit_class_fpr); + stxi(alloca_offset - 8, _FP_REGNO, r1); + ldxi_f(rn(t0), _FP_REGNO, alloca_offset - 8); + stxi(alloca_offset - 8, _FP_REGNO, r2); + ldxi_f(rn(t1), _FP_REGNO, alloca_offset - 8); + XMPYU(rn(t0), rn(t1), rn(t0)); + stxi_d(alloca_offset - 8, _FP_REGNO, rn(t0)); + ldxi(r0, _FP_REGNO, alloca_offset - 4); + jit_unget_reg(t1); + jit_unget_reg(t0); +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (r0 != r1) { + movi(r0, i0); + mulr(r0, r1, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + mulr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static long long +__llmul(int u, int v) +{ + return ((long long)u * (long long)v); +} + +static void +_qmulr(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + movr(_R26_REGNO, r2); + movr(_R25_REGNO, r3); + calli((jit_word_t)__llmul); + movr(r0, _R29_REGNO); + movr(r1, _R28_REGNO); +} + +static void +_qmuli(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + movr(_R26_REGNO, r2); + movi(_R25_REGNO, i0); + calli((jit_word_t)__llmul); + movr(r0, _R29_REGNO); + movr(r1, _R28_REGNO); +} + +static void +_qmulr_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_fpr); + t1 = jit_get_reg(jit_class_fpr); + stxi(alloca_offset - 8, _FP_REGNO, r2); + ldxi_f(rn(t0), _FP_REGNO, alloca_offset - 8); + stxi(alloca_offset - 8, _FP_REGNO, r3); + ldxi_f(rn(t1), _FP_REGNO, alloca_offset - 8); + XMPYU(rn(t0), rn(t1), rn(t0)); + stxi_d(alloca_offset - 8, _FP_REGNO, rn(t0)); + ldxi(r0, _FP_REGNO, alloca_offset - 4); + ldxi(r1, _FP_REGNO, alloca_offset - 8); + jit_unget_reg(t1); + jit_unget_reg(t0); +} + +static void +_qmuli_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + qmulr_u(r0, r1, r2, rn(reg)); + jit_unget_reg(reg); +} + +static int +__idiv(int u, int v) +{ + return (u / v); +} + +static void +_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + movr(_R26_REGNO, r1); + movr(_R25_REGNO, r2); + calli((jit_word_t)__idiv); + movr(r0, _R28_REGNO); +} + +static void +_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(_R26_REGNO, r1); + movi(_R25_REGNO, i0); + calli((jit_word_t)__idiv); + movr(r0, _R28_REGNO); +} + +static unsigned int +__udiv(unsigned int u, unsigned int v) +{ + return (u / v); +} + +static void +_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + movr(_R26_REGNO, r1); + movr(_R25_REGNO, r2); + calli((jit_word_t)__udiv); + movr(r0, _R28_REGNO); +} + +static void +_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(_R26_REGNO, r1); + movi(_R25_REGNO, i0); + calli((jit_word_t)__udiv); + movr(r0, _R28_REGNO); +} + +static int +__irem(int u, int v) +{ + return (u % v); +} + +static void +_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + movr(_R26_REGNO, r1); + movr(_R25_REGNO, r2); + calli((jit_word_t)__irem); + movr(r0, _R28_REGNO); +} + +static void +_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(_R26_REGNO, r1); + movi(_R25_REGNO, i0); + calli((jit_word_t)__irem); + movr(r0, _R28_REGNO); +} + +static unsigned int +__urem(unsigned int u, unsigned int v) +{ + return (u % v); +} + +static void +_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + movr(_R26_REGNO, r1); + movr(_R25_REGNO, r2); + calli((jit_word_t)__urem); + movr(r0, _R28_REGNO); +} + +static void +_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(_R26_REGNO, r1); + movi(_R25_REGNO, i0); + calli((jit_word_t)__urem); + movr(r0, _R28_REGNO); +} + +static idiv_t +__idivrem(int u, int v) +{ + idiv_t div; + div.quo = u / v; + div.rem = u % v; + return (div); +} + +static void +_qdivr(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + movr(_R26_REGNO, r2); + movr(_R25_REGNO, r3); + calli((jit_word_t)__idivrem); + movr(r0, _R28_REGNO); + movr(r1, _R29_REGNO); +} + +static void +_qdivi(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + movr(_R26_REGNO, r2); + movi(_R25_REGNO, i0); + calli((jit_word_t)__idivrem); + movr(r0, _R28_REGNO); + movr(r1, _R29_REGNO); +} + +static udiv_t +__udivrem(unsigned int u, unsigned int v) +{ + udiv_t div; + div.quo = u / v; + div.rem = u % v; + return (div); +} + +static void +_qdivr_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + movr(_R26_REGNO, r2); + movr(_R25_REGNO, r3); + calli((jit_word_t)__udivrem); + movr(r0, _R28_REGNO); + movr(r1, _R29_REGNO); +} + +static void +_qdivi_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + movr(_R26_REGNO, r2); + movi(_R25_REGNO, i0); + calli((jit_word_t)__udivrem); + movr(r0, _R28_REGNO); + movr(r1, _R29_REGNO); +} + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + andr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + orr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + xorr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_lshr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + SUBI(0x1f, r2, _R1_REGNO); + MTSAR(_R1_REGNO); + DEPW_Z(r1, 32, r0); +} + +static void +_rshr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + SUBI(0x1f, r2, _R1_REGNO); + MTSAR(_R1_REGNO); + EXTRW(r1, 32, r0); +} + +static void +_rshr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + SUBI(0x1f, r2, _R1_REGNO); + MTSAR(_R1_REGNO); + EXTRW_U(r1, 32, r0); +} + +static void +_cmpr(jit_state_t *_jit, jit_word_t c, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMPCLR_(c, r1, r2, r0); + LDI(1, r0); +} + +static void +_cmpi(jit_state_t *_jit, jit_word_t c, jit_word_t ci, + jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -16 && i0 <= 15) + CMPICLR_(ci, i0, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMPCLR_(c, r1, rn(reg), r0); + jit_unget_reg(reg); + } + LDI(1, r0); +} + +static void +_ldr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + ldr_uc(r0, r1); + extr_c(r0, r0); +} + +static void +_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + ldi_uc(r0, i0); + extr_c(r0, r0); +} + +static void +_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + ldxr_uc(r0, r1, r2); + extr_c(r0, r0); +} + +static void +_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi_uc(r0, r1, i0); + extr_c(r0, r0); +} + +static void +_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -8182 && i0 <= 8191) + LDBL(i0, _R0_REGNO, r0); + else { + reg = jit_get_reg(jit_class_gpr); + LDIL(i0 & ~0x7ff, rn(reg)); + LDBL(sign_extend(i0, 11), rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -16 && i0 <= 15) + LDBI(i0, r1, r0); + else if (i0 >= -8182 && i0 <= 8191) + LDBL(i0, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_uc(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + ldr_us(r0, r1); + extr_s(r0, r0); +} + +static void +_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + ldi_us(r0, i0); + extr_s(r0, r0); +} + +static void +_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + ldxr_us(r0, r1, r2); + extr_s(r0, r0); +} + +static void +_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi_us(r0, r1, i0); + extr_s(r0, r0); +} + +static void +_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -8182 && i0 <= 8191) + LDHL(i0, _R0_REGNO, r0); + else { + reg = jit_get_reg(jit_class_gpr); + LDIL(i0 & ~0x7ff, rn(reg)); + LDHL(sign_extend(i0, 11), rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -16 && i0 <= 15) + LDHI(i0, r1, r0); + else if (i0 >= -8182 && i0 <= 8191) + LDHL(i0, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_us(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -8182 && i0 <= 8191) + LDWL(i0, _R0_REGNO, r0); + else { + reg = jit_get_reg(jit_class_gpr); + LDIL(i0 & ~0x7ff, rn(reg)); + LDWL(sign_extend(i0, 11), rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -16 && i0 <= 15) + LDWI(i0, r1, r0); + else if (i0 >= -8182 && i0 <= 8191) + LDWL(i0, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_ui(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (i0 >= -8182 && i0 <= 8191) + STBL(r0, i0, _R0_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + LDIL(i0 & ~0x7ff, rn(reg)); + STBL(r0, sign_extend(i0, 11), rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_c(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0 >= -16 && i0 <= 15) + STBI(r1, i0, r0); + else if (i0 >= -8182 && i0 <= 8191) + STBL(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_c(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (i0 >= -8182 && i0 <= 8191) + STHL(r0, i0, _R0_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + LDIL(i0 & ~0x7ff, rn(reg)); + STHL(r0, sign_extend(i0, 11), rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_s(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0 >= -16 && i0 <= 15) + STHI(r1, i0, r0); + else if (i0 >= -8182 && i0 <= 8191) + STHL(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_s(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (i0 >= -8182 && i0 <= 8191) + STWL(r0, i0, _R0_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + LDIL(i0 & ~0x7ff, rn(reg)); + STWL(r0, sign_extend(i0, 11), rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_i(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0 >= -16 && i0 <= 15) + STWI(r1, i0, r0); + else if (i0 >= -8182 && i0 <= 8191) + STWL(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_i(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static jit_word_t +_bcmpr(jit_state_t *_jit, jit_word_t c, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + CMPB_N_(c, r0, r1, ((i0 - w) >> 2) - 2); + NOP(); + return (w); +} + +static jit_word_t +_bcmpi(jit_state_t *_jit, jit_word_t c, jit_word_t ci, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 >= -16 && i1 <= 15) { + w = _jit->pc.w; + CMPIB_N_(ci, i1, r0, ((i0 - w) >> 2) - 2); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = _jit->pc.w; + CMPB_N_(c, r0, rn(reg), ((i0 - w) >> 2) - 2); + jit_unget_reg(reg); + } + NOP(); + return (w); +} + +static jit_word_t +_bmxr(jit_state_t *_jit, jit_bool_t c, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + andr(rn(reg), r0, r1); + w = c ? bnei(i0, rn(reg), 0) : beqi(i0, rn(reg), 0); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bmxi(jit_state_t *_jit, jit_bool_t c, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + andr(rn(reg), r0, rn(reg)); + w = c ? bnei(i0, rn(reg), 0) : beqi(i0, rn(reg), 0); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_boaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + ADDB_N_SV(r1, r0, ((i0 - w) >> 2) - 2); + NOP(); + return (w); +} + +static jit_word_t +_boaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 >= -16 && i1 <= 15) { + w = _jit->pc.w; + ADDIB_N_SV(i1, r0, ((i0 - w) >> 2) - 2); + NOP(); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = boaddr(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_boaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + ADDB_N_UV(r1, r0, ((i0 - w) >> 2) - 2); + NOP(); + return (w); +} + +static jit_word_t +_boaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 >= -16 && i1 <= 15) { + w = _jit->pc.w; + ADDIB_N_UV(i1, r0, ((i0 - w) >> 2) - 2); + NOP(); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = boaddr_u(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bxaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + ADDB_N_NSV(r1, r0, ((i0 - w) >> 2) - 2); + NOP(); + return (w); +} + +static jit_word_t +_bxaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 >= -16 && i1 <= 15) { + w = _jit->pc.w; + ADDIB_N_NSV(i1, r0, ((i0 - w) >> 2) - 2); + NOP(); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bxaddr(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bxaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + ADDB_N_NUV(r1, r0, ((i0 - w) >> 2) - 2); + NOP(); + return (w); +} + +static jit_word_t +_bxaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 >= -16 && i1 <= 15) { + w = _jit->pc.w; + ADDIB_N_NUV(i1, r0, ((i0 - w) >> 2) - 2); + NOP(); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bxaddr_u(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bosubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + SUB_NSV(r0, r1, r0); + w = _jit->pc.w; + /* null'ed if no signed overflow */ + B_N(((i0 - w) >> 2) - 2, _R0_REGNO); + NOP(); + return (w); +} + +static jit_word_t +_bosubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + movi(_R1_REGNO, i1); + return (bosubr(i0, r0, _R1_REGNO)); +} + +static jit_word_t +_bosubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + SUB(r0, r1, r0); + SUB_B(_R0_REGNO, _R0_REGNO, _R1_REGNO); + return (bnei(i0, _R1_REGNO, 0)); +} + +static jit_word_t +_bosubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + movi(_R1_REGNO, i1); + SUB(r0, _R1_REGNO, r0); + SUB_B(_R0_REGNO, _R0_REGNO, _R1_REGNO); + return (bnei(i0, _R1_REGNO, 0)); +} + +static jit_word_t +_bxsubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + SUB_SV(r0, r1, r0); + w = _jit->pc.w; + /* null'ed if signed overflow */ + B_N(((i0 - w) >> 2) - 2, _R0_REGNO); + NOP(); + return (w); +} + +static jit_word_t +_bxsubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + movi(_R1_REGNO, i1); + return (bxsubr(i0, r0, _R1_REGNO)); +} + +static jit_word_t +_bxsubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + SUB(r0, r1, r0); + SUB_B(_R0_REGNO, _R0_REGNO, _R1_REGNO); + return (beqi(i0, _R1_REGNO, 0)); +} + +static jit_word_t +_bxsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + movi(_R1_REGNO, i1); + SUB(r0, _R1_REGNO, r0); + SUB_B(_R0_REGNO, _R0_REGNO, _R1_REGNO); + return (beqi(i0, _R1_REGNO, 0)); +} + +static void +_jmpr(jit_state_t *_jit, jit_int32_t r0) +{ + BV_N(_R0_REGNO, r0); +} + +static void +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + w = ((i0 - _jit->pc.w) >> 2) - 2; + if (w >= -32768 && w <= 32767) + B_N(w, _R0_REGNO); + else { + movi(_R1_REGNO, w); + BV_N(_R0_REGNO, _R1_REGNO); + } +} + +static jit_word_t +_jmpi_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + w = movi_p(_R1_REGNO, i0); + jmpr(_R1_REGNO); + return (w); +} + +static void +_callr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_word_t dyn; + jit_word_t imm; + if (r0 != _R1_REGNO) + COPY(r0, _R1_REGNO); + /* inline $$dyncall */ + imm = _jit->pc.w; + BBI_N_GE(_R1_REGNO, 30, 0); /* if (r1 & 2) { */ + DEPWRI(0, 31, 2, _R1_REGNO); /* r1 &= ~2; */ + LDWI(4, _R1_REGNO, _R19_REGNO); /* r19 = r1[1]; */ + LDWI(0, _R1_REGNO, _R1_REGNO); /* r1 = r1[0]; */ + /* } */ + BVE_L(_R1_REGNO); + STWL(_RP_REGNO, -24, _SP_REGNO); + dyn = _jit->pc.w; + jmpi(_jit->pc.w); + patch_at(imm, _jit->pc.w); + BVE_L_N(_R1_REGNO); + NOP(); + patch_at(dyn, _jit->pc.w); +} + +static void +_calli(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + if (i0 & 2) { + i0 &= -4; + movi(_R1_REGNO, i0); + LDWI(4, _R1_REGNO, _R19_REGNO); + LDWI(0, _R1_REGNO, _R1_REGNO); + BVE_L(_R1_REGNO); + STWL(_RP_REGNO, -24, _SP_REGNO); + } + else { + w = ((i0 - _jit->pc.w) >> 2) - 2; + if (w >= -32768 && w <= 32767) + B_L_N(w); + else { + movi(_R1_REGNO, i0); + BVE_L_N(_R1_REGNO); + } + NOP(); + } +} + +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + w = movi_p(_R1_REGNO, i0); + callr(_R1_REGNO); + return (w); +} + +static jit_int32_t gr[] = { + _R4, _R5, _R6, _R7, _R8, + _R9, _R10, _R11, _R12, _R13, + _R14, _R15, _R16, _R17, _R18 +}; + +static jit_int32_t fr[] = { + _F12, _F13, _F14, _F15, _F16, + _F17, _F18, _F19, _F20, _F21 +}; + +static void +_prolog(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t regno; + jit_word_t offset; + + if (_jitc->function->define_frame || _jitc->function->assume_frame) { + /* hppa stack grows up */ + assert(_jitc->function->self.aoff <= _jitc->function->frame); + if (_jitc->function->assume_frame) + return; + _jitc->function->self.aoff = _jitc->function->frame; + } + if (_jitc->function->allocar) { + _jitc->function->self.aoff += 63; + _jitc->function->self.aoff &= -64; + } + _jitc->function->stack = ((_jitc->function->self.aoff - + _jitc->function->self.alen - + _jitc->function->self.size) + 63) & -64; + + /* Save stack frame (FIXME Only required if non leaf) */ + STWL(_RP_REGNO, -20, _SP_REGNO); + + /* Create stack frame */ + COPY(_FP_REGNO, _R1_REGNO); + COPY(_SP_REGNO, _FP_REGNO); + STWL_MA(_R1_REGNO, _jitc->function->stack, _SP_REGNO); + + /* Save any modified callee save registers */ + offset = alloca_offset - 140; + for (regno = 0; regno < jit_size(gr); regno++, offset += 4) { + if (jit_regset_tstbit(&_jitc->function->regset, gr[regno])) + stxi(offset, _FP_REGNO, rn(gr[regno])); + } + for (regno = 0; regno < jit_size(fr); regno++, offset += 8) { + if (jit_regset_tstbit(&_jitc->function->regset, fr[regno])) + stxi_d(offset, _FP_REGNO, rn(fr[regno])); + } + + if (_jitc->function->allocar) { + regno = jit_get_reg(jit_class_gpr); + movi(rn(regno), _jitc->function->self.aoff); + stxi_i(_jitc->function->aoffoff, _FP_REGNO, rn(regno)); + jit_unget_reg(regno); + } + + if (_jitc->function->self.call & jit_call_varargs) { + for (regno = 3; regno >= _jitc->function->vagp; --regno) + stxi(params_offset - regno * 4 - 4, _FP_REGNO, rn(_R26 - regno)); + } +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t regno; + jit_word_t offset; + + if (_jitc->function->assume_frame) + return; + /* Restore any modified callee save registers */ + offset = alloca_offset - 140; + for (regno = 0; regno < jit_size(gr); regno++, offset += 4) { + if (jit_regset_tstbit(&_jitc->function->regset, gr[regno])) + ldxi(rn(gr[regno]), _FP_REGNO, offset); + } + for (regno = 0; regno < jit_size(fr); regno++, offset += 8) { + if (jit_regset_tstbit(&_jitc->function->regset, fr[regno])) + ldxi_d(rn(fr[regno]), _FP_REGNO, offset); + } + + /* Restore stack frame (FIXME Only required if non leaf) */ + LDWL(-20, _FP_REGNO, _RP_REGNO); + LDO(_jitc->function->stack, _FP_REGNO, _SP_REGNO); + LDWL_MB(-_jitc->function->stack, _SP_REGNO, _FP_REGNO); +#if defined(__hpux) + BVE_N(_RP_REGNO); +#else + BV_N(_R0_REGNO, _RP_REGNO); +#endif +} + +static void +_vastart(jit_state_t *_jit, jit_int32_t r0) +{ + /* Initialize stack pointer to the first stack argument. */ + if (jit_arg_reg_p(_jitc->function->vagp)) + addi(r0, _FP_REGNO, params_offset - _jitc->function->vagp * 4); + else + addi(r0, _FP_REGNO, _jitc->function->self.size); +} + +static void +_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(_jitc->function->self.call & jit_call_varargs); + + /* Update vararg stack pointer. */ + subi(r1, r1, 4); + + /* Load argument. */ + ldr(r0, r1); +} + +static void +_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label) +{ + jit_word_t w; + union { + jit_uint32_t *i; + jit_word_t w; + } u; + u.w = instr; + switch (u.i[0] >> 26) { + case 0x8: /* LDIL */ + u.i[0] &= ~0x1fffff; + u.i[0] |= re_assemble_21((label & ~0x7ff) >> 11); + assert((u.i[1] >> 26) == 0xd); /* LDO */ + u.i[1] &= ~0xffff; + u.i[1] |= re_assemble_16(label & 0x7ff); + break; + case 0x20: case 0x22: /* CMPB */ + case 0x21: case 0x23: /* CMPIB */ + case 0x28: case 0x2a: /* ADDB */ + case 0x29: case 0x2b: /* ADDIB */ + case 0x31: /* BBI */ + w = ((label - instr) >> 2) - 2; + assert(w >= -2048 && w <= 2047); + u.i[0] &= ~0x1ffd; + u.i[0] |= re_assemble_12(w); + break; + case 0x3a: /* B */ + w = ((label - instr) >> 2) - 2; + assert(w >= -32768 && w <= 32767); + u.i[0] &= ~0x1f1ffd; + u.i[0] |= re_assemble_17(w); + break; + default: + abort(); + } +} +#endif diff --git a/deps/lightning/lib/jit_hppa-fpu.c b/deps/lightning/lib/jit_hppa-fpu.c new file mode 100644 index 0000000..5fa6856 --- /dev/null +++ b/deps/lightning/lib/jit_hppa-fpu.c @@ -0,0 +1,1070 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO + +/* FIXME should actually be hw model/version/etc or other constraint + * that causes a SIGSEGV/SIGILL if using these instructions */ +#if 1 //defined(__hpux) +# define FSTXR 0 +# define FLDXR 0 +#else +# define FSTXR 1 +# define FLDXR 1 +#endif + +#define f39(o,b,x,t) _f39(_jit,o,b,x,t) +static void _f39(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f40(o,b,x,r) _f40(_jit,o,b,x,r) +static void _f40(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) + maybe_unused; +#define f41(o,b,x,t) _f41(_jit,o,b,x,t) +static void _f41(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f42(o,b,i,r) _f42(_jit,o,b,i,r) +static void _f42(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f43(o,b,t,i) f1(o,b,t,i) +#define f45(o,r,a,b,fmt,c,d,e,t) _f45(_jit,o,r,a,b,fmt,c,d,e,t) +static void _f45(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f46(o,r,a,s,df,sf,b,c,d,t) _f46(_jit,o,r,a,s,df,sf,b,c,d,t) +static void _f46(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f47(o,r1,r2,a,fmt,b,c,d,t) f47_48(o,r1,r2,a,fmt,b,c,d,t) +#define f48(o,r1,r2,a,fmt,b,c,d,t) f47_48(o,r1,r2,a,fmt,b,c,d,t) +#define f47_48(o,r1,r2,y,fmt,b,c,d,t) _f47_48(_jit,o,r1,r2,y,fmt,b,c,d,t) +static void _f47_48(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f49(o,r,a,b,c,f,d,e,g,h,i,t) f49_52(o,r,a,b,c,f,d,e,g,h,i,t) +#define f51(o,r1,r2,y,a,f,b,d,e,g,h,c) f49_52(o,r1,r2,y,a,f,b,d,e,g,h,c) +#define f52(o,r1,r2,a,b,f,c,d,e,g,h,t) f49_52(o,r1,r2,a,b,f,c,d,e,g,h,t) +#define f49_52(o,r1,r2,y,v,f,a,b,u,c,d,t) _f49_52(_jit,o,r1,r2,y,v,f,a,b,u,c,d,t) +static void _f49_52(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define f53(o,r1,r2,ta,ra,f,tm) _f53(_jit,o,r1,r2,ta,ra,f,tm) +static void _f53(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define f54(o,r1,r2,a,b,f,c,d,e,g,t) _f54(_jit,o,r1,r2,a,b,f,c,d,e,g,t) +static void _f54(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) maybe_unused; +#define FABS_(f,r,t) f49(0xe,r,0,3,0,f,0,0,0,0,0,t) +#define FABS_S(r,t) FABS_(0,r,t) +#define FABS_D(r,t) FABS_(1,r,t) +#define FABS_Q(r,t) f45(0xc,r,0,3,3,0,0,0,t) +#define FADD_(f,r1,r2,t) f52(0xe,r1,r2,0,0,f,3,0,0,0,0,t) +#define FADD_S(r1,r2,t) FADD_(0,r1,r2,t) +#define FADD_D(r1,r2,t) FADD_(1,r1,r2,t) +#define FADD_Q(r1,r2,t) f48(0xc,r1,r2,0,3,3,0,0,t) +#define FPSR_GT 1 +#define FPSR_LT 2 +#define FPSR_EQ 4 +#define FPSR_UN 8 +/* + Actually these are reversed, but easier for the FTEST after the FCMP + fcmp,dbl,false? fr4,fr12 0 + fcmp,dbl,false fr4,fr12 1 + fcmp,dbl,? fr4,fr12 2 + fcmp,dbl,!<=> fr4,fr12 3 ORD + fcmp,dbl,= fr4,fr12 4 NE + fcmp,dbl,=t fr4,fr12 5 + fcmp,dbl,?= fr4,fr12 6 + fcmp,dbl,!<> fr4,fr12 7 LTGT + fcmp,dbl,!?>= fr4,fr12 8 + fcmp,dbl,< fr4,fr12 9 UNGE + fcmp,dbl,?< fr4,fr12 10 + fcmp,dbl,!>= fr4,fr12 11 GE + fcmp,dbl,!?> fr4,fr12 12 + fcmp,dbl,<= fr4,fr12 13 UNGT + fcmp,dbl,?<= fr4,fr12 14 + fcmp,dbl,!> fr4,fr12 15 GT + fcmp,dbl,!?<= fr4,fr12 16 + fcmp,dbl,> fr4,fr12 17 UNLE + fcmp,dbl,?> fr4,fr12 18 + fcmp,dbl,!<= fr4,fr12 19 LE + fcmp,dbl,!?< fr4,fr12 20 + fcmp,dbl,>= fr4,fr12 21 UNLT + fcmp,dbl,?>= fr4,fr12 22 + fcmp,dbl,!< fr4,fr12 23 LT + fcmp,dbl,!?= fr4,fr12 24 + fcmp,dbl,<> fr4,fr12 25 UNEQ + fcmp,dbl,!= fr4,fr12 26 EQ + fcmp,dbl,!=t fr4,fr12 27 + fcmp,dbl,!? fr4,fr12 28 + fcmp,dbl,<=> fr4,fr12 29 UNORD + fcmp,dbl,true? fr4,fr12 30 + fcmp,dbl,true fr4,fr12 31 + */ +#define FCMP_LT 23 +#define FCMP_LE 19 +#define FCMP_EQ 26 +#define FCMP_GE 11 +#define FCMP_GT 15 +#define FCMP_NE 4 +#define FCMP_UNLT 21 +#define FCMP_UNLE 17 +#define FCMP_UNEQ 25 +#define FCMP_UNGE 9 +#define FCMP_UNGT 13 +#define FCMP_LTGT 7 +#define FCMP_ORD 3 +#define FCMP_UNORD 29 +#define FCMP_(f,r1,r2,c) f51(0xe,r1,r2,0,0,f,2,0,0,0,0,c) +#define FCMP_S_(r1,r2,c) FCMP_(0,r1,r2,c) +#define FCMP_D_(r1,r2,c) FCMP_(1,r1,r2,c) +#define FCMP_Q_(r1,r2,c) f47(0xc,r1,r2,0,3,2,0,0,c) +#define FCMP_S_LT(r1,r2) FCMP_S_(r1,r2,FCMP_LT) +#define FCMP_D_LT(r1,r2) FCMP_D_(r1,r2,FCMP_LT) +#define FCMP_Q_LT(r1,r2) FCMP_Q_(r1,r2,FCMP_LT) +#define FCMP_S_LE(r1,r2) FCMP_S_(r1,r2,FCMP_LE) +#define FCMP_D_LE(r1,r2) FCMP_D_(r1,r2,FCMP_LE) +#define FCMP_Q_LE(r1,r2) FCMP_Q_(r1,r2,FCMP_LE) +#define FCMP_S_EQ(r1,r2) FCMP_S_(r1,r2,FCMP_EQ) +#define FCMP_D_EQ(r1,r2) FCMP_D_(r1,r2,FCMP_EQ) +#define FCMP_Q_EQ(r1,r2) FCMP_Q_(r1,r2,FCMP_EQ) +#define FCMP_S_GE(r1,r2) FCMP_S_(r1,r2,FCMP_GE) +#define FCMP_D_GE(r1,r2) FCMP_D_(r1,r2,FCMP_GE) +#define FCMP_Q_GE(r1,r2) FCMP_Q_(r1,r2,FCMP_GE) +#define FCMP_S_GT(r1,r2) FCMP_S_(r1,r2,FCMP_GT) +#define FCMP_D_GT(r1,r2) FCMP_D_(r1,r2,FCMP_GT) +#define FCMP_Q_GT(r1,r2) FCMP_Q_(r1,r2,FCMP_GT) +#define FCMP_S_NE(r1,r2) FCMP_S_(r1,r2,FCMP_NE) +#define FCMP_D_NE(r1,r2) FCMP_D_(r1,r2,FCMP_NE) +#define FCMP_Q_NE(r1,r2) FCMP_Q_(r1,r2,FCMP_NE) +#define FCMP_S_UNLT(r1,r2) FCMP_S_(r1,r2,FCMP_UNLT) +#define FCMP_D_UNLT(r1,r2) FCMP_D_(r1,r2,FCMP_UNLT) +#define FCMP_Q_UNLT(r1,r2) FCMP_Q_(r1,r2,FCMP_UNLT) +#define FCMP_S_UNLE(r1,r2) FCMP_S_(r1,r2,FCMP_UNLE) +#define FCMP_D_UNLE(r1,r2) FCMP_D_(r1,r2,FCMP_UNLE) +#define FCMP_Q_UNLE(r1,r2) FCMP_Q_(r1,r2,FCMP_UNLE) +#define FCMP_S_UNEQ(r1,r2) FCMP_S_(r1,r2,FCMP_UNEQ) +#define FCMP_D_UNEQ(r1,r2) FCMP_D_(r1,r2,FCMP_UNEQ) +#define FCMP_Q_UNEQ(r1,r2) FCMP_Q_(r1,r2,FCMP_UNEQ) +#define FCMP_S_UNGE(r1,r2) FCMP_S_(r1,r2,FCMP_UNGE) +#define FCMP_D_UNGE(r1,r2) FCMP_D_(r1,r2,FCMP_UNGE) +#define FCMP_Q_UNGE(r1,r2) FCMP_Q_(r1,r2,FCMP_UNGE) +#define FCMP_S_UNGT(r1,r2) FCMP_S_(r1,r2,FCMP_UNGT) +#define FCMP_D_UNGT(r1,r2) FCMP_D_(r1,r2,FCMP_UNGT) +#define FCMP_Q_UNGT(r1,r2) FCMP_Q_(r1,r2,FCMP_UNGT) +#define FCMP_S_LTGT(r1,r2) FCMP_S_(r1,r2,FCMP_LTGT) +#define FCMP_D_LTGT(r1,r2) FCMP_D_(r1,r2,FCMP_LTGT) +#define FCMP_Q_LTGT(r1,r2) FCMP_Q_(r1,r2,FCMP_LTGT) +#define FCMP_S_ORD(r1,r2) FCMP_S_(r1,r2,FCMP_ORD) +#define FCMP_D_ORD(r1,r2) FCMP_D_(r1,r2,FCMP_ORD) +#define FCMP_Q_ORD(r1,r2) FCMP_Q_(r1,r2,FCMP_ORD) +#define FCMP_S_UNORD(r1,r2) FCMP_S_(r1,r2,FCMP_UNORD) +#define FCMP_D_UNORD(r1,r2) FCMP_D_(r1,r2,FCMP_UNORD) +#define FCMP_Q_UNORD(r1,r2) FCMP_Q_(r1,r2,FCMP_UNORD) +#define XFNVFF(s,d,r,t) f46(0xc,r,0,0,d,s,1,0,0,t) +#define FCNVFF_Q_S(r,t) XFNVFF(3,0,r,t) +#define FCNVFF_Q_D(r,t) XFNVFF(3,1,r,t) +#define FCNVFF_S_Q(r,t) XFNVFF(0,3,r,t) +#define FCNVFF_D_Q(r,t) XFNVFF(1,3,r,t) +#define FCNVFF_(s,d,r,t) f46(0xc,r,0,0,d,s,1,0,0,t) +#define FCNVFF_S_D(r,t) FCNVFF_(0,1,r,t) +#define FCNVFF_D_S(r,t) FCNVFF_(1,0,r,t) +#define FCNVXF_(s,d,r,t) f46(0xc,r,0,1,d,s,1,0,0,t) +#define FCNVXF_S_S(r,t) FCNVXF_(0,0,r,t) +#define FCNVXF_S_D(r,t) FCNVXF_(0,1,r,t) +#define FCNVXT_(s,d,r,t) f46(0xc,r,0,3,d,s,1,0,0,t) +#define FCNVXT_S_S(r,t) FCNVXT_(0,0,r,t) +#define FCNVXT_D_S(r,t) FCNVXT_(1,0,r,t) +#define FCPY_(f,r,t) f49(0xe,r,0,2,0,f,0,0,0,0,0,t) +#define FCPY_S(r,t) FCPY_(0,r,t) +#define FCPY_D(r,t) FCPY_(1,r,t) +#define FCPY_Q(r,t) f45(0xc,r,0,2,2,0,0,0,t) +#define FDIV_(f,r1,r2,t) f52(0xe,r1,r2,3,0,f,3,0,0,0,0,t) +#define FDIV_S(r1,r2,t) FDIV_(0,r1,r2,t) +#define FDIV_D(r1,r2,t) FDIV_(1,r1,r2,t) +#define FDIV_Q(r1,r2,t) f48(0xc,r1,r2,3,3,3,0,0,t) +#define FID() f45(0xc,0,0,0,2,0,0,0,0) +#define FLDDL(i,b,t) f3(0x14,b,t,i,1) +#define FLDD(x,b,t) f39(0xb,b,x,t) +#define FLDDI(i,b,t) f41(0xb,b,i,t) +#define FLDWL(i,b,t) f43(0x17,b,t,i) +#define FLDW(x,b,t) f39(0x9,b,x,t) +#define FLDWI(i,b,t) f41(0x9,b,i,t) +#define FMPY_(f,r1,r2,t) f52(0xe,r1,r2,2,0,f,3,0,0,0,0,t) +#define FMPY_S(r1,r2,t) FMPY_(0,r1,r2,t) +#define FMPY_D(r1,r2,t) FMPY_(1,r1,r2,t) +#define FMPY_Q(r1,r2,t) f48(0xc,r1,r2,2,3,3,0,0,t) +/* FIXME not disassembled */ +#define FMPYADD_(f,r1,r2,ta,ra,tm) f53(0x6,r1,r2,ta,ra,f,tm) +#define FMPYADD_S(r1,r2,ta,ra,tm) FMPYADD_(0,r1,r2,ta,ra,tm) +#define FMPYADD_D(r1,r2,ta,ra,tm) FMPYADD_(1,r1,r2,ta,ra,tm) +#define FMPYFADD_(f,r1,r2,ra,t) f54(0x2e,r1,r2,ra>>3,0,f,(ra)&7,0,0,0,t) +#define FMPYFADD_S(r1,r2,ra,t) FMPYFADD_(0,r1,r2,ra,t) +#define FMPYFADD_D(r1,r2,ra,t) FMPYFADD_(1,r1,r2,ra,t) +#define FMPYNFADD_(f,r1,r2,ra,t) f54(0x2e,r1,r2,ra>>3,0,f,(ra)&7,0,0,1,t) +#define FMPYNFADD_S(r1,r2,ra,t) FMPYNFADD_(0,r1,r2,ra,t) +#define FMPYNFADD_D(r1,r2,ra,t) FMPYNFADD_(1,r1,r2,ra,t) +#define FMPYSUB_(f,r1,r2,ta,ra,tm) f53(0x26,r1,r2,ta,ra,f,tm) +#define FMPYSUB_S(r1,r2,ta,ra,tm) FMPYSUB_(0,r1,r2,ta,ra,tm) +#define FMPYSUB_D(r1,r2,ta,ra,tm) FMPYSUB_(1,r1,r2,ta,ra,tm) +#define FNEG_(f,r,t) f49(0xe,r,0,6,0,f,0,0,0,0,0,t) +#define FNEG_S(r,t) FNEG_(0,r,t) +#define FNEG_D(r,t) FNEG_(1,r,t) +/* FIXME not disassembled */ +#define FNEG_Q(r,t) f45(0xc,r,0,6,3,0,0,0,t) +#define FNEGABS_(f,r,t) f49(0xe,r,0,7,0,f,0,0,0,0,0,t) +#define FNEGABS_S(r,t) FNEGABS_(0,r,t) +#define FNEGABS_D(r,t) FNEGABS_(1,r,t) +#define FNEGABS_Q(r,t) f45(0xc,r,0,7,3,0,0,0,t) +#define FRND_(f,r,t) f49(0xe,r,0,5,0,f,0,0,0,0,0,t) +#define FRND_S(r,t) FRND_(0,r,t) +#define FRND_D(r,t) FRND_(1,r,t) +#define FRND_Q(r,t) f45(0xc,r,0,5,3,0,0,0,t) +#define FSQRT_(f,r,t) f49(0xe,r,0,4,0,f,0,0,0,0,0,t) +#define FSQRT_S(r,t) FSQRT_(0,r,t) +#define FSQRT_D(r,t) FSQRT_(1,r,t) +#define FSQRT_Q(r,t) f45(0xc,r,0,4,3,0,0,0,t) +#define FSTDL(r,i,b) f3(0x1c,b,r,i,1) +#define FSTD(r,x,b) f40(0xb,b,x,r) +#define FSTDI(r,i,b) f42(0xb,b,i,r) +#define FSTWL(r,i,b) f43(0x1f,b,r,i) +#define FSTW(r,x,b) f40(0x9,b,x,r) +#define FSTWI(r,i,b) f42(0x9,b,i,r) +#define FSUB_(f,r1,r2,t) f52(0xe,r1,r2,1,0,f,3,0,0,0,0,t) +#define FSUB_S(r1,r2,t) FSUB_(0,r1,r2,t) +#define FSUB_D(r1,r2,t) FSUB_(1,r1,r2,t) +#define FSUB_Q(r1,r2,t) f48(0xc,r1,r2,1,3,3,0,0,t) +#define FTEST_(c) f47(0xc,0,0,0,0,2,0,1,c) +#define FTEST() f47(0xc,0,0,1,0,2,0,1,0) +#define FTEST_LT() FTEST_(FCMP_LT) +#define FTEST_LE() FTEST_(FCMP_LE) +#define FTEST_EQ() FTEST_(FCMP_EQ) +#define FTEST_GE() FTEST_(FCMP_GE) +#define FTEST_GT() FTEST_(FCMP_GT) +#define FTEST_NE() FTEST_(FCMP_NE) +#define FTEST_UNLT() FTEST_(FCMP_UNLT) +#define FTEST_UNLE() FTEST_(FCMP_UNLE) +#define FTEST_UNEQ() FTEST_(FCMP_UNEQ) +#define FTEST_UNGE() FTEST_(FCMP_UNGE) +#define FTEST_UNGT() FTEST_(FCMP_UNGT) +#define FTEST_LTGT() FTEST_(FCMP_LTGT) +#define FTEST_ORD() FTEST_(FCMP_ORD) +#define FTEST_UNORD() FTEST_(FCMP_UNORD) +#define XMPYU(r1,r2,t) f52(0xe,r1,r2,2,0,0,3,1,0,0,0,t) +#define XMPYU_L_R(r1,r2,t) f52(0xe,r1,r2,2,1,0,3,1,0,0,0,t) +#define XMPYU_R_L(r1,r2,t) f52(0xe,r1,r2,2,0,0,3,1,1,0,0,t) +#define XMPYU_R_R(r1,r2,t) f52(0xe,r1,r2,2,1,0,3,1,1,0,0,t) +#define negr_f(r0,r1) FNEG_S(r1,r0) +#define negr_d(r0,r1) FNEG_D(r1,r0) +#define sqrtr_f(r0,r1) FSQRT_S(r1,r0) +#define sqrtr_d(r0,r1) FSQRT_D(r1,r0) +#define extr_f(r0,r1) _extr_f(_jit,r0,r1) +static void _extr_f(jit_state_t*,jit_int32_t,jit_int32_t); +#define extr_d(r0,r1) _extr_d(_jit,r0,r1) +static void _extr_d(jit_state_t*,jit_int32_t,jit_int32_t); +#define extr_f_d(r0,r1) FCNVFF_S_D(r1,r0) +#define extr_d_f(r0,r1) FCNVFF_D_S(r1,r0) +#define truncr_f(r0,r1) truncr_f_i(r0,r1) +#define truncr_f_i(r0,r1) _truncr_f_i(_jit,r0,r1) +static void _truncr_f_i(jit_state_t*,jit_int32_t,jit_int32_t); +#define truncr_d(r0,r1) truncr_d_i(r0,r1) +#define truncr_d_i(r0,r1) _truncr_d_i(_jit,r0,r1) +static void _truncr_d_i(jit_state_t*,jit_int32_t,jit_int32_t); +#define movr_f(r0,r1) FCPY_S(r1,r0) +#define movi_f(r0,i0) _movi_f(_jit,r0,i0) +static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*); +#define movr_d(r0,r1) FCPY_D(r1,r0) +#define movi_d(r0,i0) _movi_d(_jit,r0,i0) +static void _movi_d(jit_state_t*,jit_int32_t,jit_float64_t*); +#define absr_f(r0,r1) FABS_S(r1,r0) +#define absr_d(r0,r1) FABS_D(r1,r0) +#define addr_f(r0,r1,r2) FADD_S(r1,r2,r0) +#define addi_f(r0,r1,i0) _addi_f(_jit,r0,r1,i0) +static void _addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define addr_d(r0,r1,r2) FADD_D(r1,r2,r0) +#define addi_d(r0,r1,i0) _addi_d(_jit,r0,r1,i0) +static void _addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define subr_f(r0,r1,r2) FSUB_S(r1,r2,r0) +#define subi_f(r0,r1,i0) _subi_f(_jit,r0,r1,i0) +static void _subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define subr_d(r0,r1,r2) FSUB_D(r1,r2,r0) +#define subi_d(r0,r1,i0) _subi_d(_jit,r0,r1,i0) +static void _subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define rsbr_f(r0,r1,r2) subr_f(r0,r2,r1) +#define rsbi_f(r0,r1,i0) _rsbi_f(_jit,r0,r1,i0) +static void _rsbi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define rsbr_d(r0,r1,r2) subr_d(r0,r2,r1) +#define rsbi_d(r0,r1,i0) _rsbi_d(_jit,r0,r1,i0) +static void _rsbi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define mulr_f(r0,r1,r2) FMPY_S(r1,r2,r0) +#define muli_f(r0,r1,i0) _muli_f(_jit,r0,r1,i0) +static void _muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define mulr_d(r0,r1,r2) FMPY_D(r1,r2,r0) +#define muli_d(r0,r1,i0) _muli_d(_jit,r0,r1,i0) +static void _muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define divr_f(r0,r1,r2) FDIV_S(r1,r2,r0) +#define divi_f(r0,r1,i0) _divi_f(_jit,r0,r1,i0) +static void _divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define divr_d(r0,r1,r2) FDIV_D(r1,r2,r0) +#define divi_d(r0,r1,i0) _divi_d(_jit,r0,r1,i0) +static void _divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define cmpr_f(c,r0,r1,r2) _cmpr_f(_jit,c,r0,r1,r2) +static void _cmpr_f(jit_state_t*,jit_word_t, + jit_int32_t,jit_int32_t,jit_int32_t); +#define cmpi_f(c,r0,r1,i0) _cmpi_f(_jit,c,r0,r1,i0) +static void _cmpi_f(jit_state_t*,jit_word_t, + jit_int32_t,jit_int32_t,jit_float32_t*); +#define cmpr_d(c,r0,r1,r2) _cmpr_d(_jit,c,r0,r1,r2) +static void _cmpr_d(jit_state_t*,jit_word_t, + jit_int32_t,jit_int32_t,jit_int32_t); +#define cmpi_d(c,r0,r1,i0) _cmpi_d(_jit,c,r0,r1,i0) +static void _cmpi_d(jit_state_t*,jit_word_t, + jit_int32_t,jit_int32_t,jit_float64_t*); +#define ltr_f(r0,r1,r2) cmpr_f(FCMP_LT,r0,r1,r2) +#define lti_f(r0,r1,i0) cmpi_f(FCMP_LT,r0,r1,i0) +#define ltr_d(r0,r1,r2) cmpr_d(FCMP_LT,r0,r1,r2) +#define lti_d(r0,r1,i0) cmpi_d(FCMP_LT,r0,r1,i0) +#define ler_f(r0,r1,r2) cmpr_f(FCMP_LE,r0,r1,r2) +#define lei_f(r0,r1,i0) cmpi_f(FCMP_LE,r0,r1,i0) +#define ler_d(r0,r1,r2) cmpr_d(FCMP_LE,r0,r1,r2) +#define lei_d(r0,r1,i0) cmpi_d(FCMP_LE,r0,r1,i0) +#define eqr_f(r0,r1,r2) cmpr_f(FCMP_EQ,r0,r1,r2) +#define eqi_f(r0,r1,i0) cmpi_f(FCMP_EQ,r0,r1,i0) +#define eqr_d(r0,r1,r2) cmpr_d(FCMP_EQ,r0,r1,r2) +#define eqi_d(r0,r1,i0) cmpi_d(FCMP_EQ,r0,r1,i0) +#define ger_f(r0,r1,r2) cmpr_f(FCMP_GE,r0,r1,r2) +#define gei_f(r0,r1,i0) cmpi_f(FCMP_GE,r0,r1,i0) +#define ger_d(r0,r1,r2) cmpr_d(FCMP_GE,r0,r1,r2) +#define gei_d(r0,r1,i0) cmpi_d(FCMP_GE,r0,r1,i0) +#define gtr_f(r0,r1,r2) cmpr_f(FCMP_GT,r0,r1,r2) +#define gti_f(r0,r1,i0) cmpi_f(FCMP_GT,r0,r1,i0) +#define gtr_d(r0,r1,r2) cmpr_d(FCMP_GT,r0,r1,r2) +#define gti_d(r0,r1,i0) cmpi_d(FCMP_GT,r0,r1,i0) +#define ner_f(r0,r1,r2) cmpr_f(FCMP_NE,r0,r1,r2) +#define nei_f(r0,r1,i0) cmpi_f(FCMP_NE,r0,r1,i0) +#define ner_d(r0,r1,r2) cmpr_d(FCMP_NE,r0,r1,r2) +#define nei_d(r0,r1,i0) cmpi_d(FCMP_NE,r0,r1,i0) +#define unltr_f(r0,r1,r2) cmpr_f(FCMP_UNLT,r0,r1,r2) +#define unlti_f(r0,r1,i0) cmpi_f(FCMP_UNLT,r0,r1,i0) +#define unltr_d(r0,r1,r2) cmpr_d(FCMP_UNLT,r0,r1,r2) +#define unlti_d(r0,r1,i0) cmpi_d(FCMP_UNLT,r0,r1,i0) +#define unler_f(r0,r1,r2) cmpr_f(FCMP_UNLE,r0,r1,r2) +#define unlei_f(r0,r1,i0) cmpi_f(FCMP_UNLE,r0,r1,i0) +#define unler_d(r0,r1,r2) cmpr_d(FCMP_UNLE,r0,r1,r2) +#define unlei_d(r0,r1,i0) cmpi_d(FCMP_UNLE,r0,r1,i0) +#define uneqr_f(r0,r1,r2) cmpr_f(FCMP_UNEQ,r0,r1,r2) +#define uneqi_f(r0,r1,i0) cmpi_f(FCMP_UNEQ,r0,r1,i0) +#define uneqr_d(r0,r1,r2) cmpr_d(FCMP_UNEQ,r0,r1,r2) +#define uneqi_d(r0,r1,i0) cmpi_d(FCMP_UNEQ,r0,r1,i0) +#define unger_f(r0,r1,r2) cmpr_f(FCMP_UNGE,r0,r1,r2) +#define ungei_f(r0,r1,i0) cmpi_f(FCMP_UNGE,r0,r1,i0) +#define unger_d(r0,r1,r2) cmpr_d(FCMP_UNGE,r0,r1,r2) +#define ungei_d(r0,r1,i0) cmpi_d(FCMP_UNGE,r0,r1,i0) +#define ungtr_f(r0,r1,r2) cmpr_f(FCMP_UNGT,r0,r1,r2) +#define ungti_f(r0,r1,i0) cmpi_f(FCMP_UNGT,r0,r1,i0) +#define ungtr_d(r0,r1,r2) cmpr_d(FCMP_UNGT,r0,r1,r2) +#define ungti_d(r0,r1,i0) cmpi_d(FCMP_UNGT,r0,r1,i0) +#define ltgtr_f(r0,r1,r2) cmpr_f(FCMP_LTGT,r0,r1,r2) +#define ltgti_f(r0,r1,i0) cmpi_f(FCMP_LTGT,r0,r1,i0) +#define ltgtr_d(r0,r1,r2) cmpr_d(FCMP_LTGT,r0,r1,r2) +#define ltgti_d(r0,r1,i0) cmpi_d(FCMP_LTGT,r0,r1,i0) +#define ordr_f(r0,r1,r2) cmpr_f(FCMP_ORD,r0,r1,r2) +#define ordi_f(r0,r1,i0) cmpi_f(FCMP_ORD,r0,r1,i0) +#define ordr_d(r0,r1,r2) cmpr_d(FCMP_ORD,r0,r1,r2) +#define ordi_d(r0,r1,i0) cmpi_d(FCMP_ORD,r0,r1,i0) +#define unordr_f(r0,r1,r2) cmpr_f(FCMP_UNORD,r0,r1,r2) +#define unordi_f(r0,r1,i0) cmpi_f(FCMP_UNORD,r0,r1,i0) +#define unordr_d(r0,r1,r2) cmpr_d(FCMP_UNORD,r0,r1,r2) +#define unordi_d(r0,r1,i0) cmpi_d(FCMP_UNORD,r0,r1,i0) +#define ldr_f(r0,r1) FLDWI(0,r1,r0) +#define ldi_f(r0,i0) _ldi_f(_jit,r0,i0) +static void _ldi_f(jit_state_t*,jit_int32_t,jit_word_t); +#if FLDXR +# define ldxr_f(r0,r1,r2) FLDW(r2,r1,r0) +# define ldxr_d(r0,r1,r2) FLDD(r2,r1,r0) +#else +#define ldxr_f(r0,r1,r2) _ldxr_f(_jit,r0,r1,r2) +static void _ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ldxr_d(r0,r1,r2) _ldxr_d(_jit,r0,r1,r2) +static void _ldxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#endif +#define ldxi_f(r0,r1,i0) _ldxi_f(_jit,r0,r1,i0) +static void _ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ldr_d(r0,r1) FLDDI(0,r1,r0) +#define ldi_d(r0,i0) _ldi_d(_jit,r0,i0) +static void _ldi_d(jit_state_t*,jit_int32_t,jit_word_t); +#define ldxi_d(r0,r1,i0) _ldxi_d(_jit,r0,r1,i0) +static void _ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define str_f(r0,r1) FSTWI(r1,0,r0) +#define sti_f(i0,r0) _sti_f(_jit,i0,r0) +static void _sti_f(jit_state_t*,jit_word_t,jit_int32_t); +#if FSTXR +# define stxr_f(r0,r1,r2) FSTW(r2,r1,r0) +# define stxr_d(r0,r1,r2) FSTD(r2,r1,r0) +#else +# define stxr_f(r0,r1,r2) _stxr_f(_jit,r0,r1,r2) +static void _stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxr_d(r0,r1,r2) _stxr_d(_jit,r0,r1,r2) +static void _stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#endif +#define stxi_f(i0,r0,r1) _stxi_f(_jit,i0,r0,r1) +static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define str_d(r0,r1) FSTDI(r1,0,r0) +#define sti_d(i0,r0) _sti_d(_jit,i0,r0) +static void _sti_d(jit_state_t*,jit_word_t,jit_int32_t); +#define stxi_d(i0,r0,r1) _stxi_d(_jit,i0,r0,r1) +static void _stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bcmpr_f(c,i0,r0,r1) _bcmpr_f(_jit,c,i0,r0,r1) +static jit_word_t _bcmpr_f(jit_state_t*,jit_word_t, + jit_word_t,jit_int32_t,jit_int32_t); +#define bcmpi_f(c,i0,r0,i1) _bcmpi_f(_jit,c,i0,r0,i1) +static jit_word_t _bcmpi_f(jit_state_t*,jit_word_t, + jit_word_t,jit_int32_t,jit_float32_t*); +#define bcmpr_d(c,i0,r0,r1) _bcmpr_d(_jit,c,i0,r0,r1) +static jit_word_t _bcmpr_d(jit_state_t*,jit_word_t, + jit_word_t,jit_int32_t,jit_int32_t); +#define bcmpi_d(c,i0,r0,i1) _bcmpi_d(_jit,c,i0,r0,i1) +static jit_word_t _bcmpi_d(jit_state_t*,jit_word_t, + jit_word_t,jit_int32_t,jit_float64_t*); +#define bltr_f(i0,r0,r1) bcmpr_f(FCMP_LT,i0,r0,r1) +#define blti_f(i0,r0,i1) bcmpi_f(FCMP_LT,i0,r0,i1) +#define bltr_d(i0,r0,r1) bcmpr_d(FCMP_LT,i0,r0,r1) +#define blti_d(i0,r0,i1) bcmpi_d(FCMP_LT,i0,r0,i1) +#define bler_f(i0,r0,r1) bcmpr_f(FCMP_LE,i0,r0,r1) +#define blei_f(i0,r0,i1) bcmpi_f(FCMP_LE,i0,r0,i1) +#define bler_d(i0,r0,r1) bcmpr_d(FCMP_LE,i0,r0,r1) +#define blei_d(i0,r0,i1) bcmpi_d(FCMP_LE,i0,r0,i1) +#define beqr_f(i0,r0,r1) bcmpr_f(FCMP_EQ,i0,r0,r1) +#define beqi_f(i0,r0,i1) bcmpi_f(FCMP_EQ,i0,r0,i1) +#define beqr_d(i0,r0,r1) bcmpr_d(FCMP_EQ,i0,r0,r1) +#define beqi_d(i0,r0,i1) bcmpi_d(FCMP_EQ,i0,r0,i1) +#define bger_f(i0,r0,r1) bcmpr_f(FCMP_GE,i0,r0,r1) +#define bgei_f(i0,r0,i1) bcmpi_f(FCMP_GE,i0,r0,i1) +#define bger_d(i0,r0,r1) bcmpr_d(FCMP_GE,i0,r0,r1) +#define bgei_d(i0,r0,i1) bcmpi_d(FCMP_GE,i0,r0,i1) +#define bgtr_f(i0,r0,r1) bcmpr_f(FCMP_GT,i0,r0,r1) +#define bgti_f(i0,r0,i1) bcmpi_f(FCMP_GT,i0,r0,i1) +#define bgtr_d(i0,r0,r1) bcmpr_d(FCMP_GT,i0,r0,r1) +#define bgti_d(i0,r0,i1) bcmpi_d(FCMP_GT,i0,r0,i1) +#define bner_f(i0,r0,r1) bcmpr_f(FCMP_NE,i0,r0,r1) +#define bnei_f(i0,r0,i1) bcmpi_f(FCMP_NE,i0,r0,i1) +#define bner_d(i0,r0,r1) bcmpr_d(FCMP_NE,i0,r0,r1) +#define bnei_d(i0,r0,i1) bcmpi_d(FCMP_NE,i0,r0,i1) +#define bunltr_f(i0,r0,r1) bcmpr_f(FCMP_UNLT,i0,r0,r1) +#define bunlti_f(i0,r0,i1) bcmpi_f(FCMP_UNLT,i0,r0,i1) +#define bunltr_d(i0,r0,r1) bcmpr_d(FCMP_UNLT,i0,r0,r1) +#define bunlti_d(i0,r0,i1) bcmpi_d(FCMP_UNLT,i0,r0,i1) +#define bunler_f(i0,r0,r1) bcmpr_f(FCMP_UNLE,i0,r0,r1) +#define bunlei_f(i0,r0,i1) bcmpi_f(FCMP_UNLE,i0,r0,i1) +#define bunler_d(i0,r0,r1) bcmpr_d(FCMP_UNLE,i0,r0,r1) +#define bunlei_d(i0,r0,i1) bcmpi_d(FCMP_UNLE,i0,r0,i1) +#define buneqr_f(i0,r0,r1) bcmpr_f(FCMP_UNEQ,i0,r0,r1) +#define buneqi_f(i0,r0,i1) bcmpi_f(FCMP_UNEQ,i0,r0,i1) +#define buneqr_d(i0,r0,r1) bcmpr_d(FCMP_UNEQ,i0,r0,r1) +#define buneqi_d(i0,r0,i1) bcmpi_d(FCMP_UNEQ,i0,r0,i1) +#define bunger_f(i0,r0,r1) bcmpr_f(FCMP_UNGE,i0,r0,r1) +#define bungei_f(i0,r0,i1) bcmpi_f(FCMP_UNGE,i0,r0,i1) +#define bunger_d(i0,r0,r1) bcmpr_d(FCMP_UNGE,i0,r0,r1) +#define bungei_d(i0,r0,i1) bcmpi_d(FCMP_UNGE,i0,r0,i1) +#define bungtr_f(i0,r0,r1) bcmpr_f(FCMP_UNGT,i0,r0,r1) +#define bungti_f(i0,r0,i1) bcmpi_f(FCMP_UNGT,i0,r0,i1) +#define bungtr_d(i0,r0,r1) bcmpr_d(FCMP_UNGT,i0,r0,r1) +#define bungti_d(i0,r0,i1) bcmpi_d(FCMP_UNGT,i0,r0,i1) +#define bltgtr_f(i0,r0,r1) bcmpr_f(FCMP_LTGT,i0,r0,r1) +#define bltgti_f(i0,r0,i1) bcmpi_f(FCMP_LTGT,i0,r0,i1) +#define bltgtr_d(i0,r0,r1) bcmpr_d(FCMP_LTGT,i0,r0,r1) +#define bltgti_d(i0,r0,i1) bcmpi_d(FCMP_LTGT,i0,r0,i1) +#define bordr_f(i0,r0,r1) bcmpr_f(FCMP_ORD,i0,r0,r1) +#define bordi_f(i0,r0,i1) bcmpi_f(FCMP_ORD,i0,r0,i1) +#define bordr_d(i0,r0,r1) bcmpr_d(FCMP_ORD,i0,r0,r1) +#define bordi_d(i0,r0,i1) bcmpi_d(FCMP_ORD,i0,r0,i1) +#define bunordr_f(i0,r0,r1) bcmpr_f(FCMP_UNORD,i0,r0,r1) +#define bunordi_f(i0,r0,i1) bcmpi_f(FCMP_UNORD,i0,r0,i1) +#define bunordr_d(i0,r0,r1) bcmpr_d(FCMP_UNORD,i0,r0,r1) +#define bunordi_d(i0,r0,i1) bcmpi_d(FCMP_UNORD,i0,r0,i1) +#define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1) +static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t); +#endif + +#if CODE +static void +_f39(jit_state_t *_jit, jit_int32_t o, + jit_int32_t b, jit_int32_t x, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(!(x & ~0x1f)); + assert(!(t & ~0x1f)); + ii((o<<26)|(b<<21)|(x<<16)|t); +} + +static void +_f40(jit_state_t *_jit, jit_int32_t o, + jit_int32_t b, jit_int32_t x, jit_int32_t r) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(!(x & ~0x1f)); + assert(!(r & ~0x1f)); + ii((o<<26)|(b<<21)|(x<<16)|(1<<9)|r); +} + +static void +_f41(jit_state_t *_jit, jit_int32_t o, + jit_int32_t b, jit_int32_t x, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(x >= -16 && x < 15); + assert(!(t & ~0x1f)); + ii((o<<26)|(b<<21)|(low_sign_unext(x,5)<<16)|(1<<12)|t); +} + +static void +_f42(jit_state_t *_jit, jit_int32_t o, + jit_int32_t b, jit_int32_t i, jit_int32_t r) +{ + assert(!(o & ~0x3f)); + assert(!(b & ~0x1f)); + assert(i >= -16 && i < 15); + assert(!(r & ~0x1f)); + ii((o<<26)|(b<<21)|(low_sign_unext(i,5)<<16)|(1<<12)|(1<<9)|r); +} + +static void +_f45(jit_state_t *_jit, jit_int32_t o, + jit_int32_t r, jit_int32_t a, jit_int32_t b, jit_int32_t fmt, + jit_int32_t c, jit_int32_t d, jit_int32_t e, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(r & ~0x1f)); + assert(!(a & ~0x1f)); + assert(!(b & ~0x7)); + assert(!(fmt & ~0x3)); + assert(!(c & ~0x3)); + assert(!(d & ~0x7)); + assert(!(e & ~0x1)); + assert(!(t & ~0x1f)); + ii((o<<26)|(r<<21)|(a<<16)|(fmt<<13)|(b<<11)|(c<<9)|(d<<6)|(e<<5)|t); +} + +static void +_f46(jit_state_t *_jit, jit_int32_t o, jit_int32_t r, + jit_int32_t a, jit_int32_t s, jit_int32_t df, jit_int32_t sf, + jit_int32_t b, jit_int32_t c, jit_int32_t d, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(r & ~0x1f)); + assert(!(a & ~0x7)); + assert(!(s & ~0x7)); + assert(!(df & ~0x3)); + assert(!(sf & ~0x3)); + assert(!(b & ~0x3)); + assert(!(c & ~0x7)); + assert(!(d & ~0x1)); + assert(!(t & ~0x1f)); + ii((o<<26)|(r<<21)|(a<<18)|(s<<15)| + (df<<13)|(sf<<11)|(b<<9)|(c<<6)|(d<<5)|t); +} + +static void +_f47_48(jit_state_t *_jit, jit_int32_t o, + jit_int32_t r2, jit_int32_t r1, jit_int32_t y, jit_int32_t fmt, + jit_int32_t a, jit_int32_t b, jit_int32_t c, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(r2 & ~0x1f)); + assert(!(r1 & ~0x1f)); + assert(!(y & ~0x7)); + assert(!(fmt & ~0x3)); + assert(!(a & ~0x3)); + assert(!(b & ~0x7)); + assert(!(c & ~0x1)); + assert(!(t & ~0x1f)); + ii((o<<26)|(r2<<21)|(r1<<16)|(y<<13)|(fmt<<11)|(a<<9)|(b<<6)|(c<<5)|t); +} + +static void +_f49_52(jit_state_t *_jit, jit_int32_t o, + jit_int32_t r1, jit_int32_t r2, jit_int32_t y, + jit_int32_t v, jit_int32_t f, jit_int32_t a, jit_int32_t b, + jit_int32_t u, jit_int32_t c, jit_int32_t d, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(r1 & ~0x1f)); + assert(!(r2 & ~0x3f)); + assert(!(y & ~0x7)); + assert(!(v & ~0x1)); + assert(!(f & ~0x1)); + assert(!(a & ~0x3)); + assert(!(b & ~0x1)); + assert(!(u & ~0x1)); + assert(!(c & ~0x1)); + assert(!(d & ~0x1)); + assert(!(t & ~0x1f)); + ii((o<<26)|(r1<<21)|(r2<<16)|(y<<13)|(v<<12)| + (f<<11)|(a<<9)|(b<<8)|(u<<7)|(c<<6)|(d<<5)|t); +} + +static void +_f53(jit_state_t *_jit, jit_int32_t o, jit_int32_t r1, jit_int32_t r2, + jit_int32_t ta, jit_int32_t ra, jit_int32_t f, jit_int32_t tm) +{ + assert(!(o & ~0x3f)); + assert(!(r1 & ~0x1f)); + assert(!(r2 & ~0x1f)); + assert(!(ta & ~0x1f)); + assert(!(ra & ~0x1f)); + assert(!(f & ~0x1)); + assert(!(tm & ~0x1f)); + assert(ra != tm || + (ta == r1 || ta == r2 || ta == tm) || + (f && ra == 1) || (!f && !ra)); + ii((o<<26)|(r1<<21)|(r2<<16)|(ta<<11)|(ra<<6)|(f<<5)|tm); +} + +static void +_f54(jit_state_t *_jit, jit_int32_t o, jit_int32_t r1, jit_int32_t r2, + jit_int32_t a, jit_int32_t b, jit_int32_t f, jit_int32_t c, + jit_int32_t d, jit_int32_t e, jit_int32_t g, jit_int32_t t) +{ + assert(!(o & ~0x3f)); + assert(!(r1 & ~0x1f)); + assert(!(r2 & ~0x1f)); + assert(!(a & ~0x7)); + assert(!(b & ~0x1)); + assert(!(f & ~0x1)); + assert(!(c & ~0x7)); + assert(!(e & ~0x1)); + assert(!(e & ~0x1)); + assert(!(g & ~0x1)); + assert(!(t & ~0x1f)); + ii((o<<26)|(r1<<21)|(r2<<16)|(a<<13)| + (b<<12)|(f<11)|(c<<8)|(d<<7)|(e<<6)|(g<<5)|t); +} + +static void +_extr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + stxi(alloca_offset - 8, _FP_REGNO, r1); + ldxi_f(r0, _FP_REGNO, alloca_offset - 8); + FCNVXF_S_S(r0, r0); +} + +static void +_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + stxi(alloca_offset - 8, _FP_REGNO, r1); + ldxi_f(r0, _FP_REGNO, alloca_offset - 8); + FCNVXF_S_D(r0, r0); +} + +static void +_truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + FCNVXT_S_S(r1, rn(reg)); + stxi_f(alloca_offset - 8, _FP_REGNO, rn(reg)); + ldxi(r0, _FP_REGNO, alloca_offset - 8); + jit_unget_reg(reg); +} + +static void +_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + FCNVXT_D_S(r1, rn(reg)); + stxi_d(alloca_offset - 8, _FP_REGNO, rn(reg)); + ldxi(r0, _FP_REGNO, alloca_offset - 8); + jit_unget_reg(reg); +} + +static void +_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_int32_t reg; + + if (_jitc->no_data) { + data.f = *i0; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.i); + stxi_i(alloca_offset - 8, _FP_REGNO, rn(reg)); + jit_unget_reg(reg); + ldxi_f(r0, _FP_REGNO, alloca_offset - 8); + } + else + ldi_f(r0, (jit_word_t)i0); +} + +static void +_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + union { + jit_int32_t ii[2]; + jit_word_t w; + jit_float64_t d; + } data; + jit_int32_t reg; + + data.d = *i0; + if (_jitc->no_data) { + data.d = *i0; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.ii[0]); + stxi_i(alloca_offset - 8, _FP_REGNO, rn(reg)); + movi(rn(reg), data.ii[1]); + stxi_i(alloca_offset - 4, _FP_REGNO, rn(reg)); + jit_unget_reg(reg); + ldxi_d(r0, _FP_REGNO, alloca_offset - 8); + } + else + ldi_d(r0, (jit_word_t)i0); +} + +#define fpr_opi(name, type, size) \ +static void \ +_##name##i_##type(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, \ + jit_float##size##_t *i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr); \ + movi_##type(rn(reg), i0); \ + name##r_##type(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +#define fopi(name) fpr_opi(name, f, 32) +#define dopi(name) fpr_opi(name, d, 64) + +fopi(add) +dopi(add) +fopi(sub) +dopi(sub) +fopi(rsb) +dopi(rsb) +fopi(mul) +dopi(mul) +fopi(div) +dopi(div) + +static void +_cmpr_f(jit_state_t *_jit, jit_word_t c, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + LDI(0, r0); + FCMP_S_(r1, r2, c); + FTEST(); + LDI(1, r0); +} + +static void +_cmpi_f(jit_state_t *_jit, jit_word_t c, + jit_int32_t r0, jit_int32_t r1, jit_float32_t *i0) +{ + jit_int32_t reg = jit_get_reg(jit_class_fpr); + movi_f(rn(reg), i0); + cmpr_f(c, r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_cmpr_d(jit_state_t *_jit, jit_word_t c, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + LDI(0, r0); + FCMP_D_(r1, r2, c); + FTEST(); + LDI(1, r0); +} + +static void +_cmpi_d(jit_state_t *_jit, jit_word_t c, + jit_int32_t r0, jit_int32_t r1, jit_float64_t *i0) +{ + jit_int32_t reg = jit_get_reg(jit_class_fpr); + movi_d(rn(reg), i0); + cmpr_d(c, r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + assert(!(i0 & 3)); + if (i0 >= -8192 && i0 <= 8191 && !(re_assemble_16(i0) & 6)) + FLDWL(i0, _R0_REGNO, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +#if !FLDXR +static void +_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); +} +#endif + +static void +_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -16 && i0 <= 15) + FLDWI(i0, r1, r0); + /* |im11a|0|t|i| */ + else if (FLDXR && i0 >= -8192 && i0 <= 8191 && !(re_assemble_16(i0) & 6)) + FLDWL(i0, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_f(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + assert(!(i0 & 7)); + if (i0 >= -8192 && i0 <= 8191 && !(re_assemble_16(i0) & 14)) + FLDDL(i0, _R0_REGNO, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -16 && i0 <= 15) + FLDDI(i0, r1, r0); + /* |im10a|m|a|1|i| */ + else if (FLDXR && i0 >= -8192 && i0 <= 8191 && !(re_assemble_16(i0) & 14)) + FLDDL(i0, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_d(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + assert(!(i0 & 3)); + if (i0 >= -8192 && i0 <= 8191 && !(re_assemble_16(i0) & 6)) + FSTWL(r0, i0, _R0_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_f(rn(reg), r0); + jit_unget_reg(reg); + } +} + +#if !FSTXR +static void +_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_f(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_d(rn(reg), r2); + jit_unget_reg(reg); +} +#endif + +static void +_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0 >= -16 && i0 <= 15) + FSTWI(r1, i0, r0); + /* |im11a|0|t|i| */ + else if (FSTXR && i0 >= -8192 && i0 <= 8191 && !(re_assemble_16(i0) & 6)) + FSTWL(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); +#if FSTXR + movi(rn(reg), i0); + stxr_f(rn(reg), r0, r1); +#else + addi(rn(reg), r0, i0); + str_f(rn(reg), r1); +#endif + jit_unget_reg(reg); + } +} + +static void +_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + assert(!(i0 & 7)); + if (i0 >= -8192 && i0 <= 8191 && !(re_assemble_16(i0) & 14)) + FSTDL(r0, i0, _R0_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_d(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0 >= -16 && i0 <= 15) + FSTDI(r1, i0, r0); + /* |im10a|m|a|1|i| */ + else if (FSTXR && i0 >= -8192 && i0 <= 8191 && !(re_assemble_16(i0) & 14)) + FSTDL(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); +#if FSTXR + movi(rn(reg), i0); + stxr_d(rn(reg), r0, r1); +#else + addi(rn(reg), r0, i0); + str_d(rn(reg), r1); +#endif + jit_unget_reg(reg); + } +} + +static jit_word_t +_bcmpr_f(jit_state_t *_jit, jit_word_t c, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_S_(r0, r1, c); + FTEST(); + w = _jit->pc.w; + B_N(((i0 - w) >> 2) - 2, _R0_REGNO); + NOP(); + return (w); +} + +static jit_word_t +_bcmpi_f(jit_state_t *_jit, jit_word_t c, + jit_word_t i0, jit_int32_t r0, jit_float32_t *i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi_f(rn(reg), i1); + FCMP_S_(r0, rn(reg), c); + FTEST(); + w = _jit->pc.w; + B_N(((i0 - w) >> 2) - 2, _R0_REGNO); + NOP(); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bcmpr_d(jit_state_t *_jit, jit_word_t c, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_D_(r0, r1, c); + FTEST(); + w = _jit->pc.w; + B_N(((i0 - w) >> 2) - 2, _R0_REGNO); + NOP(); + return (w); +} + +static jit_word_t +_bcmpi_d(jit_state_t *_jit, jit_word_t c, + jit_word_t i0, jit_int32_t r0, jit_float64_t *i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi_d(rn(reg), i1); + FCMP_D_(r0, rn(reg), c); + FTEST(); + w = _jit->pc.w; + B_N(((i0 - w) >> 2) - 2, _R0_REGNO); + NOP(); + jit_unget_reg(reg); + return (w); +} + +static void +_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + + assert(_jitc->function->self.call & jit_call_varargs); + + /* Align pointer if required. */ + reg = jit_get_reg(jit_class_gpr); + andi(rn(reg), r1, 7); + subr(r1, r1, rn(reg)); + jit_unget_reg(reg); + + /* Adjust vararg stack pointer. */ + subi(r1, r1, 8); + + /* Load argument. */ + ldr_d(r0, r1); +} +#endif diff --git a/deps/lightning/lib/jit_hppa-sz.c b/deps/lightning/lib/jit_hppa-sz.c new file mode 100644 index 0000000..3c04f63 --- /dev/null +++ b/deps/lightning/lib/jit_hppa-sz.c @@ -0,0 +1,402 @@ + +#if __WORDSIZE == 32 +#define JIT_INSTR_MAX 64 + 0, /* data */ + 0, /* live */ + 0, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 64, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 0, /* va_start */ + 0, /* va_arg */ + 0, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 12, /* addi */ + 4, /* addcr */ + 12, /* addci */ + 4, /* addxr */ + 8, /* addxi */ + 4, /* subr */ + 12, /* subi */ + 4, /* subcr */ + 12, /* subci */ + 4, /* subxr */ + 8, /* subxi */ + 16, /* rsbi */ + 28, /* mulr */ + 36, /* muli */ + 40, /* qmulr */ + 44, /* qmuli */ + 32, /* qmulr_u */ + 40, /* qmuli_u */ + 36, /* divr */ + 40, /* divi */ + 36, /* divr_u */ + 40, /* divi_u */ + 40, /* qdivr */ + 40, /* qdivi */ + 40, /* qdivr_u */ + 40, /* qdivi_u */ + 36, /* remr */ + 40, /* remi */ + 36, /* remr_u */ + 40, /* remi_u */ + 4, /* andr */ + 12, /* andi */ + 4, /* orr */ + 12, /* ori */ + 4, /* xorr */ + 12, /* xori */ + 12, /* lshr */ + 4, /* lshi */ + 12, /* rshr */ + 4, /* rshi */ + 12, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 8, /* ltr */ + 8, /* lti */ + 8, /* ltr_u */ + 8, /* lti_u */ + 8, /* ler */ + 8, /* lei */ + 8, /* ler_u */ + 8, /* lei_u */ + 8, /* eqr */ + 12, /* eqi */ + 8, /* ger */ + 8, /* gei */ + 8, /* ger_u */ + 8, /* gei_u */ + 8, /* gtr */ + 8, /* gti */ + 8, /* gtr_u */ + 8, /* gti_u */ + 8, /* ner */ + 8, /* nei */ + 4, /* movr */ + 8, /* movi */ + 4, /* extr_c */ + 4, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 0, /* extr_i */ + 0, /* extr_ui */ + 4, /* htonr_us */ + 4, /* htonr_ui */ + 0, /* htonr_l */ + 8, /* ldr_c */ + 12, /* ldi_c */ + 4, /* ldr_uc */ + 8, /* ldi_uc */ + 8, /* ldr_s */ + 12, /* ldi_s */ + 4, /* ldr_us */ + 8, /* ldi_us */ + 4, /* ldr_i */ + 8, /* ldi_i */ + 0, /* ldr_ui */ + 0, /* ldi_ui */ + 0, /* ldr_l */ + 0, /* ldi_l */ + 8, /* ldxr_c */ + 8, /* ldxi_c */ + 4, /* ldxr_uc */ + 4, /* ldxi_uc */ + 8, /* ldxr_s */ + 8, /* ldxi_s */ + 4, /* ldxr_us */ + 4, /* ldxi_us */ + 4, /* ldxr_i */ + 4, /* ldxi_i */ + 0, /* ldxr_ui */ + 0, /* ldxi_ui */ + 0, /* ldxr_l */ + 0, /* ldxi_l */ + 4, /* str_c */ + 8, /* sti_c */ + 4, /* str_s */ + 8, /* sti_s */ + 4, /* str_i */ + 8, /* sti_i */ + 0, /* str_l */ + 0, /* sti_l */ + 8, /* stxr_c */ + 4, /* stxi_c */ + 8, /* stxr_s */ + 4, /* stxi_s */ + 8, /* stxr_i */ + 4, /* stxi_i */ + 0, /* stxr_l */ + 0, /* stxi_l */ + 8, /* bltr */ + 8, /* blti */ + 8, /* bltr_u */ + 8, /* blti_u */ + 8, /* bler */ + 12, /* blei */ + 8, /* bler_u */ + 8, /* blei_u */ + 8, /* beqr */ + 16, /* beqi */ + 8, /* bger */ + 8, /* bgei */ + 8, /* bger_u */ + 8, /* bgei_u */ + 8, /* bgtr */ + 8, /* bgti */ + 8, /* bgtr_u */ + 8, /* bgti_u */ + 8, /* bner */ + 16, /* bnei */ + 12, /* bmsr */ + 16, /* bmsi */ + 12, /* bmcr */ + 16, /* bmci */ + 8, /* boaddr */ + 8, /* boaddi */ + 8, /* boaddr_u */ + 8, /* boaddi_u */ + 8, /* bxaddr */ + 8, /* bxaddi */ + 8, /* bxaddr_u */ + 8, /* bxaddi_u */ + 12, /* bosubr */ + 16, /* bosubi */ + 16, /* bosubr_u */ + 20, /* bosubi_u */ + 12, /* bxsubr */ + 16, /* bxsubi */ + 16, /* bxsubr_u */ + 20, /* bxsubi_u */ + 0, /* jmpr */ + 12, /* jmpi */ + 40, /* callr */ + 44, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 64, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 16, /* addi_f */ + 4, /* subr_f */ + 16, /* subi_f */ + 16, /* rsbi_f */ + 4, /* mulr_f */ + 16, /* muli_f */ + 4, /* divr_f */ + 16, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 16, /* ltr_f */ + 28, /* lti_f */ + 16, /* ler_f */ + 28, /* lei_f */ + 16, /* eqr_f */ + 28, /* eqi_f */ + 16, /* ger_f */ + 28, /* gei_f */ + 16, /* gtr_f */ + 28, /* gti_f */ + 16, /* ner_f */ + 28, /* nei_f */ + 16, /* unltr_f */ + 28, /* unlti_f */ + 16, /* unler_f */ + 28, /* unlei_f */ + 16, /* uneqr_f */ + 28, /* uneqi_f */ + 16, /* unger_f */ + 28, /* ungei_f */ + 16, /* ungtr_f */ + 28, /* ungti_f */ + 16, /* ltgtr_f */ + 28, /* ltgti_f */ + 16, /* ordr_f */ + 28, /* ordi_f */ + 16, /* unordr_f */ + 28, /* unordi_f */ + 12, /* truncr_f_i */ + 0, /* truncr_f_l */ + 12, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 12, /* movi_f */ + 4, /* ldr_f */ + 12, /* ldi_f */ + 4, /* ldxr_f */ + 4, /* ldxi_f */ + 4, /* str_f */ + 12, /* sti_f */ + 8, /* stxr_f */ + 4, /* stxi_f */ + 16, /* bltr_f */ + 28, /* blti_f */ + 16, /* bler_f */ + 28, /* blei_f */ + 16, /* beqr_f */ + 28, /* beqi_f */ + 16, /* bger_f */ + 28, /* bgei_f */ + 16, /* bgtr_f */ + 28, /* bgti_f */ + 16, /* bner_f */ + 28, /* bnei_f */ + 16, /* bunltr_f */ + 28, /* bunlti_f */ + 16, /* bunler_f */ + 28, /* bunlei_f */ + 16, /* buneqr_f */ + 28, /* buneqi_f */ + 16, /* bunger_f */ + 28, /* bungei_f */ + 16, /* bungtr_f */ + 28, /* bungti_f */ + 16, /* bltgtr_f */ + 28, /* bltgti_f */ + 16, /* bordr_f */ + 28, /* bordi_f */ + 16, /* bunordr_f */ + 28, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 24, /* addi_d */ + 4, /* subr_d */ + 24, /* subi_d */ + 24, /* rsbi_d */ + 4, /* mulr_d */ + 24, /* muli_d */ + 4, /* divr_d */ + 24, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 16, /* ltr_d */ + 36, /* lti_d */ + 16, /* ler_d */ + 36, /* lei_d */ + 16, /* eqr_d */ + 36, /* eqi_d */ + 16, /* ger_d */ + 36, /* gei_d */ + 16, /* gtr_d */ + 36, /* gti_d */ + 16, /* ner_d */ + 36, /* nei_d */ + 16, /* unltr_d */ + 36, /* unlti_d */ + 16, /* unler_d */ + 36, /* unlei_d */ + 16, /* uneqr_d */ + 36, /* uneqi_d */ + 16, /* unger_d */ + 36, /* ungei_d */ + 16, /* ungtr_d */ + 36, /* ungti_d */ + 16, /* ltgtr_d */ + 36, /* ltgti_d */ + 16, /* ordr_d */ + 36, /* ordi_d */ + 16, /* unordr_d */ + 36, /* unordi_d */ + 12, /* truncr_d_i */ + 0, /* truncr_d_l */ + 12, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 20, /* movi_d */ + 4, /* ldr_d */ + 12, /* ldi_d */ + 4, /* ldxr_d */ + 4, /* ldxi_d */ + 4, /* str_d */ + 12, /* sti_d */ + 8, /* stxr_d */ + 4, /* stxi_d */ + 16, /* bltr_d */ + 36, /* blti_d */ + 16, /* bler_d */ + 36, /* blei_d */ + 16, /* beqr_d */ + 36, /* beqi_d */ + 16, /* bger_d */ + 36, /* bgei_d */ + 16, /* bgtr_d */ + 36, /* bgti_d */ + 16, /* bner_d */ + 36, /* bnei_d */ + 16, /* bunltr_d */ + 36, /* bunlti_d */ + 16, /* bunler_d */ + 36, /* bunlei_d */ + 16, /* buneqr_d */ + 36, /* buneqi_d */ + 16, /* bunger_d */ + 36, /* bungei_d */ + 16, /* bungtr_d */ + 36, /* bungti_d */ + 16, /* bltgtr_d */ + 36, /* bltgti_d */ + 16, /* bordr_d */ + 36, /* bordi_d */ + 16, /* bunordr_d */ + 36, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __WORDSIZE */ diff --git a/deps/lightning/lib/jit_hppa.c b/deps/lightning/lib/jit_hppa.c new file mode 100644 index 0000000..21fe20c --- /dev/null +++ b/deps/lightning/lib/jit_hppa.c @@ -0,0 +1,1585 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include <lightning.h> +#include <lightning/jit_private.h> + +#define jit_arg_reg_p(i) (i >= 0 && i < 4) + +#define PROTO 1 +# include "jit_hppa-cpu.c" +# include "jit_hppa-fpu.c" +#undef PROTO + +/* + * Types + */ +typedef jit_pointer_t jit_va_list; + +/* + * Prototypes + */ +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); + +/* libgcc */ +extern void __clear_cache(void *, void *); + +/* + * Initialization + */ +jit_register_t _rvs[] = { + { 0, "r0" }, /* Zero */ + /* Not register starved, so, avoid allocating r1 and rp + * due to being implicit target of ADDIL and B,L */ + { 1, "r1" }, /* Scratch */ + { 2, "rp" }, /* Return Pointer and scratch */ + { rc(sav) | 3, "r3" }, + { 19, "r19" }, /* Linkage Table */ + { rc(gpr) | 20, "r20" }, + { rc(gpr) | 21, "r21" }, + { rc(gpr) | 22, "r22" }, + { rc(gpr) | 29, "ret1" }, + { rc(gpr) | 28, "ret0" }, + /* JIT_Rx in callee save registers due to need to call + * functions to implement some instructions */ + /* JIT_R0- JIT_R2 */ + { rc(gpr) | rc(sav) | 4, "r4" }, + { rc(gpr) | rc(sav) | 5, "r5" }, + { rc(gpr) | rc(sav) | 6, "r6" }, + /* JIT_V0- JIT_V2 */ + { rc(gpr) | rc(sav) | 7, "r7" }, + { rc(sav) | rc(sav) | 8, "r8" }, + { rc(gpr) | rc(sav) | 9, "r9" }, + /* JIT_R3 */ + { rc(gpr) | rc(sav) | 10, "r10" }, + /* JIT_V3+ */ + { rc(gpr) | rc(sav) | 11, "r11" }, + { rc(gpr) | rc(sav) | 12, "r12" }, + { rc(gpr) | rc(sav) | 13, "r13" }, + { rc(gpr) | rc(sav) | 14, "r14" }, + { rc(gpr) | rc(sav) | 15, "r15" }, + { rc(gpr) | rc(sav) | 16, "r16" }, + { rc(gpr) | rc(sav) | 17, "r17" }, + { rc(gpr) | rc(sav) | 18, "r18" }, + /* Arguments */ + { rc(gpr) | rc(arg) | 23, "r23" }, + { rc(gpr) | rc(arg) | 24, "r24" }, + { rc(gpr) | rc(arg) | 25, "r25" }, + { rc(gpr) | rc(arg) | 26, "r26" }, + { 27, "dp" }, /* Data Pointer */ + { 30, "sp" }, + { 31, "r31" }, /* Link Register */ + { rc(fpr) | 31, "fr31" }, + { rc(fpr) | 30, "fr30" }, + { rc(fpr) | 29, "fr29" }, + { rc(fpr) | 28, "fr28" }, + { rc(fpr) | 27, "fr27" }, + { rc(fpr) | 26, "fr26" }, + { rc(fpr) | 25, "fr25" }, + { rc(fpr) | 24, "fr24" }, + { rc(fpr) | 23, "fr23" }, + { rc(fpr) | 22, "fr22" }, + { rc(fpr) | 11, "fr11" }, + { rc(fpr) | 10, "fr10" }, + { rc(fpr) | 9, "fr9" }, + { rc(fpr) | 8, "fr8" }, + /* Arguments */ + { rc(fpr) | rc(arg) | 7, "fr7" }, + { rc(fpr) | rc(arg) | 6, "fr6" }, + { rc(fpr) | rc(arg) | 5, "fr5" }, + { rc(fpr) | rc(arg) | 4, "fr4" }, + /* Callee Saves */ + { rc(fpr) | rc(sav) | 21, "fr21" }, + { rc(fpr) | rc(sav) | 20, "fr20" }, + { rc(fpr) | rc(sav) | 19, "fr19" }, + { rc(fpr) | rc(sav) | 18, "fr18" }, + { rc(fpr) | rc(sav) | 17, "fr17" }, + { rc(fpr) | rc(sav) | 16, "fr16" }, + { rc(fpr) | rc(sav) | 15, "fr15" }, + { rc(fpr) | rc(sav) | 14, "fr14" }, + { rc(fpr) | rc(sav) | 13, "fr13" }, + { rc(fpr) | rc(sav) | 12, "fr12" }, + { 0, "fpsr" }, + { 1, "fpe2" }, + { 2, "fpe4" }, + { 3, "fpe6" }, + { _NOREG, "<none>" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ + /* FIXME Expecting PARISC 2.0, for PARISC 1.0 should not use fr16-fr31 */ +} + +void +_jit_init(jit_state_t *_jit) +{ + _jitc->reglen = jit_size(_rvs) - 1; +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + _jitc->function->self.size = params_offset; + _jitc->function->self.argi = _jitc->function->self.alen = 0; + /* float conversion */ + _jitc->function->self.aoff = alloca_offset; + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + jit_int32_t offset; + assert(_jitc->function); + switch (length) { + case 0: case 1: + break; + case 2: + _jitc->function->self.aoff = (_jitc->function->self.aoff + 1) & -2; + break; + case 3: case 4: + _jitc->function->self.aoff = (_jitc->function->self.aoff + 3) & -4; + break; + default: + _jitc->function->self.aoff = (_jitc->function->self.aoff + 7) & -8; + break; + } + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } + offset = _jitc->function->self.aoff; + _jitc->function->self.aoff += length; + return (offset); +} + +void +_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) +{ + jit_int32_t reg; + assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); + if (!_jitc->function->allocar) { + _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); + _jitc->function->allocar = 1; + } + reg = jit_get_reg(jit_class_gpr); + jit_addi(reg, v, 63); + jit_andi(reg, reg, -64); + jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); + jit_addr(JIT_SP, JIT_SP, reg); + jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); + jit_unget_reg(reg); + jit_dec_synth(); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + assert(_jitc->function); + jit_inc_synth(ret); + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr, u); + jit_movr(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti(jit_state_t *_jit, jit_word_t u) +{ + jit_inc_synth_w(reti, u); + jit_movi(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_f, u); + jit_movr_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_inc_synth_f(reti_f, u); + jit_movi_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_d, u); + jit_movr_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_inc_synth_d(reti_d, u); + jit_movi_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_epilog(jit_state_t *_jit) +{ + assert(_jitc->function); + assert(_jitc->function->epilog->next == NULL); + jit_link(_jitc->function->epilog); + _jitc->function = NULL; +} + +jit_bool_t +_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) +{ + assert(u->code == jit_code_arg || + u->code == jit_code_arg_f || u->code == jit_code_arg_d); + return (jit_arg_reg_p(u->u.w)); +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + jit_inc_synth(ellipsis); + if (_jitc->prepare) { + jit_link_prepare(); + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; + } + else { + jit_link_prolog(); + assert(!(_jitc->function->self.call & jit_call_varargs)); + _jitc->function->self.call |= jit_call_varargs; + + _jitc->function->vagp = _jitc->function->self.argi; + } + jit_dec_synth(); +} + +void +_jit_va_push(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(va_push, u); + jit_pushargr(u); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + _jitc->function->self.size -= sizeof(jit_word_t); + if (jit_arg_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else + offset = _jitc->function->self.size; + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + _jitc->function->self.size -= sizeof(jit_word_t); + if (jit_arg_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else + offset = _jitc->function->self.size; + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + if (_jitc->function->self.argi & 1) { + ++_jitc->function->self.argi; + _jitc->function->self.size -= sizeof(jit_word_t); + } + _jitc->function->self.size -= sizeof(jit_float64_t); + if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi + 1; + _jitc->function->self.argi += 2; + } + else { + /* "Standard" initial value (-52) is unaligned */ + if (_jitc->function->self.size & 7) + _jitc->function->self.size -= sizeof(jit_word_t); + offset = _jitc->function->self.size; + } + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +void +_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); + if (v->u.w >= 0) + jit_extr_c(u, _R26 - v->u.w); + else + jit_ldxi_c(u, JIT_FP, v->u.w + 3); + jit_dec_synth(); +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); + if (v->u.w >= 0) + jit_extr_uc(u, _R26 - v->u.w); + else + jit_ldxi_uc(u, JIT_FP, v->u.w + 3); + jit_dec_synth(); +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); + if (v->u.w >= 0) + jit_extr_s(u, _R26 - v->u.w); + else + jit_ldxi_s(u, JIT_FP, v->u.w + 2); + jit_dec_synth(); +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); + if (v->u.w >= 0) + jit_extr_us(u, _R26 - v->u.w); + else + jit_ldxi_us(u, JIT_FP, v->u.w + 2); + jit_dec_synth(); +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); + if (v->u.w >= 0) + jit_movr(u, _R26 - v->u.w); + else + jit_ldxi_i(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); + if (v->u.w >= 0) + jit_movr(_R26 - v->u.w, u); + else + jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); + if (v->u.w >= 0) + jit_movi(_R26 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); + if (v->u.w >= 0) + jit_movr_f(u, _F4 - v->u.w); + else + jit_ldxi_f(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); + if (v->u.w >= 0) + jit_movr_f(_F4 - v->u.w, u); + else + jit_stxi_f(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); + if (v->u.w >= 0) + jit_movi_f(_R26 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); + if (v->u.w >= 0) + jit_movr_d(u, _F4 - v->u.w); + else + jit_ldxi_d(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); + if (v->u.w >= 0) + jit_movr_d(_F4 - v->u.w, u); + else + jit_stxi_d(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); + if (v->u.w >= 0) + jit_movi_d(_R26 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); + _jitc->function->call.size -= sizeof(jit_word_t); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr(_R26 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else + jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u); + jit_dec_synth(); +} + +void +_jit_pushargi(jit_state_t *_jit, jit_word_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); + _jitc->function->call.size -= sizeof(jit_word_t); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi(_R26 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); + _jitc->function->call.size -= sizeof(jit_word_t); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr_f(_F4 - _jitc->function->call.argi, u); +#if !defined(__hpux) + /* HP-UX appears to always pass float arguments in gpr registers */ + if (_jitc->function->call.call & jit_call_varargs) +#endif + { + jit_stxi_f(alloca_offset - 8, JIT_FP, u); + jit_ldxi(_R26 - _jitc->function->call.argi, JIT_FP, + alloca_offset - 8); + } + ++_jitc->function->call.argi; + } + else + jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, u); + jit_dec_synth(); +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); + _jitc->function->call.size -= sizeof(jit_word_t); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi_f(_F4 - _jitc->function->call.argi, u); +#if !defined(__hpux) + /* HP-UX appears to always pass float arguments in gpr registers */ + if (_jitc->function->call.call & jit_call_varargs) +#endif + { + jit_stxi_f(alloca_offset - 8, JIT_FP, + _F4 - _jitc->function->call.argi); + jit_ldxi(_R26 - _jitc->function->call.argi, + JIT_FP, alloca_offset - 8); + } + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(_jitc->function->call.size + params_offset, JIT_SP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); + _jitc->function->call.size -= sizeof(jit_float64_t); + if (_jitc->function->call.argi & 1) { + ++_jitc->function->call.argi; + _jitc->function->call.size -= sizeof(jit_word_t); + } + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr_d(_F4 - (_jitc->function->call.argi + 1), u); +#if !defined(__hpux) + /* HP-UX appears to always pass float arguments in gpr registers */ + if (_jitc->function->call.call & jit_call_varargs) +#endif + { + jit_stxi_d(alloca_offset - 8, JIT_FP, u); + jit_ldxi(_R26 - _jitc->function->call.argi, + JIT_FP, alloca_offset - 4); + jit_ldxi(_R25 - _jitc->function->call.argi, + JIT_FP, alloca_offset - 8); + } + _jitc->function->call.argi += 2; + } + else { + /* "Standard" initial value (-52) is unaligned */ + if ((_jitc->function->call.size + params_offset) & 7) + _jitc->function->call.size -= sizeof(jit_word_t); + jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u); + } + jit_dec_synth(); +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); + _jitc->function->call.size -= sizeof(jit_float64_t); + if (_jitc->function->call.argi & 1) { + ++_jitc->function->call.argi; + _jitc->function->call.size -= sizeof(jit_word_t); + } + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi_d(_F4 - (_jitc->function->call.argi + 1), u); +#if !defined(__hpux) + /* HP-UX appears to always pass float arguments in gpr registers */ + if (_jitc->function->call.call & jit_call_varargs) +#endif + { + jit_stxi_d(alloca_offset - 8, JIT_FP, + _F4 - (_jitc->function->call.argi + 1)); + jit_ldxi(_R26 - _jitc->function->call.argi, + JIT_FP, alloca_offset - 4); + jit_ldxi(_R25 - _jitc->function->call.argi, + JIT_FP, alloca_offset - 8); + } + _jitc->function->call.argi += 2; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + if ((_jitc->function->call.size + params_offset) & 7) + _jitc->function->call.size -= sizeof(jit_word_t); + jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + jit_int32_t spec; + spec = jit_class(_rvs[regno].spec); + if (spec & jit_class_arg) { + if (spec & jit_class_gpr) { + regno -= _R23; + if (regno >= 0 && regno < node->v.w) + return (1); + } + else if (spec & jit_class_fpr) { + regno = _F4 - regno; + if (regno >= 0 && regno < node->w.w) + return (1); + } + } + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_node_t *call; + assert(_jitc->function); + jit_inc_synth_w(finishr, r0); + if (_jitc->function->self.alen > _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + call = jit_callr(r0); + call->v.w = call->w.w = _jitc->function->call.argi; + _jitc->function->call.argi = _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); + if (_jitc->function->self.alen > _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_calli(i0); + node->v.w = node->w.w = _jitc->function->call.argi; + _jitc->function->call.argi = _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); + return (node); +} + +void +_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_c, r0); + jit_extr_c(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_uc, r0); + jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_s, r0); + jit_extr_s(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_us, r0); + jit_extr_us(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_i, r0); + jit_movr(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_f, r0); + jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_d, r0); + jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_int32_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + jit_int32_t patch_offset; + } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + + _jitc->function = NULL; + + jit_reglive_setup(); + + undo.word = 0; + undo.node = NULL; + undo.patch_offset = 0; + +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w),rn(node->v.w), node->w.w); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_rrf(name, type, size) \ + case jit_code_##name##i##type: \ + assert(node->flag & jit_flag_data); \ + name##i##type(rn(node->u.w), rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w,rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type(_jit->pc.w, \ + rn(node->v.w), rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break +#define case_brf(name, type, size) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + else { \ + word = name##i##type(_jit->pc.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + patch(word, node); \ + } \ + break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end) + return (NULL); + +#if DEVEL_DISASSEMBLER + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; +#endif + value = jit_classify(node->code); + jit_regarg_set(node, value); + switch (node->code) { + case jit_code_align: + assert(!(node->u.w & (node->u.w - 1)) && + node->u.w <= sizeof(jit_word_t)); + if (node->u.w == sizeof(jit_word_t) && + (word = _jit->pc.w & (sizeof(jit_word_t) - 1))) + nop(sizeof(jit_word_t) - word); + break; + case jit_code_note: case jit_code_name: + node->u.w = _jit->pc.w; + break; + case jit_code_label: + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + break; + case_rrr(add,); + case_rrw(add,); + case_rrr(addc,); + case_rrw(addc,); + case_rrr(addx,); + case_rrw(addx,); + case_rrr(sub,); + case_rrw(sub,); + case_rrr(subc,); + case_rrw(subc,); + case_rrr(subx,); + case_rrw(subx,); + case_rrw(rsb,); + case_rrr(mul,); + case_rrw(mul,); + case_rrrr(qmul,); + case_rrrw(qmul,); + case_rrrr(qmul, _u); + case_rrrw(qmul, _u); + case_rrr(div,); + case_rrw(div,); + case_rrr(div, _u); + case_rrw(div, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), node->v.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rr(neg,); + case_rr(com,); + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); + case_rr(hton, _us); + case_rr(hton, _ui); + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_rr(ld, _c); + case_rw(ld, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rr(ld, _i); + case_rw(ld, _i); + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rrr(ldx, _i); + case_rrw(ldx, _i); + case_rr(st, _c); + case_wr(st, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rr(st, _i); + case_wr(st, _i); + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rrr(stx, _i); + case_wrr(stx, _i); + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_rr(mov, _f); + case jit_code_movi_f: + assert(node->flag & jit_flag_data); + movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); + break; + case_rr(mov, _d); + case jit_code_movi_d: + assert(node->flag & jit_flag_data); + movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w); + break; + case_rr(trunc, _f_i); + case_rr(trunc, _d_i); + case_rr(ext, _f); + case_rr(ext, _d); + case_rr(ext, _d_f); + case_rr(ext, _f_d); + case_rr(abs, _f); + case_rr(abs, _d); + case_rr(neg, _f); + case_rr(neg, _d); + case_rr(sqrt, _f); + case_rr(sqrt, _d); + case_rrr(add, _f); + case_rrf(add, _f, 32); + case_rrr(add, _d); + case_rrf(add, _d, 64); + case_rrr(sub, _f); + case_rrf(sub, _f, 32); + case_rrf(rsb, _f, 32); + case_rrr(sub, _d); + case_rrf(sub, _d, 64); + case_rrf(rsb, _d, 64); + case_rrr(mul, _f); + case_rrf(mul, _f, 32); + case_rrr(mul, _d); + case_rrf(mul, _d, 64); + case_rrr(div, _f); + case_rrf(div, _f, 32); + case_rrr(div, _d); + case_rrf(div, _d, 64); + case_rrr(lt, _f); + case_rrf(lt, _f, 32); + case_rrr(lt, _d); + case_rrf(lt, _d, 64); + case_rrr(le, _f); + case_rrf(le, _f, 32); + case_rrr(le, _d); + case_rrf(le, _d, 64); + case_rrr(eq, _f); + case_rrf(eq, _f, 32); + case_rrr(eq, _d); + case_rrf(eq, _d, 64); + case_rrr(ge, _f); + case_rrf(ge, _f, 32); + case_rrr(ge, _d); + case_rrf(ge, _d, 64); + case_rrr(gt, _f); + case_rrf(gt, _f, 32); + case_rrr(gt, _d); + case_rrf(gt, _d, 64); + case_rrr(ne, _f); + case_rrf(ne, _f, 32); + case_rrr(ne, _d); + case_rrf(ne, _d, 64); + case_rrr(unlt, _f); + case_rrf(unlt, _f, 32); + case_rrr(unlt, _d); + case_rrf(unlt, _d, 64); + case_rrr(unle, _f); + case_rrf(unle, _f, 32); + case_rrr(unle, _d); + case_rrf(unle, _d, 64); + case_rrr(uneq, _f); + case_rrf(uneq, _f, 32); + case_rrr(uneq, _d); + case_rrf(uneq, _d, 64); + case_rrr(unge, _f); + case_rrf(unge, _f, 32); + case_rrr(unge, _d); + case_rrf(unge, _d, 64); + case_rrr(ungt, _f); + case_rrf(ungt, _f, 32); + case_rrr(ungt, _d); + case_rrf(ungt, _d, 64); + case_rrr(ltgt, _f); + case_rrf(ltgt, _f, 32); + case_rrr(ltgt, _d); + case_rrf(ltgt, _d, 64); + case_rrr(ord, _f); + case_rrf(ord, _f, 32); + case_rrr(ord, _d); + case_rrf(ord, _d, 64); + case_rrr(unord, _f); + case_rrf(unord, _f, 32); + case_rrr(unord, _d); + case_rrf(unord, _d, 64); + case_rr(ld, _f); + case_rw(ld, _f); + case_rr(ld, _d); + case_rw(ld, _d); + case_rrr(ldx, _f); + case_rrw(ldx, _f); + case_rrr(ldx, _d); + case_rrw(ldx, _d); + case_rr(st, _f); + case_wr(st, _f); + case_rr(st, _d); + case_wr(st, _d); + case_rrr(stx, _f); + case_wrr(stx, _f); + case_rrr(stx, _d); + case_wrr(stx, _d); + case_brr(blt, _f); + case_brf(blt, _f, 32); + case_brr(blt, _d); + case_brf(blt, _d, 64); + case_brr(ble, _f); + case_brf(ble, _f, 32); + case_brr(ble, _d); + case_brf(ble, _d, 64); + case_brr(beq, _f); + case_brf(beq, _f, 32); + case_brr(beq, _d); + case_brf(beq, _d, 64); + case_brr(bge, _f); + case_brf(bge, _f, 32); + case_brr(bge, _d); + case_brf(bge, _d, 64); + case_brr(bgt, _f); + case_brf(bgt, _f, 32); + case_brr(bgt, _d); + case_brf(bgt, _d, 64); + case_brr(bne, _f); + case_brf(bne, _f, 32); + case_brr(bne, _d); + case_brf(bne, _d, 64); + case_brr(bunlt, _f); + case_brf(bunlt, _f, 32); + case_brr(bunlt, _d); + case_brf(bunlt, _d, 64); + case_brr(bunle, _f); + case_brf(bunle, _f, 32); + case_brr(bunle, _d); + case_brf(bunle, _d, 64); + case_brr(buneq, _f); + case_brf(buneq, _f, 32); + case_brr(buneq, _d); + case_brf(buneq, _d, 64); + case_brr(bunge, _f); + case_brf(bunge, _f, 32); + case_brr(bunge, _d); + case_brf(bunge, _d, 64); + case_brr(bungt, _f); + case_brf(bungt, _f, 32); + case_brr(bungt, _d); + case_brf(bungt, _d, 64); + case_brr(bltgt, _f); + case_brf(bltgt, _f, 32); + case_brr(bltgt, _d); + case_brf(bltgt, _d, 64); + case_brr(bord, _f); + case_brf(bord, _f, 32); + case_brr(bord, _d); + case_brf(bord, _d, 64); + case_brr(bunord, _f); + case_brf(bunord, _f, 32); + case_brr(bunord, _d); + case_brf(bunord, _d, 64); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + break; + case jit_code_jmpi: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } + } + else + jmpi(node->u.w); + break; + case jit_code_callr: + callr(rn(node->u.w)); + break; + case jit_code_calli: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (!(temp->flag & jit_flag_patch)) { + word = calli_p(temp->u.w); + patch(word, node); + } + else + calli(temp->u.w); + } + else + calli(node->u.w); + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif + undo.patch_offset = _jitc->patches.offset; + restart_function: + _jitc->again = 0; + prolog(node); + break; + case jit_code_epilog: + assert(_jitc->function == _jitc->functions.ptr + node->w.w); + if (_jitc->again) { + for (temp = undo.node->next; + temp != node; temp = temp->next) { + if (temp->code == jit_code_label || + temp->code == jit_code_epilog) + temp->flag &= ~jit_flag_patch; + } + temp->flag &= ~jit_flag_patch; + node = undo.node; + _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif + _jitc->patches.offset = undo.patch_offset; + goto restart_function; + } + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + epilog(node); + _jitc->function = NULL; + break; + case jit_code_va_start: + vastart(rn(node->u.w)); + break; + case jit_code_va_arg: + vaarg(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_va_arg_d: + vaarg_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_live: + case jit_code_arg: case jit_code_ellipsis: + case jit_code_va_push: + case jit_code_allocai: case jit_code_allocar: + case jit_code_arg_f: case jit_code_arg_d: + case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: + break; + default: + abort(); + } + jit_regarg_clr(node, value); + assert(_jitc->regarg == 0 && _jitc->synth == 0); + /* update register live state */ + jit_reglive(node); + } +#undef case_brf +#undef case_brw +#undef case_brr +#undef case_wrr +#undef case_rrf +#undef case_rrrw +#undef case_rrw +#undef case_rrrr +#undef case_rrr +#undef case_wr +#undef case_rw +#undef case_rr + + for (offset = 0; offset < _jitc->patches.offset; offset++) { + node = _jitc->patches.ptr[offset].node; + word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(_jitc->patches.ptr[offset].inst, word); + } + + jit_flush(_jit->code.ptr, _jit->pc.uc); + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_hppa-cpu.c" +# include "jit_hppa-fpu.c" +#undef CODE + +void +jit_flush(void *fptr, void *tptr) +{ + jit_word_t f, t, s; + s = sysconf(_SC_PAGE_SIZE); + f = (jit_word_t)fptr & -s; + t = (((jit_word_t)tptr) + s - 1) & -s; +#if defined(__hppa) +/* --- parisc2.0.pdf --- + Programming Note + +The minimum spacing that is guaranteed to work for "self-modifying code" is +shown in the code segment below. Since instruction prefetching is permitted, +any data cache flushes must be separated from any instruction cache flushes +by a SYNC. This will ensure that the "new" instruction will be written to +memory prior to any attempts at prefetching it as an instruction. + + LDIL l%newinstr,rnew + LDW r%newinstr(0,rnew),temp + LDIL l%instr,rinstr + STW temp,r%instr(0,rinstr) + FDC r%instr(0,rinstr) + SYNC + FIC r%instr(rinstr) + SYNC + instr ... + (at least seven instructions) + +This sequence assumes a uniprocessor system. In a multiprocessor system, +software must ensure no processor is executing code which is in the process +of being modified. +*/ + +/* + Adapted from ffcall/trampoline/cache-hppa.c:__TR_clear_cache to +loop over addresses as it is unlikely from and to addresses would fit in +at most two cachelines. + FIXME A cache line can be 16, 32, or 64 bytes. + */ + /* + * Copyright 1995-1997 Bruno Haible, <bruno@clisp.org> + * + * This is free software distributed under the GNU General Public Licence + * described in the file COPYING. Contact the author if you don't have this + * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied, + * on this software. + */ + { + jit_word_t n = f + 32; + register int u, v; + for (; f <= t; n = f + 32, f += 64) { + asm volatile ("fdc 0(0,%0)" + "\n\t" "fdc 0(0,%1)" + "\n\t" "sync" + : + : "r" (f), "r" (n) + ); + asm volatile ("mfsp %%sr0,%1" + "\n\t" "ldsid (0,%4),%0" + "\n\t" "mtsp %0,%%sr0" + "\n\t" "fic 0(%%sr0,%2)" + "\n\t" "fic 0(%%sr0,%3)" + "\n\t" "sync" + "\n\t" "mtsp %1,%%sr0" + "\n\t" "nop" + "\n\t" "nop" + "\n\t" "nop" + "\n\t" "nop" + "\n\t" "nop" + "\n\t" "nop" + : "=r" (u), "=r" (v) + : "r" (f), "r" (n), "r" (f) + ); + } + } +#else + /* This is supposed to work but appears to fail on multiprocessor systems */ + __clear_cache((void *)f, (void *)t); +#endif +} + +void +_emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0) +{ + ldxi(rn(r0), rn(r1), i0); +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1) +{ + stxi(i0, rn(r0), rn(r1)); +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0) +{ + ldxi_d(rn(r0), rn(r1), i0); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1) +{ + stxi_d(i0, rn(r0), rn(r1)); +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) + flag = node->v.n->flag; + else + flag = node->u.n->flag; + assert(!(flag & jit_flag_patch)); + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} diff --git a/deps/lightning/lib/jit_ia64-cpu.c b/deps/lightning/lib/jit_ia64-cpu.c new file mode 100644 index 0000000..dec1465 --- /dev/null +++ b/deps/lightning/lib/jit_ia64-cpu.c @@ -0,0 +1,5402 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +#define stack_framesize 144 +#define params_offset 16 +#define INST_NONE 0 /* should never be generated */ +#define INST_STOP 1 /* or'ed if stop is required */ +#define INST_A 2 /* M- or I- unit */ +#define INST_As 3 +#define INST_I 4 +#define INST_Is 5 +#define INST_M 6 +#define INST_Ms 7 +#define INST_F 8 +#define INST_Fs 9 +#define INST_B 10 +#define INST_Bs 11 +#define INST_L 12 +#define INST_Ls 13 +#define INST_X 14 +#define INST_Xs 15 + +/* Data and instructions are referenced by 64-bit addresses. Instructions + * are stored in memory in little endian byte order, in which the least + * significant byte appears in the lowest addressed byte of a memory + * location. For data, modes for both big and little endian byte order are + * supported and can be controlled by a bit in the User Mask Register. + */ +#define il(ii) *_jit->pc.ul++ = ii +#define set_bundle(p, l, h, tm, s0, s1, s2) \ + do { \ + l = tm | ((s0 & 0x1ffffffffffL) << 5L) | (s1 << 46L); \ + h = ((s1 >> 18L) & 0x7fffffLL) | (s2 << 23L); \ + p[0] = byte_swap_if_big_endian(l); \ + p[1] = byte_swap_if_big_endian(h); \ + } while (0) +#define get_bundle(p, l, h, tm, s0, s1, s2) \ + do { \ + l = byte_swap_if_big_endian(p[0]); \ + h = byte_swap_if_big_endian(p[1]); \ + tm = l & 0x1f; \ + s0 = (l >> 5L) & 0x1ffffffffffL; \ + s1 = ((l >> 46L) & 0x3ffffL) | ((h & 0x7fffffL) << 18L); \ + s2 = (h >> 23L) & 0x1ffffffffffL; \ + } while (0) + +/* Need to insert a stop if a modified register would (or could) + * be read in the same cycle. + */ +#define TSTREG1(r0) \ + do { \ + if (jit_regset_tstbit(&_jitc->regs, r0)) \ + stop(); \ + } while (0) +#define TSTREG2(r0, r1) \ + do { \ + if (jit_regset_tstbit(&_jitc->regs, r0) || \ + jit_regset_tstbit(&_jitc->regs, r1)) \ + stop(); \ + } while (0) +#define TSTPRED(p0) \ + do { \ + if (p0 && (_jitc->pred & (1 << p0))) \ + stop(); \ + } while (0) +/* Record register was modified */ +#define SETREG(r0) jit_regset_setbit(&_jitc->regs, r0) + +/* Avoid using constants in macros and code */ +typedef enum { + GR_0, GR_1, GR_2, GR_3, + GR_4, GR_5, GR_6, GR_7, + GR_8, GR_9, GR_10, GR_11, + GR_12, GR_13, GR_14, GR_15, + GR_16, GR_17, GR_18, GR_19, + GR_20, GR_21, GR_22, GR_23, + GR_24, GR_25, GR_26, GR_27, + GR_28, GR_29, GR_30, GR_31, + GR_32, GR_33, GR_34, GR_35, + GR_36, GR_37, GR_38, GR_39, + GR_40, GR_41, GR_42, GR_43, + /* GR_44...GR_127 */ +} gr_reg_t; + +typedef enum { + PR_0, /* constant - always 1 */ + /* p0-p5 - preserved */ + PR_1, PR_2, PR_3, PR_4, + PR_5, + /* p6-p15 - scratch */ + PR_6, PR_7, PR_8, PR_9, + PR_10, PR_11, PR_12, PR_13, + PR_14, PR_15, + /* p16-... - preserved - rotating */ +} pr_reg_t; + +typedef enum { + BR_0, /* scratch - Return link */ + /* b1-b5 - preserved */ + BR_1, BR_2, BR_3, BR_4, + BR_5, + /* b6-b7 - scratch */ + BR_6, BR_7 +} br_reg_t; + +typedef enum { + AR_KR0, AR_KR1, AR_KR2, AR_KR3, + AR_KR4, AR_KR5, AR_KR6, AR_KR7, + AR_8, AR_9, AR_10, AR_11, + AR_12, AR_13, AR_14, AR_15, + AR_RSC, AR_BSP, AR_BSPSTORE, AR_RNAT, + AR_20, AR_FCR, AR_22, AR_23, + AR_EFLAG, AR_CSD, AR_SSD, AR_CFLG, + AR_FSR, AR_FIR, AR_FDR, AR_31, + AR_CCV, AR_33, AR_34, AR_35, + AR_UNAT, AR_37, AR_38, AR_39, + AR_FPSR, AR_41, AR_42, AR_43, + AR_ITC, AR_RUC, AR_46, AR_47, + AR_48, AR_49, AR_50, AR_51, + AR_52, AR_53, AR_54, AR_55, + AR_56, AR_57, AR_58, AR_59, + AR_60, AR_61, AR_62, AR_63, + AR_PFS, AR_LC, AR_EC, + /* AR_67 ... AR_127 */ +} ar_reg_t; + +typedef enum { + TM_M_I_I_, TM_M_I_Is, TM_M_IsI_, TM_M_IsIs, + TM_M_L_X_, TM_M_L_Xs, TM_ILL_06, TM_ILL_07, + TM_M_M_I_, TM_M_M_Is, TM_MsM_I_, TM_MsM_Is, + TM_M_F_I_, TM_M_F_Is, TM_M_M_F_, TM_M_M_Fs, + TM_M_I_B_, TM_M_I_Bs, TM_M_B_B_, TM_M_B_Bs, + TM_ILL_14, TM_ILL_15, TM_B_B_B_, TM_B_B_Bs, + TM_M_M_B_, TM_M_M_Bs, TM_ILL_1A, TM_ILL_1B, + TM_M_F_B_, TM_M_F_Bs, TM_ILL_1E, TM_ILL_1F, +} template_t; + +#define MWH_SPTK 0 +#define MWH_NONE 1 +#define MWH_DPTK 2 + +#define IH_NONE 0 +#define IH_IMP 1 + +#define LD_NONE 0 +#define LD_NT1 1 +#define LD_NTA 3 + +#define ST_NONE 0 +#define ST_NTA 3 + +#define LF_NONE 0 +#define LF_NT1 1 +#define LF_NT2 2 +#define LF_NTA 3 + +#define BR_PH_FEW 0 +#define BR_PH_MANY 1 + +#define BR_BWH_SPTK 0 +#define BR_BWH_SPNT 1 +#define BR_BWH_DPTK 2 +#define BR_BWH_DPNT 3 + +#define BRI_BWH_SPTK 1 +#define BRI_BWH_SPNT 3 +#define BRI_BWH_DPTK 5 +#define BRI_BWH_DPNT 7 + +#define BR_DH_NONE 0 +#define BR_DH_CLR 1 + +#define BR_IH_NONE 0 +#define BR_IH_IMP 1 + +#define BR_IPWH_SPTK 0 +#define BR_IPWH_LOOP 1 +#define BR_IPWH_DPTK 2 +#define BR_IPWH_EXIT 3 + +#define BR_INDWH_SPTK 0 +#define BR_INDWH_DPTK 2 + +#define MUX_BRCST 0 +#define MUX_REV 11 +#define MUX_MIX 8 +#define MUX_SHUF 9 +#define MUX_ALT 10 + +#define ldr(r0,r1) ldr_l(r0,r1) +#define ldi(r0,i0) ldi_l(r0,i0) +#define str(r0,r1) str_l(r0,r1) +#define sti(i0,r0) str_l(i0,r0) +#define ldxr(r0,r1,r2) ldxr_l(r0,r1,r2) +#define ldxi(r0,r1,i0) ldxi_l(r0,r1,i0) +#define stxr(r0,r1,r2) stxr_l(r0,r1,r2) +#define stxi(i0,r0,r1) stxi_l(i0,r0,r1) + +#if !HAVE_FFSL +# define ffsl(l) __builtin_ffsl(l) +#endif + +/* libgcc */ +#if defined(__GNUC__) +extern long __divdi3(long,long); +extern unsigned long __udivdi3(unsigned long,unsigned long); +extern long __moddi3(long,long); +extern unsigned long __umoddi3(unsigned long,unsigned long); +#else +static long __divdi3(long,long); +static unsigned long __udivdi3(unsigned long,unsigned long); +static long __moddi3(long,long); +static unsigned long __umoddi3(unsigned long,unsigned long); +#endif +#define out(n,tm,s0,s1,s2) _out(_jit,n,tm,s0,s1,s2) +static void _out(jit_state_t*,int,int,jit_word_t,jit_word_t,jit_word_t); +#define stop() _stop(_jit) +static void _stop(jit_state_t*); +#define sync() _sync(_jit) +static void _sync(jit_state_t*); +#define flush() _flush(_jit) +static void _flush(jit_state_t*); +#define inst(w, t) _inst(_jit, w, t) +static void _inst(jit_state_t*, jit_word_t, jit_uint8_t); +#define A1(x4,x2,r3,r2,r1) _A1(_jit,0,x4,x2,r3,r2,r1) +static void _A1(jit_state_t*, jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define A2(x4,ct,r3,r2,r1) A1(x4,ct,r3,r2,r1) +#define A3(x4,x2,r3,im,r1) _A3(_jit,0,x4,x2,r3,im,r1) +static void _A3(jit_state_t*, jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define A4(x2a,r3,im,r1) _A4(_jit,0,x2a,r3,im,r1) +static void _A4(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define A5(r3,im,r1) _A5(_jit,0,r3,im,r1) +static void _A5(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t); +#define A6(o,x2,ta,p2,r3,r2,c,p1) _A6(_jit,0,o,x2,ta,p2,r3,r2,c,p1) +static void _A6(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define A7(o,x2,ta,p2,r3,c,p1) _A7(_jit,0,o,x2,ta,p2,r3,c,p1) +static void _A7(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define A8(o,x2,ta,p2,r3,im,c,p1) _A8(_jit,0,o,x2,ta,p2,r3,im,c,p1) +static void _A8(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define A9(za,zb,x4,x2,r3,r2,r1) _A9(_jit,0,za,zb,x4,x2,r3,r2,r1) +static void _A9(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define A10(x4,ct,r3,r2,r1) A9(0,1,x4,ct,r3,r2,r1) +#define I1(ct,x2,r3,r2,r1) _I1(_jit,0,ct,x2,r3,r2,r1) +static void _I1(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I2(za,x2a,zb,x2c,x2b,r3,r2,r1) _I2(_jit,0,za,x2a,zb,x2c,x2b,r3,r2,r1) +static void _I2(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I3(mbt,r2,r1) _I3(_jit,0,mbt,r2,r1) +static void _I3(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) +#if __BYTE_ORDER == __BIG_ENDIAN + maybe_unused +#endif + ; +#define I4(mht,r2,r1) _I4(_jit,0,mht,r2,r1) +static void _I4(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I5(za,zb,x2b,r3,r2,r1) _I5(_jit,0,za,zb,x2b,r3,r2,r1) +static void _I5(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t); +#define I6(za,zb,x2b,r3,ct,r1) _I6(_jit,0,za,zb,x2b,r3,ct,r1) +static void _I6(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I7(za,zb,r3,r2,r1) _I7(_jit,0,za,zb,r3,r2,r1) +static void _I7(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define I8(za,zb,ct,r2,r1) _I8(_jit,0,za,zb,ct,r2,r1) +static void _I8(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I9(x2c,r3,r1) _I9(_jit,0,x2c,r3,r1) +static void _I9(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I10(ct,r3,r2,r1) _I10(_jit,0,ct,r3,r2,r1) +static void _I10(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I11(len,r3,pos,y,r1) _I11(_jit,0,len,r3,pos,y,r1) +static void _I11(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I12(len,pos,r2,r1) _I12(_jit,0,len,pos,r2,r1) +static void _I12(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I13(len,pos,im,r1) _I13(_jit,0,len,pos,im,r1) +static void _I13(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I14(s,len,r3,pos,r1) _I14(_jit,0,s,len,r3,pos,r1) +static void _I14(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I15(pos,len,r3,r2,r1) _I15(_jit,0,pos,len,r3,r2,r1) +static void _I15(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I16(tb,ta,p2,r3,pos,c,p1) _I16(_jit,0,tb,ta,p2,r3,pos,c,p1) +static void _I16(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I17(tb,ta,p2,r3,c,p1) _I17(_jit,0,tb,ta,p2,r3,c,p1) +static void _I17(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define I18(im,y) _I18(_jit,0,im,y) +static void _I18(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define I19(im) _I19(_jit,0,im) +static void _I19(jit_state_t*,jit_word_t, + jit_word_t) + maybe_unused; +#define I20(r2,im) _I20(_jit,0,r2,im) +static void _I20(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define I21(im,ih,x,wh,r2,b1) _I21(_jit,0,im,ih,x,wh,r2,b1) +static void _I21(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define I22(b2,r1) _I22(_jit,0,b2,r1) +static void _I22(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t); +#define I23(r2,im) _I23(_jit,0,r2,im) +static void _I23(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define I24(im) _I24(_jit,0,im) +static void _I24(jit_state_t*,jit_word_t, + jit_word_t) + maybe_unused; +#define I25(x6,r1) _I25(_jit,0,x6,r1) +static void _I25(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define I26(ar,r2) _I26(_jit,0,ar,r2) +static void _I26(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t); +#define I27(ar,im) _I27(_jit,0,ar,im) +static void _I27(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define I28(ar,r1) _I28(_jit,0,ar,r1) +static void _I28(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define I29(x6,r3,r1) _I29(_jit,0,x6,r3,r1) +static void _I29(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t); +#define I30(tb,ta,p2,im,c,p1) _I30(_jit,0,ta,tb,p2,im,c,p1) +static void _I30(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M1(x6,ht,x,r3,r1) _M1(_jit,0,x6,ht,x,r3,r1) +static void _M1(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define M2(x6,ht,r3,r2,r1) _M2(_jit,0,x6,ht,r3,r2,r1) +static void _M2(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M3(x6,ht,r3,im,r1) _M3(_jit,0,x6,ht,r3,im,r1) +static void _M3(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define M5(x6,ht,r3,r2,im) _M5(_jit,0,x6,ht,r3,r2,im) +static void _M5(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M6(x6,ht,x,r3,r2) _M6(_jit,0,x6,ht,x,r3,r2) +static void _M6(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define M13(x6,ht,r3,f2) _M13(_jit,0,x6,ht,r3,f2) +static void _M13(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define M14(x6,ht,r3,r2) _M14(_jit,0,x6,ht,r3,r2) +static void _M14(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M15(x6,ht,r3,im) _M15(_jit,0,x6,ht,r3,im) +static void _M15(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M16(x6,ht,r3,r2,r1) _M16(_jit,0,x6,ht,r3,r2,r1) +static void _M16(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M17(x6,ht,r3,im,r1) _M17(_jit,0,x6,ht,r3,im,r1) +static void _M17(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M20(r2,im) M20x(0x1,r2,im) +#define M20x(x3,r2,im) _M20x(_jit,0,x3,r2,im) +static void _M20x(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M22(x3,im,r1) M22x(x3,im,r1) +#define M22x(x3,im,r1) _M22x(_jit,0,x3,im,r1) +static void _M22x(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M24(x2,x4) _M24(_jit,0,x2,x4) +#define M25(x4) M24(0,x4) +static void _M24(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define M26(r1) M26x(2,r1) +#define M26x(x4,r1) _M26x(_jit,0,x4,r1) +static void _M26x(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define M28(x,r3) _M28(_jit,0,x,r3) +static void _M28(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define M29(ar,r2) _M29(_jit,0,ar,r2) +static void _M29(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define M30(ar,im) _M30(_jit,0,ar,im) +static void _M30(jit_state_t*,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M31(ar,r1) _M31(_jit,0,ar,r1) +static void _M31(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define M32(cr,r2) _M32(_jit,0,cr,r2) +static void _M32(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define M33(cr,r1) _M33(_jit,0,cr,r1) +static void _M33(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define M34(sor,sol,sof,r1) _M34(_jit,0,sor,sol,sof,r1) +static void _M34(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define M35(x6,r2) _M35(_jit,0,x6,r2) +static void _M35(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define M36(x6,r1) _M36(_jit,0,x6,r1) +static void _M36(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define M37(im) _M37(_jit,0,im) +static void _M37(jit_state_t*,jit_word_t, + jit_word_t) + maybe_unused; +#define M38(x6,r3,r2,r1) _M38(_jit,0,x6,r3,r2,r1) +static void _M38(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M39(x6,r3,im,r1) _M39(_jit,0,x6,r3,im,r1) +static void _M39(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M40(x6,r3,im) _M40(_jit,0,x6,r3,im) +static void _M40(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M41(x6,r2) _M41(_jit,0,x6,r2) +static void _M41(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define M42(x6,r3,r2) _M42(_jit,0,x6,r3,r2) +static void _M42(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M43(x6,r3,r1) _M43(_jit,0,x6,r3,r1) +static void _M43(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M44(x4,im) _M44(_jit,0,x4,im) +static void _M44(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define M45(x6,r3,r2) _M45(_jit,0,x6,r3,r2) +static void _M45(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M46(x6,r3,r1) _M46(_jit,0,x6,r3,r1) +#define M47(x6,r3) M46(x6,r3,0) +static void _M46(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M48(y,im) _M48(_jit,0,y,im) +static void _M48(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; +#define B1(d,wh,im,p,tp) _B1(_jit,0,d,wh,im,p,tp) +#define B2(d,wh,im,p,tp) B1(d,wh,im,p,tp) +static void _B1(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define B3(d,wh,im,p,b) _B3(_jit,0,d,wh,im,p,b) +static void _B3(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define B4(d,wh,x6,b,p,tp) _B4(_jit,0,d,wh,x6,b,p,tp) +static void _B4(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t); +#define B5(d,wh,b2,p,b1) _B5(_jit,0,d,wh,b2,p,b1) +static void _B5(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define B6(ih,im,tag,wh) _B6(_jit,0,ih,im,tag,wh) +static void _B6(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define B7(ih,x6,b2,tag,wh) _B7(_jit,0,ih,x6,b2,tag,wh) +static void _B7(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define B8(x6) _B8(_jit,0,x6) +static void _B8(jit_state_t*,jit_word_t, + jit_word_t) + maybe_unused; +#define B9(op,x6,im) _B9(_jit,0,op,x6,im) +static void _B9(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define X1(im) _X1(_jit,0,im) +static void _X1(jit_state_t*,jit_word_t, + jit_word_t) + maybe_unused; +#define X2(r1,im) _X2(_jit,0,r1,im) +static void _X2(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t); +#define X3x(o,d,wh,p,tp,im) _X3x(_jit,0,o,d,wh,p,tp,im) +#define X3(d,wh,p,tp,im) X3x(0xc,d,wh,p,tp,im) +#define X4(d,wh,p,tp,im) X3x(0xd,d,wh,p,tp,im) +static void _X3x(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t); +#define X5(y,im) _X5(_jit,0,y,im) +static void _X5(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t) + maybe_unused; + +/* add */ +#define ADD(r1,r2,r3) A1(0,0,r3,r2,r1) +#define ADD1(r1,r2,r3) A1(0,1,r3,r2,r1) +#define ADDS(r1,im,r3) A4(2,r3,im,r1) +#define ADDS_p(r1,im,r3,_p) _A4(_jit,_p,2,r3,im,r1) +#define ADDL(r1,im,r3) A5(r3,im,r1) +#define ADDL_p(r1,im,r3,_p) _A5(_jit,_p,r3,im,r1) +/* addp4 */ +#define ADDP4(r1,r2,r3) A1(2,0,r3,r2,r1) +#define ADDIP4(r1,im,r3) A4(3,r3,im,r1) +/* alloc */ +#define ALLOCR(r1,i,l,o,r) M34((r)>>3,(i)+(l),(i)+(l)+(o),r1) +#define ALLOC(r1,i,o) ALLOCR(r1,i,0,o,0) +/* and */ +#define AND(r1,r2,r3) A1(3,0,r3,r2,r1) +#define ANDI(r1,im,r3) A3(0xb,0,r3,im,r1) +/* andcm */ +#define ANDCM(r1,r2,r3) A1(3,1,r3,r2,r1) +#define ANDCMI(r1,im,r3) A3(0xb,1,r3,im,r1) +/* br */ +#define BRI(im) B1(BR_DH_NONE,BR_BWH_SPTK,im,BR_PH_FEW,0) +#define BRI_COND(im,_p) _B1(_jit,_p,BR_DH_NONE,BR_BWH_SPTK,im,BR_PH_FEW,0) +#define BRI_WEXIT(im) B1(BR_DH_NONE,BR_BWH_SPTK,im,BR_PH_MANY,2) +#define BRI_WTOP(im) B1(BR_DH_NONE,BR_BWH_SPTK,im,BR_PH_MANY,3) +#define BRI_CALL(b,im) B3(BR_DH_NONE,BR_BWH_SPTK,im,BR_PH_MANY,b) +#define BRI_CLOOP(im) B2(BR_DH_NONE,BR_BWH_SPTK,im,BR_PH_MANY,5) +#define BRI_CEXIT(im) B2(BR_DH_NONE,BR_BWH_SPTK,im,BR_PH_MANY,6) +#define BRI_CTOP(im) B2(BR_DH_NONE,BR_BWH_SPTK,im,BR_PH_MANY,7) +#define BR_COND(b,_p) _B4(_jit,_p,BR_DH_NONE,BR_BWH_SPTK,0x20,b,BR_PH_FEW,0) +#define BR(b) B4(BR_DH_NONE,BR_BWH_SPTK,0x20,b,BR_PH_FEW,0) +#define BR_IA(b) B4(BR_DH_NONE,BR_BWH_SPTK,0x20,b,BR_PH_MANY,1) +#define BR_RET(b) B4(BR_DH_NONE,BR_BWH_SPTK,0x21,b,BR_PH_MANY,4) +#define BR_CALL(b1,b2) B5(BR_DH_NONE,BRI_BWH_SPTK,b2,BR_PH_MANY,b1) +/* break */ +#define BREAK_I(im) I19(im) +#define BREAK_M(im) M37(im) +#define BREAK_B(im) B9(0,0,im) +#define BREAK_X(im) X1(im) +/* brl */ +#define BRL(im) X3(BR_DH_NONE,BR_BWH_SPTK,BR_PH_MANY,0,im) +#define BRL_COND(im,_p) _X3(_jit,_p,BR_DH_NONE,BR_BWH_SPTK,BR_PH_MANY,0,im) +#define BRL_CALL(b1,im) X4(BR_DH_NONE,BR_BWH_SPTK,BR_PH_MANY,b1,im) +/* brp */ +#define BRP(im,tag) B6(BR_IH_NONE,im,tag,BR_IPWH_SPTK) +#define BRPI(b2,tag) B7(BR_IH_NONE,0x10,b2,tag,BR_INDWH_SPTK) +#define BRPI_RET(b2,tag) B7(BR_IH_NONE,0x11,b2,tag,BR_INDWH_SPTK) +/* bsw */ +#define BSW_0() B8(0x0c) +#define BSW_1() B8(0x0d) +/* chk */ +#define CHK_S_I(r2,im) I20(r2,im) +#define CHK_S_M(r2,im) M20(r2,im) +#define CHK_A_NC(r1,im) M22(0x4,im,r1) +#define CHK_A_CLR(r1,im) M22(0x5,im,r1) +/* clrrrb */ +#define CLRRRB() B8(0x04) +#define CLRRRB_PR() B8(0x05) +/* clz */ +#define CLZ(r1,r3) I9(3,r3,r1) +/* cmp */ +#define CMP_LT(p1,p2,r2,r3) A6(0xc,0,0,p2,r3,r2,0,p1) +#define CMP_LT_p(p1,p2,r2,r3,_p) A6(_jit,_p,0xc,0,0,p2,r3,r2,0,p1) +#define CMP_LTU(p1,p2,r2,r3) A6(0xd,0,0,p2,r3,r2,0,p1) +#define CMP_EQ(p1,p2,r2,r3) A6(0xe,0,0,p2,r3,r2,0,p1) +#define CMP_LT_UNC(p1,p2,r2,r3) A6(0xc,0,0,p2,r3,r2,1,p1) +#define CMP_LTU_UNC(p1,p2,r2,r3) A6(0xd,0,0,p2,r3,r2,1,p1) +#define CMP_EQ_UNC(p1,p2,r2,r3) A6(0xe,0,0,p2,r3,r2,1,p1) +#define CMP_EQ_AND(p1,p2,r2,r3) A6(0xc,0,1,p2,r3,r2,0,p1) +#define CMP_EQ_OR(p1,p2,r2,r3) A6(0xd,0,1,p2,r3,r2,0,p1) +#define CMP_EQ_OR_ANDCM(p1,p2,r2,r3) A6(0xe,0,1,p2,r3,r2,0,p1) +#define CMP_NE_AND(p1,p2,r2,r3) A6(0xc,0,1,p2,r3,r2,1,p1) +#define CMP_NE_OR(p1,p2,r2,r3) A6(0xd,0,1,p2,r3,r2,1,p1) +#define CMP_NE_OR_ANDCM(p1,p2,r2,r3) A6(0xe,0,1,p2,r3,r2,1,p1) +#define CMPI_LT(p1,p2,im,r3) A8(0xc,2,0,p2,r3,im,0,p1) +#define CMPI_LTU(p1,p2,im,r3) A8(0xd,2,0,p2,r3,im,0,p1) +#define CMPI_EQ(p1,p2,im,r3) A8(0xe,2,0,p2,r3,im,0,p1) +#define CMPI_EQ_p(p1,p2,im,r3,_p) _A8(_jit,_p,0xe,2,0,p2,r3,im,0,p1) +#define CMPI_LT_UNC(p1,p2,im,r3) A8(0xc,2,0,p2,r3,im,1,p1) +#define CMPI_LTU_UNC(p1,p2,im,r3) A8(0xd,2,0,p2,r3,im,1,p1) +#define CMPI_EQ_UNC(p1,p2,im,r3) A8(0xe,2,0,p2,r3,im,1,p1) +#define CMPI_EQ_AND(p1,p2,im,r3) A8(0xc,2,1,p2,r3,im,0,p1) +#define CMPI_EQ_OR(p1,p2,im,r3) A8(0xd,2,1,p2,r3,im,0,p1) +#define CMPI_EQ_ANDCM(p1,p2,im,r3) A8(0xe,2,1,p2,r3,im,0,p1) +#define CMPI_NE_AND(p1,p2,im,r3) A8(0xc,2,1,p2,r3,im,1,p1) +#define CMPI_NE_OR(p1,p2,im,r3) A8(0xd,2,1,p2,r3,im,1,p1) +#define CMPI_NE_ANDCM(p1,p2,im,r3) A8(0xe,2,1,p2,r3,im,1,p1) +#define ZCMP_GT_AND(p1,p2,r3) A7(0xc,0,0,p2,r3,0,p1) +#define ZCMP_GT_OR(p1,p2,r3) A7(0xd,0,0,p2,r3,0,p1) +#define ZCMP_GT_ANDCM(p1,p2,r3) A7(0xe,0,0,p2,r3,0,p1) +#define ZCMP_LE_AND(p1,p2,r3) A7(0xc,0,0,p2,r3,1,p1) +#define ZCMP_LE_OR(p1,p2,r3) A7(0xd,0,0,p2,r3,1,p1) +#define ZCMP_LE_ANDCM(p1,p2,r3) A7(0xe,0,0,p2,r3,1,p1) +#define ZCMP_GE_AND(p1,p2,r3) A7(0xc,0,1,p2,r3,0,p1) +#define ZCMP_GE_OR(p1,p2,r3) A7(0xd,0,1,p2,r3,0,p1) +#define ZCMP_GE_ANDCM(p1,p2,r3) A7(0xe,0,1,p2,r3,0,p1) +#define ZCMP_LT_AND(p1,p2,r3) A7(0xc,0,1,p2,r3,1,p1) +#define ZCMP_LT_OR(p1,p2,r3) A7(0xd,0,1,p2,r3,1,p1) +#define ZCMP_LT_ANDCM(p1,p2,r3) A7(0xe,0,1,p2,r3,1,p1) +/* cmp4 */ +#define CMP4_LT(p1,p2,r2,r3) A6(0xc,1,0,p2,r3,r2,0,p1) +#define CMP4_LTU(p1,p2,r2,r3) A6(0xd,1,0,p2,r3,r2,0,p1) +#define CMP4_EQ(p1,p2,r2,r3) A6(0xe,1,0,p2,r3,r2,0,p1) +#define CMP4_LT_UNC(p1,p2,r2,r3) A6(0xc,1,0,p2,r3,r2,1,p1) +#define CMP4_LTU_UNC(p1,p2,r2,r3) A6(0xd,1,0,p2,r3,r2,1,p1) +#define CMP4_EQ_UNC(p1,p2,r2,r3) A6(0xe,1,0,p2,r3,r2,1,p1) +#define CMP4_EQ_AND(p1,p2,r2,r3) A6(0xc,1,1,p2,r3,r2,0,p1) +#define CMP4_EQ_OR(p1,p2,r2,r3) A6(0xd,1,1,p2,r3,r2,0,p1) +#define CMP4_EQ_XOR(p1,p2,r2,r3) A6(0xe,1,1,p2,r3,r2,0,p1) +#define CMP4_NE_AND(p1,p2,r2,r3) A6(0xc,1,1,p2,r3,r2,1,p1) +#define CMP4_NE_OR(p1,p2,r2,r3) A6(0xd,1,1,p2,r3,r2,1,p1) +#define CMP4_NE_XOR(p1,p2,r2,r3) A6(0xe,1,1,p2,r3,r2,1,p1) +#define CMP4I_LT(p1,p2,im,r3) A8(0xc,3,0,p2,r3,im,0,p1) +#define CMP4I_LTU(p1,p2,im,r3) A8(0xd,3,0,p2,r3,im,0,p1) +#define CMP4I_EQ(p1,p2,im,r3) A8(0xe,3,0,p2,r3,im,0,p1) +#define CMP4I_LT_UNC(p1,p2,im,r3) A8(0xc,3,0,p2,r3,im,1,p1) +#define CMP4I_LTU_UNC(p1,p2,im,r3) A8(0xd,3,0,p2,r3,im,1,p1) +#define CMP4I_EQ_UNC(p1,p2,im,r3) A8(0xe,3,0,p2,r3,im,1,p1) +#define CMP4I_EQ_AND(p1,p2,im,r3) A8(0xc,3,1,p2,r3,im,0,p1) +#define CMP4I_EQ_OR(p1,p2,im,r3) A8(0xd,3,1,p2,r3,im,0,p1) +#define CMP4I_EQ_ANDCM(p1,p2,im,r3) A8(0xe,3,1,p2,r3,im,0,p1) +#define CMP4I_NE_AND(p1,p2,im,r3) A8(0xc,3,1,p2,r3,im,1,p1) +#define CMP4I_NE_OR(p1,p2,im,r3) A8(0xd,3,1,p2,r3,im,1,p1) +#define CMP4I_NE_ANDCM(p1,p2,im,r3) A8(0xe,3,1,p2,r3,im,1,p1) +#define ZCMP4_GT_AND(p1,p2,r3) A7(0xc,1,0,p2,r3,0,p1) +#define ZCMP4_GT_OR(p1,p2,r3) A7(0xd,1,0,p2,r3,0,p1) +#define ZCMP4_GT_ANDCM(p1,p2,r3) A7(0xe,1,0,p2,r3,0,p1) +#define ZCMP4_LE_AND(p1,p2,r3) A7(0xc,1,0,p2,r3,1,p1) +#define ZCMP4_LE_OR(p1,p2,r3) A7(0xd,1,0,p2,r3,1,p1) +#define ZCMP4_LE_ANDCM(p1,p2,r3) A7(0xe,1,0,p2,r3,1,p1) +#define ZCMP4_GE_AND(p1,p2,r3) A7(0xc,1,1,p2,r3,0,p1) +#define ZCMP4_GE_OR(p1,p2,r3) A7(0xd,1,1,p2,r3,0,p1) +#define ZCMP4_GE_ANDCM(p1,p2,r3) A7(0xe,1,1,p2,r3,0,p1) +#define ZCMP4_LT_AND(p1,p2,r3) A7(0xc,1,1,p2,r3,1,p1) +#define ZCMP4_LT_OR(p1,p2,r3) A7(0xd,1,1,p2,r3,1,p1) +#define ZCMP4_LT_ANDCM(p1,p2,r3) A7(0xe,1,1,p2,r3,1,p1) +/* cmpxchg */ +#define CMPXCHG1_ACQ(r1,r3,r2) M16(0x00,LD_NONE,r3,r2,r1) +#define CMPXCHG2_ACQ(r1,r3,r2) M16(0x01,LD_NONE,r3,r2,r1) +#define CMPXCHG4_ACQ(r1,r3,r2) M16(0x02,LD_NONE,r3,r2,r1) +#define CMPXCHG8_ACQ(r1,r3,r2) M16(0x03,LD_NONE,r3,r2,r1) +#define CMPXCHG1_REL(r1,r3,r2) M16(0x04,LD_NONE,r3,r2,r1) +#define CMPXCHG2_REL(r1,r3,r2) M16(0x05,LD_NONE,r3,r2,r1) +#define CMPXCHG4_REL(r1,r3,r2) M16(0x06,LD_NONE,r3,r2,r1) +#define CMPXCHG8_REL(r1,r3,r2) M16(0x07,LD_NONE,r3,r2,r1) +#define CMP8XCHG16_ACQ(r1,r3,r2) M16(0x20,LD_NONE,r3,r2,r1) +#define CMP8XCHG16_REL(r1,r3,r2) M16(0x24,LD_NONE,r3,r2,r1) +/* cover */ +#define COVER() B8(0x02) +/* cxz */ +#define CZX1_L(r1,r3) I29(0x18,r3,r1) +#define CZX2_L(r1,r3) I29(0x19,r3,r1) +#define CZX1_R(r1,r3) I29(0x1c,r3,r1) +#define CZX2_R(r1,r3) I29(0x1d,r3,r1) +/* dep */ +#define DEP_Z(r1,r2,pos,len) I12(len,pos,r2,r1) +#define DEPI_Z(r1,im,pos,len) I13(len,pos,im,r1) +#define DEPs(r1,r2,r3,pos,len) I14(1,len,r3,pos,r1) +#define DEPu(r1,r2,r3,pos,len) I14(0,len,r3,pos,r1) +#define DEP(r1,r2,r3,pos,len) I15(pos,len,r3,r2,r1) +/* epc */ +#define EPC() B8(0x10) +/* extr */ +#define EXTR(r1,r3,pos,len) I11(len,r3,pos,1,r1) +#define EXTR_U(r1,r3,pos,len) I11(len,r3,pos,0,r1) +/* fc */ +#define FC(r3) M28(0,r3) +#define FC_I(r3) M28(1,r3) +/* fetchadd */ +#define FETCHADD4_ACQ(r1,r3,im) M17(0x12,LD_NONE,r3,im,r1) +#define FETCHADD8_ACQ(r1,r3,im) M17(0x13,LD_NONE,r3,im,r1) +#define FETCHADD4_REL(r1,r3,im) M17(0x16,LD_NONE,r3,im,r1) +#define FETCHADD8_REL(r1,r3,im) M17(0x17,LD_NONE,r3,im,r1) +/* flushrs */ +#define FLUSHRS() M25(0xc) +/* fwb */ +#define FWB() M24(2,0) +/* hint */ +#define HINT_I(im) I18(im,1) +#define HINT_M(im) M48(1,im) +#define HINT_B(im) B9(2,1,im) +#define HINT_X(im) X5(1,im) +/* invala */ +#define INVALA() M24(1,0) +#define INVALA_E(r1) M26(r1) +/* itc */ +#define ITC_I(r2) M41(0x2f,r2) +#define ITC_D(r2) M41(0x2e,r2) +/* itr */ +#define ITR_I(r3,r2) M42(0x0f,r3,r2) +#define ITR_D(r3,r2) M42(0x0e,r3,r2) +/* ld */ +#define LD1(r1,r3) M1(0x00,LD_NONE,0,r3,r1) +#define LD2(r1,r3) M1(0x01,LD_NONE,0,r3,r1) +#define LD4(r1,r3) M1(0x02,LD_NONE,0,r3,r1) +#define LD8(r1,r3) M1(0x03,LD_NONE,0,r3,r1) +#define LD1_S(r1,r3) M1(0x04,LD_NONE,0,r3,r1) +#define LD2_S(r1,r3) M1(0x05,LD_NONE,0,r3,r1) +#define LD4_S(r1,r3) M1(0x06,LD_NONE,0,r3,r1) +#define LD8_S(r1,r3) M1(0x07,LD_NONE,0,r3,r1) +#define LD1_A(r1,r3) M1(0x08,LD_NONE,0,r3,r1) +#define LD2_A(r1,r3) M1(0x09,LD_NONE,0,r3,r1) +#define LD4_A(r1,r3) M1(0x0a,LD_NONE,0,r3,r1) +#define LD8_A(r1,r3) M1(0x0b,LD_NONE,0,r3,r1) +#define LD1_SA(r1,r3) M1(0x0c,LD_NONE,0,r3,r1) +#define LD2_SA(r1,r3) M1(0x0d,LD_NONE,0,r3,r1) +#define LD4_SA(r1,r3) M1(0x0e,LD_NONE,0,r3,r1) +#define LD8_SA(r1,r3) M1(0x0f,LD_NONE,0,r3,r1) +#define LD1_BIAS(r1,r3) M1(0x10,LD_NONE,0,r3,r1) +#define LD2_BIAS(r1,r3) M1(0x11,LD_NONE,0,r3,r1) +#define LD4_BIAS(r1,r3) M1(0x12,LD_NONE,0,r3,r1) +#define LD8_BIAS(r1,r3) M1(0x13,LD_NONE,0,r3,r1) +#define LD1_ACQ(r1,r3) M1(0x14,LD_NONE,0,r3,r1) +#define LD2_ACQ(r1,r3) M1(0x15,LD_NONE,0,r3,r1) +#define LD4_ACQ(r1,r3) M1(0x16,LD_NONE,0,r3,r1) +#define LD8_ACQ(r1,r3) M1(0x17,LD_NONE,0,r3,r1) +#define LD8_FILL(r1,r3) M1(0x1b,LD_NONE,0,r3,r1) +#define LD1_C_CLR(r1,r3) M1(0x20,LD_NONE,0,r3,r1) +#define LD2_C_CLR(r1,r3) M1(0x21,LD_NONE,0,r3,r1) +#define LD4_C_CLR(r1,r3) M1(0x22,LD_NONE,0,r3,r1) +#define LD8_C_CLR(r1,r3) M1(0x23,LD_NONE,0,r3,r1) +#define LD1_C_NC(r1,r3) M1(0x24,LD_NONE,0,r3,r1) +#define LD2_C_NC(r1,r3) M1(0x25,LD_NONE,0,r3,r1) +#define LD4_C_NC(r1,r3) M1(0x26,LD_NONE,0,r3,r1) +#define LD8_C_NC(r1,r3) M1(0x27,LD_NONE,0,r3,r1) +#define LD1_C_CLR_ACQ(r1,r3) M1(0x28,LD_NONE,0,r3,r1) +#define LD2_C_CLR_ACQ(r1,r3) M1(0x29,LD_NONE,0,r3,r1) +#define LD4_C_CLR_ACQ(r1,r3) M1(0x2a,LD_NONE,0,r3,r1) +#define LD8_C_CLR_ACQ(r1,r3) M1(0x2b,LD_NONE,0,r3,r1) +#define LD16(r1,r3) M1(0x28,LD_NONE,1,r3,r1) +#define LD16_ACQ(r1,r3) M1(0x2c,LD_NONE,1,r3,r1) +#define LD1_inc(r1,r3,im) M3(0x00,LD_NONE,r3,im,r1) +#define LD2_inc(r1,r3,im) M3(0x01,LD_NONE,r3,im,r1) +#define LD4_inc(r1,r3,im) M3(0x02,LD_NONE,r3,im,r1) +#define LD8_inc(r1,r3,im) M3(0x03,LD_NONE,r3,im,r1) +#define LD1_S_inc(r1,r3,im) M3(0x04,LD_NONE,r3,im,r1) +#define LD2_S_inc(r1,r3,im) M3(0x05,LD_NONE,r3,im,r1) +#define LD4_S_inc(r1,r3,im) M3(0x06,LD_NONE,r3,im,r1) +#define LD8_S_inc(r1,r3,im) M3(0x07,LD_NONE,r3,im,r1) +#define LD1_A_inc(r1,r3,im) M3(0x08,LD_NONE,r3,im,r1) +#define LD2_A_inc(r1,r3,im) M3(0x09,LD_NONE,r3,im,r1) +#define LD4_A_inc(r1,r3,im) M3(0x0a,LD_NONE,r3,im,r1) +#define LD8_A_inc(r1,r3,im) M3(0x0b,LD_NONE,r3,im,r1) +#define LD1_SA_inc(r1,r3,im) M3(0x0c,LD_NONE,r3,im,r1) +#define LD2_SA_inc(r1,r3,im) M3(0x0d,LD_NONE,r3,im,r1) +#define LD4_SA_inc(r1,r3,im) M3(0x0e,LD_NONE,r3,im,r1) +#define LD8_SA_inc(r1,r3,im) M3(0x0f,LD_NONE,r3,im,r1) +#define LD1_BIAS_inc(r1,r3,im) M3(0x10,LD_NONE,r3,im,r1) +#define LD2_BIAS_inc(r1,r3,im) M3(0x11,LD_NONE,r3,im,r1) +#define LD4_BIAS_inc(r1,r3,im) M3(0x12,LD_NONE,r3,im,r1) +#define LD8_BIAS_inc(r1,r3,im) M3(0x13,LD_NONE,r3,im,r1) +#define LD1_ACQ_inc(r1,r3,im) M3(0x14,LD_NONE,r3,im,r1) +#define LD2_ACQ_inc(r1,r3,im) M3(0x15,LD_NONE,r3,im,r1) +#define LD4_ACQ_inc(r1,r3,im) M3(0x16,LD_NONE,r3,im,r1) +#define LD8_AVQ_inc(r1,r3,im) M3(0x17,LD_NONE,r3,im,r1) +#define LD8_FILL_inc(r1,r3,im) M3(0x1b,LD_NONE,r3,im,r1) +#define LD1_C_CLR_inc(r1,r3,im) M3(0x20,LD_NONE,r3,im,r1) +#define LD2_C_CLR_inc(r1,r3,im) M3(0x21,LD_NONE,r3,im,r1) +#define LD4_C_CLR_inc(r1,r3,im) M3(0x22,LD_NONE,r3,im,r1) +#define LD8_C_CLR_inc(r1,r3,im) M3(0x23,LD_NONE,r3,im,r1) +#define LD1_C_NC_inc(r1,r3,im) M3(0x24,LD_NONE,r3,im,r1) +#define LD2_C_NC_inc(r1,r3,im) M3(0x25,LD_NONE,r3,im,r1) +#define LD4_C_NC_inc(r1,r3,im) M3(0x26,LD_NONE,r3,im,r1) +#define LD8_C_NC_inc(r1,r3,im) M3(0x27,LD_NONE,r3,im,r1) +#define LD1_C_CLR_ACQ_inc(r1,r3,im) M3(0x28,LD_NONE,r3,im,r1) +#define LD2_C_CLR_ACQ_inc(r1,r3,im) M3(0x29,LD_NONE,r3,im,r1) +#define LD4_C_CLR_ACQ_inc(r1,r3,im) M3(0x2a,LD_NONE,r3,im,r1) +#define LD8_C_CLR_ACQ_inc(r1,r3,im) M3(0x2b,LD_NONE,r3,im,r1) +#define LDX1(r1,r3,r2) M2(0x00,LD_NONE,r3,r2,r1) +#define LDX2(r1,r3,r2) M2(0x01,LD_NONE,r3,r2,r1) +#define LDX4(r1,r3,r2) M2(0x02,LD_NONE,r3,r2,r1) +#define LDX8(r1,r3,r2) M2(0x03,LD_NONE,r3,r2,r1) +#define LDX1_S(r1,r3,r2) M2(0x04,LD_NONE,r3,r2,r1) +#define LDX2_S(r1,r3,r2) M2(0x05,LD_NONE,r3,r2,r1) +#define LDX4_S(r1,r3,r2) M2(0x06,LD_NONE,r3,r2,r1) +#define LDX8_S(r1,r3,r2) M2(0x07,LD_NONE,r3,r2,r1) +#define LDX1_A(r1,r3,r2) M2(0x08,LD_NONE,r3,r2,r1) +#define LDX2_A(r1,r3,r2) M2(0x09,LD_NONE,r3,r2,r1) +#define LDX4_A(r1,r3,r2) M2(0x0a,LD_NONE,r3,r2,r1) +#define LDX8_A(r1,r3,r2) M2(0x0b,LD_NONE,r3,r2,r1) +#define LDX1_SA(r1,r3,r2) M2(0x0c,LD_NONE,r3,r2,r1) +#define LDX2_SA(r1,r3,r2) M2(0x0d,LD_NONE,r3,r2,r1) +#define LDX4_SA(r1,r3,r2) M2(0x0e,LD_NONE,r3,r2,r1) +#define LDX8_SA(r1,r3,r2) M2(0x0f,LD_NONE,r3,r2,r1) +#define LDX1_BIAS(r1,r3,r2) M2(0x10,LD_NONE,r3,r2,r1) +#define LDX2_BIAS(r1,r3,r2) M2(0x11,LD_NONE,r3,r2,r1) +#define LDX4_BIAS(r1,r3,r2) M2(0x12,LD_NONE,r3,r2,r1) +#define LDX8_BIAS(r1,r3,r2) M2(0x13,LD_NONE,r3,r2,r1) +#define LDX1_ACQ(r1,r3,r2) M2(0x14,LD_NONE,r3,r2,r1) +#define LDX2_ACQ(r1,r3,r2) M2(0x15,LD_NONE,r3,r2,r1) +#define LDX4_ACQ(r1,r3,r2) M2(0x16,LD_NONE,r3,r2,r1) +#define LDX8_ACQ(r1,r3,r2) M2(0x17,LD_NONE,r3,r2,r1) +#define LDX8_FILL(r1,r3,r2) M2(0x1b,LD_NONE,r3,r2,r1) +#define LDX1_C_CLR(r1,r3,r2) M2(0x20,LD_NONE,r3,r2,r1) +#define LDX2_C_CLR(r1,r3,r2) M2(0x21,LD_NONE,r3,r2,r1) +#define LDX4_C_CLR(r1,r3,r2) M2(0x22,LD_NONE,r3,r2,r1) +#define LDX8_C_CLR(r1,r3,r2) M2(0x23,LD_NONE,r3,r2,r1) +#define LDX1_C_NC(r1,r3,r2) M2(0x24,LD_NONE,r3,r2,r1) +#define LDX2_C_NC(r1,r3,r2) M2(0x25,LD_NONE,r3,r2,r1) +#define LDX4_C_NC(r1,r3,r2) M2(0x26,LD_NONE,r3,r2,r1) +#define LDX8_C_NC(r1,r3,r2) M2(0x27,LD_NONE,r3,r2,r1) +#define LDX1_C_CLR_ACQ(r1,r3,r2) M2(0x28,LD_NONE,r3,r2,r1) +#define LDX2_C_CLR_ACQ(r1,r3,r2) M2(0x29,LD_NONE,r3,r2,r1) +#define LDX4_C_CLR_ACQ(r1,r3,r2) M2(0x2a,LD_NONE,r3,r2,r1) +#define LDX8_C_CLR_ACQ(r1,r3,r2) M2(0x2b,LD_NONE,r3,r2,r1) +/* lfetch */ +#define LFETCH_EXCL(r3) M13(0x2d,LF_NONE,r3,GR_0) +#define LFETCH_FAULT(r3) M13(0x2e,LF_NONE,r3,GR_0) +#define LFETCH_FAULT_EXCL(r3) M13(0x2f,LF_NONE,r3,GR_0) +#define LXFETCH(r3,r2) M14(0x2c,LF_NONE,r3,r2) +#define LXFETCH_EXCL(r3,r2) M14(0x2d,LF_NONE,r3,r2) +#define LXFETCH_FAULT(r3,r2) M14(0x2e,LF_NONE,r3,r2) +#define LXFETCH_FAULT_EXCL(r3,r2) M14(0x2f,LF_NONE,r3,r2) +#define LFETCHI(r3,im) M15(0x2c,LF_NONE,r3,im) +#define LFETCHI_EXCL(r3,im) M15(0x2d,LF_NONE,r3,im) +#define LFETCHI_FAULT(r3,im) M15(0x2e,LF_NONE,r3,im) +#define LFETCHI_FAULT_EXCL(r3,im) M15(0x2f,LF_NONE,r3,im) +/* loadrs */ +#define LOADRS() M25(0xa) +/* mf */ +#define MF() M24(2,2) +#define MF_A() M24(2,3) +/* mix */ +#define MIX1_R(r1,r2,r3) I2(0,2,0,2,0,r3,r2,r1) +#define MIX2_R(r1,r2,r3) I2(0,2,1,2,0,r3,r2,r1) +#define MIX4_R(r1,r2,r3) I2(1,2,0,2,0,r3,r2,r1) +#define MIX1_L(r1,r2,r3) I2(0,2,0,2,2,r3,r2,r1) +#define MIX2_L(r1,r2,r3) I2(0,2,1,2,2,r3,r2,r1) +#define MIX4_L(r1,r2,r3) I2(1,2,0,2,2,r3,r2,r1) +/* mov - Move Application Register */ +#define MOV_I_rn_ar(r1,ar) I28(ar,r1) +#define MOV_I_ar_rn(ar,r2) I26(ar,r2) +#define MOV_I_ar_im(ar,im) I27(ar,im) +#define MOV_M_rn_a(r1,ar) M31(r1,ar) +#define MOV_M_ar_rn(ar,r2) M29(ar,r2) +#define MOV_M_ar_im(ar,im) M30(ar,im) +/* mov - Move Branch Register */ +#define MOV_rn_br(r1,b2) I22(b2,r1) +#define MOV_br_rn_tg(b1,r2,tag) I21(tag,IH_NONE,0,MWH_NONE,r2,b1) +#define MOV_br_rn(b1,r2) MOV_br_rn_tg(b1,r2,0) +#define MOV_RET_br_rn_tg(b1,r2,tag) I21(tag,IH_NONE,1,MWH_NONE,r2,b1) +/* mov - Move Control Register */ +#define MOV_rn_cr(cr,r1) M33(cr,r1) +#define MOV_cr_rr(cr,r2) M32(cr,r2) +/* mov - Move General Register */ +#define MOV(r0,r1) ADDS(r0,0,r1) +#define MOV_p(r0,r1,_p) ADDS_p(r0,0,r1,_p) +/* mov - Move Immediate */ +#define MOVI(r1,im) ADDL(r1,im,GR_0) +#define MOVI_p(r1,im,_p) ADDL_p(r1,im,GR_0,_p) +/* mov - Move Indirect Register */ +#define MOV_rn_RR(r1,r3) M43(0x10,r3,r1) +#define MOV_rn_DBR(r1,r3) M43(0x11,r3,r1) +#define MOV_rn_IBR(r1,r3) M43(0x012,r3,r1) +#define MOV_rn_PKR(r1,r3) M43(0x13,r3,r1) +#define MOV_rn_PMC(r1,r3) M43(0x14,r3,r1) +#define MOV_rn_PMD(r1,r3) M43(0x15,r3,r1) +#define MOV_rn_CPUID(r1,r3) M43(0x17,r3,r1) +#define MOV_RR_rn(r3,r2) M42(0x00,r3,r2) +#define MOV_DBR_rn(r3,r2) M42(0x01,r3,r2) +#define MOV_IBR_rn(r3,r2) M42(0x02,r3,r2) +#define MOV_PKR_rn(r3,r2) M42(0x03,r3,r2) +#define MOV_PMC_rn(r3,r2) M42(0x04,r3,r2) +#define MOV_PMD_rn(r3,r2) M42(0x05,r3,r2) +/* mov - Move Instruction Pointer */ +#define MOV_rn_ip(r1) I25(0x30,r1) +/* mov - Move Predicates */ +#define MOV_rn_pr(r1) I25(0x33,r1) +#define MOV_pr_rn(r2,im) I23(r2,im) +#define MOVI_pr(im) I24(im) +/* mov - Move Processor Status Register */ +#define MOV_rn_psr(r1) M36(0x25,r1) +#define MOV_psr_l_rn(r2) M35(0x2d,r2) +/* mov - Move User Mask */ +#define MOV_rn_psr_um(r1) M36(0x21,r1) +#define MOV_psr_um_rn(r2) M35(0x29,r2) +/* movl */ +#define MOVL(r1,im) X2(r1,im) +/* mpy4 */ +#define MPY4(r1,r2,r3) I2(1,0,0,3,1,r3,r2,r1) +/* mpyshl4 */ +#define MPYSHL4(r1,r2,r3) I2(1,0,0,3,3,r3,r2,r1) +/* mux */ +#define MUX1(r1,r2,mbt) I3(mbt,r2,r1) +#define MUX2(r1,r2,mht) I4(mht,r2,r1) +/* nop */ +#define NOP_I(im) I18(im,0) +#define NOP_M(im) M48(0,im) +#define NOP_B(im) B9(2,0,im) +#define NOP_X(im) X5(0,im) +/* or */ +#define OR(r1,r2,r3) A1(3,2,r3,r2,r1) +#define ORI(r1,im,r3) A3(0xb,2,r3,im,r1) +/* pack */ +#define PACK2_USS(r1,r2,r3) I2(0,2,1,0,0,r3,r2,r1) +#define PACK2_SSS(r1,r2,r3) I2(0,2,1,0,2,r3,r2,r1) +#define PACK4_SSS(r1,r2,r3) I2(1,2,0,0,2,r3,r2,r1) +/* padd */ +#define PADD1(r1,r2,r3) A9(0,0,0,0,r3,r2,r1) +#define PADD1_SSS(r1,r2,r3) A9(0,0,0,1,r3,r2,r1) +#define PADD1_UUU(r1,r2,r3) A9(0,0,0,2,r3,r2,r1) +#define PADD1_UUS(r1,r2,r3) A9(0,0,0,3,r3,r2,r1) +#define PADD2(r1,r2,r3) A9(0,1,0,0,r3,r2,r1) +#define PADD2_SSS(r1,r2,r3) A9(0,1,0,1,r3,r2,r1) +#define PADD2_UUU(r1,r2,r3) A9(0,1,0,2,r3,r2,r1) +#define PADD2_UUS(r1,r2,r3) A9(0,1,0,3,r3,r2,r1) +#define PADD4(r1,r2,r3) A9(1,0,0,0,r3,r2,r1) +/* pavg */ +#define PAVG1(r1,r2,r3) A9(0,0,2,2,r3,r2,r1) +#define PAVG2(r1,r2,r3) A9(0,1,2,2,r3,r2,r1) +#define PAVG1_RAZ(r1,r2,r3) A9(0,0,2,3,r3,r2,r1) +#define PAVG2_RAZ(r1,r2,r3) A9(0,1,2,3,r3,r2,r1) +/* pavgsub */ +#define PAVGSUB1(r1,r2,r3) A9(0,0,3,2,r3,r2,r1) +#define PAVGSUB2(r1,r2,r3) A9(0,1,3,2,r3,r2,r1) +/* pcmp */ +#define PCMP1_EQ(r1,r2,r3) A9(0,0,9,0,r3,r2,r1) +#define PCMP2_EQ(r1,r2,r3) A9(0,1,9,0,r3,r2,r1) +#define PCMP4_EQ(r1,r2,r3) A9(1,0,9,0,r3,r2,r1) +#define PCMP1_GT(r1,r2,r3) A9(0,0,9,1,r3,r2,r1) +#define PCMP2_GT(r1,r2,r3) A9(0,1,9,1,r3,r2,r1) +#define PCMP4_GT(r1,r2,r3) A9(1,0,9,1,r3,r2,r1) +/* pmax */ +#define PMAX1_U(r1,r2,r3) I2(0,2,0,1,1,r3,r2,r1) +#define PMAX2(r1,r2,r3) I2(0,2,1,1,3,r3,r2,r1) +/* pmin */ +#define PMIN1_U(r1,r2,r3) I2(0,2,0,0,1,r3,r2,r1) +#define PMIN2(r1,r2,r3) I2(0,2,1,0,3,r3,r2,r1) +/* pmpy */ +#define PMPY2_R(r1,r2,r3) I2(0,2,1,3,1,r3,r2,r1) +#define PMPY2_L(r1,r2,r3) I2(0,2,1,3,3,r3,r2,r1) +/* pmpyshr */ +#define PMPYSHR2(r1,r2,r3,im) I1(im,3,r3,r2,r1) +#define PMPYSHR2_U(r1,r2,r3,im) I1(im,1,r3,r2,r1) +/* popcnt */ +#define POPCNT(r1,r3) I9(2,r3,r1) +/* probe */ +#define PROBE_R(r1,r3,r2) M38(0x38,r3,r2,r1) +#define PROBE_W(r1,r3,r2) M38(0x39,r3,r2,r1) +#define PROBEI_R(r1,r3,im) M39(0x18,r3,im,r1) +#define PROBEI_W(r1,r3,im) M39(0x19,r3,im,r1) +#define PROBE_RW_FAULT(r3,im) M40(0x31,r3,im) +#define PROBE_R_FAULT(r3,im) M40(0x32,r3,im) +#define PROBE_W_FAULT(r3,im) M40(0x33,r3,im) +/* psad */ +#define PSAD1(r1,r2,r3) I2(0,2,0,2,3,r3,r2,r1) +/* pshl */ +#define PSHL2(r1,r2,r3) I7(0,1,r3,r2,r1) +#define PSHL4(r1,r2,r3) I7(1,0,r3,r2,r1) +#define PSHL2I(r1,r2,im) I8(0,1,im,r2,r1) +#define PSHL4I(r1,r2,im) I8(1,0,im,r2,r1) +/* pshladd */ +#define PSHLADD2(r1,r2,im,r3) A10(4,im,r3,r2,r1) +/* pshr */ +#define PSHR2(r1,r3,r2) I5(0,1,2,r3,r2,r1) +#define PSHR2I(r1,r3,im) I6(0,1,3,r3,im,r1) +#define PSHR2_U(r1,r3,r2) I5(0,1,0,r3,r2,r1) +#define PSHR2I_U(r1,r3,im) I6(0,1,1,r3,im,r1) +#define PSHR4(r1,r3,r2) I5(1,0,2,r3,r2,r1) +#define PSHR4I(r1,r3,im) I6(1,0,3,r3,im,r1) +#define PSHR4_U(r1,r3,r2) I5(1,0,0,r3,r2,r1) +#define PSHR4I_U(r1,r3,im) I6(1,0,1,r3,im,r1) +/* pshradd */ +#define PSHRADD2(r1,r2,im,r3) A10(6,im,r3,r2,r1) +/* psub */ +#define PSUB1(r1,r2,r3) A9(0,0,1,0,r3,r2,r1) +#define PSUB1_SSS(r1,r2,r3) A9(0,0,1,1,r3,r2,r1) +#define PSUB1_UUU(r1,r2,r3) A9(0,0,1,2,r3,r2,r1) +#define PSUB1_UUS(r1,r2,r3) A9(0,0,1,3,r3,r2,r1) +#define PSUB2(r1,r2,r3) A9(0,1,1,0,r3,r2,r1) +#define PSUB2_SSS(r1,r2,r3) A9(0,1,1,1,r3,r2,r1) +#define PSUB2_UUU(r1,r2,r3) A9(0,1,1,2,r3,r2,r1) +#define PSUB2_UUS(r1,r2,r3) A9(0,1,1,3,r3,r2,r1) +#define PSUB4(r1,r2,r3) A9(1,0,1,0,r3,r2,r1) +/* ptc.e */ +#define PTC_E(r3) M47(0x34,r3) +/* ptc.g, ptc.ga */ +#define PTC_G(r3,r2) M45(0xa,r3,r2) +#define PTC_GA(r3,r2) M45(0xb,r3,r2) +/* ptc.l */ +#define PTC_L(r3,r2) M45(0x9,r3,r2) +/* ptr */ +#define PTR_D(r3,r2) M45(0xc,r3,r2) +#define PTR_I(r3,r2) M45(0xd,r3,r2) +/* rfi */ +#define RFI() B8(0x08) +/* rsm */ +#define RSM(im) M44(7,im) +/* rum */ +#define RUM(im) M44(5,im) +/* shl */ +#define SHL(r1,r2,r3) I7(1,1,r3,r2,r1) +/* shladd */ +#define SHLADD(r1,r2,im,r3) A2(4,im,r3,r2,r1) +/* shladdp4 */ +#define SHLADDP4(r1,r2,im,r3) A2(6,im,r3,r2,r1) +/* shr */ +#define SHR(r1,r3,r2) I5(1,1,2,r3,r2,r1) +#define SHR_U(r1,r3,r2) I5(1,1,0,r3,r2,r1) +/* shrp */ +#define SHRP(r1,r2,r3,im) I10(im,r3,r2,r1) +/* srlz */ +#define SRLZ_I() M24(3,1) +#define SRLZ_D() M24(3,0) +/* ssm */ +#define SSM(im) M44(6,im) +/* st */ +#define ST1(r3,r2) M6(0x30,ST_NONE,0,r3,r2) +#define ST2(r3,r2) M6(0x31,ST_NONE,0,r3,r2) +#define ST4(r3,r2) M6(0x32,ST_NONE,0,r3,r2) +#define ST8(r3,r2) M6(0x33,ST_NONE,0,r3,r2) +#define ST1_REL(r3,r2) M6(0x34,ST_NONE,0,r3,r2) +#define ST2_REL(r3,r2) M6(0x35,ST_NONE,0,r3,r2) +#define ST4_REL(r3,r2) M6(0x36,ST_NONE,0,r3,r2) +#define ST8_REL(r3,r2) M6(0x37,ST_NONE,0,r3,r2) +#define ST8_SPILL(r3,r2) M6(0x3b,ST_NONE,0,r3,r2) +#define ST16(r3,r2) M6(0x30,ST_NONE,1,r3,r2) +#define ST16_REL(r3,r2) M6(0x34,ST_NONE,1,r3,r2) +#define ST1_inc(r3,r2,im) M5(0x30,ST_NONE,r3,r2,im) +#define ST2_inc(r3,r2,im) M5(0x31,ST_NONE,r3,r2,im) +#define ST4_inc(r3,r2,im) M5(0x32,ST_NONE,r3,r2,im) +#define ST8_inc(r3,r2,im) M5(0x33,ST_NONE,r3,r2,im) +#define ST1_REL_inc(r3,r2,im) M5(0x34,ST_NONE,r3,r2,im) +#define ST2_REL_inc(r3,r2,im) M5(0x35,ST_NONE,r3,r2,im) +#define ST4_REL_inc(r3,r2,im) M5(0x36,ST_NONE,r3,r2,im) +#define ST8_REL_inc(r3,r2,im) M5(0x37,ST_NONE,r3,r2,im) +#define ST8_SPILL_inc(r3,r2,im) M5(0x3b,ST_NONE,r3,r2,im) +/* sub */ +#define SUB(r1,r2,r3) A1(1,1,r3,r2,r1) +#define SUB1(r1,r2,r3) A1(1,0,r3,r2,r1) +#define SUBI(r1,im,r3) A3(9,1,r3,im,r1) +/* sum */ +#define SUM(im) M44(4,im) +/* sxt */ +#define SXT1(r1,r3) I29(0x14,r3,r1) +#define SXT2(r1,r3) I29(0x15,r3,r1) +#define SXT4(r1,r3) I29(0x16,r3,r1) +/* sync */ +#define SYNC_I() M24(3,3) +/* tak */ +#define TAK(r1,r3) M46(0x1f,r3,r1) +/* tbit */ +#define TBIT_Z(p1,p2,r3,pos) I16(0,0,p2,r3,pos,0,p1) +#define TBIT_Z_UNC(p1,p2,r3,pos) I16(0,0,p2,r3,pos,1,p1) +#define TBIT_Z_AND(p1,p2,r3,pos) I16(1,0,p2,r3,pos,0,p1) +#define TBIT_NZ_AND(p1,p2,r3,pos) I16(1,0,p2,r3,pos,1,p1) +#define TBIT_Z_OR(p1,p2,r3,pos) I16(0,1,p2,r3,pos,0,p1) +#define TBIT_NZ_OR(p1,p2,r3,pos) I16(0,1,p2,r3,pos,1,p1) +#define TBIT_Z_ANDCM(p1,p2,r3,pos) I16(1,1,p2,r3,pos,0,p1) +#define TBIT_NZ_ANDCM(p1,p2,r3,pos) I16(1,1,p2,r3,pos,1,p1) +/* tf */ +#define TF_Z(p1,p2,im) I30(0,0,p2,im,0,p1) +#define TF_Z_UNC(p1,p2,im) I30(0,0,p2,im,1,p1) +#define TF_Z_AND(p1,p2,im) I30(1,0,p2,im,0,p1) +#define TF_NZ_AND(p1,p2,im) I30(1,0,p2,im,1,p1) +#define TF_Z_OR(p1,p2,im) I30(0,1,p2,im,0,p1) +#define TF_NZ_OR(p1,p2,im) I30(0,1,p2,im,1,p1) +#define TF_Z_ANDCM(p1,p2,im) I30(1,1,p2,im,0,p1) +#define TF_NZ_ANDCM(p1,p2,im) I30(1,1,p2,im,1,p1) +/* thash */ +#define THASH(r1,r3) M46(0x1a,r3,r1) +/* tnat */ +#define TNAT_Z(p1,p2,r3) I17(0,0,p2,r3,0,p1) +#define TNAT_Z_UNC(p1,p2,r3) I17(0,0,p2,r3,1,p1) +#define TNAT_Z_AND(p1,p2,r3) I17(1,0,p2,r3,0,p1) +#define TNAT_NZ_AND(p1,p2,r3) I17(1,0,p2,r3,1,p1) +#define TNAT_Z_OR(p1,p2,r3) I17(0,1,p2,r3,0,p1) +#define TNAT_NZ_OR(p1,p2,r3) I17(0,1,p2,r3,1,p1) +#define TNAT_Z_ANDCM(p1,p2,r3) I17(1,1,p2,r3,0,p1) +#define TNAT_NZ_ANDCM(p1,p2,r3) I17(1,1,p2,r3,1,p1) +/* tpa */ +#define TPA(r1,r3) M46(0x1e,r3,r1) +/* ttag */ +#define TTAG(r1,r3) M46(0x1b,r3,r1) +/* unpack */ +#define UNPACK1_H(r1,r2,r3) I2(0,2,0,1,0,r3,r2,r1) +#define UNPACK2_H(r1,r2,r3) I2(0,2,1,1,0,r3,r2,r1) +#define UNPACK4_H(r1,r2,r3) I2(1,2,0,1,0,r3,r2,r1) +#define UNPACK1_L(r1,r2,r3) I2(0,2,0,1,2,r3,r2,r1) +#define UNPACK2_L(r1,r2,r3) I2(0,2,1,1,2,r3,r2,r1) +#define UNPACK4_L(r1,r2,r3) I2(1,2,0,1,2,r3,r2,r1) +/* vmsw */ +#define VMSW_0() B8(0x18) +#define VMSW_1() B8(0x19) +/* xchg */ +#define XCHG1_ACQ(r1,r3,r2) M16(0x08,LD_NONE,r3,r2,r1) +#define XCHG2_ACQ(r1,r3,r2) M16(0x09,LD_NONE,r3,r2,r1) +#define XCHG4_ACQ(r1,r3,r2) M16(0x0a,LD_NONE,r3,r2,r1) +#define XCHG8_ACQ(r1,r3,r2) M16(0x0b,LD_NONE,r3,r2,r1) +/* xor */ +#define XOR(r1,r2,r3) A1(3,3,r3,r2,r1) +#define XORI(r1,im,r3) A3(0xb,3,r3,im,r1) +/* zxt */ +#define ZXT1(r1,r3) I29(0x10,r3,r1) +#define ZXT2(r1,r3) I29(0x11,r3,r1) +#define ZXT4(r1,r3) I29(0x12,r3,r1) + +#define addr(r0,r1,r2) ADD(r0,r1,r2) +#define addi(r0,r1,i0) _addi(_jit,r0,r1,i0) +static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define addcr(r0, r1, r2) _addcr(_jit, r0, r1, r2) +static void _addcr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +#define addci(r0, r1, i0) _addci(_jit, r0, r1, i0) +static void _addci(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define addxr(r0, r1, r2) _addxr(_jit, r0, r1, r2) +static void _addxr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define addxi(r0, r1, i0) _addxi(_jit, r0, r1, i0) +static void _addxi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +#define subr(r0,r1,r2) SUB(r0,r1,r2) +#define subi(r0,r1,i0) _subi(_jit,r0,r1,i0) +static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subcr(r0, r1, r2) _subcr(_jit, r0, r1, r2) +static void _subcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subci(r0, r1, i0) _subci(_jit, r0, r1, i0) +static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subxr(r0, r1, r2) _subxr(_jit, r0, r1, r2) +static void _subxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subxi(r0, r1, i0) _subxi(_jit, r0, r1, i0) +static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0) +static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define mulr(r0,r1,r2) _mulr(_jit,r0,r1,r2) +static void _mulr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define muli(r0,r1,i0) _muli(_jit,r0,r1,i0) +static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define divr(r0,r1,r2) _divr(_jit,r0,r1,r2) +static void _divr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define divi(r0,r1,i0) _divi(_jit,r0,r1,i0) +static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define divr_u(r0,r1,r2) _divr_u(_jit,r0,r1,r2) +static void _divr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0) +static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define remr(r0,r1,r2) _remr(_jit,r0,r1,r2) +static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define remi(r0,r1,i0) _remi(_jit,r0,r1,i0) +static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2) +static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0) +static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define mulh(r0,r1,r2,sign) _mulh(_jit,r0,r1,r2,sign) +static void _mulh(jit_state_t*,jit_bool_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define qmulr(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,1) +#define qmulr_u(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,0) +#define iqmulr(r0,r1,r2,r3,sign) _iqmulr(_jit,r0,r1,r2,r3,sign) +static void _iqmulr(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_bool_t); +#define qmuli(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,1) +#define qmuli_u(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,0) +#define iqmuli(r0,r1,r2,i0,sign) _iqmuli(_jit,r0,r1,r2,i0,sign) +static void _iqmuli(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_word_t,jit_bool_t); +#define qdivr(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,1) +#define qdivr_u(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,0) +#define iqdivr(r0,r1,r2,r3,sign) _iqdivr(_jit,r0,r1,r2,r3,sign) +static void _iqdivr(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_bool_t); +#define qdivi(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,1) +#define qdivi_u(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,0) +#define iqdivi(r0,r1,r2,i0,sign) _iqdivi(_jit,r0,r1,r2,i0,sign) +static void _iqdivi(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_word_t,jit_bool_t); +#define andr(r0,r1,r2) AND(r0,r1,r2) +#define andi(r0,r1,i0) _andi(_jit,r0,r1,i0) +static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define orr(r0,r1,r2) OR(r0,r1,r2) +#define ori(r0,r1,i0) _ori(_jit,r0,r1,i0) +static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define xorr(r0,r1,r2) XOR(r0,r1,r2) +#define xori(r0,r1,i0) _xori(_jit,r0,r1,i0) +static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define lshr(r0,r1,r2) SHL(r0,r1,r2) +#define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0) +static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define rshr(r0,r1,r2) SHR(r0,r1,r2) +#define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0) +static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define rshr_u(r0,r1,r2) SHR_U(r0,r1,r2) +#define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0) +static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ltr(r0,r1,r2) _ltr(_jit,r0,r1,r2) +static void _ltr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define lti(r0,r1,i0) _lti(_jit,r0,r1,i0) +static void _lti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ltr_u(r0,r1,r2) _ltr_u(_jit,r0,r1,r2) +static void _ltr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define lti_u(r0,r1,i0) _lti_u(_jit,r0,r1,i0) +static void _lti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ler(r0,r1,r2) _ler(_jit,r0,r1,r2) +static void _ler(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define lei(r0,r1,i0) _lei(_jit,r0,r1,i0) +static void _lei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ler_u(r0,r1,r2) _ler_u(_jit,r0,r1,r2) +static void _ler_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define lei_u(r0,r1,i0) _lei_u(_jit,r0,r1,i0) +static void _lei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define eqr(r0,r1,r2) _eqr(_jit,r0,r1,r2) +static void _eqr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define eqi(r0,r1,i0) _eqi(_jit,r0,r1,i0) +static void _eqi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ger(r0,r1,r2) _ger(_jit,r0,r1,r2) +static void _ger(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define gei(r0,r1,i0) _gei(_jit,r0,r1,i0) +static void _gei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ger_u(r0,r1,r2) _ger_u(_jit,r0,r1,r2) +static void _ger_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define gei_u(r0,r1,i0) _gei_u(_jit,r0,r1,i0) +static void _gei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define gtr(r0,r1,r2) _gtr(_jit,r0,r1,r2) +static void _gtr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define gti(r0,r1,i0) _gti(_jit,r0,r1,i0) +static void _gti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define gtr_u(r0,r1,r2) _gtr_u(_jit,r0,r1,r2) +static void _gtr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define gti_u(r0,r1,i0) _gti_u(_jit,r0,r1,i0) +static void _gti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ner(r0,r1,r2) _ner(_jit,r0,r1,r2) +static void _ner(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define nei(r0,r1,i0) _nei(_jit,r0,r1,i0) +static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define negr(r0,r1) subr(r0,0,r1) +#define comr(r0,r1) ANDCMI(r0,-1,r1) +#define movr(r0,r1) _movr(_jit,r0,r1) +static void _movr(jit_state_t*,jit_int32_t,jit_int32_t); +#define movi(r0,i0) _movi(_jit,r0,i0) +static void _movi(jit_state_t*,jit_int32_t,jit_word_t); +#define movi_p(r0,i0) _movi_p(_jit,r0,i0) +static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t); +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1) +static void _htonr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1) +static void _htonr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# define htonr_ul(r0,r1) MUX1(r0,r1,MUX_REV) +#else +# define htonr_us(r0,r1) extr_us(r0,r1) +# define htonr_ui(r0,r1) extr_ui(r0,r1) +# define htonr_ul(r0,r1) movr(r0,r1) +#endif +#define extr_c(r0,r1) SXT1(r0,r1) +#define extr_uc(r0,r1) ZXT1(r0,r1) +#define extr_s(r0,r1) SXT2(r0,r1) +#define extr_us(r0,r1) ZXT2(r0,r1) +#define extr_i(r0,r1) SXT4(r0,r1) +#define extr_ui(r0,r1) ZXT4(r0,r1) +#define bltr(i0,r0,r1) _bltr(_jit,i0,r0,r1) +static jit_word_t _bltr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define blti(i0,r0,i1) _blti(_jit,i0,r0,i1) +static jit_word_t _blti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bltr_u(i0,r0,r1) _bltr_u(_jit,i0,r0,r1) +static jit_word_t _bltr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define blti_u(i0,r0,i1) _blti_u(_jit,i0,r0,i1) +static jit_word_t _blti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bler(i0,r0,r1) _bler(_jit,i0,r0,r1) +static jit_word_t _bler(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define blei(i0,r0,i1) _blei(_jit,i0,r0,i1) +static jit_word_t _blei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bler_u(i0,r0,r1) _bler_u(_jit,i0,r0,r1) +static jit_word_t _bler_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define blei_u(i0,r0,i1) _blei_u(_jit,i0,r0,i1) +static jit_word_t _blei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define beqr(i0,r0,r1) _beqr(_jit,i0,r0,r1) +static jit_word_t _beqr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define beqi(i0,r0,i1) _beqi(_jit,i0,r0,i1) +static jit_word_t _beqi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bger(i0,r0,r1) _bger(_jit,i0,r0,r1) +static jit_word_t _bger(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bgei(i0,r0,i1) _bgei(_jit,i0,r0,i1) +static jit_word_t _bgei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bger_u(i0,r0,r1) _bger_u(_jit,i0,r0,r1) +static jit_word_t _bger_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bgei_u(i0,r0,i1) _bgei_u(_jit,i0,r0,i1) +static jit_word_t _bgei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bgtr(i0,r0,r1) _bgtr(_jit,i0,r0,r1) +static jit_word_t _bgtr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bgti(i0,r0,i1) _bgti(_jit,i0,r0,i1) +static jit_word_t _bgti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bgtr_u(i0,r0,r1) _bgtr_u(_jit,i0,r0,r1) +static jit_word_t _bgtr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bgti_u(i0,r0,i1) _bgti_u(_jit,i0,r0,i1) +static jit_word_t _bgti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bner(i0,r0,r1) _bner(_jit,i0,r0,r1) +static jit_word_t _bner(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bnei(i0,r0,i1) _bnei(_jit,i0,r0,i1) +static jit_word_t _bnei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bmsr(i0,r0,r1) _bmsr(_jit,i0,r0,r1) +static jit_word_t _bmsr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bmsi(i0,r0,i1) _bmsi(_jit,i0,r0,i1) +static jit_word_t _bmsi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bmcr(i0,r0,r1) _bmcr(_jit,i0,r0,r1) +static jit_word_t _bmcr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bmci(i0,r0,i1) _bmci(_jit,i0,r0,i1) +static jit_word_t _bmci(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define baddr(i0,r0,r1,cc) _baddr(_jit,i0,r0,r1,cc) +static jit_word_t _baddr(jit_state_t*,jit_word_t, + jit_int32_t,jit_int32_t,jit_bool_t); +#define baddi(i0,r0,i1,cc) _baddi(_jit,i0,r0,i1,cc) +static jit_word_t _baddi(jit_state_t*,jit_word_t, + jit_int32_t,jit_word_t,jit_bool_t); +#define baddr_u(i0,r0,r1,cc) _baddr_u(_jit,i0,r0,r1,cc) +static jit_word_t _baddr_u(jit_state_t*,jit_word_t, + jit_int32_t,jit_int32_t,jit_bool_t); +#define baddi_u(i0,r0,i1,cc) _baddi_u(_jit,i0,r0,i1,cc) +static jit_word_t _baddi_u(jit_state_t*,jit_word_t, + jit_int32_t,jit_word_t,jit_bool_t); +#define bsubr(i0,r0,r1,cc) _bsubr(_jit,i0,r0,r1,cc) +static jit_word_t _bsubr(jit_state_t*,jit_word_t, + jit_int32_t,jit_int32_t,jit_bool_t); +#define bsubi(i0,r0,i1,cc) _bsubi(_jit,i0,r0,i1,cc) +static jit_word_t _bsubi(jit_state_t*,jit_word_t, + jit_int32_t,jit_word_t,jit_bool_t); +#define bsubr_u(i0,r0,r1,cc) _bsubr_u(_jit,i0,r0,r1,cc) +static jit_word_t _bsubr_u(jit_state_t*,jit_word_t, + jit_int32_t,jit_int32_t,jit_bool_t); +#define bsubi_u(i0,r0,i1,cc) _bsubi_u(_jit,i0,r0,i1,cc) +static jit_word_t _bsubi_u(jit_state_t*,jit_word_t, + jit_int32_t,jit_word_t,jit_bool_t); +#define boaddr(i0,r0,r1) baddr(i0,r0,r1,1) +#define boaddi(i0,r0,i1) baddi(i0,r0,i1,1) +#define boaddr_u(i0,r0,r1) baddr_u(i0,r0,r1,1) +#define boaddi_u(i0,r0,i1) baddi_u(i0,r0,i1,1) +#define bxaddr(i0,r0,r1) baddr(i0,r0,r1,0) +#define bxaddi(i0,r0,i1) baddi(i0,r0,i1,0) +#define bxaddr_u(i0,r0,r1) baddr_u(i0,r0,r1,0) +#define bxaddi_u(i0,r0,i1) baddi_u(i0,r0,i1,0) +#define bosubr(i0,r0,r1) bsubr(i0,r0,r1,1) +#define bosubi(i0,r0,i1) bsubi(i0,r0,i1,1) +#define bosubr_u(i0,r0,r1) bsubr_u(i0,r0,r1,1) +#define bosubi_u(i0,r0,i1) bsubi_u(i0,r0,i1,1) +#define bxsubr(i0,r0,r1) bsubr(i0,r0,r1,0) +#define bxsubi(i0,r0,i1) bsubi(i0,r0,i1,0) +#define bxsubr_u(i0,r0,r1) bsubr_u(i0,r0,r1,0) +#define bxsubi_u(i0,r0,i1) bsubi_u(i0,r0,i1,0) +#define ldr_c(r0,r1) _ldr_c(_jit,r0,r1) +static void _ldr_c(jit_state_t*,jit_int32_t,jit_int32_t); +#define ldi_c(r0,i0) _ldi_c(_jit,r0,i0) +static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t); +#define ldr_uc(r0,r1) LD1(r0,r1) +#define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0) +static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t); +#define ldr_s(r0,r1) _ldr_s(_jit,r0,r1) +static void _ldr_s(jit_state_t*,jit_int32_t,jit_int32_t); +#define ldi_s(r0,i0) _ldi_s(_jit,r0,i0) +static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t); +#define ldr_us(r0,r1) LD2(r0,r1) +#define ldi_us(r0,i0) _ldi_us(_jit,r0,i0) +static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t); +#define ldr_i(r0,r1) _ldr_i(_jit,r0,r1) +static void _ldr_i(jit_state_t*,jit_int32_t,jit_int32_t); +#define ldi_i(r0,i0) _ldi_i(_jit,r0,i0) +static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t); +#define ldr_ui(r0,r1) LD4(r0,r1) +#define ldi_ui(r0,i0) _ldi_ui(_jit,r0,i0) +static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t); +#define ldr_l(r0,r1) LD8(r0,r1) +#define ldi_l(r0,i0) _ldi_l(_jit,r0,i0) +static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t); +#define ldxr_c(r0,r1,r2) _ldxr_c(_jit,r0,r1,r2) +static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0) +static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ldxr_uc(r0,r1,r2) _ldxr_uc(_jit,r0,r1,r2) +static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0) +static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ldxr_s(r0,r1,r2) _ldxr_s(_jit,r0,r1,r2) +static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0) +static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ldxr_us(r0,r1,r2) _ldxr_us(_jit,r0,r1,r2) +static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0) +static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ldxr_i(r0,r1,r2) _ldxr_i(_jit,r0,r1,r2) +static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ldxi_i(r0,r1,i0) _ldxi_i(_jit,r0,r1,i0) +static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ldxr_ui(r0,r1,r2) _ldxr_ui(_jit,r0,r1,r2) +static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ldxi_ui(r0,r1,i0) _ldxi_ui(_jit,r0,r1,i0) +static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ldxr_l(r0,r1,r2) _ldxr_l(_jit,r0,r1,r2) +static void _ldxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ldxi_l(r0,r1,i0) _ldxi_l(_jit,r0,r1,i0) +static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define str_c(r0,r1) ST1(r0,r1) +#define sti_c(i0,r0) _sti_c(_jit,i0,r0) +static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t); +#define str_s(r0,r1) ST2(r0,r1) +#define sti_s(i0,r0) _sti_s(_jit,i0,r0) +static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t); +#define str_i(r0,r1) ST4(r0,r1) +#define sti_i(i0,r0) _sti_i(_jit,i0,r0) +static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); +#define str_l(r0,r1) ST8(r0,r1) +#define sti_l(i0,r0) _sti_l(_jit,i0,r0) +static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t); +#define stxr_c(r0,r1,r2) _stxr_c(_jit,r0,r1,r2) +static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define stxi_c(i0,r0,r1) _stxi_c(_jit,i0,r0,r1) +static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define stxr_s(r0,r1,r2) _stxr_s(_jit,r0,r1,r2) +static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define stxi_s(i0,r0,r1) _stxi_s(_jit,i0,r0,r1) +static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define stxr_i(r0,r1,r2) _stxr_i(_jit,r0,r1,r2) +static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define stxi_i(i0,r0,r1) _stxi_i(_jit,i0,r0,r1) +static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define stxr_l(r0,r1,r2) _stxr_l(_jit,r0,r1,r2) +static void _stxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1) +static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define jmpr(r0) _jmpr(_jit,r0) +static void _jmpr(jit_state_t*,jit_int32_t); +#define jmpi(i0) _jmpi(_jit,i0) +static void _jmpi(jit_state_t*,jit_word_t); +#define jmpi_p(i0) _jmpi_p(_jit,i0) +static jit_word_t _jmpi_p(jit_state_t*,jit_word_t); +#define callr(r0) _callr(_jit,r0) +static void _callr(jit_state_t*,jit_int32_t); +#define calli(i0) _calli(_jit,i0) +static void _calli(jit_state_t*,jit_word_t); +#define calli_p(i0) _calli_p(_jit,i0) +static jit_word_t _calli_p(jit_state_t*,jit_word_t); +#define prolog(node) _prolog(_jit,node) +static void _prolog(jit_state_t*,jit_node_t*); +#define epilog(node) _epilog(_jit,node) +static void _epilog(jit_state_t*,jit_node_t*); +# define vastart(r0) _vastart(_jit, r0) +static void _vastart(jit_state_t*, jit_int32_t); +# define vaarg(r0, r1) _vaarg(_jit, r0, r1) +static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t); +#define patch_at(node,instr,label) _patch_at(_jit,node,instr,label) +static void _patch_at(jit_state_t*,jit_code_t,jit_word_t,jit_word_t); +#endif + +#if CODE +#if __BYTE_ORDER == __BIG_ENDIAN +static jit_word_t +byte_swap_if_big_endian(jit_word_t w) +{ + union { + char c[8]; + long w; + } l, h; + l.w = w; + h.c[0] = l.c[7]; + h.c[1] = l.c[6]; + h.c[2] = l.c[5]; + h.c[3] = l.c[4]; + h.c[4] = l.c[3]; + h.c[5] = l.c[2]; + h.c[6] = l.c[1]; + h.c[7] = l.c[0]; + return (h.w); +} +#else +#define byte_swap_if_big_endian(w) (w) +#endif + +static void +_out(jit_state_t *_jit, int n, int tm, + jit_word_t s0, jit_word_t s1, jit_word_t s2) +{ + int i; + jit_word_t l, h, *w; + set_bundle(_jit->pc.ul, l, h, tm, s0, s1, s2); + _jit->pc.ul += 2; + w = (jit_word_t *)_jitc->inst; + for (i = n; i < _jitc->ioff; i++) + w[i - n] = w[i]; + _jitc->ioff -= n; +} + +#define nop_m 0x0008000000L +#define nop_i 0x0008000000L +#define nop_b 0x4000000000L +static void +_stop(jit_state_t *_jit) +{ + /* Clear set of live registers */ + jit_regset_set_ui(&_jitc->regs, 0); + _jitc->pred = 0; + /* Flag a stop is required */ + if (_jitc->ioff) + _jitc->inst[_jitc->ioff - 1].t |= INST_STOP; + else + inst(nop_m, INST_Ms); +} + +static void +_sync(jit_state_t *_jit) +{ + /* Taken branches are supposed to not need a stop, so, it + * should not be required to stop if no registers live in + * sequential code */ + if (jit_regset_cmp_ui(&_jitc->regs, 0) != 0 || _jitc->pred) + stop(); + do + flush(); + while (_jitc->ioff); +} + +#define A_0 INST_A +#define As0 INST_As +#define I_0 INST_I +#define Is0 INST_Is +#define M_0 INST_M +#define Ms0 INST_Ms +#define F_0 INST_F +#define Fs0 INST_Fs +#define B_0 INST_B +#define Bs0 INST_Bs +#define L_0 INST_L +#define Ls0 INST_Ls +#define X_0 INST_X +#define Xs0 INST_Xs +#define A_1 (INST_A<<4) +#define As1 (INST_As<<4) +#define I_1 (INST_I<<4) +#define Is1 (INST_Is<<4) +#define M_1 (INST_M<<4) +#define Ms1 (INST_Ms<<4) +#define F_1 (INST_F<<4) +#define Fs1 (INST_Fs<<4) +#define B_1 (INST_B<<4) +#define Bs1 (INST_Bs<<4) +#define L_1 (INST_L<<4) +#define Ls1 (INST_Ls<<4) +#define X_1 (INST_X<<4) +#define Xs1 (INST_Xs<<4) +#define A_2 (INST_A<<8) +#define As2 (INST_As<<8) +#define I_2 (INST_I<<8) +#define Is2 (INST_Is<<8) +#define M_2 (INST_M<<8) +#define Ms2 (INST_Ms<<8) +#define F_2 (INST_F<<8) +#define Fs2 (INST_Fs<<8) +#define B_2 (INST_B<<8) +#define Bs2 (INST_Bs<<8) +#define L_2 (INST_L<<8) +#define Ls2 (INST_Ls<<8) +#define X_2 (INST_X<<8) +#define Xs2 (INST_Xs<<8) + +#define I_ I_0 +#define I_I_ I_0|I_1 +#define I_Is I_0|Is1 +#define I_B_ I_0|B_1 +#define I_Bs I_0|Bs1 +#define Is Is0 +#define IsI_ Is0|I_1 +#define IsIs Is0|Is1 +#define M_ M_0 +#define M_I_ M_0|I_1 +#define M_Is M_0|Is1 +#define M_M_ M_0|M_1 +#define M_Ms M_0|Ms1 +#define M_F_ M_0|F_1 +#define M_Fs M_0|Fs1 +#define M_B_ M_0|B_1 +#define M_Bs M_0|Bs1 +#define M_I_I_ M_0|I_1|I_2 +#define M_I_Is M_0|I_1|Is2 +#define M_I_B_ M_0|I_1|B_2 +#define M_I_Bs M_0|I_1|Bs2 +#define M_IsI_ M_0|Is1|I_2 +#define M_IsIs M_0|Is1|Is2 +#define M_M_I_ M_0|M_1|I_2 +#define M_M_Is M_0|M_1|Is2 +#define M_M_F_ M_0|M_1|F_2 +#define M_M_Fs M_0|M_1|Fs2 +#define M_M_B_ M_0|M_1|B_2 +#define M_M_Bs M_0|M_1|Bs2 +#define M_F_I_ M_0|F_1|I_2 +#define M_F_Is M_0|F_1|Is2 +#define M_F_B_ M_0|F_1|B_2 +#define M_F_Bs M_0|F_1|Bs2 +#define M_B_B_ M_0|B_1|B_2 +#define M_B_Bs M_0|B_1|Bs2 +#define M_L_X_ M_0|L_1|X_2 +#define M_L_Xs M_0|L_1|Xs2 +#define Ms Ms0 +#define MsI_ Ms0|I_1 +#define MsIs Ms0|Is1 +#define MsM_ Ms0|M_1 +#define MsMs Ms0|Ms1 +#define MsM_I_ Ms0|M_1|I_2 +#define MsM_Is Ms0|M_1|Is2 +#define F_ F_0 +#define F_I_ F_0|I_1 +#define F_Is F_0|Is1 +#define F_B_ F_0|B_1 +#define F_Bs F_0|Bs1 +#define Fs Fs0 +#define B_ B_0 +#define B_B_ B_0|B_1 +#define B_Bs B_0|Bs1 +#define B_B_B_ B_0|B_1|B_2 +#define B_B_Bs B_0|B_1|Bs2 +#define Bs Bs0 +#define L_X_ L_0|X_1 +#define L_Xs L_0|Xs1 + +static jit_word_t +templat(jit_word_t cc) +{ + switch (cc) { + case I_: + case I_I_: case I_Is: + case I_B_: case I_Bs: + case Is: + case IsI_: case IsIs: + case M_: + case M_I_: case M_Is: + case M_M_: case M_Ms: + case M_F_: case M_Fs: + case M_B_: case M_Bs: + case M_I_I_: case M_I_Is: + case M_I_B_: case M_I_Bs: + case M_IsI_: case M_IsIs: + case M_M_I_: case M_M_Is: + case M_M_F_: case M_M_Fs: + case M_M_B_: case M_M_Bs: + case M_F_I_: case M_F_Is: + case M_F_B_: case M_F_Bs: + case M_B_B_: case M_B_Bs: + case M_L_X_: case M_L_Xs: + case Ms: + case MsI_: case MsIs: + case MsM_: case MsMs: + case MsM_I_: case MsM_Is: + case F_: + case F_I_: case F_Is: + case F_B_: case F_Bs: + case Fs: + case B_: + case B_B_: case B_Bs: + case B_B_B_: case B_B_Bs: + case Bs: + case L_X_: case L_Xs: + return (cc); + default: + return (0); + } +} + +/* match* functions recurse attempting to find a template for A- + * instructions, that may be executed in M- or I- unit. + * It also uses an heuristic of trying first M- for slot 0 and 2, + * and I- for slot 1, but tries all possible matches. + */ +static jit_word_t +match_2(jit_word_t cc) +{ + jit_word_t t; + if ((t = templat(cc | M_2))) + return (t); + if ((t = templat(cc | I_2))) + return (t); + return (0); +} + +static jit_word_t +matchs2(jit_word_t cc) +{ + jit_word_t t; + if ((t = templat(cc | Ms2))) + return (t); + if ((t = templat(cc | Is2))) + return (t); + return (0); +} + +static jit_word_t +match2(jit_word_t cc) +{ + if ((cc & 0xf00) == A_2) + return (match_2(cc & ~0xf00)); + if ((cc & 0xf00) == As2) + return (matchs2(cc & ~0xf00)); + return (0); +} + +static jit_word_t +match_1(jit_word_t cc) +{ + jit_word_t t; + if ((t = templat(cc | I_1))) + return (t); + if ((t = templat(cc | M_1))) + return (t); + if ((t = match2(cc | I_1))) + return (t); + if ((t = match2(cc | M_1))) + return (t); + return (0); +} + +static jit_word_t +matchs1(jit_word_t cc) +{ + jit_word_t t; + if ((t = templat(cc | Is1))) + return (t); + if ((t = templat(cc | Ms1))) + return (t); + if ((t = match2(cc | Is1))) + return (t); + if ((t = match2(cc | Ms1))) + return (t); + return (0); +} + +static jit_word_t +match1(jit_word_t cc) +{ + if ((cc & 0x0f0) == A_1) + return (match_1(cc & ~0x0f0)); + if ((cc & 0x0f0) == As1) + return (matchs1(cc & ~0x0f0)); + return (0); +} + +static jit_word_t +match_0(jit_word_t cc) +{ + jit_word_t t; + if ((t = templat(cc | M_0))) + return (t); + if ((t = templat(cc | I_0))) + return (t); + if ((t = match1(cc | M_0))) + return (t); + if ((t = match1(cc | I_0))) + return (t); + return (0); +} + +static jit_word_t +matchs0(jit_word_t cc) +{ + jit_word_t t; + if ((t = templat(cc | Ms0))) + return (t); + if ((t = templat(cc | Is0))) + return (t); + if ((t = match1(cc | Ms0))) + return (t); + if ((t = match1(cc | Is0))) + return (t); + return (0); +} + +static jit_word_t +match0(jit_word_t cc) +{ + if ((cc & 0x00f) == A_0) + return (match_0(cc & ~0x00f)); + if ((cc & 0x00f) == As0) + return (matchs0(cc & ~0x00f)); + return (0); +} + +static void +_flush(jit_state_t *_jit) +{ + int n, soff; + jit_word_t t, cc, tm, s0, s1, s2; + + if (!_jitc->ioff) + return; + for (cc = 0, n = soff = 0; n < _jitc->ioff; n++, soff += 4) + cc |= (jit_uword_t)(_jitc->inst[n].t) << soff; + + soff = 0xf00; + while (soff) { + /* Try to find a template, or reduce down + * to one instruction if no template match */ + if ((t = templat(cc))) { + cc = t; + break; + } + /* A- instructions may be execute in M- or I- unit */ + if ((t = match0(cc))) { + cc = t; + break; + } + cc &= ~soff; + soff >>= 4; + } + assert(soff); + + /* Prefer tail nop if need to add some nop, so that patching is easier */ +#define ii(n) _jitc->inst[n].i + switch (cc) { + case I_: + n = 1; tm = TM_M_I_I_; + s0 = nop_m; s1 = ii(0); s2 = nop_i; + break; + case I_I_: + n = 2; tm = TM_M_I_I_; + s0 = nop_m; s1 = ii(0); s2 = ii(1); + break; + case I_Is: + n = 2; tm = TM_M_I_Is; + s0 = nop_m; s1 = ii(0); s2 = ii(1); + break; + case I_B_: + n = 2; tm = TM_M_I_B_; + s0 = nop_m; s1 = ii(0); s2 = ii(1); + break; + case I_Bs: + n = 2; tm = TM_M_I_Bs; + s0 = nop_m; s1 = ii(0); s2 = ii(1); + break; + case Is: + n = 1; tm = TM_M_IsI_; + s0 = nop_m; s1 = ii(0); s2 = nop_i; + break; + case IsI_: + n = 2; tm = TM_M_IsI_; + s0 = nop_m; s1 = ii(0); s2 = ii(1); + break; + case IsIs: + n = 2; tm = TM_M_IsIs; + s0 = nop_m; s1 = ii(0); s2 = ii(1); + break; + case M_: + n = 1; tm = TM_M_I_I_; + s0 = ii(0); s1 = nop_i; s2 = nop_i; + break; + case M_I_: + n = 2; tm = TM_M_I_I_; + s0 = ii(0); s1 = ii(1); s2 = nop_i; + break; + case M_Is: + n = 2; tm = TM_M_IsI_; + s0 = ii(0); s1 = ii(1); s2 = nop_i; + break; + case M_M_: + n = 2; tm = TM_M_M_I_; + s0 = ii(0); s1 = ii(1); s2 = nop_i; + break; + case M_Ms: + n = 2; tm = TM_M_M_Is; + s0 = ii(0); s1 = ii(1); s2 = nop_i; + break; + case M_F_: + n = 2; tm = TM_M_F_I_; + s0 = ii(0); s1 = ii(1); s2 = nop_i; + break; + case M_Fs: + n = 2; tm = TM_M_F_Is; + s0 = ii(0); s1 = ii(1); s2 = nop_i; + break; + case M_B_: + n = 2; tm = TM_M_B_B_; + s0 = ii(0); s1 = ii(1); s2 = nop_b; + break; + case M_Bs: + n = 2; tm = TM_M_B_Bs; + s0 = ii(0); s1 = ii(1); s2 = nop_b; + break; + case M_I_I_: + n = 3; tm = TM_M_I_I_; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_I_Is: + n = 3; tm = TM_M_I_Is; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_I_B_: + n = 3; tm = TM_M_I_B_; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_I_Bs: + n = 3; tm = TM_M_I_Bs; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_IsI_: + n = 3; tm = TM_M_IsI_; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_IsIs: + n = 3; tm = TM_M_IsIs; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_M_I_: + n = 3; tm = TM_M_M_I_; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_M_Is: + n = 3; tm = TM_M_M_Is; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_M_F_: + n = 3; tm = TM_M_M_F_; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_M_Fs: + n = 3; tm = TM_M_M_Fs; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_M_B_: + n = 3; tm = TM_M_M_B_; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_M_Bs: + n = 3; tm = TM_M_M_Bs; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_F_I_: + n = 3; tm = TM_M_F_I_; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_F_Is: + n = 3; tm = TM_M_F_Is; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_F_B_: + n = 3; tm = TM_M_F_B_; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_F_Bs: + n = 3; tm = TM_M_F_Bs; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_B_B_: + n = 3; tm = TM_M_B_B_; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_B_Bs: + n = 3; tm = TM_M_B_Bs; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_L_X_: + n = 3; tm = TM_M_L_X_; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case M_L_Xs: + n = 3; tm = TM_M_L_Xs; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case Ms: + n = 1; tm = TM_MsM_I_; + s0 = ii(0); s1 = nop_m; s2 = nop_i; + break; + case MsI_: + n = 2; tm = TM_MsM_I_; + s0 = ii(0); s1 = nop_m; s2 = ii(1); + break; + case MsIs: + n = 2; tm = TM_MsM_Is; + s0 = ii(0); s1 = nop_m; s2 = ii(1); + break; + case MsM_: + n = 2; tm = TM_MsM_I_; + s0 = ii(0); s1 = ii(1); s2 = nop_i; + break; + case MsMs: + n = 2; tm = TM_MsM_Is; + s0 = ii(0); s1 = ii(1); s2 = nop_i; + break; + case MsM_I_: + n = 3; tm = TM_MsM_I_; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case MsM_Is: + n = 3; tm = TM_MsM_Is; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case F_: + n = 1; tm = TM_M_F_I_; + s0 = nop_m; s1 = ii(0); s2 = nop_i; + break; + case F_I_: + n = 2; tm = TM_M_F_I_; + s0 = nop_m; s1 = ii(0); s2 = ii(1); + break; + case F_Is: + n = 2; tm = TM_M_F_Is; + s0 = nop_m; s1 = ii(0); s2 = ii(1); + break; + case F_B_: + n = 2; tm = TM_M_F_B_; + s0 = nop_m; s1 = ii(0); s2 = ii(1); + break; + case F_Bs: + n = 2; tm = TM_M_F_Bs; + s0 = nop_m; s1 = ii(0); s2 = ii(1); + break; + case Fs: + n = 1; tm = TM_M_F_Is; + s0 = nop_m; s1 = ii(0); s2 = nop_i; + break; + case B_: + n = 1; tm = TM_B_B_B_; + s0 = ii(0); s1 = nop_b; s2 = nop_b; + break; + case B_B_: + n = 2; tm = TM_B_B_B_; + s0 = ii(0); s1 = ii(1); s2 = nop_b; + break; + case B_Bs: + n = 2; tm = TM_B_B_Bs; + s0 = ii(0); s1 = ii(1); s2 = nop_b; + break; + case B_B_B_: + n = 3; tm = TM_B_B_B_; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case B_B_Bs: + n = 3; tm = TM_B_B_Bs; + s0 = ii(0); s1 = ii(1); s2 = ii(2); + break; + case Bs: + n = 1; tm = TM_B_B_Bs; + s0 = ii(0); s1 = nop_b; s2 = nop_b; + break; + case L_X_: + n = 2; tm = TM_M_L_X_; + s0 = nop_m; s1 = ii(0); s2 = ii(1); + break; + case L_Xs: + n = 2; tm = TM_M_L_Xs; + s0 = nop_m; s1 = ii(0); s2 = ii(1); + break; + default: + abort(); + } + out(n, tm, s0, s1, s2); +} + +static void +_inst(jit_state_t *_jit, jit_word_t i, jit_uint8_t t) +{ + if (_jitc->ioff > 2) + flush(); + assert(!(i & 0x11111e0000000000L)); + _jitc->inst[_jitc->ioff].i = i; + _jitc->inst[_jitc->ioff].t = t; + ++_jitc->ioff; +} + +static void +_A1(jit_state_t *_jit, jit_word_t _p, + jit_word_t x4, jit_word_t x2, jit_word_t r3, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x4 & ~0xfL)); + assert(!(x2 & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + TSTREG1(r1); + inst((8L<<37)|(x4<<29)|(x2<<27)|(r3<<20)|(r2<<13)|(r1<<6)|_p, INST_A); + SETREG(r1); +} + +static void +_A3(jit_state_t *_jit, jit_word_t _p, + jit_word_t x4, jit_word_t x2, jit_word_t r3, jit_word_t im, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x4 & ~0xfL)); + assert(!(x2 & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(im >= -128 && im <= 127); + assert(!(r1 & ~0x7f)); + TSTREG1(r3); + TSTPRED(_p); + TSTREG1(r1); + inst((8L<<37)|(((im>>7)&1L)<<36)|(x4<<29)|(x2<<27)| + (r3<<20)|((im&0x7fL)<<13)|(r1<<6)|_p, INST_A); + SETREG(r1); +} + +static void +_A4(jit_state_t *_jit, jit_word_t _p, + jit_word_t x2, jit_word_t r3, jit_word_t im, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x2 & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(im >= -8192 && im <= 8191); + assert(!(r1 & ~0x7f)); + TSTREG1(r3); + TSTPRED(_p); + TSTREG1(r1); + inst((8L<<37)|(((im>>13)&1L)<<36)|(x2<<34)|(((im>>7)&0x3fL)<<27)| + (r3<<20)|((im&0x7fL)<<13)|(r1<<6)|_p, INST_A); + SETREG(r1); +} + +static void +_A5(jit_state_t *_jit, jit_word_t _p, + jit_word_t r3, jit_word_t im, jit_word_t r1) +{ + jit_word_t s, i5, i9, i7; + assert(!(_p & ~0x3fL)); + assert(!(r3 & ~0x3L)); + assert(im >= -2097152 && im <= 2097151); + assert(!(r1 & ~0x7fL)); + /* imm22 = sign_ext(s << 21 | imm5c << 16 | imm9d << 7 | imm7b, 22) */ + s = (im & 0x200000) >> 21; + i5 = (im & 0x1f0000) >> 16; + i9 = (im & 0xff80) >> 7; + i7 = im & 0x7f; + TSTREG1(r3); + TSTPRED(_p); + TSTREG1(r1); + inst((9L<<37)|(s<<36)|(i9<<27)|(i5<<22)| + (r3<<20)|(i7<<13)|(r1<<6)|_p, INST_A); + SETREG(r1); +} + +static void +_A6(jit_state_t *_jit, jit_word_t _p, + jit_word_t o, jit_word_t x2, jit_word_t ta, jit_word_t p2, + jit_word_t r3, jit_word_t r2, jit_word_t c, jit_word_t p1) +{ + assert(!(_p & ~0x3fL)); + assert(!(o & ~0xfL)); + assert(!(x2 & ~0x3L)); + assert(!(ta & ~0x1L)); + assert(!(p2 & ~0x7fL)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(!(c & ~0x1L)); + assert(!(p1 & ~0x3fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + inst((o<<37)|(x2<<34)|(ta<<33)|(p2<<27)|(r3<<20)| + (r2<<13)|(c<<12)|(p1<<6)|_p, INST_A); + if (p1) + _jitc->pred |= 1 << p1; + if (p2) + _jitc->pred |= 1 << p2; +} + +static void +_A7(jit_state_t *_jit, jit_word_t _p, + jit_word_t o, jit_word_t x2, jit_word_t ta, + jit_word_t p2, jit_word_t r3, jit_word_t c, jit_word_t p1) +{ + assert(!(_p & ~0x3fL)); + assert(!(o & ~0xfL)); + assert(!(x2 & ~0x3L)); + assert(!(ta & ~0x1L)); + assert(!(p2 & ~0x7fL)); + assert(!(r3 & ~0x7fL)); + assert(!(c & ~0x1L)); + assert(!(p1 & ~0x3fL)); + TSTREG1(r3); + TSTPRED(_p); + inst((o<<37)|(1L<<36)|(x2<<34)|(ta<<33)| + (p2<<27)|(r3<<20)|(c<<12)|(p1<<6)|_p, INST_A); + if (p1) + _jitc->pred |= 1 << p1; + if (p2) + _jitc->pred |= 1 << p2; +} + +static void +_A8(jit_state_t *_jit, jit_word_t _p, + jit_word_t o, jit_word_t x2, jit_word_t ta, jit_word_t p2, + jit_word_t r3, jit_word_t im, jit_word_t c, jit_word_t p1) +{ + assert(!(_p & ~0x3fL)); + assert(!(o & ~0xfL)); + assert(!(x2 & ~0x3L)); + assert(!(ta & ~0x1L)); + assert(!(p2 & ~0x7fL)); + assert(!(r3 & ~0x7fL)); + assert(im >= -128 && im <= 127); + assert(!(c & ~0x1L)); + assert(!(p1 & ~0x3fL)); + TSTREG1(r3); + TSTPRED(_p); + inst((o<<37)|(((im>>7)&1L)<<36)|(x2<<34)|(ta<<33)|(p2<<27)|(r3<<20)| + ((im&0x7fL)<<13)|(c<<12)|(p1<<6)|_p, INST_A); + if (p1) + _jitc->pred |= 1 << p1; + if (p2) + _jitc->pred |= 1 << p2; +} + +static void +_A9(jit_state_t *_jit, jit_word_t _p, + jit_word_t za, jit_word_t zb, jit_word_t x4, + jit_word_t x2, jit_word_t r3, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(za & ~0x1L)); + assert(!(zb & ~0x1L)); + assert(!(x4 & ~0xfL)); + assert(!(x2 & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + TSTREG1(r1); + inst((8L<<37)|(za<<36)|(1L<<34)|(zb<<33)|(x4<<29)|(x2<<27)| + (r3<<20)|(r2<<13)|(r1<<6)|_p, INST_A); + SETREG(r1); +} + +static void +_I1(jit_state_t *_jit, jit_word_t _p, + jit_word_t ct, jit_word_t x2, jit_word_t r3, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(ct & ~0x3L)); + assert(!(x2 & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + TSTREG1(r1); + inst((7L<<37)|(1L<<33)|(ct<<30)|(x2<<28)| + (r3<<20)|(r2<<13)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I2(jit_state_t *_jit, jit_word_t _p, + jit_word_t za, jit_word_t xa, jit_word_t zb, jit_word_t xc, + jit_word_t xb ,jit_word_t r3, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(za & ~0x1L)); + assert(!(xa & ~0x3L)); + assert(!(zb & ~0x1L)); + assert(!(xc & ~0x3L)); + assert(!(xb & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + TSTREG1(r1); + inst((7L<<37)|(za<<36)|(xa<<34)|(zb<<33)|(xc<<30)| + (xb<<28)|(r3<<20)|(r2<<13)|(r1<<6), INST_I); + SETREG(r1); +} + +static void +_I3(jit_state_t *_jit, jit_word_t _p, + jit_word_t mb, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(mb & ~0xfL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG1(r2); + TSTPRED(_p); + TSTREG1(r1); + inst((7L<<37)|(3L<<34)|(2L<<30)|(2L<<28)| + (mb<<20)|(r2<<13)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I4(jit_state_t *_jit, jit_word_t _p, + jit_word_t mh, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(mh & ~0xffL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG1(r2); + TSTPRED(_p); + TSTREG1(r1); + inst((7L<<37)|(3L<<34)|(1L<<33)|(2L<<30)| + (2L<<28)|(mh<<20)|(r2<<13)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I5(jit_state_t *_jit, jit_word_t _p, + jit_word_t za, jit_word_t zb, jit_word_t x2, + jit_word_t r3, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(za & ~0x1L)); + assert(!(zb & ~0x1L)); + assert(!(x2 & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + TSTREG1(r1); + inst((7L<<37)|(za<<36)|(zb<<33)|(x2<<28)| + (r3<<20)|(r2<<13)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I6(jit_state_t *_jit, jit_word_t _p, + jit_word_t za, jit_word_t zb, jit_word_t x2, + jit_word_t r3, jit_word_t ct, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(za & ~0x1L)); + assert(!(zb & ~0x1L)); + assert(!(x2 & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(ct & ~0x1fL)); + assert(!(r1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + TSTREG1(r1); + inst((7L<<37)|(za<<36)|(1L<<34)|(zb<<33)| + (x2<<28)|(r3<<20)|(ct<<14)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I7(jit_state_t *_jit, jit_word_t _p, + jit_word_t za, jit_word_t zb, jit_word_t r3, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(za & ~0x1L)); + assert(!(zb & ~0x1L)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + TSTREG1(r1); + inst((7L<<37)|(za<<36)|(zb<<33)|(1L<<30)| + (r3<<20)|(r2<<13)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I8(jit_state_t *_jit, jit_word_t _p, + jit_word_t za, jit_word_t zb, jit_word_t im, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(za & ~0x1L)); + assert(!(zb & ~0x1L)); + assert(!(im & ~0x1fL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG1(r2); + TSTPRED(_p); + TSTREG1(r1); + inst((7L<<37)|(za<<36)|(3L<<34)|(zb<<33)|(1L<<30)|(1L<<28)| + (im<<20)|(r2<<13)|(r1<<6), INST_I); + SETREG(r1); +} + +static void +_I9(jit_state_t *_jit, jit_word_t _p, + jit_word_t x2, jit_word_t r3, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x2 & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + TSTREG1(r1); + inst((7L<<37)|(1L<<34)|(1L<<34)|(1L<<33)| + (x2<<30)|(1L<<28)|(r3<<20)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I10(jit_state_t *_jit, jit_word_t _p, + jit_word_t ct, jit_word_t r3, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(ct & ~0x3fL)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + TSTREG1(r1); + inst((5L<<37)|(3L<<34)|(ct<<27)|(r3<<20)|(r2<<13)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I11(jit_state_t *_jit, jit_word_t _p, + jit_word_t len, jit_word_t r3, + jit_word_t pos, jit_word_t y, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(len & ~0x3fL)); + assert(!(r3 & ~0x7fL)); + assert(!(pos & ~0x1fL)); + assert(!(y & ~0x1L)); + assert(!(r1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + TSTREG1(r1); + inst((5L<<37)|(1L<<34)|(len<<27)|(r3<<20)| + (pos<<14)|(y<<13)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I12(jit_state_t *_jit, jit_word_t _p, + jit_word_t len, jit_word_t pos, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(len & ~0x3fL)); + assert(!(pos & ~0x3fL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG1(r2); + TSTPRED(_p); + TSTREG1(r1); + inst((5L<<37)|(1L<<34)|(1L<<33)|(len<<27)| + (pos<<20)|(r2<<13)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I13(jit_state_t *_jit, jit_word_t _p, + jit_word_t len, jit_word_t pos, jit_word_t im, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(len & ~0x3fL)); + assert(!(pos & ~0x3fL)); + assert(!(im & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTPRED(_p); + TSTREG1(r1); + inst((5L<<37)|(((im>>7)&1L)<<36)|(1L<<34)|(1L<<33)|(len<<27)| + (1L<<26)|(pos<<20)|((im&0x7fL)<<13)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I14(jit_state_t *_jit, jit_word_t _p, + jit_word_t s, jit_word_t len, jit_word_t r3, jit_word_t pos, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(s & ~0x1L)); + assert(!(len & ~0x3fL)); + assert(!(r3 & ~0x7fL)); + assert(!(pos & ~0x1fL)); + assert(!(r1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + TSTREG1(r1); + inst((5L<<37)|(s<<36)|(3L<<34)|(1L<<33)| + (len<<27)|(r3<<20)|(pos<<14)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I15(jit_state_t *_jit, jit_word_t _p, + jit_word_t pos, jit_word_t len, + jit_word_t r3, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(pos & ~0x3fL)); + assert(!(len & ~0xfL)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + TSTREG1(r1); + inst((4L<<37)|(pos<<31)|(len<<27)|(r3<<20)|(r2<<13)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I16(jit_state_t *_jit, jit_word_t _p, + jit_word_t tb, jit_word_t ta, jit_word_t p2, + jit_word_t r3, jit_word_t ps, jit_word_t c, jit_word_t p1) +{ + assert(!(_p & ~0x3fL)); + assert(!(tb & ~0x1L)); + assert(!(ta & ~0x1L)); + assert(!(p2 & ~0x7fL)); + assert(!(r3 & ~0x7fL)); + assert(!(ps & ~0x3fL)); + assert(!(c & ~0x1L)); + assert(!(p1 & ~0x3fL)); + TSTREG1(r3); + TSTPRED(_p); + inst((5L<<37)|(tb<<36)|(ta<<33)|(p2<<27)| + (r3<<20)|(ps<<14)|(c<<12)|(p1<<6), INST_I); + if (p1) + _jitc->pred |= 1 << p1; + if (p2) + _jitc->pred |= 1 << p2; +} + +static void +_I17(jit_state_t *_jit, jit_word_t _p, + jit_word_t tb, jit_word_t ta, jit_word_t p2, + jit_word_t r3, jit_word_t c, jit_word_t p1) +{ + assert(!(_p & ~0x3fL)); + assert(!(tb & ~0x1L)); + assert(!(ta & ~0x1L)); + assert(!(p2 & ~0x7fL)); + assert(!(r3 & ~0x7fL)); + assert(!(c & ~0x1L)); + assert(!(p1 & ~0x3fL)); + TSTREG1(r3); + TSTPRED(_p); + inst((5L<<37)|(tb<<36)|(ta<<33)|(p2<<27)| + (r3<<20)|(1L<<13)|(c<<12)|(p1<<6)|_p, INST_I); + if (p1) + _jitc->pred |= 1 << p1; + if (p2) + _jitc->pred |= 1 << p2; +} + +static void +_I18(jit_state_t *_jit, jit_word_t _p, + jit_word_t im, jit_word_t y) +{ + assert(!(_p & ~0x3fL)); + assert(!(im & ~0x1fffffL)); + assert(!(y & ~0x1L)); + TSTPRED(_p); + inst((((im>>20)&1L)<<26)|(1L<<27)|(y<<26)|((im&0xffffL)<<6)|_p, INST_I); +} + +static void +_I19(jit_state_t *_jit, jit_word_t _p, + jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(im & ~0x1fffffL)); + TSTPRED(_p); + inst(((im>>20)&1L)|((im&0xffffL)<<6)|_p, INST_I); +} + +static void +_I20(jit_state_t *_jit, jit_word_t _p, + jit_word_t r2, jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(r2 & ~0x7fL)); + assert(!(im & ~0x1fffffL)); + TSTREG1(r2); + TSTPRED(_p); + inst(((im>>20)&1L)|(1L<<33)|(((im>>7)&0x1fffL)<<20)| + (r2<<13)|((im&0x7fL)<<6)|_p, INST_I); +} + +static void +_I21(jit_state_t *_jit, jit_word_t _p, + jit_word_t im, jit_word_t ih, jit_word_t x, + jit_word_t wh, jit_word_t r2, jit_word_t b1) +{ + assert(!(_p & ~0x3fL)); + assert(!(im & ~0x1ffL)); + assert(!(ih & ~0x1L)); + assert(!(x & ~0x1L)); + assert(!(wh & ~0x3L)); + assert(!(r2 & ~0x7fL)); + assert(!(b1 & ~0x7L)); + TSTREG1(r2); + TSTPRED(_p); + inst((7L<<33)|(im<<24)|(ih<<23)|(x<<22)|(wh<<20)| + (r2<<13)|(b1<<6), INST_I); +} + +static void +_I22(jit_state_t *_jit, jit_word_t _p, + jit_word_t b2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(b2 & ~0x7L)); + assert(!(r1 & ~0x7fL)); + TSTPRED(_p); + inst((0x31L<<27)|(b2<<13)|(r1<<6)|_p, INST_I); +} + +static void +_I23(jit_state_t *_jit, jit_word_t _p, + jit_word_t r2, jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(r2 & ~0x7fL)); + assert(!(im & ~0xffffL)); + TSTREG1(r2); + TSTPRED(_p); + inst((((im>>15)&1L)<<36)|(3L<<33)|(((im>>7)&0xffL)<<24)| + (r2<<13)|(im&0x7fL)|_p, INST_I); +} + +static void +_I24(jit_state_t *_jit, jit_word_t _p, + jit_word_t im) +{ + jit_uint8_t cc = INST_I; + assert(!(_p & ~0x3fL)); + assert(!(im & ~0xfffffffL)); + TSTPRED(_p); + inst((((im>>27)&1L)<<36)|(2L<<33)|((im&0x7ffffffL)<<6)|_p, cc); +} + +static void +_I25(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(r1 & ~0x7fL)); + TSTPRED(_p); + TSTREG1(r1); + inst((x6<<27)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I26(jit_state_t *_jit, jit_word_t _p, + jit_word_t ar,jit_word_t r2) +{ + assert(!(_p & ~0x3fL)); + assert(!(ar & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + TSTREG1(r2); + TSTPRED(_p); + inst((0x2aL<<27)|(ar<<20)|(r2<<13)|_p, INST_I); +} + +static void +_I27(jit_state_t *_jit, jit_word_t _p, + jit_word_t ar,jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(ar & ~0x7fL)); + assert(!(im & ~0xffL)); + TSTPRED(_p); + inst((((im>>7)&1L)<<36)|(0xaL<<27)|(ar<<20)|((im&0x7fL)<<13)|_p, INST_I); +} + +static void +_I28(jit_state_t *_jit, jit_word_t _p, + jit_word_t ar, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(ar & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTPRED(_p); + TSTREG1(r1); + inst((0x32L<<27)|(ar<<20)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I29(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t r3,jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(r3 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + TSTREG1(r1); + inst((x6<<27)|(r3<<20)|(r1<<6)|_p, INST_I); + SETREG(r1); +} + +static void +_I30(jit_state_t *_jit, jit_word_t _p, + jit_word_t ta, jit_word_t tb, jit_word_t p2, + jit_word_t im, jit_word_t c, jit_word_t p1) +{ + assert(!(_p & ~0x3fL)); + assert(!(ta & ~0x1L)); + assert(!(tb & ~0x1L)); + assert(!(p2 & ~0x3fL)); + assert(!(im & ~0x1fL)); + assert(!(c & ~0x1L)); + assert(!(p1 & ~0x1fL)); + TSTPRED(_p); + inst((5L<<37)|(tb<<36)|(ta<<33)|(1L<<19)|(im<<14)| + (1L<<13)|(c<<12)|(p1<<6)|_p, INST_I); + if (p1) + _jitc->pred |= 1 << p1; + if (p2) + _jitc->pred |= 1 << p2; +} + +static void +_M1(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t x, jit_word_t r3, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(x & ~0x1L)); + assert(!(r3 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + TSTREG1(r1); + inst((4L<<37)|(x6<<30)|(ht<<28)|(x<<27)|(r3<<20)|(r1<<6)|_p, INST_M); + SETREG(r1); +} + +static void +_M2(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + TSTREG1(r1); + inst((4L<<37)|(1L<<36)|(x6<<30)|(ht<<28)| + (r3<<20)|(r2<<13)|(r1<<6)|_p, INST_M); + SETREG(r1); + SETREG(r3); +} + +static void +_M3(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t im, jit_word_t r1) +{ + jit_uint8_t cc = INST_M; + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(im > -256 && im <= 255); + assert(!(r1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + TSTREG1(r1); + inst((5L<<37)|(((im>>8)&1L)<<36)|(x6<<30)|(ht<<28)| + (((im>>7)&1L)<<27)|(r3<<20)|((im&0x7fL)<<13)|(r1<<6)|_p, cc); + SETREG(r1); + SETREG(r3); +} + +static void +_M5(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t r2, jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(im > -256 && im <= 255); + TSTREG2(r2, r3); + TSTPRED(_p); + inst((5L<<37)|(((im>>8)&1L)<<36)|(x6<<30)|(ht<<28)| + (((im>>7)&1L)<<27)|(r3<<20)|(r2<<13)|((im&0x7fL)<<6)|_p, INST_M); + SETREG(r3); +} + +static void +_M6(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t x, jit_word_t r3, jit_word_t r2) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(x & ~0x1L)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + inst((4L<<37)|(x6<<30)|(ht<<28)|(x<<27)|(r3<<20)|(r2<<13)|_p, INST_M); +} + +static void +_M13(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t r2) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + TSTREG1(r3); + if (r2) + TSTFREG1(r2); + TSTPRED(_p); + inst((6L<<37)|(x6<<30)|(ht<<28)|(r3<<20)|(r2<<13)|_p, INST_M); +} + +static void +_M14(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t r2) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + inst((6L<<37)|(1L<<36)|(x6<<30)|(ht<<28)|(r3<<20)|(r2<<13)|_p, INST_M); +} + +static void +_M15(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(im & ~0x1ffL)); + TSTREG1(r3); + TSTPRED(_p); + inst((7L<<37)|(((im>>8)&1L)<<36)|(x6<<30)|(ht<<28)| + (((im>>7)&1L)<<27)|(r3<<20)|((im&0x7fL)<<13)|_p, INST_M); +} + +static void +_M16(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + TSTREG1(r1); + inst((4L<<37)|(x6<<30)|(ht<<28)|(1L<<27)| + (r3<<20)|(r2<<13)|(r1<<6)|_p, INST_M); + SETREG(r1); +} + +static void +_M17(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t im, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(im & ~0x7L)); + assert(!(r1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + TSTREG1(r1); + inst((4L<<37)|(x6<<30)|(ht<<28)|(1L<<27)| + (r3<<20)|(im<<13)|(r1<<6)|_p, INST_M); + SETREG(r1); +} + +static void +_M20x(jit_state_t *_jit, jit_word_t _p, + jit_word_t x3, jit_word_t r2, jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(x3 & ~0x7L)); + assert(!(r2 & ~0x7fL)); + assert(!(im & ~0x1fffffL)); + if (x3 == 1) + TSTREG1(r2); + else + TSTFREG1(r2); + TSTPRED(_p); + inst((1L<<37)|(((im>>20)&1L)<<36)|(x3<<33)| + (((im>>7)&0x1fffL)<<20)|(r2<<13)|((im&0x7fL)<<6)|_p, INST_M); +} + +static void +_M22x(jit_state_t *_jit, jit_word_t _p, + jit_word_t x3, jit_word_t im, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x3 & ~0x7L)); + assert(!(im & ~0x1fffffL)); + assert(!(r1 & ~0x7fL)); + TSTPRED(_p); + if (x3 < 6) + TSTREG1(r1); + else + TSTFREG1(r1); + inst((((im>>20)&1L)<<36)|(x3<<33)|((im&0xffffL)<<13)|(r1<<6)|_p, INST_M); + if (x3 < 6) + SETREG(r1); + else + SETFREG(r1); +} + +static void +_M24(jit_state_t *_jit, jit_word_t _p, + jit_word_t x2, jit_word_t x4) +{ + assert(!(_p & ~0x3fL)); + assert(!(x2 & ~0x3L)); + assert(!(x4 & ~0xfL)); + TSTPRED(_p); + inst((x2<<31)|(x4<<27)|_p, INST_M); +} + +static void +_M26x(jit_state_t *_jit, jit_word_t _p, + jit_word_t x4, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x4 & ~0xfL)); + assert(!(r1 & ~0x7fL)); + if (x4 == 2) + TSTREG1(r1); + else + TSTFREG1(r1); + TSTPRED(_p); + inst((1L<<31)|(x4<<27)|(r1<<6)|_p, INST_M); +} + +static void +_M28(jit_state_t *_jit, jit_word_t _p, + jit_word_t x, jit_word_t r3) +{ + assert(!(_p & ~0x3fL)); + assert(!(x & ~0x1L)); + assert(!(r3 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + inst((1L<<37)|(x<<36)|(0x30L<<27)|(r3<<20)|_p, INST_M); +} + +static void +_M29(jit_state_t *_jit, jit_word_t _p, + jit_word_t ar, jit_word_t r2) +{ + assert(!(_p & ~0x3fL)); + assert(!(ar & ~0x7L)); + assert(!(r2 & ~0x7fL)); + TSTREG1(r2); + TSTPRED(_p); + inst((1L<<37)|(0x2aL<<27)|(ar<<20)|(r2<<13)|_p, INST_M); +} + +static void +_M30(jit_state_t *_jit, jit_word_t _p, + jit_word_t ar, jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(ar & ~0x7L)); + assert(!(im & ~0xffL)); + TSTPRED(_p); + inst((((im>>7)&1L)<<36)|(2L<<31)|(0x8L<<27)| + (ar<<20)|((im&0x7fL)<<13)|_p, INST_M); +} + +static void +_M31(jit_state_t *_jit, jit_word_t _p, + jit_word_t ar, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(ar & ~0x7L)); + assert(!(r1 & ~0x7fL)); + TSTPRED(_p); + TSTREG1(r1); + inst((1L<<37)|(0x22L<<27)|(ar<<20)|(r1<<6)|_p, INST_M); + SETREG(r1); +} + +static void +_M32(jit_state_t *_jit, jit_word_t _p, + jit_word_t cr, jit_word_t r2) +{ + assert(!(_p & ~0x3fL)); + assert(!(cr & ~0x7L)); + assert(!(r2 & ~0x7fL)); + TSTREG1(r2); + TSTPRED(_p); + inst((1L<<37)|(0x2cL<<27)|(cr<<20)|(r2<<13)|_p, INST_M); +} + +static void +_M33(jit_state_t *_jit, jit_word_t _p, + jit_word_t cr, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(cr & ~0x7L)); + assert(!(r1 & ~0x7fL)); + TSTPRED(_p); + TSTREG1(r1); + inst((1L<<37)|(0x24L<<27)|(cr<<20)|(r1<<6)|_p, INST_M); + SETREG(r1); +} + +static void +_M34(jit_state_t *_jit, jit_word_t _p, + jit_word_t sor, jit_word_t sol, jit_word_t sof, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(sor & ~0xfL)); + assert(!(sol & ~0x7fL)); + assert(!(sof & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTPRED(_p); + inst((1L<<37)|(6L<<33)|(sor<<27)|(sol<<20)|(sof<<13)|(r1<<6)|_p, INST_M); +} + +static void +_M35(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t r2) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(r2 & ~0x7fL)); + TSTREG1(r2); + TSTPRED(_p); + inst((1L<<37)|(x6<<27)|(r2<<13)|_p, INST_M); +} + +static void +_M36(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(r1 & ~0x7fL)); + TSTPRED(_p); + TSTREG1(r1); + inst((1L<<37)|(x6<<27)|(r1<<6)|_p, INST_M); + SETREG(r1); +} + +static void +_M37(jit_state_t *_jit, jit_word_t _p, + jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(im & ~0x1ffffL)); + TSTPRED(_p); + inst((((im>>20)&1L)<<36)|((im&0xffffL)<<6)|_p, INST_M); +} + +static void +_M38(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t r3, jit_word_t r2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + TSTREG1(r1); + inst((1L<<37)|(x6<<27)|(r3<<20)|(r2<<13)|(r1<<6)|_p, INST_M); + SETREG(r1); +} + +static void +_M39(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t r3, jit_word_t im, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(r3 & ~0x7fL)); + assert(!(im & ~0x7L)); + assert(!(r1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + TSTREG1(r1); + inst((1L<<37)|(x6<<27)|(r3<<20)|(im<<13)|(r1<<6)|_p, INST_M); + SETREG(r1); +} + +static void +_M40(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t r3, jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(r3 & ~0x7fL)); + assert(!(im & ~0x7L)); + TSTREG1(r3); + TSTPRED(_p); + inst((1L<<37)|(x6<<27)|(r3<<20)|(im<<13)|_p, INST_M); +} + +static void +_M41(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t r2) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(r2 & ~0x7fL)); + TSTREG1(r2); + TSTPRED(_p); + inst((1L<<37)|(x6<<27)|(r2<<13)|_p, INST_M); +} + +static void +_M42(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t r3, jit_word_t r2) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + TSTREG1(r2); + TSTPRED(_p); + inst((1L<<37)|(x6<<27)|(r3<<20)|(r2<<13)|_p, INST_M); +} + +static void +_M43(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t r3, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(r3 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTPRED(_p); + TSTREG1(r1); + inst((1L<<37)|(x6<<27)|(r3<<20)|(r1<<6)|_p, INST_M); + SETREG(r1); +} + +static void +_M44(jit_state_t *_jit, jit_word_t _p, + jit_word_t x4, jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(x4 & ~0xfL)); + assert(!(im & ~0xfffffL)); + TSTPRED(_p); + inst((((im>>23)&1L)<<36)|(((im>>21)&3L)<<31)| + (x4<<27)|((im&0x1ffffL)<<6)|_p, INST_M); +} + +static void +_M45(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t r3, jit_word_t r2) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + inst((1L<<37)|(x6<<27)|(r3<<20)|(r2<<13)|_p, INST_M); +} + +static void +_M46(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t r3, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(r3 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + if (r1) TSTREG1(r1); + inst((1L<<37)|(x6<<27)|(r3<<20)|(r1<<6)|_p, INST_M); + if (r1) SETREG(r1); +} + +static void +_M48(jit_state_t *_jit, jit_word_t _p, + jit_word_t y, jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(y & ~0x1L)); + assert(!(im & ~0x1ffffL)); + TSTPRED(_p); + inst((((im>>20)&1L)<<36)|(1L<<27)|(y<<26)|((im&0xffffL)<<6)|_p, INST_M); +} + +static void +_B1(jit_state_t *_jit, jit_word_t _p, + jit_word_t d, jit_word_t wh, jit_word_t im, jit_word_t p, jit_word_t tp) +{ + assert(!(_p & ~0x3fL)); + assert(!(d & ~0x1L)); + assert(!(wh & ~0x3L)); + assert(im >= -1048576 && im <= 1048575); + assert(!(p & ~0x1L)); + assert(!(tp & ~0x7L)); + TSTPRED(_p); + inst((4L<<37)|(((im>>20)&1L)<<36)|(d<<35)|(wh<<33)| + ((im&0xfffffL)<<13)|(p<<12)|(tp<<6)|_p, INST_B); +} + +static void +_B3(jit_state_t *_jit, jit_word_t _p, + jit_word_t d, jit_word_t wh, jit_word_t im, jit_word_t p, jit_word_t b) +{ + assert(!(_p & ~0x3fL)); + assert(!(d & ~0x1L)); + assert(!(wh & ~0x3L)); + assert(im >= -1048576 && im <= 1048575); + assert(!(p & ~0x1L)); + assert(!(b & ~0x3L)); + TSTPRED(_p); + inst((5L<<37)|(((im>>20)&1L)<<36)|(d<<35)|(wh<<33)| + ((im&0xfffffL)<<13)|(p<<12)|(b<<6)|_p, INST_B); +} + +static void +_B4(jit_state_t *_jit, jit_word_t _p, + jit_word_t d, jit_word_t wh, jit_word_t x6, + jit_word_t b, jit_word_t p, jit_word_t tp) +{ + assert(!(_p & ~0x3fL)); + assert(!(d & ~0x1L)); + assert(!(wh & ~0x3L)); + assert(!(x6 & ~0x3fL)); + assert(!(b & ~0x7L)); + assert(!(p & ~0x1L)); + assert(!(tp & ~0x7L)); + TSTPRED(_p); + inst((d<<35)|(wh<<33)|(x6<<27)|(b<<13)|(p<<12)|(tp<<6)|_p, INST_B); +} + +static void +_B5(jit_state_t *_jit, jit_word_t _p, + jit_word_t d, jit_word_t wh, jit_word_t b2, jit_word_t p, jit_word_t b1) +{ + assert(!(_p & ~0x3fL)); + assert(!(d & ~0x1L)); + assert(!(wh & ~0x3L)); + assert(!(b2 & ~0x7L)); + assert(!(p & ~0x1L)); + assert(!(b1 & ~0x7L)); + TSTPRED(_p); + inst((1L<<37)|(d<<35)|(wh<<32)|(b2<<13)|(p<<12)|(b1<<6)|_p, INST_B); +} + +static void +_B6(jit_state_t *_jit, jit_word_t _p, + jit_word_t ih, jit_word_t im, jit_word_t tag, jit_word_t wh) +{ + assert(!(_p & ~0x3fL)); + assert(!(ih & ~0x1L)); + assert(!(im & ~0x1ffffL)); + assert(!(tag & ~0x1ffL)); + assert(!(wh & ~0x3L)); + TSTPRED(_p); + inst((7L<<37)|(((im>>20)&1L)<<36)|(ih<<35)|(((tag>>7)&3L)<<33)| + ((im&0xfffffL)<<13)|((tag&0x7fL)<<6)|(wh<<3)|_p, INST_B); +} + +static void +_B7(jit_state_t *_jit, jit_word_t _p, + jit_word_t ih, jit_word_t x6, jit_word_t b2, jit_word_t tag, jit_word_t wh) +{ + assert(!(_p & ~0x3fL)); + assert(!(ih & ~0x1L)); + assert(!(x6 & ~0x3fL)); + assert(!(b2 & ~0x7L)); + assert(!(tag & ~0x1ffL)); + assert(!(wh & ~0x3L)); + TSTPRED(_p); + inst((2L<<37)|(ih<<35)|(((tag>>7)&3L)<<33)|(x6<<27)| + (b2<<13)|((tag&0x7fL)<<6)|(wh<<3)|_p, INST_B); +} + +static void +_B8(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + TSTPRED(_p); + inst((x6<<27)|_p, INST_B); +} + +static void +_B9(jit_state_t *_jit, jit_word_t _p, + jit_word_t op, jit_word_t x6, jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(op & ~0xfL)); + assert(!(x6 & ~0x3fL)); + assert(!(im & ~0x1ffffL)); + TSTPRED(_p); + inst((op<<37)|(((im>>20)&1L)<<36)|(x6<<27)|((im&0xffffL)<<6)|_p, INST_B); +} + +static void +_X1(jit_state_t *_jit, jit_word_t _p, + jit_word_t im) +{ + jit_word_t i41, i1, i20; + assert(!(_p & ~0x3fL)); + assert(im > -0x2000000000000000 && im <= 0x1fffffffffffffff); + i41 = (im >> 22) & 0x1ffffffffffL; + i1 = (im >> 21) & 0x1L; + i20 = im & 0xfffffL; + TSTPRED(_p); + inst(i41, INST_L); + inst((i1<<36)|(i20<<6)|_p, INST_X); +} + +static void +_X2(jit_state_t *_jit, jit_word_t _p, + jit_word_t r1, jit_word_t im) +{ + jit_word_t i1, i41, ic, i5, i9, i7; + assert(!(_p & ~0x3fL)); + assert(!(r1 & ~0x7fL)); + i1 = (im >> 63) & 0x1L; + i41 = (im >> 22) & 0x1ffffffffffL; + ic = (im >> 21) & 0x1L; + i5 = (im >> 16) & 0x1fL; + i9 = (im >> 7) & 0x1ffL; + i7 = im & 0x7fL; + TSTPRED(_p); + TSTREG1(r1); + inst(i41, INST_L); + inst((6L<<37)|(i1<<36)|(i9<<27)|(i5<<22)| + (ic<<21)|(i7<<13)|(r1<<6)|_p, INST_X); + SETREG(r1); +} + +static void +_X3x(jit_state_t *_jit, jit_word_t _p, + jit_word_t op, jit_word_t d, jit_word_t wh, + jit_word_t p, jit_word_t tp, jit_word_t im) +{ + /* target64 = IP + ((i1 << 59 | imm39 << 20 | imm20b) << 4) */ + jit_word_t i1, i41, i20; + assert(!(_p & ~0x3fL)); + assert(!(op & ~0xfL)); + assert(!(d & ~0x1L)); + assert(!(wh & ~0x3L)); + assert(!(p & ~0x1L)); + assert(!(tp & ~0x7L)); + i1 = (im >> 61) & 0x1L; + i41 = (im >> 22) & 0x1ffffffffffL; + i20 = im & 0xfffffL; + TSTPRED(_p); + inst(i41, INST_L); + inst((op<<37)|(i1<<36)|(d<<35)|(wh<<33)| + (i20<<13)|(p<<12)|(tp<<6)|_p, INST_X); +} + +static void +_X5(jit_state_t *_jit, jit_word_t _p, + jit_word_t y, jit_word_t im) +{ + jit_word_t i41, i1, i20; + assert(!(_p & ~0x3fL)); + assert(im > -0x2000000000000000 && im <= 0x1fffffffffffffff); + i41 = (im >> 22) & 0x1ffffffffffL; + i1 = (im >> 21) & 0x1L; + i20 = im & 0xfffffL; + TSTPRED(_p); + inst(i41, INST_L); + inst((i1<<36)|(1L<<27)|(y<<26)|(i20<<6)|_p, INST_X); +} + +static void +_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + /* patch pushargr */ + if (r0 >= 120) + r0 = _jitc->rout + (r0 - 120); + + MOV(r0, r1); +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + /* patch pushargi */ + if (r0 >= 120) + r0 = _jitc->rout + (r0 - 120); + + if (i0 >= -2097152 && i0 <= 2097151) + MOVI(r0, i0); + else + MOVL(r0, i0); +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + sync(); + w = _jit->pc.w; + MOVL(r0, i0); + return (w); +} + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -8192 && i0 <= 8191) + ADDS(r0, i0, r1); + else if (!(r1 & ~3) && i0 >= -2097152 && i0 <= 2097151) + ADDL(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ltr_u(rn(jit_carry), rn(reg), r1); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + addr(r0, r1, r2); + ltr_u(rn(jit_carry), r0, r1); + } +} + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ltr_u(rn(jit_carry), rn(reg), r1); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + addi(r0, r1, i0); + ltr_u(rn(jit_carry), r0, r1); + } +} + +static void +_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + addcr(r0, r1, r2); + addcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + addci(r0, r1, i0); + addcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + subr(rn(reg), r1, r2); + ltr_u(rn(jit_carry), r1, rn(reg)); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + subr(r0, r1, r2); + ltr_u(rn(jit_carry), r1, r0); + } +} + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, -i0); + ltr_u(rn(jit_carry), r1, rn(reg)); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + addi(r0, r1, -i0); + ltr_u(rn(jit_carry), r1, r0); + } +} + +static void +_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + subcr(r0, r1, r2); + subcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + subci(r0, r1, i0); + subcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -128 && i0 <= 127) + SUBI(r0, i0, r1); + else if (!(r1 & ~3) && i0 >= -2097151 && i0 <= 2097152) + ADDL(r1, -i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subr(r0, rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_mulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t f0, f1; + f0 = jit_get_reg(jit_class_fpr); + f1 = jit_get_reg(jit_class_fpr); + SETF_SIG(rn(f0), r1); + SETF_SIG(rn(f1), r2); + XMPY_L(rn(f0), rn(f0), rn(f1)); + GETF_SIG(r0, rn(f0)); + jit_unget_reg(f0); + jit_unget_reg(f1); +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + mulr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +#if !defined(__GNUC__) +static long +__divdi3(long u, long v) +{ + return (u / v); +} + +static unsigned long +__udivdi3(unsigned long u, unsigned long v) +{ + return (u / v); +} + +static long +__moddi3(long u, long v) +{ + return (u % v); +} + +static unsigned long +__umoddi3(unsigned long u, unsigned long v) +{ + return (u % v); +} +#endif + +static void +_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + MOV(_jitc->rout, r1); + MOV(_jitc->rout + 1, r2); + calli((jit_word_t)__divdi3); + MOV(r0, GR_8); +} + +static void +_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + switch (i0) { + case 1: + movr(r0, r1); + return; + case -1: + negr(r0, r1); + return; + default: + if (i0 > 0 && !(i0 & (i0 - 1))) { + movr(r0, r1); + rshi(r0, r0, ffsl(i0) - 1); + return; + } + break; + } + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + divr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + MOV(_jitc->rout, r1); + MOV(_jitc->rout + 1, r2); + calli((jit_word_t)__udivdi3); + MOV(r0, GR_8); +} + +static void +_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 1) { + movr(r0, r1); + return; + } + else if (i0 > 0 && !(i0 & (i0 - 1))) { + movr(r0, r1); + rshi_u(r0, r0, ffsl(i0) - 1); + return; + } + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + divr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + MOV(_jitc->rout, r1); + MOV(_jitc->rout + 1, r2); + calli((jit_word_t)__moddi3); + MOV(r0, GR_8); +} + +static void +_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 1 || i0 == -1) { + MOV(r0, GR_0); + return; + } + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + MOV(_jitc->rout, r1); + MOV(_jitc->rout + 1, r2); + calli((jit_word_t)__umoddi3); + MOV(r0, GR_8); +} + +static void +_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 1) { + MOV(r0, GR_0); + return; + } + else if (i0 > 0 && !(i0 & (i0 - 1))) { + andi(r0, r1, i0 - 1); + return; + } + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_mulh(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_bool_t sign) +{ + jit_int32_t f0, f1; + f0 = jit_get_reg(jit_class_fpr); + f1 = jit_get_reg(jit_class_fpr); + SETF_SIG(rn(f0), r1); + SETF_SIG(rn(f1), r2); + if (sign) + XMPY_H(rn(f0), rn(f0), rn(f1)); + else + XMPY_HU(rn(f0), rn(f0), rn(f1)); + GETF_SIG(r0, rn(f0)); + jit_unget_reg(f0); + jit_unget_reg(f1); +} + +static void +_iqmulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + jit_int32_t reg; + if (r0 == r2 || r0 == r3) { + reg = jit_get_reg(jit_class_gpr); + mulr(rn(reg), r2, r3); + } + else + mulr(r0, r2, r3); + mulh(r1, r2, r3, sign); + if (r0 == r2 || r0 == r3) { + movr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_iqmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iqmulr(r0, r1, r2, rn(reg), sign); + jit_unget_reg(reg); +} + +static void +_iqdivr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + jit_int32_t sv0, rg0; + jit_int32_t sv1, rg1; + + if (r0 == r2 || r0 == r3) { + sv0 = jit_get_reg(jit_class_gpr); + rg0 = rn(sv0); + } + else + rg0 = r0; + if (r1 == r2 || r1 == r3) { + sv1 = jit_get_reg(jit_class_gpr); + rg1 = rn(sv1); + } + else + rg1 = r1; + + if (sign) + divr(rg0, r2, r3); + else + divr_u(rg0, r2, r3); + mulr(rg1, r3, rg0); + subr(rg1, r2, rg1); + if (rg0 != r0) { + movr(r0, rg0); + jit_unget_reg(sv0); + } + if (rg1 != r1) { + movr(r1, rg1); + jit_unget_reg(sv1); + } +} + +static void +_iqdivi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iqdivr(r0, r1, r2, rn(reg), sign); + jit_unget_reg(reg); +} + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -128 && i0 <= 127) + ANDI(r0, i0, r1); + else if (~i0 >= -128 && ~i0 <= 127) + ANDCMI(r0, ~i0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + andr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -128 && i0 <= 127) + ORI(r0, i0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + orr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -128 && i0 <= 127) + XORI(r0, i0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + xorr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +#if __BYTE_ORDER == __LITTLE_ENDIAN +static void +_htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + rshi(rn(t0), r1, 8); + andi(r0, r1, 0xff); + andi(rn(t0), rn(t0), 0xff); + lshi(r0, r0, 8); + orr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr); + t2 = jit_get_reg(jit_class_gpr); + rshi(rn(t0), r1, 24); + rshi(rn(t1), r1, 16); + rshi(rn(t2), r1, 8); + andi(rn(t0), rn(t0), 0xff); + andi(rn(t1), rn(t1), 0xff); + andi(rn(t2), rn(t2), 0xff); + andi(r0, r1, 0xff); + lshi(r0, r0, 24); + lshi(rn(t1), rn(t1), 8); + orr(r0, r0, rn(t0)); + lshi(rn(t2), rn(t2), 16); + orr(r0, r0, rn(t1)); + orr(r0, r0, rn(t2)); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); +} +#endif + +static void +_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + lshr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + rshr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + rshr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ltr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMP_LT(PR_6, PR_7, r1, r2); + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} + +static void +_lti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -127 && i0 <= 128) + CMPI_LT(PR_7, PR_6, i0 - 1, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMP_LT(PR_6, PR_7, r1, rn(reg)); + jit_unget_reg(reg); + } + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} + +static void +_ltr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMP_LTU(PR_6, PR_7, r1, r2); + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} + +static void +_lti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -127 && i0 <= 128) + CMPI_LTU(PR_7, PR_6, i0 - 1, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMP_LTU(PR_6, PR_7, r1, rn(reg)); + jit_unget_reg(reg); + } + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} + +static void +_ler(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMP_LT(PR_6, PR_7, r2, r1); + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} + +static void +_lei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ler(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ler_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMP_LTU(PR_6, PR_7, r2, r1); + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} + +static void +_lei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ler_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_eqr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMP_EQ(PR_6, PR_7, r1, r2); + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} + +static void +_eqi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -128 && i0 <= 127) + CMPI_EQ(PR_6, PR_7, i0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMP_EQ(PR_6, PR_7, r1, rn(reg)); + jit_unget_reg(reg); + } + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} + +static void +_ger(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMP_LT(PR_6, PR_7, r1, r2); + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} + +static void +_gei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -127 && i0 <= 128) + CMPI_LT(PR_7, PR_6, i0 - 1, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMP_LT(PR_6, PR_7, r1, rn(reg)); + jit_unget_reg(reg); + } + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} + +static void +_ger_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMP_LTU(PR_6, PR_7, r1, r2); + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} + +static void +_gei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -127 && i0 <= 128) + CMPI_LTU(PR_7, PR_6, i0 - 1, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMP_LTU(PR_6, PR_7, r1, rn(reg)); + jit_unget_reg(reg); + } + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} + +static void +_gtr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMP_LT(PR_6, PR_7, r2, r1); + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} + +static void +_gti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + gtr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_gtr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMP_LTU(PR_6, PR_7, r2, r1); + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} + +static void +_gti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + gtr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMP_EQ(PR_6, PR_7, r1, r2); + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} + +static void +_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 >= -128 && i0 <= 127) + CMPI_EQ(PR_6, PR_7, i0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMP_EQ(PR_6, PR_7, r1, rn(reg)); + jit_unget_reg(reg); + } + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} + +static void +_ldr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + ldr_uc(r0, r1); + extr_c(r0, r0); +} + +static void +_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + ldr_us(r0, r1); + extr_s(r0, r0); +} + +static void +_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + ldr_ui(r0, r1); + extr_i(r0, r0); +} + +static void +_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_c(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + else + ldr_c(r0, r1); +} + +static void +_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_uc(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + else + ldr_uc(r0, r1); +} + +static void +_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_s(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + else + ldr_s(r0, r1); +} + +static void +_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_us(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + else + ldr_us(r0, r1); +} + +static void +_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_i(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + else + ldr_i(r0, r1); +} + +static void +_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_ui(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + else + ldr_ui(r0, r1); +} + +static void +_ldxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_l(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + else + ldr_l(r0, r1); +} + +static void +_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_c(rn(reg), r0); + jit_unget_reg(reg); +} + +static void +_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_s(rn(reg), r0); + jit_unget_reg(reg); +} + +static void +_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_i(rn(reg), r0); + jit_unget_reg(reg); +} + +static void +_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_l(rn(reg), r0); + jit_unget_reg(reg); +} + +static void +_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_c(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_c(rn(reg), r1); + jit_unget_reg(reg); + } + else + str_c(r0, r1); +} + +static void +_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_s(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_s(rn(reg), r1); + jit_unget_reg(reg); + } + else + str_s(r0, r1); +} + +static void +_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_i(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_i(rn(reg), r1); + jit_unget_reg(reg); + } + else + str_i(r0, r1); +} + +static void +_stxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_l(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_l(rn(reg), r1); + jit_unget_reg(reg); + } + else + str_l(r0, r1); +} + +static jit_word_t +_bltr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CMP_LT(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} + +static jit_word_t +_blti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 >= -127 && i1 <= 128) + CMPI_LT(PR_7, PR_6, i1 - 1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMP_LT(PR_6, PR_7, r0, rn(reg)); + jit_unget_reg(reg); + } + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} + +static jit_word_t +_bltr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CMP_LTU(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} + +static jit_word_t +_blti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 >= -127 && i1 <= 128) + CMPI_LTU(PR_7, PR_6, i1 - 1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMP_LTU(PR_6, PR_7, r0, rn(reg)); + jit_unget_reg(reg); + } + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} + +static jit_word_t +_bler(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CMP_LT(PR_6, PR_7, r1, r0); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} + +static jit_word_t +_blei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bler(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bler_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CMP_LTU(PR_6, PR_7, r1, r0); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} + +static jit_word_t +_blei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bler_u(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_beqr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CMP_EQ(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} + +static jit_word_t +_beqi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 >= -128 && i1 <= 127) + CMPI_EQ(PR_6, PR_7, i1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMP_EQ(PR_6, PR_7, r0, rn(reg)); + jit_unget_reg(reg); + } + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} + +static jit_word_t +_bger(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CMP_LT(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} + +static jit_word_t +_bgei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 >= -127 && i1 <= 128) + CMPI_LT(PR_7, PR_6, i1 - 1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMP_LT(PR_6, PR_7, r0, rn(reg)); + jit_unget_reg(reg); + } + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} + +static jit_word_t +_bger_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CMP_LTU(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} + +static jit_word_t +_bgei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 >= -127 && i1 <= 128) + CMPI_LTU(PR_7, PR_6, i1 - 1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMP_LTU(PR_6, PR_7, r0, rn(reg)); + jit_unget_reg(reg); + } + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} + +static jit_word_t +_bgtr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CMP_LT(PR_6, PR_7, r1, r0); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} + +static jit_word_t +_bgti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bgtr(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bgtr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CMP_LTU(PR_6, PR_7, r1, r0); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} + +static jit_word_t +_bgti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bgtr_u(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bner(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CMP_EQ(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} + +static jit_word_t +_bnei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 >= -128 && i1 <= 127) + CMPI_EQ(PR_6, PR_7, i1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMP_EQ(PR_6, PR_7, r0, rn(reg)); + jit_unget_reg(reg); + } + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} + +static jit_word_t +_bmsr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + andr(rn(reg), r0, r1); + CMPI_EQ(PR_6, PR_7, 0, rn(reg)); + jit_unget_reg(reg); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} + +static jit_word_t +_bmsi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + andr(rn(reg), r0, rn(reg)); + CMPI_EQ(PR_6, PR_7, 0, rn(reg)); + jit_unget_reg(reg); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} + +static jit_word_t +_bmcr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + andr(rn(reg), r0, r1); + CMPI_EQ(PR_6, PR_7, 0, rn(reg)); + jit_unget_reg(reg); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} + +static jit_word_t +_bmci(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + andr(rn(reg), r0, rn(reg)); + CMPI_EQ(PR_6, PR_7, 0, rn(reg)); + jit_unget_reg(reg); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} + +static jit_word_t +_baddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + /* t1 = r0 + r1; overflow = r1 < 0 ? r0 < t1 : t1 < r0 */ + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t2 = jit_get_reg(jit_class_gpr|jit_class_nospill); + lti(rn(t0), r1, 0); /* t0 = r1 < 0 */ + addr(rn(t1), r0, r1); /* t1 = r0 + r1 */ + ltr(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */ + ltr(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */ + CMPI_EQ(PR_6, PR_7, 0, rn(t0)); + CMPI_EQ_p(PR_8, PR_9, 0, rn(t2), PR_6);/* if (t0==0) p8=t2==0,p9=t2!=0; */ + CMPI_EQ_p(PR_8, PR_9, 0, rn(t1), PR_7);/* if (t0!=0) p8=t1==0,p9=t1!=0; */ + addr(r0, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, carry ? PR_9 : PR_8); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_baddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = baddr(i0, r0, rn(reg), carry); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_baddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addr(rn(t0), r0, r1); + ltr_u(rn(t1), rn(t0), r0); + CMPI_EQ(PR_6, PR_7, 0, rn(t1)); + MOV(r0, rn(t0)); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, carry ? PR_7 : PR_6); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_baddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = baddr_u(i0, r0, rn(reg), carry); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bsubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + /* t1 = r0 - r1; overflow = 0 < r1 ? r0 < t1 : t1 < r0 */ + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t2 = jit_get_reg(jit_class_gpr|jit_class_nospill); + gti(rn(t0), r1, 0); /* t0 = r1 > 0 */ + subr(rn(t1), r0, r1); /* t1 = r0 - r1 */ + ltr(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */ + ltr(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */ + CMPI_EQ(PR_6, PR_7, 0, rn(t0)); + CMPI_EQ_p(PR_8, PR_9, 0, rn(t2), PR_6);/* if (t0==0) p4=t2==0,p5=t2!=0; */ + CMPI_EQ_p(PR_8, PR_9, 0, rn(t1), PR_7);/* if (t0!=0) p4=t1==0,p5=t1!=0; */ + subr(r0, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, carry ? PR_9 : PR_8); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bsubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bsubr(i0, r0, rn(reg), carry); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bsubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + subr(rn(t0), r0, r1); + ltr_u(rn(t1), r0, rn(t0)); + CMPI_EQ(PR_6, PR_7, 0, rn(t1)); + MOV(r0, rn(t0)); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, carry ? PR_7 : PR_6); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bsubr_u(i0, r0, rn(reg), carry); + jit_unget_reg(reg); + return (w); +} + +static void +_jmpr(jit_state_t *_jit, jit_int32_t r0) +{ + MOV_br_rn(BR_6, r0); + BR(BR_6); +} + +static void +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t d; + sync(); + d = ((jit_word_t)i0 - _jit->pc.w) >> 4; + if (d >= -16777216 && d <= 16777215) + BRI(d); + else + BRL(d); +} + +static jit_word_t +_jmpi_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t d, w; + sync(); + w = _jit->pc.w; + d = ((jit_word_t)i0 - w) >> 4; + BRL(d); + return (w); +} + +static void +_callr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + LD8_inc(rn(reg), r0, 8); + MOV_br_rn(BR_6, rn(reg)); + jit_unget_reg(reg); + LD8(GR_1, r0); + BR_CALL(BR_0, BR_6); +} + +static void +_calli(jit_state_t *_jit, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + callr(rn(reg)); + jit_unget_reg(reg); +} + +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + w = movi_p(rn(reg), i0); + callr(rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_prolog(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t reg, ruse, rout; + + if (_jitc->function->define_frame || _jitc->function->assume_frame) { + jit_int32_t frame = -_jitc->function->frame; + assert(_jitc->function->self.aoff >= frame); + if (_jitc->function->assume_frame) + return; + _jitc->function->self.aoff = frame; + } + if (_jitc->function->allocar) + _jitc->function->self.aoff &= -16; + _jitc->function->stack = ((_jitc->function->self.alen - + _jitc->function->self.aoff) + 15) & -16; + + /* First lowest unused register is first output register */ + for (reg = _R115; reg >= _R40; reg--) { + if (jit_regset_tstbit(&_jitc->function->regset, reg)) + break; + } + _jitc->breg = rn(reg) + 1; + _jitc->rout = _jitc->breg + 5; + ruse = _jitc->rout - GR_32; + + /* How many out argument registers required? */ + if (!_jitc->function->define_frame) { + for (reg = _OUT7; reg >= _OUT0; --reg) { + if (jit_regset_tstbit(&_jitc->function->regset, reg)) + break; + } + rout = (reg + 1) - _OUT0; + } + else + rout = 8; + + /* Do not know if will call div/mod functions (sqrt* needs one) */ + if (rout < 2) + rout = 2; + + /* Match gcc prolog */ + ALLOC(_jitc->breg + 1, ruse, rout); + MOV(_jitc->breg + 2, GR_12); + MOV_rn_br(_jitc->breg, BR_0); + MOV(_jitc->breg + 3, GR_1); + + /* lightning specific, use r4 as frame pointer */ + MOV(_jitc->breg + 4, GR_4); + addi(GR_4, GR_12, -(stack_framesize + params_offset)); + + /* adjust stack pointer */ + addi(GR_12, GR_12, -(stack_framesize + + (params_offset << 1) + _jitc->function->stack)); + + if (jit_regset_tstbit(&_jitc->function->regset, JIT_F0)) + STF_SPILL(GR_4, rn(JIT_F0)); + if (jit_regset_tstbit(&_jitc->function->regset, JIT_F1)) { + addi(GR_2, GR_4, 16); + STF_SPILL(GR_2, rn(JIT_F1)); + } + if (jit_regset_tstbit(&_jitc->function->regset, JIT_F2)) { + addi(GR_2, GR_4, 32); + STF_SPILL(GR_2, rn(JIT_F2)); + } + if (jit_regset_tstbit(&_jitc->function->regset, JIT_F3)) { + addi(GR_2, GR_4, 48); + STF_SPILL(GR_2, rn(JIT_F3)); + } + if (jit_regset_tstbit(&_jitc->function->regset, JIT_F4)) { + addi(GR_2, GR_4, 64); + STF_SPILL(GR_2, rn(JIT_F4)); + } + if (jit_regset_tstbit(&_jitc->function->regset, JIT_F5)) { + addi(GR_2, GR_4, 80); + STF_SPILL(GR_2, rn(JIT_F5)); + } + + if (_jitc->function->allocar) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), _jitc->function->self.aoff); + stxi_i(_jitc->function->aoffoff, GR_4, rn(reg)); + jit_unget_reg(reg); + } + + if (_jitc->function->self.call & jit_call_varargs) { + for (reg = _jitc->function->vagp; reg < 8; ++reg) + stxi(112 + reg * 8, GR_4, GR_32 + reg); + } +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *node) +{ + if (_jitc->function->assume_frame) + return; + if (jit_regset_tstbit(&_jitc->function->regset, JIT_F0)) + LDF_FILL(rn(JIT_F0), GR_4); + if (jit_regset_tstbit(&_jitc->function->regset, JIT_F1)) { + addi(GR_2, GR_4, 16); + LDF_FILL(rn(JIT_F1), GR_2); + } + if (jit_regset_tstbit(&_jitc->function->regset, JIT_F2)) { + addi(GR_2, GR_4, 32); + LDF_FILL(rn(JIT_F2), GR_2); + } + if (jit_regset_tstbit(&_jitc->function->regset, JIT_F3)) { + addi(GR_2, GR_4, 48); + LDF_FILL(rn(JIT_F3), GR_2); + } + if (jit_regset_tstbit(&_jitc->function->regset, JIT_F4)) { + addi(GR_2, GR_4, 64); + LDF_FILL(rn(JIT_F4), GR_2); + } + if (jit_regset_tstbit(&_jitc->function->regset, JIT_F5)) { + addi(GR_2, GR_4, 80); + LDF_FILL(rn(JIT_F5), GR_2); + } + /* Match gcc epilog */ + MOV(GR_1, _jitc->breg + 3); + MOV_I_ar_rn(AR_PFS, _jitc->breg + 1); + MOV_br_rn(BR_0, _jitc->breg); + MOV(GR_12, _jitc->breg + 2); + /* Restore lightning specific r4 as frame pointer */ + MOV(GR_4, _jitc->breg + 4); + BR_RET(BR_0); + flush(); +} + +static void +_vastart(jit_state_t *_jit, jit_int32_t r0) +{ + assert(_jitc->function->self.call & jit_call_varargs); + /* Initialize va_list to the first stack argument. */ + if (_jitc->function->vagp < 8) + addi(r0, GR_4, 112 + _jitc->function->vagp * 8); + else + addi(r0, GR_4, _jitc->function->self.size); +} + +static void +_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(_jitc->function->self.call & jit_call_varargs); + /* Load argument. */ + ldr(r0, r1); + /* Update va_list. */ + addi(r1, r1, 8); +} + +static void +_patch_at(jit_state_t *_jit, jit_code_t code, + jit_word_t instr, jit_word_t label) +{ + jit_word_t l, h, tm, s0, s1, s2; + union { + jit_word_t w; + jit_word_t *p; + } c; + jit_word_t i1, i41, i20, ic, i5, i9, i7; + c.w = instr; + get_bundle(c.p, l, h, tm, s0, s1, s2); + switch (code) { + case jit_code_movi: + /* Handle jit functions as C function, so that jit function + * pointers can be passed to C code, and jit code does not + * need to try to differentiate them. */ + case jit_code_calli: + i1 = (label >> 63) & 0x1L; + i41 = (label >> 22) & 0x1ffffffffffL; + ic = (label >> 21) & 0x1L; + i5 = (label >> 16) & 0x1fL; + i9 = (label >> 7) & 0x1ffL; + i7 = label & 0x7fL; + s1 = i41; + assert((tm & ~1) == TM_M_L_X_ && + (s2 & 0xfL<<37) == (6L<<37) && + s0 == nop_m); + s2 &= (6L<<37)|(0x7fL<<6); + s2 |= (i1<<36)|(i9<<27)|(i5<<22)|(ic<<21)|(i7<<13); + break; + case jit_code_jmpi: + if (_jitc->jump) { + /* kludge to hide function descriptors; check that gp + * is zero, what is done for all jit functions */ + if (((long *)label)[1] == 0) { + for (ic = 0; ic < _jitc->prolog.offset; ic++) { + if (_jitc->prolog.ptr[ic] == label) { + label += 16; + break; + } + } + } + } + ic = (label - instr) >> 4; + i1 = (ic >> 61) & 0x1L; + i41 = (ic >> 22) & 0x1ffffffffffL; + i20 = ic & 0xfffffL; + assert((tm & ~1) == TM_M_L_X_ && + (s2 & 0xfL<<37) == (0xcL<<37) && + s0 == nop_m); + s1 = i41; + s2 &= (0xcL<<37)|(0x7L<<33)|(1L<<12); + s2 |= (i1<<36)|(i20<<13); + break; + default: + /* Only B1 in slot 0 expected due to need to either + * a stop to update predicates, or a sync before + * unconditional short branch */ + ic = (label - instr) >> 4; + assert((s0 >> 37) == 4 && (s0 & (7 << 6)) == 0); + s0 &= (4L<<37)|(7L<<33)|(1L<<12)|0x1f; + s0 |= (((ic>>20)&1L)<<36)|((ic&0xfffffL)<<13); + break; + } + set_bundle(c.p, l, h, tm, s0, s1, s2); +} +#endif diff --git a/deps/lightning/lib/jit_ia64-fpu.c b/deps/lightning/lib/jit_ia64-fpu.c new file mode 100644 index 0000000..19cc381 --- /dev/null +++ b/deps/lightning/lib/jit_ia64-fpu.c @@ -0,0 +1,1762 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +#define SF_S0 0 +#define SF_S1 1 +#define SF_S2 2 +#define SF_S3 3 + +#define TSTFREG1(r0) \ + do { \ + if (jit_regset_tstbit(&_jitc->regs, r0 + 128)) \ + stop(); \ + } while (0) +#define TSTFREG2(r0, r1) \ + do { \ + if (jit_regset_tstbit(&_jitc->regs, r0 + 128) || \ + jit_regset_tstbit(&_jitc->regs, r1 + 128)) \ + stop(); \ + } while (0) +#define TSTFREG3(r0, r1, r2) \ + do { \ + if (jit_regset_tstbit(&_jitc->regs, r0 + 128) || \ + jit_regset_tstbit(&_jitc->regs, r1 + 128) || \ + jit_regset_tstbit(&_jitc->regs, r2 + 128)) \ + stop(); \ + } while (0) +#define SETFREG(r0) jit_regset_setbit(&_jitc->regs, r0 + 128) + +/* libm */ +extern float sqrtf(float); +extern double sqrt(double); +#define M7(x6,ht,r3,r2,f1) _M7(_jit,0,x6,ht,r3,r2,f1) +static void _M7(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M8(x6,ht,r3,im,f1) _M8(_jit,0,x6,ht,r3,im,f1) +static void _M8(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M9(x6,ht,r3,f1) _M9(_jit,0,x6,ht,r3,f1) +static void _M9(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define M10(x6,ht,r3,r2,im) _M10(_jit,0,x6,ht,r3,r2,im) +static void _M10(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M11(x6,ht,r3,f2,f1) _M11(_jit,0,x6,ht,r3,f2,f1) +static void _M11(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M12(x6,ht,r3,f2,f1) _M12(_jit,0,x6,ht,r3,f2,f1) +static void _M12(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define M18(x6,r2,f1) _M18(_jit,0,x6,r2,f1) +static void _M18(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t); +#define M19(x6,f2,r1) _M19(_jit,0,x6,f2,r1) +static void _M19(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t); +#define M21(f2,im) M20x(0x3,f2,im) +#define M23(x3,im,f1) M22x(x3,im,f1) +#define M27(f1) M26x(3,f1) +#define F1(op,x,sf,f4,f3,f2,f1) F1_(_jit,0,op,x,sf,f4,f3,f2,f1) +#define F2(x2,f4,f3,f2,f1) F1(0xe,1,x2,f4,f3,f2,f1) +#define F3(f4,f3,f2,f1) F1(0xe,0,0,f4,f3,f2,f1) +static void F1_(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define F4(rb,sf,ra,p2,f3,f2,ta,p1) F4_(_jit,0,rb,sf,ra,p2,f3,f2,ta,p1) +static void F4_(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define F5(p2,fc,f2,ta,p1) F5_(_jit,0,p2,fc,f2,ta,p1) +static void F5_(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define F6x(op,q,sf,p2,f3,f2,f1) F6x_(_jit,0,op,q,sf,p2,f3,f2,f1) +#define F6(op,sf,p2,f3,f2,f1) F6x(op,0,sf,p2,f3,f2,f1) +#define F7(op,sf,p2,f3,f1) F6x(op,1,sf,p2,f3,0,f1) +static void F6x_(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t); +#define F8(op,sf,x6,f3,f2,f1) F8_(_jit,0,op,sf,x6,f3,f2,f1) +#define F9(op,x6,f3,f2,f1) F8(op,0,x6,f3,f2,f1) +#define F10(op,sf,x6,f2,f1) F8(op,sf,x6,0,f2,f1) +#define F11(x6,f2,f1) F8(0,0,x6,0,f2,f1) +static void F8_(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t, + jit_word_t,jit_word_t,jit_word_t); +#define F12(sf,x6,omsk,amsk) F12_(_jit,0,sf,x6,omsk,amsk) +#define F13(sf,x6) F12(sf,x6,0,0) +static void F12_(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define F14x(sf,x,x6,im) F14x_(_jit,0,sf,x,x6,im) +#define F14(sf,im) F14x(sf,0,8,im) +#define F15(im) F14x(0,0,0,im) +static void F14x_(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t,jit_word_t,jit_word_t) + maybe_unused; +#define F16(y,im) F16_(_jit,0,y,im) +static void F16_(jit_state_t*,jit_word_t, + jit_word_t,jit_word_t)maybe_unused; + +/* break */ +#define BREAK_F(im) F15(im) +/* chk */ +#define CHK_S(f2,im) M21(f2,im) +#define CHKF_A_NC(f1,im) M23(0x6,im,f1) +#define CHKF_A_CLR(f1,im) M23(0x7,im,f1) +/* fabs */ +#define FABS(f1,f3) FMERGE_S(f1,0,f3) +/* fadd */ +#define FADD(f1,f3,f2) FMA(f1,f3,1,f2) +#define FADD_S(f1,f3,f2) FMA_S(f1,f3,1,f2) +#define FADD_D(f1,f3,f2) FMA_D(f1,f3,1,f2) +/* famax */ +#define FAMAX(f1,f2,f3) F8(0,SF_S0,0x17,f3,f2,f1) +/* famin */ +#define FAMIN(f1,f2,f3) F8(0,SF_S0,0x16,f3,f2,f1) +/* fand */ +#define FAND(f1,f2,f3) F9(0,0x2c,f3,f2,f1) +/* fandcm */ +#define FANDCM(f1,f2,f3) F9(0,0x2d,f3,f2,f1) +/* fchkf */ +#define FCHKF(im) F14(SF_S0,im) +/* fclass */ +#define FCLASS_M(p1,p2,f2,fc) F5(p2,fc,f2,0,p1) +#define FCLASS_M_UNC(p1,p2,f2,fc) F5(p2,fc,f2,1,p1) +/* fclrf */ +#define FCLRF() F13(SF_S0,5) +/* fcmp */ +#define FCMP_EQ(p1,p2,f2,f3) F4(0,SF_S0,0,p2,f3,f2,0,p1) +#define FCMP_LT(p1,p2,f2,f3) F4(1,SF_S0,0,p2,f3,f2,0,p1) +#define FCMP_LE(p1,p2,f2,f3) F4(0,SF_S0,1,p2,f3,f2,0,p1) +#define FCMP_UNORD(p1,p2,f2,f3) F4(1,SF_S0,1,p2,f3,f2,0,p1) +#define FCMP_EQ_UNC(p1,p2,f2,f3) F4(0,SF_S0,0,p2,f3,f2,1,p1) +#define FCMP_LT_UNC(p1,p2,f2,f3) F4(1,SF_S0,0,p2,f3,f2,1,p1) +#define FCMP_LE_UNC(p1,p2,f2,f3) F4(0,SF_S0,1,p2,f3,f2,1,p1) +#define FCMP_UNORD_UNC(p1,p2,f2,f3) F4(1,SF_S0,1,p2,f3,f2,1,p1) +/* fcvt.fx */ +#define FCVT_FX(f1,f2) F10(0,SF_S0,0x18,f2,f1) +#define FCVT_FXU(f1,f2) F10(0,SF_S0,0x19,f2,f1) +#define FCVT_FX_TRUNC(f1,f2) F10(0,SF_S0,0x1a,f2,f1) +#define FCVT_FXU_TRUNC(f1,f2) F10(0,SF_S0,0x1b,f2,f1) +/* fcvt.xf */ +#define FCVT_XF(f1,f2) F11(0x1c,f2,f1) +/* fcvt.fxuf */ +#define FCVT_XUF(f1,f3) FMA(f1,f3,1,0) +/* fma */ +#define FMA(f1,f3,f4,f2) F1(0x8,0,SF_S0,f4,f3,f2,f1) +#define FMA_p(f1,f3,f4,f2,sf,_p) F1_(_jit,_p,0x8,0,sf,f4,f3,f2,f1) +#define FMA_S(f1,f3,f4,f2) F1(0x8,1,SF_S0,f4,f3,f2,f1) +#define FMA_S_p(f1,f3,f4,f2,sf,_p) F1_(_jit,_p,0x8,1,sf,f4,f3,f2,f1) +#define FMA_D(f1,f3,f4,f2) F1(0x9,0,SF_S0,f4,f3,f2,f1) +#define FMA_D_p(f1,f3,f4,f2,sf,_p) F1_(_jit,_p,0x9,0,sf,f4,f3,f2,f1) +/* fmax */ +#define FMAX(f1,f2,f3) F8(0,SF_S0,0x15,f3,f2,f1) +/* fmerge */ +#define FMERGE_S(f1,f2,f3) F9(0,0x10,f3,f2,f1) +#define FMERGE_NS(f1,f2,f3) F9(0,0x11,f3,f2,f1) +#define FMERGE_SE(f1,f2,f3) F9(0,0x12,f3,f2,f1) +/* fmin */ +#define FMIN(f1,f2,f3) F8(0,SF_S0,0x14,f3,f2,f1) +/* fmix */ +#define FMIX_LR(f1,f2,f3) F9(0,0x39,f3,f2,f1) +#define FMIX_R(f1,f2,f3) F9(0,0x3a,f3,f2,f1) +#define FMIX_L(f1,f2,f3) F9(0,0x3b,f3,f2,f1) +/* fmpy */ +#define FMPY(f1,f3,f4) FMA(f1,f3,f4,0) +#define FMPY_p(f1,f3,f4,sf,_p) FMA_p(f1,f3,f4,0,sf,_p) +#define FMPY_S(f1,f3,f4) FMA_S(f1,f3,f4,0) +#define FMPY_S_p(f1,f3,f4,sf,_p) FMA_S_p(f1,f3,f4,0,sf,_p) +#define FMPY_D(f1,f3,f4) FMA_D(f1,f3,f4,0) +#define FMPY_D_p(f1,f3,f4,sf,_p) FMA_D_p(f1,f3,f4,0,sf,_p) +/* fms */ +#define FMS(f1,f3,f4,f2) F1(0xa,0,SF_S0,f4,f3,f2,f1) +#define FMS_S(f1,f3,f4,f2) F1(0xa,1,SF_S0,f4,f3,f2,f1) +#define FMS_D(f1,f3,f4,f2) F1(0xb,0,SF_S0,f4,f3,f2,f1) +/* fneg */ +#define FNEG(f1,f3) FMERGE_NS(f1,f3,f3) +/* fnegabs */ +#define FNEGABS(f1,f3) FMERGE_NS(f1,0,f3) +/* fnma */ +#define FNMA(f1,f3,f4,f2) F1(0xc,0,SF_S0,f4,f3,f2,f1) +#define FNMA_p(f1,f3,f4,f2,sf,_p) F1_(_jit,_p,0xc,0,sf,f4,f3,f2,f1) +#define FNMA_S(f1,f3,f4,f2) F1(0xc,1,SF_S0,f4,f3,f2,f1) +#define FNMA_D(f1,f3,f4,f2) F1(0xd,0,SF_S0,f4,f3,f2,f1) +/* fnmpy */ +#define FNMPY(f1,f3,f4) FNMA(f1,f3,f4,0) +/* fnorm */ +#define FNORM(f1,f3) FMA(f1,f3,1,0) +#define FNORM_S(f1,f3) FMA_S(f1,f3,1,0) +#define FNORM_D(f1,f3) FMA_D(f1,f3,1,0) +/* for */ +#define FOR(f1,f2,f3) F9(0,0x2e,f3,f2,f1) +/* fpabs */ +#define FPABS(f1,f3) FPMERGE_S(f1,0,f3) +/* fpack */ +#define FPACK(f1,f2,f3) F9(0,0x28,f3,f2,f1) +/* fpamax */ +#define FPAMAX(f1,f2,f3) F8(1,SF_S0,0x17,f3,f2,f1) +/* fpamin */ +#define FPAMIN(f1,f2,f3) F8(1,SF_S0,0x16,f3,f2,f1) +/* fpcmp */ +#define FPCMP_EQ(f1,f2,f3) F8(1,SF_S0,0x30,f3,f2,f1) +#define FPCMP_LT(f1,f2,f3) F8(1,SF_S0,0x31,f3,f2,f1) +#define FPCMP_LE(f1,f2,f3) F8(1,SF_S0,0x32,f3,f2,f1) +#define FPCMP_UNORD(f1,f2,f3) F8(1,SF_S0,0x33,f3,f2,f1) +#define FPCMP_NEQ(f1,f2,f3) F8(1,SF_S0,0x34,f3,f2,f1) +#define FPCMP_NLT(f1,f2,f3) F8(1,SF_S0,0x35,f3,f2,f1) +#define FPCMP_NLE(f1,f2,f3) F8(1,SF_S0,0x36,f3,f2,f1) +#define FPCMP_ORD(f1,f2,f3) F8(1,SF_S0,0x37,f3,f2,f1) +/* fpcvt.fx */ +#define FPCVT_FX(f1,f2) F10(1,SF_S0,0x18,f2,f1) +#define FPCVT_FXU(f1,f2) F10(1,SF_S0,0x19,f2,f1) +#define FPCVT_FX_TRUNC(f1,f2) F10(1,SF_S0,0x1a,f2,f1) +#define FPCVT_FXU_TRUNC(f1,f2) F10(1,SF_S0,0x1b,f2,f1) +/* fpma */ +#define FPMA(f1,f3,f4,f2) F1(0x9,1,SF_S0,f4,f3,f3,f1) +/* fpmax */ +#define FPMAX(f1,f2,f3) F8(1,SF_S0,0x15,f3,f2,f1) +/* fpmerge */ +#define FPMERGE_S(f1,f2,f3) F9(1,0x10,f3,f2,f1) +#define FPMERGE_NS(f1,f2,f3) F9(1,0x11,f3,f2,f1) +#define FPMERGE_SE(f1,f2,f3) F9(1,0x12,f3,f2,f1) +/* fpmin */ +#define FPMIN(f1,f2,f3) F8(1,SF_S0,0x14,f3,f2,f1) +/* fpmpy */ +#define FPMPY(f1,f3,f4) FPMA(f1,f3,f4,0) +/* fpms */ +#define FPMS(f1,f3,f4,f2) F1(0xb,1,SF_S0,f4,f3,f3,f1) +/* fpneg */ +#define FPNEG(f1,f3) FPMERGE_NS(f1,f3,f3) +/* fpnegabs */ +#define FPNEGABS(f1,f3) FPMERGE_NS(f1,0,f3) +/* fpnma */ +#define FPNMA(f1,f3,f4,f2) F1(0xd,1,SF_S0,f4,f3,f3,f1) +/* fpnmpy */ +#define FPNMPY(f1,f3,f4) FPNMA(f1,f3,f4,0) +/* fprcpa */ +#define FPRCPA(f1,p2,f2,f3) F6(1,SF_S0,p2,f3,f2,f1) +/* fprsqrta */ +#define FPRSQRTA(f1,p2,f3) F7(1,SF_S0,p2,f3,f1) +/* frcpa */ +#define FRCPA(f1,p2,f2,f3) F6(0,SF_S0,p2,f3,f2,f1) +/* frsqrta */ +#define FRSQRTA(f1,p2,f3) F7(0,SF_S0,p2,f3,f1) +/* fselect */ +#define FSELECT(f1,f3,f4,f2) F3(f4,f3,f2,f1) +#define FSETC(amsk,omsk) F12(SF_S0,4,omsk,amsk) +/* fsub */ +#define FSUB(f1,f3,f2) FMS(f1,f3,1,f2) +#define FSUB_S(f1,f3,f2) FMS_S(f1,f3,1,f2) +#define FSUB_D(f1,f3,f2) FMS_D(f1,f3,1,f2) +/* fswap */ +#define FSWAP(f1,f2,f3) F9(0,0x34,f3,f2,f1) +#define FSWAP_NL(f1,f2,f3) F9(0,0x35,f3,f2,f1) +#define FSWAP_NR(f1,f2,f3) F9(0,0x36,f3,f2,f1) +/* fsxt */ +#define FSXT_R(f1,f2,f3) F9(0,0x3c,f3,f2,f1) +#define FSXT_L(f1,f2,f3) F9(0,0x3d,f3,f2,f1) +/* fxor */ +#define FXOR(f1,f2,f3) F9(0,0x2f,f3,f2,f1) +/* getf */ +#define GETF_S(r1,f2) M19(0x1e,f2,r1) +#define GETF_D(r1,f2) M19(0x1f,f2,r1) +#define GETF_EXP(r1,f2) M19(0x1d,f2,r1) +#define GETF_SIG(r1,f2) M19(0x1c,f2,r1) +/* hint */ +#define HINT_F(im) F16(1,im) +/* invala */ +#define INVALAF_E(f1) M27(f1) +/* ldf */ +#define LDFS(f1,r3) M9(0x02,LD_NONE,r3,f1) +#define LDFD(f1,r3) M9(0x03,LD_NONE,r3,f1) +#define LDF8(f1,r3) M9(0x01,LD_NONE,r3,f1) +#define LDFE(f1,r3) M9(0x00,LD_NONE,r3,f1) +#define LDFS_S(f1,r3) M9(0x06,LD_NONE,r3,f1) +#define LDFD_S(f1,r3) M9(0x07,LD_NONE,r3,f1) +#define LDF8_S(f1,r3) M9(0x05,LD_NONE,r3,f1) +#define LDFE_S(f1,r3) M9(0x04,LD_NONE,r3,f1) +#define LDFS_A(f1,r3) M9(0x0a,LD_NONE,r3,f1) +#define LDFD_A(f1,r3) M9(0x0b,LD_NONE,r3,f1) +#define LDF8_A(f1,r3) M9(0x09,LD_NONE,r3,f1) +#define LDFE_A(f1,r3) M9(0x08,LD_NONE,r3,f1) +#define LDFS_SA(f1,r3) M9(0x0e,LD_NONE,r3,f1) +#define LDFD_SA(f1,r3) M9(0x0f,LD_NONE,r3,f1) +#define LDF8_SA(f1,r3) M9(0x0d,LD_NONE,r3,f1) +#define LDFE_SA(f1,r3) M9(0x0c,LD_NONE,r3,f1) +#define LDF_FILL(f1,r3) M9(0x1b,LD_NONE,r3,f1) +#define LDFS_C_CLR(f1,r3) M9(0x22,LD_NONE,r3,f1) +#define LDFD_C_CLR(f1,r3) M9(0x23,LD_NONE,r3,f1) +#define LDF8_C_CLR(f1,r3) M9(0x21,LD_NONE,r3,f1) +#define LDFE_C_CLR(f1,r3) M9(0x20,LD_NONE,r3,f1) +#define LDFS_C_NC(f1,r3) M9(0x26,LD_NONE,r3,f1) +#define LDFD_C_NC(f1,r3) M9(0x27,LD_NONE,r3,f1) +#define LDF8_C_NC(f1,r3) M9(0x25,LD_NONE,r3,f1) +#define LDFE_C_NC(f1,r3) M9(0x24,LD_NONE,r3,f1) +#define LDFS_inc(f1,r3,r2) M7(0x02,LD_NONE,r3,r2,f1) +#define LDFD_inc(f1,r3,r2) M7(0x03,LD_NONE,r3,r2,f1) +#define LDF8_inc(f1,r3,r2) M7(0x01,LD_NONE,r3,r2,f1) +#define LDFE_inc(f1,r3,r2) M7(0x00,LD_NONE,r3,r2,f1) +#define LDFS_S_inc(f1,r3,r2) M7(0x06,LD_NONE,r3,r2,f1) +#define LDFD_S_inc(f1,r3,r2) M7(0x07,LD_NONE,r3,r2,f1) +#define LDF8_S_inc(f1,r3,r2) M7(0x05,LD_NONE,r3,r2,f1) +#define LDFE_S_inc(f1,r3,r2) M7(0x04,LD_NONE,r3,r2,f1) +#define LDFS_A_inc(f1,r3,r2) M7(0x0a,LD_NONE,r3,r2,f1) +#define LDXFD_A_inc(f1,r3,r2) M7(0x0b,LD_NONE,r3,r2,f1) +#define LDXF8_A_inc(f1,r3,r2) M7(0x09,LD_NONE,r3,r2,f1) +#define LDXFE_A_inc(f1,r3,r2) M7(0x08,LD_NONE,r3,r2,f1) +#define LDXFS_SA_inc(f1,r3,r2) M7(0x0e,LD_NONE,r3,r2,f1) +#define LDXFD_SA_inc(f1,r3,r2) M7(0x0f,LD_NONE,r3,r2,f1) +#define LDXF8_SA_inc(f1,r3,r2) M7(0x0d,LD_NONE,r3,r2,f1) +#define LDXFE_SA_inc(f1,r3,r2) M7(0x0c,LD_NONE,r3,r2,f1) +#define LDXFS_FILL_inc(f1,r3,r2) M7(0x1b,LD_NONE,r3,r2,f1) +#define LDXFS_C_CLR_inc(f1,r3,r2) M7(0x22,LD_NONE,r3,r2,f1) +#define LDXFD_C_CLR_inc(f1,r3,r2) M7(0x23,LD_NONE,r3,r2,f1) +#define LDXF8_C_CLR_inc(f1,r3,r2) M7(0x21,LD_NONE,r3,r2,f1) +#define LDXFE_C_CLR_inc(f1,r3,r2) M7(0x20,LD_NONE,r3,r2,f1) +#define LDXFS_C_NC_inc(f1,r3,r2) M7(0x26,LD_NONE,r3,r2,f1) +#define LDXFD_C_NC_inc(f1,r3,r2) M7(0x27,LD_NONE,r3,r2,f1) +#define LDXF8_C_NC_inc(f1,r3,r2) M7(0x25,LD_NONE,r3,r2,f1) +#define LDXFE_C_NC_inc(f1,r3,r2) M7(0x24,LD_NONE,r3,r2,f1) +#define LDIFS_inc(f1,f3,im) M8(0x02,LD_NONE,f3,im,f1) +#define LDIFD_inc(f1,f3,im) M8(0x03,LD_NONE,f3,im,f1) +#define LDIF8_inc(f1,f3,im) M8(0x01,LD_NONE,f3,im,f1) +#define LDIFE_inc(f1,f3,im) M8(0x00,LD_NONE,f3,im,f1) +#define LDIFS_S_inc(f1,f3,im) M8(0x06,LD_NONE,f3,im,f1) +#define LDIFD_S_inc(f1,f3,im) M8(0x07,LD_NONE,f3,im,f1) +#define LDIF8_S_inc(f1,f3,im) M8(0x05,LD_NONE,f3,im,f1) +#define LDIFE_S_inc(f1,f3,im) M8(0x04,LD_NONE,f3,im,f1) +#define LDIFS_A_inc(f1,f3,im) M8(0x0a,LD_NONE,f3,im,f1) +#define LDIFD_A_inc(f1,f3,im) M8(0x0b,LD_NONE,f3,im,f1) +#define LDIF8_A_inc(f1,f3,im) M8(0x09,LD_NONE,f3,im,f1) +#define LDIFE_A_inc(f1,f3,im) M8(0x08,LD_NONE,f3,im,f1) +#define LDIF_FILL_inc(f1,f3,im) M8(0x1b,LD_NONE,f3,im,f1) +#define LDIFS_C_CLR_inc(f1,f3,im) M8(0x22,LD_NONE,f3,im,f1) +#define LDIFD_C_CLR_inc(f1,f3,im) M8(0x23,LD_NONE,f3,im,f1) +#define LDIF8_C_CLR_inc(f1,f3,im) M8(0x21,LD_NONE,f3,im,f1) +#define LDIFE_C_CLR_inc(f1,f3,im) M8(0x20,LD_NONE,f3,im,f1) +#define LDIFS_C_NC_inc(f1,f3,im) M8(0x26,LD_NONE,f3,im,f1) +#define LDIFD_C_NC_inc(f1,f3,im) M8(0x27,LD_NONE,f3,im,f1) +#define LDIF8_C_NC_inc(f1,f3,im) M8(0x25,LD_NONE,f3,im,f1) +#define LDIFE_C_NC_inc(f1,f3,im) M8(0x24,LD_NONE,f3,im,f1) +/* ldpf */ +#define LDFPS(f1,f2,r3) M11(0x02,LD_NONE,r3,f2,f1) +#define LDFPD(f1,f2,r3) M11(0x03,LD_NONE,r3,f2,f1) +#define LDFP8(f1,f2,r3) M11(0x01,LD_NONE,r3,f2,f1) +#define LDFPS_S(f1,f2,r3) M11(0x06,LD_NONE,r3,f2,f1) +#define LDFPD_S(f1,f2,r3) M11(0x07,LD_NONE,r3,f2,f1) +#define LDFP8_S(f1,f2,r3) M11(0x05,LD_NONE,r3,f2,f1) +#define LDFPS_A(f1,f2,r3) M11(0x0a,LD_NONE,r3,f2,f1) +#define LDFPD_A(f1,f2,r3) M11(0x0b,LD_NONE,r3,f2,f1) +#define LDFP8_A(f1,f2,r3) M11(0x09,LD_NONE,r3,f2,f1) +#define LDFPS_SA(f1,f2,r3) M11(0x0e,LD_NONE,r3,f2,f1) +#define LDFPD_SA(f1,f2,r3) M11(0x0f,LD_NONE,r3,f2,f1) +#define LDFP8_SA(f1,f2,r3) M11(0x0d,LD_NONE,r3,f2,f1) +#define LDFPS_C_CLR(f1,f2,r3) M11(0x22,LD_NONE,r3,f2,f1) +#define LDFPD_C_CLR(f1,f2,r3) M11(0x23,LD_NONE,r3,f2,f1) +#define LDFP8_C_CLR(f1,f2,r3) M11(0x21,LD_NONE,r3,f2,f1) +#define LDFPS_C_NC(f1,f2,r3) M11(0x26,LD_NONE,r3,f2,f1) +#define LDFPD_C_NC(f1,f2,r3) M11(0x27,LD_NONE,r3,f2,f1) +#define LDFP8_C_NC(f1,f2,r3) M11(0x25,LD_NONE,r3,f2,f1) +#define LDIFPS(f1,f2,r3) M12(0x02,LD_NONE,r3,f2,f1) +#define LDIFPD(f1,f2,r3) M12(0x03,LD_NONE,r3,f2,f1) +#define LDIFP8(f1,f2,r3) M12(0x01,LD_NONE,r3,f2,f1) +#define LDIFPS_S(f1,f2,r3) M12(0x06,LD_NONE,r3,f2,f1) +#define LDIFPD_S(f1,f2,r3) M12(0x07,LD_NONE,r3,f2,f1) +#define LDIFP8_S(f1,f2,r3) M12(0x05,LD_NONE,r3,f2,f1) +#define LDIFPS_A(f1,f2,r3) M12(0x0a,LD_NONE,r3,f2,f1) +#define LDIFPD_A(f1,f2,r3) M12(0x0b,LD_NONE,r3,f2,f1) +#define LDIFP8_A(f1,f2,r3) M12(0x09,LD_NONE,r3,f2,f1) +#define LDIFPS_SA(f1,f2,r3) M12(0x0e,LD_NONE,r3,f2,f1) +#define LDIFPD_SA(f1,f2,r3) M12(0x0f,LD_NONE,r3,f2,f1) +#define LDIFP8_SA(f1,f2,r3) M12(0x0d,LD_NONE,r3,f2,f1) +#define LDIFPS_C_CLR(f1,f2,r3) M12(0x22,LD_NONE,r3,f2,f1) +#define LDIFPD_C_CLR(f1,f2,r3) M12(0x23,LD_NONE,r3,f2,f1) +#define LDIFP8_C_CLR(f1,f2,r3) M12(0x21,LD_NONE,r3,f2,f1) +#define LDIFPS_C_NC(f1,f2,r3) M12(0x26,LD_NONE,r3,f2,f1) +#define LDIFPD_C_NC(f1,f2,r3) M12(0x27,LD_NONE,r3,f2,f1) +#define LDIFP8_C_NC(f1,f2,r3) M12(0x25,LD_NONE,r3,f2,f1) +/* mov - Move Floating-point Register */ +#define MOVF(f1,f3) FMERGE_S(f1,f3,f3) +/* nop */ +#define NOP_F(im) F16(0,im) +/* setf */ +#define SETF_S(f1,r2) M18(0x1e,r2,f1) +#define SETF_D(f1,r2) M18(0x1f,r2,f1) +#define SETF_EXP(f1,r2) M18(0x1d,r2,f1) +#define SETF_SIG(f1,r2) M18(0x1c,r2,f1) +/* stf */ +#define STFS(r3,f2) M13(0x32,ST_NONE,r3,f2) +#define STFD(r3,f2) M13(0x33,ST_NONE,r3,f2) +#define STF8(r3,f2) M13(0x31,ST_NONE,r3,f2) +#define STFE(r3,f2) M13(0x30,ST_NONE,r3,f2) +#define STF_SPILL(r3,f2) M13(0x3b,ST_NONE,r3,f2) +#define STFS_inc(r3,f2,im) M10(0x32,ST_NONE,r3,f2,im) +#define STFD_inc(r3,f2,im) M10(0x33,ST_NONE,r3,f2,im) +#define STF8_inc(r3,f2,im) M10(0x31,ST_NONE,r3,f2,im) +#define STFE_inc(r3,f2,im) M10(0x30,ST_NONE,r3,f2,im) +#define STF_SPILL_inc(r3,f2,im) M10(0x3b,ST_NONE,r3,f2,im) +/* xma */ +#define XMA_L(f1,f3,f4,f2) F2(0,f4,f3,f2,f1) +#define XMA_LU(f1,f3,f4,f2) XMA_L(f1,f3,f4,f2) +#define XMA_H(f1,f3,f4,f2) F2(3,f4,f3,f2,f1) +#define XMA_HU(f1,f3,f4,f2) F2(2,f4,f3,f2,f1) +/* xmpy */ +#define XMPY_L(f1,f3,f4) XMA_L(f1,f3,f4,0) +#define XMPY_LU(f1,f3,f4) XMA_L(f1,f3,f4,0) +#define XMPY_H(f1,f3,f4) XMA_H(f1,f3,f4,0) +#define XMPY_HU(f1,f3,f4) XMA_HU(f1,f3,f4,0) + +#define movr_f(r0,r1) movr_d(r0,r1) +#define movr_d(r0,r1) MOVF(r0,r1) +#define movi_f(r0,i0) _movi_f(_jit,r0,i0) +static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*); +#define movi_d(r0,i0) _movi_d(_jit,r0,i0) +static void _movi_d(jit_state_t*,jit_int32_t,jit_float64_t*); +#define movr_w_f(r0,r1) _movr_w_f(_jit,r0,r1) +static void _movr_w_f(jit_state_t*,jit_int32_t,jit_int32_t); +#define movr_f_w(r0,r1) _movr_f_w(_jit,r0,r1) +static void _movr_f_w(jit_state_t*,jit_int32_t,jit_int32_t); +#define movr_w_d(r0,r1) _movr_w_d(_jit,r0,r1) +static void _movr_w_d(jit_state_t*,jit_int32_t,jit_int32_t); +#define movr_d_w(r0,r1) _movr_d_w(_jit,r0,r1) +static void _movr_d_w(jit_state_t*,jit_int32_t,jit_int32_t); +#define movi_f_w(r0,i0) _movi_f_w(_jit,r0,i0) +static void _movi_f_w(jit_state_t*,jit_int32_t,jit_float32_t*); +#define movi_d_w(r0,i0) _movi_d_w(_jit,r0,i0) +static void _movi_d_w(jit_state_t*,jit_int32_t,jit_float64_t*); +#define absr_f(r0,r1) absr_d(r0,r1) +#define absr_d(r0,r1) FABS(r0,r1) +#define negr_f(r0,r1) negr_d(r0,r1) +#define negr_d(r0,r1) FNEG(r0,r1) +#define sqrtr_f(r0,r1) _sqrtr_f(_jit,r0,r1) +static void _sqrtr_f(jit_state_t*,jit_int32_t,jit_int32_t); +#define sqrtr_d(r0,r1) _sqrtr_d(_jit,r0,r1) +static void _sqrtr_d(jit_state_t*,jit_int32_t,jit_int32_t); +#define extr_f_d(r0,r1) FNORM_D(r0,r1) +#define extr_d_f(r0,r1) FNORM_S(r0,r1) +#define extr_f(r0,r1) _extr_f(_jit,r0,r1) +static void _extr_f(jit_state_t*,jit_int32_t,jit_int32_t); +#define extr_d(r0,r1) _extr_d(_jit,r0,r1) +static void _extr_d(jit_state_t*,jit_int32_t,jit_int32_t); +#define truncr_f_i(r0,r1) truncr_d_l(r0,r1) +#define truncr_d_i(r0,r1) truncr_d_l(r0,r1) +#define truncr_f_l(r0,r1) truncr_d_l(r0,r1) +#define truncr_d_l(r0,r1) _truncr_d_l(_jit,r0,r1) +static void _truncr_d_l(jit_state_t*,jit_int32_t,jit_int32_t); +#define addr_f(r0,r1,r2) FADD_S(r0,r1,r2) +#define addi_f(r0,r1,i0) _addi_f(_jit,r0,r1,i0) +static void _addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define addr_d(r0,r1,r2) FADD_D(r0,r1,r2) +#define addi_d(r0,r1,i0) _addi_d(_jit,r0,r1,i0) +static void _addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define subr_f(r0,r1,r2) FSUB_S(r0,r1,r2) +#define subi_f(r0,r1,i0) _subi_f(_jit,r0,r1,i0) +static void _subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define subr_d(r0,r1,r2) FSUB_D(r0,r1,r2) +#define subi_d(r0,r1,i0) _subi_d(_jit,r0,r1,i0) +static void _subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define rsbr_f(r0,r1,r2) subr_f(r0,r2,r1) +#define rsbi_f(r0,r1,i0) _rsbi_f(_jit,r0,r1,i0) +static void _rsbi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define rsbr_d(r0,r1,r2) subr_d(r0,r2,r1) +#define rsbi_d(r0,r1,i0) _rsbi_d(_jit,r0,r1,i0) +static void _rsbi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define mulr_f(r0,r1,r2) FMPY_S(r0,r1,r2) +#define muli_f(r0,r1,i0) _muli_f(_jit,r0,r1,i0) +static void _muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define mulr_d(r0,r1,r2) FMPY_D(r0,r1,r2) +#define muli_d(r0,r1,i0) _muli_d(_jit,r0,r1,i0) +static void _muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define divr_f(r0,r1,r2) _divr_f(_jit,r0,r1,r2) +static void _divr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define divi_f(r0,r1,i0) _divi_f(_jit,r0,r1,i0) +static void _divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define divr_d(r0,r1,r2) _divr_d(_jit,r0,r1,r2) +static void _divr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define divi_d(r0,r1,i0) _divi_d(_jit,r0,r1,i0) +static void _divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define ltr_f(r0,r1,r2) ltr_d(r0,r1,r2) +#define ltr_d(r0,r1,r2) _ltr_d(_jit,r0,r1,r2) +static void _ltr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define lti_f(r0,r1,i0) _lti_f(_jit,r0,r1,i0) +static void _lti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define lti_d(r0,r1,i0) _lti_d(_jit,r0,r1,i0) +static void _lti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define ler_f(r0,r1,r2) ler_d(r0,r1,r2) +#define ler_d(r0,r1,r2) _ler_d(_jit,r0,r1,r2) +static void _ler_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define lei_f(r0,r1,i0) _lei_f(_jit,r0,r1,i0) +static void _lei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define lei_d(r0,r1,i0) _lei_d(_jit,r0,r1,i0) +static void _lei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define eqr_f(r0,r1,r2) eqr_d(r0,r1,r2) +#define eqr_d(r0,r1,r2) _eqr_d(_jit,r0,r1,r2) +static void _eqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define eqi_f(r0,r1,i0) _eqi_f(_jit,r0,r1,i0) +static void _eqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define eqi_d(r0,r1,i0) _eqi_d(_jit,r0,r1,i0) +static void _eqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define ger_f(r0,r1,r2) ger_d(r0,r1,r2) +#define ger_d(r0,r1,r2) _ger_d(_jit,r0,r1,r2) +static void _ger_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define gei_f(r0,r1,i0) _gei_f(_jit,r0,r1,i0) +static void _gei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define gei_d(r0,r1,i0) _gei_d(_jit,r0,r1,i0) +static void _gei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define gtr_f(r0,r1,r2) gtr_d(r0,r1,r2) +#define gtr_d(r0,r1,r2) _gtr_d(_jit,r0,r1,r2) +static void _gtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define gti_f(r0,r1,i0) _gti_f(_jit,r0,r1,i0) +static void _gti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define gti_d(r0,r1,i0) _gti_d(_jit,r0,r1,i0) +static void _gti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define ner_f(r0,r1,r2) ner_d(r0,r1,r2) +#define ner_d(r0,r1,r2) _ner_d(_jit,r0,r1,r2) +static void _ner_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define nei_f(r0,r1,i0) _nei_f(_jit,r0,r1,i0) +static void _nei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define nei_d(r0,r1,i0) _nei_d(_jit,r0,r1,i0) +static void _nei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define unltr_f(r0,r1,r2) unltr_d(r0,r1,r2) +#define unltr_d(r0,r1,r2) _unltr_d(_jit,r0,r1,r2) +static void _unltr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define unlti_f(r0,r1,i0) _unlti_f(_jit,r0,r1,i0) +static void _unlti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define unlti_d(r0,r1,i0) _unlti_d(_jit,r0,r1,i0) +static void _unlti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define unler_f(r0,r1,r2) unler_d(r0,r1,r2) +#define unler_d(r0,r1,r2) _unler_d(_jit,r0,r1,r2) +static void _unler_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define unlei_f(r0,r1,i0) _unlei_f(_jit,r0,r1,i0) +static void _unlei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define unlei_d(r0,r1,i0) _unlei_d(_jit,r0,r1,i0) +static void _unlei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define uneqr_f(r0,r1,r2) uneqr_d(r0,r1,r2) +#define uneqr_d(r0,r1,r2) _uneqr_d(_jit,r0,r1,r2) +static void _uneqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define uneqi_f(r0,r1,i0) _uneqi_f(_jit,r0,r1,i0) +static void _uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define uneqi_d(r0,r1,i0) _uneqi_d(_jit,r0,r1,i0) +static void _uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define unger_f(r0,r1,r2) unger_d(r0,r1,r2) +#define unger_d(r0,r1,r2) _unger_d(_jit,r0,r1,r2) +static void _unger_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ungei_f(r0,r1,i0) _ungei_f(_jit,r0,r1,i0) +static void _ungei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define ungei_d(r0,r1,i0) _ungei_d(_jit,r0,r1,i0) +static void _ungei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define ungtr_f(r0,r1,r2) ungtr_d(r0,r1,r2) +#define ungtr_d(r0,r1,r2) _ungtr_d(_jit,r0,r1,r2) +static void _ungtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ungti_f(r0,r1,i0) _ungti_f(_jit,r0,r1,i0) +static void _ungti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define ungti_d(r0,r1,i0) _ungti_d(_jit,r0,r1,i0) +static void _ungti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define ltgtr_f(r0,r1,r2) ltgtr_d(r0,r1,r2) +#define ltgtr_d(r0,r1,r2) _ltgtr_d(_jit,r0,r1,r2) +static void _ltgtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ltgti_f(r0,r1,i0) _ltgti_f(_jit,r0,r1,i0) +static void _ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define ltgti_d(r0,r1,i0) _ltgti_d(_jit,r0,r1,i0) +static void _ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define ordr_f(r0,r1,r2) ordr_d(r0,r1,r2) +#define ordr_d(r0,r1,r2) _ordr_d(_jit,r0,r1,r2) +static void _ordr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ordi_f(r0,r1,i0) _ordi_f(_jit,r0,r1,i0) +static void _ordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define ordi_d(r0,r1,i0) _ordi_d(_jit,r0,r1,i0) +static void _ordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define unordr_f(r0,r1,r2) unordr_d(r0,r1,r2) +#define unordr_d(r0,r1,r2) _unordr_d(_jit,r0,r1,r2) +static void _unordr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define unordi_f(r0,r1,i0) _unordi_f(_jit,r0,r1,i0) +static void _unordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +#define unordi_d(r0,r1,i0) _unordi_d(_jit,r0,r1,i0) +static void _unordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define ldr_f(r0,r1) LDFS(r0,r1) +#define ldi_f(r0,i0) _ldi_f(_jit,r0,i0) +static void _ldi_f(jit_state_t*,jit_int32_t,jit_word_t); +#define ldxr_f(r0,r1,r2) _ldxr_f(_jit,r0,r1,r2) +static void _ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ldxi_f(r0,r1,i0) _ldxi_f(_jit,r0,r1,i0) +static void _ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ldr_d(r0,r1) LDFD(r0,r1) +#define ldi_d(r0,i0) _ldi_d(_jit,r0,i0) +static void _ldi_d(jit_state_t*,jit_int32_t,jit_word_t); +#define ldxr_d(r0,r1,r2) _ldxr_d(_jit,r0,r1,r2) +static void _ldxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define ldxi_d(r0,r1,i0) _ldxi_d(_jit,r0,r1,i0) +static void _ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define str_f(r0,r1) STFS(r0,r1) +#define sti_f(i0,r0) _sti_f(_jit,i0,r0) +static void _sti_f(jit_state_t*,jit_word_t,jit_int32_t); +#define stxr_f(r0,r1,r2) _stxr_f(_jit,r0,r1,r2) +static void _stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define stxi_f(i0,r0,r1) _stxi_f(_jit,i0,r0,r1) +static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define str_d(r0,r1) STFD(r0,r1) +#define sti_d(i0,r0) _sti_d(_jit,i0,r0) +static void _sti_d(jit_state_t*,jit_word_t,jit_int32_t); +#define stxr_d(r0,r1,r2) _stxr_d(_jit,r0,r1,r2) +static void _stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define stxi_d(i0,r0,r1) _stxi_d(_jit,i0,r0,r1) +static void _stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bltr_f(i0,r0,r1) bltr_d(i0,r0,r1) +#define bltr_d(i0,r0,r1) _bltr_d(_jit,i0,r0,r1) +static jit_word_t _bltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define blti_f(i0,r0,i1) _blti_f(_jit,i0,r0,i1) +static jit_word_t _blti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define blti_d(i0,r0,i1) _blti_d(_jit,i0,r0,i1) +static jit_word_t _blti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +#define bler_f(i0,r0,r1) bler_d(i0,r0,r1) +#define bler_d(i0,r0,r1) _bler_d(_jit,i0,r0,r1) +static jit_word_t _bler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define blei_f(i0,r0,i1) _blei_f(_jit,i0,r0,i1) +static jit_word_t _blei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define blei_d(i0,r0,i1) _blei_d(_jit,i0,r0,i1) +static jit_word_t _blei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +#define beqr_f(i0,r0,r1) beqr_d(i0,r0,r1) +#define beqr_d(i0,r0,r1) _beqr_d(_jit,i0,r0,r1) +static jit_word_t _beqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define beqi_f(i0,r0,i1) _beqi_f(_jit,i0,r0,i1) +static jit_word_t _beqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define beqi_d(i0,r0,i1) _beqi_d(_jit,i0,r0,i1) +static jit_word_t _beqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +#define bger_f(i0,r0,r1) bger_d(i0,r0,r1) +#define bger_d(i0,r0,r1) _bger_d(_jit,i0,r0,r1) +static jit_word_t _bger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bgei_f(i0,r0,i1) _bgei_f(_jit,i0,r0,i1) +static jit_word_t _bgei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define bgei_d(i0,r0,i1) _bgei_d(_jit,i0,r0,i1) +static jit_word_t _bgei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +#define bgtr_f(i0,r0,r1) bgtr_d(i0,r0,r1) +#define bgtr_d(i0,r0,r1) _bgtr_d(_jit,i0,r0,r1) +static jit_word_t _bgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bgti_f(i0,r0,i1) _bgti_f(_jit,i0,r0,i1) +static jit_word_t _bgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define bgti_d(i0,r0,i1) _bgti_d(_jit,i0,r0,i1) +static jit_word_t _bgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +#define bner_f(i0,r0,r1) bner_d(i0,r0,r1) +#define bner_d(i0,r0,r1) _bner_d(_jit,i0,r0,r1) +static jit_word_t _bner_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bnei_f(i0,r0,i1) _bnei_f(_jit,i0,r0,i1) +static jit_word_t _bnei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define bnei_d(i0,r0,i1) _bnei_d(_jit,i0,r0,i1) +static jit_word_t _bnei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +#define bunltr_f(i0,r0,r1) bunltr_d(i0,r0,r1) +#define bunltr_d(i0,r0,r1) _bunltr_d(_jit,i0,r0,r1) +static jit_word_t _bunltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bunlti_f(i0,r0,i1) _bunlti_f(_jit,i0,r0,i1) +static jit_word_t _bunlti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define bunlti_d(i0,r0,i1) _bunlti_d(_jit,i0,r0,i1) +static jit_word_t _bunlti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +#define bunler_f(i0,r0,r1) bunler_d(i0,r0,r1) +#define bunler_d(i0,r0,r1) _bunler_d(_jit,i0,r0,r1) +static jit_word_t _bunler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bunlei_f(i0,r0,i1) _bunlei_f(_jit,i0,r0,i1) +static jit_word_t _bunlei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define bunlei_d(i0,r0,i1) _bunlei_d(_jit,i0,r0,i1) +static jit_word_t _bunlei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +#define buneqr_f(i0,r0,r1) buneqr_d(i0,r0,r1) +#define buneqr_d(i0,r0,r1) _buneqr_d(_jit,i0,r0,r1) +static jit_word_t _buneqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define buneqi_f(i0,r0,i1) _buneqi_f(_jit,i0,r0,i1) +static jit_word_t _buneqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define buneqi_d(i0,r0,i1) _buneqi_d(_jit,i0,r0,i1) +static jit_word_t _buneqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +#define bunger_f(i0,r0,r1) bunger_d(i0,r0,r1) +#define bunger_d(i0,r0,r1) _bunger_d(_jit,i0,r0,r1) +static jit_word_t _bunger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bungei_f(i0,r0,i1) _bungei_f(_jit,i0,r0,i1) +static jit_word_t _bungei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define bungei_d(i0,r0,i1) _bungei_d(_jit,i0,r0,i1) +static jit_word_t _bungei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +#define bungtr_f(i0,r0,r1) bungtr_d(i0,r0,r1) +#define bungtr_d(i0,r0,r1) _bungtr_d(_jit,i0,r0,r1) +static jit_word_t _bungtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bungti_f(i0,r0,i1) _bungti_f(_jit,i0,r0,i1) +static jit_word_t _bungti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define bungti_d(i0,r0,i1) _bungti_d(_jit,i0,r0,i1) +static jit_word_t _bungti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +#define bltgtr_f(i0,r0,r1) bltgtr_d(i0,r0,r1) +#define bltgtr_d(i0,r0,r1) _bltgtr_d(_jit,i0,r0,r1) +static jit_word_t _bltgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bltgti_f(i0,r0,i1) _bltgti_f(_jit,i0,r0,i1) +static jit_word_t _bltgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define bltgti_d(i0,r0,i1) _bltgti_d(_jit,i0,r0,i1) +static jit_word_t _bltgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +#define bordr_f(i0,r0,r1) bordr_d(i0,r0,r1) +#define bordr_d(i0,r0,r1) _bordr_d(_jit,i0,r0,r1) +static jit_word_t _bordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bordi_f(i0,r0,i1) _bordi_f(_jit,i0,r0,i1) +static jit_word_t _bordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define bordi_d(i0,r0,i1) _bordi_d(_jit,i0,r0,i1) +static jit_word_t _bordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +#define bunordr_f(i0,r0,r1) bunordr_d(i0,r0,r1) +#define bunordr_d(i0,r0,r1) _bunordr_d(_jit,i0,r0,r1) +static jit_word_t _bunordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bunordi_f(i0,r0,i1) _bunordi_f(_jit,i0,r0,i1) +static jit_word_t _bunordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +#define bunordi_d(i0,r0,i1) _bunordi_d(_jit,i0,r0,i1) +static jit_word_t _bunordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1) +static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t); +#endif + +#if CODE +static void +_M7(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t r2, jit_word_t f1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(r2 & ~0x7fL)); + assert(!(f1 & ~0x7fL)); + TSTREG2(r2, r3); + TSTPRED(_p); + TSTFREG1(f1); + inst((6L<<37)|(1L<<36)|(x6<<30)|(ht<<28)| + (r3<<20)|(r2<<13)|(f1<<6)|_p, INST_M); + SETFREG(f1); + SETREG(r3); +} + +static void +_M8(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t im, jit_word_t f1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(im > -256 && im <= 255); + assert(!(f1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + TSTFREG1(f1); + inst((7L<<37)|(((im>>8)&1L)<<36)|(x6<<30)|(ht<<28)| + (((im>>8)&1L)<<27)|(r3<<20)|((im&0x7fLL)<<13)|(f1<<6)|_p, INST_M); + SETFREG(f1); + SETREG(r3); +} + +static void +_M9(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t f1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(f1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + TSTFREG1(f1); + inst((6L<<37)|(x6<<30)|(ht<<28)|(r3<<20)|(f1<<6)|_p, INST_M); + SETFREG(f1); +} + +static void +_M10(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t f2, jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(f2 & ~0x7fL)); + assert(im > -256 && im <= 255); + TSTREG1(r3); + TSTFREG1(f2); + TSTPRED(_p); + inst((7L<<37)|(((im>>8)&1L)<<36)|(x6<<30)|(ht<<28)| + (((im>>8)&1L)<<27)|(r3<<20)|(f2<<13)|((im&0x7fL)<<6)|_p, INST_M); + SETREG(r3); +} + +static void +_M11(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t f2, jit_word_t f1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(f2 & ~0x7fL)); + assert(!(f1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + TSTFREG2(f1, f2); + inst((6L<<37)|(x6<<30)|(ht<<28)|(1L<<27)| + (r3<<20)|(f2<<13)|(f1<<6)|_p, INST_M); + SETFREG(f1); + SETFREG(f2); +} + +static void +_M12(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t ht, jit_word_t r3, jit_word_t f2, jit_word_t f1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(ht & ~0x3L)); + assert(!(r3 & ~0x7fL)); + assert(!(f2 & ~0x7fL)); + assert(!(f1 & ~0x7fL)); + TSTREG1(r3); + TSTPRED(_p); + TSTFREG2(f1, f2); + inst((6L<<37)|(1L<<36)|(x6<<30)|(ht<<28)| + (1L<<27)|(r3<<20)|(f2<<13)|(f1<<6)|_p, INST_M); + SETFREG(f1); + SETFREG(f2); + SETREG(r3); +} + +static void +_M18(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t r2, jit_word_t f1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(r2 & ~0x7fL)); + assert(!(f1 & ~0x7fL)); + TSTREG1(r2); + TSTPRED(_p); + TSTFREG1(f1); + inst((6L<<37)|(x6<<30)|(1L<<27)|(r2<<13)|(f1<<6)|_p, INST_M); + SETFREG(f1); +} + +static void +_M19(jit_state_t *_jit, jit_word_t _p, + jit_word_t x6, jit_word_t f2, jit_word_t r1) +{ + assert(!(_p & ~0x3fL)); + assert(!(x6 & ~0x3fL)); + assert(!(f2 & ~0x7fL)); + assert(!(r1 & ~0x7fL)); + TSTFREG1(f2); + TSTPRED(_p); + TSTREG1(r1); + inst((4L<<37)|(x6<<30)|(1L<<27)|(f2<<13)|(r1<<6)|_p, INST_M); + SETREG(r1); +} + +static void +F1_(jit_state_t *_jit, jit_word_t _p, + jit_word_t op, jit_word_t x, jit_word_t sf, + jit_word_t f4, jit_word_t f3, jit_word_t f2, jit_word_t f1) +{ + assert(!(_p & ~0x3fL)); + assert(!(op & ~0xfL)); + assert(!(x & ~0x1L)); + assert(!(sf & ~0x3L)); + assert(!(f4 & ~0x7fL)); + assert(!(f3 & ~0x7fL)); + assert(!(f2 & ~0x7fL)); + assert(!(f1 & ~0x7fL)); + TSTFREG3(f2, f3, f4); + TSTPRED(_p); + TSTFREG1(f1); + inst((op<<37)|(x<<36)|(sf<<34)|(f4<<27)| + (f3<<20)|(f2<<13)|(f1<<6)|_p, INST_F); + SETFREG(f1); +} + +static void +F4_(jit_state_t *_jit, jit_word_t _p, + jit_word_t rb, jit_word_t sf, jit_word_t ra, jit_word_t p2, + jit_word_t f3, jit_word_t f2, jit_word_t ta, jit_word_t p1) +{ + assert(!(_p & ~0x3fL)); + assert(!(rb & ~0x1L)); + assert(!(sf & ~0x3L)); + assert(!(ra & ~0x1L)); + assert(!(p2 & ~0x3fL)); + assert(!(f3 & ~0x7fL)); + assert(!(f2 & ~0x7fL)); + assert(!(ta & ~0x1L)); + assert(!(p1 & ~0x3fL)); + TSTFREG2(f2, f3); + TSTPRED(_p); + inst((4L<<37)|(rb<<36)|(sf<<34)|(ra<<33)|(p2<<27)| + (f3<<20)|(f2<<13)|(ta<<12)|(p1<<6)|_p, INST_F); + if (p1) + _jitc->pred |= 1 << p1; + if (p2) + _jitc->pred |= 1 << p2; +} + +static void +F5_(jit_state_t *_jit, jit_word_t _p, + jit_word_t p2, jit_word_t fc, jit_word_t f2, jit_word_t ta, jit_word_t p1) +{ + assert(!(_p & ~0x3fL)); + assert(!(p2 & ~0x3fL)); + assert(!(fc & ~0x1ffL)); + assert(!(f2 & ~0x7fL)); + assert(!(ta & ~0x1L)); + assert(!(p1 & ~0x3fL)); + TSTFREG1(f2); + TSTPRED(_p); + inst((5L<<37)|(((fc>>7)&3L)<<33)|(p2<<27)| + ((fc&0x7fL)<<20)|(f2<<13)|(ta<<12)|(p1<<6)|_p, INST_F); + if (p1) + _jitc->pred |= 1 << p1; + if (p2) + _jitc->pred |= 1 << p2; +} + +static void +F6x_(jit_state_t *_jit, jit_word_t _p, + jit_word_t op, jit_word_t q, jit_word_t sf, + jit_word_t p2, jit_word_t f3, jit_word_t f2, jit_word_t f1) +{ + assert(!(_p & ~0x3fL)); + assert(!(op & ~0xfL)); + assert(!(q & ~0x1L)); + assert(!(sf & ~0x3L)); + assert(!(p2 & ~0x3fL)); + assert(!(f3 & ~0x7fL)); + assert(!(f2 & ~0x7fL)); + assert(!(f1 & ~0x7fL)); + TSTFREG2(f2, f3); + TSTPRED(_p); + TSTFREG1(f1); + inst((op<<37)|(q<<36)|(sf<<34)|(1L<<33)| + (p2<<27)|(f3<<20)|(f2<<13)|(f1<<6)|_p, INST_F); + SETFREG(f1); + if (p2) + _jitc->pred |= 1 << p2; +} + +static void +F8_(jit_state_t *_jit, jit_word_t _p, + jit_word_t op, jit_word_t sf, jit_word_t x6, + jit_word_t f3, jit_word_t f2, jit_word_t f1) +{ + assert(!(_p & ~0x3fL)); + assert(!(op & ~0xfL)); + assert(!(sf & ~0x3L)); + assert(!(x6 & ~0x3fL)); + assert(!(f3 & ~0x7fL)); + assert(!(f2 & ~0x7fL)); + assert(!(f1 & ~0x7fL)); + TSTFREG2(f2, f3); + TSTPRED(_p); + TSTFREG1(f1); + inst((op<<37)|(sf<<34)|(x6<<27)|(f3<<20)|(f2<<13)|(f1<<6)|_p, INST_F); + SETFREG(f1); +} + +static void +F12_(jit_state_t *_jit, jit_word_t _p, + jit_word_t sf, jit_word_t x6, jit_word_t omsk, jit_word_t amsk) +{ + assert(!(_p & ~0x3fL)); + assert(!(sf & ~0x3L)); + assert(!(x6 & ~0x3fL)); + assert(!(omsk & ~0x7fL)); + assert(!(amsk & ~0x7fL)); + TSTPRED(_p); + inst((sf<<34)|(x6<<27)|(omsk<<20)|(amsk<<13), INST_F); +} + +static void +F14x_(jit_state_t* _jit, jit_word_t _p, + jit_word_t sf, jit_word_t x, jit_word_t x6, jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(sf & ~0x3L)); + assert(!(x & ~0x1L)); + assert(!(x6 & ~0x3fL)); + assert(!(im & ~0x1ffffL)); + TSTPRED(_p); + inst((((im>>20)&1L)<<36)|(sf<<34)|(x<<33)| + (x6<<27)|((im&0xffffL)<<6)|_p, INST_F); +} + +static void +F16_(jit_state_t* _jit, jit_word_t _p, + jit_word_t y, jit_word_t im) +{ + assert(!(_p & ~0x3fL)); + assert(!(y & ~0x1L)); + assert(!(im & ~0x1ffffL)); + TSTPRED(_p); + inst((((im>>20)&1L)<<36)|(y<<27)|(1L<<26)|((im&0xffffL)<<6)|_p, INST_F); +} + +static void +_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_int32_t reg; + + if (_jitc->no_data) { + data.f = *i0; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.i & 0xffffffff); + SETF_S(r0, rn(reg)); + jit_unget_reg(reg); + } + else + ldi_f(r0, (jit_word_t)i0); +} + +static void +_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + union { + jit_word_t w; + jit_float64_t d; + } data; + jit_int32_t reg; + + if (_jitc->no_data) { + data.d = *i0; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.w); + SETF_D(r0, rn(reg)); + jit_unget_reg(reg); + } + else + ldi_d(r0, (jit_word_t)i0); +} + +static void +_movr_w_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + /* Should be used only in this case (with out0 == 120) */ + if (r1 >= 120) + r1 = _jitc->rout + (r1 - 120); + SETF_S(r0, r1); +} + +static void +_movr_f_w(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + /* Should actually be used only in this case (with out0 == 120) */ + if (r0 >= 120) + r0 = _jitc->rout + (r0 - 120); + GETF_S(r0, r1); +} + +static void +_movi_f_w(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) +{ + jit_data_t data; + + /* Should be used only in this case (with out0 == 120) */ + if (r0 >= 120) + r0 = _jitc->rout + (r0 - 120); + if (_jitc->no_data) { + data.f = *i0; + movi(r0, data.q.l); + } + else + ldi_i(r0, (jit_word_t)i0); +} + +static void +_movr_w_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + /* Should be used only in this case (with out0 == 120) */ + if (r1 >= 120) + r1 = _jitc->rout + (r1 - 120); + SETF_D(r0, r1); +} + +static void +_movr_d_w(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + /* Should be used only in this case (with out0 == 120) */ + if (r0 >= 120) + r0 = _jitc->rout + (r0 - 120); + GETF_D(r0, r1); +} + +static void +_movi_d_w(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + union { + jit_word_t w; + jit_float64_t d; + } data; + + /* Should be used only in this case (with out0 == 120) */ + if (r0 >= 120) + r0 = _jitc->rout + (r0 - 120); + if (_jitc->no_data) { + data.d = *i0; + movi(r0, data.w); + } + else + ldi_l(r0, (jit_word_t)i0); +} + +#define fpr_opi(name, type, size) \ +static void \ +_##name##i_##type(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, \ + jit_float##size##_t *i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr); \ + movi_##type(rn(reg), i0); \ + name##r_##type(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +#define fpr_bopi(name, type, size) \ +static jit_word_t \ +_b##name##i_##type(jit_state_t *_jit, \ + jit_word_t i0, jit_int32_t r0, \ + jit_float##size##_t *i1) \ +{ \ + jit_word_t word; \ + jit_int32_t reg = jit_get_reg(jit_class_fpr| \ + jit_class_nospill); \ + movi_##type(rn(reg), i1); \ + word = b##name##r_##type(i0, r0, rn(reg)); \ + jit_unget_reg(reg); \ + return (word); \ +} +#define fopi(name) fpr_opi(name, f, 32) +#define fbopi(name) fpr_bopi(name, f, 32) +#define dopi(name) fpr_opi(name, d, 64) +#define dbopi(name) fpr_bopi(name, d, 64) + +fopi(add) +fopi(sub) +fopi(rsb) +fopi(mul) +fopi(div) +dopi(add) +dopi(sub) +dopi(rsb) +dopi(mul) +dopi(div) + +/* translation from gcc -O0 */ +static void +_divr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0, t1, t2; + t0 = jit_get_reg(jit_class_fpr); + t1 = jit_get_reg(jit_class_fpr); + t2 = jit_get_reg(jit_class_fpr); + FRCPA(rn(t0), PR_6, r1, r2); + FNMA_p(rn(t1), r2, rn(t0), GR_1, SF_S1, PR_6); + FMA_p(rn(t2), rn(t0), rn(t1), rn(t0), SF_S1, PR_6); + FMPY_p(rn(t1), rn(t1), rn(t1), SF_S1, PR_6); + FMA_p(rn(t2), rn(t2), rn(t1), rn(t2), SF_S1, PR_6); + FMPY_p(rn(t1), rn(t1), rn(t1), SF_S1, PR_6); + FMA_p(rn(t1), rn(t2), rn(t1), rn(t2), SF_S1, PR_6); + FMPY_S_p(rn(t2), r1, rn(t1), SF_S1, PR_6); + FNMA_p(rn(t0), r2, rn(t2), r1, SF_S1, PR_6); + FMA_S_p(r0, rn(t0), rn(t1), rn(t2), SF_S0, PR_6); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); +} + +static void +_divr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0, t1, t2; + t0 = jit_get_reg(jit_class_fpr); + t1 = jit_get_reg(jit_class_fpr); + t2 = jit_get_reg(jit_class_fpr); + FRCPA(rn(t0), PR_6, r1, r2); + FNMA_p(rn(t1), r2, rn(t0), GR_1, SF_S1, PR_6); + FMA_p(rn(t2), rn(t0), rn(t1), rn(t0), SF_S1, PR_6); + FMPY_p(rn(t1), rn(t1), rn(t1), SF_S1, PR_6); + FMA_p(rn(t2), rn(t2), rn(t1), rn(t2), SF_S1, PR_6); + FMPY_p(rn(t1), rn(t1), rn(t1), SF_S1, PR_6); + FMA_p(rn(t1), rn(t2), rn(t1), rn(t2), SF_S1, PR_6); + FMPY_D_p(rn(t2), r1, rn(t1), SF_S1, PR_6); + FNMA_p(rn(t0), r2, rn(t2), r1, SF_S1, PR_6); + FMA_D_p(r0, rn(t0), rn(t1), rn(t2), SF_S0, PR_6); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); +} + +static void +_extr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + SETF_SIG(rn(reg), r1); + FCVT_XF(r0, rn(reg)); + FNORM_S(r0, r0); + jit_unget_reg(reg); +} + +static void +_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + SETF_SIG(rn(reg), r1); + FCVT_XF(r0, rn(reg)); + FNORM_D(r0, r0); + jit_unget_reg(reg); +} + +static void +_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + FCVT_FX_TRUNC(rn(reg), r1); + GETF_SIG(r0, rn(reg)); + FNORM(r0, r0); + jit_unget_reg(reg); +} + +static void +_ltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_LT(PR_6, PR_7, r1, r2); + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} +fopi(lt) +dopi(lt) + +static void +_ler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_LE(PR_6, PR_7, r1, r2); + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} +fopi(le) +dopi(le) + +static void +_eqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_EQ(PR_6, PR_7, r1, r2); + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} +fopi(eq) +dopi(eq) + +static void +_ger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_LE(PR_6, PR_7, r2, r1); + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} +fopi(ge) +dopi(ge) + +static void +_gtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_LT(PR_6, PR_7, r2, r1); + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} +fopi(gt) +dopi(gt) + +static void +_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_EQ(PR_6, PR_7, r1, r2); + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} +fopi(ne) +dopi(ne) + +static void +_unltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_LE(PR_6, PR_7, r2, r1); + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} +fopi(unlt) +dopi(unlt) + +static void +_unler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_LT(PR_6, PR_7, r2, r1); + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} +fopi(unle) +dopi(unle) + +static void +_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + MOVI(r0, 1); + FCMP_LT(PR_8, PR_9, r1, r2); + FCMP_LT(PR_6, PR_7, r2, r1); + MOV_p(r0, GR_0, PR_8); /* !(r1 < r2) && !(r2 < r1) */ + MOV_p(r0, GR_0, PR_6); +} +fopi(uneq) +dopi(uneq) + +static void +_unger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_LT(PR_6, PR_7, r1, r2); + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} +fopi(unge) +dopi(unge) + +static void +_ungtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_LE(PR_6, PR_7, r1, r2); + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} +fopi(ungt) +dopi(ungt) + +static void +_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + MOVI(r0, 1); + FCMP_EQ(PR_8, PR_9, r1, r2); + FCMP_UNORD(PR_6, PR_7, r1, r2); + MOV_p(r0, GR_0, PR_8); + MOV_p(r0, GR_0, PR_6); +} +fopi(ltgt) +dopi(ltgt) + +static void +_ordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_UNORD(PR_6, PR_7, r1, r2); + MOV_p(r0, GR_0, PR_6); + MOVI_p(r0, 1, PR_7); +} +fopi(ord) +dopi(ord) + +static void +_unordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_UNORD(PR_6, PR_7, r1, r2); + MOVI_p(r0, 1, PR_6); + MOV_p(r0, GR_0, PR_7); +} +fopi(unord) +dopi(unord) + +static void +_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (r0) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); + } + else + ldr_f(r0, r1); +} + +static void +_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (r0) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); + } + else + ldr_d(r0, r1); +} + +static void +_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_f(rn(reg), r0); + jit_unget_reg(reg); +} + +static void +_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_f(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_f(rn(reg), r1); + jit_unget_reg(reg); + } + else + str_f(r0, r1); +} + +static void +_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_d(rn(reg), r0); + jit_unget_reg(reg); +} + +static void +_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_d(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_d(rn(reg), r1); + jit_unget_reg(reg); + } + else + str_d(r0, r1); +} + +static void +_sqrtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + movr_f(GR_8, r1); + calli((jit_word_t)sqrtf); + MOVF(r0, GR_8); +} + +static void +_sqrtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + movr_d(GR_8, r1); + calli((jit_word_t)sqrt); + MOVF(r0, GR_8); +} + +static jit_word_t +_bltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_LT(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} +fbopi(lt) +dbopi(lt) + +static jit_word_t +_bler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_LE(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} +fbopi(le) +dbopi(le) + +static jit_word_t +_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_EQ(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} +fbopi(eq) +dbopi(eq) + +static jit_word_t +_bger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_LE(PR_6, PR_7, r1, r0); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} +fbopi(ge) +dbopi(ge) + +static jit_word_t +_bgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_LT(PR_6, PR_7, r1, r0); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} +fbopi(gt) +dbopi(gt) + +static jit_word_t +_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_EQ(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} +fbopi(ne) +dbopi(ne) + +static jit_word_t +_bunltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_LE(PR_6, PR_7, r1, r0); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} +fbopi(unlt) +dbopi(unlt) + +static jit_word_t +_bunler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_LT(PR_6, PR_7, r1, r0); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} +fbopi(unle) +dbopi(unle) + +static jit_word_t +_buneqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_word_t junord, jne; + FCMP_UNORD(PR_8, PR_9, r0, r1); + sync(); + /* junord L1 */ + junord = _jit->pc.w; + BRI_COND(3, PR_8); + FCMP_EQ(PR_6, PR_7, r0, r1); + sync(); + /* jne L2 */ + jne = _jit->pc.w; + BRI_COND(2, PR_7); + sync(); + w = _jit->pc.w; + /* L1: */ + patch_at(jit_code_bunordr_d, junord, _jit->pc.w); + BRI((i0 - w) >> 4); /* unconditional jump to patch */ + sync(); + /* L2: */ + patch_at(jit_code_bner_d, jne, _jit->pc.w); + return (w); +} +fbopi(uneq) +dbopi(uneq) + +static jit_word_t +_bunger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_LT(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} +fbopi(unge) +dbopi(unge) + +static jit_word_t +_bungtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_LE(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} +fbopi(ungt) +dbopi(ungt) + +static jit_word_t +_bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_word_t jeq, junord; + FCMP_EQ(PR_8, PR_9, r0, r1); + /* jeq L1 */ + sync(); + jeq = _jit->pc.w; + BRI_COND(4, PR_8); + FCMP_UNORD(PR_6, PR_7, r0, r1); + /* junord L1 */ + sync(); + junord = _jit->pc.w; + BRI_COND(2, PR_6); + sync(); + w = _jit->pc.w; + BRI((i0 - w) >> 4); /* unconditional jump to patch */ + /* L1 */ + sync(); + patch_at(jit_code_beqr_d, jeq, _jit->pc.w); + patch_at(jit_code_bordr_d, junord, _jit->pc.w); + return (w); +} +fbopi(ltgt) +dbopi(ltgt) + +static jit_word_t +_bordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_UNORD(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_7); + return (w); +} +fbopi(ord) +dbopi(ord) + +static jit_word_t +_bunordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMP_UNORD(PR_6, PR_7, r0, r1); + sync(); + w = _jit->pc.w; + BRI_COND((i0 - w) >> 4, PR_6); + return (w); +} +fbopi(unord) +dbopi(unord) + +static void +_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(_jitc->function->self.call & jit_call_varargs); + /* Load argument. */ + ldr_d(r0, r1); + /* Update va_list. */ + addi(r1, r1, 8); +} +#endif diff --git a/deps/lightning/lib/jit_ia64-sz.c b/deps/lightning/lib/jit_ia64-sz.c new file mode 100644 index 0000000..59826d9 --- /dev/null +++ b/deps/lightning/lib/jit_ia64-sz.c @@ -0,0 +1,402 @@ + +#if __WORDSIZE == 64 +#define JIT_INSTR_MAX 224 + 0, /* data */ + 0, /* live */ + 0, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 224, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 16, /* va_start */ + 32, /* va_arg */ + 32, /* va_arg_d */ + 0, /* va_end */ + 16, /* addr */ + 32, /* addi */ + 32, /* addcr */ + 48, /* addci */ + 64, /* addxr */ + 64, /* addxi */ + 16, /* subr */ + 32, /* subi */ + 32, /* subcr */ + 48, /* subci */ + 64, /* subxr */ + 64, /* subxi */ + 32, /* rsbi */ + 48, /* mulr */ + 64, /* muli */ + 112, /* qmulr */ + 112, /* qmuli */ + 112, /* qmulr_u */ + 112, /* qmuli_u */ + 80, /* divr */ + 96, /* divi */ + 80, /* divr_u */ + 96, /* divi_u */ + 144, /* qdivr */ + 144, /* qdivi */ + 144, /* qdivr_u */ + 144, /* qdivi_u */ + 80, /* remr */ + 96, /* remi */ + 80, /* remr_u */ + 96, /* remi_u */ + 16, /* andr */ + 32, /* andi */ + 16, /* orr */ + 32, /* ori */ + 16, /* xorr */ + 32, /* xori */ + 16, /* lshr */ + 16, /* lshi */ + 16, /* rshr */ + 16, /* rshi */ + 16, /* rshr_u */ + 16, /* rshi_u */ + 16, /* negr */ + 16, /* comr */ + 32, /* ltr */ + 32, /* lti */ + 32, /* ltr_u */ + 32, /* lti_u */ + 32, /* ler */ + 32, /* lei */ + 32, /* ler_u */ + 32, /* lei_u */ + 32, /* eqr */ + 32, /* eqi */ + 32, /* ger */ + 32, /* gei */ + 32, /* ger_u */ + 32, /* gei_u */ + 32, /* gtr */ + 32, /* gti */ + 32, /* gtr_u */ + 32, /* gti_u */ + 32, /* ner */ + 32, /* nei */ + 16, /* movr */ + 16, /* movi */ + 16, /* extr_c */ + 16, /* extr_uc */ + 16, /* extr_s */ + 16, /* extr_us */ + 16, /* extr_i */ + 16, /* extr_ui */ + 64, /* htonr_us */ + 160, /* htonr_ui */ + 16, /* htonr_ul */ + 16, /* ldr_c */ + 32, /* ldi_c */ + 16, /* ldr_uc */ + 32, /* ldi_uc */ + 16, /* ldr_s */ + 32, /* ldi_s */ + 16, /* ldr_us */ + 32, /* ldi_us */ + 16, /* ldr_i */ + 32, /* ldi_i */ + 16, /* ldr_ui */ + 32, /* ldi_ui */ + 16, /* ldr_l */ + 32, /* ldi_l */ + 32, /* ldxr_c */ + 48, /* ldxi_c */ + 16, /* ldxr_uc */ + 32, /* ldxi_uc */ + 32, /* ldxr_s */ + 48, /* ldxi_s */ + 16, /* ldxr_us */ + 32, /* ldxi_us */ + 32, /* ldxr_i */ + 48, /* ldxi_i */ + 16, /* ldxr_ui */ + 32, /* ldxi_ui */ + 16, /* ldxr_l */ + 32, /* ldxi_l */ + 16, /* str_c */ + 32, /* sti_c */ + 16, /* str_s */ + 32, /* sti_s */ + 16, /* str_i */ + 32, /* sti_i */ + 16, /* str_l */ + 32, /* sti_l */ + 16, /* stxr_c */ + 32, /* stxi_c */ + 16, /* stxr_s */ + 32, /* stxi_s */ + 16, /* stxr_i */ + 32, /* stxi_i */ + 16, /* stxr_l */ + 32, /* stxi_l */ + 32, /* bltr */ + 32, /* blti */ + 32, /* bltr_u */ + 32, /* blti_u */ + 32, /* bler */ + 32, /* blei */ + 32, /* bler_u */ + 32, /* blei_u */ + 32, /* beqr */ + 48, /* beqi */ + 32, /* bger */ + 32, /* bgei */ + 32, /* bger_u */ + 32, /* bgei_u */ + 32, /* bgtr */ + 32, /* bgti */ + 32, /* bgtr_u */ + 32, /* bgti_u */ + 32, /* bner */ + 48, /* bnei */ + 32, /* bmsr */ + 48, /* bmsi */ + 32, /* bmcr */ + 48, /* bmci */ + 96, /* boaddr */ + 112, /* boaddi */ + 64, /* boaddr_u */ + 64, /* boaddi_u */ + 96, /* bxaddr */ + 112, /* bxaddi */ + 64, /* bxaddr_u */ + 64, /* bxaddi_u */ + 112, /* bosubr */ + 112, /* bosubi */ + 64, /* bosubr_u */ + 64, /* bosubi_u */ + 112, /* bxsubr */ + 112, /* bxsubi */ + 64, /* bxsubr_u */ + 64, /* bxsubi_u */ + 16, /* jmpr */ + 16, /* jmpi */ + 32, /* callr */ + 48, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 128, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 16, /* addr_f */ + 48, /* addi_f */ + 16, /* subr_f */ + 48, /* subi_f */ + 48, /* rsbi_f */ + 16, /* mulr_f */ + 48, /* muli_f */ + 160, /* divr_f */ + 192, /* divi_f */ + 16, /* negr_f */ + 16, /* absr_f */ + 80, /* sqrtr_f */ + 32, /* ltr_f */ + 64, /* lti_f */ + 32, /* ler_f */ + 64, /* lei_f */ + 32, /* eqr_f */ + 64, /* eqi_f */ + 32, /* ger_f */ + 64, /* gei_f */ + 32, /* gtr_f */ + 64, /* gti_f */ + 32, /* ner_f */ + 64, /* nei_f */ + 32, /* unltr_f */ + 64, /* unlti_f */ + 32, /* unler_f */ + 64, /* unlei_f */ + 48, /* uneqr_f */ + 96, /* uneqi_f */ + 32, /* unger_f */ + 64, /* ungei_f */ + 32, /* ungtr_f */ + 64, /* ungti_f */ + 48, /* ltgtr_f */ + 96, /* ltgti_f */ + 32, /* ordr_f */ + 64, /* ordi_f */ + 32, /* unordr_f */ + 64, /* unordi_f */ + 32, /* truncr_f_i */ + 32, /* truncr_f_l */ + 48, /* extr_f */ + 16, /* extr_d_f */ + 16, /* movr_f */ + 32, /* movi_f */ + 16, /* ldr_f */ + 32, /* ldi_f */ + 16, /* ldxr_f */ + 32, /* ldxi_f */ + 16, /* str_f */ + 32, /* sti_f */ + 16, /* stxr_f */ + 32, /* stxi_f */ + 32, /* bltr_f */ + 64, /* blti_f */ + 32, /* bler_f */ + 64, /* blei_f */ + 32, /* beqr_f */ + 64, /* beqi_f */ + 32, /* bger_f */ + 64, /* bgei_f */ + 32, /* bgtr_f */ + 64, /* bgti_f */ + 32, /* bner_f */ + 64, /* bnei_f */ + 32, /* bunltr_f */ + 64, /* bunlti_f */ + 32, /* bunler_f */ + 64, /* bunlei_f */ + 80, /* buneqr_f */ + 112, /* buneqi_f */ + 32, /* bunger_f */ + 64, /* bungei_f */ + 32, /* bungtr_f */ + 64, /* bungti_f */ + 80, /* bltgtr_f */ + 112, /* bltgti_f */ + 32, /* bordr_f */ + 64, /* bordi_f */ + 32, /* bunordr_f */ + 64, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 16, /* addr_d */ + 48, /* addi_d */ + 16, /* subr_d */ + 48, /* subi_d */ + 48, /* rsbi_d */ + 16, /* mulr_d */ + 48, /* muli_d */ + 160, /* divr_d */ + 192, /* divi_d */ + 16, /* negr_d */ + 16, /* absr_d */ + 80, /* sqrtr_d */ + 32, /* ltr_d */ + 64, /* lti_d */ + 32, /* ler_d */ + 64, /* lei_d */ + 32, /* eqr_d */ + 64, /* eqi_d */ + 32, /* ger_d */ + 64, /* gei_d */ + 32, /* gtr_d */ + 64, /* gti_d */ + 32, /* ner_d */ + 64, /* nei_d */ + 32, /* unltr_d */ + 64, /* unlti_d */ + 32, /* unler_d */ + 64, /* unlei_d */ + 48, /* uneqr_d */ + 96, /* uneqi_d */ + 32, /* unger_d */ + 64, /* ungei_d */ + 32, /* ungtr_d */ + 64, /* ungti_d */ + 48, /* ltgtr_d */ + 96, /* ltgti_d */ + 32, /* ordr_d */ + 64, /* ordi_d */ + 32, /* unordr_d */ + 64, /* unordi_d */ + 32, /* truncr_d_i */ + 32, /* truncr_d_l */ + 48, /* extr_d */ + 16, /* extr_f_d */ + 16, /* movr_d */ + 32, /* movi_d */ + 16, /* ldr_d */ + 32, /* ldi_d */ + 16, /* ldxr_d */ + 32, /* ldxi_d */ + 16, /* str_d */ + 32, /* sti_d */ + 16, /* stxr_d */ + 32, /* stxi_d */ + 32, /* bltr_d */ + 64, /* blti_d */ + 32, /* bler_d */ + 64, /* blei_d */ + 32, /* beqr_d */ + 64, /* beqi_d */ + 32, /* bger_d */ + 64, /* bgei_d */ + 32, /* bgtr_d */ + 64, /* bgti_d */ + 32, /* bner_d */ + 64, /* bnei_d */ + 32, /* bunltr_d */ + 64, /* bunlti_d */ + 32, /* bunler_d */ + 64, /* bunlei_d */ + 80, /* buneqr_d */ + 112, /* buneqi_d */ + 32, /* bunger_d */ + 64, /* bungei_d */ + 32, /* bungtr_d */ + 64, /* bungti_d */ + 80, /* bltgtr_d */ + 112, /* bltgti_d */ + 32, /* bordr_d */ + 64, /* bordi_d */ + 32, /* bunordr_d */ + 64, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 16, /* movr_d_w */ + 32, /* movi_d_w */ +#endif /* __WORDSIZE */ diff --git a/deps/lightning/lib/jit_ia64.c b/deps/lightning/lib/jit_ia64.c new file mode 100644 index 0000000..9207d81 --- /dev/null +++ b/deps/lightning/lib/jit_ia64.c @@ -0,0 +1,1769 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include <lightning.h> +#include <lightning/jit_private.h> + +#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 8) +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define C_DISP 0 +# define S_DISP 0 +# define I_DISP 0 +# define F_DISP 0 +#else +# define C_DISP 8 - sizeof(jit_int8_t) +# define S_DISP 8 - sizeof(jit_int16_t) +# define I_DISP 8 - sizeof(jit_int32_t) +# define F_DISP 8 - sizeof(jit_float32_t) +#endif + +/* + * Types + */ +typedef jit_pointer_t jit_va_list_t; + +/* + * Prototypes + */ +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); + +#if defined(__GNUC__) +/* libgcc */ +extern void __clear_cache(void *, void *); +#endif + +#define PROTO 1 +# include "jit_ia64-cpu.c" +# include "jit_ia64-fpu.c" +#undef PROTO + +/* + * Initialization + */ +jit_register_t _rvs[] = { + /* Always 0 */ + { 0, "r0" }, + /* Global Pointer */ + { rc(sav)|1, "r1" }, + /* Used when a register cannot be allocated */ + { 2, "r2" }, + /* First scratch register */ + { rc(gpr)|3, "r3" }, + /* Use r4 as lightning fp register */ + { rc(sav)|4, "r4" }, + /* Do not touch callee save registers not automatically spill/reloaded */ + { rc(sav)|5, "r5" }, { rc(sav)|6, "r6" }, + { rc(sav)|7, "r7" }, + /* Do not touch return register for the sake of simplicity, besides + * having JIT_R0 being the same as JIT_RET usually an optimization */ + { 8, "r8" }, + /* Return registers, use as temporaries */ + { rc(gpr)|9, "r9" }, + { rc(gpr)|10, "r10" }, { rc(gpr)|11, "r11" }, + /* Stack pointer */ + { rc(sav)|12, "r12" }, + /* Thread pointer */ + { rc(sav)|13, "r13" }, + /* (Usually) assembly temporaries */ + { rc(gpr)|31, "r31" }, { rc(gpr)|30, "r30" }, + { rc(gpr)|29, "r29" }, { rc(gpr)|28, "r28" }, + { rc(gpr)|27, "r27" }, { rc(gpr)|26, "r26" }, + { rc(gpr)|25, "r25" }, { rc(gpr)|24, "r24" }, + { rc(gpr)|23, "r23" }, { rc(gpr)|22, "r22" }, + { rc(gpr)|21, "r21" }, { rc(gpr)|20, "r20" }, + { rc(gpr)|19, "r19" }, { rc(gpr)|18, "r18" }, + { rc(gpr)|17, "r17" }, { rc(gpr)|16, "r16" }, + { rc(gpr)|15, "r15" }, { rc(gpr)|14, "r14" }, + /* Do not allow allocating r32-r41 as temoraries for the sake of + * avoiding the need of extra complexity in the non backend code */ + { rc(arg)|32, "r32" }, { rc(arg)|33, "r33" }, + { rc(arg)|34, "r34" }, { rc(arg)|35, "r35" }, + { rc(arg)|36, "r36" }, { rc(arg)|37, "r37" }, + { rc(arg)|38, "r38" }, { rc(arg)|39, "r39" }, + /* JIT_R0-JIT_V3 */ + { rc(gpr)|rc(sav)|40, "r40" }, { rc(gpr)|rc(sav)|41, "r41" }, + { rc(gpr)|rc(sav)|42, "r42" }, { rc(gpr)|rc(sav)|43, "r43" }, + { rc(gpr)|rc(sav)|44, "r44" }, { rc(gpr)|rc(sav)|45, "r45" }, + { rc(gpr)|rc(sav)|46, "r46" }, { rc(gpr)|rc(sav)|47, "r47" }, + /* Temporaries/locals */ + { rc(gpr)|rc(sav)|48, "r48" }, { rc(gpr)|rc(sav)|49, "r49" }, + { rc(gpr)|rc(sav)|50, "r50" }, { rc(gpr)|rc(sav)|51, "r51" }, + { rc(gpr)|rc(sav)|52, "r52" }, { rc(gpr)|rc(sav)|53, "r53" }, + { rc(gpr)|rc(sav)|54, "r54" }, { rc(gpr)|rc(sav)|55, "r55" }, + { rc(gpr)|rc(sav)|56, "r56" }, { rc(gpr)|rc(sav)|57, "r57" }, + { rc(gpr)|rc(sav)|58, "r58" }, { rc(gpr)|rc(sav)|59, "r59" }, + { rc(gpr)|rc(sav)|60, "r60" }, { rc(gpr)|rc(sav)|61, "r61" }, + { rc(gpr)|rc(sav)|62, "r62" }, { rc(gpr)|rc(sav)|63, "r63" }, + { rc(gpr)|rc(sav)|64, "r64" }, { rc(gpr)|rc(sav)|65, "r65" }, + { rc(gpr)|rc(sav)|66, "r66" }, { rc(gpr)|rc(sav)|67, "r67" }, + { rc(gpr)|rc(sav)|68, "r68" }, { rc(gpr)|rc(sav)|69, "r69" }, + { rc(gpr)|rc(sav)|70, "r70" }, { rc(gpr)|rc(sav)|71, "r71" }, + { rc(gpr)|rc(sav)|72, "r72" }, { rc(gpr)|rc(sav)|73, "r73" }, + { rc(gpr)|rc(sav)|74, "r74" }, { rc(gpr)|rc(sav)|75, "r75" }, + { rc(gpr)|rc(sav)|76, "r76" }, { rc(gpr)|rc(sav)|77, "r77" }, + { rc(gpr)|rc(sav)|78, "r78" }, { rc(gpr)|rc(sav)|79, "r79" }, + { rc(gpr)|rc(sav)|80, "r80" }, { rc(gpr)|rc(sav)|81, "r81" }, + { rc(gpr)|rc(sav)|82, "r82" }, { rc(gpr)|rc(sav)|83, "r83" }, + { rc(gpr)|rc(sav)|84, "r84" }, { rc(gpr)|rc(sav)|85, "r85" }, + { rc(gpr)|rc(sav)|86, "r86" }, { rc(gpr)|rc(sav)|87, "r87" }, + { rc(gpr)|rc(sav)|88, "r88" }, { rc(gpr)|rc(sav)|89, "r89" }, + { rc(gpr)|rc(sav)|90, "r90" }, { rc(gpr)|rc(sav)|91, "r91" }, + { rc(gpr)|rc(sav)|92, "r92" }, { rc(gpr)|rc(sav)|93, "r93" }, + { rc(gpr)|rc(sav)|94, "r94" }, { rc(gpr)|rc(sav)|95, "r95" }, + { rc(gpr)|rc(sav)|96, "r96" }, { rc(gpr)|rc(sav)|97, "r97" }, + { rc(gpr)|rc(sav)|98, "r98" }, { rc(gpr)|rc(sav)|99, "r99" }, + { rc(gpr)|rc(sav)|100,"r100"}, { rc(gpr)|rc(sav)|101, "r101"}, + { rc(gpr)|rc(sav)|102,"r102"}, { rc(gpr)|rc(sav)|103, "r103"}, + { rc(gpr)|rc(sav)|104,"r104"}, { rc(gpr)|rc(sav)|105, "r105"}, + { rc(gpr)|rc(sav)|106,"r106"}, { rc(gpr)|rc(sav)|107, "r107"}, + { rc(gpr)|rc(sav)|108,"r108"}, { rc(gpr)|rc(sav)|109, "r109"}, + { rc(gpr)|rc(sav)|110,"r110"}, { rc(gpr)|rc(sav)|111, "r111"}, + { rc(gpr)|rc(sav)|112,"r112"}, { rc(gpr)|rc(sav)|113, "r113"}, + { rc(gpr)|rc(sav)|114,"r114"}, + /* Do not enable these because no matter what, want 13 free registers, + * 5 for prolog and epilog and 8 for outgoing arguments */ + { 115, "r115"}, + { 116, "r116"}, { 117, "r117"}, + { 118, "r118"}, { 119, "r119"}, + { 120, "r120"}, { 121, "r121"}, + { 122, "r122"}, { 123, "r123"}, + { 124, "r124"}, { 125, "r125"}, + { 126, "r126"}, { 127, "r127"}, + /* Always 0.0 */ + { 0, "f0" }, + /* Always 1.0 */ + { 1, "f1" }, + /* Do not touch callee save registers not automatically spill/reloaded */ + { rc(sav)|2, "f2" }, { rc(sav)|3, "f3" }, + { rc(sav)|4, "f4" }, { rc(sav)|5, "f5" }, + /* Scratch */ + { rc(fpr)|6, "f6" }, { rc(fpr)|7, "f7" }, + /* Do not allocate for the sake of simplification */ + { rc(arg)|8, "f8" }, + /* Scratch - Argument/return registers */ + { rc(arg)|9, "f9" }, + { rc(arg)|10, "f10" }, { rc(arg)|11, "f11" }, + { rc(arg)|12, "f12" }, { rc(arg)|13, "f13" }, + { rc(arg)|14, "f14" }, { rc(arg)|15, "f15" }, + /* Do not touch callee save registers not automatically spill/reloaded */ + { rc(sav)|16, "f16" }, { rc(sav)|17, "f17" }, + { rc(sav)|18, "f18" }, { rc(sav)|19, "f19" }, + { rc(sav)|20, "f20" }, { rc(sav)|21, "f21" }, + { rc(sav)|22, "f22" }, { rc(sav)|23, "f23" }, + { rc(sav)|24, "f24" }, { rc(sav)|25, "f25" }, + { rc(sav)|26, "f26" }, { rc(sav)|27, "f27" }, + { rc(sav)|28, "f28" }, { rc(sav)|29, "f29" }, + { rc(sav)|30, "f30" }, { rc(sav)|31, "f31" }, + /* Scratch */ + { rc(fpr)|32, "f32" }, { rc(fpr)|33, "f33" }, + { rc(fpr)|34, "f34" }, { rc(fpr)|35, "f35" }, + { rc(fpr)|36, "f36" }, { rc(fpr)|37, "f37" }, + { rc(fpr)|38, "f38" }, { rc(fpr)|39, "f39" }, + { rc(fpr)|40, "f40" }, { rc(fpr)|41, "f41" }, + { rc(fpr)|42, "f42" }, { rc(fpr)|43, "f43" }, + { rc(fpr)|44, "f44" }, { rc(fpr)|45, "f45" }, + { rc(fpr)|46, "f46" }, { rc(fpr)|47, "f47" }, + { rc(fpr)|48, "f48" }, { rc(fpr)|49, "f49" }, + { rc(fpr)|50, "f50" }, { rc(fpr)|51, "f51" }, + { rc(fpr)|52, "f52" }, { rc(fpr)|53, "f53" }, + { rc(fpr)|54, "f54" }, { rc(fpr)|55, "f55" }, + { rc(fpr)|56, "f56" }, { rc(fpr)|57, "f57" }, + { rc(fpr)|58, "f58" }, { rc(fpr)|59, "f59" }, + { rc(fpr)|60, "f60" }, { rc(fpr)|61, "f61" }, + { rc(fpr)|62, "f62" }, { rc(fpr)|63, "f63" }, + { rc(fpr)|64, "f64" }, { rc(fpr)|65, "f65" }, + { rc(fpr)|66, "f66" }, { rc(fpr)|67, "f67" }, + { rc(fpr)|68, "f68" }, { rc(fpr)|69, "f69" }, + { rc(fpr)|70, "f70" }, { rc(fpr)|71, "f71" }, + { rc(fpr)|72, "f72" }, { rc(fpr)|73, "f73" }, + { rc(fpr)|74, "f74" }, { rc(fpr)|75, "f75" }, + { rc(fpr)|76, "f76" }, { rc(fpr)|77, "f77" }, + { rc(fpr)|78, "f78" }, { rc(fpr)|79, "f79" }, + { rc(fpr)|80, "f80" }, { rc(fpr)|81, "f81" }, + { rc(fpr)|82, "f82" }, { rc(fpr)|83, "f83" }, + { rc(fpr)|84, "f84" }, { rc(fpr)|85, "f85" }, + { rc(fpr)|86, "f86" }, { rc(fpr)|87, "f87" }, + { rc(fpr)|88, "f88" }, { rc(fpr)|89, "f89" }, + { rc(fpr)|90, "f90" }, { rc(fpr)|91, "f91" }, + { rc(fpr)|92, "f92" }, { rc(fpr)|93, "f93" }, + { rc(fpr)|94, "f94" }, { rc(fpr)|95, "f95" }, + { rc(fpr)|96, "f96" }, { rc(fpr)|97, "f97" }, + { rc(fpr)|98, "f98" }, { rc(fpr)|99, "f99" }, + { rc(fpr)|100, "f100"}, { rc(fpr)|101, "f101"}, + { rc(fpr)|102, "f102"}, { rc(fpr)|103, "f103"}, + { rc(fpr)|104, "f104"}, { rc(fpr)|105, "f105"}, + { rc(fpr)|106, "f106"}, { rc(fpr)|107, "f107"}, + { rc(fpr)|108, "f108"}, { rc(fpr)|109, "f109"}, + { rc(fpr)|110, "f110"}, { rc(fpr)|111, "f111"}, + { rc(fpr)|112, "f112"}, { rc(fpr)|113, "f113"}, + { rc(fpr)|114, "f114"}, { rc(fpr)|115, "f115"}, + { rc(fpr)|116, "f116"}, { rc(fpr)|117, "f117"}, + { rc(fpr)|118, "f118"}, { rc(fpr)|119, "f119"}, +#if 0 + /* commented to fit a jit_regset_t in 256 bits, so that the fake + * O0-O7 registers are easily patched when an argument is pushed */ + { rc(fpr)|120, "f120"}, { rc(fpr)|121, "f121"}, + { rc(fpr)|122, "f122"}, { rc(fpr)|123, "f123"}, + { rc(fpr)|124, "f124"}, { rc(fpr)|125, "f125"}, + { rc(fpr)|126, "f126"}, { rc(fpr)|127, "f127"}, +#endif + /* Fake registers to patch in movr and movi arguments */ + { rc(arg)|120, "o0" }, { rc(arg)|121, "o1" }, + { rc(arg)|122, "o2" }, { rc(arg)|123, "o3" }, + { rc(arg)|124, "o4" }, { rc(arg)|125, "o5" }, + { rc(arg)|126, "o6" }, { rc(arg)|127, "o7" }, + { _NOREG, "<none>" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ +} + +void +_jit_init(jit_state_t *_jit) +{ + _jitc->reglen = jit_size(_rvs) - 1; + jit_regset_new(&_jitc->regs); + jit_carry = _NOREG; +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + /* params_offset << 1, once for ours arguments, once for arguments + * to any called function; required because offsets are computed + * as JIT_FP displacement */ + _jitc->function->self.size = stack_framesize + (params_offset << 1); + _jitc->function->self.argi = _jitc->function->self.argf = + _jitc->function->self.aoff = _jitc->function->self.alen = 0; + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + assert(_jitc->function); + switch (length) { + case 0: case 1: break; + case 2: _jitc->function->self.aoff &= -2; break; + case 3: case 4: _jitc->function->self.aoff &= -4; break; + default: _jitc->function->self.aoff &= -8; break; + } + _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } + return (_jitc->function->self.aoff); +} + +void +_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) +{ + jit_int32_t reg; + assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); + if (!_jitc->function->allocar) { + _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); + _jitc->function->allocar = 1; + } + reg = jit_get_reg(jit_class_gpr); + jit_negr(reg, v); + jit_andi(reg, reg, -16); + jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); + jit_addr(u, u, reg); + jit_addr(JIT_SP, JIT_SP, reg); + jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); + jit_unget_reg(reg); + jit_dec_synth(); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + assert(_jitc->function); + jit_inc_synth(ret); + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr, u); + jit_movr(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti(jit_state_t *_jit, jit_word_t u) +{ + jit_inc_synth_w(reti, u); + jit_movi(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_f, u); + jit_movr_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_inc_synth_f(reti_f, u); + jit_movi_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_d, u); + jit_movr_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_inc_synth_d(reti_d, u); + jit_movi_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_epilog(jit_state_t *_jit) +{ + assert(_jitc->function); + assert(_jitc->function->epilog->next == NULL); + jit_link(_jitc->function->epilog); + _jitc->function = NULL; +} + +jit_bool_t +_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) +{ + assert(u->code == jit_code_arg || + u->code == jit_code_arg_f || u->code == jit_code_arg_d); + return (jit_arg_reg_p(u->u.w)); +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + jit_inc_synth(ellipsis); + if (_jitc->prepare) { + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; + jit_link_prepare(); + } + else { + assert(!(_jitc->function->self.call & jit_call_varargs)); + _jitc->function->self.call |= jit_call_varargs; + _jitc->function->vagp = _jitc->function->self.argi; + jit_link_prolog(); + } + jit_dec_synth(); +} + +void +_jit_va_push(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(va_push, u); + jit_pushargr(u); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + if (jit_arg_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + if (jit_arg_reg_p(_jitc->function->self.argi)) { + if (!(_jitc->function->self.call & jit_call_varargs)) + offset = 8 + _jitc->function->self.argf++; + else + offset = _jitc->function->self.argi; + ++_jitc->function->self.argi; + } + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + if (jit_arg_reg_p(_jitc->function->self.argi)) { + if (!(_jitc->function->self.call & jit_call_varargs)) + offset = 8 + _jitc->function->self.argf++; + else + offset = _jitc->function->self.argi; + ++_jitc->function->self.argi; + } + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_float64_t); + } + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +void +_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_c(u, _R32 + v->u.w); + else + jit_ldxi_c(u, JIT_FP, v->u.w + C_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_uc(u, _R32 + v->u.w); + else + jit_ldxi_uc(u, JIT_FP, v->u.w + C_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_s(u, _R32 + v->u.w); + else + jit_ldxi_s(u, JIT_FP, v->u.w + S_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_us(u, _R32 + v->u.w); + else + jit_ldxi_us(u, JIT_FP, v->u.w + S_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_i(u, _R32 + v->u.w); + else + jit_ldxi_i(u, JIT_FP, v->u.w + I_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_ui(u, _R32 + v->u.w); + else + jit_ldxi_ui(u, JIT_FP, v->u.w + I_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(u, _R32 + v->u.w); + else + jit_ldxi(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(_R32 + v->u.w, u); + else + jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movi(_R32 + v->u.w, u); + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr_w_f(u, _OUT0 + v->u.w); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_f(u, _F8 + (v->u.w - 8)); + else + jit_ldxi_f(u, JIT_FP, v->u.w + F_DISP); + jit_dec_synth(); +} + +void +_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr_f_w(_OUT0 + v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_f(_F8 + (v->u.w - 8), u); + else + jit_stxi_f(v->u.w, JIT_FP, u + F_DISP); + jit_dec_synth(); +} + +void +_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movi_f_w(_OUT0 + v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movi_f(_F8 + (v->u.w - 8), u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(v->u.w, JIT_FP, regno + F_DISP); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr_w_d(u, _OUT0 + v->u.w); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_d(u, _F8 + (v->u.w - 8)); + else + jit_ldxi_d(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr_d_w(_OUT0 + v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_d(_F8 + (v->u.w - 8), u); + else + jit_stxi_d(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movi_d_w(_OUT0 + v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movi_d(_F8 + (v->u.w - 8), u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr(_OUT0 + _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi(jit_state_t *_jit, jit_word_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi(_OUT0 + _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, regno); + _jitc->function->call.size += sizeof(jit_word_t); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + if (!(_jitc->function->call.call & jit_call_varargs)) { + jit_movr_f(_F8 + _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else + jit_movr_f_w(_OUT0 + _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP, + JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + if (!(_jitc->function->call.call & jit_call_varargs)) { + jit_movi_f(_F8 + _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else + jit_movi_f_w(_OUT0 + _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP, + JIT_SP, regno); + _jitc->function->call.size += sizeof(jit_word_t); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + if (!(_jitc->function->call.call & jit_call_varargs)) { + jit_movr_d(_F8 + _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else + jit_movr_d_w(_OUT0 + _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_float64_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + if (!(_jitc->function->call.call & jit_call_varargs)) { + jit_movi_d(_F8 + _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else + jit_movi_d_w(_OUT0 + _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, regno); + _jitc->function->call.size += sizeof(jit_float64_t); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + /* Argument registers are allocated from the pool of unused registers */ + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_node_t *call; + assert(_jitc->function); + jit_inc_synth_w(finishr, r0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + call = jit_callr(r0); + call->v.w = _jitc->function->call.argi; + call->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_calli(i0); + node->v.w = _jitc->function->call.argi; + node->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); + return (node); +} + +void +_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_c, r0); + jit_extr_c(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_uc, r0); + jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_s, r0); + jit_extr_s(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_us, r0); + jit_extr_us(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_i, r0); + jit_extr_i(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_ui, r0); + jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_l, r0); + jit_movr(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_l, r0); + jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_d, r0); + jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_int32_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + jit_int32_t patch_offset; + jit_word_t prolog_offset; + } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + + _jitc->function = NULL; + + /* If did resize the code buffer, these were not reset */ + _jitc->ioff = 0; + jit_regset_set_ui(&_jitc->regs, 0); + _jitc->pred = 0; + + jit_reglive_setup(); + + undo.word = 0; + undo.node = NULL; + undo.patch_offset = 0; + +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif + undo.prolog_offset = 0; + for (node = _jitc->head; node; node = node->next) + if (node->code != jit_code_label && + node->code != jit_code_note && + node->code != jit_code_name) + break; + if (node && (node->code != jit_code_prolog || + !(_jitc->functions.ptr + node->w.w)->assume_frame)) { + /* code may start with a jump so add an initial function descriptor */ + word = _jit->pc.w + 16; + il(word); /* addr */ + il(0); /* gp */ + } +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_rrf(name, type, size) \ + case jit_code_##name##i##type: \ + assert(node->flag & jit_flag_data); \ + name##i##type(rn(node->u.w), rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type(_jit->pc.w, \ + rn(node->v.w), rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break +#define case_brf(name, type, size) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + else { \ + word = name##i##type(_jit->pc.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + patch(word, node); \ + } \ + break + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end) + return (NULL); + + value = jit_classify(node->code); +#if GET_JIT_SIZE + sync(); +#endif +#if DEVEL_DISASSEMBLER + /* FIXME DEVEL_DISASSEMBLER should become DISASSEMBLER, + * but a "real" DEVEL_DISASSEMBLER should be required + * to turn the below "#if 0" into "#if 1" */ +# if 0 /* Since disassembly outputs 3 instructions at a time, + * make it "#if 1" for more clear debug output. */ + sync(); +# endif + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; +#endif + jit_regarg_set(node, value); + switch (node->code) { + case jit_code_align: + assert(!(node->u.w & (node->u.w - 1)) && + node->u.w <= sizeof(jit_word_t)); + /* nothing done */ + break; + case jit_code_note: case jit_code_name: + sync(); + node->u.w = _jit->pc.w; + break; + case jit_code_label: + sync(); + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + break; + case_rrr(add,); + case_rrw(add,); + case_rrr(addc,); + case_rrw(addc,); + case_rrr(addx,); + case_rrw(addx,); + case_rrr(sub,); + case_rrw(sub,); + case_rrr(subx,); + case_rrw(subx,); + case_rrw(rsb,); + case_rrr(subc,); + case_rrw(subc,); + case_rrr(mul,); + case_rrw(mul,); + case_rrrr(qmul,); + case_rrrw(qmul,); + case_rrrr(qmul, _u); + case_rrrw(qmul, _u); + case_rrr(div,); + case_rrw(div,); + case_rrr(div, _u); + case_rrw(div, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rr(neg,); + case_rr(com,); + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), node->v.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rr(hton, _us); + case_rr(hton, _ui); + case_rr(hton, _ul); + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); + case_rr(ext, _i); + case_rr(ext, _ui); + case_rr(trunc, _f_i); + case_rr(trunc, _d_i); + case_rr(trunc, _f_l); + case_rr(trunc, _d_l); + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_rr(ld, _c); + case_rw(ld, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rr(ld, _i); + case_rw(ld, _i); + case_rr(ld, _ui); + case_rw(ld, _ui); + case_rr(ld, _l); + case_rw(ld, _l); + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rrr(ldx, _i); + case_rrw(ldx, _i); + case_rrr(ldx, _ui); + case_rrw(ldx, _ui); + case_rrr(ldx, _l); + case_rrw(ldx, _l); + case_rr(st, _c); + case_wr(st, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rr(st, _i); + case_wr(st, _i); + case_rr(st, _l); + case_wr(st, _l); + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rrr(stx, _i); + case_wrr(stx, _i); + case_rrr(stx, _l); + case_wrr(stx, _l); + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_rrr(add, _f); + case_rrf(add, _f, 32); + case_rrr(sub, _f); + case_rrf(sub, _f, 32); + case_rrf(rsb, _f, 32); + case_rrr(mul, _f); + case_rrf(mul, _f, 32); + case_rrr(div, _f); + case_rrf(div, _f, 32); + case_rr(ext, _f); + case_rr(abs, _f); + case_rr(neg, _f); + case_rr(sqrt, _f); + case_rr(ld, _f); + case_rw(ld, _f); + case_rrr(ldx, _f); + case_rrw(ldx, _f); + case_rr(st, _f); + case_wr(st, _f); + case_rrr(stx, _f); + case_wrr(stx, _f); + case_rr(mov, _f); + case jit_code_movi_f: + assert(node->flag & jit_flag_data); + movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); + break; + case_rr(ext, _d_f); + case_rrr(lt, _f); + case_rrf(lt, _f, 32); + case_rrr(le, _f); + case_rrf(le, _f, 32); + case_rrr(eq, _f); + case_rrf(eq, _f, 32); + case_rrr(ge, _f); + case_rrf(ge, _f, 32); + case_rrr(gt, _f); + case_rrf(gt, _f, 32); + case_rrr(ne, _f); + case_rrf(ne, _f, 32); + case_rrr(unlt, _f); + case_rrf(unlt, _f, 32); + case_rrr(unle, _f); + case_rrf(unle, _f, 32); + case_rrr(uneq, _f); + case_rrf(uneq, _f, 32); + case_rrr(unge, _f); + case_rrf(unge, _f, 32); + case_rrr(ungt, _f); + case_rrf(ungt, _f, 32); + case_rrr(ltgt, _f); + case_rrf(ltgt, _f, 32); + case_rrr(ord, _f); + case_rrf(ord, _f, 32); + case_rrr(unord, _f); + case_rrf(unord, _f, 32); + case_brr(blt, _f); + case_brf(blt, _f, 32); + case_brr(ble, _f); + case_brf(ble, _f, 32); + case_brr(beq, _f); + case_brf(beq, _f, 32); + case_brr(bge, _f); + case_brf(bge, _f, 32); + case_brr(bgt, _f); + case_brf(bgt, _f, 32); + case_brr(bne, _f); + case_brf(bne, _f, 32); + case_brr(bunlt, _f); + case_brf(bunlt, _f, 32); + case_brr(bunle, _f); + case_brf(bunle, _f, 32); + case_brr(buneq, _f); + case_brf(buneq, _f, 32); + case_brr(bunge, _f); + case_brf(bunge, _f, 32); + case_brr(bungt, _f); + case_brf(bungt, _f, 32); + case_brr(bltgt, _f); + case_brf(bltgt, _f, 32); + case_brr(bord, _f); + case_brf(bord, _f, 32); + case_brr(bunord, _f); + case_brf(bunord, _f, 32); + case_rrr(add, _d); + case_rrf(add, _d, 64); + case_rrr(sub, _d); + case_rrf(sub, _d, 64); + case_rrf(rsb, _d, 64); + case_rrr(mul, _d); + case_rrf(mul, _d, 64); + case_rrr(div, _d); + case_rrf(div, _d, 64); + case_rr(ext, _d); + case_rr(abs, _d); + case_rr(neg, _d); + case_rr(sqrt, _d); + case_rr(ld, _d); + case_rw(ld, _d); + case_rrr(ldx, _d); + case_rrw(ldx, _d); + case_rr(st, _d); + case_wr(st, _d); + case_rrr(stx, _d); + case_wrr(stx, _d); + case_rr(mov, _d); + case jit_code_movi_d: + assert(node->flag & jit_flag_data); + movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w); + break; + case_rr(ext, _f_d); + case_rrr(lt, _d); + case_rrf(lt, _d, 64); + case_rrr(le, _d); + case_rrf(le, _d, 64); + case_rrr(eq, _d); + case_rrf(eq, _d, 64); + case_rrr(ge, _d); + case_rrf(ge, _d, 64); + case_rrr(gt, _d); + case_rrf(gt, _d, 64); + case_rrr(ne, _d); + case_rrf(ne, _d, 64); + case_rrr(unlt, _d); + case_rrf(unlt, _d, 64); + case_rrr(unle, _d); + case_rrf(unle, _d, 64); + case_rrr(uneq, _d); + case_rrf(uneq, _d, 64); + case_rrr(unge, _d); + case_rrf(unge, _d, 64); + case_rrr(ungt, _d); + case_rrf(ungt, _d, 64); + case_rrr(ltgt, _d); + case_rrf(ltgt, _d, 64); + case_rrr(ord, _d); + case_rrf(ord, _d, 64); + case_rrr(unord, _d); + case_rrf(unord, _d, 64); + case_brr(blt, _d); + case_brf(blt, _d, 64); + case_brr(ble, _d); + case_brf(ble, _d, 64); + case_brr(beq, _d); + case_brf(beq, _d, 64); + case_brr(bge, _d); + case_brf(bge, _d, 64); + case_brr(bgt, _d); + case_brf(bgt, _d, 64); + case_brr(bne, _d); + case_brf(bne, _d, 64); + case_brr(bunlt, _d); + case_brf(bunlt, _d, 64); + case_brr(bunle, _d); + case_brf(bunle, _d, 64); + case_brr(buneq, _d); + case_brf(buneq, _d, 64); + case_brr(bunge, _d); + case_brf(bunge, _d, 64); + case_brr(bungt, _d); + case_brf(bungt, _d, 64); + case_brr(bltgt, _d); + case_brf(bltgt, _d, 64); + case_brr(bord, _d); + case_brf(bord, _d, 64); + case_brr(bunord, _d); + case_brf(bunord, _d, 64); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + break; + case jit_code_jmpi: + if (node->flag & jit_flag_node) { + if (_jit->pc.uc == _jit->code.ptr + 16) + _jitc->jump = 1; + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } + } + else + jmpi(node->u.w); + break; + case jit_code_callr: + callr(rn(node->u.w)); + break; + case jit_code_calli: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = calli_p(temp->u.w); + if (!(temp->flag & jit_flag_patch)) + patch(word, node); + } + else + calli(node->u.w); + break; + case jit_code_prolog: + jit_regset_set_ui(&_jitc->regs, 0); + _jitc->pred = 0; + sync(); + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif + undo.patch_offset = _jitc->patches.offset; + undo.prolog_offset = _jitc->prolog.offset; + restart_function: + _jitc->again = 0; + if (_jitc->jump && !_jitc->function->assume_frame) { + /* remember prolog to hide offset adjustment for a jump + * to the start of a function, what is expected to be + * a common practice as first jit instruction */ + if (_jitc->prolog.offset >= _jitc->prolog.length) { + _jitc->prolog.length += 16; + jit_realloc((jit_pointer_t *)&_jitc->prolog.ptr, + (_jitc->prolog.length - 16) * + sizeof(jit_word_t), + _jitc->prolog.length * sizeof(jit_word_t)); + } + _jitc->prolog.ptr[_jitc->prolog.offset++] = _jit->pc.w; + /* function descriptor */ + word = _jit->pc.w + 16; + il(word); /* addr */ + il(0); /* gp */ + } + prolog(node); + break; + case jit_code_epilog: + assert(_jitc->function == _jitc->functions.ptr + node->w.w); + if (_jitc->again) { + for (temp = undo.node->next; + temp != node; temp = temp->next) { + if (temp->code == jit_code_label || + temp->code == jit_code_epilog) + temp->flag &= ~jit_flag_patch; + } + temp->flag &= ~jit_flag_patch; + node = undo.node; + _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif + _jitc->patches.offset = undo.patch_offset; + _jitc->prolog.offset = undo.prolog_offset; + _jitc->ioff = 0; + jit_regset_set_ui(&_jitc->regs, 0); + _jitc->pred = 0; + goto restart_function; + } + /* remember label is defined */ + sync(); + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + epilog(node); + jit_regset_set_ui(&_jitc->regs, 0); + _jitc->pred = 0; + _jitc->function = NULL; + break; + case jit_code_va_start: + vastart(rn(node->u.w)); + break; + case jit_code_va_arg: + vaarg(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_va_arg_d: + vaarg_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_live: + case jit_code_arg: case jit_code_ellipsis: + case jit_code_va_push: + case jit_code_allocai: case jit_code_allocar: + case jit_code_arg_f: case jit_code_arg_d: + case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: case jit_code_getarg_ui: + case jit_code_getarg_l: + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: + case jit_code_retval_ui: case jit_code_retval_l: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: + break; + case jit_code_movr_w_f: + movr_w_f(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movr_f_w: + movr_f_w(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movr_w_d: + movr_w_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movr_d_w: + movr_d_w(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movi_f_w: + movi_f_w(rn(node->u.w), node->v.n->u.p); + break; + case jit_code_movi_d_w: + movi_d_w(rn(node->u.w), node->v.n->u.p); + break; + default: + abort(); + } + if (jit_carry != _NOREG) { + switch (node->code) { + case jit_code_note: + case jit_code_addcr: case jit_code_addci: + case jit_code_addxr: case jit_code_addxi: + case jit_code_subcr: case jit_code_subci: + case jit_code_subxr: case jit_code_subxi: + break; + default: + jit_unget_reg(jit_carry); + jit_carry = _NOREG; + break; + } + } +#if GET_JIT_SIZE + sync(); +#endif + jit_regarg_clr(node, value); + if (jit_regset_cmp_ui(&_jitc->regarg, 0) != 0) { + assert(jit_regset_scan1(&_jitc->regarg, 0) == jit_carry); + assert(jit_regset_scan1(&_jitc->regarg, jit_carry + 1) == ULONG_MAX); + } + assert(_jitc->synth == 0); + /* update register live state */ + jit_reglive(node); + } + sync(); +#undef case_brf +#undef case_brw +#undef case_brr +#undef case_wrr +#undef case_rrrw +#undef case_rrf +#undef case_rrw +#undef case_rrrr +#undef case_rrr +#undef case_wr +#undef case_rw +#undef case_rr + + for (offset = 0; offset < _jitc->patches.offset; offset++) { + node = _jitc->patches.ptr[offset].node; + word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(node->code, _jitc->patches.ptr[offset].inst, word); + } + + jit_flush(_jit->code.ptr, _jit->pc.uc); + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_ia64-cpu.c" +# include "jit_ia64-fpu.c" +#undef CODE + +void +jit_flush(void *fptr, void *tptr) +{ +#if defined(__GNUC__) + jit_word_t f, t, s; + + s = sysconf(_SC_PAGE_SIZE); + f = (jit_word_t)fptr & -s; + t = (((jit_word_t)tptr) + s - 1) & -s; +# if 0 + __clear_cache((void *)f, (void *)t); +# else + /* __clear_cache is a noop in (old?) gcc, but cache flush is + * required on a multi processor Linux system. */ + for (s = f; s < t; s += 32) + asm volatile("fc %0" :: "r"(s) : "memory"); +# endif +#endif +} + +/* Use r2 that is reserved to not require a jit_get_reg call, also note + * that addil needs a register that first in 2 bits, so, if using a + * register other than r2 must be less than r8 (or check for a smaller + * immediate, i.e. i0 >= -8192 && i0 <= 8191) */ +void +_emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0) +{ + assert(i0 >= -2097152 && i0 < 2097151); + addi(GR_2, rn(r1), i0); + ldr(rn(r0), GR_2); +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1) +{ + assert(i0 >= -2097152 && i0 < 2097151); + addi(GR_2, rn(r0), i0); + str(GR_2, rn(r1)); +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0) +{ + assert(i0 >= -2097152 && i0 < 2097151); + addi(GR_2, rn(r1), i0); + ldr_d(rn(r0), GR_2); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1) +{ + assert(i0 >= -2097152 && i0 < 2097151); + addi(GR_2, rn(r0), i0); + str_d(GR_2, rn(r1)); +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) + flag = node->v.n->flag; + else + flag = node->u.n->flag; + assert(!(flag & jit_flag_patch)); + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} diff --git a/deps/lightning/lib/jit_memory.c b/deps/lightning/lib/jit_memory.c new file mode 100644 index 0000000..e6b4c73 --- /dev/null +++ b/deps/lightning/lib/jit_memory.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include <lightning.h> +#include <lightning/jit_private.h> +#include <mman.h> + +/* + * Prototypes + */ +static void *jit_default_alloc_func(size_t); +static void *jit_default_realloc_func(void*, size_t); +static void jit_default_free_func(void *); + +/* + * Initialization + */ +static jit_alloc_func_ptr jit_alloc_ptr = jit_default_alloc_func; +static jit_realloc_func_ptr jit_realloc_ptr = jit_default_realloc_func; +static jit_free_func_ptr jit_free_ptr = jit_default_free_func; + +/* + * Implementation + */ +jit_pointer_t +jit_memcpy(jit_pointer_t dst, const void * src, jit_word_t size) +{ + if (size) + return (memcpy(dst, src, size)); + return (dst); +} + +jit_pointer_t +jit_memmove(jit_pointer_t dst, const void *src , jit_word_t size) +{ + if (size) + return (memmove(dst, src, size)); + return (dst); +} + +void +jit_set_memory_functions(jit_alloc_func_ptr alloc_ptr, + jit_realloc_func_ptr realloc_ptr, + jit_free_func_ptr free_ptr) +{ + if (alloc_ptr == NULL) + alloc_ptr = jit_default_alloc_func; + if (realloc_ptr == NULL) + realloc_ptr = jit_default_realloc_func; + if (free_ptr == NULL) + free_ptr = jit_default_free_func; + jit_alloc_ptr = alloc_ptr; + jit_realloc_ptr = realloc_ptr; + jit_free_ptr = free_ptr; +} + +void +jit_get_memory_functions(jit_alloc_func_ptr *alloc_ptr, + jit_realloc_func_ptr *realloc_ptr, + jit_free_func_ptr *free_ptr) +{ + *alloc_ptr = jit_alloc_ptr; + *realloc_ptr = jit_realloc_ptr; + *free_ptr = jit_free_ptr; +} + +void +jit_alloc(jit_pointer_t *ptr, jit_word_t size) +{ + *ptr = (*jit_alloc_ptr)(size); + memset(*ptr, 0, size); +} + +void +jit_realloc(jit_pointer_t *ptr, jit_word_t old_size, jit_word_t new_size) +{ + *ptr = (*jit_realloc_ptr)(*ptr, new_size); + if (old_size < new_size) + memset((jit_int8_t*)*ptr + old_size, 0, new_size - old_size); +} + +void +jit_free(jit_pointer_t *ptr) +{ + if (*ptr) { + (*jit_free_ptr)(*ptr); + *ptr = NULL; + } +} + +static void * +jit_default_alloc_func(size_t size) +{ + return (malloc(size)); +} + +static void * +jit_default_realloc_func(void *ptr, size_t size) +{ + return (realloc(ptr, size)); +} + +static void +jit_default_free_func(void *ptr) +{ + free(ptr); +} diff --git a/deps/lightning/lib/jit_mips-cpu.c b/deps/lightning/lib/jit_mips-cpu.c new file mode 100644 index 0000000..8fb7fa1 --- /dev/null +++ b/deps/lightning/lib/jit_mips-cpu.c @@ -0,0 +1,3157 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +typedef union { +#if __BYTE_ORDER == __LITTLE_ENDIAN + struct { jit_uint32_t _:26; jit_uint32_t b : 6; } hc; + struct { jit_uint32_t _:21; jit_uint32_t b : 5; } rs; + struct { jit_uint32_t _:21; jit_uint32_t b : 5; } fm; + struct { jit_uint32_t _:16; jit_uint32_t b : 5; } rt; + struct { jit_uint32_t _:16; jit_uint32_t b : 5; } ft; + struct { jit_uint32_t _:11; jit_uint32_t b : 5; } rd; + struct { jit_uint32_t _:11; jit_uint32_t b : 5; } fs; + struct { jit_uint32_t _: 6; jit_uint32_t b : 5; } ic; + struct { jit_uint32_t _: 6; jit_uint32_t b : 5; } fd; + struct { jit_uint32_t _: 6; jit_uint32_t b : 10; } tr; + struct { jit_uint32_t _: 6; jit_uint32_t b : 20; } br; + struct { jit_uint32_t b : 6; } tc; + struct { jit_uint32_t b : 11; } cc; + struct { jit_uint32_t b : 16; } is; + struct { jit_uint32_t b : 26; } ii; +#else + struct { jit_uint32_t b : 6; } hc; + struct { jit_uint32_t _: 6; jit_uint32_t b : 5; } rs; + struct { jit_uint32_t _: 6; jit_uint32_t b : 5; } fm; + struct { jit_uint32_t _:11; jit_uint32_t b : 5; } rt; + struct { jit_uint32_t _:11; jit_uint32_t b : 5; } ft; + struct { jit_uint32_t _:16; jit_uint32_t b : 5; } rd; + struct { jit_uint32_t _:16; jit_uint32_t b : 5; } fs; + struct { jit_uint32_t _:21; jit_uint32_t b : 5; } ic; + struct { jit_uint32_t _:21; jit_uint32_t b : 5; } fd; + struct { jit_uint32_t _:21; jit_uint32_t b : 10; } tr; + struct { jit_uint32_t _:21; jit_uint32_t b : 20; } br; + struct { jit_uint32_t _:26; jit_uint32_t b : 6; } tc; + struct { jit_uint32_t _:21; jit_uint32_t b : 11; } cc; + struct { jit_uint32_t _:16; jit_uint32_t b : 16; } is; + struct { jit_uint32_t _: 6; jit_uint32_t b : 26; } ii; +#endif + int op; +} jit_instr_t; +/* FIXME */ +# define jit_mips2_p() 0 +# define _ZERO_REGNO 0 +# define _T0_REGNO 0x08 +# define _T1_REGNO 0x09 +# define _T2_REGNO 0x0a +# define _T3_REGNO 0x0b +# define _T4_REGNO 0x0c +# define _T5_REGNO 0x0d +# define _T6_REGNO 0x0e +# define _T7_REGNO 0x0f +# define _S0_REGNO 0x10 +# define _S1_REGNO 0x11 +# define _S2_REGNO 0x12 +# define _S3_REGNO 0x13 +# define _S4_REGNO 0x14 +# define _S5_REGNO 0x15 +# define _S6_REGNO 0x16 +# define _S7_REGNO 0x17 +# define _T8_REGNO 0x18 +# define _T9_REGNO 0x19 +# define _SP_REGNO 0x1d +# define _BP_REGNO 0x1e +# define _RA_REGNO 0x1f +# define _F16_REGNO 16 +# define _F18_REGNO 18 +# define _F20_REGNO 20 +# define _F22_REGNO 22 +# define _F24_REGNO 24 +# define _F26_REGNO 26 +# define _F28_REGNO 28 +# define _F30_REGNO 30 +# if __WORDSIZE == 32 +# if NEW_ABI +# define stack_framesize 144 +# else +# define stack_framesize 112 +# endif +# define ldr(u,v) ldr_i(u,v) +# define ldi(u,v) ldi_i(u,v) +# define ldxi(u,v,w) ldxi_i(u,v,w) +# define sti(u,v) sti_i(u,v) +# define stxi(u,v,w) stxi_i(u,v,w) +# else +# define stack_framesize 144 +# define ldr(u,v) ldr_l(u,v) +# define ldi(u,v) ldi_l(u,v) +# define ldxi(u,v,w) ldxi_l(u,v,w) +# define sti(u,v) sti_l(u,v) +# define stxi(u,v,w) stxi_l(u,v,w) +# endif +# define can_sign_extend_short_p(im) ((im) >= -32678 && (im) <= 32767) +# define can_zero_extend_short_p(im) ((im) >= 0 && (im) <= 65535) +# if __WORDSIZE == 32 +# define can_sign_extend_int_p(im) 1 +# define can_zero_extend_int_p(im) 1 +# else +# define can_sign_extend_int_p(im) \ + (((im) >= 0 && (im) <= 0x7fffffffL) || \ + ((im) < 0 && (im) >= -0x80000000L)) +# define can_zero_extend_int_p(im) ((im) >= 0 && (im) <= 0xffffffff) +# endif +# define MIPS_SPECIAL 0x00 +# define MIPS_REGIMM 0x01 +# define MIPS_J 0x02 +# define MIPS_SRL 0x02 +# define MIPS_JAL 0x03 +# define MIPS_SRA 0x03 +# define MIPS_BEQ 0x04 +# define MIPS_BNE 0x05 +# define MIPS_BLEZ 0x06 +# define MIPS_BGTZ 0x07 +# define MIPS_ADDI 0x08 +# define MIPS_ADDIU 0x09 +# define MIPS_SLTI 0x0a +# define MIPS_SLTIU 0x0b +# define MIPS_ANDI 0x0c +# define MIPS_ORI 0x0d +# define MIPS_XORI 0x0e +# define MIPS_LUI 0x0f +# define MIPS_COP0 0x10 +# define MIPS_COP1 0x11 +# define MIPS_COP2 0x12 +# define MIPS_COP1X 0x13 +# define MIPS_BEQL 0x14 +# define MIPS_BNEL 0x15 +# define MIPS_BLEZL 0x16 +# define MIPS_BGTZL 0x17 +# define MIPS_DADDI 0x18 +# define MIPS_DADDIU 0x19 +# define MIPS_LDL 0x1a +# define MIPS_LDR 0x1b +# define MIPS_SPECIAL2 0x1c +# define MIPS_JALX 0x1d +# define MIPS_SPECIAL3 0x1f +# define MIPS_LB 0x20 +# define MIPS_LH 0x21 +# define MIPS_LWL 0x22 +# define MIPS_LW 0x23 +# define MIPS_LBU 0x24 +# define MIPS_LHU 0x25 +# define MIPS_LWR 0x26 +# define MIPS_LWU 0x27 +# define MIPS_SB 0x28 +# define MIPS_SH 0x29 +# define MIPS_SWL 0x2a +# define MIPS_SW 0x2b +# define MIPS_SWR 0x2e +# define MIPS_CACHE 0x2f +# define MIPS_LL 0x30 +# define MIPS_LWC1 0x31 +# define MIPS_LWC2 0x32 +# define MIPS_PREF 0x33 +# define MIPS_LLD 0x34 +# define MIPS_LDC1 0x35 +# define MIPS_LDC2 0x36 +# define MIPS_LD 0x37 +# define MIPS_SC 0x38 +# define MIPS_SCD 0x3c +# define MIPS_SDC1 0x3d +# define MIPS_SDC2 0x3e +# define MIPS_SWC1 0x39 +# define MIPS_SWC2 0x3a +# define MIPS_SD 0x3f +# define MIPS_MF 0x00 +# define MIPS_DMF 0x01 +# define MIPS_CF 0x02 +# define MIPS_MFH 0x03 +# define MIPS_MT 0x04 +# define MIPS_DMT 0x05 +# define MIPS_CT 0x06 +# define MIPS_MTH 0x07 +# define MIPS_BC 0x08 +# define MIPS_WRPGPR 0x0e +# define MIPS_BGZAL 0x11 +# define MIPS_MFMC0 0x11 +# define MIPS_BCF 0x00 +# define MIPS_BLTZ 0x00 +# define MIPS_BCT 0x01 +# define MIPS_BGEZ 0x01 +# define MIPS_BCFL 0x02 +# define MIPS_BLTZL 0x02 +# define MIPS_BCTL 0x03 +# define MIPS_BGEZL 0x03 +# define MIPS_TGEI 0x08 +# define MIPS_TGEIU 0x09 +# define MIPS_TLTI 0x0a +# define MIPS_TLTIU 0x0b +# define MIPS_TEQI 0x0c +# define MIPS_TNEI 0x0e +# define MIPS_BLTZAL 0x10 +# define MIPS_BGEZAL 0x11 +# define MIPS_BLTZALL 0x12 +# define MIPS_BGEZALL 0x13 +# define MIPS_SYNCI 0x1f +# define MIPS_WSBH 0x02 +# define MIPS_DBSH 0x02 +# define MIPS_DSHD 0x05 +# define MIPS_SEB 0x10 +# define MIPS_SEH 0x18 +# define MIPS_MADD 0x00 +# define MIPS_SLL 0x00 +# define MIPS_EXT 0x00 +# define MIPS_DEXTM 0x01 +# define MIPS_MADDU 0x01 +# define MIPS_MOVFT 0x01 +# define MIPS_TLBR 0x01 +# define MIPS_MUL 0x02 +# define MIPS_DEXTU 0x02 +# define MIPS_TLBWI 0x02 +# define MIPS_DEXT 0x03 +# define MIPS_SLLV 0x04 +# define MIPS_INS 0x04 +# define MIPS_MSUB 0x04 +# define MIPS_DINSM 0x05 +# define MIPS_MSUBU 0x05 +# define MIPS_SRLV 0x06 +# define MIPS_DINSU 0x06 +# define MIPS_TLBWR 0x06 +# define MIPS_SRAV 0x07 +# define MIPS_DINS 0x07 +# define MIPS_JR 0x08 +# define MIPS_TLBP 0x08 +# define MIPS_JALR 0x09 +# define MIPS_MOVZ 0x0a +# define MIPS_MOVN 0x0b +# define MIPS_SYSCALL 0x0c +# define MIPS_BREAK 0x0d +# define MIPS_PREFX 0x0f +# define MIPS_SYNC 0x0f +# define MIPS_MFHI 0x10 +# define MIPS_MTHI 0x11 +# define MIPS_MFLO 0x12 +# define MIPS_MTLO 0x13 +# define MIPS_DSLLV 0x14 +# define MIPS_DSRLV 0x16 +# define MIPS_DSRAV 0x17 +# define MIPS_MULT 0x18 +# define MIPS_ERET 0x18 +# define MIPS_MULTU 0x19 +# define MIPS_DIV 0x1a +# define MIPS_DIVU 0x1b +# define MIPS_DMULT 0x1c +# define MIPS_DMULTU 0x1d +# define MIPS_DDIV 0x1e +# define MIPS_DDIVU 0x1f +# define MIPS_DERET 0x1f +# define MIPS_ADD 0x20 +# define MIPS_CLZ 0x20 +# define MIPS_BSHFL 0x20 +# define MIPS_ADDU 0x21 +# define MIPS_CLO 0x21 +# define MIPS_SUB 0x22 +# define MIPS_SUBU 0x23 +# define MIPS_AND 0x24 +# define MIPS_DCLZ 0x24 +# define MIPS_DBSHFL 0x24 +# define MIPS_OR 0x25 +# define MIPS_DCLO 0x25 +# define MIPS_XOR 0x26 +# define MIPS_NOR 0x27 +# define MIPS_SLT 0x2a +# define MIPS_SLTU 0x2b +# define MIPS_DADD 0x2c +# define MIPS_DADDU 0x2d +# define MIPS_DSUB 0x2e +# define MIPS_DSUBU 0x2f +# define MIPS_TGE 0x30 +# define MIPS_TGEU 0x31 +# define MIPS_TLT 0x32 +# define MIPS_TLTU 0x33 +# define MIPS_TEQ 0x34 +# define MIPS_TNE 0x36 +# define MIPS_DSLL 0x38 +# define MIPS_DSRL 0x3a +# define MIPS_DSRA 0x3b +# define MIPS_DSLL32 0x3c +# define MIPS_DSRL32 0x3e +# define MIPS_DSRA32 0x3f +# define MIPS_SDBPP 0x3f +# define ii(i) *_jit->pc.ui++ = i +static void +_hrrrit(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t); +# define hrrrit(hc,rs,rt,rd,im,tc) _hrrrit(_jit,hc,rs,rt,rd,im,tc) +# define hrrr_t(hc,rs,rt,rd,tc) hrrrit(hc,rs,rt,rd,0,tc) +# define rrr_t(rs,rt,rd,tc) hrrr_t(0,rs,rt,rd,tc) +# define hrri(hc,rs,rt,im) _hrri(_jit,hc,rs,rt,im) +static void _hrri(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define hi(hc,im) _hi(_jit,hc,im) +static void _hi(jit_state_t*,jit_int32_t,jit_int32_t); +# define NOP(i0) ii(0) +# define nop(i0) _nop(_jit,i0) +static void _nop(jit_state_t*,jit_int32_t); +# define h_ri(hc,rt,im) _hrri(_jit,hc,0,rt,im) +# define rrit(rt,rd,im,tc) _hrrrit(_jit,0,0,rt,rd,im,tc) +# define LUI(rt,im) h_ri(MIPS_LUI,rt,im) +# define ADDU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_ADDU) +# define DADDU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_DADDU) +# define ADDIU(rt,rs,im) hrri(MIPS_ADDIU,rs,rt,im) +# define DADDIU(rt,rs,im) hrri(MIPS_DADDIU,rs,rt,im) +# define SUBU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_SUBU) +# define DSUBU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_DSUBU) +# define MULT(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_MULT) +# define MULTU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_MULTU) +# define DMULT(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DMULT) +# define DMULTU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DMULTU) +# define DIV(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DIV) +# define DIVU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DIVU) +# define DDIV(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DDIV) +# define DDIVU(rs,rt) rrr_t(rs,rt,_ZERO_REGNO,MIPS_DDIVU) +# define SLLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SLLV) +# define SLL(rd,rt,sa) rrit(rt,rd,sa,MIPS_SLL) +# define DSLLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSLLV) +# define DSLL(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSLL) +# define DSLL32(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSLL32) +# define SRAV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SRAV) +# define SRA(rd,rt,sa) rrit(rt,rd,sa,MIPS_SRA) +# define SRLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_SRLV) +# define SRL(rd,rt,sa) rrit(rt,rd,sa,MIPS_SRL) +# define DSRAV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSRAV) +# define DSRA(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRA) +# define DSRA32(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRA32) +# define DSRLV(rd,rt,rs) rrr_t(rs,rt,rd,MIPS_DSRLV) +# define DSRL(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRL) +# define DSRL32(rd,rt,sa) rrit(rt,rd,sa,MIPS_DSRL32) +# define INS(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,pos,pos+size-1,MIPS_INS) +# define DINS(rt,rs,pos,size) hrrrit(MIPS_SPECIAL3,rs,rt,pos,pos+size-1,MIPS_DINS) +# define ROTR(rd,rt,sa) hrrrit(MIPS_SPECIAL,1,rt,rd,sa,MIPS_SRL) +# define DROTR(rd,rt,sa) hrrrit(MIPS_SPECIAL,1,rt,rd,sa,MIPS_DSRL) +# define MFHI(rd) rrr_t(_ZERO_REGNO,_ZERO_REGNO,rd,MIPS_MFHI) +# define MFLO(rd) rrr_t(_ZERO_REGNO,_ZERO_REGNO,rd,MIPS_MFLO) +# define MTHI(rs) rrr_t(rs,_ZERO_REGNO,_ZERO_REGNO,MIPS_MTHI) +# define MTLO(rs) rrr_t(rs,_ZERO_REGNO,_ZERO_REGNO,MIPS_MTLO) +# define AND(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_AND) +# define ANDI(rt,rs,im) hrri(MIPS_ANDI,rs,rt,im) +# define OR(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_OR) +# define ORI(rt,rs,im) hrri(MIPS_ORI,rs,rt,im) +# define XOR(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_XOR) +# define XORI(rt,rs,im) hrri(MIPS_XORI,rs,rt,im) +# define LB(rt,of,rb) hrri(MIPS_LB,rb,rt,of) +# define LBU(rt,of,rb) hrri(MIPS_LBU,rb,rt,of) +# define LH(rt,of,rb) hrri(MIPS_LH,rb,rt,of) +# define LHU(rt,of,rb) hrri(MIPS_LHU,rb,rt,of) +# define LW(rt,of,rb) hrri(MIPS_LW,rb,rt,of) +# define LWU(rt,of,rb) hrri(MIPS_LWU,rb,rt,of) +# define LD(rt,of,rb) hrri(MIPS_LD,rb,rt,of) +# define SB(rt,of,rb) hrri(MIPS_SB,rb,rt,of) +# define SH(rt,of,rb) hrri(MIPS_SH,rb,rt,of) +# define SW(rt,of,rb) hrri(MIPS_SW,rb,rt,of) +# define SD(rt,of,rb) hrri(MIPS_SD,rb,rt,of) +# define WSBH(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,MIPS_WSBH,MIPS_BSHFL) +# define SEB(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,MIPS_SEB,MIPS_BSHFL) +# define SEH(rd,rt) hrrrit(MIPS_SPECIAL3,0,rt,rd,MIPS_SEH,MIPS_BSHFL) +# define SLT(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_SLT) +# define SLTU(rd,rs,rt) rrr_t(rs,rt,rd,MIPS_SLTU) +# define SLTI(rt,rs,im) hrri(MIPS_SLTI,rs,rt,im) +# define SLTIU(rt,rs,im) hrri(MIPS_SLTIU,rs,rt,im) +# define BLTZ(rs,im) hrri(MIPS_REGIMM,rs,MIPS_BLTZ,im) +# define BLEZ(rs,im) hrri(MIPS_BLEZ,rs,_ZERO_REGNO,im) +# define BEQ(rs,rt,im) hrri(MIPS_BEQ,rs,rt,im) +# define BGEZ(rs,im) hrri(MIPS_REGIMM,rs,MIPS_BGEZ,im) +# define BGTZ(rs,im) hrri(MIPS_BGTZ,rs,_ZERO_REGNO,im) +# define BNE(rs,rt,im) hrri(MIPS_BNE,rs,rt,im) +# define JALR(r0) hrrrit(MIPS_SPECIAL,r0,0,_RA_REGNO,0,MIPS_JALR) +# if 1 /* supports MIPS32 R6 */ +# define JR(r0) hrrrit(MIPS_SPECIAL,r0,0,0,0,MIPS_JALR) +# else /* does not support MIPS32 R6 */ +# define JR(r0) hrrrit(MIPS_SPECIAL,r0,0,0,0,MIPS_JR) +# endif +# define J(i0) hi(MIPS_J,i0) +# define MOVZ(rd,rs,rt) hrrrit(0,rs,rt,rd,0,MIPS_MOVZ) +# define comr(r0,r1) xori(r0,r1,-1) +# define negr(r0,r1) subr(r0,_ZERO_REGNO,r1) +# if __WORDSIZE == 32 +# define addr(rd,rs,rt) ADDU(rd,rs,rt) +# define addiu(r0,r1,i0) ADDIU(r0,r1,i0) +# define subr(rd,rs,rt) SUBU(rd,rs,rt) +# define mult(rs,rt) MULT(rs,rt) +# define multu(rs,rt) MULTU(rs,rt) +# define div(rs,rt) DIV(rs,rt) +# define divu(rs,rt) DIVU(rs,rt) +# else +# define addr(rd,rs,rt) DADDU(rd,rs,rt) +# define addiu(r0,r1,i0) DADDIU(r0,r1,i0) +# define subr(rd,rs,rt) DSUBU(rd,rs,rt) +# define mult(rs,rt) DMULT(rs,rt) +# define multu(rs,rt) DMULTU(rs,rt) +# define div(rs,rt) DDIV(rs,rt) +# define divu(rs,rt) DDIVU(rs,rt) +# endif +# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0) +static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define addcr(r0,r1,r2) _addcr(_jit,r0,r1,r2) +static void _addcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define addci(r0,r1,i0) _addci(_jit,r0,r1,i0) +static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addxr(r0,r1,r2) _addxr(_jit,r0,r1,r2) +static void _addxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0) +static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subi(r0,r1,i0) _subi(_jit,r0,r1,i0) +static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subcr(r0,r1,r2) _subcr(_jit,r0,r1,r2) +static void _subcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subci(r0,r1,i0) _subci(_jit,r0,r1,i0) +static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subxr(r0,r1,r2) _subxr(_jit,r0,r1,r2) +static void _subxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subxi(r0,r1,i0) _subxi(_jit,r0,r1,i0) +static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0) +static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define mulr(r0,r1,r2) _mulr(_jit,r0,r1,r2) +static void _mulr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define muli(r0,r1,i0) _muli(_jit,r0,r1,i0) +static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,1) +# define qmulr_u(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,0) +# define iqmulr(r0,r1,r2,r3,cc) _iqmulr(_jit,r0,r1,r2,r3,cc) +static void _iqmulr(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_bool_t); +# define qmuli(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,1) +# define qmuli_u(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,0) +# define iqmuli(r0,r1,r2,i0,cc) _iqmuli(_jit,r0,r1,r2,i0,cc) +static void _iqmuli(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_word_t,jit_bool_t); +# define divr(r0,r1,r2) _divr(_jit,r0,r1,r2) +static void _divr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi(r0,r1,i0) _divi(_jit,r0,r1,i0) +static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define divr_u(r0,r1,r2) _divr_u(_jit,r0,r1,r2) +static void _divr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0) +static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qdivr(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,1) +# define qdivr_u(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,0) +# define iqdivr(r0,r1,r2,r3,cc) _iqdivr(_jit,r0,r1,r2,r3,cc) +static void _iqdivr(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_bool_t); +# define qdivi(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,1) +# define qdivi_u(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,0) +# define iqdivi(r0,r1,r2,i0,cc) _iqdivi(_jit,r0,r1,r2,i0,cc) +static void _iqdivi(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_word_t,jit_bool_t); +# define remr(r0,r1,r2) _remr(_jit,r0,r1,r2) +static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi(r0,r1,i0) _remi(_jit,r0,r1,i0) +static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2) +static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0) +static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define lshr(r0,r1,r2) SLLV(r0,r1,r2) +# define lshi(r0,r1,i0) SLL(r0,r1,i0) +# define rshr(r0,r1,r2) SRAV(r0,r1,r2) +# define rshi(r0,r1,i0) SRA(r0,r1,i0) +# define rshr_u(r0,r1,r2) SRLV(r0,r1,r2) +# define rshi_u(r0,r1,i0) SRL(r0,r1,i0) +# else +# define lshr(r0,r1,r2) DSLLV(r0,r1,r2) +# define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0) +static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr(r0,r1,r2) DSRAV(r0,r1,r2) +# define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0) +static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr_u(r0,r1,r2) DSRLV(r0,r1,r2) +# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0) +static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# endif +# define andr(r0,r1,r2) AND(r0,r1,r2) +# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0) +static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define orr(r0,r1,r2) OR(r0,r1,r2) +# define ori(r0,r1,i0) _ori(_jit,r0,r1,i0) +static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define xorr(r0,r1,r2) XOR(r0,r1,r2) +# define xori(r0,r1,i0) _xori(_jit,r0,r1,i0) +static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define movr(r0,r1) orr(r0,r1,_ZERO_REGNO) +# define movi(r0,i0) _movi(_jit,r0,i0) +static void _movi(jit_state_t*,jit_int32_t,jit_word_t); +# define movi_p(r0,i0) _movi_p(_jit,r0,i0) +static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_c(r0,r1) LB(r0,0,r1) +# define ldi_c(r0,i0) _ldi_c(_jit,r0,i0) +static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_uc(r0,r1) LBU(r0,0,r1) +# define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0) +static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_s(r0,r1) LH(r0,0,r1) +# define ldi_s(r0,i0) _ldi_s(_jit,r0,i0) +static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_us(r0,r1) LHU(r0,0,r1) +# define ldi_us(r0,i0) _ldi_us(_jit,r0,i0) +static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_i(r0,r1) LW(r0,0,r1) +# define ldi_i(r0,i0) _ldi_i(_jit,r0,i0) +static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t); +# if __WORDSIZE == 64 +# define ldr_ui(r0,r1) LWU(r0,0,r1) +# define ldi_ui(r0,i0) _ldi_ui(_jit,r0,i0) +static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_l(r0,r1) LD(r0,0,r1) +# define ldi_l(r0,i0) _ldi_l(_jit,r0,i0) +static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t); +# endif +# define ldxr_c(r0,r1,r2) _ldxr_c(_jit,r0,r1,r2) +static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0) +static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_uc(r0,r1,r2) _ldxr_uc(_jit,r0,r1,r2) +static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0) +static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_s(r0,r1,r2) _ldxr_s(_jit,r0,r1,r2) +static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0) +static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_us(r0,r1,r2) _ldxr_us(_jit,r0,r1,r2) +static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0) +static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_i(r0,r1,r2) _ldxr_i(_jit,r0,r1,r2) +static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_i(r0,r1,i0) _ldxi_i(_jit,r0,r1,i0) +static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 64 +# define ldxr_ui(r0,r1,r2) _ldxr_ui(_jit,r0,r1,r2) +static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_ui(r0,r1,i0) _ldxi_ui(_jit,r0,r1,i0) +static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_l(r0,r1,r2) _ldxr_l(_jit,r0,r1,r2) +static void _ldxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_l(r0,r1,i0) _ldxi_l(_jit,r0,r1,i0) +static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# endif +# define str_c(r0,r1) SB(r1,0,r0) +# define sti_c(i0,r0) _sti_c(_jit,i0,r0) +static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t); +# define str_s(r0,r1) SH(r1,0,r0) +# define sti_s(i0,r0) _sti_s(_jit,i0,r0) +static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t); +# define str_i(r0,r1) SW(r1,0,r0) +# define sti_i(i0,r0) _sti_i(_jit,i0,r0) +static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); +# if __WORDSIZE == 64 +# define str_l(r0,r1) SD(r1,0,r0) +# define sti_l(i0,r0) _sti_l(_jit,i0,r0) +static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t); +# endif +# define stxr_c(r0,r1,r2) _stxr_c(_jit,r0,r1,r2) +static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_c(i0,r0,r1) _stxi_c(_jit,i0,r0,r1) +static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_s(r0,r1,r2) _stxr_s(_jit,r0,r1,r2) +static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_s(i0,r0,r1) _stxi_s(_jit,i0,r0,r1) +static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_i(r0,r1,r2) _stxr_i(_jit,r0,r1,r2) +static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_i(i0,r0,r1) _stxi_i(_jit,i0,r0,r1) +static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# if __WORDSIZE == 64 +# define stxr_l(r0,r1,r2) _stxr_l(_jit,r0,r1,r2) +static void _stxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1) +static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# endif +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1) +static void _htonr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1) +static void _htonr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# if __WORDSIZE == 64 +# define htonr_ul(r0,r1) _htonr_ul(_jit,r0,r1) +static void _htonr_ul(jit_state_t*,jit_int32_t,jit_int32_t); +# endif +# else +# define htonr_us(r0,r1) extr_us(r0,r1) +# if __WORDSIZE == 32 +# define htonr_ui(r0,r1) movr(r0,r1) +# else +# define htonr_ui(r0,r1) extr_ui(r0,r1) +# define htonr_ul(r0,r1) movr(r0,r1) +# endif +# endif +# define extr_c(r0,r1) _extr_c(_jit,r0,r1) +static void _extr_c(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_uc(r0,r1) ANDI(r0,r1,0xff) +# define extr_s(r0,r1) _extr_s(_jit,r0,r1) +static void _extr_s(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_us(r0,r1) ANDI(r0,r1,0xffff) +# if __WORDSIZE == 64 +# define extr_i(r0,r1) SLL(r0,r1,0) +# define extr_ui(r0,r1) _extr_ui(_jit,r0,r1) +static void _extr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# endif +# define ltr(r0,r1,r2) SLT(r0,r1,r2) +# define lti(r0,r1,i0) _lti(_jit,r0,r1,i0) +static void _lti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ltr_u(r0,r1,r2) SLTU(r0,r1,r2) +# define lti_u(r0,r1,i0) _lti_u(_jit,r0,r1,i0) +static void _lti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ler(r0,r1,r2) _ler(_jit,r0,r1,r2) +static void _ler(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define lei(r0,r1,i0) _lei(_jit,r0,r1,i0) +static void _lei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ler_u(r0,r1,r2) _ler_u(_jit,r0,r1,r2) +static void _ler_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define lei_u(r0,r1,i0) _lei_u(_jit,r0,r1,i0) +static void _lei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define eqr(r0,r1,r2) _eqr(_jit,r0,r1,r2) +static void _eqr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define eqi(r0,r1,i0) _eqi(_jit,r0,r1,i0) +static void _eqi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ger(r0,r1,r2) _ger(_jit,r0,r1,r2) +static void _ger(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define gei(r0,r1,i0) _gei(_jit,r0,r1,i0) +static void _gei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ger_u(r0,r1,i0) _ger_u(_jit,r0,r1,i0) +static void _ger_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define gei_u(r0,r1,i0) _gei_u(_jit,r0,r1,i0) +static void _gei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define gtr(r0,r1,r2) SLT(r0,r2,r1) +#define gti(r0,r1,i0) _gti(_jit,r0,r1,i0) +static void _gti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define gtr_u(r0,r1,r2) SLTU(r0,r2,r1) +# define gti_u(r0,r1,i0) _gti_u(_jit,r0,r1,i0) +static void _gti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define ner(r0,r1,r2) _ner(_jit,r0,r1,r2) +static void _ner(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +#define nei(r0,r1,i0) _nei(_jit,r0,r1,i0) +static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define bltr(i0,r0,r1) _bltr(_jit,i0,r0,r1) +static jit_word_t _bltr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bltr_u(i0,r0,r1) _bltr_u(_jit,i0,r0,r1) +static jit_word_t _bltr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define blti(i0,r0,i1) _blti(_jit,i0,r0,i1) +static jit_word_t _blti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define blti_u(i0,r0,i1) _blti_u(_jit,i0,r0,i1) +static jit_word_t _blti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bler(i0,r0,r1) _bler(_jit,i0,r0,r1) +static jit_word_t _bler(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bler_u(i0,r0,r1) _bler_u(_jit,i0,r0,r1) +static jit_word_t _bler_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define blei(i0,r0,i1) _blei(_jit,i0,r0,i1) +static jit_word_t _blei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define blei_u(i0,r0,i1) _blei_u(_jit,i0,r0,i1) +static jit_word_t _blei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define beqr(i0,r0,r1) _beqr(_jit,i0,r0,r1) +static jit_word_t _beqr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define beqi(i0,r0,i1) _beqi(_jit,i0,r0,i1) +static jit_word_t _beqi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bger(i0,r0,r1) _bger(_jit,i0,r0,r1) +static jit_word_t _bger(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bger_u(i0,r0,r1) _bger_u(_jit,i0,r0,r1) +static jit_word_t _bger_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bgei(i0,r0,i1) _bgei(_jit,i0,r0,i1) +static jit_word_t _bgei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bgei_u(i0,r0,i1) _bgei_u(_jit,i0,r0,i1) +static jit_word_t _bgei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bgtr(i0,r0,r1) _bgtr(_jit,i0,r0,r1) +static jit_word_t _bgtr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bgtr_u(i0,r0,r1) _bgtr_u(_jit,i0,r0,r1) +static jit_word_t _bgtr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bgti(i0,r0,i1) _bgti(_jit,i0,r0,i1) +static jit_word_t _bgti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bgti_u(i0,r0,i1) _bgti_u(_jit,i0,r0,i1) +static jit_word_t _bgti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bner(i0,r0,r1) _bner(_jit,i0,r0,r1) +static jit_word_t _bner(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bnei(i0,r0,i1) _bnei(_jit,i0,r0,i1) +static jit_word_t _bnei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define jmpr(r0) _jmpr(_jit,r0) +static void _jmpr(jit_state_t*,jit_int32_t); +# define jmpi(i0) _jmpi(_jit,i0) +static jit_word_t _jmpi(jit_state_t*,jit_word_t); +# define boaddr(i0,r0,r1) _boaddr(_jit,i0,r0,r1) +static jit_word_t _boaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define boaddi(i0,r0,i1) _boaddi(_jit,i0,r0,i1) +static jit_word_t _boaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define boaddr_u(i0,r0,r1) _boaddr_u(_jit,i0,r0,r1) +static jit_word_t _boaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define boaddi_u(i0,r0,i1) _boaddi_u(_jit,i0,r0,i1) +static jit_word_t _boaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bxaddr(i0,r0,r1) _bxaddr(_jit,i0,r0,r1) +static jit_word_t _bxaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bxaddi(i0,r0,i1) _bxaddi(_jit,i0,r0,i1) +static jit_word_t _bxaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bxaddr_u(i0,r0,r1) _bxaddr_u(_jit,i0,r0,r1) +static jit_word_t _bxaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bxaddi_u(i0,r0,i1) _bxaddi_u(_jit,i0,r0,i1) +static jit_word_t _bxaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bosubr(i0,r0,r1) _bosubr(_jit,i0,r0,r1) +static jit_word_t _bosubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bosubi(i0,r0,i1) _bosubi(_jit,i0,r0,i1) +static jit_word_t _bosubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bosubr_u(i0,r0,r1) _bosubr_u(_jit,i0,r0,r1) +static jit_word_t _bosubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bosubi_u(i0,r0,i1) _bosubi_u(_jit,i0,r0,i1) +static jit_word_t _bosubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bxsubr(i0,r0,r1) _bxsubr(_jit,i0,r0,r1) +static jit_word_t _bxsubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bxsubi(i0,r0,i1) _bxsubi(_jit,i0,r0,i1) +static jit_word_t _bxsubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bxsubr_u(i0,r0,r1) _bxsubr_u(_jit,i0,r0,r1) +static jit_word_t _bxsubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bxsubi_u(i0,r0,i1) _bxsubi_u(_jit,i0,r0,i1) +static jit_word_t _bxsubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bmsr(i0,r0,r1) _bmsr(_jit,i0,r0,r1) +static jit_word_t _bmsr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bmsi(i0,r0,i1) _bmsi(_jit,i0,r0,i1) +static jit_word_t _bmsi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bmcr(i0,r0,r1) _bmcr(_jit,i0,r0,r1) +static jit_word_t _bmcr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bmci(i0,r0,i1) _bmci(_jit,i0,r0,i1) +static jit_word_t _bmci(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define callr(r0) _callr(_jit,r0) +static void _callr(jit_state_t*,jit_int32_t); +# define calli(i0) _calli(_jit,i0) +static void _calli(jit_state_t*,jit_word_t); +# define calli_p(i0) _calli_p(_jit,i0) +static jit_word_t _calli_p(jit_state_t*,jit_word_t); +# define prolog(node) _prolog(_jit,node) +static void _prolog(jit_state_t*,jit_node_t*); +# define epilog(node) _epilog(_jit,node) +static void _epilog(jit_state_t*,jit_node_t*); +# define vastart(r0) _vastart(_jit, r0) +static void _vastart(jit_state_t*, jit_int32_t); +# define vaarg(r0, r1) _vaarg(_jit, r0, r1) +static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t); +#define patch_abs(instr,label) _patch_abs(_jit,instr,label) +static void _patch_abs(jit_state_t*,jit_word_t,jit_word_t); +#define patch_at(jump,label) _patch_at(_jit,jump,label) +static void _patch_at(jit_state_t*,jit_word_t,jit_word_t); +#endif + +#if CODE +static void +_hrrrit(jit_state_t *_jit,jit_int32_t hc, + jit_int32_t rs, jit_int32_t rt, jit_int32_t rd, + jit_int32_t ic, jit_int32_t tc) +{ + jit_instr_t i; + i.tc.b = tc; + i.ic.b = ic; + i.rd.b = rd; + i.rt.b = rt; + i.rs.b = rs; + i.hc.b = hc; + ii(i.op); +} + +static void +_hrri(jit_state_t *_jit, jit_int32_t hc, + jit_int32_t rs, jit_int32_t rt, jit_int32_t im) +{ + jit_instr_t i; + i.op = 0; + i.is.b = im; + i.rt.b = rt; + i.rs.b = rs; + i.hc.b = hc; + ii(i.op); +} + +static void +_hi(jit_state_t *_jit, jit_int32_t hc, jit_int32_t im) +{ + jit_instr_t i; + i.ii.b = im; + i.hc.b = hc; + ii(i.op); +} + +static void +_nop(jit_state_t *_jit, jit_int32_t i0) +{ + for (; i0 > 0; i0 -= 4) + NOP(); + assert(i0 == 0); +} + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + movr(r0, r1); + else if (can_sign_extend_short_p(i0)) + addiu(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + t0 = jit_get_reg(jit_class_gpr); + addr(rn(t0), r1, r2); + SLTU(rn(jit_carry), rn(t0), r1); + movr(r0, rn(t0)); + jit_unget_reg(t0); + } + else { + addr(r0, r1, r2); + SLTU(rn(jit_carry), r0, r1); + } +} + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + t0 = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + if (can_sign_extend_short_p(i0)) + addiu(rn(t0), r1, i0); + else { + movi(rn(t0), i0); + addr(rn(t0), r1, rn(t0)); + } + SLTU(rn(jit_carry), rn(t0), r1); + movr(r0, rn(t0)); + } + else { + if (can_sign_extend_short_p(i0)) + addiu(r0, r1, i0); + else { + movi(rn(t0), i0); + addr(r0, r1, rn(t0)); + } + SLTU(rn(jit_carry), r0, r1); + } + jit_unget_reg(t0); +} + +static void +_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + + assert(jit_carry != _NOREG); + t0 = jit_get_reg(jit_class_gpr); + movr(rn(t0), rn(jit_carry)); + addcr(r0, r1, r2); + addcr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + + assert(jit_carry != _NOREG); + t0 = jit_get_reg(jit_class_gpr); + movr(rn(t0), rn(jit_carry)); + addci(r0, r1, i0); + addcr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + movr(r0, r1); + else if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) + addiu(r0, r1, -i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + t0 = jit_get_reg(jit_class_gpr); + subr(rn(t0), r1, r2); + SLTU(rn(jit_carry), r1, rn(t0)); + movr(r0, rn(t0)); + jit_unget_reg(t0); + } + else { + subr(r0, r1, r2); + SLTU(rn(jit_carry), r1, r0); + } +} + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + t0 = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) + addiu(rn(t0), r1, -i0); + else { + movi(rn(t0), i0); + subr(rn(t0), r1, rn(t0)); + } + SLTU(rn(jit_carry), r1, rn(t0)); + movr(r0, rn(t0)); + } + else { + if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) + addiu(r0, r1, -i0); + else { + movi(rn(t0), i0); + subr(r0, r1, rn(t0)); + } + SLTU(rn(jit_carry), r1, r0); + } + jit_unget_reg(t0); +} + +static void +_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + + assert(jit_carry != _NOREG); + t0 = jit_get_reg(jit_class_gpr); + movr(rn(t0), rn(jit_carry)); + subcr(r0, r1, r2); + subcr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + + assert(jit_carry != _NOREG); + t0 = jit_get_reg(jit_class_gpr); + movr(rn(t0), rn(jit_carry)); + subci(r0, r1, i0); + subcr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + subi(r0, r1, i0); + negr(r0, r0); +} + +static void +_mulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + multu(r1, r2); + MFLO(r0); +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + mulr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_iqmulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + if (sign) + mult(r2, r3); + else + multu(r2, r3); + MFLO(r0); + MFHI(r1); +} + +static void +_iqmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iqmulr(r0, r1, r2, rn(reg), sign); + jit_unget_reg(reg); +} + +static void +_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + div(r1, r2); + MFLO(r0); +} + +static void +_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + divr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + divu(r1, r2); + MFLO(r0); +} + +static void +_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + divr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_iqdivr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + if (sign) + div(r2, r3); + else + divu(r2, r3); + MFLO(r0); + MFHI(r1); +} + +static void +_iqdivi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iqdivr(r0, r1, r2, rn(reg), sign); + jit_unget_reg(reg); +} + +static void +_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + div(r1, r2); + MFHI(r0); +} + +static void +_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + divu(r1, r2); + MFHI(r0); +} + +static void +_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +#if __WORDSIZE == 64 +static void +_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + assert(i0 >= 0 && i0 <= 63); + if (i0 < 32) + DSLL(r0, r1, i0); + else + DSLL32(r0, r1, i0 - 32); +} + +static void +_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + assert(i0 >= 0 && i0 <= 63); + if (i0 < 32) + DSRA(r0, r1, i0); + else + DSRA32(r0, r1, i0 - 32); +} + +static void +_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + assert(i0 >= 0 && i0 <= 63); + if (i0 < 32) + DSRL(r0, r1, i0); + else + DSRL32(r0, r1, i0 - 32); +} +#endif + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_zero_extend_short_p(i0)) + ANDI(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + AND(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_zero_extend_short_p(i0)) + ORI(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + OR(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_zero_extend_short_p(i0)) + XORI(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + XOR(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + if (i0 == 0) + OR(r0, _ZERO_REGNO, _ZERO_REGNO); + else if (can_sign_extend_short_p(i0)) + addiu(r0, _ZERO_REGNO, i0); + else if (can_zero_extend_short_p(i0)) + ORI(r0, _ZERO_REGNO, i0); + else { + if (can_sign_extend_int_p(i0)) + LUI(r0, i0 >> 16); + else if (can_zero_extend_int_p(i0)) { + if (i0 & 0xffff0000) { + ORI(r0, _ZERO_REGNO, i0 >> 16); + lshi(r0, r0, 16); + } + } +# if __WORDSIZE == 64 + else { + movi(r0, (jit_uword_t)i0 >> 32); + if (i0 & 0xffff0000) { + lshi(r0, r0, 16); + ORI(r0, r0, i0 >> 16); + lshi(r0, r0, 16); + } + else + lshi(r0, r0, 32); + } +# endif + if (i0 & 0xffff) + ORI(r0, r0, i0); + } +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + + w = _jit->pc.w; +# if __WORDSIZE == 32 + LUI(r0, i0 >> 16); + ORI(r0, r0, i0); +# else + LUI(r0, i0 >> 48); + ORI(r0, r0, i0 >> 32); + lshi(r0, r0, 16); + ORI(r0, r0, i0 >> 16); + lshi(r0, r0, 16); + ORI(r0, r0, i0); +# endif + + return (w); +} + +static void +_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LB(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LBU(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LH(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LHU(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LW(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +#if __WORDSIZE == 64 +static void +_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LWU(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LD(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); + } +} +#endif + +static void +_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LB(r0, i0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LBU(r0, i0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LH(r0, i0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LHU(r0, i0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LW(r0, i0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +#if __WORDSIZE == 64 +static void +_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LWU(r0, i0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LD(r0, i0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); + } +} +#endif + +static void +_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + SB(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_c(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + SH(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_s(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + SW(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_i(rn(reg), r0); + jit_unget_reg(reg); + } +} + +#if __WORDSIZE == 64 +static void +_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + SD(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_l(rn(reg), r0); + jit_unget_reg(reg); + } +} +#endif + +static void +_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_c(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + SB(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_c(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_s(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + SH(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_s(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_i(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + SW(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_i(rn(reg), r1); + jit_unget_reg(reg); + } +} + +#if __WORDSIZE == 64 +static void +_stxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1 ,jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_l(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + SD(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_l(rn(reg), r1); + jit_unget_reg(reg); + } +} +#endif + +# if __BYTE_ORDER == __LITTLE_ENDIAN +static void +_htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + rshi(rn(t0), r1, 8); + andi(r0, r1, 0xff); + andi(rn(t0), rn(t0), 0xff); + lshi(r0, r0, 8); + orr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr); + t2 = jit_get_reg(jit_class_gpr); + rshi(rn(t0), r1, 24); + rshi(rn(t1), r1, 16); + rshi(rn(t2), r1, 8); + andi(rn(t0), rn(t0), 0xff); + andi(rn(t1), rn(t1), 0xff); + andi(rn(t2), rn(t2), 0xff); + andi(r0, r1, 0xff); + lshi(r0, r0, 24); + lshi(rn(t1), rn(t1), 8); + orr(r0, r0, rn(t0)); + lshi(rn(t2), rn(t2), 16); + orr(r0, r0, rn(t1)); + orr(r0, r0, rn(t2)); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); +} + +static void +_htonr_ul(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + rshi_u(rn(reg), r1, 32); + htonr_ui(r0, r1); + htonr_ui(rn(reg), rn(reg)); + lshi(r0, r0, 32); + orr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} +# endif + +static void +_extr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_mips2_p()) + SEB(r0, r1); + else { + lshi(r0, r1, __WORDSIZE - 8); + rshi(r0, r0, __WORDSIZE - 8); + } +} + +static void +_extr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (jit_mips2_p()) + SEH(r0, r1); + else { + lshi(r0, r1, __WORDSIZE - 16); + rshi(r0, r0, __WORDSIZE - 16); + } +} + +# if __WORDSIZE == 64 +static void +_extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 32); + rshi_u(r0, r0, 32); +} +# endif + +static void +_lti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + + if (can_sign_extend_short_p(i0)) + SLTI(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ltr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_lti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + + if (can_sign_extend_short_p(i0)) + SLTIU(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ltr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ler(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SLT(r0, r2, r1); + XORI(r0, r0, 1); +} + +static void +_lei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + + if (i0 == 0) { + SLT(r0, _ZERO_REGNO, r1); + XORI(r0, r0, 1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ler(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ler_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SLTU(r0, r2, r1); + XORI(r0, r0, 1); +} + +static void +_lei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + + if (i0 == 0) { + SLTU(r0, _ZERO_REGNO, r1); + XORI(r0, r0, 1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ler_u(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_eqr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + subr(r0, r1, r2); + SLTU(r0, _ZERO_REGNO, r0); + XORI(r0, r0, 1); +} + +static void +_eqi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0) { + subi(r0, r1, i0); + SLTU(r0, _ZERO_REGNO, r0); + } + else + SLTU(r0, _ZERO_REGNO, r1); + XORI(r0, r0, 1); +} + +static void +_ger(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SLT(r0, r1, r2); + XORI(r0, r0, 1); +} + +static void +_gei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ger(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ger_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SLTU(r0, r1, r2); + XORI(r0, r0, 1); +} + +static void +_gei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ger_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_gti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + + if (i0 == 0) + SLT(r0, _ZERO_REGNO, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + SLT(r0, rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_gti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + + if (i0 == 0) + SLTU(r0, _ZERO_REGNO, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + SLTU(r0, rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + subr(r0, r1, r2); + SLTU(r0, _ZERO_REGNO, r0); +} + +static void +_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0) { + subi(r0, r1, i0); + SLTU(r0, _ZERO_REGNO, r0); + } + else + SLTU(r0, _ZERO_REGNO, r1); +} + +static jit_word_t +_bltr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr); + SLT(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + jit_unget_reg(reg); + + return (w); +} + +static jit_word_t +_bltr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLTU(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + jit_unget_reg(reg); + + return (w); +} + +static jit_word_t +_blti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_word_t d; + jit_int32_t reg; + jit_bool_t zero_p; + + if (!(zero_p = i1 == 0)) + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + if (can_sign_extend_short_p(i1)) { + if (!zero_p) + SLTI(rn(reg), r0, i1); + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 1; + if (!zero_p) + BNE(rn(reg), _ZERO_REGNO, d); + else + BLTZ(r0, d); + NOP(1); + } + else { + movi(rn(reg), i1); + w = bltr(i0, r0, rn(reg)); + } + if (!zero_p) + jit_unget_reg(reg); + + return (w); +} + +static jit_word_t +_blti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + if (can_sign_extend_short_p(i1)) { + SLTIU(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + } + else { + movi(rn(reg), i1); + w = bltr_u(i0, r0, rn(reg)); + } + jit_unget_reg(reg); + + return (w); +} + +static jit_word_t +_bler(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLT(rn(reg), r1, r0); + w = _jit->pc.w; + BEQ(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + jit_unget_reg(reg); + + return (w); +} + +static jit_word_t +_bler_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLTU(rn(reg), r1, r0); + w = _jit->pc.w; + BEQ(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + jit_unget_reg(reg); + + return (w); +} + +static jit_word_t +_blei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + + if (i1 == 0) { + w = _jit->pc.w; + BLEZ(r0, ((i0 - w) >> 2) - 1); + NOP(1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bler(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + + return (w); +} + +static jit_word_t +_blei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + + if (i1 == 0) { + w = _jit->pc.w; + BEQ(r0, _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bler_u(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + + return (w); +} + +static jit_word_t +_beqr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + + w = _jit->pc.w; + BEQ(r0, r1, ((i0 - w) >> 2) - 1); + NOP(1); + + return (w); +} + +static jit_word_t +_beqi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + + if (i1 == 0) { + w = _jit->pc.w; + BEQ(r0, _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = beqr(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + + return (w); +} + +static jit_word_t +_bger(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLT(rn(reg), r0, r1); + w = _jit->pc.w; + BEQ(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + jit_unget_reg(reg); + + return (w); +} + +static jit_word_t +_bger_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLTU(rn(reg), r0, r1); + w = _jit->pc.w; + BEQ(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + jit_unget_reg(reg); + + return (w); +} + +static jit_word_t +_bgei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_word_t d; + jit_int32_t reg; + jit_bool_t zero_p; + + if (!(zero_p = i1 == 0)) + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + if (can_sign_extend_short_p(i1)) { + if (!zero_p) + SLTI(rn(reg), r0, i1); + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 1; + if (!zero_p) + BEQ(rn(reg), _ZERO_REGNO, d); + else + BGEZ(r0, d); + NOP(1); + } + else { + movi(rn(reg), i1); + w = bger(i0, r0, rn(reg)); + } + if (!zero_p) + jit_unget_reg(reg); + + return (w); +} + +static jit_word_t +_bgei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + if (can_sign_extend_short_p(i1)) { + SLTIU(rn(reg), r0, i1); + w = _jit->pc.w; + BEQ(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + } + else { + movi(rn(reg), i1); + w = bger_u(i0, r0, rn(reg)); + } + jit_unget_reg(reg); + + return (w); +} + +static jit_word_t +_bgtr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLT(rn(reg), r1, r0); + w = _jit->pc.w; + BNE(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + jit_unget_reg(reg); + + return (w); +} + +static jit_word_t +_bgtr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLTU(rn(reg), r1, r0); + w = _jit->pc.w; + BNE(rn(reg), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + jit_unget_reg(reg); + + return (w); +} + +static jit_word_t +_bgti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + + if (i1 == 0) { + w = _jit->pc.w; + BGTZ(r0, ((i0 - w) >> 2) - 1); + NOP(1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bgtr(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + + return (w); +} + +static jit_word_t +_bgti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + + if (i1 == 0) { + w = _jit->pc.w; + BNE(r0, _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bgtr_u(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + + return (w); +} + +static jit_word_t +_bner(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + + w = _jit->pc.w; + BNE(r0, r1, ((i0 - w) >> 2) - 1); + NOP(1); + + return (w); +} + +static jit_word_t +_bnei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + + if (i1 == 0) { + w = _jit->pc.w; + BNE(r0, _ZERO_REGNO, ((i0 - w) >> 2) - 1); + NOP(1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bner(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + + return (w); +} + +static void +_jmpr(jit_state_t *_jit, jit_int32_t r0) +{ + JR(r0); + NOP(1); +} + +static jit_word_t +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + + w = _jit->pc.w; + if (((w + sizeof(jit_int32_t)) & 0xf0000000) == (i0 & 0xf0000000)) { + J((i0 & ~0xf0000000) >> 2); + NOP(1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi_p(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + } + + return (w); +} + +static jit_word_t +_boaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + + /* t1 = r0 + r1; overflow = r1 < 0 ? r0 < t1 : t1 < r0 */ + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t2 = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLT(rn(t0), r1, _ZERO_REGNO); /* t0 = r1 < 0 */ + addr(rn(t1), r0, r1); /* t1 = r0 + r1 */ + SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */ + SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */ + MOVZ(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */ + w = _jit->pc.w; + BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + /* delay slot */ + addr(r0, r0, r1); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + + return (w); +} + +static jit_word_t +_boaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + + if (can_sign_extend_short_p(i1)) { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t2 = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLTI(rn(t0), _ZERO_REGNO, i1); + addiu(rn(t1), r0, i1); + SLT(rn(t2), r0, rn(t1)); + SLT(rn(t1), rn(t1), r0); + MOVZ(rn(t1), rn(t2), rn(t0)); + w = _jit->pc.w; + BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + /* delay slot */ + addiu(r0, r0, i1); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + } + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i1); + w = boaddr(i0, r0, rn(t0)); + jit_unget_reg(t0); + } + return (w); +} + +static jit_word_t +_boaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addr(rn(t0), r0, r1); + SLTU(rn(t1), rn(t0), r0); + w = _jit->pc.w; + BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); + /* delay slot */ + movr(r0, rn(t0)); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_boaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + + if (can_sign_extend_short_p(i0)) { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addiu(rn(t0), r0, i1); + SLTU(rn(t1), rn(t0), r0); + w = _jit->pc.w; + BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); + /* delay slot */ + movr(r0, rn(t0)); + jit_unget_reg(t1); + jit_unget_reg(t0); + } + else { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = boaddr_u(i0, r0, rn(t0)); + jit_unget_reg(t0); + } + return (w); +} + +static jit_word_t +_bxaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + + /* t1 = r0 + r1; overflow = r1 < 0 ? r0 < t1 : t1 < r0 */ + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t2 = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLT(rn(t0), r1, _ZERO_REGNO); /* t0 = r1 < 0 */ + addr(rn(t1), r0, r1); /* t1 = r0 + r1 */ + SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */ + SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */ + MOVZ(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */ + w = _jit->pc.w; + BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + /* delay slot */ + addr(r0, r0, r1); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + + return (w); +} + +static jit_word_t +_bxaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + + if (can_sign_extend_short_p(i1)) { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t2 = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLTI(rn(t0), _ZERO_REGNO, i1); + addiu(rn(t1), r0, i1); + SLT(rn(t2), r0, rn(t1)); + SLT(rn(t1), rn(t1), r0); + MOVZ(rn(t1), rn(t2), rn(t0)); + w = _jit->pc.w; + BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + /* delay slot */ + addiu(r0, r0, i1); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + } + else { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = bxaddr(i0, r0, rn(t0)); + jit_unget_reg(t0); + } + return (w); +} + +static jit_word_t +_bxaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addr(rn(t0), r0, r1); + SLTU(rn(t1), rn(t0), r0); + w = _jit->pc.w; + BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); + /* delay slot */ + movr(r0, rn(t0)); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + + if (can_sign_extend_short_p(i0)) { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addiu(rn(t0), r0, i1); + SLTU(rn(t1), rn(t0), r0); + w = _jit->pc.w; + BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); + /* delay slot */ + movr(r0, rn(t0)); + jit_unget_reg(t1); + jit_unget_reg(t0); + } + else { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = bxaddr_u(i0, r0, rn(t0)); + jit_unget_reg(t0); + } + return (w); +} + +static jit_word_t +_bosubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + + /* t1 = r0 - r1; overflow = 0 < r1 ? r0 < t1 : t1 < r0 */ + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t2 = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLT(rn(t0), _ZERO_REGNO, r1); /* t0 = 0 < r1 */ + subr(rn(t1), r0, r1); /* t1 = r0 - r1 */ + SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */ + SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */ + MOVZ(rn(t1), rn(t2), rn(t0)); /* if (r0 == 0) t1 = t2 */ + w = _jit->pc.w; + BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + /* delay slot */ + subr(r0, r0, r1); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + + return (w); +} + +static jit_word_t +_bosubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + + if (can_sign_extend_short_p(i1) && (i1 & 0xffff) != 0x8000) { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t2 = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLTI(rn(t0), _ZERO_REGNO, i1); + addiu(rn(t1), r0, -i1); + SLT(rn(t2), rn(t1), r0); + SLT(rn(t1), r0, rn(t1)); + MOVZ(rn(t1), rn(t2), rn(t0)); + w = _jit->pc.w; + BNE(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + /* delay slot */ + addiu(r0, r0, -i1); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + } + else { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = bosubr(i0, r0, rn(t0)); + jit_unget_reg(t0); + } + return (w); +} + +static jit_word_t +_bosubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + subr(rn(t0), r0, r1); + SLTU(rn(t1), r0, rn(t0)); + w = _jit->pc.w; + BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); + /* delay slot */ + movr(r0, rn(t0)); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bosubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + + if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addiu(rn(t0), r0, -i1); + SLTU(rn(t1), r0, rn(t0)); + w = _jit->pc.w; + BNE(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); + /* delay slot */ + movr(r0, rn(t0)); + jit_unget_reg(t1); + jit_unget_reg(t0); + } + else { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = bosubr_u(i0, r0, rn(t0)); + jit_unget_reg(t0); + } + return (w); +} + +static jit_word_t +_bxsubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + + /* t1 = r0 - r1; overflow = 0 < r1 ? r0 < t1 : t1 < r0 */ + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t2 = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLT(rn(t0), _ZERO_REGNO, r1); /* t0 = 0 < r1 */ + subr(rn(t1), r0, r1); /* t1 = r0 - r1 */ + SLT(rn(t2), rn(t1), r0); /* t2 = t1 < r0 */ + SLT(rn(t1), r0, rn(t1)); /* t1 = r0 < t1 */ + MOVZ(rn(t1), rn(t2), rn(t0)); /* if (t0 == 0) t1 = t2 */ + w = _jit->pc.w; + BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + /* delay slot */ + subr(r0, r0, r1); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + + return (w); +} + +static jit_word_t +_bxsubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + + if (can_sign_extend_short_p(i1) && (i1 & 0xffff) != 0x8000) { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t2 = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLTI(rn(t0), _ZERO_REGNO, i1); + addiu(rn(t1), r0, -i1); + SLT(rn(t2), rn(t1), r0); + SLT(rn(t1), r0, rn(t1)); + MOVZ(rn(t1), rn(t2), rn(t0)); + w = _jit->pc.w; + BEQ(rn(t1), _ZERO_REGNO, ((i0 - w) >> 2) - 1); + /* delay slot */ + addiu(r0, r0, -i1); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + } + else { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = bxsubr(i0, r0, rn(t0)); + jit_unget_reg(t0); + } + return (w); +} + +static jit_word_t +_bxsubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + subr(rn(t0), r0, r1); + SLTU(rn(t1), r0, rn(t0)); + w = _jit->pc.w; + BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); + /* delay slot */ + movr(r0, rn(t0)); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + + if (can_sign_extend_short_p(i0) && (i0 & 0xffff) != 0x8000) { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addiu(rn(t0), r0, -i1); + SLTU(rn(t1), r0, rn(t0)); + w = _jit->pc.w; + BEQ(_ZERO_REGNO, rn(t1), ((i0 - w) >> 2) - 1); + /* delay slot */ + movr(r0, rn(t0)); + jit_unget_reg(t1); + jit_unget_reg(t0); + } + else { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = bxsubr_u(i0, r0, rn(t0)); + jit_unget_reg(t0); + } + return (w); +} + +static jit_word_t +_bmsr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + AND(rn(t0), r0, r1); + w = _jit->pc.w; + BNE(_ZERO_REGNO, rn(t0), ((i0 - w) >> 2) - 1); + NOP(1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bmsi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + if (can_zero_extend_short_p(i1)) { + ANDI(rn(t0), r0, i1); + w = _jit->pc.w; + BNE(_ZERO_REGNO, rn(t0), ((i0 - w) >> 2) - 1); + NOP(1); + } + else { + movi(rn(t0), i1); + w = bmsr(i0, r0, rn(t0)); + } + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bmcr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + AND(rn(t0), r0, r1); + w = _jit->pc.w; + BEQ(_ZERO_REGNO, rn(t0), ((i0 - w) >> 2) - 1); + NOP(1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bmci(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + if (can_zero_extend_short_p(i1)) { + ANDI(rn(t0), r0, i1); + w = _jit->pc.w; + BEQ(_ZERO_REGNO, rn(t0), ((i0 - w) >> 2) - 1); + NOP(1); + } + else { + movi(rn(t0), i1); + w = bmcr(i0, r0, rn(t0)); + } + jit_unget_reg(t0); + return (w); +} + +static void +_callr(jit_state_t *_jit, jit_int32_t r0) +{ + if (r0 != _T9_REGNO) + movr(_T9_REGNO, r0); + JALR(r0); + NOP(1); +} + +static void +_calli(jit_state_t *_jit, jit_word_t i0) +{ + movi(_T9_REGNO, i0); + JALR(_T9_REGNO); + NOP(1); +} + +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t word; + + word = _jit->pc.w; + movi_p(_T9_REGNO, i0); + JALR(_T9_REGNO); + NOP(1); + + return (word); +} + +static jit_int32_t fregs[] = { + _F30, _F28, _F26, _F24, _F22, _F20, +#if !NEW_ABI + _F18, _F16, +#endif +}; + +static jit_int32_t iregs[] = { + _S7, _S6, _S5, _S4, _S3, _S2, _S1, _S0, +}; + +static void +_prolog(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t index; + jit_int32_t offset; + if (_jitc->function->define_frame || _jitc->function->assume_frame) { + jit_int32_t frame = -_jitc->function->frame; + assert(_jitc->function->self.aoff >= frame); + if (_jitc->function->assume_frame) + return; + _jitc->function->self.aoff = frame; + } + if (_jitc->function->allocar) + _jitc->function->self.aoff &= -8; +#if NEW_ABI + _jitc->function->stack = ((_jitc->function->self.alen - + /* align stack at 16 bytes */ + _jitc->function->self.aoff) + 15) & -16; +#else + _jitc->function->stack = ((/* first 16 bytes must be allocated */ + (_jitc->function->self.alen > 16 ? + _jitc->function->self.alen : 16) - + /* align stack at 8 bytes */ + _jitc->function->self.aoff) + 7) & -8; +#endif + /* callee save registers */ +#if NEW_ABI + if ((_jitc->function->self.call & jit_call_varargs) && + jit_arg_reg_p(_jitc->function->vagp)) + subi(_SP_REGNO, _SP_REGNO, stack_framesize + 64); + else +#endif + subi(_SP_REGNO, _SP_REGNO, stack_framesize); + offset = stack_framesize - (sizeof(jit_word_t) << 1); + for (index = 0; index < jit_size(fregs); index++, offset -= 8) { + if (jit_regset_tstbit(&_jitc->function->regset, fregs[index])) + stxi_d(offset, _SP_REGNO, rn(fregs[index])); + } + for (index = 0; index < jit_size(iregs); + index++, offset -= sizeof(jit_word_t)) { + if (jit_regset_tstbit(&_jitc->function->regset, iregs[index])) + stxi(offset, _SP_REGNO, rn(iregs[index])); + } + assert(offset >= sizeof(jit_word_t)); + stxi(offset, _SP_REGNO, _RA_REGNO); + stxi(0, _SP_REGNO, _BP_REGNO); + movr(_BP_REGNO, _SP_REGNO); + + /* alloca */ + if (_jitc->function->stack) + subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack); + if (_jitc->function->allocar) { + index = jit_get_reg(jit_class_gpr); + movi(rn(index), _jitc->function->self.aoff); + stxi_i(_jitc->function->aoffoff, _BP_REGNO, rn(index)); + jit_unget_reg(index); + } + + if (_jitc->function->self.call & jit_call_varargs) { +#if NEW_ABI + index = _jitc->function->vagp; +#else + index = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT; +#endif + offset = stack_framesize + index * STACK_SLOT; + for (; jit_arg_reg_p(index); ++index, offset += STACK_SLOT) { +#if NEW_ABI + SD(rn(_A0 - index), offset, _BP_REGNO); +#else + stxi(offset + WORD_ADJUST, _BP_REGNO, rn(_A0 - index)); +#endif + } + } +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t index; + jit_int32_t offset; + if (_jitc->function->assume_frame) + return; + /* callee save registers */ + movr(_SP_REGNO, _BP_REGNO); + offset = stack_framesize - (sizeof(jit_word_t) << 1); + for (index = 0; index < jit_size(fregs); index++, offset -= 8) { + if (jit_regset_tstbit(&_jitc->function->regset, fregs[index])) + ldxi_d(rn(fregs[index]), _SP_REGNO, offset); + } + for (index = 0; index < jit_size(iregs); + index++, offset -= sizeof(jit_word_t)) { + if (jit_regset_tstbit(&_jitc->function->regset, iregs[index])) + ldxi(rn(iregs[index]), _SP_REGNO, offset); + } + assert(offset >= sizeof(jit_word_t)); + ldxi(_RA_REGNO, _SP_REGNO, offset); + ldxi(_BP_REGNO, _SP_REGNO, 0); + JR(_RA_REGNO); + /* delay slot */ +#if NEW_ABI + if ((_jitc->function->self.call & jit_call_varargs) && + jit_arg_reg_p(_jitc->function->vagp)) + addi(_SP_REGNO, _SP_REGNO, stack_framesize + 64); + else +#endif + addi(_SP_REGNO, _SP_REGNO, stack_framesize); +} + +static void +_vastart(jit_state_t *_jit, jit_int32_t r0) +{ + assert(_jitc->function->self.call & jit_call_varargs); + /* Initialize va_list to the first stack argument. */ +#if NEW_ABI + if (jit_arg_reg_p(_jitc->function->vagp)) + addi(r0, _BP_REGNO, stack_framesize + _jitc->function->vagp * + sizeof(jit_int64_t)); + else +#endif + addi(r0, _BP_REGNO, _jitc->function->self.size); +} + +static void +_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + /* Load argument. */ +#if WORD_ADJUST + ldxi(r0, r1, WORD_ADJUST); +#else + ldr(r0, r1); +#endif + + /* Update va_list. */ + addi(r1, r1, STACK_SLOT); +} + +static void +_patch_abs(jit_state_t *_jit, jit_word_t instr, jit_word_t label) +{ + jit_instr_t i; + union { + jit_int32_t *i; + jit_word_t w; + } u; + + u.w = instr; +#if __WORDSIZE == 32 + i.op = u.i[0]; + assert(i.hc.b == MIPS_LUI); + i.is.b = label >> 16; + u.i[0] = i.op; + i.op = u.i[1]; + assert(i.hc.b == MIPS_ORI); + i.is.b = label; + u.i[1] = i.op; +#else + i.op = u.i[0]; + assert(i.hc.b == MIPS_LUI); + i.is.b = label >> 48; + u.i[0] = i.op; + i.op = u.i[1]; + assert(i.hc.b == MIPS_ORI); + i.is.b = label >> 32; + u.i[1] = i.op; + /* lshi */ + i.op = u.i[3]; + assert(i.hc.b == MIPS_ORI); + i.is.b = label >> 16; + u.i[3] = i.op; + /* lshi */ + i.op = u.i[5]; + assert(i.hc.b == MIPS_ORI); + i.is.b = label; + u.i[5] = i.op; +#endif +} + +static void +_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label) +{ + jit_instr_t i; + union { + jit_int32_t *i; + jit_word_t w; + } u; + + u.w = instr; + i.op = u.i[0]; + switch (i.hc.b) { + /* 16 bit immediate opcodes */ + case MIPS_REGIMM: + switch (i.rt.b) { + case MIPS_BLTZ: case MIPS_BLTZL: + case MIPS_BLTZAL: case MIPS_BLTZALL: + case MIPS_BGEZ: case MIPS_BGEZAL: + case MIPS_BGEZALL: case MIPS_BGEZL: + case MIPS_TEQI: case MIPS_TGEI: + case MIPS_TGEIU: case MIPS_TLTI: + case MIPS_TLTIU: case MIPS_TNEI: + i.is.b = ((label - instr) >> 2) - 1; + u.i[0] = i.op; + break; + default: + assert(!"unhandled branch opcode"); + break; + } + break; + + case MIPS_COP1: case MIPS_COP2: + assert(i.rs.b == MIPS_BC); + switch (i.rt.b) { + case MIPS_BCF: case MIPS_BCFL: + case MIPS_BCT: case MIPS_BCTL: + i.is.b = ((label - instr) >> 2) - 1; + u.i[0] = i.op; + break; + default: + assert(!"unhandled branch opcode"); + break; + } + break; + + case MIPS_BLEZ: case MIPS_BLEZL: + case MIPS_BEQ: case MIPS_BEQL: + case MIPS_BGTZ: case MIPS_BGTZL: + case MIPS_BNE: case MIPS_BNEL: + i.is.b = ((label - instr) >> 2) - 1; + u.i[0] = i.op; + break; + + case MIPS_LUI: + patch_abs(instr, label); + break; + + case MIPS_J: case MIPS_JAL: + case MIPS_JALX: + assert(((instr + sizeof(jit_int32_t)) & 0xf0000000) == + (label & 0xf0000000)); + i.ii.b = (label & ~0xf0000000) >> 2; + u.i[0] = i.op; + break; + + default: + assert(!"unhandled branch opcode"); + break; + } +} +#endif diff --git a/deps/lightning/lib/jit_mips-fpu.c b/deps/lightning/lib/jit_mips-fpu.c new file mode 100644 index 0000000..7513219 --- /dev/null +++ b/deps/lightning/lib/jit_mips-fpu.c @@ -0,0 +1,1844 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# define BE_P (__BYTE_ORDER == __BIG_ENDIAN) +# define LE_P (__BYTE_ORDER == __LITTLE_ENDIAN) +# define MIPS_fmt_S 0x10 /* float32 */ +# define MIPS_fmt_D 0x11 /* float64 */ +# define MIPS_fmt_W 0x14 /* int32 */ +# define MIPS_fmt_L 0x15 /* int64 */ +# define MIPS_fmt_PS 0x16 /* 2 x float32 */ +# define MIPS_fmt_S_PU 0x20 +# define MIPS_fmt_S_PL 0x26 +# define MIPS_ADD_fmt 0x00 +# define MIPS_LWXC1 0x00 +# define MIPS_SUB_fmt 0x01 +# define MIPS_LDXC1 0x01 +# define MIPS_MUL_fmt 0x02 +# define MIPS_DIV_fmt 0x03 +# define MIPS_SQRT_fmt 0x04 +# define MIPS_ABS_fmt 0x05 +# define MIPS_LUXC1 0x05 +# define MIPS_MOV_fmt 0x06 +# define MIPS_NEG_fmt 0x07 +# define MIPS_SWXC1 0x08 +# define MIPS_ROUND_fmt_L 0x08 +# define MIPS_TRUNC_fmt_L 0x09 +# define MIPS_SDXC1 0x09 +# define MIPS_CEIL_fmt_L 0x0a +# define MIPS_FLOOR_fmt_L 0x0b +# define MIPS_ROUND_fmt_W 0x0c +# define MIPS_TRUNC_fmt_W 0x0d +# define MIPS_SUXC1 0x0d +# define MIPS_CEIL_fmt_W 0x0e +# define MIPS_FLOOR_fmt_W 0x0f +# define MIPS_RECIP 0x15 +# define MIPS_RSQRT 0x16 +# define MIPS_ALNV_PS 0x1e +# define MIPS_CVT_fmt_S 0x20 +# define MIPS_CVT_fmt_D 0x21 +# define MIPS_CVT_fmt_W 0x24 +# define MIPS_CVT_fmt_L 0x25 +# define MIPS_PLL 0x2c +# define MIPS_PLU 0x2d +# define MIPS_PUL 0x2e +# define MIPS_PUU 0x2f +# define MIPS_MADD_fmt_S (0x20 | MIPS_fmt_S) +# define MIPS_MADD_fmt_D (0x20 | MIPS_fmt_D) +# define MIPS_MADD_fmt_PS (0x20 | MIPS_fmt_PS) +# define MIPS_MSUB_fmt_S (0x28 | MIPS_fmt_S) +# define MIPS_MSUB_fmt_D (0x28 | MIPS_fmt_D) +# define MIPS_MSUB_fmt_PS (0x28 | MIPS_fmt_PS) +# define MIPS_NMADD_fmt_S (0x30 | MIPS_fmt_S) +# define MIPS_NMADD_fmt_D (0x30 | MIPS_fmt_D) +# define MIPS_NMADD_fmt_PS (0x30 | MIPS_fmt_PS) +# define MIPS_NMSUB_fmt_S (0x38 | MIPS_fmt_S) +# define MIPS_NMSUB_fmt_D (0x38 | MIPS_fmt_D) +# define MIPS_NMSUB_fmt_PS (0x38 | MIPS_fmt_PS) +# define MIPS_cond_F 0x30 +# define MIPS_cond_UN 0x31 +# define MIPS_cond_EQ 0x32 +# define MIPS_cond_UEQ 0x33 +# define MIPS_cond_OLT 0x34 +# define MIPS_cond_ULT 0x35 +# define MIPS_cond_OLE 0x36 +# define MIPS_cond_ULE 0x37 +# define MIPS_cond_SF 0x38 +# define MIPS_cond_NGLE 0x39 +# define MIPS_cond_SEQ 0x3a +# define MIPS_cond_NGL 0x3b +# define MIPS_cond_LT 0x3c +# define MIPS_cond_NGE 0x3d +# define MIPS_cond_LE 0x3e +# define MIPS_cond_UGT 0x3f +# define ADD_S(fd,fs,ft) hrrrit(MIPS_COP1,MIPS_fmt_S,ft,fs,fd,MIPS_ADD_fmt) +# define ADD_D(fd,fs,ft) hrrrit(MIPS_COP1,MIPS_fmt_D,ft,fs,fd,MIPS_ADD_fmt) +# define SUB_S(fd,fs,ft) hrrrit(MIPS_COP1,MIPS_fmt_S,ft,fs,fd,MIPS_SUB_fmt) +# define SUB_D(fd,fs,ft) hrrrit(MIPS_COP1,MIPS_fmt_D,ft,fs,fd,MIPS_SUB_fmt) +# define MUL_S(fd,fs,ft) hrrrit(MIPS_COP1,MIPS_fmt_S,ft,fs,fd,MIPS_MUL_fmt) +# define MUL_D(fd,fs,ft) hrrrit(MIPS_COP1,MIPS_fmt_D,ft,fs,fd,MIPS_MUL_fmt) +# define DIV_S(fd,fs,ft) hrrrit(MIPS_COP1,MIPS_fmt_S,ft,fs,fd,MIPS_DIV_fmt) +# define DIV_D(fd,fs,ft) hrrrit(MIPS_COP1,MIPS_fmt_D,ft,fs,fd,MIPS_DIV_fmt) +# define ABS_S(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_S,0,fs,fd,MIPS_ABS_fmt) +# define ABS_D(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_D,0,fs,fd,MIPS_ABS_fmt) +# define NEG_S(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_S,0,fs,fd,MIPS_NEG_fmt) +# define NEG_D(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_D,0,fs,fd,MIPS_NEG_fmt) +# define SQRT_S(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_S,0,fs,fd,MIPS_SQRT_fmt) +# define SQRT_D(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_D,0,fs,fd,MIPS_SQRT_fmt) +# define MFC1(rt, fs) hrrrit(MIPS_COP1,MIPS_MF,rt,fs,0,0) +# define MTC1(rt, fs) hrrrit(MIPS_COP1,MIPS_MT,rt,fs,0,0) +# define DMFC1(rt, fs) hrrrit(MIPS_COP1,MIPS_DMF,rt,fs,0,0) +# define DMTC1(rt, fs) hrrrit(MIPS_COP1,MIPS_DMT,rt,fs,0,0) +# define CVT_D_S(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_S,0,fs,fd,MIPS_CVT_fmt_D) +# define CVT_D_W(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_W,0,fs,fd,MIPS_CVT_fmt_D) +# define CVT_D_L(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_L,0,fs,fd,MIPS_CVT_fmt_D) +# define CVT_L_S(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_S,0,fs,fd,MIPS_CVT_fmt_L) +# define CVT_L_D(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_D,0,fs,fd,MIPS_CVT_fmt_L) +# define CVT_PS_S(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_S,0,fs,fd,MIPS_CVT_fmt_PS) +# define CVT_S_D(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_D,0,fs,fd,MIPS_CVT_fmt_S) +# define CVT_S_W(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_W,0,fs,fd,MIPS_CVT_fmt_S) +# define CVT_S_L(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_L,0,fs,fd,MIPS_CVT_fmt_S) +# define CVT_S_PL(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_PS,0,fs,fd,MIPS_CVT_fmt_S_PL) +# define CVT_S_PU(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_PS,0,fs,fd,MIPS_CVT_fmt_S_PU) +# define CVT_W_S(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_S,0,fs,fd,MIPS_CVT_fmt_W) +# define CVT_W_D(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_D,0,fs,fd,MIPS_CVT_fmt_W) +# define TRUNC_L_S(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_S,0,fs,fd,MIPS_TRUNC_fmt_L) +# define TRUNC_L_D(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_D,0,fs,fd,MIPS_TRUNC_fmt_L) +# define TRUNC_W_S(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_S,0,fs,fd,MIPS_TRUNC_fmt_W) +# define TRUNC_W_D(fd,fs) hrrrit(MIPS_COP1,MIPS_fmt_D,0,fs,fd,MIPS_TRUNC_fmt_W) +# define LWC1(rt, of, rb) hrri(MIPS_LWC1, rb, rt, of) +# define SWC1(rt, of, rb) hrri(MIPS_SWC1, rb, rt, of) +# define LDC1(rt, of, rb) hrri(MIPS_LDC1, rb, rt, of) +# define SDC1(rt, of, rb) hrri(MIPS_SDC1, rb, rt, of) +# define MOV_S(fd, fs) hrrrit(MIPS_COP1,MIPS_fmt_S,0,fs,fd,MIPS_MOV_fmt) +# define MOV_D(fd, fs) hrrrit(MIPS_COP1,MIPS_fmt_D,0,fs,fd,MIPS_MOV_fmt) +# define BC1F(im) hrri(MIPS_COP1,MIPS_BC,MIPS_BCF,im) +# define BC1T(im) hrri(MIPS_COP1,MIPS_BC,MIPS_BCT,im) +# define C_F_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_F) +# define C_F_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_F) +# define C_F_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_F) +# define C_UN_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_UN) +# define C_UN_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_UN) +# define C_UN_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_UN) +# define C_EQ_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_EQ) +# define C_EQ_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_EQ) +# define C_EQ_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_EQ) +# define C_UEQ_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_UEQ) +# define C_UEQ_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_UEQ) +# define C_UEQ_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_UEQ) +# define C_OLT_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_OLT) +# define C_OLT_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_OLT) +# define C_OLT_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_OLT) +# define C_ULT_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_ULT) +# define C_ULT_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_ULT) +# define C_ULT_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_ULT) +# define C_OLE_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_OLE) +# define C_OLE_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_OLE) +# define C_OLE_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_OLE) +# define C_ULE_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_ULE) +# define C_ULE_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_ULE) +# define C_ULE_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_ULE) +# define C_SF_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_SF) +# define C_SF_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_SF) +# define C_SF_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_SF) +# define C_NGLE_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_NGLE) +# define C_NGLE_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_NGLE) +# define C_NGLE_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_NGLE) +# define C_SEQ_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_SEQ) +# define C_SEQ_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_SEQ) +# define C_SEQ_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_SEQ) +# define C_NGL_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_NGL) +# define C_NGL_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_NGL) +# define C_NGL_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_NGL) +# define C_NLT_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_NLT) +# define C_NLT_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_NLT) +# define C_NLT_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_NLT) +# define C_NGE_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_NGE) +# define C_NGE_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_NGE) +# define C_NGE_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_NGE) +# define C_NLE_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_NLE) +# define C_NLE_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_NLE) +# define C_NLE_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_NLE) +# define C_UGT_S(fs,ft) c_cond_fmt(MIPS_fmt_S,ft,fs,MIPS_cond_UGT) +# define C_UGT_D(fs,ft) c_cond_fmt(MIPS_fmt_D,ft,fs,MIPS_cond_UGT) +# define C_UGT_PS(fs,ft) c_cond_fmt(MIPS_fmt_PS,ft,fs,MIPS_cond_UGT) +# define c_cond_fmt(fm,ft,fs,cc) _c_cond_fmt(_jit,fm,ft,fs,cc) +static void +_c_cond_fmt(jit_state_t *_jit, jit_int32_t fm, + jit_int32_t ft, jit_int32_t fs, jit_int32_t cc); +# define addr_f(r0,r1,r2) ADD_S(r0,r1,r2) +# define addi_f(r0,r1,i0) _addi_f(_jit,r0,r1,i0) +static void _addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define addr_d(r0,r1,r2) ADD_D(r0,r1,r2) +# define addi_d(r0,r1,i0) _addi_d(_jit,r0,r1,i0) +static void _addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define subr_f(r0,r1,r2) SUB_S(r0,r1,r2) +# define subi_f(r0,r1,i0) _subi_f(_jit,r0,r1,i0) +static void _subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define subr_d(r0,r1,r2) SUB_D(r0,r1,r2) +# define subi_d(r0,r1,i0) _subi_d(_jit,r0,r1,i0) +static void _subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define rsbr_f(r0,r1,r2) subr_f(r0,r2,r1) +# define rsbi_f(r0,r1,i0) _rsbi_f(_jit,r0,r1,i0) +static void _rsbi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define rsbr_d(r0,r1,r2) subr_d(r0,r2,r1) +# define rsbi_d(r0,r1,i0) _rsbi_d(_jit,r0,r1,i0) +static void _rsbi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define mulr_f(r0,r1,r2) MUL_S(r0,r1,r2) +# define muli_f(r0,r1,i0) _muli_f(_jit,r0,r1,i0) +static void _muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define mulr_d(r0,r1,r2) MUL_D(r0,r1,r2) +# define muli_d(r0,r1,i0) _muli_d(_jit,r0,r1,i0) +static void _muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define divr_f(r0,r1,r2) DIV_S(r0,r1,r2) +# define divi_f(r0,r1,i0) _divi_f(_jit,r0,r1,i0) +static void _divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define divr_d(r0,r1,r2) DIV_D(r0,r1,r2) +# define divi_d(r0,r1,i0) _divi_d(_jit,r0,r1,i0) +static void _divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define absr_f(r0,r1) ABS_S(r0,r1) +# define absr_d(r0,r1) ABS_D(r0,r1) +# define negr_f(r0,r1) NEG_S(r0,r1) +# define negr_d(r0,r1) NEG_D(r0,r1) +# define sqrtr_f(r0,r1) SQRT_S(r0,r1) +# define sqrtr_d(r0,r1) SQRT_D(r0,r1) +# define movr_w_f(r0, r1) MTC1(r1, r0) +# define movr_f_w(r0, r1) MFC1(r1, r0) +# define movi_f_w(r0, i0) _movi_f_w(_jit, r0, i0) +static void _movi_f_w(jit_state_t*,jit_int32_t,jit_float32_t*); +# define extr_f(r0, r1) _extr_f(_jit, r0, r1) +static void _extr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define truncr_f_i(r0, r1) _truncr_f_i(_jit, r0, r1) +static void _truncr_f_i(jit_state_t*,jit_int32_t,jit_int32_t); +# if __WORDSIZE == 64 +# define truncr_f_l(r0, r1) _truncr_f_l(_jit, r0, r1) +static void _truncr_f_l(jit_state_t*,jit_int32_t,jit_int32_t); +# endif +# define extr_d_f(r0, r1) CVT_S_D(r0, r1) +# define ldr_f(r0, r1) LWC1(r0, 0, r1) +# define ldi_f(r0, i0) _ldi_f(_jit, r0, i0) +static void _ldi_f(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_f(r0, r1, r2) _ldxr_f(_jit, r0, r1, r2) +static void _ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_f(r0, r1, i0) _ldxi_f(_jit, r0, r1, i0) +static void _ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_f(r0, r1) SWC1(r1, 0, r0) +# define sti_f(i0, r0) _sti_f(_jit, i0, r0) +static void _sti_f(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_f(r0, r1, r2) _stxr_f(_jit, r0, r1, r2) +static void _stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_f(i0, r0, r1) _stxi_f(_jit, i0, r0, r1) +static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define movr_f(r0, r1) _movr_f(_jit, r0, r1) +static void _movr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi_f(r0, i0) _movi_f(_jit, r0, i0) +static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*); +# if NEW_ABI +# if __WORDSIZE == 32 +# define movi64(r0, i0) _movi64(_jit, r0, i0) +static void _movi64(jit_state_t*,jit_int32_t,jit_int64_t); +# else +# define movi64(r0, i0) movi(r0, i0) +# endif +# define movr_w_d(r0, r1) DMTC1(r1, r0) +# define movr_d_w(r0, r1) DMFC1(r0, r1) +# define movi_d_w(r0, i0) _movi_d_w(_jit,r0,i0) +static void _movi_d_w(jit_state_t*,jit_int32_t,jit_float64_t*); +# else +# define movr_ww_d(r0, r1, r2) _movr_ww_d(_jit, r0, r1, r2) +static void _movr_ww_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define movr_d_ww(r0, r1, r2) _movr_d_ww(_jit, r0, r1, r2) +static void _movr_d_ww(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define movi_d_ww(r0, r1, i0) _movi_d_ww(_jit, r0, r1, i0) +static void _movi_d_ww(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# endif +# define extr_d(r0, r1) _extr_d(_jit, r0, r1) +static void _extr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define truncr_d_i(r0, r1) _truncr_d_i(_jit, r0, r1) +static void _truncr_d_i(jit_state_t*,jit_int32_t,jit_int32_t); +# if __WORDSIZE == 64 +# define truncr_d_l(r0, r1) _truncr_d_l(_jit, r0, r1) +static void _truncr_d_l(jit_state_t*,jit_int32_t,jit_int32_t); +# endif +# define ldr_d(r0, r1) _ldr_d(_jit, r0, r1) +static void _ldr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_d(r0, i0) _ldi_d(_jit, r0, i0) +static void _ldi_d(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_d(r0, r1, r2) _ldxr_d(_jit, r0, r1, r2) +static void _ldxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_d(r0, r1, i0) _ldxi_d(_jit, r0, r1, i0) +static void _ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_d(r0, r1) _str_d(_jit, r0, r1) +static void _str_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define sti_d(i0, r0) _sti_d(_jit, i0, r0) +static void _sti_d(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_d(r0, r1, r2) _stxr_d(_jit, r0, r1, r2) +static void _stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_d(i0, r0, r1) _stxi_d(_jit, i0, r0, r1) +static void _stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define movr_d(r0, r1) _movr_d(_jit, r0, r1) +static void _movr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi_d(r0, i0) _movi_d(_jit, r0, i0) +static void _movi_d(jit_state_t*,jit_int32_t,jit_float64_t*); +# define ltr_f(r0, r1, r2) _ltr_f(_jit, r0, r1, r2) +static void _ltr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lti_f(r0, r1, i2) _lti_f(_jit, r0, r1, i2) +static void _lti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ler_f(r0, r1, r2) _ler_f(_jit, r0, r1, r2) +static void _ler_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lei_f(r0, r1, i2) _lei_f(_jit, r0, r1, i2) +static void _lei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define eqr_f(r0, r1, r2) _eqr_f(_jit, r0, r1, r2) +static void _eqr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define eqi_f(r0, r1, i2) _eqi_f(_jit, r0, r1, i2) +static void _eqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ger_f(r0, r1, r2) _ger_f(_jit, r0, r1, r2) +static void _ger_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gei_f(r0, r1, i2) _gei_f(_jit, r0, r1, i2) +static void _gei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define gtr_f(r0, r1, r2) _gtr_f(_jit, r0, r1, r2) +static void _gtr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gti_f(r0, r1, i2) _gti_f(_jit, r0, r1, i2) +static void _gti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ner_f(r0, r1, r2) _ner_f(_jit, r0, r1, r2) +static void _ner_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define nei_f(r0, r1, i2) _nei_f(_jit, r0, r1, i2) +static void _nei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define unltr_f(r0, r1, r2) _unltr_f(_jit, r0, r1, r2) +static void _unltr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unlti_f(r0, r1, i2) _unlti_f(_jit, r0, r1, i2) +static void _unlti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define unler_f(r0, r1, r2) _unler_f(_jit, r0, r1, r2) +static void _unler_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unlei_f(r0, r1, i2) _unlei_f(_jit, r0, r1, i2) +static void _unlei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define uneqr_f(r0, r1, r2) _uneqr_f(_jit, r0, r1, r2) +static void _uneqr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define uneqi_f(r0, r1, i2) _uneqi_f(_jit, r0, r1, i2) +static void _uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define unger_f(r0, r1, r2) _unger_f(_jit, r0, r1, r2) +static void _unger_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ungei_f(r0, r1, i2) _ungei_f(_jit, r0, r1, i2) +static void _ungei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ungtr_f(r0, r1, r2) _ungtr_f(_jit, r0, r1, r2) +static void _ungtr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ungti_f(r0, r1, i2) _ungti_f(_jit, r0, r1, i2) +static void _ungti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ltgtr_f(r0, r1, r2) _ltgtr_f(_jit, r0, r1, r2) +static void _ltgtr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ltgti_f(r0, r1, i2) _ltgti_f(_jit, r0, r1, i2) +static void _ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ordr_f(r0, r1, r2) _ordr_f(_jit, r0, r1, r2) +static void _ordr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ordi_f(r0, r1, i2) _ordi_f(_jit, r0, r1, i2) +static void _ordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define unordr_f(r0, r1, r2) _unordr_f(_jit, r0, r1, r2) +static void _unordr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unordi_f(r0, r1, i2) _unordi_f(_jit, r0, r1, i2) +static void _unordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define bltr_f(i0, r0, r1) _bltr_f(_jit, i0, r0, r1) +static jit_word_t _bltr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blti_f(i0, r0, i1) _blti_f(_jit, i0, r0, i1) +static jit_word_t +_blti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define bler_f(i0, r0, r1) _bler_f(_jit, i0, r0, r1) +static jit_word_t _bler_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blei_f(i0, r0, i1) _blei_f(_jit, i0, r0, i1) +static jit_word_t +_blei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define beqr_f(i0, r0, r1) _beqr_f(_jit, i0, r0, r1) +static jit_word_t _beqr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define beqi_f(i0, r0, i1) _beqi_f(_jit, i0, r0, i1) +static jit_word_t +_beqi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define bger_f(i0, r0, r1) _bger_f(_jit, i0, r0, r1) +static jit_word_t _bger_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgei_f(i0, r0, i1) _bgei_f(_jit, i0, r0, i1) +static jit_word_t +_bgei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define bgtr_f(i0, r0, r1) _bgtr_f(_jit, i0, r0, r1) +static jit_word_t _bgtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgti_f(i0, r0, i1) _bgti_f(_jit, i0, r0, i1) +static jit_word_t +_bgti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define bner_f(i0, r0, r1) _bner_f(_jit, i0, r0, r1) +static jit_word_t _bner_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bnei_f(i0, r0, i1) _bnei_f(_jit, i0, r0, i1) +static jit_word_t +_bnei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define bunltr_f(i0, r0, r1) _bunltr_f(_jit, i0, r0, r1) +static jit_word_t _bunltr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlti_f(i0, r0, i1) _bunlti_f(_jit, i0, r0, i1) +static jit_word_t +_bunlti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define bunler_f(i0, r0, r1) _bunler_f(_jit, i0, r0, r1) +static jit_word_t _bunler_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlei_f(i0, r0, i1) _bunlei_f(_jit, i0, r0, i1) +static jit_word_t +_bunlei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define buneqr_f(i0, r0, r1) _buneqr_f(_jit, i0, r0, r1) +static jit_word_t _buneqr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define buneqi_f(i0, r0, i1) _buneqi_f(_jit, i0, r0, i1) +static jit_word_t +_buneqi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define bunger_f(i0, r0, r1) _bunger_f(_jit, i0, r0, r1) +static jit_word_t _bunger_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungei_f(i0, r0, i1) _bungei_f(_jit, i0, r0, i1) +static jit_word_t +_bungei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define bungtr_f(i0, r0, r1) _bungtr_f(_jit, i0, r0, r1) +static jit_word_t _bungtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungti_f(i0, r0, i1) _bungti_f(_jit, i0, r0, i1) +static jit_word_t +_bungti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define bltgtr_f(i0, r0, r1) _bltgtr_f(_jit, i0, r0, r1) +static jit_word_t _bltgtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bltgti_f(i0, r0, i1) _bltgti_f(_jit, i0, r0, i1) +static jit_word_t +_bltgti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define bordr_f(i0, r0, r1) _bordr_f(_jit, i0, r0, r1) +static jit_word_t _bordr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bordi_f(i0, r0, i1) _bordi_f(_jit, i0, r0, i1) +static jit_word_t +_bordi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define bunordr_f(i0, r0, r1) _bunordr_f(_jit, i0, r0, r1) +static jit_word_t _bunordr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunordi_f(i0, r0, i1) _bunordi_f(_jit, i0, r0, i1) +static jit_word_t +_bunordi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define extr_f_d(r0, r1) CVT_D_S(r0, r1) +# define ltr_d(r0, r1, r2) _ltr_d(_jit, r0, r1, r2) +static void _ltr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lti_d(r0, r1, i2) _lti_d(_jit, r0, r1, i2) +static void _lti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ler_d(r0, r1, r2) _ler_d(_jit, r0, r1, r2) +static void _ler_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lei_d(r0, r1, i2) _lei_d(_jit, r0, r1, i2) +static void _lei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define eqr_d(r0, r1, r2) _eqr_d(_jit, r0, r1, r2) +static void _eqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define eqi_d(r0, r1, i2) _eqi_d(_jit, r0, r1, i2) +static void _eqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ger_d(r0, r1, r2) _ger_d(_jit, r0, r1, r2) +static void _ger_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gei_d(r0, r1, i2) _gei_d(_jit, r0, r1, i2) +static void _gei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define gtr_d(r0, r1, r2) _gtr_d(_jit, r0, r1, r2) +static void _gtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gti_d(r0, r1, i2) _gti_d(_jit, r0, r1, i2) +static void _gti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ner_d(r0, r1, r2) _ner_d(_jit, r0, r1, r2) +static void _ner_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define nei_d(r0, r1, i2) _nei_d(_jit, r0, r1, i2) +static void _nei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unltr_d(r0, r1, r2) _unltr_d(_jit, r0, r1, r2) +static void _unltr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unlti_d(r0, r1, i2) _unlti_d(_jit, r0, r1, i2) +static void _unlti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unler_d(r0, r1, r2) _unler_d(_jit, r0, r1, r2) +static void _unler_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unlei_d(r0, r1, i2) _unlei_d(_jit, r0, r1, i2) +static void _unlei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define uneqr_d(r0, r1, r2) _uneqr_d(_jit, r0, r1, r2) +static void _uneqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define uneqi_d(r0, r1, i2) _uneqi_d(_jit, r0, r1, i2) +static void _uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unger_d(r0, r1, r2) _unger_d(_jit, r0, r1, r2) +static void _unger_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ungei_d(r0, r1, i2) _ungei_d(_jit, r0, r1, i2) +static void _ungei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ungtr_d(r0, r1, r2) _ungtr_d(_jit, r0, r1, r2) +static void _ungtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ungti_d(r0, r1, i2) _ungti_d(_jit, r0, r1, i2) +static void _ungti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ltgtr_d(r0, r1, r2) _ltgtr_d(_jit, r0, r1, r2) +static void _ltgtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ltgti_d(r0, r1, i2) _ltgti_d(_jit, r0, r1, i2) +static void _ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ordr_d(r0, r1, r2) _ordr_d(_jit, r0, r1, r2) +static void _ordr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ordi_d(r0, r1, i2) _ordi_d(_jit, r0, r1, i2) +static void _ordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unordr_d(r0, r1, r2) _unordr_d(_jit, r0, r1, r2) +static void _unordr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unordi_d(r0, r1, i2) _unordi_d(_jit, r0, r1, i2) +static void _unordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define bltr_d(i0, r0, r1) _bltr_d(_jit, i0, r0, r1) +static jit_word_t _bltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blti_d(i0, r0, i1) _blti_d(_jit, i0, r0, i1) +static jit_word_t +_blti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define bler_d(i0, r0, r1) _bler_d(_jit, i0, r0, r1) +static jit_word_t _bler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blei_d(i0, r0, i1) _blei_d(_jit, i0, r0, i1) +static jit_word_t +_blei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define beqr_d(i0, r0, r1) _beqr_d(_jit, i0, r0, r1) +static jit_word_t _beqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define beqi_d(i0, r0, i1) _beqi_d(_jit, i0, r0, i1) +static jit_word_t +_beqi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define bger_d(i0, r0, r1) _bger_d(_jit, i0, r0, r1) +static jit_word_t _bger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgei_d(i0, r0, i1) _bgei_d(_jit, i0, r0, i1) +static jit_word_t +_bgei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define bgtr_d(i0, r0, r1) _bgtr_d(_jit, i0, r0, r1) +static jit_word_t _bgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgti_d(i0, r0, i1) _bgti_d(_jit, i0, r0, i1) +static jit_word_t +_bgti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define bner_d(i0, r0, r1) _bner_d(_jit, i0, r0, r1) +static jit_word_t _bner_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bnei_d(i0, r0, i1) _bnei_d(_jit, i0, r0, i1) +static jit_word_t +_bnei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define bunltr_d(i0, r0, r1) _bunltr_d(_jit, i0, r0, r1) +static jit_word_t _bunltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlti_d(i0, r0, i1) _bunlti_d(_jit, i0, r0, i1) +static jit_word_t +_bunlti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define bunler_d(i0, r0, r1) _bunler_d(_jit, i0, r0, r1) +static jit_word_t _bunler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlei_d(i0, r0, i1) _bunlei_d(_jit, i0, r0, i1) +static jit_word_t +_bunlei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define buneqr_d(i0, r0, r1) _buneqr_d(_jit, i0, r0, r1) +static jit_word_t _buneqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define buneqi_d(i0, r0, i1) _buneqi_d(_jit, i0, r0, i1) +static jit_word_t +_buneqi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define bunger_d(i0, r0, r1) _bunger_d(_jit, i0, r0, r1) +static jit_word_t _bunger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungei_d(i0, r0, i1) _bungei_d(_jit, i0, r0, i1) +static jit_word_t +_bungei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define bungtr_d(i0, r0, r1) _bungtr_d(_jit, i0, r0, r1) +static jit_word_t _bungtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungti_d(i0, r0, i1) _bungti_d(_jit, i0, r0, i1) +static jit_word_t +_bungti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define bltgtr_d(i0, r0, r1) _bltgtr_d(_jit, i0, r0, r1) +static jit_word_t _bltgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bltgti_d(i0, r0, i1) _bltgti_d(_jit, i0, r0, i1) +static jit_word_t +_bltgti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define bordr_d(i0, r0, r1) _bordr_d(_jit, i0, r0, r1) +static jit_word_t _bordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bordi_d(i0, r0, i1) _bordi_d(_jit, i0, r0, i1) +static jit_word_t +_bordi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define bunordr_d(i0, r0, r1) _bunordr_d(_jit, i0, r0, r1) +static jit_word_t _bunordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunordi_d(i0, r0, i1) _bunordi_d(_jit, i0, r0, i1) +static jit_word_t +_bunordi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1) +static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t); +#endif + +#if CODE +static void +_c_cond_fmt(jit_state_t *_jit, jit_int32_t fm, + jit_int32_t ft, jit_int32_t fs, jit_int32_t cc) +{ + jit_instr_t i; + i.cc.b = cc; + i.fs.b = fs; + i.ft.b = ft; + i.fm.b = fm; + i.hc.b = MIPS_COP1; + ii(i.op); +} + +# define fpr_opi(name, type, size) \ +static void \ +_##name##i_##type(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, \ + jit_float##size##_t *i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr); \ + movi_##type(rn(reg), i0); \ + name##r_##type(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +# define fpr_bopi(name, type, size) \ +static jit_word_t \ +_b##name##i_##type(jit_state_t *_jit, \ + jit_word_t i0, jit_int32_t r0, \ + jit_float##size##_t *i1) \ +{ \ + jit_word_t word; \ + jit_int32_t reg = jit_get_reg(jit_class_fpr| \ + jit_class_nospill); \ + movi_##type(rn(reg), i1); \ + word = b##name##r_##type(i0, r0, rn(reg)); \ + jit_unget_reg(reg); \ + return (word); \ +} +# define fopi(name) fpr_opi(name, f, 32) +# define fbopi(name) fpr_bopi(name, f, 32) +# define dopi(name) fpr_opi(name, d, 64) +# define dbopi(name) fpr_bopi(name, d, 64) + +fopi(add) +fopi(sub) +fopi(rsb) +fopi(mul) +fopi(div) + +static void +_movi_f_w(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + + data.f = *i0; + movi(r0, data.i); +} + +static void +_extr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_fpr); +# if __WORDSIZE == 32 + MTC1(r1, rn(t0)); + CVT_S_W(r0, rn(t0)); +# else + DMTC1(r1, rn(t0)); + CVT_S_L(r0, rn(t0)); +# endif + jit_unget_reg(t0); +} + +static void +_truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_fpr); + TRUNC_W_S(rn(t0), r1); + MFC1(r0, rn(t0)); + jit_unget_reg(t0); +} + +# if __WORDSIZE == 64 +static void +_truncr_f_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_fpr); + TRUNC_L_S(rn(t0), r1); + DMFC1(r0, rn(t0)); + jit_unget_reg(t0); +} +# endif + +static void +_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LWC1(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + LWC1(r0, i0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + SWC1(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_f(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_f(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + SWC1(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_f(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_movr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + MOV_S(r0, r1); +} + +static void +_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_int32_t reg; + + data.f = *i0; + if (data.i) { + if (_jitc->no_data) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.i); + MTC1(rn(reg), r0); + jit_unget_reg(reg); + } + else + ldi_f(r0, (jit_word_t)i0); + } + else + MTC1(_ZERO_REGNO, r0); +} + +dopi(add) +dopi(sub) +dopi(rsb) +dopi(mul) +dopi(div) + +#if NEW_ABI +/* n32 abi requires 64 bit cpu */ +static void +_movi64(jit_state_t *_jit, jit_int32_t r0, jit_int64_t i0) +{ + if (i0 == 0) + OR(r0, _ZERO_REGNO, _ZERO_REGNO); + else if (i0 >= -32678 && i0 <= 32767) + DADDIU(r0, _ZERO_REGNO, i0); + else if (i0 >= 0 && i0 <= 65535) + ORI(r0, _ZERO_REGNO, i0); + else { + if (i0 >= 0 && i0 <= 0x7fffffffLL) + LUI(r0, i0 >> 16); + else if (i0 >= 0 && i0 <= 0xffffffffLL) { + if (i0 & 0xffff0000LL) { + ORI(r0, _ZERO_REGNO, (jit_word_t)(i0 >> 16)); + DSLL(r0, r0, 16); + } + } + else { + movi(r0, (jit_word_t)(i0 >> 32)); + if (i0 & 0xffff0000LL) { + DSLL(r0, r0, 16); + ORI(r0, r0, (jit_word_t)(i0 >> 16)); + DSLL(r0, r0, 16); + } + else + DSLL32(r0, r0, 0); + } + if ((jit_word_t)i0 & 0xffff) + ORI(r0, r0, (jit_word_t)i0 & 0xffff); + } +} + +static void +_movi_d_w(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + jit_word_t w; + union { + jit_int64_t l; + jit_float64_t d; + } data; + if (_jitc->no_data) { + data.d = *i0; + movi64(r0, data.l); + } + else { + w = (jit_word_t)i0; + if (can_sign_extend_short_p(w)) + LD(r0, w, _ZERO_REGNO); + else { + movi(r0, w); + LD(r0, 0, r0); + } + } +} + +#else +static void +_movr_ww_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + assert(r1 == r2 - 1); + MTC1(r1, r0 + BE_P); + MTC1(r2, r0 + LE_P); +} + +static void +_movr_d_ww(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + assert(r0 == r1 - 1); + MFC1(r0, r2 + BE_P); + MFC1(r1, r2 + LE_P); +} + +static void +_movi_d_ww(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_float64_t *i0) +{ + union { + jit_int32_t i[2]; + jit_int64_t l; + jit_float64_t d; + } data; + + data.d = *i0; + movi(r0, data.i[0]); + movi(r1, data.i[1]); +} +#endif + +static void +_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_fpr); +# if __WORDSIZE == 32 + MTC1(r1, rn(t0)); + CVT_D_W(r0, rn(t0)); +# else + DMTC1(r1, rn(t0)); + CVT_D_L(r0, rn(t0)); +# endif + jit_unget_reg(t0); +} + +static void +_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_fpr); + TRUNC_W_D(rn(t0), r1); + MFC1(r0, rn(t0)); + jit_unget_reg(t0); +} + +# if __WORDSIZE == 64 +static void +_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_fpr); + TRUNC_L_D(rn(t0), r1); + DMFC1(r0, rn(t0)); + jit_unget_reg(t0); +} +# endif + +static void +_ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ +# if __WORDSIZE == 64 || NEW_ABI + LDC1(r0, 0, r1); +# else + LWC1(r0 + BE_P, 0, r1); + LWC1(r0 + LE_P, 4, r1); +# endif +} + +static void +_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; +# if __WORDSIZE == 64 || NEW_ABI + if (can_sign_extend_short_p(i0)) + LDC1(r0, i0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDC1(r0, 0, rn(reg)); + jit_unget_reg(reg); + } +# else + if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) { + LWC1(r0 + BE_P, i0, _ZERO_REGNO); + LWC1(r0 + LE_P, i0 + 4, _ZERO_REGNO); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LWC1(r0 + BE_P, 0, rn(reg)); + LWC1(r0 + LE_P, 4, rn(reg)); + jit_unget_reg(reg); + } +# endif +} + +static void +_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; +# if __WORDSIZE == 64 || NEW_ABI + if (can_sign_extend_short_p(i0)) + LDC1(r0, i0, r1); +# else + if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) { + LWC1(r0 + BE_P, i0, r1); + LWC1(r0 + LE_P, i0 + 4, r1); + } +# endif + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_str_d(jit_state_t *_jit,jit_int32_t r0, jit_int32_t r1) +{ +# if __WORDSIZE == 64 || NEW_ABI + SDC1(r1, 0, r0); +# else + SWC1(r1 + BE_P, 0, r0); + SWC1(r1 + LE_P, 4, r0); +# endif +} + +static void +_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; +# if __WORDSIZE == 64 || NEW_ABI + if (can_sign_extend_short_p(i0)) + SDC1(r0, i0, _ZERO_REGNO); +# else + if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) { + SWC1(r0 + BE_P, i0, _ZERO_REGNO); + SWC1(r0 + LE_P, i0 + 4, _ZERO_REGNO); + } +# endif + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_d(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_d(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; +# if __WORDSIZE == 64 || NEW_ABI + if (can_sign_extend_short_p(i0)) + SDC1(r1, i0, r0); +# else + if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) { + SWC1(r1 + BE_P, i0, r0); + SWC1(r1 + LE_P, i0 + 4, r0); + } +# endif + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_d(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + MOV_D(r0, r1); +} + +static void +_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + union { + jit_int32_t i[2]; + jit_int64_t l; + jit_float64_t d; + } data; + jit_int32_t reg; + + data.d = *i0; +# if __WORDSIZE == 64 || NEW_ABI + if (data.l) { + if (_jitc->no_data) { + reg = jit_get_reg(jit_class_gpr); + movi64(rn(reg), data.l); + DMTC1(rn(reg), r0); + jit_unget_reg(reg); + } + else + ldi_d(r0, (jit_word_t)i0); + } + else + DMTC1(_ZERO_REGNO, r0); +# else + if (_jitc->no_data) + reg = jit_get_reg(jit_class_gpr); + if (data.i[0]) { + if (_jitc->no_data) { + movi(rn(reg), data.i[0]); + MTC1(rn(reg), r0 + BE_P); + } + else + ldi_f(r0 + BE_P, (jit_word_t)i0); + } + else + MTC1(_ZERO_REGNO, r0 + BE_P); + if (data.i[1]) { + if (_jitc->no_data) { + movi(rn(reg), data.i[1]); + MTC1(rn(reg), r0 + LE_P); + } + else + ldi_f(r0 + LE_P, ((jit_word_t)i0) + 4); + } + else + MTC1(_ZERO_REGNO, r0 + LE_P); + if (_jitc->no_data) + jit_unget_reg(reg); +# endif +} + +static void +_ltr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLT_S(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(lt) + +static void +_ler_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLE_S(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(le) + +static void +_eqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_EQ_S(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(eq) + +static void +_ger_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULT_S(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(ge) + +static void +_gtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULE_S(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(gt) + +static void +_ner_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_EQ_S(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(ne) + +static void +_unltr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULT_S(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(unlt) + +static void +_unler_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULE_S(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(unle) + +static void +_uneqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UEQ_S(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(uneq) + +static void +_unger_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLT_S(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(unge) + +static void +_ungtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLE_S(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(ungt) + +static void +_ltgtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UEQ_S(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(ltgt) + +static void +_ordr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UN_S(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(ord) + +static void +_unordr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UN_S(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(unord) + +static jit_word_t +_bltr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLT_S(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(lt) + +static jit_word_t +_bler_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLE_S(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(le) + +static jit_word_t +_beqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_EQ_S(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(eq) + +static jit_word_t +_bger_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULT_S(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(ge) + +static jit_word_t +_bgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULE_S(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(gt) + +static jit_word_t +_bner_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_EQ_S(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(ne) + +static jit_word_t +_bunltr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULT_S(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(unlt) + +static jit_word_t +_bunler_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULE_S(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(unle) + +static jit_word_t +_buneqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UEQ_S(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(uneq) + +static jit_word_t +_bunger_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLT_S(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(unge) + +static jit_word_t +_bungtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLE_S(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(ungt) + +static jit_word_t +_bltgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UEQ_S(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(ltgt) + +static jit_word_t +_bordr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UN_S(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(ord) + +static jit_word_t +_bunordr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UN_S(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +fbopi(unord) + +static void +_ltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLT_D(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(lt) + +static void +_ler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLE_D(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(le) + +static void +_eqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_EQ_D(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(eq) + +static void +_ger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULT_D(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(ge) + +static void +_gtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULE_D(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(gt) + +static void +_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_EQ_D(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(ne) + +static void +_unltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULT_D(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(unlt) + +static void +_unler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULE_D(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(unle) + +static void +_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UEQ_D(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(uneq) + +static void +_unger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLT_D(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(unge) + +static void +_ungtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLE_D(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(ungt) + +static void +_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UEQ_D(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(ltgt) + +static void +_ordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UN_D(r1, r2); + w = _jit->pc.w; + BC1F(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(ord) + +static void +_unordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UN_D(r1, r2); + w = _jit->pc.w; + BC1T(0); + /* delay slot */ + movi(r0, 1); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +dopi(unord) + +static jit_word_t +_bltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLT_D(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(lt) + +static jit_word_t +_bler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLE_D(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(le) + +static jit_word_t +_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_EQ_D(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(eq) + +static jit_word_t +_bger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULT_D(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(ge) + +static jit_word_t +_bgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULE_D(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(gt) + +static jit_word_t +_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_EQ_D(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(ne) + +static jit_word_t +_bunltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULT_D(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(unlt) + +static jit_word_t +_bunler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_ULE_D(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(unle) + +static jit_word_t +_buneqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UEQ_D(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(uneq) + +static jit_word_t +_bunger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLT_D(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(unge) + +static jit_word_t +_bungtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_OLE_D(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(ungt) + +static jit_word_t +_bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UEQ_D(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(ltgt) + +static jit_word_t +_bordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UN_D(r1, r2); + w = _jit->pc.w; + BC1F(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(ord) + +static jit_word_t +_bunordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + C_UN_D(r1, r2); + w = _jit->pc.w; + BC1T(((i0 - w) >> 2) - 1); + NOP(1); + return (w); +} +dbopi(unord) + +static void +_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ +#if !NEW_ABI + jit_int32_t reg; +#endif + assert(_jitc->function->self.call & jit_call_varargs); +#if !NEW_ABI + /* Align, if required. */ + reg = jit_get_reg(jit_class_gpr); + andi(rn(reg), r1, 7); + addr(r1, r1, rn(reg)); + jit_unget_reg(reg); +#endif + + /* Load argument. */ + ldr_d(r0, r1); + + /* Update va_list. */ + addi(r1, r1, sizeof(jit_float64_t)); +} + +# undef fopi +# undef fbopi +# undef dopi +# undef dbopi +# undef fpr_bopi +# undef fpr_opi +#endif diff --git a/deps/lightning/lib/jit_mips-sz.c b/deps/lightning/lib/jit_mips-sz.c new file mode 100644 index 0000000..613aa00 --- /dev/null +++ b/deps/lightning/lib/jit_mips-sz.c @@ -0,0 +1,1210 @@ + +#if __WORDSIZE == 32 +#if NEW_ABI +#define JIT_INSTR_MAX 44 + 0, /* data */ + 0, /* live */ + 0, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 44, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 0, /* va_start */ + 0, /* va_arg */ + 0, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 12, /* addi */ + 12, /* addcr */ + 20, /* addci */ + 28, /* addxr */ + 28, /* addxi */ + 4, /* subr */ + 12, /* subi */ + 12, /* subcr */ + 20, /* subci */ + 28, /* subxr */ + 28, /* subxi */ + 16, /* rsbi */ + 8, /* mulr */ + 16, /* muli */ + 12, /* qmulr */ + 20, /* qmuli */ + 12, /* qmulr_u */ + 20, /* qmuli_u */ + 8, /* divr */ + 16, /* divi */ + 8, /* divr_u */ + 16, /* divi_u */ + 12, /* qdivr */ + 16, /* qdivi */ + 12, /* qdivr_u */ + 16, /* qdivi_u */ + 8, /* remr */ + 16, /* remi */ + 8, /* remr_u */ + 16, /* remi_u */ + 4, /* andr */ + 12, /* andi */ + 4, /* orr */ + 12, /* ori */ + 4, /* xorr */ + 12, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 8, /* comr */ + 4, /* ltr */ + 4, /* lti */ + 4, /* ltr_u */ + 4, /* lti_u */ + 8, /* ler */ + 12, /* lei */ + 8, /* ler_u */ + 12, /* lei_u */ + 12, /* eqr */ + 12, /* eqi */ + 8, /* ger */ + 12, /* gei */ + 8, /* ger_u */ + 12, /* gei_u */ + 4, /* gtr */ + 8, /* gti */ + 4, /* gtr_u */ + 8, /* gti_u */ + 8, /* ner */ + 8, /* nei */ + 4, /* movr */ + 8, /* movi */ + 8, /* extr_c */ + 4, /* extr_uc */ + 8, /* extr_s */ + 4, /* extr_us */ + 0, /* extr_i */ + 0, /* extr_ui */ + 4, /* htonr_us */ + 4, /* htonr_ui */ + 0, /* htonr_ul */ + 4, /* ldr_c */ + 12, /* ldi_c */ + 4, /* ldr_uc */ + 12, /* ldi_uc */ + 4, /* ldr_s */ + 12, /* ldi_s */ + 4, /* ldr_us */ + 12, /* ldi_us */ + 4, /* ldr_i */ + 12, /* ldi_i */ + 0, /* ldr_ui */ + 0, /* ldi_ui */ + 0, /* ldr_l */ + 0, /* ldi_l */ + 8, /* ldxr_c */ + 4, /* ldxi_c */ + 8, /* ldxr_uc */ + 4, /* ldxi_uc */ + 8, /* ldxr_s */ + 4, /* ldxi_s */ + 8, /* ldxr_us */ + 4, /* ldxi_us */ + 8, /* ldxr_i */ + 4, /* ldxi_i */ + 0, /* ldxr_ui */ + 0, /* ldxi_ui */ + 0, /* ldxr_l */ + 0, /* ldxi_l */ + 4, /* str_c */ + 12, /* sti_c */ + 4, /* str_s */ + 12, /* sti_s */ + 4, /* str_i */ + 12, /* sti_i */ + 0, /* str_l */ + 0, /* sti_l */ + 8, /* stxr_c */ + 4, /* stxi_c */ + 8, /* stxr_s */ + 4, /* stxi_s */ + 8, /* stxr_i */ + 4, /* stxi_i */ + 0, /* stxr_l */ + 0, /* stxi_l */ + 12, /* bltr */ + 12, /* blti */ + 12, /* bltr_u */ + 12, /* blti_u */ + 12, /* bler */ + 16, /* blei */ + 12, /* bler_u */ + 16, /* blei_u */ + 8, /* beqr */ + 16, /* beqi */ + 12, /* bger */ + 12, /* bgei */ + 12, /* bger_u */ + 12, /* bgei_u */ + 12, /* bgtr */ + 16, /* bgti */ + 12, /* bgtr_u */ + 16, /* bgti_u */ + 8, /* bner */ + 16, /* bnei */ + 12, /* bmsr */ + 12, /* bmsi */ + 12, /* bmcr */ + 12, /* bmci */ + 28, /* boaddr */ + 28, /* boaddi */ + 16, /* boaddr_u */ + 20, /* boaddi_u */ + 28, /* bxaddr */ + 28, /* bxaddi */ + 16, /* bxaddr_u */ + 20, /* bxaddi_u */ + 28, /* bosubr */ + 28, /* bosubi */ + 16, /* bosubr_u */ + 20, /* bosubi_u */ + 28, /* bxsubr */ + 28, /* bxsubi */ + 16, /* bxsubr_u */ + 20, /* bxsubi_u */ + 0, /* jmpr */ + 8, /* jmpi */ + 12, /* callr */ + 16, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 44, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 16, /* addi_f */ + 4, /* subr_f */ + 16, /* subi_f */ + 16, /* rsbi_f */ + 4, /* mulr_f */ + 16, /* muli_f */ + 4, /* divr_f */ + 16, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 16, /* ltr_f */ + 28, /* lti_f */ + 16, /* ler_f */ + 28, /* lei_f */ + 16, /* eqr_f */ + 28, /* eqi_f */ + 16, /* ger_f */ + 28, /* gei_f */ + 16, /* gtr_f */ + 28, /* gti_f */ + 16, /* ner_f */ + 28, /* nei_f */ + 16, /* unltr_f */ + 28, /* unlti_f */ + 16, /* unler_f */ + 28, /* unlei_f */ + 16, /* uneqr_f */ + 28, /* uneqi_f */ + 16, /* unger_f */ + 28, /* ungei_f */ + 16, /* ungtr_f */ + 28, /* ungti_f */ + 16, /* ltgtr_f */ + 28, /* ltgti_f */ + 16, /* ordr_f */ + 28, /* ordi_f */ + 16, /* unordr_f */ + 28, /* unordi_f */ + 8, /* truncr_f_i */ + 0, /* truncr_f_l */ + 8, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 12, /* movi_f */ + 4, /* ldr_f */ + 12, /* ldi_f */ + 8, /* ldxr_f */ + 4, /* ldxi_f */ + 4, /* str_f */ + 12, /* sti_f */ + 8, /* stxr_f */ + 4, /* stxi_f */ + 12, /* bltr_f */ + 24, /* blti_f */ + 12, /* bler_f */ + 24, /* blei_f */ + 12, /* beqr_f */ + 24, /* beqi_f */ + 12, /* bger_f */ + 24, /* bgei_f */ + 12, /* bgtr_f */ + 24, /* bgti_f */ + 12, /* bner_f */ + 24, /* bnei_f */ + 12, /* bunltr_f */ + 24, /* bunlti_f */ + 12, /* bunler_f */ + 24, /* bunlei_f */ + 12, /* buneqr_f */ + 24, /* buneqi_f */ + 12, /* bunger_f */ + 24, /* bungei_f */ + 12, /* bungtr_f */ + 24, /* bungti_f */ + 12, /* bltgtr_f */ + 24, /* bltgti_f */ + 12, /* bordr_f */ + 24, /* bordi_f */ + 12, /* bunordr_f */ + 24, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 16, /* addi_d */ + 4, /* subr_d */ + 16, /* subi_d */ + 16, /* rsbi_d */ + 4, /* mulr_d */ + 16, /* muli_d */ + 4, /* divr_d */ + 16, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 16, /* ltr_d */ + 28, /* lti_d */ + 16, /* ler_d */ + 28, /* lei_d */ + 16, /* eqr_d */ + 28, /* eqi_d */ + 16, /* ger_d */ + 28, /* gei_d */ + 16, /* gtr_d */ + 28, /* gti_d */ + 16, /* ner_d */ + 28, /* nei_d */ + 16, /* unltr_d */ + 28, /* unlti_d */ + 16, /* unler_d */ + 28, /* unlei_d */ + 16, /* uneqr_d */ + 28, /* uneqi_d */ + 16, /* unger_d */ + 28, /* ungei_d */ + 16, /* ungtr_d */ + 28, /* ungti_d */ + 16, /* ltgtr_d */ + 28, /* ltgti_d */ + 16, /* ordr_d */ + 28, /* ordi_d */ + 16, /* unordr_d */ + 28, /* unordi_d */ + 8, /* truncr_d_i */ + 0, /* truncr_d_l */ + 8, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 12, /* movi_d */ + 4, /* ldr_d */ + 12, /* ldi_d */ + 8, /* ldxr_d */ + 4, /* ldxi_d */ + 4, /* str_d */ + 12, /* sti_d */ + 8, /* stxr_d */ + 4, /* stxi_d */ + 12, /* bltr_d */ + 24, /* blti_d */ + 12, /* bler_d */ + 24, /* blei_d */ + 12, /* beqr_d */ + 24, /* beqi_d */ + 12, /* bger_d */ + 24, /* bgei_d */ + 12, /* bgtr_d */ + 24, /* bgti_d */ + 12, /* bner_d */ + 24, /* bnei_d */ + 12, /* bunltr_d */ + 24, /* bunlti_d */ + 12, /* bunler_d */ + 24, /* bunlei_d */ + 12, /* buneqr_d */ + 24, /* buneqi_d */ + 12, /* bunger_d */ + 24, /* bungei_d */ + 12, /* bungtr_d */ + 24, /* bungti_d */ + 12, /* bltgtr_d */ + 24, /* bltgti_d */ + 12, /* bordr_d */ + 24, /* bordi_d */ + 12, /* bunordr_d */ + 24, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 4, /* movr_d_w */ + 12, /* movi_d_w */ +#endif /* NEW_ABI */ +#endif /* __WORDSIZE */ + +#if __WORDSIZE == 32 +#if !NEW_ABI +#define JIT_INSTR_MAX 116 + 0, /* data */ + 0, /* live */ + 0, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 116, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 20, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 12, /* addi */ + 12, /* addcr */ + 20, /* addci */ + 28, /* addxr */ + 28, /* addxi */ + 4, /* subr */ + 12, /* subi */ + 12, /* subcr */ + 20, /* subci */ + 28, /* subxr */ + 28, /* subxi */ + 16, /* rsbi */ + 8, /* mulr */ + 16, /* muli */ + 12, /* qmulr */ + 20, /* qmuli */ + 12, /* qmulr_u */ + 20, /* qmuli_u */ + 8, /* divr */ + 16, /* divi */ + 8, /* divr_u */ + 16, /* divi_u */ + 12, /* qdivr */ + 16, /* qdivi */ + 12, /* qdivr_u */ + 16, /* qdivi_u */ + 8, /* remr */ + 16, /* remi */ + 8, /* remr_u */ + 16, /* remi_u */ + 4, /* andr */ + 12, /* andi */ + 4, /* orr */ + 12, /* ori */ + 4, /* xorr */ + 12, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 8, /* comr */ + 4, /* ltr */ + 4, /* lti */ + 4, /* ltr_u */ + 4, /* lti_u */ + 8, /* ler */ + 12, /* lei */ + 8, /* ler_u */ + 12, /* lei_u */ + 12, /* eqr */ + 12, /* eqi */ + 8, /* ger */ + 12, /* gei */ + 8, /* ger_u */ + 12, /* gei_u */ + 4, /* gtr */ + 8, /* gti */ + 4, /* gtr_u */ + 8, /* gti_u */ + 8, /* ner */ + 8, /* nei */ + 4, /* movr */ + 8, /* movi */ + 8, /* extr_c */ + 4, /* extr_uc */ + 8, /* extr_s */ + 4, /* extr_us */ + 0, /* extr_i */ + 0, /* extr_ui */ + 20, /* htonr_us */ + 52, /* htonr_ui */ + 0, /* htonr_ul */ + 4, /* ldr_c */ + 12, /* ldi_c */ + 4, /* ldr_uc */ + 12, /* ldi_uc */ + 4, /* ldr_s */ + 12, /* ldi_s */ + 4, /* ldr_us */ + 12, /* ldi_us */ + 4, /* ldr_i */ + 12, /* ldi_i */ + 0, /* ldr_ui */ + 0, /* ldi_ui */ + 0, /* ldr_l */ + 0, /* ldi_l */ + 8, /* ldxr_c */ + 16, /* ldxi_c */ + 8, /* ldxr_uc */ + 16, /* ldxi_uc */ + 8, /* ldxr_s */ + 16, /* ldxi_s */ + 8, /* ldxr_us */ + 16, /* ldxi_us */ + 8, /* ldxr_i */ + 16, /* ldxi_i */ + 0, /* ldxr_ui */ + 0, /* ldxi_ui */ + 0, /* ldxr_l */ + 0, /* ldxi_l */ + 4, /* str_c */ + 12, /* sti_c */ + 4, /* str_s */ + 12, /* sti_s */ + 4, /* str_i */ + 12, /* sti_i */ + 0, /* str_l */ + 0, /* sti_l */ + 8, /* stxr_c */ + 16, /* stxi_c */ + 8, /* stxr_s */ + 16, /* stxi_s */ + 8, /* stxr_i */ + 16, /* stxi_i */ + 0, /* stxr_l */ + 0, /* stxi_l */ + 12, /* bltr */ + 12, /* blti */ + 12, /* bltr_u */ + 12, /* blti_u */ + 12, /* bler */ + 16, /* blei */ + 12, /* bler_u */ + 16, /* blei_u */ + 8, /* beqr */ + 16, /* beqi */ + 12, /* bger */ + 12, /* bgei */ + 12, /* bger_u */ + 12, /* bgei_u */ + 12, /* bgtr */ + 16, /* bgti */ + 12, /* bgtr_u */ + 16, /* bgti_u */ + 8, /* bner */ + 16, /* bnei */ + 12, /* bmsr */ + 12, /* bmsi */ + 12, /* bmcr */ + 12, /* bmci */ + 28, /* boaddr */ + 28, /* boaddi */ + 16, /* boaddr_u */ + 20, /* boaddi_u */ + 28, /* bxaddr */ + 28, /* bxaddi */ + 16, /* bxaddr_u */ + 20, /* bxaddi_u */ + 28, /* bosubr */ + 28, /* bosubi */ + 16, /* bosubr_u */ + 20, /* bosubi_u */ + 28, /* bxsubr */ + 28, /* bxsubi */ + 16, /* bxsubr_u */ + 20, /* bxsubi_u */ + 8, /* jmpr */ + 8, /* jmpi */ + 12, /* callr */ + 16, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 116, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 16, /* addi_f */ + 4, /* subr_f */ + 16, /* subi_f */ + 16, /* rsbi_f */ + 4, /* mulr_f */ + 16, /* muli_f */ + 4, /* divr_f */ + 16, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 16, /* ltr_f */ + 28, /* lti_f */ + 16, /* ler_f */ + 28, /* lei_f */ + 16, /* eqr_f */ + 28, /* eqi_f */ + 16, /* ger_f */ + 28, /* gei_f */ + 16, /* gtr_f */ + 28, /* gti_f */ + 16, /* ner_f */ + 28, /* nei_f */ + 16, /* unltr_f */ + 28, /* unlti_f */ + 16, /* unler_f */ + 28, /* unlei_f */ + 16, /* uneqr_f */ + 28, /* uneqi_f */ + 16, /* unger_f */ + 28, /* ungei_f */ + 16, /* ungtr_f */ + 28, /* ungti_f */ + 16, /* ltgtr_f */ + 28, /* ltgti_f */ + 16, /* ordr_f */ + 28, /* ordi_f */ + 16, /* unordr_f */ + 28, /* unordi_f */ + 8, /* truncr_f_i */ + 0, /* truncr_f_l */ + 8, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 12, /* movi_f */ + 4, /* ldr_f */ + 12, /* ldi_f */ + 8, /* ldxr_f */ + 16, /* ldxi_f */ + 4, /* str_f */ + 12, /* sti_f */ + 8, /* stxr_f */ + 16, /* stxi_f */ + 12, /* bltr_f */ + 24, /* blti_f */ + 12, /* bler_f */ + 24, /* blei_f */ + 12, /* beqr_f */ + 24, /* beqi_f */ + 12, /* bger_f */ + 24, /* bgei_f */ + 12, /* bgtr_f */ + 24, /* bgti_f */ + 12, /* bner_f */ + 24, /* bnei_f */ + 12, /* bunltr_f */ + 24, /* bunlti_f */ + 12, /* bunler_f */ + 24, /* bunlei_f */ + 12, /* buneqr_f */ + 24, /* buneqi_f */ + 12, /* bunger_f */ + 24, /* bungei_f */ + 12, /* bungtr_f */ + 24, /* bungti_f */ + 12, /* bltgtr_f */ + 24, /* bltgti_f */ + 12, /* bordr_f */ + 24, /* bordi_f */ + 12, /* bunordr_f */ + 24, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 20, /* addi_d */ + 4, /* subr_d */ + 20, /* subi_d */ + 20, /* rsbi_d */ + 4, /* mulr_d */ + 20, /* muli_d */ + 4, /* divr_d */ + 20, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 16, /* ltr_d */ + 40, /* lti_d */ + 16, /* ler_d */ + 40, /* lei_d */ + 16, /* eqr_d */ + 40, /* eqi_d */ + 16, /* ger_d */ + 40, /* gei_d */ + 16, /* gtr_d */ + 40, /* gti_d */ + 16, /* ner_d */ + 40, /* nei_d */ + 16, /* unltr_d */ + 40, /* unlti_d */ + 16, /* unler_d */ + 40, /* unlei_d */ + 16, /* uneqr_d */ + 40, /* uneqi_d */ + 16, /* unger_d */ + 40, /* ungei_d */ + 16, /* ungtr_d */ + 40, /* ungti_d */ + 16, /* ltgtr_d */ + 40, /* ltgti_d */ + 16, /* ordr_d */ + 40, /* ordi_d */ + 16, /* unordr_d */ + 40, /* unordi_d */ + 8, /* truncr_d_i */ + 0, /* truncr_d_l */ + 8, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 24, /* movi_d */ + 8, /* ldr_d */ + 16, /* ldi_d */ + 12, /* ldxr_d */ + 20, /* ldxi_d */ + 8, /* str_d */ + 16, /* sti_d */ + 12, /* stxr_d */ + 20, /* stxi_d */ + 12, /* bltr_d */ + 28, /* blti_d */ + 12, /* bler_d */ + 28, /* blei_d */ + 12, /* beqr_d */ + 28, /* beqi_d */ + 12, /* bger_d */ + 28, /* bgei_d */ + 12, /* bgtr_d */ + 28, /* bgti_d */ + 12, /* bner_d */ + 36, /* bnei_d */ + 12, /* bunltr_d */ + 36, /* bunlti_d */ + 12, /* bunler_d */ + 36, /* bunlei_d */ + 12, /* buneqr_d */ + 36, /* buneqi_d */ + 12, /* bunger_d */ + 36, /* bungei_d */ + 12, /* bungtr_d */ + 36, /* bungti_d */ + 12, /* bltgtr_d */ + 28, /* bltgti_d */ + 12, /* bordr_d */ + 28, /* bordi_d */ + 12, /* bunordr_d */ + 36, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 4, /* movr_w_f */ + 8, /* movr_ww_d */ + 0, /* movr_w_d */ + 4, /* movr_f_w */ + 4, /* movi_f_w */ + 8, /* movr_d_ww */ + 8, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* NEW_ABI */ +#endif /* __WORDSIZE */ + +#if __WORDSIZE == 64 +#define JIT_INSTR_MAX 44 + 0, /* data */ + 0, /* live */ + 4, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 44, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 0, /* va_start */ + 0, /* va_arg */ + 0, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 28, /* addi */ + 12, /* addcr */ + 36, /* addci */ + 28, /* addxr */ + 28, /* addxi */ + 4, /* subr */ + 28, /* subi */ + 12, /* subcr */ + 36, /* subci */ + 28, /* subxr */ + 28, /* subxi */ + 32, /* rsbi */ + 8, /* mulr */ + 32, /* muli */ + 12, /* qmulr */ + 32, /* qmuli */ + 12, /* qmulr_u */ + 32, /* qmuli_u */ + 8, /* divr */ + 32, /* divi */ + 8, /* divr_u */ + 32, /* divi_u */ + 12, /* qdivr */ + 16, /* qdivi */ + 12, /* qdivr_u */ + 16, /* qdivi_u */ + 8, /* remr */ + 32, /* remi */ + 8, /* remr_u */ + 32, /* remi_u */ + 4, /* andr */ + 28, /* andi */ + 4, /* orr */ + 28, /* ori */ + 4, /* xorr */ + 28, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 8, /* comr */ + 4, /* ltr */ + 4, /* lti */ + 4, /* ltr_u */ + 4, /* lti_u */ + 8, /* ler */ + 12, /* lei */ + 8, /* ler_u */ + 12, /* lei_u */ + 12, /* eqr */ + 12, /* eqi */ + 8, /* ger */ + 12, /* gei */ + 8, /* ger_u */ + 12, /* gei_u */ + 4, /* gtr */ + 8, /* gti */ + 4, /* gtr_u */ + 8, /* gti_u */ + 8, /* ner */ + 8, /* nei */ + 4, /* movr */ + 28, /* movi */ + 8, /* extr_c */ + 4, /* extr_uc */ + 8, /* extr_s */ + 4, /* extr_us */ + 4, /* extr_i */ + 8, /* extr_ui */ + 4, /* htonr_us */ + 4, /* htonr_ui */ + 4, /* htonr_ul */ + 4, /* ldr_c */ + 12, /* ldi_c */ + 4, /* ldr_uc */ + 12, /* ldi_uc */ + 4, /* ldr_s */ + 12, /* ldi_s */ + 4, /* ldr_us */ + 12, /* ldi_us */ + 4, /* ldr_i */ + 12, /* ldi_i */ + 4, /* ldr_ui */ + 12, /* ldi_ui */ + 4, /* ldr_l */ + 12, /* ldi_l */ + 8, /* ldxr_c */ + 4, /* ldxi_c */ + 8, /* ldxr_uc */ + 4, /* ldxi_uc */ + 8, /* ldxr_s */ + 4, /* ldxi_s */ + 8, /* ldxr_us */ + 4, /* ldxi_us */ + 8, /* ldxr_i */ + 4, /* ldxi_i */ + 8, /* ldxr_ui */ + 4, /* ldxi_ui */ + 8, /* ldxr_l */ + 4, /* ldxi_l */ + 4, /* str_c */ + 12, /* sti_c */ + 4, /* str_s */ + 12, /* sti_s */ + 4, /* str_i */ + 12, /* sti_i */ + 4, /* str_l */ + 12, /* sti_l */ + 8, /* stxr_c */ + 4, /* stxi_c */ + 8, /* stxr_s */ + 4, /* stxi_s */ + 8, /* stxr_i */ + 4, /* stxi_i */ + 8, /* stxr_l */ + 4, /* stxi_l */ + 12, /* bltr */ + 12, /* blti */ + 12, /* bltr_u */ + 12, /* blti_u */ + 12, /* bler */ + 16, /* blei */ + 12, /* bler_u */ + 16, /* blei_u */ + 8, /* beqr */ + 36, /* beqi */ + 12, /* bger */ + 12, /* bgei */ + 12, /* bger_u */ + 12, /* bgei_u */ + 12, /* bgtr */ + 16, /* bgti */ + 12, /* bgtr_u */ + 16, /* bgti_u */ + 8, /* bner */ + 32, /* bnei */ + 12, /* bmsr */ + 12, /* bmsi */ + 12, /* bmcr */ + 12, /* bmci */ + 28, /* boaddr */ + 28, /* boaddi */ + 16, /* boaddr_u */ + 20, /* boaddi_u */ + 28, /* bxaddr */ + 28, /* bxaddi */ + 16, /* bxaddr_u */ + 20, /* bxaddi_u */ + 28, /* bosubr */ + 28, /* bosubi */ + 16, /* bosubr_u */ + 20, /* bosubi_u */ + 28, /* bxsubr */ + 28, /* bxsubi */ + 16, /* bxsubr_u */ + 20, /* bxsubi_u */ + 0, /* jmpr */ + 8, /* jmpi */ + 12, /* callr */ + 32, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 44, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 16, /* addi_f */ + 4, /* subr_f */ + 16, /* subi_f */ + 16, /* rsbi_f */ + 4, /* mulr_f */ + 16, /* muli_f */ + 4, /* divr_f */ + 16, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 16, /* ltr_f */ + 28, /* lti_f */ + 16, /* ler_f */ + 28, /* lei_f */ + 16, /* eqr_f */ + 28, /* eqi_f */ + 16, /* ger_f */ + 28, /* gei_f */ + 16, /* gtr_f */ + 28, /* gti_f */ + 16, /* ner_f */ + 28, /* nei_f */ + 16, /* unltr_f */ + 28, /* unlti_f */ + 16, /* unler_f */ + 28, /* unlei_f */ + 16, /* uneqr_f */ + 28, /* uneqi_f */ + 16, /* unger_f */ + 28, /* ungei_f */ + 16, /* ungtr_f */ + 28, /* ungti_f */ + 16, /* ltgtr_f */ + 28, /* ltgti_f */ + 16, /* ordr_f */ + 28, /* ordi_f */ + 16, /* unordr_f */ + 28, /* unordi_f */ + 8, /* truncr_f_i */ + 8, /* truncr_f_l */ + 8, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 12, /* movi_f */ + 4, /* ldr_f */ + 12, /* ldi_f */ + 8, /* ldxr_f */ + 4, /* ldxi_f */ + 4, /* str_f */ + 12, /* sti_f */ + 8, /* stxr_f */ + 4, /* stxi_f */ + 12, /* bltr_f */ + 24, /* blti_f */ + 12, /* bler_f */ + 24, /* blei_f */ + 12, /* beqr_f */ + 24, /* beqi_f */ + 12, /* bger_f */ + 24, /* bgei_f */ + 12, /* bgtr_f */ + 24, /* bgti_f */ + 12, /* bner_f */ + 24, /* bnei_f */ + 12, /* bunltr_f */ + 24, /* bunlti_f */ + 12, /* bunler_f */ + 24, /* bunlei_f */ + 12, /* buneqr_f */ + 24, /* buneqi_f */ + 12, /* bunger_f */ + 24, /* bungei_f */ + 12, /* bungtr_f */ + 24, /* bungti_f */ + 12, /* bltgtr_f */ + 24, /* bltgti_f */ + 12, /* bordr_f */ + 24, /* bordi_f */ + 12, /* bunordr_f */ + 24, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 16, /* addi_d */ + 4, /* subr_d */ + 16, /* subi_d */ + 16, /* rsbi_d */ + 4, /* mulr_d */ + 16, /* muli_d */ + 4, /* divr_d */ + 16, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 16, /* ltr_d */ + 28, /* lti_d */ + 16, /* ler_d */ + 28, /* lei_d */ + 16, /* eqr_d */ + 28, /* eqi_d */ + 16, /* ger_d */ + 28, /* gei_d */ + 16, /* gtr_d */ + 28, /* gti_d */ + 16, /* ner_d */ + 28, /* nei_d */ + 16, /* unltr_d */ + 28, /* unlti_d */ + 16, /* unler_d */ + 28, /* unlei_d */ + 16, /* uneqr_d */ + 28, /* uneqi_d */ + 16, /* unger_d */ + 28, /* ungei_d */ + 16, /* ungtr_d */ + 28, /* ungti_d */ + 16, /* ltgtr_d */ + 28, /* ltgti_d */ + 16, /* ordr_d */ + 28, /* ordi_d */ + 16, /* unordr_d */ + 28, /* unordi_d */ + 8, /* truncr_d_i */ + 8, /* truncr_d_l */ + 8, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 12, /* movi_d */ + 4, /* ldr_d */ + 12, /* ldi_d */ + 8, /* ldxr_d */ + 4, /* ldxi_d */ + 4, /* str_d */ + 12, /* sti_d */ + 8, /* stxr_d */ + 4, /* stxi_d */ + 12, /* bltr_d */ + 24, /* blti_d */ + 12, /* bler_d */ + 24, /* blei_d */ + 12, /* beqr_d */ + 24, /* beqi_d */ + 12, /* bger_d */ + 24, /* bgei_d */ + 12, /* bgtr_d */ + 24, /* bgti_d */ + 12, /* bner_d */ + 24, /* bnei_d */ + 12, /* bunltr_d */ + 24, /* bunlti_d */ + 12, /* bunler_d */ + 24, /* bunlei_d */ + 12, /* buneqr_d */ + 24, /* buneqi_d */ + 12, /* bunger_d */ + 24, /* bungei_d */ + 12, /* bungtr_d */ + 24, /* bungti_d */ + 12, /* bltgtr_d */ + 24, /* bltgti_d */ + 12, /* bordr_d */ + 24, /* bordi_d */ + 12, /* bunordr_d */ + 24, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 4, /* movr_d_w */ + 12, /* movi_d_w */ +#endif /* __WORDSIZE */ diff --git a/deps/lightning/lib/jit_mips.c b/deps/lightning/lib/jit_mips.c new file mode 100644 index 0000000..dafade8 --- /dev/null +++ b/deps/lightning/lib/jit_mips.c @@ -0,0 +1,1930 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if defined(__linux__) +# include <sys/cachectl.h> +#endif + +#if NEW_ABI +# define NUM_WORD_ARGS 8 +# define STACK_SLOT 8 +# define STACK_SHIFT 3 +#else +# define NUM_WORD_ARGS 4 +# define STACK_SLOT 4 +# define STACK_SHIFT 2 +#endif +#if NEW_ABI && __BYTE_ORDER == __BIG_ENDIAN && __WORDSIZE == 32 +# define WORD_ADJUST 4 +#else +# define WORD_ADJUST 0 +#endif +#define jit_arg_reg_p(i) ((i) >= 0 && (i) < NUM_WORD_ARGS) +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define C_DISP 0 +# define S_DISP 0 +# define I_DISP 0 +#else +# define C_DISP STACK_SLOT - sizeof(jit_int8_t) +# define S_DISP STACK_SLOT - sizeof(jit_int16_t) +# define I_DISP STACK_SLOT - sizeof(jit_int32_t) +#endif + +/* + * Types + */ +typedef struct jit_pointer_t jit_va_list_t; + +/* + * Prototypes + */ +#define jit_make_arg(node) _jit_make_arg(_jit,node) +static jit_node_t *_jit_make_arg(jit_state_t*,jit_node_t*); +#define jit_make_arg_f(node) _jit_make_arg_f(_jit,node) +static jit_node_t *_jit_make_arg_f(jit_state_t*,jit_node_t*); +#define jit_make_arg_d(node) _jit_make_arg_d(_jit,node) +static jit_node_t *_jit_make_arg_d(jit_state_t*,jit_node_t*); +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); + +#define PROTO 1 +# include "jit_rewind.c" +# include "jit_mips-cpu.c" +# include "jit_mips-fpu.c" +#undef PROTO + +/* + * Initialization + */ +jit_register_t _rvs[] = { + { rc(gpr) | 0x01, "at" }, + { rc(gpr) | 0x02, "v0" }, + { rc(gpr) | 0x03, "v1" }, +#if !NEW_ABI + { rc(gpr) | 0x08, "t0" }, + { rc(gpr) | 0x09, "t1" }, + { rc(gpr) | 0x0a, "t2" }, + { rc(gpr) | 0x0b, "t3" }, +#endif + { rc(gpr) | 0x0c, "t4" }, + { rc(gpr) | 0x0d, "t5" }, + { rc(gpr) | 0x0e, "t6" }, + { rc(gpr) | 0x0f, "t7" }, + { rc(gpr) | 0x18, "t8" }, + { rc(gpr) | 0x19, "t9" }, + { rc(sav) | rc(gpr) | 0x10, "s0" }, + { rc(sav) | rc(gpr) | 0x11, "s1" }, + { rc(sav) | rc(gpr) | 0x12, "s2" }, + { rc(sav) | rc(gpr) | 0x13, "s3" }, + { rc(sav) | rc(gpr) | 0x14, "s4" }, + { rc(sav) | rc(gpr) | 0x15, "s5" }, + { rc(sav) | rc(gpr) | 0x16, "s6" }, + { rc(sav) | rc(gpr) | 0x17, "s7" }, + { 0x00, "zero" }, + { 0x1a, "k0" }, + { 0x1b, "k1" }, + { rc(sav) | 0x1f, "ra" }, + { rc(sav) | 0x1c, "gp" }, + { rc(sav) | 0x1d, "sp" }, + { rc(sav) | 0x1e, "fp" }, +#if NEW_ABI + { rc(gpr) | 0x0b, "a7" }, + { rc(gpr) | 0x0a, "a6" }, + { rc(gpr) | 0x09, "a5" }, + { rc(gpr) | 0x08, "a4" }, +#endif + { rc(arg) | rc(gpr) | 0x07, "a3" }, + { rc(arg) | rc(gpr) | 0x06, "a2" }, + { rc(arg) | rc(gpr) | 0x05, "a1" }, + { rc(arg) | rc(gpr) | 0x04, "a0" }, + { rc(fpr) | 0x00, "$f0" }, + { rc(fpr) | 0x02, "$f2" }, + { rc(fpr) | 0x04, "$f4" }, + { rc(fpr) | 0x06, "$f6" }, + { rc(fpr) | 0x08, "$f8" }, + { rc(fpr) | 0x0a, "$f10" }, +#if !NEW_ABI + { rc(sav) | rc(fpr) | 0x10, "$f16" }, + { rc(sav) | rc(fpr) | 0x12, "$f18" }, +#endif + { rc(sav) | rc(fpr) | 0x14, "$f20" }, + { rc(sav) | rc(fpr) | 0x16, "$f22" }, + { rc(sav) | rc(fpr) | 0x18, "$f24" }, + { rc(sav) | rc(fpr) | 0x1a, "$f26" }, + { rc(sav) | rc(fpr) | 0x1c, "$f28" }, + { rc(sav) | rc(fpr) | 0x1e, "$f30" }, +#if NEW_ABI + { rc(arg) | rc(fpr) | 0x13, "$f19" }, + { rc(arg) | rc(fpr) | 0x12, "$f18" }, + { rc(arg) | rc(fpr) | 0x11, "$f17" }, + { rc(arg) | rc(fpr) | 0x10, "$f16" }, + { rc(arg) | rc(fpr) | 0x0f, "$f15" }, + { rc(arg) | rc(fpr) | 0x0e, "$f14" }, + { rc(arg) | rc(fpr) | 0x0d, "$f13" }, + { rc(arg) | rc(fpr) | 0x0c, "$f12" }, +#else + { rc(arg) | rc(fpr) | 0x0e, "$f14" }, + { rc(arg) | rc(fpr) | 0x0c, "$f12" }, +#endif + { _NOREG, "<none>" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ +} + +void +_jit_init(jit_state_t *_jit) +{ + _jitc->reglen = jit_size(_rvs) - 1; +/* Could also: + * o reserve a register for carry (overkill) + * o use MTLO/MFLO (performance hit) + * So, keep a register allocated after setting carry, and implicitly + * deallocate it if it can no longer be tracked + */ + jit_carry = _NOREG; +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + _jitc->function->self.size = stack_framesize; + _jitc->function->self.argi = _jitc->function->self.argf = + _jitc->function->self.aoff = _jitc->function->self.alen = 0; + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + assert(_jitc->function); + switch (length) { + case 0: case 1: break; + case 2: _jitc->function->self.aoff &= -2; break; + case 3: case 4: _jitc->function->self.aoff &= -4; break; + default: _jitc->function->self.aoff &= -8; break; + } + _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } + return (_jitc->function->self.aoff); +} + +void +_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) +{ + jit_int32_t reg; + assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); + if (!_jitc->function->allocar) { + _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); + _jitc->function->allocar = 1; + } + reg = jit_get_reg(jit_class_gpr); + jit_negr(reg, v); + jit_andi(reg, reg, -8); + jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); + jit_addr(u, u, reg); + jit_addr(JIT_SP, JIT_SP, reg); + jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); + jit_unget_reg(reg); + jit_dec_synth(); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + assert(_jitc->function); + jit_inc_synth(ret); + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr, u); + if (JIT_RET != u) + jit_movr(JIT_RET, u); + jit_live(JIT_RET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti(jit_state_t *_jit, jit_word_t u) +{ + jit_inc_synth_w(reti, u); + jit_movi(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_f, u); + if (JIT_FRET != u) + jit_movr_f(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_inc_synth_f(reti_f, u); + jit_movi_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_d, u); + if (JIT_FRET != u) + jit_movr_d(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_inc_synth_d(reti_d, u); + jit_movi_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_epilog(jit_state_t *_jit) +{ + assert(_jitc->function); + assert(_jitc->function->epilog->next == NULL); + jit_link(_jitc->function->epilog); + _jitc->function = NULL; +} + +jit_bool_t +_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) +{ + if (u->code == jit_code_arg) + return (jit_arg_reg_p(u->u.w)); + assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d); +#if NEW_ABI + return (jit_arg_reg_p(u->u.w)); +#else + return (u->u.w < 8); +#endif +} + +static jit_node_t * +_jit_make_arg(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t offset; +#if NEW_ABI + if (jit_arg_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += STACK_SLOT; + } +#else + offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT; + _jitc->function->self.argi = 1; + if (offset >= 4) + offset = _jitc->function->self.size; + _jitc->function->self.size += STACK_SLOT; +#endif + if (node == (jit_node_t *)0) + node = jit_new_node(jit_code_arg); + else + link_node(node); + node->u.w = offset; + node->v.w = ++_jitc->function->self.argn; + jit_link_prolog(); + return (node); +} + +static jit_node_t * +_jit_make_arg_f(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t offset; +#if NEW_ABI + if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi++; + if (_jitc->function->self.call & jit_call_varargs) + offset += 8; + } + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += STACK_SLOT; + } +#else + offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT; + if (offset < NUM_WORD_ARGS) { + if (!_jitc->function->self.argi && + !(_jitc->function->self.call & jit_call_varargs)) { + if (offset == 0) + offset = 4; + else { + offset = 6; + _jitc->function->self.argi = 1; + } + /* Use as flag to rewind in case of varargs function */ + ++_jitc->function->self.argf; + } + } + else + offset = _jitc->function->self.size; + _jitc->function->self.size += STACK_SLOT; +#endif + if (node == (jit_node_t *)0) + node = jit_new_node(jit_code_arg_f); + else + link_node(node); + node->u.w = offset; + node->v.w = ++_jitc->function->self.argn; + jit_link_prolog(); + return (node); +} + +static jit_node_t * +_jit_make_arg_d(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t offset; +#if NEW_ABI + if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi++; + if (_jitc->function->self.call & jit_call_varargs) + offset += 8; + } + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += STACK_SLOT; + } +#else + if (_jitc->function->self.size & 7) { + _jitc->function->self.size += 4; + _jitc->function->self.argi = 1; + } + offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT; + if (offset < NUM_WORD_ARGS) { + if (!_jitc->function->self.argi && + !(_jitc->function->self.call & jit_call_varargs)) { + offset += 4; + /* Use as flag to rewind in case of varargs function */ + ++_jitc->function->self.argf; + } + } + else + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_float64_t); +#endif + if (node == (jit_node_t *)0) + node = jit_new_node(jit_code_arg_d); + else + link_node(node); + node->u.w = offset; + node->v.w = ++_jitc->function->self.argn; + jit_link_prolog(); + return (node); +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + if (_jitc->prepare) { + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; +#if !NEW_ABI + if (_jitc->function->call.argf) + rewind_prepare(); +#endif + } + else { + assert(!(_jitc->function->self.call & jit_call_varargs)); +#if NEW_ABI + /* If varargs start in a register, allocate extra 64 bytes. */ + if (jit_arg_reg_p(_jitc->function->self.argi)) + rewind_prolog(); + /* Do not set during possible rewind. */ + _jitc->function->self.call |= jit_call_varargs; +#else + _jitc->function->self.call |= jit_call_varargs; + if (_jitc->function->self.argf) + rewind_prolog(); +#endif + _jitc->function->vagp = _jitc->function->self.argi; + } + jit_inc_synth(ellipsis); + if (_jitc->prepare) + jit_link_prepare(); + else + jit_link_prolog(); + jit_dec_synth(); +} + +void +_jit_va_push(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(va_push, u); + jit_pushargr(u); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + assert(_jitc->function); + return (jit_make_arg((jit_node_t*)0)); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + assert(_jitc->function); + return (jit_make_arg_f((jit_node_t*)0)); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + assert(_jitc->function); + return (jit_make_arg_d((jit_node_t*)0)); +} + +void +_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_c(u, _A0 - v->u.w); + else + jit_ldxi_c(u, _FP, v->u.w + C_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_uc(u, _A0 - v->u.w); + else + jit_ldxi_uc(u, _FP, v->u.w + C_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_s(u, _A0 - v->u.w); + else + jit_ldxi_s(u, _FP, v->u.w + S_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_us(u, _A0 - v->u.w); + else + jit_ldxi_us(u, _FP, v->u.w + S_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); + if (jit_arg_reg_p(v->u.w)) { +#if __WORDSIZE == 64 + jit_extr_i(u, _A0 - v->u.w); +#else + jit_movr(u, _A0 - v->u.w); +#endif + } + else + jit_ldxi_i(u, _FP, v->u.w + I_DISP); + jit_dec_synth(); +} + +#if __WORDSIZE == 64 +void +_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_ui(u, _A0 - v->u.w); + else + jit_ldxi_ui(u, _FP, v->u.w + I_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(u, _A0 - v->u.w); + else + jit_ldxi_l(u, _FP, v->u.w); + jit_dec_synth(); +} +#endif + +void +_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + jit_inc_synth_wp(putargr, u, v); + assert(v->code == jit_code_arg); + if (jit_arg_reg_p(v->u.w)) + jit_movr(_A0 - v->u.w, u); + else + jit_stxi(v->u.w + WORD_ADJUST, _FP, u); + jit_dec_synth(); +} + +void +_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movi(_A0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(v->u.w + WORD_ADJUST, _FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); +#if NEW_ABI + if (jit_arg_reg_p(v->u.w)) + jit_movr_f(u, _F12 - v->u.w); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_w_f(u, _A0 - v->u.w - 8); +#else + if (v->u.w < 4) + jit_movr_w_f(u, _A0 - v->u.w); + else if (v->u.w < 8) + jit_movr_f(u, _F12 - ((v->u.w - 4) >> 1)); +#endif + else + jit_ldxi_f(u, _FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); +#if NEW_ABI + if (jit_arg_reg_p(v->u.w)) + jit_movr_f(_F12 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_f_w(_A0 - v->u.w - 8, u); +#else + if (v->u.w < 4) + jit_movr_f_w(_A0 - v->u.w, u); + else if (v->u.w < 8) + jit_movr_f(_F12 - ((v->u.w - 4) >> 1), u); +#endif + else + jit_stxi_f(v->u.w, _FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); +#if NEW_ABI + if (jit_arg_reg_p(v->u.w)) + jit_movi_f(_F12 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_movr_f_w(_A0 - v->u.w - 8, u); + jit_unget_reg(regno); + } +#else + if (v->u.w < 4) { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_movr_f_w(_A0 - ((v->u.w - 4) >> 1), regno); + jit_unget_reg(regno); + } + else if (v->u.w < 8) + jit_movi_f(_F12 - ((v->u.w - 4) >> 1), u); +#endif + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(v->u.w, _FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); +#if NEW_ABI + if (jit_arg_reg_p(v->u.w)) + jit_movr_d(u, _F12 - v->u.w); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_d_w(_A0 - v->u.w - 8, u); +#else + if (v->u.w < 4) + jit_movr_ww_d(u, _A0 - v->u.w, _A0 - (v->u.w + 1)); + else if (v->u.w < 8) + jit_movr_d(u, _F12 - ((v->u.w - 4) >> 1)); +#endif + else + jit_ldxi_d(u, _FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); +#if NEW_ABI + if (jit_arg_reg_p(v->u.w)) + jit_movr_d(_F12 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_d_w(_A0 - v->u.w - 8, u); +#else + if (v->u.w < 4) + jit_movr_d_ww(_A0 - v->u.w, _A0 - (v->u.w + 1), u); + else if (v->u.w < 8) + jit_movr_d(_F12 - ((v->u.w - 4) >> 1), u); +#endif + else + jit_stxi_d(v->u.w, _FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); +#if NEW_ABI + if (jit_arg_reg_p(v->u.w)) + jit_movi_d(_F12 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_movr_d_w(_A0 - v->u.w - 8, u); + jit_unget_reg(regno); + } +#else + if (v->u.w < 4) { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_movr_d_ww(_A0 - v->u.w, _A0 - (v->u.w + 1), regno); + jit_unget_reg(regno); + } + else if (v->u.w < 8) + jit_movi_d(_F12 - ((v->u.w - 4) >> 1), u); +#endif + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(v->u.w, _FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); +#if NEW_ABI + assert(_jitc->function); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi(_jitc->function->call.size + WORD_ADJUST, JIT_SP, u); + _jitc->function->call.size += STACK_SLOT; + } +#else + jit_word_t offset; + assert(_jitc->function); + offset = _jitc->function->call.size >> STACK_SHIFT; + _jitc->function->call.argi = 1; + if (jit_arg_reg_p(offset)) + jit_movr(_A0 - offset, u); + else + jit_stxi(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += STACK_SLOT; +#endif + jit_dec_synth(); +} + +void +_jit_pushargi(jit_state_t *_jit, jit_word_t u) +{ + jit_int32_t regno; +#if !NEW_ABI + jit_word_t offset; +#endif + assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); +#if NEW_ABI + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size + WORD_ADJUST, JIT_SP, regno); + _jitc->function->call.size += STACK_SLOT; + jit_unget_reg(regno); + } +#else + offset = _jitc->function->call.size >> STACK_SHIFT; + ++_jitc->function->call.argi; + if (jit_arg_reg_p(offset)) + jit_movi(_A0 - offset, u); + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + } + _jitc->function->call.size += STACK_SLOT; +#endif + jit_dec_synth(); +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ +#if !NEW_ABI + jit_word_t offset; +#endif + assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); +#if NEW_ABI + if (jit_arg_reg_p(_jitc->function->call.argi)) { + if (!(_jitc->function->call.call & jit_call_varargs)) + jit_movr_f(_F12 - _jitc->function->call.argi, u); + else + jit_movr_f_w(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi_f(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += STACK_SLOT; + } +#else + offset = _jitc->function->call.size >> STACK_SHIFT; + if (offset < 2 && !_jitc->function->call.argi && + !(_jitc->function->call.call & jit_call_varargs)) { + ++_jitc->function->call.argf; + jit_movr_f(_F12 - offset, u); + } + else if (offset < 4) { + ++_jitc->function->call.argi; + jit_movr_f_w(_A0 - offset, u); + } + else + jit_stxi_f(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += STACK_SLOT; +#endif + jit_dec_synth(); +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_int32_t regno; +#if !NEW_ABI + jit_word_t offset; +#endif + assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); +#if NEW_ABI + if (jit_arg_reg_p(_jitc->function->call.argi)) { + if (!(_jitc->function->call.call & jit_call_varargs)) + jit_movi_f(_F12 - _jitc->function->call.argi, u); + else + jit_movi_f_w(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(_jitc->function->call.size, JIT_SP, regno); + _jitc->function->call.size += STACK_SLOT; + jit_unget_reg(regno); + } +#else + offset = _jitc->function->call.size >> STACK_SHIFT; + if (offset < 2 && !_jitc->function->call.argi && + !(_jitc->function->call.call & jit_call_varargs)) { + ++_jitc->function->call.argf; + jit_movi_f(_F12 - offset, u); + } + else if (offset < 4) { + ++_jitc->function->call.argi; + jit_movi_f_w(_A0 - offset, u); + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + } + _jitc->function->call.size += STACK_SLOT; +#endif + jit_dec_synth(); +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ +#if !NEW_ABI + jit_bool_t adjust; + jit_word_t offset; +#endif + assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); +#if NEW_ABI + if (jit_arg_reg_p(_jitc->function->call.argi)) { + if (!(_jitc->function->call.call & jit_call_varargs)) + jit_movr_d(_F12 - _jitc->function->call.argi, u); + else + jit_movr_d_w(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi_d(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += STACK_SLOT; + } +#else + adjust = !!_jitc->function->call.argi; + if (_jitc->function->call.size & 7) { + _jitc->function->call.size += 4; + adjust = 1; + } + offset = _jitc->function->call.size >> STACK_SHIFT; + if (offset < 3) { + if (adjust || (_jitc->function->call.call & jit_call_varargs)) { + jit_movr_d_ww(_A0 - offset, _A0 - (offset + 1), u); + _jitc->function->call.argi += 2; + } + else { + jit_movr_d(_F12 - (offset >> 1), u); + ++_jitc->function->call.argf; + } + } + else + jit_stxi_d(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_float64_t); +#endif + jit_dec_synth(); +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; +#if !NEW_ABI + jit_bool_t adjust; + jit_word_t offset; +#endif + assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); +#if NEW_ABI + if (jit_arg_reg_p(_jitc->function->call.argi)) { + if (!(_jitc->function->call.call & jit_call_varargs)) + jit_movi_d(_F12 - _jitc->function->call.argi, u); + else + jit_movi_d_w(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(_jitc->function->call.size, JIT_SP, regno); + _jitc->function->call.size += STACK_SLOT; + jit_unget_reg(regno); + } +#else + adjust = !!_jitc->function->call.argi; + if (_jitc->function->call.size & 7) { + _jitc->function->call.size += 4; + adjust = 1; + } + offset = _jitc->function->call.size >> STACK_SHIFT; + if (offset < 3) { + if (adjust || (_jitc->function->call.call & jit_call_varargs)) { + jit_movi_d_ww(_A0 - offset, _A0 - (offset + 1), u); + _jitc->function->call.argi += 2; + } + else { + jit_movi_d(_F12 - (offset >> 1), u); + ++_jitc->function->call.argf; + } + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + } + _jitc->function->call.size += sizeof(jit_float64_t); +#endif + jit_dec_synth(); +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + jit_int32_t spec; + + spec = jit_class(_rvs[regno].spec); + if (spec & jit_class_arg) { + if (spec & jit_class_gpr) { + regno = _A0 - regno; + if (regno >= 0 && regno < node->v.w) + return (1); + } + else if (spec & jit_class_fpr) { + regno = _F12 - regno; + if (regno >= 0 && regno < node->w.w) + return (1); + } + } + + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_node_t *call; + assert(_jitc->function); + jit_inc_synth_w(finishr, r0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + jit_movr(_T9, r0); + call = jit_callr(_T9); + call->v.w = _jitc->function->self.argi; +#if NEW_ABI + call->w.w = call->v.w; +#else + call->w.w = _jitc->function->self.argf; +#endif + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ + jit_node_t *call; + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_movi(_T9, (jit_word_t)i0); + call = jit_callr(_T9); + call->v.w = _jitc->function->call.argi; +#if NEW_ABI + call->w.w = call->v.w; +#else + call->w.w = _jitc->function->call.argf; +#endif + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); + return (node); +} + +void +_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) +{ + jit_extr_c(r0, JIT_RET); +} + +void +_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) +{ + jit_extr_uc(r0, JIT_RET); +} + +void +_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) +{ + jit_extr_s(r0, JIT_RET); +} + +void +_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) +{ + jit_extr_us(r0, JIT_RET); +} + +void +_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) +{ +#if __WORDSIZE == 32 + if (r0 != JIT_RET) + jit_movr(r0, JIT_RET); +#else + jit_extr_i(r0, JIT_RET); +#endif +} + +#if __WORDSIZE == 64 +void +_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) +{ + jit_extr_ui(r0, JIT_RET); +} + +void +_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) +{ + if (r0 != JIT_RET) + jit_movr(r0, JIT_RET); +} +#endif + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + if (r0 != JIT_FRET) + jit_movr_f(r0, JIT_FRET); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + if (r0 != JIT_FRET) + jit_movr_d(r0, JIT_FRET); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_int32_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + jit_int32_t patch_offset; + } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + + _jitc->function = NULL; + + jit_reglive_setup(); + + undo.word = 0; + undo.node = NULL; + undo.patch_offset = 0; +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_rrf(name, type, size) \ + case jit_code_##name##i##type: \ + assert(node->flag & jit_flag_data); \ + name##i##type(rn(node->u.w), rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type(_jit->pc.w, \ + rn(node->v.w), rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break +#define case_brf(name, type, size) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + else { \ + word = name##i##type(_jit->pc.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + patch(word, node); \ + } \ + break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end) + return (NULL); + +#if DEVEL_DISASSEMBLER + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; +#endif + value = jit_classify(node->code); + jit_regarg_set(node, value); + switch (node->code) { + case jit_code_align: + assert(!(node->u.w & (node->u.w - 1)) && + node->u.w <= sizeof(jit_word_t)); + if (node->u.w == sizeof(jit_word_t) && + (word = _jit->pc.w & (sizeof(jit_word_t) - 1))) + nop(sizeof(jit_word_t) - word); + break; + case jit_code_note: case jit_code_name: + node->u.w = _jit->pc.w; + break; + case jit_code_label: + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + break; + case_rrr(add,); + case_rrw(add,); + case_rrr(addc,); + case_rrw(addc,); + case_rrr(addx,); + case_rrw(addx,); + case_rrr(sub,); + case_rrw(sub,); + case_rrr(subc,); + case_rrw(subc,); + case_rrr(subx,); + case_rrw(subx,); + case_rrw(rsb,); + case_rrr(mul,); + case_rrw(mul,); + case_rrrr(qmul,); + case_rrrw(qmul,); + case_rrrr(qmul, _u); + case_rrrw(qmul, _u); + case_rrr(div,); + case_rrw(div,); + case_rrr(div, _u); + case_rrw(div, _u); + case_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_rr(trunc, _f_i); + case_rr(trunc, _d_i); +#if __WORDSIZE == 64 + case_rr(trunc, _f_l); + case_rr(trunc, _d_l); +#endif + case_rr(ld, _c); + case_rw(ld, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rr(ld, _i); + case_rw(ld, _i); +#if __WORDSIZE == 64 + case_rr(ld, _ui); + case_rw(ld, _ui); + case_rr(ld, _l); + case_rw(ld, _l); +#endif + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rrr(ldx, _i); + case_rrw(ldx, _i); +#if __WORDSIZE == 64 + case_rrr(ldx, _ui); + case_rrw(ldx, _ui); + case_rrr(ldx, _l); + case_rrw(ldx, _l); +#endif + case_rr(st, _c); + case_wr(st, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rr(st, _i); + case_wr(st, _i); +#if __WORDSIZE == 64 + case_rr(st, _l); + case_wr(st, _l); +#endif + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rrr(stx, _i); + case_wrr(stx, _i); +#if __WORDSIZE == 64 + case_rrr(stx, _l); + case_wrr(stx, _l); +#endif + case_rr(hton, _us); + case_rr(hton, _ui); +#if __WORDSIZE == 64 + case_rr(hton, _ul); +#endif + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); +#if __WORDSIZE == 64 + case_rr(ext, _i); + case_rr(ext, _ui); +#endif + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), node->v.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rr(neg,); + case_rr(com,); + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_rrr(add, _f); + case_rrf(add, _f, 32); + case_rrr(sub, _f); + case_rrf(sub, _f, 32); + case_rrf(rsb, _f, 32); + case_rrr(mul, _f); + case_rrf(mul, _f, 32); + case_rrr(div, _f); + case_rrf(div, _f, 32); + case_rr(abs, _f); + case_rr(neg, _f); + case_rr(sqrt, _f); + case_rr(ext, _f); + case_rr(ld, _f); + case_rw(ld, _f); + case_rrr(ldx, _f); + case_rrw(ldx, _f); + case_rr(st, _f); + case_wr(st, _f); + case_rrr(stx, _f); + case_wrr(stx, _f); + case_rr(mov, _f); + case jit_code_movi_f: + assert(node->flag & jit_flag_data); + movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); + break; + case_rr(ext, _d_f); + case_rrr(lt, _f); + case_rrf(lt, _f, 32); + case_rrr(le, _f); + case_rrf(le, _f, 32); + case_rrr(eq, _f); + case_rrf(eq, _f, 32); + case_rrr(ge, _f); + case_rrf(ge, _f, 32); + case_rrr(gt, _f); + case_rrf(gt, _f, 32); + case_rrr(ne, _f); + case_rrf(ne, _f, 32); + case_rrr(unlt, _f); + case_rrf(unlt, _f, 32); + case_rrr(unle, _f); + case_rrf(unle, _f, 32); + case_rrr(uneq, _f); + case_rrf(uneq, _f, 32); + case_rrr(unge, _f); + case_rrf(unge, _f, 32); + case_rrr(ungt, _f); + case_rrf(ungt, _f, 32); + case_rrr(ltgt, _f); + case_rrf(ltgt, _f, 32); + case_rrr(ord, _f); + case_rrf(ord, _f, 32); + case_rrr(unord, _f); + case_rrf(unord, _f, 32); + case_brr(blt, _f); + case_brf(blt, _f, 32); + case_brr(ble, _f); + case_brf(ble, _f, 32); + case_brr(beq, _f); + case_brf(beq, _f, 32); + case_brr(bge, _f); + case_brf(bge, _f, 32); + case_brr(bgt, _f); + case_brf(bgt, _f, 32); + case_brr(bne, _f); + case_brf(bne, _f, 32); + case_brr(bunlt, _f); + case_brf(bunlt, _f, 32); + case_brr(bunle, _f); + case_brf(bunle, _f, 32); + case_brr(buneq, _f); + case_brf(buneq, _f, 32); + case_brr(bunge, _f); + case_brf(bunge, _f, 32); + case_brr(bungt, _f); + case_brf(bungt, _f, 32); + case_brr(bltgt, _f); + case_brf(bltgt, _f, 32); + case_brr(bord, _f); + case_brf(bord, _f, 32); + case_brr(bunord, _f); + case_brf(bunord, _f, 32); + case_rrr(add, _d); + case_rrf(add, _d, 64); + case_rrr(sub, _d); + case_rrf(sub, _d, 64); + case_rrf(rsb, _d, 64); + case_rrr(mul, _d); + case_rrf(mul, _d, 64); + case_rrr(div, _d); + case_rrf(div, _d, 64); + case_rr(abs, _d); + case_rr(neg, _d); + case_rr(sqrt, _d); + case_rr(ext, _d); + case_rr(ld, _d); + case_rw(ld, _d); + case_rrr(ldx, _d); + case_rrw(ldx, _d); + case_rr(st, _d); + case_wr(st, _d); + case_rrr(stx, _d); + case_wrr(stx, _d); + case_rr(mov, _d); + case jit_code_movi_d: + assert(node->flag & jit_flag_data); + movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w); + break; + case_rr(ext, _f_d); + case_rrr(lt, _d); + case_rrf(lt, _d, 64); + case_rrr(le, _d); + case_rrf(le, _d, 64); + case_rrr(eq, _d); + case_rrf(eq, _d, 64); + case_rrr(ge, _d); + case_rrf(ge, _d, 64); + case_rrr(gt, _d); + case_rrf(gt, _d, 64); + case_rrr(ne, _d); + case_rrf(ne, _d, 64); + case_rrr(unlt, _d); + case_rrf(unlt, _d, 64); + case_rrr(unle, _d); + case_rrf(unle, _d, 64); + case_rrr(uneq, _d); + case_rrf(uneq, _d, 64); + case_rrr(unge, _d); + case_rrf(unge, _d, 64); + case_rrr(ungt, _d); + case_rrf(ungt, _d, 64); + case_rrr(ltgt, _d); + case_rrf(ltgt, _d, 64); + case_rrr(ord, _d); + case_rrf(ord, _d, 64); + case_rrr(unord, _d); + case_rrf(unord, _d, 64); + case_brr(blt, _d); + case_brf(blt, _d, 64); + case_brr(ble, _d); + case_brf(ble, _d, 64); + case_brr(beq, _d); + case_brf(beq, _d, 64); + case_brr(bge, _d); + case_brf(bge, _d, 64); + case_brr(bgt, _d); + case_brf(bgt, _d, 64); + case_brr(bne, _d); + case_brf(bne, _d, 64); + case_brr(bunlt, _d); + case_brf(bunlt, _d, 64); + case_brr(bunle, _d); + case_brf(bunle, _d, 64); + case_brr(buneq, _d); + case_brf(buneq, _d, 64); + case_brr(bunge, _d); + case_brf(bunge, _d, 64); + case_brr(bungt, _d); + case_brf(bungt, _d, 64); + case_brr(bltgt, _d); + case_brf(bltgt, _d, 64); + case_brr(bord, _d); + case_brf(bord, _d, 64); + case_brr(bunord, _d); + case_brf(bunord, _d, 64); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + break; + case jit_code_jmpi: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi(_jit->pc.w); + patch(word, node); + } + } + else + jmpi(node->u.w); + break; + case jit_code_callr: + callr(rn(node->u.w)); + break; + case jit_code_calli: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = calli_p(temp->u.w); + if (!(temp->flag & jit_flag_patch)) + patch(word, node); + } + else + calli(node->u.w); + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif + undo.patch_offset = _jitc->patches.offset; + restart_function: + _jitc->again = 0; + prolog(node); + break; + case jit_code_epilog: + assert(_jitc->function == _jitc->functions.ptr + node->w.w); + if (_jitc->again) { + for (temp = undo.node->next; + temp != node; temp = temp->next) { + if (temp->code == jit_code_label || + temp->code == jit_code_epilog) + temp->flag &= ~jit_flag_patch; + } + temp->flag &= ~jit_flag_patch; + node = undo.node; + _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif + _jitc->patches.offset = undo.patch_offset; + goto restart_function; + } + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + epilog(node); + _jitc->function = NULL; + break; +#if !NEW_ABI + case jit_code_movr_w_f: + movr_w_f(rn(node->u.w), rn(node->v.w)); + break; +#endif + case jit_code_movr_f_w: + movr_f_w(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movi_f_w: + assert(node->flag & jit_flag_data); + movi_f_w(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); + break; +#if NEW_ABI + case jit_code_movr_d_w: + movr_d_w(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movi_d_w: + assert(node->flag & jit_flag_data); + movi_d_w(rn(node->u.w), (jit_float64_t *)node->v.n->u.w); + break; +#else + case jit_code_movr_ww_d: + movr_ww_d(rn(node->u.w), rn(node->v.w), rn(node->w.w)); + break; + case jit_code_movr_d_ww: + movr_d_ww(rn(node->u.w), rn(node->v.w), rn(node->w.w)); + break; + case jit_code_movi_d_ww: + assert(node->flag & jit_flag_data); + movi_d_ww(rn(node->u.w), rn(node->v.w), + (jit_float64_t *)node->w.n->u.w); + break; +#endif + case jit_code_va_start: + vastart(rn(node->u.w)); + break; + case jit_code_va_arg: + vaarg(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_va_arg_d: + vaarg_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_live: + case jit_code_arg: case jit_code_ellipsis: + case jit_code_va_push: + case jit_code_allocai: case jit_code_allocar: + case jit_code_arg_f: case jit_code_arg_d: + case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: +#if __WORDSIZE == 64 + case jit_code_getarg_ui: case jit_code_getarg_l: +#endif + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: +#if __WORDSIZE == 64 + case jit_code_retval_ui: case jit_code_retval_l: +#endif + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: + break; + default: + abort(); + } + if (jit_carry != _NOREG) { + switch (node->code) { + case jit_code_note: + case jit_code_addcr: case jit_code_addci: + case jit_code_addxr: case jit_code_addxi: + case jit_code_subcr: case jit_code_subci: + case jit_code_subxr: case jit_code_subxi: + break; + default: + jit_unget_reg(jit_carry); + jit_carry = _NOREG; + break; + } + } + jit_regarg_clr(node, value); + assert(_jitc->regarg == 0 || + (jit_carry != _NOREG && _jitc->regarg == (1 << jit_carry))); + assert(_jitc->synth == 0); + /* update register live state */ + jit_reglive(node); + } +#undef case_brf +#undef case_brw +#undef case_brr +#undef case_wrr +#undef case_rrf +#undef case_rrw +#undef case_rrr +#undef case_wr +#undef case_rw +#undef case_rr + + for (offset = 0; offset < _jitc->patches.offset; offset++) { + node = _jitc->patches.ptr[offset].node; + word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(_jitc->patches.ptr[offset].inst, word); + } + + jit_flush(_jit->code.ptr, _jit->pc.uc); + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_rewind.c" +# include "jit_mips-cpu.c" +# include "jit_mips-fpu.c" +#undef CODE + +void +jit_flush(void *fptr, void *tptr) +{ +#if defined(__linux__) + jit_word_t f, t, s; + + s = sysconf(_SC_PAGE_SIZE); + f = (jit_word_t)fptr & -s; + t = (((jit_word_t)tptr) + s - 1) & -s; + _flush_cache((void *)f, t - f, ICACHE); +#endif +} + +void +_emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi(rn(r0), rn(r1), i0); +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi(i0, rn(r0), rn(r1)); +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi_d(rn(r0), rn(r1), i0); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi_d(i0, rn(r0), rn(r1)); +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) + flag = node->v.n->flag; + else + flag = node->u.n->flag; + assert(!(flag & jit_flag_patch)); + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} diff --git a/deps/lightning/lib/jit_names.c b/deps/lightning/lib/jit_names.c new file mode 100644 index 0000000..475bc96 --- /dev/null +++ b/deps/lightning/lib/jit_names.c @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2014-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +static char *code_name[] = { + "data", + "live", "align", + "save", "load", + "#name", "#note", + "label", + "prolog", + "ellipsis", "va_push", + "allocai", "allocar", + "arg", + "getarg_c", "getarg_uc", + "getarg_s", "getarg_us", + "getarg_i", "getarg_ui", + "getarg_l", + "putargr", "putargi", + "va_start", + "va_arg", "va_arg_d", + "va_end", + "addr", "addi", + "addcr", "addci", + "addxr", "addxi", + "subr", "subi", + "subcr", "subci", + "subxr", "subxi", + "rsbi", + "mulr", "muli", + "qmulr", "qmuli", + "qmulr_u", "qmuli_u", + "divr", "divi", + "divr_u", "divi_u", + "qdivr", "qdivi", + "qdivr_u", "qdivi_u", + "remr", "remi", + "remr_u", "remi_u", + "andr", "andi", + "orr", "ori", + "xorr", "xori", + "lshr", "lshi", + "rshr", "rshi", + "rshr_u", "rshi_u", + "negr", "comr", + "ltr", "lti", + "ltr_u", "lti_u", + "ler", "lei", + "ler_u", "lei_u", + "eqr", "eqi", + "ger", "gei", + "ger_u", "gei_u", + "gtr", "gti", + "gtr_u", "gti_u", + "ner", "nei", + "movr", "movi", + "extr_c", "extr_uc", + "extr_s", "extr_us", + "extr_i", "extr_ui", + "htonr_us", + "htonr_ui", "htonr_ul", + "ldr_c", "ldi_c", + "ldr_uc", "ldi_uc", + "ldr_s", "ldi_s", + "ldr_us", "ldi_us", + "ldr_i", "ldi_i", + "ldr_ui", "ldi_ui", + "ldr_l", "ldi_l", + "ldxr_c", "ldxi_c", + "ldxr_uc", "ldxi_uc", + "ldxr_s", "ldxi_s", + "ldxr_us", "ldxi_us", + "ldxr_i", "ldxi_i", + "ldxr_ui", "ldxi_ui", + "ldxr_l", "ldxi_l", + "str_c", "sti_c", + "str_s", "sti_s", + "str_i", "sti_i", + "str_l", "sti_l", + "stxr_c", "stxi_c", + "stxr_s", "stxi_s", + "stxr_i", "stxi_i", + "stxr_l", "stxi_l", + "bltr", "blti", + "bltr_u", "blti_u", + "bler", "blei", + "bler_u", "blei_u", + "beqr", "beqi", + "bger", "bgei", + "bger_u", "bgei_u", + "bgtr", "bgti", + "bgtr_u", "bgti_u", + "bner", "bnei", + "bmsr", "bmsi", + "bmcr", "bmci", + "boaddr", "boaddi", + "boaddr_u", "boaddi_u", + "bxaddr", "bxaddi", + "bxaddr_u", "bxaddi_u", + "bosubr", "bosubi", + "bosubr_u", "bosubi_u", + "bxsubr", "bxsubi", + "bxsubr_u", "bxsubi_u", + "jmpr", "jmpi", + "callr", "calli", + "prepare", + "pushargr", "pushargi", + "finishr", "finishi", + "ret", + "retr", "reti", + "retval_c", "retval_uc", + "retval_s", "retval_us", + "retval_i", "retval_ui", + "retval_l", + "epilog", + "arg_f", "getarg_f", + "putargr_f", "putargi_f", + "addr_f", "addi_f", + "subr_f", "subi_f", + "rsbi_f", + "mulr_f", "muli_f", + "divr_f", "divi_f", + "negr_f", "absr_f", + "sqrtr_f", + "ltr_f", "lti_f", + "ler_f", "lei_f", + "eqr_f", "eqi_f", + "ger_f", "gei_f", + "gtr_f", "gti_f", + "ner_f", "nei_f", + "unltr_f", "unlti_f", + "unler_f", "unlei_f", + "uneqr_f", "uneqi_f", + "unger_f", "ungei_f", + "ungtr_f", "ungti_f", + "ltgtr_f", "ltgti_f", + "ordr_f", "ordi_f", + "unordr_f", "unordi_f", + "truncr_f_i", "truncr_f_l", + "extr_f", "extr_d_f", + "movr_f", "movi_f", + "ldr_f", "ldi_f", + "ldxr_f", "ldxi_f", + "str_f", "sti_f", + "stxr_f", "stxi_f", + "bltr_f", "blti_f", + "bler_f", "blei_f", + "beqr_f", "beqi_f", + "bger_f", "bgei_f", + "bgtr_f", "bgti_f", + "bner_f", "bnei_f", + "bunltr_f", "bunlti_f", + "bunler_f", "bunlei_f", + "buneqr_f", "buneqi_f", + "bunger_f", "bungei_f", + "bungtr_f", "bungti_f", + "bltgtr_f", "bltgti_f", + "bordr_f", "bordi_f", + "bunordr_f", "bunordi_f", + "pushargr_f", "pushargi_f", + "retr_f", "reti_f", + "retval_f", + "arg_d", "getarg_d", + "putargr_d", "putargi_d", + "addr_d", "addi_d", + "subr_d", "subi_d", + "rsbi_d", + "mulr_d", "muli_d", + "divr_d", "divi_d", + "negr_d", "absr_d", + "sqrtr_d", + "ltr_d", "lti_d", + "ler_d", "lei_d", + "eqr_d", "eqi_d", + "ger_d", "gei_d", + "gtr_d", "gti_d", + "ner_d", "nei_d", + "unltr_d", "unlti_d", + "unler_d", "unlei_d", + "uneqr_d", "uneqi_d", + "unger_d", "ungei_d", + "ungtr_d", "ungti_d", + "ltgtr_d", "ltgti_d", + "ordr_d", "ordi_d", + "unordr_d", "unordi_d", + "truncr_d_i", "truncr_d_l", + "extr_d", "extr_f_d", + "movr_d", "movi_d", + "ldr_d", "ldi_d", + "ldxr_d", "ldxi_d", + "str_d", "sti_d", + "stxr_d", "stxi_d", + "bltr_d", "blti_d", + "bler_d", "blei_d", + "beqr_d", "beqi_d", + "bger_d", "bgei_d", + "bgtr_d", "bgti_d", + "bner_d", "bnei_d", + "bunltr_d", "bunlti_d", + "bunler_d", "bunlei_d", + "buneqr_d", "buneqi_d", + "bunger_d", "bungei_d", + "bungtr_d", "bungti_d", + "bltgtr_d", "bltgti_d", + "bordr_d", "bordi_d", + "bunordr_d", "bunordi_d", + "pushargr_d", "pushargi_d", + "retr_d", "reti_d", + "retval_d", + "movr_w_f", "movr_ww_d", + "movr_w_d", + "movr_f_w", "movi_f_w", + "movr_d_ww", "movi_d_ww", + "movr_d_w", "movi_d_w", +}; diff --git a/deps/lightning/lib/jit_note.c b/deps/lightning/lib/jit_note.c new file mode 100644 index 0000000..c79b818 --- /dev/null +++ b/deps/lightning/lib/jit_note.c @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include <lightning.h> +#include <lightning/jit_private.h> + +/* + * Prototypes + */ +#define new_note(u, v) _new_note(_jit, u, v) +static jit_note_t *_new_note(jit_state_t *, jit_uint8_t*, char*); +static void new_line(jit_int32_t,jit_note_t*,char*,jit_int32_t,jit_int32_t); +#define note_search_index(u) _note_search_index(_jit, u) +static jit_int32_t _note_search_index(jit_state_t*, jit_uint8_t*); +static jit_int32_t line_insert_index(jit_note_t*,jit_int32_t); +static jit_int32_t line_search_index(jit_note_t*,jit_int32_t); +static jit_int32_t offset_insert_index(jit_line_t*,jit_int32_t); +static jit_int32_t offset_search_index(jit_line_t*,jit_int32_t); + +/* + * Implementation + */ +void +jit_init_note(void) +{ +} + +void +jit_finish_note(void) +{ +} + +jit_node_t * +_jit_name(jit_state_t *_jit, const char *name) +{ + jit_node_t *node; + + node = jit_new_node(jit_code_name); + if (name) + node->v.n = jit_data(name, strlen(name) + 1, 1); + else + node->v.p = NULL; + if (_jitc->note.head == NULL) + _jitc->note.head = _jitc->note.tail = node; + else { + _jitc->note.tail->link = node; + _jitc->note.tail = node; + } + ++_jit->note.length; + _jitc->note.size += sizeof(jit_note_t); + /* remember previous note is invalid due to name change */ + _jitc->note.note = NULL; + return (_jitc->note.name = node); +} + +jit_node_t * +_jit_note(jit_state_t *_jit, const char *name, int line) +{ + jit_node_t *node; + + node = jit_new_node(jit_code_note); + if (name) + node->v.n = jit_data(name, strlen(name) + 1, 1); + else + node->v.p = NULL; + node->w.w = line; + if (_jitc->note.head == NULL) + _jitc->note.head = _jitc->note.tail = node; + else { + _jitc->note.tail->link = node; + _jitc->note.tail = node; + } + if (_jitc->note.note == NULL || + (name == NULL && _jitc->note.note != NULL) || + (name != NULL && _jitc->note.note == NULL) || + (name != NULL && _jitc->note.note != NULL && + strcmp(name, (char *)_jitc->data.ptr + _jitc->note.note->v.n->u.w))) + _jitc->note.size += sizeof(jit_line_t); + _jitc->note.size += sizeof(jit_int32_t) * 2; + return (_jitc->note.note = node); +} + +void +_jit_annotate(jit_state_t *_jit) +{ + jit_node_t *node; + jit_note_t *note; + jit_line_t *line; + jit_word_t length; + jit_word_t note_offset; + jit_word_t line_offset; + + /* initialize pointers in mmaped data area */ + _jit->note.ptr = (jit_note_t *)_jitc->note.base; + _jit->note.length = 0; + + note = NULL; + for (node = _jitc->note.head; node; node = node->link) { + if (node->code == jit_code_name) + note = new_note(node->u.p, node->v.p ? node->v.n->u.p : NULL); + else if (node->v.p) { + if (note == NULL) + note = new_note(node->u.p, NULL); + jit_set_note(note, node->v.n->u.p, node->w.w, + (jit_uint8_t *)node->u.p - note->code); + } + } + /* last note */ + if (note) + note->size = _jit->pc.uc - note->code; + + /* annotations may be very complex with conditions to extend + * or ignore redundant notes, as well as add entries to earlier + * notes, so, relocate the information to the data buffer, + * with likely over allocated reserved space */ + + /* relocate jit_line_t objects */ + for (note_offset = 0; note_offset < _jit->note.length; note_offset++) { + note = _jit->note.ptr + note_offset; + if ((length = sizeof(jit_line_t) * note->length) == 0) + continue; + assert(_jitc->note.base + length < _jit->data.ptr + _jit->data.length); + jit_memcpy(_jitc->note.base, note->lines, length); + jit_free((jit_pointer_t *)¬e->lines); + note->lines = (jit_line_t *)_jitc->note.base; + _jitc->note.base += length; + } + + /* relocate offset and line number information */ + for (note_offset = 0; note_offset < _jit->note.length; note_offset++) { + note = _jit->note.ptr + note_offset; + for (line_offset = 0; line_offset < note->length; line_offset++) { + line = note->lines + line_offset; + length = sizeof(jit_int32_t) * line->length; + assert(_jitc->note.base + length < + _jit->data.ptr + _jit->data.length); + jit_memcpy(_jitc->note.base, line->linenos, length); + jit_free((jit_pointer_t *)&line->linenos); + line->linenos = (jit_int32_t *)_jitc->note.base; + _jitc->note.base += length; + assert(_jitc->note.base + length < + _jit->data.ptr + _jit->data.length); + jit_memcpy(_jitc->note.base, line->offsets, length); + jit_free((jit_pointer_t *)&line->offsets); + line->offsets = (jit_int32_t *)_jitc->note.base; + _jitc->note.base += length; + } + } +} + +void +_jit_set_note(jit_state_t *_jit, jit_note_t *note, + char *file, int lineno, jit_int32_t offset) +{ + jit_line_t *line; + jit_int32_t index; + + index = line_insert_index(note, offset); + if (note->length && index == note->length && + note->lines[index - 1].file == file) + --index; + if (index >= note->length || note->lines[index].file != file) + new_line(index, note, file, lineno, offset); + else { + line = note->lines + index; + index = offset_insert_index(line, offset); + if (index < line->length && line->offsets[index] == offset) { + /* common case if no code was generated for several source lines */ + if (line->linenos[index] < lineno) + line->linenos[index] = lineno; + } + else if (index < line->length && line->linenos[index] == lineno) { + /* common case of extending entry */ + if (line->offsets[index] > offset) + line->offsets[index] = offset; + } + else { + /* line or offset changed */ + if ((line->length & 15) == 0) { + jit_realloc((jit_pointer_t *)&line->linenos, + line->length * sizeof(jit_int32_t), + (line->length + 17) * sizeof(jit_int32_t)); + jit_realloc((jit_pointer_t *)&line->offsets, + line->length * sizeof(jit_int32_t), + (line->length + 17) * sizeof(jit_int32_t)); + } + if (index < note->length) { + jit_memmove(line->linenos + index + 1, line->linenos + index, + sizeof(jit_int32_t) * (line->length - index)); + jit_memmove(line->offsets + index + 1, line->offsets + index, + sizeof(jit_int32_t) * (line->length - index)); + } + line->linenos[index] = lineno; + line->offsets[index] = offset; + ++line->length; + } + } +} + +jit_bool_t +_jit_get_note(jit_state_t *_jit, jit_pointer_t code, + char **name, char **file, jit_int32_t *lineno) +{ + jit_note_t *note; + jit_line_t *line; + jit_int32_t index; + jit_int32_t offset; + + if ((index = note_search_index((jit_uint8_t *)code)) >= _jit->note.length) + return (0); + note = _jit->note.ptr + index; + if ((jit_uint8_t *)code < note->code || + (jit_uint8_t *)code >= note->code + note->size) + return (0); + offset = (jit_uint8_t *)code - note->code; + if ((index = line_search_index(note, offset)) >= note->length) + return (0); + if (index == 0 && offset < note->lines[0].offsets[0]) + return (0); + line = note->lines + index; + if ((index = offset_search_index(line, offset)) >= line->length) + return (0); + + if (name) + *name = note->name; + if (file) + *file = line->file; + if (lineno) + *lineno = line->linenos[index]; + + return (1); +} + +static jit_note_t * +_new_note(jit_state_t *_jit, jit_uint8_t *code, char *name) +{ + jit_note_t *note; + jit_note_t *prev; + + if (_jit->note.length) { + prev = _jit->note.ptr + _jit->note.length - 1; + assert(code >= prev->code); + prev->size = code - prev->code; + } + note = (jit_note_t *)_jitc->note.base; + _jitc->note.base += sizeof(jit_note_t); + ++_jit->note.length; + note->code = code; + note->name = name; + + return (note); +} + +static void +new_line(jit_int32_t index, jit_note_t *note, + char *file, jit_int32_t lineno, jit_int32_t offset) +{ + jit_line_t *line; + + if (note->lines == NULL) + jit_alloc((jit_pointer_t *)¬e->lines, 16 * sizeof(jit_line_t)); + else if ((note->length & 15) == 15) + jit_realloc((jit_pointer_t *)¬e->lines, + note->length * sizeof(jit_line_t), + (note->length + 17) * sizeof(jit_line_t)); + + if (index < note->length) + jit_memmove(note->lines + index + 1, note->lines + index, + sizeof(jit_line_t) * (note->length - index)); + line = note->lines + index; + ++note->length; + + line->file = file; + line->length = 1; + jit_alloc((jit_pointer_t *)&line->linenos, 16 * sizeof(jit_int32_t)); + line->linenos[0] = lineno; + jit_alloc((jit_pointer_t *)&line->offsets, 16 * sizeof(jit_int32_t)); + line->offsets[0] = offset; +} + +static jit_int32_t +_note_search_index(jit_state_t *_jit, jit_uint8_t *code) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_note_t *notes; + + bot = 0; + top = _jit->note.length; + notes = _jit->note.ptr; + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (code < notes[index].code) + top = index; + else if (code >= notes[index].code && + code - notes[index].code < notes[index].size) + break; + else + bot = index + 1; + } + + return (index); +} + +static jit_int32_t +line_insert_index(jit_note_t *note, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_line_t *lines; + + bot = 0; + top = note->length; + if ((lines = note->lines) == NULL) + return (0); + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < *lines[index].offsets) + top = index; + else + bot = index + 1; + } + + return ((bot + top) >> 1); +} + +static jit_int32_t +line_search_index(jit_note_t *note, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_line_t *lines; + + bot = 0; + top = note->length; + if ((lines = note->lines) == NULL) + return (0); + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < *lines[index].offsets) + top = index; + /* offset should be already verified to be in range */ + else if (index == note->length - 1 || + (offset >= *lines[index].offsets && + offset < *lines[index + 1].offsets)) + break; + else + bot = index + 1; + } + + return (index); +} + +static jit_int32_t +offset_insert_index(jit_line_t *line, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_int32_t *offsets; + + bot = 0; + top = line->length; + offsets = line->offsets; + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < offsets[index]) + top = index; + else + bot = index + 1; + } + + return ((bot + top) >> 1); +} + +static jit_int32_t +offset_search_index(jit_line_t *line, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_int32_t *offsets; + + bot = 0; + top = line->length; + offsets = line->offsets; + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < offsets[index]) + top = index; + /* offset should be already verified to be in range */ + else if (index == line->length - 1 || + (offset >= offsets[index] && offset < offsets[index + 1])) + break; + else + bot = index + 1; + } + + return (index); +} diff --git a/deps/lightning/lib/jit_ppc-cpu.c b/deps/lightning/lib/jit_ppc-cpu.c new file mode 100644 index 0000000..c4397ad --- /dev/null +++ b/deps/lightning/lib/jit_ppc-cpu.c @@ -0,0 +1,3654 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# if __WORDSIZE == 32 +# define gpr_save_area 72 /* r14~r31 = 18 * 4 */ +# if _CALL_SYSV +# define params_offset (sizeof(jit_word_t) << 1) +# else +# define params_offset 24 +# endif +# define can_sign_extend_int_p(im) 1 +# define can_zero_extend_int_p(im) 1 +# define fits_uint32_p(im) 1 +# else +# define gpr_save_area 144 /* r14~r31 = 18 * 8 */ +# if _CALL_ELF == 2 +# define params_offset 32 +# else +# define params_offset 48 +# endif +# define can_sign_extend_int_p(im) \ + (((im) >= 0 && (long)(im) <= 0x7fffffffL) || \ + ((im) < 0 && (long)(im) >= -0x80000000L)) +# define can_zero_extend_int_p(im) \ + ((im) >= 0 && (im) < 0x80000000L) +# define fits_uint32_p(im) ((im & 0xffffffff00000000L) == 0) +# endif +# define fpr_save_area 64 +# define alloca_offset -(gpr_save_area + fpr_save_area) +# define ii(i) *_jit->pc.ui++ = i +# if __WORDSIZE == 32 +# define iw(i) *_jit->pc.ui++ = i +# else +# define iw(i) *_jit->pc.ul++ = i +# endif +# define can_sign_extend_short_p(im) ((im) >= -32768 && (im) <= 32767) +# define can_zero_extend_short_p(im) ((im) >= 0 && (im) <= 65535) +# define can_sign_extend_jump_p(im) ((im) >= -33554432 && (im) <= 33554431) +# define _R0_REGNO 0 +# define _SP_REGNO 1 +# define _R2_REGNO 2 +# define _R11_REGNO 11 +# define _R12_REGNO 12 +# define _FP_REGNO 31 +# if __WORDSIZE == 32 +# define ldr(r0,r1) ldr_i(r0,r1) +# define ldxi(r0,r1,i0) ldxi_i(r0,r1,i0) +# define ldxr(r0,r1,r2) ldxr_i(r0,r1,r2) +# define stxi(i0,r0,r1) stxi_i(i0,r0,r1) +# define stxr(r0,r1,r2) stxr_i(r0,r1,r2) +# else +# define ldr(r0,r1) ldr_l(r0,r1) +# define ldxi(r0,r1,i0) ldxi_l(r0,r1,i0) +# define ldxr(r0,r1,r2) ldxr_l(r0,r1,r2) +# define stxi(i0,r0,r1) stxi_l(i0,r0,r1) +# define stxr(r0,r1,r2) stxr_l(r0,r1,r2) +# endif +# define FXO(o,d,a,b,e,x) _FXO(_jit,o,d,a,b,e,x,0) +# define FXO_(o,d,a,b,e,x) _FXO(_jit,o,d,a,b,e,x,1) +static void _FXO(jit_state_t*,int,int,int,int,int,int,int); +# define FDs(o,d,a,s) _FDs(_jit,o,d,a,s) +static void _FDs(jit_state_t*,int,int,int,int); +# define FDu(o,d,a,s) _FDu(_jit,o,d,a,s) +static void _FDu(jit_state_t*,int,int,int,int); +# define FX(o,d,a,b,x) _FX(_jit,o,d,a,b,x,0) +# define FX_(o,d,a,b,x) _FX(_jit,o,d,a,b,x,1) +static void _FX(jit_state_t*,int,int,int,int,int,int); +# define FI(o,t,a,k) _FI(_jit,o,t,a,k) +static void _FI(jit_state_t*,int,int,int,int); +# define FB(o,bo,bi,t,a,k) _FB(_jit,o,bo,bi,t,a,k) +static void _FB(jit_state_t*,int,int,int,int,int,int); +# define FXL(o,bo,bi,x) _FXL(_jit,o,bo,bi,x,0) +# define FXL_(o,bo,bi,x) _FXL(_jit,o,bo,bi,x,1) +static void _FXL(jit_state_t*,int,int,int,int,int); +# define FC(o,d,l,a,b,x) _FC(_jit,o,d,l,a,b,x) +static void _FC(jit_state_t*,int,int,int,int,int,int); +# define FCI(o,d,l,a,s) _FCI(_jit,o,d,l,a,s) +static void _FCI(jit_state_t*,int,int,int,int,int); +# define FXFX(o,s,x,f) _FXFX(_jit,o,s,x,f) +static void _FXFX(jit_state_t*,int,int,int,int); +# define FM(o,s,a,h,b,e,r) _FM(_jit,o,s,a,h,b,e,r) +static void _FM(jit_state_t*,int,int,int,int,int,int,int); +# if __WORDSIZE == 64 +# define FMDS(o,s,a,b,e,x) _FMDS(_jit,o,s,a,b,e,x,0) +# define FMDS_(o,s,a,b,e,x) _FMDS(_jit,o,s,a,b,e,x,1) +static void _FMDS(jit_state_t*,int,int,int,int,int,int,int); +# define FMD(o,s,a,h,b,x,i) _FMD(_jit,o,s,a,h,b,x,i,0) +# define FMD_(o,s,a,h,b,x,i) _FMD(_jit,o,s,a,h,b,x,i,1) +static void _FMD(jit_state_t*,int,int,int,int,int,int,int,int); +# define FXS(o,d,a,h,x,i) _FXS(_jit,o,d,a,h,x,i,0) +# define FXS_(o,d,a,h,x,i) _FXS(_jit,o,d,a,h,x,i,1) +static void _FXS(jit_state_t*,int,int,int,int,int,int,int); +# endif +# define CR_0 0 +# define CR_1 1 +# define CR_2 2 +# define CR_3 3 +# define CR_4 4 +# define CR_5 5 +# define CR_6 6 +# define CR_7 7 +# define CR_LT 0 +# define CR_GT 1 +# define CR_EQ 2 +# define CR_SO 3 +# define CR_UN 3 +# define BCC_F 4 +# define BCC_T 12 +# define ADD(d,a,b) FXO(31,d,a,b,0,266) +# define ADD_(d,a,b) FXO_(31,d,a,b,0,266) +# define ADDO(d,a,b) FXO(31,d,a,b,1,266) +# define ADDO_(d,a,b) FXO_(31,d,a,b,1,266) +# define ADDC(d,a,b) FXO_(31,d,a,b,0,10) +# define ADDC_(d,a,b) FXO_(31,d,a,b,0,10) +# define ADDCO(d,a,b) FXO(31,d,a,b,1,10) +# define ADDCO_(d,a,b) FXO_(31,d,a,b,1,10) +# define ADDE(d,a,b) FXO(31,d,a,b,0,138) +# define ADDE_(d,a,b) FXO_(31,d,a,b,0,138) +# define ADDEO(d,a,b) FXO(31,d,a,b,1,138) +# define ADDEO_(d,a,b) FXO_(31,d,a,b,1,138) +# define ADDI(d,a,s) FDs(14,d,a,s) +# define ADDIC(d,a,s) FDs(12,d,a,s) +# define ADDIC_(d,a,s) FDs(13,d,a,s) +# define ADDIS(d,a,s) FDs(15,d,a,s) +# define LIS(d,s) ADDIS(d,0,s) +# define ADDME(d,a) FXO(31,d,a,0,0,234) +# define ADDME_(d,a) FXO_(31,d,a,0,0,234) +# define ADDMEO(d,a) FXO(31,d,a,0,1,234) +# define ADDMEO_(d,a) FXO_(31,d,a,0,1,234) +# define ADDZE(d,a) FXO(31,d,a,0,0,202) +# define ADDZE_(d,a) FXO_(31,d,a,0,0,202) +# define ADDZEO(d,a) FXO(31,d,a,0,1,202) +# define ADDZEO_(d,a) FXO_(31,d,a,0,1,202) +# define AND(d,a,b) FX(31,a,d,b,28) +# define ANDC(d,a,b) FXO(31,a,d,b,0,60) +# define ANDC_(d,a,b) FXO_(31,a,d,b,0,60) +# define AND_(d,a,b) FX_(31,a,b,d,28) +# define ANDI_(d,a,u) FDu(28,a,d,u) +# define ANDIS_(d,a,u) FDu(29,a,d,u) +# define B(t) FI(18,t,0,0) +# define BA(t) FI(18,t,1,0) +# define BL(t) FI(18,t,0,1) +# define BLA(t) FI(18,t,1,1) +# define BC(o,i,t) FB(16,o,i,t,0,0) +# define BCA(o,i,t) FB(16,o,i,t,1,0) +# define BCL(o,i,t) FB(16,o,i,t,0,1) +# define BCLA(o,i,t) FB(16,o,i,t,1,1) +# define BLT(t) BC(BCC_T,CR_LT,t) +# define BLE(t) BC(BCC_F,CR_GT,t) +# define BEQ(t) BC(BCC_T,CR_EQ,t) +# define BGE(t) BC(BCC_F,CR_LT,t) +# define BGT(t) BC(BCC_T,CR_GT,t) +# define BNE(t) BC(BCC_F,CR_EQ,t) +# define BUN(t) BC(BCC_T,CR_UN,t) +# define BNU(t) BC(BCC_F,CR_UN,t) +# define BCCTR(o,i) FXL(19,o,i,528) +# define BCCTRL(o,i) FXL_(19,o,i,528) +# define BLTCTR() BCCTR(BCC_T,CR_LT) +# define BLECTR() BCCTR(BCC_F,CR_GT) +# define BEQCTR() BCCTR(BCC_T,CR_EQ) +# define BGECTR() BCCTR(BCC_F,CR_LT) +# define BGTCTR() BCCTR(BCC_T,CR_GT) +# define BNECTR() BCCTR(BCC_F,CR_EQ) +# define BCTR() BCCTR(20,0) +# define BCTRL() BCCTRL(20,0) +# define BCLR(o,i) FXL(19,o,i,16) +# define BCLRL(o,i) FXL_(19,o,i,16) +# define BLTLR() BCLR(BCC_T,CR_LT) +# define BLELR() BCLR(BCC_F,CR_GT) +# define BEQLR() BCLR(BCC_T,CR_EQ) +# define BGELR() BCLR(BCC_F,CR_LT) +# define BGTLR() BCLR(BCC_T,CR_GT) +# define BNELR() BCLR(BCC_F,CR_EQ) +# define BLR() BCLR(20,0) +# define BLRL() BCLRL(20,0) +# define XCMP(cr,l,a,b) FC(31,cr,l,a,b,0) +# define CMPD(a,b) XCMP(0,1,a,b) +# define CMPW(a,b) XCMP(0,0,a,b) +# define XCMPI(cr,l,a,s) FCI(11,cr,l,a,s) +# define CMPDI(a,s) XCMPI(0,1,a,s) +# define CMPWI(a,s) XCMPI(0,0,a,s) +# define XCMPL(cr,l,a,b) FC(31,cr,l,a,b,32) +# define CMPLD(a,b) XCMPL(0,1,a,b) +# define CMPLW(a,b) XCMPL(0,0,a,b) +# define XCMPLI(cr,l,a,u) FCI(10,cr,l,a,u) +# define CMPLDI(a,s) XCMPLI(0,1,a,s) +# define CMPLWI(a,s) XCMPLI(0,0,a,s) +# define CNTLZW(a,s) FX(31,s,a,0,26) +# define CNTLZW_(a,s) FX_(31,s,a,0,26) +# define CRAND(d,a,b) FX(19,d,a,b,257) +# define CRANDC(d,a,b) FX(19,d,a,b,129) +# define CREQV(d,a,b) FX(19,d,a,b,289) +# define CRSET(d) CREQV(d,d,d) +# define CRNAND(d,a,b) FX(19,d,a,b,225) +# define CRNOR(d,a,b) FX(19,d,a,b,33) +# define CRNOT(d,a) CRNOR(d,a,a) +# define CROR(d,a,b) FX(19,d,a,b,449) +# define CRMOVE(d,a) CROR(d,a,a) +# define CRORC(d,a,b) FX(19,d,a,b,417) +# define CRXOR(d,a,b) FX(19,d,a,b,193) +# define CRCLR(d) CRXOR(d,d,d) +# define DCBA(a,b) FX(31,0,a,b,758) +# define DCBF(a,b) FX(31,0,a,b,86) +# define DCBI(a,b) FX(31,0,a,b,470) +# define DCBST(a,b) FX(31,0,a,b,54) +# define DCBT(a,b) FX(31,0,a,b,278) +# define DCBTST(a,b) FX(31,0,a,b,246) +# define DCBZ(a,b) FX(31,0,a,b,1014) +# define DIVW(d,a,b) FXO(31,d,a,b,0,491) +# define DIVW_(d,a,b) FXO_(31,d,a,b,0,491) +# define DIVWO(d,a,b) FXO(31,d,a,b,1,491) +# define DIVWO_(d,a,b) FXO_(31,d,a,b,1,491) +# define DIVWU(d,a,b) FXO(31,d,a,b,0,459) +# define DIVWU_(d,a,b) FXO_(31,d,a,b,0,459) +# define DIVWUO(d,a,b) FXO(31,d,a,b,1,459) +# define DIVWUO_(d,a,b) FXO_(31,d,a,b,1,459) +# define DIVD(d,a,b) FXO(31,d,a,b,0,489) +# define DIVD_(d,a,b) FXO_(31,d,a,b,0,489) +# define DIVDO(d,a,b) FXO(31,d,a,b,1,489) +# define DIVDO_(d,a,b) FXO_(31,d,a,b,1,489) +# define DIVDU(d,a,b) FXO(31,d,a,b,0,457) +# define DIVDU_(d,a,b) FXO_(31,d,a,b,0,457) +# define DIVDUO(d,a,b) FXO(31,d,a,b,1,457) +# define DIVDUO_(d,a,b) FXO_(31,d,a,b,1,457) +# define ECIWX(d,a,b) FX(31,d,a,b,310) +# define ECOWX(s,a,b) FX(31,s,a,b,438) +# define EIEIO() FX(31,0,0,0,854) +# define EQV(d,a,b) FX(31,a,d,b,284) +# define EQV_(d,a,b) FX_(31,a,d,b,284) +# define EXTSB(d,a) FX(31,a,d,0,954) +# define EXTSB_(d,a) FX_(31,a,d,0,954) +# define EXTSH(d,a) FX(31,a,d,0,922) +# define EXTSH_(d,a) FX_(31,a,d,0,922) +# define EXTSW(d,a) FX(31,a,d,0,986) +# define EXTSW_(d,a) FX_(31,a,d,0,986) +# define ICIB(a,b) FX(31,0,a,b,982) +# define ISYNC() FXL(19,0,0,150) +# define LBZ(d,a,s) FDs(34,d,a,s) +# define LBZU(d,a,s) FDs(35,d,a,s) +# define LBZUX(d,a,b) FX(31,d,a,b,119) +# define LBZX(d,a,b) FX(31,d,a,b,87) +# define LHA(d,a,s) FDs(42,d,a,s) +# define LHAU(d,a,s) FDs(43,d,a,s) +# define LHAUX(d,a,b) FX(31,d,a,b,375) +# define LHAX(d,a,b) FX(31,d,a,b,343) +# define LHRBX(d,a,b) FX(31,d,a,b,790) +# define LHZ(d,a,s) FDs(40,d,a,s) +# define LHZU(d,a,s) FDs(41,d,a,s) +# define LHZUX(d,a,b) FX(31,d,a,b,311) +# define LHZX(d,a,b) FX(31,d,a,b,279) +# define LA(d,a,s) ADDI(d,a,s) +# define LI(d,s) ADDI(d,0,s) +# define LMW(d,a,s) FDs(46,d,a,s) +# define LSWI(d,a,n) FX(31,d,a,n,597) +# define LSWX(d,a,b) FX(31,d,a,b,533) +# define LWARX(d,a,b) FX(31,d,a,b,20) +# define LWBRX(d,a,b) FX(31,d,a,b,534) +# define LWA(d,a,s) FDs(58,d,a,s|2) +# define LWAUX(d,a,b) FX(31,d,a,b,373) +# define LWAX(d,a,b) FX(31,d,a,b,341) +# define LWZ(d,a,s) FDs(32,d,a,s) +# define LWZU(d,a,s) FDs(33,d,a,s) +# define LWZUX(d,a,b) FX(31,d,a,b,55) +# define LWZX(d,a,b) FX(31,d,a,b,23) +# define LD(d,a,s) FDs(58,d,a,s) +# define LDX(d,a,b) FX(31,d,a,b,21) +# define MCRF(d,s) FXL(19,d<<2,(s)<<2,0) +# if DEBUG +/* In case instruction is emulated, check the kernel can handle it. + Will only generate it if DEBUG is enabled. +""" +Chapter 6. Optional Facilities and Instructions that are being +Phased Out of the Architecture +... +6.1 Move To Condition Register from XER +The mcrxr instruction is being phased out of the archi- +tecture. Its description is included here as an aid to +constructing operating system code to emulate it. + +Move to Condition Register from XER +X-form +mcrxr BF +31 BF // /// /// 512 / +0 6 9 11 16 21 31 +CR(4xBF:4xBF+3) <- XER(32:35) +XER(32:35) <- 0b0000 +The contents of XER(32:35) are copied to Condition Reg- +ister field BF. XER(32:35) are set to zero. +Special Registers Altered: +CR field BF XER(32:35) + +Programming Note +Warning: This instruction has been phased out of +the architecture. Attempting to execute this +instruction will cause the system illegal instruction +error handler to be invoked +""" + */ +# define MCRXR(d) FX(31,d<<2,0,0,512) +# else +# define MCRXR(cr) _MCRXR(_jit,cr); +static void _MCRXR(jit_state_t*, jit_int32_t); +# endif +# define MFCR(d) FX(31,d,0,0,19) +# define MFMSR(d) FX(31,d,0,0,83) +# define MFSPR(d,s) FXFX(31,d,s<<5,339) +# define MFXER(d) MFSPR(d,1) +# define MFLR(d) MFSPR(d,8) +# define MFCTR(d) MFSPR(d,9) +# define MFSR(d,s) FX(31,d,s,0,595) +# define MFSRIN(d,b) FX(31,d,0,b,659) +# define MFTB(d,x,y) FXFX(31,d,(x)|((y)<<5),371) +# define MFTBL(d) MFTB(d,8,12) +# define MFTBU(d) MFTB(d,8,13) +# define MTCRF(c,s) FXFX(31,s,c<<1,144) +# define MTCR(s) MTCRF(0xff,s) +# define MTMSR(s) FX(31,s,0,0,146) +# define MTSPR(d,s) FXFX(31,d,s<<5,467) +# define MTXER(d) MTSPR(d,1) +# define MTLR(d) MTSPR(d,8) +# define MTCTR(d) MTSPR(d,9) +# define MTSR(r,s) FX(31,s<<1,r,0,210) +# define MTSRIN(r,b) FX(31,r<<1,0,b,242) +# define MULLI(d,a,s) FDs(07,d,a,s) +# define MULHW(d,a,b) FXO(31,d,a,b,0,75) +# define MULHW_(d,a,b) FXO_(31,d,a,b,0,75) +# define MULHWU(d,a,b) FXO(31,d,a,b,0,11) +# define MULHWU_(d,a,b) FXO_(31,d,a,b,0,11) +# define MULLW(d,a,b) FXO(31,d,a,b,0,235) +# define MULLW_(d,a,b) FXO_(31,d,a,b,0,235) +# define MULLWO(d,a,b) FXO(31,d,a,b,1,235) +# define MULLWO_(d,a,b) FXO_(31,d,a,b,1,235) +# define MULHD(d,a,b) FXO(31,d,a,b,0,73) +# define MULHD_(d,a,b) FXO_(31,d,a,b,0,73) +# define MULHDU(d,a,b) FXO(31,d,a,b,0,9) +# define MULHDU_(d,a,b) FXO_(31,d,a,b,0,9) +# define MULLD(d,a,b) FXO(31,d,a,b,0,233) +# define MULLD_(d,a,b) FXO_(31,d,a,b,0,233) +# define MULLDO(d,a,b) FXO(31,d,a,b,1,233) +# define MULLDO_(d,a,b) FXO_(31,d,a,b,1,233) +# define NAND(d,a,b) FX(31,a,d,b,476) +# define NAND_(d,a,b) FX_(31,a,d,b,476) +# define NEG(d,a) FXO(31,d,a,0,0,104) +# define NEG_(d,a) FXO_(31,d,a,0,0,104) +# define NEGO(d,a) FXO(31,d,a,0,1,104) +# define NEGO_(d,a) FXO_(31,d,a,0,1,104) +# define NOR(d,a,b) FX(31,a,d,b,124) +# define NOR_(d,a,b) FX_(31,a,d,b,124) +# define NOT(d,s) NOR(d,s,s) +# define OR(d,a,b) FX(31,a,d,b,444) +# define OR_(d,a,b) FX_(31,a,d,b,444) +# define MR(d,a) OR(d,a,a) +# define ORC(d,a,b) FX(31,a,d,b,412) +# define ORC_(d,a,b) FX_(31,a,d,b,412) +# define ORI(d,a,u) FDu(24,a,d,u) +# define NOP() ORI(0,0,0) +# define ORIS(d,a,u) FDu(25,a,d,u) +# define RFI() FXL(19,0,0,50) +# define RLWIMI(d,s,h,b,e) FM(20,s,d,h,b,e,0) +# define RLWIMI_(d,s,h,b,e) FM(20,s,d,h,b,e,1) +# define INSLWI(a,s,n,b) RLWIMI(a,s,32-b,b,b+n-1) +# define INSRWI(a,s,n,b) RLWIMI(a,s,32-(b+n),b,(b+n)-1) +# define RLWINM(a,s,h,b,e) FM(21,s,a,h,b,e,0) +# define RLWINM_(a,s,h,b,e) FM(21,s,a,h,b,e,1) +# define EXTLWI(a,s,n,b) RLWINM(a,s,b,0,n-1) +# define EXTRWI(a,s,n,b) RLWINM(a,s,b+n,32-n,31) +# define ROTLWI(a,s,n) RLWINM(a,s,n,0,31) +# define ROTRWI(a,s,n) RLWINM(a,s,32-n,0,31) +# define SLWI(a,s,n) RLWINM(a,s,n,0,31-n) +# define SRWI(a,s,n) RLWINM(a,s,32-n,n,31) +# define CLRLWI(a,s,n) RLWINM(a,s,0,n,31) +# define CLRRWI(a,s,n) RLWINM(a,s,0,0,31-n) +# define CLRLSWI(a,s,b,n) RLWINM(a,s,n,b-n,31-n) +# define RLWNM(a,s,b,m,e) FM(23,s,a,b,m,e,0) +# define RLWNM_(a,s,b,m,e) FM(23,s,a,b,m,e,1) +# define ROTLW(a,s,b) RLWNM(a,s,b,0,31) +# define SC() FDu(17,0,0,2) +# define SLW(a,s,b) FX(31,s,a,b,24) +# define SLW_(a,s,b) FX_(31,s,a,b,24) +# define SRAW(a,s,b) FX(31,s,a,b,792) +# define SRAW_(a,s,b) FX_(31,s,a,b,792) +# define SRAWI(a,s,h) FX(31,s,a,h,824) +# define SRAWI_(a,s,h) FX_(31,s,a,h,824) +# define SRW(a,s,b) FX(31,s,a,b,536) +# define SRW_(a,s,b) FX_(31,s,a,b,536) +# if __WORDSIZE == 64 +# define RLDICL(a,s,h,b) FMD(30,s,a,h&~32,b,0,h>>5) +# define RLDICL_(a,s,h,b) FMD_(30,s,a,h&~32,b,0,h>>5) +# define EXTRDI(x,y,n,b) RLDICL(x,y,(b+n),(64-n)) +# define SRDI(x,y,n) RLDICL(x,y,(64-n),n) +# define CLRLDI(x,y,n) RLDICL(x,y,0,n) +# define RLDICR(a,s,h,e) FMD(30,s,a,h&~32,e,1,h>>5) +# define RLDICR_(a,s,h,e) FMD_(30,s,a,h&~32,e,1,h>>5) +# define EXTRLI(x,y,n,b) RLDICR(x,y,b,(n-1)) +# define SLDI(x,y,n) RLDICR(x,y,n,(63-n)) +# define CLRRDI(x,y,n) RLDICR(x,y,0,(63-n)) +# define RLDIC(a,s,h,b) FMD(30,s,a,h&~32,b,2,h>>5) +# define RLDIC_(a,s,h,b) FMD_(30,s,a,h&~32,b,2,h>>5) +# define CLRLSLDI(x,y,b,n) RLDIC(x,y,n,(b-n)) +# define RLDCL(a,s,h,b) FMDS(30,s,a,h,b,8) +# define RLDCL_(a,s,h,b) FMDS_(30,s,a,h,b,8) +# define ROTLD(x,y,z) RLDCL(x,y,z,0) +# define RLDCR(a,s,b,e) FMDS(30,s,a,b,e,0) +# define RLDCR_(a,s,b,e) FMDS_(30,s,a,b,e,0) +# define RLDIMI(a,s,h,b) FMD(30,s,a,h&~32,b,3,h>>5) +# define RLDIMI_(a,s,h,b) FMD_(30,s,a,h&~32,b,3,h>>5) +# define INSRDI(x,y,n,b) RLDIMI(x,y,(64-(b+n)),b) +# define SLD(a,s,b) FX(31,s,a,b,27) +# define SLD_(a,s,b) FX_(31,s,a,b,27) +# define SRD(a,s,b) FX(31,s,a,b,539) +# define SRD_(a,s,b) FX_(31,s,a,b,539) +# define SRADI(a,s,h) FXS(31,s,a,h&~32,413,h>>5) +# define SRADI_(a,s,h) FXS_(31,s,a,h&~32,413,h>>5) +# define SRAD(a,s,b) FX(31,s,a,b,794) +# define SRAD_(a,s,b) FX_(31,s,a,b,794) +# endif +# define STB(s,a,d) FDs(38,s,a,d) +# define STBU(s,a,d) FDs(39,s,a,d) +# define STBUX(s,a,b) FX(31,s,a,b,247) +# define STBX(s,a,b) FX(31,s,a,b,215) +# define STH(s,a,d) FDs(44,s,a,d) +# define STHBRX(s,a,b) FX(31,s,a,b,918) +# define STHU(s,a,d) FDs(45,s,a,d) +# define STHUX(s,a,b) FX(31,s,a,b,439) +# define STHX(s,a,b) FX(31,s,a,b,407) +# define STMW(s,a,d) FDs(47,s,a,d) +# define STWSI(s,a,nb) FX(31,s,a,nb,725) +# define STSWX(s,a,b) FX(31,s,a,b,661) +# define STW(s,a,d) FDs(36,s,a,d) +# define STWBRX(s,a,b) FX(31,s,a,b,662) +# define STWCX_(s,a,b) FX_(31,s,a,b,150) +# define STWU(s,a,d) FDs(37,s,a,d) +# define STWUX(s,a,b) FX(31,s,a,b,183) +# define STWX(s,a,b) FX(31,s,a,b,151) +# define STD(s,a,d) FDs(62,s,a,d) +# define STDX(s,a,b) FX(31,s,a,b,149) +# define STDU(s,a,d) FDs(62,s,a,d|1) +# define STDUX(s,a,b) FX(31,s,a,b,181) +# define SUBF(d,a,b) FXO(31,d,a,b,0,40) +# define SUBF_(d,a,b) FXO_(31,d,a,b,0,40) +# define SUBFO(d,a,b) FXO(31,d,a,b,1,40) +# define SUBFO_(d,a,b) FXO_(31,d,a,b,1,40) +# define SUB(d,a,b) SUBF(d,b,a) +# define SUB_(d,a,b) SUBF_(d,b,a) +# define SUBO(d,a,b) SUBFO(d,b,a) +# define SUBO_(d,a,b) SUBFO_(d,b,a) +# define SUBI(d,a,s) ADDI(d,a,-s) +# define SUBIS(d,a,s) ADDIS(d,a,-s) +# define SUBFC(d,a,b) FXO(31,d,a,b,0,8) +# define SUBFC_(d,a,b) FXO_(31,d,a,b,0,8) +# define SUBFCO(d,a,b) FXO(31,d,a,b,1,8) +# define SUBFCO_(d,a,b) FXO_(31,d,a,b,1,8) +# define SUBC(d,a,b) SUBFC(d,b,a) +# define SUBIC(d,a,s) ADDIC(d,a,-s) +# define SUBIC_(d,a,s) ADDIC_(d,a,-s) +# define SUBFE(d,a,b) FXO(31,d,a,b,0,136) +# define SUBFE_(d,a,b) FXO_(31,d,a,b,0,136) +# define SUBFEO(d,a,b) FXO(31,d,a,b,1,136) +# define SUBFEO_(d,a,b) FXO_(31,d,a,b,1,136) +# define SUBE(d,a,b) SUBFE(d,b,a) +# define SUBFIC(d,a,s) FDs(8,d,a,s) +# define SUBFME(d,a) FXO(31,d,a,0,0,232) +# define SUBFME_(d,a) FXO_(31,d,a,0,0,232) +# define SUBFMEO(d,a) FXO(31,d,a,0,1,232) +# define SUBFMEO_(d,a) FXO_(31,d,a,0,1,232) +# define SUBFZE(d,a) FXO(31,d,a,0,0,200) +# define SUBFZE_(d,a) FXO_(31,d,a,0,0,200) +# define SUBFZEO(d,a) FXO(31,d,a,0,1,200) +# define SUBFZEO_(d,a) FXO_(31,d,a,0,1,200) +# define SYNC() FX(31,0,0,0,598) +# define TLBIA() FX(31,0,0,0,370) +# define TLBIE(b) FX(31,0,0,b,306) +# define TLBSYNC() FX(31,0,0,0,566) +# define TW(t,a,b) FX(31,t,a,b,4) +# define TWEQ(a,b) FX(31,4,a,b,4) +# define TWLGE(a,b) FX(31,5,a,b,4) +# define TRAP() FX(31,31,0,0,4) +# define TWI(t,a,s) FDs(3,t,a,s) +# define TWGTI(a,s) TWI(8,a,s) +# define TWLLEI(a,s) TWI(6,a,s) +# define XOR(d,a,b) FX(31,a,d,b,316) +# define XOR_(d,a,b) FX_(31,a,d,b,316) +# define XORI(s,a,u) FDu(26,a,s,u) +# define XORIS(s,a,u) FDu(27,a,s,u) +# define nop(c) _nop(_jit,c) +static void _nop(jit_state_t*,jit_int32_t); +# define movr(r0,r1) _movr(_jit,r0,r1) +static void _movr(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi(r0,i0) _movi(_jit,r0,i0) +static void _movi(jit_state_t*,jit_int32_t,jit_word_t); +# define movi_p(r0,i0) _movi_p(_jit,r0,i0) +static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t); +# define negr(r0,r1) NEG(r0,r1) +# define comr(r0,r1) NOT(r0,r1) +# define extr_c(r0,r1) EXTSB(r0,r1) +# define extr_uc(r0,r1) ANDI_(r0,r1,0xff) +# define extr_s(r0,r1) EXTSH(r0,r1) +# define extr_us(r0,r1) ANDI_(r0,r1,0xffff) +# if __WORDSIZE == 64 +# define extr_i(r0,r1) EXTSW(r0,r1) +# define extr_ui(r0,r1) CLRLDI(r0,r1,32) +# endif +# if __BYTE_ORDER == __BIG_ENDIAN +# define htonr_us(r0,r1) extr_us(r0,r1) +# if __WORDSIZE == 32 +# define htonr_ui(r0,r1) movr(r0,r1) +# else +# define htonr_ui(r0,r1) extr_ui(r0,r1) +# define htonr_ul(r0,r1) movr(r0,r1) +# endif +# else +# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1) +static void _htonr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1) +static void _htonr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# if __WORDSIZE == 64 +# define htonr_ul(r0,r1) _htonr_ul(_jit,r0,r1) +static void _htonr_ul(jit_state_t*,jit_int32_t,jit_int32_t); +# endif +# endif +# define addr(r0,r1,r2) ADD(r0,r1,r2) +# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0) +static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addcr(r0,r1,r2) ADDC(r0,r1,r2) +# define addci(r0,r1,i0) _addci(_jit,r0,r1,i0) +static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addxr(r0,r1,r2) ADDE(r0,r1,r2) +# define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0) +static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subr(r0,r1,r2) SUB(r0,r1,r2) +# define subi(r0,r1,i0) _subi(_jit,r0,r1,i0) +static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subcr(r0,r1,r2) SUBC(r0,r1,r2) +# define subci(r0,r1,i0) _subci(_jit,r0,r1,i0) +static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subxr(r0,r1,r2) SUBFE(r0,r2,r1) +# define subxi(r0,r1,i0) _subxi(_jit,r0,r1,i0) +static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0) +static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define mulr(r0,r1,r2) MULLW(r0,r1,r2) +# define mullr(r0,r1,r2) MULLW(r0,r1,r2) +# define mulhr(r0,r1,r2) MULHW(r0,r1,r2) +# define mulhr_u(r0,r1,r2) MULHWU(r0,r1,r2) +# else +# define mulr(r0,r1,r2) MULLD(r0,r1,r2) +# define mullr(r0,r1,r2) MULLD(r0,r1,r2) +# define mulhr(r0,r1,r2) MULHD(r0,r1,r2) +# define mulhr_u(r0,r1,r2) MULHDU(r0,r1,r2) +# endif +# define muli(r0,r1,i0) _muli(_jit,r0,r1,i0) +static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,1) +# define qmulr_u(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,0) +# define iqmulr(r0,r1,r2,r3,cc) _iqmulr(_jit,r0,r1,r2,r3,cc) +static void _iqmulr(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_bool_t); +# define qmuli(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,1) +# define qmuli_u(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,0) +# define iqmuli(r0,r1,r2,i0,cc) _iqmuli(_jit,r0,r1,r2,i0,cc) +static void _iqmuli(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_word_t,jit_bool_t); +# if __WORDSIZE == 32 +# define divr(r0,r1,r2) DIVW(r0,r1,r2) +# else +# define divr(r0,r1,r2) DIVD(r0,r1,r2) +# endif +# define divi(r0,r1,i0) _divi(_jit,r0,r1,i0) +static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define divr_u(r0,r1,r2) DIVWU(r0,r1,r2) +# else +# define divr_u(r0,r1,r2) DIVDU(r0,r1,r2) +# endif +# define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0) +static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qdivr(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,1) +# define qdivr_u(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,0) +# define iqdivr(r0,r1,r2,r3,cc) _iqdivr(_jit,r0,r1,r2,r3,cc) +static void _iqdivr(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_bool_t); +# define qdivi(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,1) +# define qdivi_u(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,0) +# define iqdivi(r0,r1,r2,i0,cc) _iqdivi(_jit,r0,r1,r2,i0,cc) +static void _iqdivi(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_word_t,jit_bool_t); +# define remr(r0,r1,r2) _remr(_jit,r0,r1,r2) +static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi(r0,r1,i0) _remi(_jit,r0,r1,i0) +static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2) +static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0) +static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define andr(r0,r1,r2) AND(r0,r1,r2) +# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0) +static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define orr(r0,r1,r2) OR(r0,r1,r2) +# define ori(r0,r1,i0) _ori(_jit,r0,r1,i0) +static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define xorr(r0,r1,r2) XOR(r0,r1,r2) +# define xori(r0,r1,i0) _xori(_jit,r0,r1,i0) +static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define lshr(r0,r1,r2) SLW(r0,r1,r2) +# else +# define lshr(r0,r1,r2) SLD(r0,r1,r2) +# endif +# define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0) +static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define rshr(r0,r1,r2) SRAW(r0,r1,r2) +# else +# define rshr(r0,r1,r2) SRAD(r0,r1,r2) +# endif +# define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0) +static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define rshr_u(r0,r1,r2) SRW(r0,r1,r2) +# else +# define rshr_u(r0,r1,r2) SRD(r0,r1,r2) +# endif +# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0) +static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ltr(r0,r1,r2) _ltr(_jit,r0,r1,r2) +static void _ltr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lti(r0,r1,i0) _lti(_jit,r0,r1,i0) +static void _lti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ltr_u(r0,r1,r2) _ltr_u(_jit,r0,r1,r2) +static void _ltr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lti_u(r0,r1,i0) _lti_u(_jit,r0,r1,i0) +static void _lti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ler(r0,r1,r2) _ler(_jit,r0,r1,r2) +static void _ler(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lei(r0,r1,i0) _lei(_jit,r0,r1,i0) +static void _lei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ler_u(r0,r1,r2) _ler_u(_jit,r0,r1,r2) +static void _ler_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lei_u(r0,r1,i0) _lei_u(_jit,r0,r1,i0) +static void _lei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define eqr(r0,r1,r2) _eqr(_jit,r0,r1,r2) +static void _eqr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define eqi(r0,r1,i0) _eqi(_jit,r0,r1,i0) +static void _eqi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ger(r0,r1,r2) _ger(_jit,r0,r1,r2) +static void _ger(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gei(r0,r1,i0) _gei(_jit,r0,r1,i0) +static void _gei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ger_u(r0,r1,r2) _ger_u(_jit,r0,r1,r2) +static void _ger_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gei_u(r0,r1,i0) _gei_u(_jit,r0,r1,i0) +static void _gei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define gtr(r0,r1,r2) _gtr(_jit,r0,r1,r2) +static void _gtr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gti(r0,r1,i0) _gti(_jit,r0,r1,i0) +static void _gti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define gtr_u(r0,r1,r2) _gtr_u(_jit,r0,r1,r2) +static void _gtr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gti_u(r0,r1,i0) _gti_u(_jit,r0,r1,i0) +static void _gti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ner(r0,r1,r2) _ner(_jit,r0,r1,r2) +static void _ner(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define nei(r0,r1,i0) _nei(_jit,r0,r1,i0) +static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +#define bltr(i0,r0,r1) _bltr(_jit,i0,r0,r1) +static jit_word_t _bltr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define blti(i0,r0,i1) _blti(_jit,i0,r0,i1) +static jit_word_t _blti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bltr_u(i0,r0,r1) _bltr_u(_jit,i0,r0,r1) +static jit_word_t _bltr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define blti_u(i0,r0,i1) _blti_u(_jit,i0,r0,i1) +static jit_word_t _blti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bler(i0,r0,r1) _bler(_jit,i0,r0,r1) +static jit_word_t _bler(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define blei(i0,r0,i1) _blei(_jit,i0,r0,i1) +static jit_word_t _blei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bler_u(i0,r0,r1) _bler_u(_jit,i0,r0,r1) +static jit_word_t _bler_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define blei_u(i0,r0,i1) _blei_u(_jit,i0,r0,i1) +static jit_word_t _blei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define beqr(i0,r0,r1) _beqr(_jit,i0,r0,r1) +static jit_word_t _beqr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define beqi(i0,r0,i1) _beqi(_jit,i0,r0,i1) +static jit_word_t _beqi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bger(i0,r0,r1) _bger(_jit,i0,r0,r1) +static jit_word_t _bger(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bgei(i0,r0,i1) _bgei(_jit,i0,r0,i1) +static jit_word_t _bgei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bger_u(i0,r0,r1) _bger_u(_jit,i0,r0,r1) +static jit_word_t _bger_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bgei_u(i0,r0,i1) _bgei_u(_jit,i0,r0,i1) +static jit_word_t _bgei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bgtr(i0,r0,r1) _bgtr(_jit,i0,r0,r1) +static jit_word_t _bgtr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bgti(i0,r0,i1) _bgti(_jit,i0,r0,i1) +static jit_word_t _bgti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bgtr_u(i0,r0,r1) _bgtr_u(_jit,i0,r0,r1) +static jit_word_t _bgtr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bgti_u(i0,r0,i1) _bgti_u(_jit,i0,r0,i1) +static jit_word_t _bgti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bner(i0,r0,r1) _bner(_jit,i0,r0,r1) +static jit_word_t _bner(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bnei(i0,r0,i1) _bnei(_jit,i0,r0,i1) +static jit_word_t _bnei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bmsr(i0,r0,r1) _bmsr(_jit,i0,r0,r1) +static jit_word_t _bmsr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bmsi(i0,r0,i1) _bmsi(_jit,i0,r0,i1) +static jit_word_t _bmsi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bmcr(i0,r0,r1) _bmcr(_jit,i0,r0,r1) +static jit_word_t _bmcr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bmci(i0,r0,i1) _bmci(_jit,i0,r0,i1) +static jit_word_t _bmci(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define boaddr(i0,r0,r1) _boaddr(_jit,i0,r0,r1) +static jit_word_t _boaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define boaddi(i0,r0,i1) _boaddi(_jit,i0,r0,i1) +static jit_word_t _boaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bxaddr(i0,r0,r1) _bxaddr(_jit,i0,r0,r1) +static jit_word_t _bxaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bxaddi(i0,r0,i1) _bxaddi(_jit,i0,r0,i1) +static jit_word_t _bxaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bosubr(i0,r0,r1) _bosubr(_jit,i0,r0,r1) +static jit_word_t _bosubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bosubi(i0,r0,i1) _bosubi(_jit,i0,r0,i1) +static jit_word_t _bosubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bxsubr(i0,r0,r1) _bxsubr(_jit,i0,r0,r1) +static jit_word_t _bxsubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bxsubi(i0,r0,i1) _bxsubi(_jit,i0,r0,i1) +static jit_word_t _bxsubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define boaddr_u(i0,r0,r1) _boaddr_u(_jit,i0,r0,r1) +static jit_word_t _boaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define boaddi_u(i0,r0,i1) _boaddi_u(_jit,i0,r0,i1) +static jit_word_t _boaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bxaddr_u(i0,r0,r1) _bxaddr_u(_jit,i0,r0,r1) +static jit_word_t _bxaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bxaddi_u(i0,r0,i1) _bxaddi_u(_jit,i0,r0,i1) +static jit_word_t _bxaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bosubr_u(i0,r0,r1) _bosubr_u(_jit,i0,r0,r1) +static jit_word_t _bosubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bosubi_u(i0,r0,i1) _bosubi_u(_jit,i0,r0,i1) +static jit_word_t _bosubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +#define bxsubr_u(i0,r0,r1) _bxsubr_u(_jit,i0,r0,r1) +static jit_word_t _bxsubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#define bxsubi_u(i0,r0,i1) _bxsubi_u(_jit,i0,r0,i1) +static jit_word_t _bxsubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define ldr_c(r0,r1) _ldr_c(_jit,r0,r1) +static void _ldr_c(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_c(r0,i0) _ldi_c(_jit,r0,i0) +static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_c(r0,r1,i0) _ldxr_c(_jit,r0,r1,i0) +static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0) +static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_uc(r0,r1) LBZX(r0, _R0_REGNO, r1) +# define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0) +static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_uc(r0,r1,r2) _ldxr_uc(_jit,r0,r1,r2) +static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0) +static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_s(r0,r1) LHAX(r0, _R0_REGNO, r1) +# define ldi_s(r0,i0) _ldi_s(_jit,r0,i0) +static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_s(r0,r1,i0) _ldxr_s(_jit,r0,r1,i0) +static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0) +static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_us(r0,r1) LHZX(r0, _R0_REGNO, r1) +# define ldi_us(r0,i0) _ldi_us(_jit,r0,i0) +static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_us(r0,r1,i0) _ldxr_us(_jit,r0,r1,i0) +static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0) +static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define ldr_i(r0,r1) LWZX(r0, _R0_REGNO, r1) +# else +# define ldr_i(r0,r1) LWAX(r0, _R0_REGNO, r1) +# endif +# define ldi_i(r0,i0) _ldi_i(_jit,r0,i0) +static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_i(r0,r1,i0) _ldxr_i(_jit,r0,r1,i0) +static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_i(r0,r1,i0) _ldxi_i(_jit,r0,r1,i0) +static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 64 +# define ldr_ui(r0,r1) LWZX(r0, _R0_REGNO, r1) +# define ldi_ui(r0,i0) _ldi_ui(_jit,r0,i0) +static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_ui(r0,r1,i0) _ldxr_ui(_jit,r0,r1,i0) +static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_ui(r0,r1,i0) _ldxi_ui(_jit,r0,r1,i0) +static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_l(r0,r1) LDX(r0, _R0_REGNO, r1) +# define ldi_l(r0,i0) _ldi_l(_jit,r0,i0) +static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_l(r0,r1,i0) _ldxr_l(_jit,r0,r1,i0) +static void _ldxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_l(r0,r1,i0) _ldxi_l(_jit,r0,r1,i0) +static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# endif +# define str_c(r0,r1) STBX(r1, _R0_REGNO, r0) +# define sti_c(i0,r0) _sti_c(_jit,i0,r0) +static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_c(r0,r1,r2) _stxr_c(_jit,r0,r1,r2) +static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_c(i0,r0,r1) _stxi_c(_jit,i0,r0,r1) +static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define str_s(r0,r1) STHX(r1, _R0_REGNO, r0) +# define sti_s(i0,r0) _sti_s(_jit,i0,r0) +static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_s(r0,r1,r2) _stxr_s(_jit,r0,r1,r2) +static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_s(i0,r0,r1) _stxi_s(_jit,i0,r0,r1) +static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define str_i(r0,r1) STWX(r1, _R0_REGNO, r0) +# define sti_i(i0,r0) _sti_i(_jit,i0,r0) +static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_i(r0,r1,r2) _stxr_i(_jit,r0,r1,r2) +static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_i(i0,r0,r1) _stxi_i(_jit,i0,r0,r1) +static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# if __WORDSIZE == 64 +# define str_l(r0,r1) STDX(r1, _R0_REGNO, r0) +# define sti_l(i0,r0) _sti_l(_jit,i0,r0) +static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_l(r0,r1,r2) _stxr_l(_jit,r0,r1,r2) +static void _stxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1) +static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# endif +# define jmpr(r0) _jmpr(_jit,r0) +static void _jmpr(jit_state_t*,jit_int32_t); +# define jmpi(i0) _jmpi(_jit,i0) +static jit_word_t _jmpi(jit_state_t*,jit_word_t); +# define jmpi_p(i0) _jmpi_p(_jit,i0) +static jit_word_t _jmpi_p(jit_state_t*,jit_word_t) maybe_unused; +# if _CALL_SYSV +# define callr(r0,i0) _callr(_jit,r0,i0) +static void _callr(jit_state_t*,jit_int32_t,jit_int32_t); +# define calli(i0,i1) _calli(_jit,i0,i1) +static void _calli(jit_state_t*,jit_word_t,jit_int32_t); +# define calli_p(i0,i1) _calli_p(_jit,i0,i1) +static jit_word_t _calli_p(jit_state_t*,jit_word_t,jit_int32_t); +# else +# define callr(r0) _callr(_jit,r0) +static void _callr(jit_state_t*,jit_int32_t); +# define calli(i0) _calli(_jit,i0) +static void _calli(jit_state_t*,jit_word_t); +# define calli_p(i0) _calli_p(_jit,i0) +static jit_word_t _calli_p(jit_state_t*,jit_word_t); +#endif +# define prolog(node) _prolog(_jit, node) +static void _prolog(jit_state_t*, jit_node_t*); +# define epilog(node) _epilog(_jit, node) +static void _epilog(jit_state_t*, jit_node_t*); +# define vastart(r0) _vastart(_jit, r0) +static void _vastart(jit_state_t*, jit_int32_t); +# define vaarg(r0, r1) _vaarg(_jit, r0, r1) +static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t); +# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1) +static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t); +# define patch_at(i,l) _patch_at(_jit,i,l) +static void _patch_at(jit_state_t*,jit_word_t,jit_word_t); +#endif + +#if CODE +# define _u16(v) ((v) & 0xffff) +# define _u26(v) ((v) & 0x3ffffff) +static void +_FXO(jit_state_t *_jit, int o, int d, int a, int b, int e, int x, int r) +{ + assert(!(o & ~((1 << 6) - 1))); + assert(!(d & ~((1 << 5) - 1))); + assert(!(a & ~((1 << 5) - 1))); + assert(!(b & ~((1 << 5) - 1))); + assert(!(e & ~((1 << 1) - 1))); + assert(!(x & ~((1 << 9) - 1))); + assert(!(r & ~((1 << 1) - 1))); + ii((o<<26)|(d<<21)|(a<<16)|(b<<11)|(e<<10)|(x<<1)|r); +} + +static void +_FDs(jit_state_t *_jit, int o, int d, int a, int s) +{ + assert(!(o & ~((1 << 6) - 1))); + assert(!(d & ~((1 << 5) - 1))); + assert(!(a & ~((1 << 5) - 1))); + assert(can_sign_extend_short_p(s)); + ii((o<<26)|(d<<21)|(a<<16)|_u16(s)); +} + +static void +_FDu(jit_state_t *_jit, int o, int d, int a, int s) +{ + assert(!(o & ~((1 << 6) - 1))); + assert(!(d & ~((1 << 5) - 1))); + assert(!(a & ~((1 << 5) - 1))); + assert(can_zero_extend_short_p(s)); + ii((o<<26)|(d<<21)|(a<<16)|_u16(s)); +} + +static void +_FX(jit_state_t *_jit, int o, int s, int a, int b, int x, int r) +{ + assert(!(o & ~((1 << 6) - 1))); + assert(!(s & ~((1 << 5) - 1))); + assert(!(a & ~((1 << 5) - 1))); + assert(!(b & ~((1 << 5) - 1))); + assert(!(x & ~((1 << 10) - 1))); + assert(!(r & ~((1 << 1) - 1))); + ii((o<<26)|(s<<21)|(a<<16)|(b<<11)|(x<<1)|r); +} + +static void +_FI(jit_state_t *_jit, int o, int t, int a, int k) +{ + assert(!(o & ~(( 1 << 6) - 1))); + assert(!(t & 3) && can_sign_extend_jump_p(t)); + assert(!(a & ~(( 1 << 1) - 1))); + assert(!(k & ~(( 1 << 1) - 1))); + ii((o<<26)|_u26(t)|(a<<1)|k); +} + +static void +_FB(jit_state_t *_jit, int o, int bo, int bi, int t, int a, int k) +{ + assert(!( o & ~((1 << 6) - 1))); + assert(!(bo & ~((1 << 5) - 1))); + assert(!(bi & ~((1 << 5) - 1))); + assert(!(t & 3) && can_sign_extend_short_p(t)); + assert(!(a & ~(( 1 << 1) - 1))); + assert(!(k & ~(( 1 << 1) - 1))); + ii((o<<26)|(bo<<21)|(bi<<16)|_u16(t)|(a<<1)|k); +} + +static void +_FXL(jit_state_t *_jit, int o, int bo, int bi, int x, int k) +{ + assert(!( o & ~((1 << 6) - 1))); + assert(!(bo & ~((1 << 5) - 1))); + assert(!(bi & ~((1 << 5) - 1))); + assert(!(x & ~(( 1 << 10) - 1))); + assert(!(k & ~(( 1 << 1) - 1))); + ii((o<<26)|(bo<<21)|(bi<<16)|(x<<1)|k); +} + +static void +_FC(jit_state_t *_jit, int o, int d, int l, int a, int b, int x) +{ + assert(!(o & ~((1 << 6) - 1))); + assert(!(d & ~((1 << 3) - 1))); + assert(!(l & ~((1 << 1) - 1))); + assert(!(a & ~((1 << 5) - 1))); + assert(!(b & ~((1 << 5) - 1))); + assert(!(x & ~((1 << 10) - 1))); + ii((o<<26)|(d<<23)|(l<<21)|(a<<16)|(b<<11)|(x<<1)); +} + +static void +_FCI(jit_state_t *_jit, int o, int d, int l, int a, int s) +{ + assert(!(o & ~((1 << 6) - 1))); + assert(!(d & ~((1 << 3) - 1))); + assert(!(l & ~((1 << 1) - 1))); + assert(!(a & ~((1 << 5) - 1))); + if (o == 11) assert(can_sign_extend_short_p(s)); + else if (o == 10) assert(can_zero_extend_short_p(s)); +#if DEBUG + else abort(); +#endif + ii((o<<26)|(d<<23)|(l<<21)|(a<<16)|_u16(s)); +} + +static void +_FXFX(jit_state_t *_jit, int o, int d, int x, int f) +{ + assert(!(o & ~((1 << 6) - 1))); + assert(!(d & ~((1 << 5) - 1))); + assert(!(x & ~((1 << 10) - 1))); + assert(!(f & ~((1 << 10) - 1))); + ii((o<<26)|(d<<21)|(x<<11)|(f<<1)); +} + +static void +_FM(jit_state_t *_jit, int o, int s, int a, int h, int b, int e, int r) +{ + assert(!(o & ~((1 << 6) - 1))); + assert(!(s & ~((1 << 5) - 1))); + assert(!(a & ~((1 << 5) - 1))); + assert(!(h & ~((1 << 5) - 1))); + assert(!(b & ~((1 << 5) - 1))); + assert(!(e & ~((1 << 5) - 1))); + assert(!(r & ~((1 << 1) - 1))); + ii((o<<26)|(s<<21)|(a<<16)|(h<<11)|(b<<6)|(e<<1)|r); +} + +# if __WORDSIZE == 64 +static void +_FMDS(jit_state_t *_jit, int o, int s, int a, int b, int e, int x, int r) +{ + assert(!(o & ~((1 << 6) - 1))); + assert(!(s & ~((1 << 5) - 1))); + assert(!(a & ~((1 << 5) - 1))); + assert(!(b & ~((1 << 5) - 1))); + assert(!(e & ~((1 << 6) - 1))); + assert(!(x & ~((1 << 4) - 1))); + assert(!(r & ~((1 << 1) - 1))); + e = (e >> 5) | ((e << 1) & 63); + ii((o<<26)|(s<<21)|(a<<16)|(b<<11)|(e<<5)|(x<<1)|r); +} + +static void +_FMD(jit_state_t *_jit, int o, int s, int a, int h, int e, int x, int i, int r) +{ + assert(!(o & ~((1 << 6) - 1))); + assert(!(s & ~((1 << 5) - 1))); + assert(!(a & ~((1 << 5) - 1))); + assert(!(h & ~((1 << 5) - 1))); + assert(!(e & ~((1 << 6) - 1))); + assert(!(x & ~((1 << 3) - 1))); + assert(!(i & ~((1 << 1) - 1))); + assert(!(r & ~((1 << 1) - 1))); + e = (e >> 5) | ((e << 1) & 63); + ii((o<<26)|(s<<21)|(a<<16)|(h<<11)|(e<<5)|(x<<2)|(i<<1)|r); +} + +static void +_FXS(jit_state_t *_jit, int o, int s, int a, int h, int x, int i, int r) +{ + assert(!(o & ~((1 << 6) - 1))); + assert(!(s & ~((1 << 5) - 1))); + assert(!(a & ~((1 << 5) - 1))); + assert(!(h & ~((1 << 5) - 1))); + assert(!(x & ~((1 << 9) - 1))); + assert(!(i & ~((1 << 1) - 1))); + assert(!(r & ~((1 << 1) - 1))); + ii((o<<26)|(s<<21)|(a<<16)|(h<<11)|(x<<2)|(i<<1)|r); +} +#endif + +#if !DEBUG +/* + * Use the sequence commented at + * http://tenfourfox.blogspot.com/2011/04/attention-g5-owners-your-javascript-no.html + */ +static void +_MCRXR(jit_state_t *_jit, jit_int32_t cr) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + MFXER(rn(reg)); + MTCRF(128, rn(reg)); + RLWINM(rn(reg), rn(reg), 0, 0, 28); + MTXER(rn(reg)); + jit_unget_reg(reg); +} +#endif + +static void +_nop(jit_state_t *_jit, jit_int32_t i0) +{ + for (; i0 > 0; i0 -= 4) + NOP(); + assert(i0 == 0); +} + +static void +_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + MR(r0, r1); +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + if (can_sign_extend_short_p(i0)) + LI(r0, i0); + else { + if (can_sign_extend_int_p(i0)) + LIS(r0, (jit_int16_t)(i0 >> 16)); + else if (can_zero_extend_int_p(i0)) { + if (i0 & 0xffff0000) { + ORI(r0, r0, (jit_uint16_t)(i0 >> 16)); + SLWI(r0, r0, 16); + } + } +# if __WORDSIZE == 64 + else { + movi(r0, (jit_uint32_t)(i0 >> 32)); + if (i0 & 0xffff0000) { + SLDI(r0, r0, 16); + ORI(r0, r0, (jit_uint16_t)(i0 >> 16)); + SLDI(r0, r0, 16); + } + else + SLDI(r0, r0, 32); + } +# endif + if (i0 & 0xffff) + ORI(r0, r0, (jit_uint16_t)i0); + } +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t word = _jit->pc.w; +# if __WORDSIZE == 32 + LIS(r0, (jit_int16_t)(i0 >> 16)); + ORI(r0, r0, (jit_uint16_t)i0); +# else + LIS(r0, (jit_int16_t)(i0 >> 48)); + ORI(r0, r0, (jit_uint16_t)(i0 >> 32)); + SLDI(r0, r0, 16); + ORI(r0, r0, (jit_uint16_t)(i0 >> 16)); + SLDI(r0, r0, 16); + ORI(r0, r0, (jit_uint16_t)i0); +# endif + return (word); +} + +# if __BYTE_ORDER == __LITTLE_ENDIAN +static void +_htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + rshi(rn(t0), r1, 8); + andi(r0, r1, 0xff); + andi(rn(t0), rn(t0), 0xff); + lshi(r0, r0, 8); + orr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + ROTLWI(rn(reg), r1, 8); + RLWIMI(rn(reg), r1, 24, 0, 7); + RLWIMI(rn(reg), r1, 24, 16, 23); + CLRLDI(r0, rn(reg), 32); + jit_unget_reg(reg); +} + +# if __WORDSIZE == 64 +static void +_htonr_ul(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + rshi_u(rn(reg), r1, 32); + htonr_ui(r0, r1); + htonr_ui(rn(reg), rn(reg)); + lshi(r0, r0, 32); + orr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} +# endif +# endif + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + ADDI(r0, r1, i0); + else if (can_zero_extend_int_p(i0) && !(i0 & 0x0000ffff)) + ADDIS(r0, r1, i0 >> 16); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ADD(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + ADDIC(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ADDC(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ADDE(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + jit_word_t ni0 = -i0; + if (can_sign_extend_short_p(ni0)) + ADDI(r0, r1, ni0); + else if (can_zero_extend_int_p(ni0) && !(ni0 & 0x0000ffff)) + ADDIS(r0, r1, ni0 >> 16); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + SUB(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + SUBC(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + SUBE(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + subi(r0, r1, i0); + negr(r0, r0); +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + MULLI(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + mulr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_iqmulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + jit_int32_t reg; + if (r0 == r2 || r0 == r3) { + reg = jit_get_reg(jit_class_gpr); + mullr(rn(reg), r2, r3); + } + else + mullr(r0, r2, r3); + if (sign) + mulhr(r1, r2, r3); + else + mulhr_u(r1, r2, r3); + if (r0 == r2 || r0 == r3) { + movr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_iqmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iqmulr(r0, r1, r2, rn(reg), sign); + jit_unget_reg(reg); +} + +static void +_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + divr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + divr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_iqdivr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + jit_int32_t sv0, rg0; + jit_int32_t sv1, rg1; + + if (r0 == r2 || r0 == r3) { + sv0 = jit_get_reg(jit_class_gpr); + rg0 = rn(sv0); + } + else + rg0 = r0; + if (r1 == r2 || r1 == r3) { + sv1 = jit_get_reg(jit_class_gpr); + rg1 = rn(sv1); + } + else + rg1 = r1; + + if (sign) + divr(rg0, r2, r3); + else + divr_u(rg0, r2, r3); + mulr(rg1, r3, rg0); + subr(rg1, r2, rg1); + if (rg0 != r0) { + movr(r0, rg0); + jit_unget_reg(sv0); + } + if (rg1 != r1) { + movr(r1, rg1); + jit_unget_reg(sv1); + } +} + +static void +_iqdivi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iqdivr(r0, r1, r2, rn(reg), sign); + jit_unget_reg(reg); +} + +static void +_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r1 || r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + divr(rn(reg), r1, r2); + mulr(rn(reg), r2, rn(reg)); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + else { + divr(r0, r1, r2); + mulr(r0, r2, r0); + subr(r0, r1, r0); + } +} + +static void +_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r1 || r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + divr_u(rn(reg), r1, r2); + mulr(rn(reg), r2, rn(reg)); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + else { + divr_u(r0, r1, r2); + mulr(r0, r2, r0); + subr(r0, r1, r0); + } +} + +static void +_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_zero_extend_short_p(i0)) + ANDI_(r0, r1, i0); + else if (can_zero_extend_int_p(i0) && !(i0 & 0x0000ffff)) + ANDIS_(r0, r1, (jit_uword_t)i0 >> 16); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + AND(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_zero_extend_short_p(i0)) + ORI(r0, r1, i0); + else if (can_zero_extend_int_p(i0) && !(i0 & 0x0000ffff)) + ORIS(r0, r1, (jit_uword_t)i0 >> 16); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + OR(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_zero_extend_short_p(i0)) + XORI(r0, r1, i0); + else if (can_zero_extend_int_p(i0) && !(i0 & 0x0000ffff)) + XORIS(r0, r1, (jit_uword_t)i0 >> 16); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + XOR(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0 == 0) + movr(r0, r1); + else { +# if __WORDSIZE == 32 + SLWI(r0, r1, i0); +# else + SLDI(r0, r1, i0); +# endif + } +} + +static void +_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0 == 0) + movr(r0, r1); + else { +# if __WORDSIZE == 32 + SRAWI(r0, r1, i0); +# else + SRADI(r0, r1, i0); +# endif + } +} + +static void +_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0 == 0) + movr(r0, r1); + else { +# if __WORDSIZE == 32 + SRWI(r0, r1, i0); +# else + SRDI(r0, r1, i0); +# endif + } +} + +static void +_ltr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMPW(r1, r2); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_LT); +} + +static void +_lti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + CMPWI(r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMPW(r1, rn(reg)); + jit_unget_reg(reg); + } + MFCR(r0); + EXTRWI(r0, r0, 1, CR_LT); +} + +static void +_ltr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMPLW(r1, r2); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_LT); +} + +static void +_lti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_zero_extend_short_p(i0)) + CMPLWI(r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMPLW(r1, rn(reg)); + jit_unget_reg(reg); + } + MFCR(r0); + EXTRWI(r0, r0, 1, CR_LT); +} + +static void +_ler(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMPW(r1, r2); + CRNOT(CR_GT, CR_GT); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_GT); +} + +static void +_lei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + CMPWI(r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMPW(r1, rn(reg)); + jit_unget_reg(reg); + } + CRNOT(CR_GT, CR_GT); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_GT); +} + +static void +_ler_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMPLW(r1, r2); + CRNOT(CR_GT, CR_GT); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_GT); +} + +static void +_lei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_zero_extend_short_p(i0)) + CMPLWI(r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMPLW(r1, rn(reg)); + jit_unget_reg(reg); + } + CRNOT(CR_GT, CR_GT); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_GT); +} + +static void +_eqr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMPW(r1, r2); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_EQ); +} + +static void +_eqi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + CMPWI(r1, i0); + else if (can_zero_extend_short_p(i0)) + CMPLWI(r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMPW(r1, rn(reg)); + jit_unget_reg(reg); + } + MFCR(r0); + EXTRWI(r0, r0, 1, CR_EQ); +} + +static void +_ger(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMPW(r1, r2); + CRNOT(CR_LT, CR_LT); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_LT); +} + +static void +_gei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + CMPWI(r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMPW(r1, rn(reg)); + jit_unget_reg(reg); + } + CRNOT(CR_LT, CR_LT); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_LT); +} + +static void +_ger_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMPLW(r1, r2); + CRNOT(CR_LT, CR_LT); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_LT); +} + +static void +_gei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_zero_extend_short_p(i0)) + CMPLWI(r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMPLW(r1, rn(reg)); + jit_unget_reg(reg); + } + CRNOT(CR_LT, CR_LT); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_LT); +} + +static void +_gtr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMPW(r1, r2); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_GT); +} + +static void +_gti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + CMPWI(r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMPW(r1, rn(reg)); + jit_unget_reg(reg); + } + MFCR(r0); + EXTRWI(r0, r0, 1, CR_GT); +} + +static void +_gtr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMPLW(r1, r2); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_GT); +} + +static void +_gti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_zero_extend_short_p(i0)) + CMPLWI(r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMPLW(r1, rn(reg)); + jit_unget_reg(reg); + } + MFCR(r0); + EXTRWI(r0, r0, 1, CR_GT); +} + +static void +_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMPW(r1, r2); + CRNOT(CR_EQ, CR_EQ); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_EQ); +} + +static void +_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_short_p(i0)) + CMPWI(r1, i0); + else if (can_zero_extend_short_p(i0)) + CMPLWI(r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + CMPW(r1, rn(reg)); + jit_unget_reg(reg); + } + CRNOT(CR_EQ, CR_EQ); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_EQ); +} + +static jit_word_t +_bltr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + CMPW(r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLT(d); + return (w); +} + +static jit_word_t +_blti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + jit_word_t d, w; + if (can_sign_extend_short_p(i1)) + CMPWI(r0, i1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMPW(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLT(d); + return (w); +} + +static jit_word_t +_bltr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + CMPLW(r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLT(d); + return (w); +} + +static jit_word_t +_blti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + jit_word_t d, w; + if (can_zero_extend_short_p(i1)) + CMPLWI(r0, i1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMPLW(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLT(d); + return (w); +} + +static jit_word_t +_bler(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + CMPW(r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLE(d); + return (w); +} + +static jit_word_t +_blei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + jit_word_t d, w; + if (can_sign_extend_short_p(i1)) + CMPWI(r0, i1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMPW(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLE(d); + return (w); +} + +static jit_word_t +_bler_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + CMPLW(r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLE(d); + return (w); +} + +static jit_word_t +_blei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + jit_word_t d, w; + if (can_zero_extend_short_p(i1)) + CMPLWI(r0, i1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMPLW(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLE(d); + return (w); +} + +static jit_word_t +_beqr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + CMPW(r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BEQ(d); + return (w); +} + +static jit_word_t +_beqi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + jit_word_t d, w; + if (can_sign_extend_short_p(i1)) + CMPWI(r0, i1); + else if (can_zero_extend_short_p(i1)) + CMPLWI(r0, i1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMPW(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = (i0 - w) & ~3; + BEQ(d); + return (w); +} + +static jit_word_t +_bger(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + CMPW(r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGE(d); + return (w); +} + +static jit_word_t +_bgei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + jit_word_t d, w; + if (can_sign_extend_short_p(i1)) + CMPWI(r0, i1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMPW(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGE(d); + return (w); +} + +static jit_word_t +_bger_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + CMPLW(r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGE(d); + return (w); +} + +static jit_word_t +_bgei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + jit_word_t d, w; + if (can_zero_extend_short_p(i1)) + CMPLWI(r0, i1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMPLW(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGE(d); + return (w); +} + +static jit_word_t +_bgtr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + CMPW(r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGT(d); + return (w); +} + +static jit_word_t +_bgti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + jit_word_t d, w; + if (can_sign_extend_short_p(i1)) + CMPWI(r0, i1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMPW(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGT(d); + return (w); +} + +static jit_word_t +_bgtr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + CMPLW(r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGT(d); + return (w); +} + +static jit_word_t +_bgti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + jit_word_t d, w; + if (can_zero_extend_short_p(i1)) + CMPLWI(r0, i1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMPLW(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGT(d); + return (w); +} + +static jit_word_t +_bner(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + CMPW(r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BNE(d); + return (w); +} + +static jit_word_t +_bnei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + jit_word_t d, w; + if (can_sign_extend_short_p(i1)) + CMPWI(r0, i1); + else if (can_zero_extend_short_p(i1)) + CMPLWI(r0, i1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + CMPW(r0, rn(reg)); + jit_unget_reg(reg); + } + w = _jit->pc.w; + d = (i0 - w) & ~3; + BNE(d); + return (w); +} + +static jit_word_t +_bmsr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + andr(rn(reg), r0, r1); + w = bnei(i0, rn(reg), 0); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bmsi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + andi(rn(reg), r0, i1); + w = bnei(i0, rn(reg), 0); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bmcr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + andr(rn(reg), r0, r1); + w = beqi(i0, rn(reg), 0); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bmci(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + andi(rn(reg), r0, i1); + w = beqi(i0, rn(reg), 0); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_boaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + ADDO(r0, r0, r1); + MCRXR(CR_0); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGT(d); /* GT = bit 1 of XER = OV */ + return (w); +} + +static jit_word_t +_boaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = boaddr(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bxaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + ADDO(r0, r0, r1); + MCRXR(CR_0); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLE(d); + return (w); +} + +static jit_word_t +_bxaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bxaddr(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bosubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + SUBO(r0, r0, r1); + MCRXR(CR_0); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGT(d); + return (w); +} + +static jit_word_t +_bosubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bosubr(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bxsubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + SUBO(r0, r0, r1); + MCRXR(CR_0); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLE(d); + return (w); +} + +static jit_word_t +_bxsubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bxsubr(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_boaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + ADDC(r0, r0, r1); + MCRXR(CR_0); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BEQ(d); /* EQ = bit 2 of XER = CA */ + return (w); +} + +static jit_word_t +_boaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + jit_word_t d, w; + if (can_sign_extend_short_p(i1)) { + ADDIC(r0, r0, i1); + MCRXR(CR_0); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BEQ(d); + return (w); + } + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = boaddr_u(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bxaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + ADDC(r0, r0, r1); + MCRXR(CR_0); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BNE(d); + return (w); +} + +static jit_word_t +_bxaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + jit_word_t d, w; + if (can_sign_extend_short_p(i1)) { + ADDIC(r0, r0, i1); + MCRXR(CR_0); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BNE(d); + return (w); + } + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bxaddr_u(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bosubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + SUBC(r0, r0, r1); + MCRXR(CR_0); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BNE(d); /* PPC uses "carry" not "borrow" */ + return (w); +} + +static jit_word_t +_bosubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bosubr_u(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bxsubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + SUBC(r0, r0, r1); + MCRXR(CR_0); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BEQ(d); + return (w); +} + +static jit_word_t +_bxsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bxsubr_u(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_ldr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + ldr_uc(r0, r1); + extr_c(r0, r0); +} + +static void +_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + ldi_uc(r0, i0); + extr_c(r0, r0); +} + +static void +_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + ldxr_uc(r0, r1, r2); + extr_c(r0, r0); +} + +static void +_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi_uc(r0, r1, i0); + extr_c(r0, r0); +} + +static void +_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + LBZ(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + LBZ(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r1 == _R0_REGNO) { + if (r2 != _R0_REGNO) + LBZX(r0, r2, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LBZX(r0, rn(reg), r2); + jit_unget_reg(reg); + } + } + else + LBZX(r0, r1, r2); +} + +static void +_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + ldr_uc(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r1 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LBZ(r0, rn(reg), i0); + jit_unget_reg(reg); + } + else + LBZ(r0, r1, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_uc(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + LHA(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + LHA(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r1 == _R0_REGNO) { + if (r2 != _R0_REGNO) + LHAX(r0, r2, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LHAX(r0, rn(reg), r2); + jit_unget_reg(reg); + } + } + else + LHAX(r0, r1, r2); +} + +static void +_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + ldr_s(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r1 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LHA(r0, rn(reg), i0); + jit_unget_reg(reg); + } + else + LHA(r0, r1, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_s(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + LHZ(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + LHZ(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r1 == _R0_REGNO) { + if (r2 != _R0_REGNO) + LHZX(r0, r2, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LHZX(r0, rn(reg), r2); + jit_unget_reg(reg); + } + } + else + LHZX(r0, r1, r2); +} + +static void +_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + ldr_us(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r1 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LHZ(r0, rn(reg), i0); + jit_unget_reg(reg); + } + else + LHZ(r0, r1, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_us(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +# if __WORDSIZE == 32 +static void +_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + LWZ(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + LWZ(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r1 == _R0_REGNO) { + if (r2 != _R0_REGNO) + LWZX(r0, r2, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LWZX(r0, rn(reg), r2); + jit_unget_reg(reg); + } + } + else + LWZX(r0, r1, r2); +} + +static void +_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + ldr_i(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r1 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LWZ(r0, rn(reg), i0); + jit_unget_reg(reg); + } + else + LWZ(r0, r1, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_i(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +# else +static void +_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + LWA(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + LWA(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r1 == _R0_REGNO) { + if (r2 != _R0_REGNO) + LWZX(r0, r2, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LWAX(r0, rn(reg), r2); + jit_unget_reg(reg); + } + } + else + LWZX(r0, r1, r2); +} + +static void +_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + ldr_i(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r1 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LWA(r0, rn(reg), i0); + jit_unget_reg(reg); + } + else + LWA(r0, r1, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_i(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + LWZ(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + LWZ(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r1 == _R0_REGNO) { + if (r2 != _R0_REGNO) + LWZX(r0, r2, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LWZX(r0, rn(reg), r2); + jit_unget_reg(reg); + } + } + else + LWZX(r0, r1, r2); +} + +static void +_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + ldr_i(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r1 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LWZ(r0, rn(reg), i0); + jit_unget_reg(reg); + } + else + LWZ(r0, r1, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_ui(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + LD(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + LD(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r1 == _R0_REGNO) { + if (r2 != _R0_REGNO) + LDX(r0, r2, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LDX(r0, rn(reg), r2); + jit_unget_reg(reg); + } + } + else + LDX(r0, r1, r2); +} + +static void +_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + ldr_l(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r1 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LD(r0, rn(reg), i0); + jit_unget_reg(reg); + } + else + LD(r0, r1, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_l(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} +# endif + +static void +_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + STB(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + STB(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_c(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == _R0_REGNO) { + if (r1 != _R0_REGNO) + STBX(r2, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r0); + STBX(r2, rn(reg), r1); + jit_unget_reg(reg); + } + } + else + STBX(r2, r0, r1); +} + +static void +_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0 == 0) + str_c(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r0 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), i0); + STB(r1, rn(reg), i0); + jit_unget_reg(reg); + } + else + STB(r1, r0, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_c(rn(reg), r0, r1); + jit_unget_reg(reg); + } +} + +static void +_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + STH(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + STH(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_s(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == _R0_REGNO) { + if (r1 != _R0_REGNO) + STHX(r2, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r0); + STHX(r2, rn(reg), r1); + jit_unget_reg(reg); + } + } + else + STHX(r2, r0, r1); +} + +static void +_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0 == 0) + str_s(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r0 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), i0); + STH(r1, rn(reg), i0); + jit_unget_reg(reg); + } + else + STH(r1, r0, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_s(rn(reg), r0, r1); + jit_unget_reg(reg); + } +} + +static void +_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + STW(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + STW(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_i(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == _R0_REGNO) { + if (r1 != _R0_REGNO) + STWX(r2, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r0); + STWX(r2, rn(reg), r1); + jit_unget_reg(reg); + } + } + else + STWX(r2, r0, r1); +} + +static void +_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0 == 0) + str_i(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r0 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), i0); + STW(r1, rn(reg), i0); + jit_unget_reg(reg); + } + else + STW(r1, r0, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_i(rn(reg), r0, r1); + jit_unget_reg(reg); + } +} + +# if __WORDSIZE == 64 +static void +_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + STD(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + STD(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_l(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_stxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == _R0_REGNO) { + if (r1 != _R0_REGNO) + STDX(r2, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r0); + STDX(r2, rn(reg), r1); + jit_unget_reg(reg); + } + } + else + STDX(r2, r0, r1); +} + +static void +_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0 == 0) + str_l(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r0 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), i0); + STD(r1, rn(reg), i0); + jit_unget_reg(reg); + } + else + STD(r1, r0, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_l(rn(reg), r0, r1); + jit_unget_reg(reg); + } +} +# endif + +static void +_jmpr(jit_state_t *_jit, jit_int32_t r0) +{ +#if 0 + MTLR(r0); + BLR(); +#else + MTCTR(r0); + BCTR(); +#endif +} + +/* pc relative jump */ +static jit_word_t +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_int32_t reg; + jit_word_t w, d; + w = _jit->pc.w; + d = (i0 - w) & ~3; + if (can_sign_extend_jump_p(d)) + B(d); + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + w = movi_p(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +/* absolute jump */ +static jit_word_t +_jmpi_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + w = movi_p(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_callr(jit_state_t *_jit, jit_int32_t r0 +# if _CALL_SYSV + , jit_int32_t varargs +# endif + ) +{ +# if _CALL_AIXDESC + stxi(sizeof(void*) * 5, _SP_REGNO, _R2_REGNO); + /* FIXME Pretend to not know about r11? */ + if (r0 == _R0_REGNO) { + movr(_R11_REGNO, _R0_REGNO); + ldxi(_R2_REGNO, _R11_REGNO, sizeof(void*)); + ldxi(_R11_REGNO, _R11_REGNO, sizeof(void*) * 2); + } + else { + ldxi(_R2_REGNO, r0, sizeof(void*)); + ldxi(_R11_REGNO, r0, sizeof(void*) * 2); + } + ldr(r0, r0); +# else +# if _CALL_SYSV + /* Tell double arguments were passed in registers. */ + if (varargs) + CREQV(6, 6, 6); +# endif + movr(_R12_REGNO, r0); +# endif + + MTCTR(r0); + BCTRL(); + +# if _CALL_AIXDESC + ldxi(_R2_REGNO, _SP_REGNO, sizeof(void*) * 5); +# endif +} + +/* assume fixed address or reachable address */ +static void +_calli(jit_state_t *_jit, jit_word_t i0 +# if _CALL_SYSV + , jit_int32_t varargs +# endif + ) +{ +# if _CALL_SYSV + jit_word_t d; + d = (i0 - _jit->pc.w) & ~3; + if (can_sign_extend_jump_p(d)) + BL(d); + else +# endif + { + movi(_R12_REGNO, i0); + callr(_R12_REGNO +# if _CALL_SYSV + , varargs +# endif + ); + } +} + +/* absolute jump */ +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0 +# if _CALL_SYSV + , jit_int32_t varargs +# endif + ) +{ + jit_word_t w; + w = movi_p(_R12_REGNO, i0); + callr(_R12_REGNO +# if _CALL_SYSV + , varargs +# endif + ); + return (w); +} + +/* order is not guaranteed to be sequential */ +static jit_int32_t save[] = { + _R14, _R15, _R16, _R17, _R18, _R19, _R20, _R21, _R22, + _R23, _R24, _R25, _R26, _R27, _R28, _R29, _R30, _R31, +}; + +static void +_prolog(jit_state_t *_jit, jit_node_t *node) +{ + unsigned long regno; + jit_word_t offset; + + if (_jitc->function->define_frame || _jitc->function->assume_frame) { + jit_int32_t frame = -_jitc->function->frame; + assert(_jitc->function->self.aoff >= frame); + if (_jitc->function->assume_frame) + return; + _jitc->function->self.aoff = frame; + } + if (_jitc->function->allocar) { + _jitc->function->self.aoff -= 2 * sizeof(jit_word_t); + _jitc->function->self.aoff &= -16; + } + _jitc->function->stack = ((_jitc->function->self.alen + + _jitc->function->self.size - + _jitc->function->self.aoff) + 15) & -16; + + /* return address */ + MFLR(_R0_REGNO); + + /* params >= %r31+params_offset+(8*sizeof(jit_word_t)) + * alloca < %r31-80 */ + +#if _CALL_SYSV + stxi(sizeof(jit_word_t), _SP_REGNO, _R0_REGNO); +#else + stxi(sizeof(void*) * 2, _SP_REGNO, _R0_REGNO); +#endif + offset = -gpr_save_area; + for (regno = 0; regno < jit_size(save); regno++, offset += sizeof(void*)) { + if (jit_regset_tstbit(&_jitc->function->regset, save[regno])) + stxi(offset, _SP_REGNO, rn(save[regno])); + } + for (offset = 0; offset < 8; offset++) { + if (jit_regset_tstbit(&_jitc->function->regset, _F14 + offset)) + stxi_d(-(gpr_save_area + 8 + offset * 8), + _SP_REGNO, rn(_F14 + offset)); + } + + stxi(-(sizeof(void*)), _SP_REGNO, _FP_REGNO); + + movr(_FP_REGNO, _SP_REGNO); +#if __WORDSIZE == 32 + STWU(_SP_REGNO, _SP_REGNO, -_jitc->function->stack); +#else + STDU(_SP_REGNO, _SP_REGNO, -_jitc->function->stack); +#endif + + if (_jitc->function->allocar) { + regno = jit_get_reg(jit_class_gpr); + movi(rn(regno), _jitc->function->self.aoff); + stxi_i(_jitc->function->aoffoff, _FP_REGNO, rn(regno)); + jit_unget_reg(regno); + } + +#if !_CALL_SYSV + if (_jitc->function->self.call & jit_call_varargs) { + for (regno = _jitc->function->vagp; jit_arg_reg_p(regno); ++regno) + stxi(params_offset + regno * sizeof(jit_word_t), + _FP_REGNO, rn(JIT_RA0 - regno)); + } +#else + if (_jitc->function->self.call & jit_call_varargs) { + for (regno = _jitc->function->vagp; jit_arg_reg_p(regno); ++regno) + stxi(_jitc->function->vaoff + first_gp_offset + + regno * sizeof(jit_word_t), _FP_REGNO, rn(JIT_RA0 - regno)); + for (regno = _jitc->function->vafp; jit_arg_f_reg_p(regno); ++regno) + stxi_d(_jitc->function->vaoff + first_fp_offset + + regno * va_fp_increment, _FP_REGNO, + rn(JIT_FA0 - regno)); + } +#endif +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *node) +{ + unsigned long regno; + jit_word_t offset; + + if (_jitc->function->assume_frame) + return; + if (_jitc->function->allocar) + ldr(_SP_REGNO, _SP_REGNO); + else + addi(_SP_REGNO, _SP_REGNO, _jitc->function->stack); +#if _CALL_SYSV + ldxi(_R0_REGNO, _SP_REGNO, sizeof(jit_word_t)); +#else + ldxi(_R0_REGNO, _SP_REGNO, sizeof(void*) * 2); +#endif + offset = -gpr_save_area; + for (regno = 0; regno < jit_size(save); regno++, offset += sizeof(void*)) { + if (jit_regset_tstbit(&_jitc->function->regset, save[regno])) + ldxi(rn(save[regno]), _SP_REGNO, offset); + } + for (offset = 0; offset < 8; offset++) { + if (jit_regset_tstbit(&_jitc->function->regset, _F14 + offset)) + ldxi_d(rn(_F14 + offset), _SP_REGNO, + -(gpr_save_area + 8 + offset * 8)); + } + + MTLR(_R0_REGNO); + ldxi(_FP_REGNO, _SP_REGNO, -(sizeof(void*))); + + BLR(); +} + +static void +_vastart(jit_state_t *_jit, jit_int32_t r0) +{ +#if !_CALL_SYSV + assert(_jitc->function->self.call & jit_call_varargs); + /* Initialize stack pointer to the first stack argument. */ + addi(r0, _FP_REGNO, _jitc->function->self.size); +#else + jit_int32_t reg; + assert(_jitc->function->self.call & jit_call_varargs); + + /* Return jit_va_list_t in the register argument */ + addi(r0, _FP_REGNO, _jitc->function->vaoff); + reg = jit_get_reg(jit_class_gpr); + + /* Initialize the gp counter. */ + movi(rn(reg), _jitc->function->vagp); + stxi_c(offsetof(jit_va_list_t, ngpr), r0, rn(reg)); + + /* Initialize the fp counter. */ + movi(rn(reg), _jitc->function->vafp); + stxi_c(offsetof(jit_va_list_t, nfpr), r0, rn(reg)); + + /* Initialize overflow pointer to the first stack argument. */ + addi(rn(reg), _FP_REGNO, _jitc->function->self.size); + stxi(offsetof(jit_va_list_t, over), r0, rn(reg)); + + /* Initialize register save area pointer. */ + addi(rn(reg), r0, first_gp_offset); + stxi(offsetof(jit_va_list_t, save), r0, rn(reg)); + + jit_unget_reg(reg); +#endif +} + +static void +_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ +#if !_CALL_SYSV + assert(_jitc->function->self.call & jit_call_varargs); + /* Load argument. */ + ldr(r0, r1); + /* Update va_list. */ + addi(r1, r1, sizeof(jit_word_t)); +#else + jit_int32_t rg0; + jit_int32_t rg1; + jit_word_t ge_code; + jit_word_t lt_code; + + assert(_jitc->function->self.call & jit_call_varargs); + + rg0 = jit_get_reg(jit_class_gpr); + rg1 = jit_get_reg(jit_class_gpr); + + /* Load the gp offset in save area in the first temporary. */ + ldxi_uc(rn(rg0), r1, offsetof(jit_va_list_t, ngpr)); + + /* Jump over if there are no remaining arguments in the save area. */ + ge_code = bgei(_jit->pc.w, rn(rg0), 8); + + /* Update the gp counter. */ + addi(rn(rg1), rn(rg0), 1); + stxi_c(offsetof(jit_va_list_t, ngpr), r1, rn(rg1)); + + /* Load the save area pointer in the second temporary. */ + ldxi(rn(rg1), r1, offsetof(jit_va_list_t, save)); + + /* Load the vararg argument in the first argument. */ + lshi(rn(rg0), rn(rg0), va_gp_shift); + ldxr(r0, rn(rg1), rn(rg0)); + + /* Will only need one temporary register below. */ + jit_unget_reg(rg1); + + /* Jump over overflow code. */ + lt_code = _jit->pc.w; + B(0); + + /* Where to land if argument is in overflow area. */ + patch_at(ge_code, _jit->pc.w); + + /* Load overflow pointer. */ + ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over)); + + /* Load argument. */ + ldr(r0, rn(rg0)); + + /* Update overflow pointer. */ + addi(rn(rg0), rn(rg0), va_gp_increment); + stxi(offsetof(jit_va_list_t, over), r1, rn(rg0)); + + /* Where to land if argument is in save area. */ + patch_at(lt_code, _jit->pc.w); + + jit_unget_reg(rg0); +#endif +} + +static void +_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ +#if !_CALL_SYSV + assert(_jitc->function->self.call & jit_call_varargs); + /* Load argument. */ + ldr_d(r0, r1); + /* Update va_list. */ + addi(r1, r1, sizeof(jit_float64_t)); +#else + jit_int32_t rg0; + jit_int32_t rg1; + jit_word_t ge_code; + jit_word_t lt_code; + + assert(_jitc->function->self.call & jit_call_varargs); + + rg0 = jit_get_reg(jit_class_gpr); + rg1 = jit_get_reg(jit_class_gpr); + + /* Load the fp offset in save area in the first temporary. */ + ldxi_uc(rn(rg0), r1, offsetof(jit_va_list_t, nfpr)); + + /* Jump over if there are no remaining arguments in the save area. */ + ge_code = bgei(_jit->pc.w, rn(rg0), 8); + + /* Update the fp counter. */ + addi(rn(rg1), rn(rg0), 1); + stxi_c(offsetof(jit_va_list_t, nfpr), r1, rn(rg1)); + + /* Load the save area pointer in the second temporary. */ + ldxi(rn(rg1), r1, offsetof(jit_va_list_t, save)); + + /* Load the vararg argument in the first argument. */ + lshi(rn(rg0), rn(rg0), 3); + addi(rn(rg0), rn(rg0), offsetof(jit_va_list_t, first_fp_argument) - + offsetof(jit_va_list_t, first_gp_argument)); + ldxr_d(r0, rn(rg1), rn(rg0)); + + /* Jump over overflow code. */ + lt_code = _jit->pc.w; + B(0); + + /* Where to land if argument is in overflow area. */ + patch_at(ge_code, _jit->pc.w); + + /* Load overflow pointer. */ + ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over)); + +# if __WORDSIZE == 32 + /* Align if required. */ + andi(rn(rg1), rn(rg0), 7); + addr(rn(rg0), rn(rg0), rn(rg1)); +# endif + + /* Load argument. */ + ldr_d(r0, rn(rg0)); + + /* Update overflow pointer. */ + addi(rn(rg0), rn(rg0), va_fp_increment); + stxi(offsetof(jit_va_list_t, over), r1, rn(rg0)); + + /* Where to land if argument is in save area. */ + patch_at(lt_code, _jit->pc.w); + + jit_unget_reg(rg0); + jit_unget_reg(rg1); +#endif +} + +static void +_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label) +{ + jit_word_t d; + union { + jit_int32_t *i; + jit_word_t w; + } u; + u.w = instr; + switch ((u.i[0] & 0xfc000000) >> 26) { + case 16: /* BCx */ + d = label - instr; + assert(!(d & 3)); + if (!can_sign_extend_short_p(d)) { + /* use absolute address */ + assert(can_sign_extend_short_p(label)); + d |= 2; + } + u.i[0] = (u.i[0] & ~0xfffd) | (d & 0xfffe); + break; + case 18: /* Bx */ +#if _CALL_AIXDESC + if (_jitc->jump && (!(u.i[0] & 1))) { /* jmpi label */ + /* zero is used for toc and env, so, quick check + * if this is a "jmpi main" like initial jit + * instruction */ + if (((long *)label)[1] == 0 && ((long *)label)[2] == 0) { + for (d = 0; d < _jitc->prolog.offset; d++) { + /* not so pretty, but hides powerpc + * specific abi intrinsics and/or + * implementation from user */ + if (_jitc->prolog.ptr[d] == label) { + label += sizeof(void*) * 3; + break; + } + } + } + } +#endif + d = label - instr; + assert(!(d & 3)); + if (!can_sign_extend_jump_p(d)) { + /* use absolute address */ + assert(can_sign_extend_jump_p(label)); + d |= 2; + } + u.i[0] = (u.i[0] & ~0x3fffffd) | (d & 0x3fffffe); + break; + case 15: /* LI */ +#if __WORDSIZE == 32 +# define MTCTR_OFF 2 +# define BCTR_OFF 3 +#else +# define MTCTR_OFF 6 +# define BCTR_OFF 7 +#endif +#if _CALL_AIXDESC + /* movi reg label; jmpr reg */ + if (_jitc->jump && +#if 0 + /* check for MLTR(reg) */ + (u.i[MTCTR_OFF] >> 26) == 31 && + ((u.i[MTCTR_OFF] >> 16) & 0x3ff) == 8 && + ((u.i[MTCTR_OFF] >> 1) & 0x3ff) == 467 && + /* check for BLR */ + u.i[BCTR_OFF] == 0x4e800020) { +#else + /* check for MTCTR(reg) */ + (u.i[MTCTR_OFF] >> 26) == 31 && + ((u.i[MTCTR_OFF] >> 16) & 0x3ff) == 9 && + ((u.i[MTCTR_OFF] >> 1) & 0x3ff) == 467 && + /* check for BCTR */ + u.i[BCTR_OFF] == 0x4e800420) { +#endif + /* zero is used for toc and env, so, quick check + * if this is a "jmpi main" like initial jit + * instruction */ + if (((long *)label)[1] == 0 && ((long *)label)[2] == 0) { + for (d = 0; d < _jitc->prolog.offset; d++) { + /* not so pretty, but hides powerpc + * specific abi intrinsics and/or + * implementation from user */ + if (_jitc->prolog.ptr[d] == label) { + label += sizeof(void*) * 3; + break; + } + } + } + } +#endif +#undef BCTR_OFF +#undef MTCTR_OFF +#if __WORDSIZE == 32 + assert(!(u.i[0] & 0x1f0000)); + u.i[0] = (u.i[0] & ~0xffff) | ((label >> 16) & 0xffff); + assert((u.i[1] & 0xfc000000) >> 26 == 24); /* ORI */ + assert(((u.i[1] >> 16) & 0x1f) == ((u.i[1] >> 21) & 0x1f)); + u.i[1] = (u.i[1] & ~0xffff) | (label & 0xffff); +#else + assert(!(u.i[0] & 0x1f0000)); + u.i[0] = (u.i[0] & ~0xffff) | ((label >> 48) & 0xffff); + assert((u.i[1] & 0xfc000000) >> 26 == 24); /* ORI */ + assert(((u.i[1] >> 16) & 0x1f) == ((u.i[1] >> 21) & 0x1f)); + u.i[1] = (u.i[1] & ~0xffff) | ((label >> 32) & 0xffff); + /* not fully validating SLDI */ + assert((u.i[2] & 0xfc000000) >> 26 == 30); /* SLDI */ + assert(((u.i[2] >> 16) & 0x1f) == ((u.i[2] >> 21) & 0x1f)); + assert((u.i[3] & 0xfc000000) >> 26 == 24); /* ORI */ + assert(((u.i[3] >> 16) & 0x1f) == ((u.i[3] >> 21) & 0x1f)); + u.i[3] = (u.i[3] & ~0xffff) | ((label >> 16) & 0xffff); + /* not fully validating SLDI */ + assert((u.i[4] & 0xfc000000) >> 26 == 30); /* SLDI */ + assert(((u.i[4] >> 16) & 0x1f) == ((u.i[4] >> 21) & 0x1f)); + assert((u.i[5] & 0xfc000000) >> 26 == 24); /* ORI */ + assert(((u.i[5] >> 16) & 0x1f) == ((u.i[5] >> 21) & 0x1f)); + u.i[5] = (u.i[5] & ~0xffff) | (label & 0xffff); +#endif + break; + default: + assert(!"unhandled branch opcode"); + } +} +#endif diff --git a/deps/lightning/lib/jit_ppc-fpu.c b/deps/lightning/lib/jit_ppc-fpu.c new file mode 100644 index 0000000..1e84f8e --- /dev/null +++ b/deps/lightning/lib/jit_ppc-fpu.c @@ -0,0 +1,1182 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +#define FA(o,d,a,b,c,x) _FA(_jit,o,d,a,b,c,x,0) +#define FA_(o,d,a,b,c,x) _FA(_jit,o,d,a,b,c,x,1) +static void _FA(jit_state_t*,int,int,int,int,int,int,int); +#define FXFL(o,m,b,x) _FXFL(_jit,o,m,b,x,0) +#define FXFL_(o,m,b,x) _FXFL(_jit,o,m,b,x,1) +static void _FXFL(jit_state_t*,int,int,int,int,int) maybe_unused; +# define FABS(d,b) FX(63,d,0,b,264) +# define FABS_(d,b) FX_(63,d,0,b,264) +# define FADD(d,a,b) FA(63,d,a,b,0,21) +# define FADD_(d,a,b) FA_(63,d,a,b,0,21) +# define FADDS(d,a,b) FA(59,d,a,b,0,21) +# define FADDS_(d,a,b) FA_(59,d,a,b,0,21) +# define FCFID(d,b) FX(63,d,0,b,846) +# define FCMPO(cr,a,b) FC(63,cr,0,a,b,32) +# define FCMPU(cr,a,b) FC(63,cr,0,a,b,0) +# define FCTIW(d,b) FX(63,d,0,b,14) +# define FCTIW_(d,b) FX_(63,d,0,b,14) +# define FCTIWZ(d,b) FX(63,d,0,b,15) +# define FCTIWZ_(d,b) FX_(63,d,0,b,15) +# define FCTID(d,b) FX(63,d,0,b,814) +# define FCTID_(d,b) FX_(63,d,0,b,814) +# define FCTIDZ(d,b) FX(63,d,0,b,815) +# define FCTIDZ_(d,b) FX_(63,d,0,b,815) +# define FDIV(d,a,b) FA(63,d,a,b,0,18) +# define FDIV_(d,a,b) FA_(63,d,a,b,0,18) +# define FDIVS(d,a,b) FA(59,d,a,b,0,18) +# define FDIVS_(d,a,b) FA_(59,d,a,b,0,18) +# define FMADD(d,a,b,c) FA(63,d,a,b,c,29) +# define FMADD_(d,a,b,c) FA(63,d,a,b,c,29) +# define FMADDS(d,a,b,c) FA(59,d,a,b,c,29) +# define FMADDS_(d,a,b,c) FA(59,d,a,b,c,29) +# define FMR(d,b) FX(63,d,0,b,72) +# define FMR_(d,b) FX_(63,d,0,b,72) +# define FMSUB(d,a,b,c) FA(63,d,a,b,c,28) +# define FMSUB_(d,a,b,c) FA(63,d,a,b,c,28) +# define FMSUBS(d,a,b,c) FA(59,d,a,b,c,28) +# define FMSUBS_(d,a,b,c) FA(59,d,a,b,c,28) +# define FMUL(d,a,c) FA(63,d,a,0,c,25) +# define FMUL_(d,a,c) FA_(63,d,a,0,c,25) +# define FMULS(d,a,c) FA(59,d,a,0,c,25) +# define FMULS_(d,a,c) FA_(59,d,a,0,c,25) +# define FNABS(d,b) FX(63,d,0,b,136) +# define FNABS_(d,b) FX_(63,d,0,b,136) +# define FNEG(d,b) FX(63,d,0,b,40) +# define FNEG_(d,b) FX_(63,d,0,b,40) +# define FNMADD(d,a,b,c) FA(63,d,a,b,c,31) +# define FNMADD_(d,a,b,c) FA_(63,d,a,b,c,31) +# define FNMADDS(d,a,b,c) FA(59,d,a,b,c,31) +# define FNMADDS_(d,a,b,c) FA_(59,d,a,b,c,31) +# define FNMSUB(d,a,b,c) FA(63,d,a,b,c,30) +# define FNMSUB_(d,a,b,c) FA_(63,d,a,b,c,30) +# define FNMSUBS(d,a,b,c) FA(59,d,a,b,c,30) +# define FNMSUBS_(d,a,b,c) FA_(59,d,a,b,c,30) +# define FRES(d,b) FA(59,d,0,b,0,24) +# define FRES_(d,b) FA_(59,d,0,b,0,24) +# define FRSP(d,b) FA(63,d,0,b,0,12) +# define FRSP_(d,b) FA_(63,d,0,b,0,12) +# define FRSQTRE(d,b) FA(63,d,0,b,0,26) +# define FRSQTRE_(d,b) FA_(63,d,0,b,0,26) +# define FSEL(d,a,b,c) FA(63,d,a,b,c,23) +# define FSEL_(d,a,b,c) FA_(63,d,a,b,c,23) +# define FSQRT(d,b) FA(63,d,0,b,0,22) +# define FSQRT_(d,b) FA_(63,d,0,b,0,22) +# define FSQRTS(d,b) FA(59,d,0,b,0,22) +# define FSQRTS_(d,b) FA_(59,d,0,b,0,22) +# define FSUB(d,a,b) FA(63,d,a,b,0,20) +# define FSUB_(d,a,b) FA(63,d,a,b,0,20) +# define FSUBS(d,a,b) FA(59,d,a,b,0,20) +# define FSUBS_(d,a,b) FA(59,d,a,b,0,20) +# define LFD(d,a,s) FDs(50,d,a,s) +# define LFDU(d,a,s) FDs(51,d,a,s) +# define LFDUX(d,a,b) FX(31,d,a,b,631) +# define LFDX(d,a,b) FX(31,d,a,b,599) +# define LFS(d,a,s) FDs(48,d,a,s) +# define LFSU(d,a,s) FDs(49,d,a,s) +# define LFSUX(d,a,b) FX(31,d,a,b,567) +# define LFSX(d,a,b) FX(31,d,a,b,535) +# define MCRFS(d,s) FXL(63,d<<2,(s)<<2,64) +# define MFFS(d) FX(63,d,0,0,583) +# define MFFS_(d) FX_(63,d,0,0,583) +# define MTFSB0(d) FX(63,d,0,0,70) +# define MTFSB0_(d) FX_(63,d,0,0,70) +# define MTFSB1(d) FX(63,d,0,0,38) +# define MTFSB1_(d) FX_(63,d,0,0,38) +# define MTFSF(m,b) FXFL(63,m,b,711) +# define MTFSF_(m,b) FXFL_(63,m,b,711) +# define MTFSFI(d,i) FX(63,d<<2,0,i<<1,134) +# define MTFSFI_(d,i) FX_(63,d<<2,0,i<<1,134) +# define STFD(s,a,d) FDs(54,s,a,d) +# define STFDU(s,a,d) FDs(55,s,a,d) +# define STFDUX(s,a,b) FX(31,s,a,b,759) +# define STFDX(s,a,b) FX(31,s,a,b,727) +# define STFIWX(s,a,b) FX(31,s,a,b,983) +# define STFS(s,a,d) FDs(52,s,a,d) +# define STFSU(s,a,d) FDs(53,s,a,d) +# define STFSUX(s,a,b) FX(31,s,a,b,695) +# define STFSX(s,a,b) FX(31,s,a,b,663) +# define movr_f(r0,r1) movr_d(r0,r1) +# define movr_d(r0,r1) _movr_d(_jit,r0,r1) +static void _movr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi_f(r0,i0) _movi_f(_jit,r0,i0) +static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*); +# define movi_d(r0,i0) _movi_d(_jit,r0,i0) +static void _movi_d(jit_state_t*,jit_int32_t,jit_float64_t*); +# define extr_f(r0,r1) extr_d(r0,r1) +# define extr_d(r0,r1) _extr_d(_jit,r0,r1) +static void _extr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define truncr_f(r0,r1) truncr_d(r0,r1) +# define truncr_f_i(r0,r1) truncr_d_i(r0,r1) +# define truncr_d_i(r0,r1) _truncr_d_i(_jit,r0,r1) +static void _truncr_d_i(jit_state_t*,jit_int32_t,jit_int32_t); +# if __WORDSIZE == 32 +# define truncr_d(r0,r1) truncr_d_i(r0,r1) +# else +# define truncr_d(r0,r1) truncr_d_l(r0,r1) +# define truncr_f_l(r0,r1) truncr_d_l(r0,r1) +# define truncr_d_l(r0,r1) _truncr_d_l(_jit,r0,r1) +static void _truncr_d_l(jit_state_t*,jit_int32_t,jit_int32_t); +# endif +# define extr_d_f(r0,r1) FRSP(r0,r1) +# define extr_f_d(r0,r1) movr_d(r0,r1) +# define absr_f(r0,r1) absr_d(r0,r1) +# define absr_d(r0,r1) FABS(r0,r1) +# define negr_f(r0,r1) negr_d(r0,r1) +# define negr_d(r0,r1) FNEG(r0,r1) +# define sqrtr_f(r0,r1) FSQRTS(r0,r1) +# define sqrtr_d(r0,r1) FSQRT(r0,r1) +# define addr_f(r0,r1,r2) FADDS(r0,r1,r2) +# define addr_d(r0,r1,r2) FADD(r0,r1,r2) +# define addi_f(r0,r1,i0) _addi_f(_jit,r0,r1,i0) +static void _addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define addi_d(r0,r1,i0) _addi_d(_jit,r0,r1,i0) +static void _addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define subr_f(r0,r1,r2) FSUBS(r0,r1,r2) +# define subi_f(r0,r1,i0) _subi_f(_jit,r0,r1,i0) +static void _subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define subr_d(r0,r1,r2) FSUB(r0,r1,r2) +# define subi_d(r0,r1,i0) _subi_d(_jit,r0,r1,i0) +static void _subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define rsbr_f(r0,r1,r2) subr_f(r0,r2,r1) +# define rsbi_f(r0,r1,i0) _rsbi_f(_jit,r0,r1,i0) +static void _rsbi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define rsbr_d(r0,r1,r2) subr_d(r0,r2,r1) +# define rsbi_d(r0,r1,i0) _rsbi_d(_jit,r0,r1,i0) +static void _rsbi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define mulr_f(r0,r1,r2) FMULS(r0,r1,r2) +# define muli_f(r0,r1,i0) _muli_f(_jit,r0,r1,i0) +static void _muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define mulr_d(r0,r1,r2) FMUL(r0,r1,r2) +# define muli_d(r0,r1,i0) _muli_d(_jit,r0,r1,i0) +static void _muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define divr_f(r0,r1,r2) FDIVS(r0,r1,r2) +# define divi_f(r0,r1,i0) _divi_f(_jit,r0,r1,i0) +static void _divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define divr_d(r0,r1,r2) FDIV(r0,r1,r2) +# define divi_d(r0,r1,i0) _divi_d(_jit,r0,r1,i0) +static void _divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ltr_f(r0,r1,r2) ltr_d(r0,r1,r2) +# define ltr_d(r0,r1,r2) _ltr_d(_jit,r0,r1,r2) +static void _ltr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lti_f(r0,r1,i0) _lti_f(_jit,r0,r1,i0) +static void _lti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define lti_d(r0,r1,i0) _lti_d(_jit,r0,r1,i0) +static void _lti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ler_f(r0,r1,r2) ler_d(r0,r1,r2) +# define ler_d(r0,r1,r2) _ler_d(_jit,r0,r1,r2) +static void _ler_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lei_f(r0,r1,i0) _lei_f(_jit,r0,r1,i0) +static void _lei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define lei_d(r0,r1,i0) _lei_d(_jit,r0,r1,i0) +static void _lei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define eqr_f(r0,r1,r2) eqr_d(r0,r1,r2) +# define eqr_d(r0,r1,r2) _eqr_d(_jit,r0,r1,r2) +static void _eqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define eqi_f(r0,r1,i0) _eqi_f(_jit,r0,r1,i0) +static void _eqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define eqi_d(r0,r1,i0) _eqi_d(_jit,r0,r1,i0) +static void _eqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ger_f(r0,r1,r2) ger_d(r0,r1,r2) +# define ger_d(r0,r1,r2) _ger_d(_jit,r0,r1,r2) +static void _ger_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gei_f(r0,r1,i0) _gei_f(_jit,r0,r1,i0) +static void _gei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define gei_d(r0,r1,i0) _gei_d(_jit,r0,r1,i0) +static void _gei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define gtr_f(r0,r1,r2) gtr_d(r0,r1,r2) +# define gtr_d(r0,r1,r2) _gtr_d(_jit,r0,r1,r2) +static void _gtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gti_f(r0,r1,i0) _gti_f(_jit,r0,r1,i0) +static void _gti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define gti_d(r0,r1,i0) _gti_d(_jit,r0,r1,i0) +static void _gti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ner_f(r0,r1,r2) ner_d(r0,r1,r2) +# define ner_d(r0,r1,r2) _ner_d(_jit,r0,r1,r2) +static void _ner_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define nei_f(r0,r1,i0) _nei_f(_jit,r0,r1,i0) +static void _nei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define nei_d(r0,r1,i0) _nei_d(_jit,r0,r1,i0) +static void _nei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unltr_f(r0,r1,r2) unltr_d(r0,r1,r2) +# define unltr_d(r0,r1,r2) _unltr_d(_jit,r0,r1,r2) +static void _unltr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unlti_f(r0,r1,i0) _unlti_f(_jit,r0,r1,i0) +static void _unlti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define unlti_d(r0,r1,i0) _unlti_d(_jit,r0,r1,i0) +static void _unlti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unler_f(r0,r1,r2) unler_d(r0,r1,r2) +# define unler_d(r0,r1,r2) _unler_d(_jit,r0,r1,r2) +static void _unler_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unlei_f(r0,r1,i0) _unlei_f(_jit,r0,r1,i0) +static void _unlei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define unlei_d(r0,r1,i0) _unlei_d(_jit,r0,r1,i0) +static void _unlei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define uneqr_f(r0,r1,r2) uneqr_d(r0,r1,r2) +# define uneqr_d(r0,r1,r2) _uneqr_d(_jit,r0,r1,r2) +static void _uneqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define uneqi_f(r0,r1,i0) _uneqi_f(_jit,r0,r1,i0) +static void _uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define uneqi_d(r0,r1,i0) _uneqi_d(_jit,r0,r1,i0) +static void _uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unger_f(r0,r1,r2) unger_d(r0,r1,r2) +# define unger_d(r0,r1,r2) _unger_d(_jit,r0,r1,r2) +static void _unger_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ungei_f(r0,r1,i0) _ungei_f(_jit,r0,r1,i0) +static void _ungei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ungei_d(r0,r1,i0) _ungei_d(_jit,r0,r1,i0) +static void _ungei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ungtr_f(r0,r1,r2) ungtr_d(r0,r1,r2) +# define ungtr_d(r0,r1,r2) _ungtr_d(_jit,r0,r1,r2) +static void _ungtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ungti_f(r0,r1,i0) _ungti_f(_jit,r0,r1,i0) +static void _ungti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ungti_d(r0,r1,i0) _ungti_d(_jit,r0,r1,i0) +static void _ungti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ltgtr_f(r0,r1,r2) ltgtr_d(r0,r1,r2) +# define ltgtr_d(r0,r1,r2) _ltgtr_d(_jit,r0,r1,r2) +static void _ltgtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ltgti_f(r0,r1,i0) _ltgti_f(_jit,r0,r1,i0) +static void _ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ltgti_d(r0,r1,i0) _ltgti_d(_jit,r0,r1,i0) +static void _ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ordr_f(r0,r1,r2) ordr_d(r0,r1,r2) +# define ordr_d(r0,r1,r2) _ordr_d(_jit,r0,r1,r2) +static void _ordr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ordi_f(r0,r1,i0) _ordi_f(_jit,r0,r1,i0) +static void _ordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ordi_d(r0,r1,i0) _ordi_d(_jit,r0,r1,i0) +static void _ordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unordr_f(r0,r1,r2) unordr_d(r0,r1,r2) +# define unordr_d(r0,r1,r2) _unordr_d(_jit,r0,r1,r2) +static void _unordr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unordi_f(r0,r1,i0) _unordi_f(_jit,r0,r1,i0) +static void _unordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define unordi_d(r0,r1,i0) _unordi_d(_jit,r0,r1,i0) +static void _unordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define bltr_f(i0,r0,r1) bltr_d(i0,r0,r1) +# define bltr_d(i0,r0,r1) _bltr_d(_jit,i0,r0,r1) +static jit_word_t _bltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blti_f(i0,r0,i1) _blti_f(_jit,i0,r0,i1) +static jit_word_t _blti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define blti_d(i0,r0,i1) _blti_d(_jit,i0,r0,i1) +static jit_word_t _blti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bler_f(i0,r0,r1) bler_d(i0,r0,r1) +# define bler_d(i0,r0,r1) _bler_d(_jit,i0,r0,r1) +static jit_word_t _bler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blei_f(i0,r0,i1) _blei_f(_jit,i0,r0,i1) +static jit_word_t _blei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define blei_d(i0,r0,i1) _blei_d(_jit,i0,r0,i1) +static jit_word_t _blei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define beqr_f(i0,r0,r1) beqr_d(i0,r0,r1) +# define beqr_d(i0,r0,r1) _beqr_d(_jit,i0,r0,r1) +static jit_word_t _beqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define beqi_f(i0,r0,i1) _beqi_f(_jit,i0,r0,i1) +static jit_word_t _beqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define beqi_d(i0,r0,i1) _beqi_d(_jit,i0,r0,i1) +static jit_word_t _beqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bger_f(i0,r0,r1) bger_d(i0,r0,r1) +# define bger_d(i0,r0,r1) _bger_d(_jit,i0,r0,r1) +static jit_word_t _bger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgei_f(i0,r0,i1) _bgei_f(_jit,i0,r0,i1) +static jit_word_t _bgei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bgei_d(i0,r0,i1) _bgei_d(_jit,i0,r0,i1) +static jit_word_t _bgei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bgtr_f(i0,r0,r1) bgtr_d(i0,r0,r1) +# define bgtr_d(i0,r0,r1) _bgtr_d(_jit,i0,r0,r1) +static jit_word_t _bgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgti_f(i0,r0,i1) _bgti_f(_jit,i0,r0,i1) +static jit_word_t _bgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bgti_d(i0,r0,i1) _bgti_d(_jit,i0,r0,i1) +static jit_word_t _bgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bner_f(i0,r0,r1) bner_d(i0,r0,r1) +# define bner_d(i0,r0,r1) _bner_d(_jit,i0,r0,r1) +static jit_word_t _bner_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bnei_f(i0,r0,i1) _bnei_f(_jit,i0,r0,i1) +static jit_word_t _bnei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bnei_d(i0,r0,i1) _bnei_d(_jit,i0,r0,i1) +static jit_word_t _bnei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bunltr_f(i0,r0,r1) bunltr_d(i0,r0,r1) +# define bunltr_d(i0,r0,r1) _bunltr_d(_jit,i0,r0,r1) +static jit_word_t _bunltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlti_f(i0,r0,i1) _bunlti_f(_jit,i0,r0,i1) +static jit_word_t _bunlti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bunlti_d(i0,r0,i1) _bunlti_d(_jit,i0,r0,i1) +static jit_word_t _bunlti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bunler_f(i0,r0,r1) bunler_d(i0,r0,r1) +# define bunler_d(i0,r0,r1) _bunler_d(_jit,i0,r0,r1) +static jit_word_t _bunler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlei_f(i0,r0,i1) _bunlei_f(_jit,i0,r0,i1) +static jit_word_t _bunlei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bunlei_d(i0,r0,i1) _bunlei_d(_jit,i0,r0,i1) +static jit_word_t _bunlei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define buneqr_f(i0,r0,r1) buneqr_d(i0,r0,r1) +# define buneqr_d(i0,r0,r1) _buneqr_d(_jit,i0,r0,r1) +static jit_word_t _buneqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define buneqi_f(i0,r0,i1) _buneqi_f(_jit,i0,r0,i1) +static jit_word_t _buneqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define buneqi_d(i0,r0,i1) _buneqi_d(_jit,i0,r0,i1) +static jit_word_t _buneqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bunger_f(i0,r0,r1) bunger_d(i0,r0,r1) +# define bunger_d(i0,r0,r1) _bunger_d(_jit,i0,r0,r1) +static jit_word_t _bunger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungei_f(i0,r0,i1) _bungei_f(_jit,i0,r0,i1) +static jit_word_t _bungei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bungei_d(i0,r0,i1) _bungei_d(_jit,i0,r0,i1) +static jit_word_t _bungei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bungtr_f(i0,r0,r1) bungtr_d(i0,r0,r1) +# define bungtr_d(i0,r0,r1) _bungtr_d(_jit,i0,r0,r1) +static jit_word_t _bungtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungti_f(i0,r0,i1) _bungti_f(_jit,i0,r0,i1) +static jit_word_t _bungti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bungti_d(i0,r0,i1) _bungti_d(_jit,i0,r0,i1) +static jit_word_t _bungti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bltgtr_f(i0,r0,r1) bltgtr_d(i0,r0,r1) +# define bltgtr_d(i0,r0,r1) _bltgtr_d(_jit,i0,r0,r1) +static jit_word_t _bltgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bltgti_f(i0,r0,i1) _bltgti_f(_jit,i0,r0,i1) +static jit_word_t _bltgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bltgti_d(i0,r0,i1) _bltgti_d(_jit,i0,r0,i1) +static jit_word_t _bltgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bordr_f(i0,r0,r1) bordr_d(i0,r0,r1) +# define bordr_d(i0,r0,r1) _bordr_d(_jit,i0,r0,r1) +static jit_word_t _bordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bordi_f(i0,r0,i1) _bordi_f(_jit,i0,r0,i1) +static jit_word_t _bordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bordi_d(i0,r0,i1) _bordi_d(_jit,i0,r0,i1) +static jit_word_t _bordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bunordr_f(i0,r0,r1) bunordr_d(i0,r0,r1) +# define bunordr_d(i0,r0,r1) _bunordr_d(_jit,i0,r0,r1) +static jit_word_t _bunordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunordi_f(i0,r0,i1) _bunordi_f(_jit,i0,r0,i1) +static jit_word_t _bunordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bunordi_d(i0,r0,i1) _bunordi_d(_jit,i0,r0,i1) +static jit_word_t _bunordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define ldr_f(r0,r1) LFSX(r0, _R0_REGNO, r1) +# define ldi_f(r0,i0) _ldi_f(_jit,r0,i0) +static void _ldi_f(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_f(r0,r1,r2) _ldxr_f(_jit,r0,r1,r2) +static void _ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_f(r0,r1,i0) _ldxi_f(_jit,r0,r1,i0) +static void _ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_f(r0,r1) STFSX(r1, _R0_REGNO, r0) +# define sti_f(i0,r0) _sti_f(_jit,i0,r0) +static void _sti_f(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_f(r0,r1,r2) _stxr_f(_jit,r0,r1,r2) +static void _stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_f(i0,r0,r1) _stxi_f(_jit,i0,r0,r1) +static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define ldr_d(r0,r1) LFDX(r0, _R0_REGNO, r1) +# define ldi_d(r0,i0) _ldi_d(_jit,r0,i0) +static void _ldi_d(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_d(r0,r1,r2) _ldxr_d(_jit,r0,r1,r2) +static void _ldxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_d(r0,r1,i0) _ldxi_d(_jit,r0,r1,i0) +static void _ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_d(r0,r1) STFDX(r1, _R0_REGNO, r0) +# define sti_d(i0,r0) _sti_d(_jit,i0,r0) +static void _sti_d(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_d(r0,r1,r2) _stxr_d(_jit,r0,r1,r2) +static void _stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_d(i0,r0,r1) _stxi_d(_jit,i0,r0,r1) +static void _stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#endif + +#if CODE +# define _u16(v) ((v) & 0xffff) +static void +_FA(jit_state_t *_jit, int o, int d, int a, int b, int c, int x, int r) +{ + assert(!(o & ~((1 << 6) - 1))); + assert(!(d & ~((1 << 5) - 1))); + assert(!(a & ~((1 << 5) - 1))); + assert(!(b & ~((1 << 5) - 1))); + assert(!(c & ~((1 << 5) - 1))); + assert(!(x & ~((1 << 5) - 1))); + assert(!(r & ~((1 << 1) - 1))); + ii((o<<26)|(d<<21)|(a<<16)|(b<<11)|(c<<6)|(x<<1)|r); +} + +static void +_FXFL(jit_state_t *_jit, int o, int m, int b, int x, int r) +{ + assert(!(o & ~((1 << 6) - 1))); + assert(!(m & ~((1 << 8) - 1))); + assert(!(b & ~((1 << 5) - 1))); + assert(!(x & ~((1 << 10) - 1))); + assert(!(r & ~((1 << 1) - 1))); + ii((o<<26)|(m<<17)|(b<<11)|(x<<1)|r); +} + +static void +_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + FMR(r0,r1); +} + +static void +_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_int32_t reg; + + if (_jitc->no_data) { + data.f = *i0; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.i & 0xffffffff); + stxi_i(alloca_offset - 4, _FP_REGNO, rn(reg)); + jit_unget_reg(reg); + ldxi_f(r0, _FP_REGNO, alloca_offset - 4); + } + else + ldi_f(r0, (jit_word_t)i0); +} + +static void +_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + union { + jit_int32_t i[2]; + jit_word_t w; + jit_float64_t d; + } data; + jit_int32_t reg; + + if (_jitc->no_data) { + data.d = *i0; + reg = jit_get_reg(jit_class_gpr); +# if __WORDSIZE == 32 + movi(rn(reg), data.i[0]); + stxi(alloca_offset - 8, _FP_REGNO, rn(reg)); + movi(rn(reg), data.i[1]); + stxi(alloca_offset - 4, _FP_REGNO, rn(reg)); +# else + movi(rn(reg), data.w); + stxi(alloca_offset - 8, _FP_REGNO, rn(reg)); +# endif + jit_unget_reg(reg); + ldxi_d(r0, _FP_REGNO, alloca_offset - 8); + } + else + ldi_d(r0, (jit_word_t)i0); +} + +/* should only work on newer ppc (fcfid is a ppc64 instruction) */ +static void +_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ +# if __WORDSIZE == 32 + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + rshi(rn(reg), r1, 31); + /* use reserved 8 bytes area */ + stxi(alloca_offset - 4, _FP_REGNO, r1); + stxi(alloca_offset - 8, _FP_REGNO, rn(reg)); + jit_unget_reg(reg); +# else + stxi(alloca_offset - 8, _FP_REGNO, r1); +# endif + ldxi_d(r0, _FP_REGNO, alloca_offset - 8); + FCFID(r0, r0); +} + +static void +_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + FCTIWZ(rn(reg), r1); + /* use reserved 8 bytes area */ + stxi_d(alloca_offset - 8, _FP_REGNO, rn(reg)); + ldxi_i(r0, _FP_REGNO, alloca_offset - 4); + jit_unget_reg(reg); +} + +# if __WORDSIZE == 64 +static void +_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + FCTIDZ(rn(reg), r1); + /* use reserved 8 bytes area */ + stxi_d(alloca_offset - 8, _FP_REGNO, rn(reg)); + ldxi(r0, _FP_REGNO, alloca_offset - 8); + jit_unget_reg(reg); +} +# endif + +# define fpr_opi(name, type, size) \ +static void \ +_##name##i_##type(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, \ + jit_float##size##_t *i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr); \ + movi_##type(rn(reg), i0); \ + name##r_##type(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +# define fpr_bopi(name, type, size) \ +static jit_word_t \ +_b##name##i_##type(jit_state_t *_jit, \ + jit_word_t i0, jit_int32_t r0, \ + jit_float##size##_t *i1) \ +{ \ + jit_word_t word; \ + jit_int32_t reg = jit_get_reg(jit_class_fpr| \ + jit_class_nospill); \ + movi_##type(rn(reg), i1); \ + word = b##name##r_##type(i0, r0, rn(reg)); \ + jit_unget_reg(reg); \ + return (word); \ +} +# define fopi(name) fpr_opi(name, f, 32) +# define fbopi(name) fpr_bopi(name, f, 32) +# define dopi(name) fpr_opi(name, d, 64) +# define dbopi(name) fpr_bopi(name, d, 64) + +fopi(add) +dopi(add) +fopi(sub) +dopi(sub) +fopi(rsb) +dopi(rsb) +fopi(mul) +dopi(mul) +fopi(div) +dopi(div) + +static void +_ltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPO(CR_0, r1, r2); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_LT); +} +fopi(lt) +dopi(lt) + +static void +_ler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPO(CR_0, r1, r2); + CREQV(CR_GT, CR_GT, CR_UN); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_GT); +} +fopi(le) +dopi(le) + +static void +_eqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPO(CR_0, r1, r2); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_EQ); +} +fopi(eq) +dopi(eq) + +static void +_ger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPO(CR_0, r1, r2); + CREQV(CR_LT, CR_LT, CR_UN); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_LT); +} +fopi(ge) +dopi(ge) + +static void +_gtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPO(CR_0, r1, r2); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_GT); +} +fopi(gt) +dopi(gt) + +static void +_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPO(CR_0, r1, r2); + CRNOT(CR_EQ, CR_EQ); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_EQ); +} +fopi(ne) +dopi(ne) + +static void +_unltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPU(CR_0, r1, r2); + CROR(CR_LT, CR_LT, CR_UN); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_LT); +} +fopi(unlt) +dopi(unlt) + +static void +_unler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPU(CR_0, r1, r2); + CRNOT(CR_GT, CR_GT); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_GT); +} +fopi(unle) +dopi(unle) + +static void +_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPU(CR_0, r1, r2); + CROR(CR_EQ, CR_EQ, CR_UN); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_EQ); +} +fopi(uneq) +dopi(uneq) + +static void +_unger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPU(CR_0, r1, r2); + CRNOT(CR_LT, CR_LT); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_LT); +} +fopi(unge) +dopi(unge) + +static void +_ungtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPU(CR_0, r1, r2); + CROR(CR_GT, CR_GT, CR_UN); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_GT); +} +fopi(ungt) +dopi(ungt) + +static void +_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPU(CR_0, r1, r2); + CROR(CR_GT, CR_GT, CR_LT); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_GT); +} +fopi(ltgt) +dopi(ltgt) + +static void +_ordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPU(CR_0, r1, r2); + CRNOT(CR_UN, CR_UN); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_UN); +} +fopi(ord) +dopi(ord) + +static void +_unordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPU(CR_0, r1, r2); + MFCR(r0); + EXTRWI(r0, r0, 1, CR_UN); +} +fopi(unord) +dopi(unord) + +static jit_word_t +_bltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPO(CR_0, r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLT(d); + return (w); +} +fbopi(lt) +dbopi(lt) + +static jit_word_t +_bler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPO(CR_0, r0, r1); + CREQV(CR_GT, CR_GT, CR_UN); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGT(d); + return (w); +} +fbopi(le) +dbopi(le) + +static jit_word_t +_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPO(CR_0, r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BEQ(d); + return (w); +} +fbopi(eq) +dbopi(eq) + +static jit_word_t +_bger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPO(CR_0, r0, r1); + CREQV(CR_LT, CR_LT, CR_UN); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLT(d); + return (w); +} +fbopi(ge) +dbopi(ge) + +static jit_word_t +_bgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPO(CR_0, r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGT(d); + return (w); +} +fbopi(gt) +dbopi(gt) + +static jit_word_t +_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPO(CR_0, r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BNE(d); + return (w); +} +fbopi(ne) +dbopi(ne) + +static jit_word_t +_bunltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPU(CR_0, r0, r1); + CROR(CR_LT, CR_LT, CR_UN); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLT(d); + return (w); +} +fbopi(unlt) +dbopi(unlt) + +static jit_word_t +_bunler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPU(CR_0, r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BLE(d); + return (w); +} +fbopi(unle) +dbopi(unle) + +static jit_word_t +_buneqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPU(CR_0, r0, r1); + CROR(CR_EQ, CR_EQ, CR_UN); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BEQ(d); + return (w); +} +fbopi(uneq) +dbopi(uneq) + +static jit_word_t +_bunger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPU(CR_0, r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGE(d); + return (w); +} +fbopi(unge) +dbopi(unge) + +static jit_word_t +_bungtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPU(CR_0, r0, r1); + CROR(CR_GT, CR_GT, CR_UN); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BGT(d); + return (w); +} +fbopi(ungt) +dbopi(ungt) + +static jit_word_t +_bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPU(CR_0, r0, r1); + CROR(CR_EQ, CR_LT, CR_GT); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BEQ(d); + return (w); +} +fbopi(ltgt) +dbopi(ltgt) + +static jit_word_t +_bordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPU(CR_0, r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BNU(d); + return (w); +} +fbopi(ord) +dbopi(ord) + +static jit_word_t +_bunordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + FCMPU(CR_0, r0, r1); + w = _jit->pc.w; + d = (i0 - w) & ~3; + BUN(d); + return (w); +} +fbopi(unord) +dbopi(unord) + +static void +_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + LFS(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + LFS(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + LFD(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + LFD(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r1 == _R0_REGNO) { + if (r2 != _R0_REGNO) + LFSX(r0, r2, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LFSX(r0, rn(reg), r2); + jit_unget_reg(reg); + } + } + else + LFSX(r0, r1, r2); +} + +static void +_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r1 == _R0_REGNO) { + if (r2 != _R0_REGNO) + LFDX(r0, r2, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LFDX(r0, rn(reg), r2); + jit_unget_reg(reg); + } + } + else + LFDX(r0, r1, r2); +} + +static void +_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + ldr_f(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r1 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LFS(r0, rn(reg), i0); + jit_unget_reg(reg); + } + else + LFS(r0, r1, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_f(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + ldr_d(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r1 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + LFD(r0, rn(reg), i0); + jit_unget_reg(reg); + } + else + LFD(r0, r1, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_d(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + STFS(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + STFS(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_f(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_bool_t inv; + jit_int32_t reg; + jit_word_t lo, hi; + if (can_sign_extend_short_p(i0)) + STFD(r0, _R0_REGNO, i0); + else if (can_sign_extend_int_p(i0)) { + hi = (jit_int16_t)((i0 >> 16) + ((jit_uint16_t)i0 >> 15)); + lo = (jit_int16_t)(i0 - (hi << 16)); + reg = jit_get_reg(jit_class_gpr); + if ((inv = reg == _R0)) reg = jit_get_reg(jit_class_gpr); + LIS(rn(reg), hi); + STFD(r0, rn(reg), lo); + jit_unget_reg(reg); + if (inv) jit_unget_reg(_R0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_d(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == _R0_REGNO) { + if (r1 != _R0_REGNO) + STFSX(r2, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + STFSX(r2, rn(reg), r0); + jit_unget_reg(reg); + } + } + else + STFSX(r2, r0, r1); +} + +static void +_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == _R0_REGNO) { + if (r1 != _R0_REGNO) + STFDX(r2, r1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r0); + STFDX(r2, rn(reg), r1); + jit_unget_reg(reg); + } + } + else + STFDX(r2, r0, r1); +} + +static void +_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0 == 0) + str_f(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r0 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), i0); + STFS(r1, rn(reg), i0); + jit_unget_reg(reg); + } + else + STFS(r1, r0, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_f(rn(reg), r0, r1); + jit_unget_reg(reg); + } +} + +static void +_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (i0 == 0) + str_d(r0, r1); + else if (can_sign_extend_short_p(i0)) { + if (r0 == _R0_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), i0); + STFD(r1, rn(reg), i0); + jit_unget_reg(reg); + } + else + STFD(r1, r0, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_d(rn(reg), r0, r1); + jit_unget_reg(reg); + } +} +#endif diff --git a/deps/lightning/lib/jit_ppc-sz.c b/deps/lightning/lib/jit_ppc-sz.c new file mode 100644 index 0000000..788ac45 --- /dev/null +++ b/deps/lightning/lib/jit_ppc-sz.c @@ -0,0 +1,1627 @@ +#if __WORDSIZE == 32 +#if defined(__powerpc__) +#if __BYTE_ORDER == __BIG_ENDIAN +#if _CALL_SYSV +#define JIT_INSTR_MAX 124 + 0, /* data */ + 0, /* live */ + 0, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 124, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 36, /* va_start */ + 52, /* va_arg */ + 64, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 12, /* addi */ + 4, /* addcr */ + 12, /* addci */ + 4, /* addxr */ + 8, /* addxi */ + 4, /* subr */ + 12, /* subi */ + 4, /* subcr */ + 12, /* subci */ + 4, /* subxr */ + 8, /* subxi */ + 16, /* rsbi */ + 4, /* mulr */ + 12, /* muli */ + 12, /* qmulr */ + 16, /* qmuli */ + 12, /* qmulr_u */ + 16, /* qmuli_u */ + 4, /* divr */ + 12, /* divi */ + 4, /* divr_u */ + 12, /* divi_u */ + 20, /* qdivr */ + 16, /* qdivi */ + 20, /* qdivr_u */ + 16, /* qdivi_u */ + 12, /* remr */ + 20, /* remi */ + 12, /* remr_u */ + 20, /* remi_u */ + 4, /* andr */ + 12, /* andi */ + 4, /* orr */ + 12, /* ori */ + 4, /* xorr */ + 12, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 12, /* ltr */ + 12, /* lti */ + 12, /* ltr_u */ + 16, /* lti_u */ + 16, /* ler */ + 16, /* lei */ + 16, /* ler_u */ + 16, /* lei_u */ + 12, /* eqr */ + 12, /* eqi */ + 16, /* ger */ + 16, /* gei */ + 16, /* ger_u */ + 16, /* gei_u */ + 12, /* gtr */ + 12, /* gti */ + 12, /* gtr_u */ + 12, /* gti_u */ + 16, /* ner */ + 16, /* nei */ + 4, /* movr */ + 8, /* movi */ + 4, /* extr_c */ + 4, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 0, /* extr_i */ + 0, /* extr_ui */ + 4, /* htonr_us */ + 4, /* htonr_ui */ + 0, /* htonr_ul */ + 8, /* ldr_c */ + 12, /* ldi_c */ + 4, /* ldr_uc */ + 8, /* ldi_uc */ + 4, /* ldr_s */ + 8, /* ldi_s */ + 4, /* ldr_us */ + 8, /* ldi_us */ + 4, /* ldr_i */ + 8, /* ldi_i */ + 0, /* ldr_ui */ + 0, /* ldi_ui */ + 0, /* ldr_l */ + 0, /* ldi_l */ + 8, /* ldxr_c */ + 16, /* ldxi_c */ + 4, /* ldxr_uc */ + 12, /* ldxi_uc */ + 4, /* ldxr_s */ + 12, /* ldxi_s */ + 4, /* ldxr_us */ + 12, /* ldxi_us */ + 4, /* ldxr_i */ + 12, /* ldxi_i */ + 0, /* ldxr_ui */ + 0, /* ldxi_ui */ + 0, /* ldxr_l */ + 0, /* ldxi_l */ + 4, /* str_c */ + 8, /* sti_c */ + 4, /* str_s */ + 8, /* sti_s */ + 4, /* str_i */ + 8, /* sti_i */ + 0, /* str_l */ + 0, /* sti_l */ + 4, /* stxr_c */ + 12, /* stxi_c */ + 4, /* stxr_s */ + 12, /* stxi_s */ + 4, /* stxr_i */ + 12, /* stxi_i */ + 0, /* stxr_l */ + 0, /* stxi_l */ + 8, /* bltr */ + 8, /* blti */ + 8, /* bltr_u */ + 12, /* blti_u */ + 8, /* bler */ + 8, /* blei */ + 8, /* bler_u */ + 12, /* blei_u */ + 8, /* beqr */ + 16, /* beqi */ + 8, /* bger */ + 8, /* bgei */ + 8, /* bger_u */ + 8, /* bgei_u */ + 8, /* bgtr */ + 8, /* bgti */ + 8, /* bgtr_u */ + 8, /* bgti_u */ + 8, /* bner */ + 16, /* bnei */ + 12, /* bmsr */ + 12, /* bmsi */ + 12, /* bmcr */ + 12, /* bmci */ + 12, /* boaddr */ + 16, /* boaddi */ + 12, /* boaddr_u */ + 12, /* boaddi_u */ + 12, /* bxaddr */ + 16, /* bxaddi */ + 12, /* bxaddr_u */ + 12, /* bxaddi_u */ + 12, /* bosubr */ + 16, /* bosubi */ + 12, /* bosubr_u */ + 16, /* bosubi_u */ + 12, /* bxsubr */ + 16, /* bxsubi */ + 12, /* bxsubr_u */ + 16, /* bxsubi_u */ + 8, /* jmpr */ + 4, /* jmpi */ + 12, /* callr */ + 20, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 124, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 16, /* addi_f */ + 4, /* subr_f */ + 16, /* subi_f */ + 16, /* rsbi_f */ + 4, /* mulr_f */ + 16, /* muli_f */ + 4, /* divr_f */ + 16, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 12, /* ltr_f */ + 24, /* lti_f */ + 16, /* ler_f */ + 28, /* lei_f */ + 12, /* eqr_f */ + 24, /* eqi_f */ + 16, /* ger_f */ + 28, /* gei_f */ + 12, /* gtr_f */ + 24, /* gti_f */ + 16, /* ner_f */ + 28, /* nei_f */ + 16, /* unltr_f */ + 28, /* unlti_f */ + 16, /* unler_f */ + 28, /* unlei_f */ + 16, /* uneqr_f */ + 28, /* uneqi_f */ + 16, /* unger_f */ + 28, /* ungei_f */ + 16, /* ungtr_f */ + 28, /* ungti_f */ + 16, /* ltgtr_f */ + 28, /* ltgti_f */ + 16, /* ordr_f */ + 28, /* ordi_f */ + 12, /* unordr_f */ + 24, /* unordi_f */ + 12, /* truncr_f_i */ + 0, /* truncr_f_l */ + 20, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 12, /* movi_f */ + 4, /* ldr_f */ + 8, /* ldi_f */ + 4, /* ldxr_f */ + 12, /* ldxi_f */ + 4, /* str_f */ + 8, /* sti_f */ + 4, /* stxr_f */ + 12, /* stxi_f */ + 8, /* bltr_f */ + 20, /* blti_f */ + 12, /* bler_f */ + 24, /* blei_f */ + 8, /* beqr_f */ + 20, /* beqi_f */ + 12, /* bger_f */ + 24, /* bgei_f */ + 8, /* bgtr_f */ + 20, /* bgti_f */ + 8, /* bner_f */ + 20, /* bnei_f */ + 12, /* bunltr_f */ + 24, /* bunlti_f */ + 8, /* bunler_f */ + 20, /* bunlei_f */ + 12, /* buneqr_f */ + 24, /* buneqi_f */ + 8, /* bunger_f */ + 20, /* bungei_f */ + 12, /* bungtr_f */ + 24, /* bungti_f */ + 12, /* bltgtr_f */ + 24, /* bltgti_f */ + 8, /* bordr_f */ + 20, /* bordi_f */ + 8, /* bunordr_f */ + 20, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 24, /* addi_d */ + 4, /* subr_d */ + 24, /* subi_d */ + 24, /* rsbi_d */ + 4, /* mulr_d */ + 24, /* muli_d */ + 4, /* divr_d */ + 24, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 12, /* ltr_d */ + 32, /* lti_d */ + 16, /* ler_d */ + 36, /* lei_d */ + 12, /* eqr_d */ + 32, /* eqi_d */ + 16, /* ger_d */ + 36, /* gei_d */ + 12, /* gtr_d */ + 32, /* gti_d */ + 16, /* ner_d */ + 36, /* nei_d */ + 16, /* unltr_d */ + 36, /* unlti_d */ + 16, /* unler_d */ + 36, /* unlei_d */ + 16, /* uneqr_d */ + 36, /* uneqi_d */ + 16, /* unger_d */ + 36, /* ungei_d */ + 16, /* ungtr_d */ + 36, /* ungti_d */ + 16, /* ltgtr_d */ + 36, /* ltgti_d */ + 16, /* ordr_d */ + 36, /* ordi_d */ + 12, /* unordr_d */ + 32, /* unordi_d */ + 12, /* truncr_d_i */ + 0, /* truncr_d_l */ + 20, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 24, /* movi_d */ + 4, /* ldr_d */ + 8, /* ldi_d */ + 4, /* ldxr_d */ + 12, /* ldxi_d */ + 4, /* str_d */ + 8, /* sti_d */ + 4, /* stxr_d */ + 12, /* stxi_d */ + 8, /* bltr_d */ + 28, /* blti_d */ + 12, /* bler_d */ + 32, /* blei_d */ + 8, /* beqr_d */ + 32, /* beqi_d */ + 12, /* bger_d */ + 32, /* bgei_d */ + 8, /* bgtr_d */ + 28, /* bgti_d */ + 8, /* bner_d */ + 28, /* bnei_d */ + 12, /* bunltr_d */ + 32, /* bunlti_d */ + 8, /* bunler_d */ + 28, /* bunlei_d */ + 12, /* buneqr_d */ + 32, /* buneqi_d */ + 8, /* bunger_d */ + 28, /* bungei_d */ + 12, /* bungtr_d */ + 32, /* bungti_d */ + 12, /* bltgtr_d */ + 32, /* bltgti_d */ + 8, /* bordr_d */ + 28, /* bordi_d */ + 8, /* bunordr_d */ + 28, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* _CALL_SYV */ +#endif /* __BYTE_ORDER */ +#endif /* __powerpc__ */ +#endif /* __WORDSIZE */ + +#if __WORDSIZE == 32 +#if defined(__powerpc__) +#if __BYTE_ORDER == __BIG_ENDIAN +#if !_CALL_SYSV +#define JIT_INSTR_MAX 136 + 0, /* data */ + 0, /* live */ + 0, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 136, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 8, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 12, /* addi */ + 4, /* addcr */ + 12, /* addci */ + 4, /* addxr */ + 8, /* addxi */ + 4, /* subr */ + 12, /* subi */ + 4, /* subcr */ + 12, /* subci */ + 4, /* subxr */ + 8, /* subxi */ + 16, /* rsbi */ + 4, /* mulr */ + 12, /* muli */ + 12, /* qmulr */ + 16, /* qmuli */ + 12, /* qmulr_u */ + 16, /* qmuli_u */ + 4, /* divr */ + 12, /* divi */ + 4, /* divr_u */ + 12, /* divi_u */ + 20, /* qdivr */ + 16, /* qdivi */ + 20, /* qdivr_u */ + 16, /* qdivi_u */ + 12, /* remr */ + 20, /* remi */ + 12, /* remr_u */ + 20, /* remi_u */ + 4, /* andr */ + 12, /* andi */ + 4, /* orr */ + 12, /* ori */ + 4, /* xorr */ + 12, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 12, /* ltr */ + 12, /* lti */ + 12, /* ltr_u */ + 16, /* lti_u */ + 16, /* ler */ + 16, /* lei */ + 16, /* ler_u */ + 16, /* lei_u */ + 12, /* eqr */ + 12, /* eqi */ + 16, /* ger */ + 16, /* gei */ + 16, /* ger_u */ + 16, /* gei_u */ + 12, /* gtr */ + 12, /* gti */ + 12, /* gtr_u */ + 12, /* gti_u */ + 16, /* ner */ + 16, /* nei */ + 4, /* movr */ + 8, /* movi */ + 4, /* extr_c */ + 4, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 0, /* extr_i */ + 0, /* extr_ui */ + 4, /* htonr_us */ + 4, /* htonr_ui */ + 0, /* htonr_ul */ + 8, /* ldr_c */ + 12, /* ldi_c */ + 4, /* ldr_uc */ + 8, /* ldi_uc */ + 4, /* ldr_s */ + 8, /* ldi_s */ + 4, /* ldr_us */ + 8, /* ldi_us */ + 4, /* ldr_i */ + 8, /* ldi_i */ + 0, /* ldr_ui */ + 0, /* ldi_ui */ + 0, /* ldr_l */ + 0, /* ldi_l */ + 8, /* ldxr_c */ + 16, /* ldxi_c */ + 4, /* ldxr_uc */ + 12, /* ldxi_uc */ + 4, /* ldxr_s */ + 12, /* ldxi_s */ + 4, /* ldxr_us */ + 12, /* ldxi_us */ + 4, /* ldxr_i */ + 12, /* ldxi_i */ + 0, /* ldxr_ui */ + 0, /* ldxi_ui */ + 0, /* ldxr_l */ + 0, /* ldxi_l */ + 4, /* str_c */ + 8, /* sti_c */ + 4, /* str_s */ + 8, /* sti_s */ + 4, /* str_i */ + 8, /* sti_i */ + 0, /* str_l */ + 0, /* sti_l */ + 4, /* stxr_c */ + 12, /* stxi_c */ + 4, /* stxr_s */ + 12, /* stxi_s */ + 4, /* stxr_i */ + 12, /* stxi_i */ + 0, /* stxr_l */ + 0, /* stxi_l */ + 8, /* bltr */ + 8, /* blti */ + 8, /* bltr_u */ + 12, /* blti_u */ + 8, /* bler */ + 8, /* blei */ + 8, /* bler_u */ + 12, /* blei_u */ + 8, /* beqr */ + 16, /* beqi */ + 8, /* bger */ + 8, /* bgei */ + 8, /* bger_u */ + 8, /* bgei_u */ + 8, /* bgtr */ + 8, /* bgti */ + 8, /* bgtr_u */ + 8, /* bgti_u */ + 8, /* bner */ + 16, /* bnei */ + 12, /* bmsr */ + 12, /* bmsi */ + 12, /* bmcr */ + 12, /* bmci */ + 12, /* boaddr */ + 16, /* boaddi */ + 12, /* boaddr_u */ + 12, /* boaddi_u */ + 12, /* bxaddr */ + 16, /* bxaddi */ + 12, /* bxaddr_u */ + 12, /* bxaddi_u */ + 12, /* bosubr */ + 16, /* bosubi */ + 12, /* bosubr_u */ + 16, /* bosubi_u */ + 12, /* bxsubr */ + 16, /* bxsubi */ + 12, /* bxsubr_u */ + 16, /* bxsubi_u */ + 8, /* jmpr */ + 4, /* jmpi */ + 28, /* callr */ + 40, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 124, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 16, /* addi_f */ + 4, /* subr_f */ + 16, /* subi_f */ + 16, /* rsbi_f */ + 4, /* mulr_f */ + 16, /* muli_f */ + 4, /* divr_f */ + 16, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 12, /* ltr_f */ + 24, /* lti_f */ + 16, /* ler_f */ + 28, /* lei_f */ + 12, /* eqr_f */ + 24, /* eqi_f */ + 16, /* ger_f */ + 28, /* gei_f */ + 12, /* gtr_f */ + 24, /* gti_f */ + 16, /* ner_f */ + 28, /* nei_f */ + 16, /* unltr_f */ + 28, /* unlti_f */ + 16, /* unler_f */ + 28, /* unlei_f */ + 16, /* uneqr_f */ + 28, /* uneqi_f */ + 16, /* unger_f */ + 28, /* ungei_f */ + 16, /* ungtr_f */ + 28, /* ungti_f */ + 16, /* ltgtr_f */ + 28, /* ltgti_f */ + 16, /* ordr_f */ + 28, /* ordi_f */ + 12, /* unordr_f */ + 24, /* unordi_f */ + 12, /* truncr_f_i */ + 0, /* truncr_f_l */ + 20, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 12, /* movi_f */ + 4, /* ldr_f */ + 8, /* ldi_f */ + 4, /* ldxr_f */ + 12, /* ldxi_f */ + 4, /* str_f */ + 8, /* sti_f */ + 4, /* stxr_f */ + 12, /* stxi_f */ + 8, /* bltr_f */ + 20, /* blti_f */ + 12, /* bler_f */ + 24, /* blei_f */ + 8, /* beqr_f */ + 20, /* beqi_f */ + 12, /* bger_f */ + 24, /* bgei_f */ + 8, /* bgtr_f */ + 20, /* bgti_f */ + 8, /* bner_f */ + 20, /* bnei_f */ + 12, /* bunltr_f */ + 24, /* bunlti_f */ + 8, /* bunler_f */ + 20, /* bunlei_f */ + 12, /* buneqr_f */ + 24, /* buneqi_f */ + 8, /* bunger_f */ + 20, /* bungei_f */ + 12, /* bungtr_f */ + 24, /* bungti_f */ + 12, /* bltgtr_f */ + 24, /* bltgti_f */ + 8, /* bordr_f */ + 20, /* bordi_f */ + 8, /* bunordr_f */ + 20, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 24, /* addi_d */ + 4, /* subr_d */ + 24, /* subi_d */ + 24, /* rsbi_d */ + 4, /* mulr_d */ + 24, /* muli_d */ + 4, /* divr_d */ + 24, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 12, /* ltr_d */ + 32, /* lti_d */ + 16, /* ler_d */ + 36, /* lei_d */ + 12, /* eqr_d */ + 32, /* eqi_d */ + 16, /* ger_d */ + 36, /* gei_d */ + 12, /* gtr_d */ + 32, /* gti_d */ + 16, /* ner_d */ + 36, /* nei_d */ + 16, /* unltr_d */ + 36, /* unlti_d */ + 16, /* unler_d */ + 36, /* unlei_d */ + 16, /* uneqr_d */ + 36, /* uneqi_d */ + 16, /* unger_d */ + 36, /* ungei_d */ + 16, /* ungtr_d */ + 36, /* ungti_d */ + 16, /* ltgtr_d */ + 36, /* ltgti_d */ + 16, /* ordr_d */ + 36, /* ordi_d */ + 12, /* unordr_d */ + 32, /* unordi_d */ + 12, /* truncr_d_i */ + 0, /* truncr_d_l */ + 20, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 24, /* movi_d */ + 4, /* ldr_d */ + 8, /* ldi_d */ + 4, /* ldxr_d */ + 12, /* ldxi_d */ + 4, /* str_d */ + 8, /* sti_d */ + 4, /* stxr_d */ + 12, /* stxi_d */ + 8, /* bltr_d */ + 28, /* blti_d */ + 12, /* bler_d */ + 32, /* blei_d */ + 8, /* beqr_d */ + 32, /* beqi_d */ + 12, /* bger_d */ + 32, /* bgei_d */ + 8, /* bgtr_d */ + 28, /* bgti_d */ + 8, /* bner_d */ + 28, /* bnei_d */ + 12, /* bunltr_d */ + 32, /* bunlti_d */ + 8, /* bunler_d */ + 28, /* bunlei_d */ + 12, /* buneqr_d */ + 32, /* buneqi_d */ + 8, /* bunger_d */ + 28, /* bungei_d */ + 12, /* bungtr_d */ + 32, /* bungti_d */ + 12, /* bltgtr_d */ + 32, /* bltgti_d */ + 8, /* bordr_d */ + 28, /* bordi_d */ + 8, /* bunordr_d */ + 28, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* _CALL_AIX */ +#endif /* __BYTEORDER */ +#endif /* __powerpc__ */ +#endif /* __WORDSIZE */ + +#if __WORDSIZE == 64 +#if defined(__powerpc__) +#if __BYTE_ORDER == __BIG_ENDIAN +#define JIT_INSTR_MAX 148 + 0, /* data */ + 0, /* live */ + 4, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 148, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 8, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 28, /* addi */ + 4, /* addcr */ + 28, /* addci */ + 4, /* addxr */ + 8, /* addxi */ + 4, /* subr */ + 28, /* subi */ + 4, /* subcr */ + 28, /* subci */ + 4, /* subxr */ + 8, /* subxi */ + 44, /* rsbi */ + 4, /* mulr */ + 28, /* muli */ + 12, /* qmulr */ + 28, /* qmuli */ + 12, /* qmulr_u */ + 28, /* qmuli_u */ + 4, /* divr */ + 28, /* divi */ + 4, /* divr_u */ + 28, /* divi_u */ + 20, /* qdivr */ + 16, /* qdivi */ + 20, /* qdivr_u */ + 16, /* qdivi_u */ + 12, /* remr */ + 36, /* remi */ + 12, /* remr_u */ + 36, /* remi_u */ + 4, /* andr */ + 28, /* andi */ + 4, /* orr */ + 28, /* ori */ + 4, /* xorr */ + 28, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 12, /* ltr */ + 12, /* lti */ + 12, /* ltr_u */ + 16, /* lti_u */ + 16, /* ler */ + 16, /* lei */ + 16, /* ler_u */ + 16, /* lei_u */ + 12, /* eqr */ + 12, /* eqi */ + 16, /* ger */ + 16, /* gei */ + 16, /* ger_u */ + 16, /* gei_u */ + 12, /* gtr */ + 12, /* gti */ + 12, /* gtr_u */ + 12, /* gti_u */ + 16, /* ner */ + 16, /* nei */ + 4, /* movr */ + 36, /* movi */ + 4, /* extr_c */ + 4, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 4, /* extr_i */ + 4, /* extr_ui */ + 4, /* htonr_us */ + 4, /* htonr_ui */ + 4, /* htonr_ul */ + 8, /* ldr_c */ + 28, /* ldi_c */ + 4, /* ldr_uc */ + 24, /* ldi_uc */ + 4, /* ldr_s */ + 24, /* ldi_s */ + 4, /* ldr_us */ + 24, /* ldi_us */ + 4, /* ldr_i */ + 24, /* ldi_i */ + 4, /* ldr_ui */ + 24, /* ldi_ui */ + 4, /* ldr_l */ + 24, /* ldi_l */ + 8, /* ldxr_c */ + 16, /* ldxi_c */ + 4, /* ldxr_uc */ + 12, /* ldxi_uc */ + 4, /* ldxr_s */ + 12, /* ldxi_s */ + 4, /* ldxr_us */ + 12, /* ldxi_us */ + 4, /* ldxr_i */ + 12, /* ldxi_i */ + 4, /* ldxr_ui */ + 12, /* ldxi_ui */ + 4, /* ldxr_l */ + 12, /* ldxi_l */ + 4, /* str_c */ + 24, /* sti_c */ + 4, /* str_s */ + 24, /* sti_s */ + 4, /* str_i */ + 24, /* sti_i */ + 4, /* str_l */ + 24, /* sti_l */ + 4, /* stxr_c */ + 12, /* stxi_c */ + 4, /* stxr_s */ + 12, /* stxi_s */ + 4, /* stxr_i */ + 12, /* stxi_i */ + 4, /* stxr_l */ + 12, /* stxi_l */ + 8, /* bltr */ + 8, /* blti */ + 8, /* bltr_u */ + 12, /* blti_u */ + 8, /* bler */ + 8, /* blei */ + 8, /* bler_u */ + 12, /* blei_u */ + 8, /* beqr */ + 44, /* beqi */ + 8, /* bger */ + 8, /* bgei */ + 8, /* bger_u */ + 8, /* bgei_u */ + 8, /* bgtr */ + 8, /* bgti */ + 8, /* bgtr_u */ + 8, /* bgti_u */ + 8, /* bner */ + 36, /* bnei */ + 12, /* bmsr */ + 12, /* bmsi */ + 12, /* bmcr */ + 12, /* bmci */ + 12, /* boaddr */ + 16, /* boaddi */ + 12, /* boaddr_u */ + 12, /* boaddi_u */ + 12, /* bxaddr */ + 16, /* bxaddi */ + 12, /* bxaddr_u */ + 12, /* bxaddi_u */ + 12, /* bosubr */ + 16, /* bosubi */ + 12, /* bosubr_u */ + 16, /* bosubi_u */ + 12, /* bxsubr */ + 16, /* bxsubi */ + 12, /* bxsubr_u */ + 16, /* bxsubi_u */ + 8, /* jmpr */ + 4, /* jmpi */ + 28, /* callr */ + 56, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 124, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 28, /* addi_f */ + 4, /* subr_f */ + 28, /* subi_f */ + 28, /* rsbi_f */ + 4, /* mulr_f */ + 28, /* muli_f */ + 4, /* divr_f */ + 28, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 12, /* ltr_f */ + 36, /* lti_f */ + 16, /* ler_f */ + 40, /* lei_f */ + 12, /* eqr_f */ + 36, /* eqi_f */ + 16, /* ger_f */ + 40, /* gei_f */ + 12, /* gtr_f */ + 36, /* gti_f */ + 16, /* ner_f */ + 40, /* nei_f */ + 16, /* unltr_f */ + 40, /* unlti_f */ + 16, /* unler_f */ + 40, /* unlei_f */ + 16, /* uneqr_f */ + 40, /* uneqi_f */ + 16, /* unger_f */ + 40, /* ungei_f */ + 16, /* ungtr_f */ + 40, /* ungti_f */ + 16, /* ltgtr_f */ + 40, /* ltgti_f */ + 16, /* ordr_f */ + 40, /* ordi_f */ + 12, /* unordr_f */ + 36, /* unordi_f */ + 12, /* truncr_f_i */ + 12, /* truncr_f_l */ + 12, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 24, /* movi_f */ + 4, /* ldr_f */ + 24, /* ldi_f */ + 4, /* ldxr_f */ + 12, /* ldxi_f */ + 4, /* str_f */ + 24, /* sti_f */ + 4, /* stxr_f */ + 12, /* stxi_f */ + 8, /* bltr_f */ + 32, /* blti_f */ + 12, /* bler_f */ + 36, /* blei_f */ + 8, /* beqr_f */ + 32, /* beqi_f */ + 12, /* bger_f */ + 36, /* bgei_f */ + 8, /* bgtr_f */ + 32, /* bgti_f */ + 8, /* bner_f */ + 32, /* bnei_f */ + 12, /* bunltr_f */ + 36, /* bunlti_f */ + 8, /* bunler_f */ + 32, /* bunlei_f */ + 12, /* buneqr_f */ + 36, /* buneqi_f */ + 8, /* bunger_f */ + 32, /* bungei_f */ + 12, /* bungtr_f */ + 36, /* bungti_f */ + 12, /* bltgtr_f */ + 36, /* bltgti_f */ + 8, /* bordr_f */ + 32, /* bordi_f */ + 8, /* bunordr_f */ + 32, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 28, /* addi_d */ + 4, /* subr_d */ + 28, /* subi_d */ + 32, /* rsbi_d */ + 4, /* mulr_d */ + 28, /* muli_d */ + 4, /* divr_d */ + 28, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 12, /* ltr_d */ + 40, /* lti_d */ + 16, /* ler_d */ + 44, /* lei_d */ + 12, /* eqr_d */ + 40, /* eqi_d */ + 16, /* ger_d */ + 44, /* gei_d */ + 12, /* gtr_d */ + 40, /* gti_d */ + 16, /* ner_d */ + 44, /* nei_d */ + 16, /* unltr_d */ + 44, /* unlti_d */ + 16, /* unler_d */ + 44, /* unlei_d */ + 16, /* uneqr_d */ + 44, /* uneqi_d */ + 16, /* unger_d */ + 44, /* ungei_d */ + 16, /* ungtr_d */ + 44, /* ungti_d */ + 16, /* ltgtr_d */ + 44, /* ltgti_d */ + 16, /* ordr_d */ + 44, /* ordi_d */ + 12, /* unordr_d */ + 40, /* unordi_d */ + 12, /* truncr_d_i */ + 12, /* truncr_d_l */ + 12, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 32, /* movi_d */ + 4, /* ldr_d */ + 24, /* ldi_d */ + 4, /* ldxr_d */ + 12, /* ldxi_d */ + 4, /* str_d */ + 24, /* sti_d */ + 4, /* stxr_d */ + 12, /* stxi_d */ + 8, /* bltr_d */ + 32, /* blti_d */ + 12, /* bler_d */ + 36, /* blei_d */ + 8, /* beqr_d */ + 40, /* beqi_d */ + 12, /* bger_d */ + 40, /* bgei_d */ + 8, /* bgtr_d */ + 36, /* bgti_d */ + 8, /* bner_d */ + 36, /* bnei_d */ + 12, /* bunltr_d */ + 36, /* bunlti_d */ + 8, /* bunler_d */ + 32, /* bunlei_d */ + 12, /* buneqr_d */ + 36, /* buneqi_d */ + 8, /* bunger_d */ + 36, /* bungei_d */ + 12, /* bungtr_d */ + 40, /* bungti_d */ + 12, /* bltgtr_d */ + 40, /* bltgti_d */ + 8, /* bordr_d */ + 36, /* bordi_d */ + 8, /* bunordr_d */ + 32, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __BYTEORDER */ +#endif /* __powerpc__ */ +#endif /* __WORDSIZE */ + +#if __WORDSIZE == 64 +#if defined(__powerpc__) +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define JIT_INSTR_MAX 124 + 0, /* data */ + 0, /* live */ + 4, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 124, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 8, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 28, /* addi */ + 4, /* addcr */ + 28, /* addci */ + 4, /* addxr */ + 8, /* addxi */ + 4, /* subr */ + 28, /* subi */ + 4, /* subcr */ + 28, /* subci */ + 4, /* subxr */ + 8, /* subxi */ + 44, /* rsbi */ + 4, /* mulr */ + 28, /* muli */ + 12, /* qmulr */ + 28, /* qmuli */ + 12, /* qmulr_u */ + 28, /* qmuli_u */ + 4, /* divr */ + 28, /* divi */ + 4, /* divr_u */ + 28, /* divi_u */ + 20, /* qdivr */ + 16, /* qdivi */ + 20, /* qdivr_u */ + 16, /* qdivi_u */ + 12, /* remr */ + 36, /* remi */ + 12, /* remr_u */ + 36, /* remi_u */ + 4, /* andr */ + 28, /* andi */ + 4, /* orr */ + 28, /* ori */ + 4, /* xorr */ + 28, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 12, /* ltr */ + 12, /* lti */ + 12, /* ltr_u */ + 16, /* lti_u */ + 16, /* ler */ + 16, /* lei */ + 16, /* ler_u */ + 16, /* lei_u */ + 12, /* eqr */ + 12, /* eqi */ + 16, /* ger */ + 16, /* gei */ + 16, /* ger_u */ + 16, /* gei_u */ + 12, /* gtr */ + 12, /* gti */ + 12, /* gtr_u */ + 12, /* gti_u */ + 16, /* ner */ + 16, /* nei */ + 4, /* movr */ + 36, /* movi */ + 4, /* extr_c */ + 4, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 4, /* extr_i */ + 4, /* extr_ui */ + 20, /* htonr_us */ + 16, /* htonr_ui */ + 44, /* htonr_ul */ + 8, /* ldr_c */ + 28, /* ldi_c */ + 4, /* ldr_uc */ + 24, /* ldi_uc */ + 4, /* ldr_s */ + 24, /* ldi_s */ + 4, /* ldr_us */ + 24, /* ldi_us */ + 4, /* ldr_i */ + 24, /* ldi_i */ + 4, /* ldr_ui */ + 24, /* ldi_ui */ + 4, /* ldr_l */ + 24, /* ldi_l */ + 8, /* ldxr_c */ + 16, /* ldxi_c */ + 4, /* ldxr_uc */ + 12, /* ldxi_uc */ + 4, /* ldxr_s */ + 12, /* ldxi_s */ + 4, /* ldxr_us */ + 12, /* ldxi_us */ + 4, /* ldxr_i */ + 12, /* ldxi_i */ + 4, /* ldxr_ui */ + 12, /* ldxi_ui */ + 4, /* ldxr_l */ + 12, /* ldxi_l */ + 4, /* str_c */ + 24, /* sti_c */ + 4, /* str_s */ + 24, /* sti_s */ + 4, /* str_i */ + 24, /* sti_i */ + 4, /* str_l */ + 24, /* sti_l */ + 4, /* stxr_c */ + 12, /* stxi_c */ + 4, /* stxr_s */ + 12, /* stxi_s */ + 4, /* stxr_i */ + 12, /* stxi_i */ + 4, /* stxr_l */ + 12, /* stxi_l */ + 8, /* bltr */ + 8, /* blti */ + 8, /* bltr_u */ + 12, /* blti_u */ + 8, /* bler */ + 8, /* blei */ + 8, /* bler_u */ + 12, /* blei_u */ + 8, /* beqr */ + 44, /* beqi */ + 8, /* bger */ + 8, /* bgei */ + 8, /* bger_u */ + 8, /* bgei_u */ + 8, /* bgtr */ + 8, /* bgti */ + 8, /* bgtr_u */ + 8, /* bgti_u */ + 8, /* bner */ + 36, /* bnei */ + 12, /* bmsr */ + 12, /* bmsi */ + 12, /* bmcr */ + 12, /* bmci */ + 12, /* boaddr */ + 16, /* boaddi */ + 12, /* boaddr_u */ + 12, /* boaddi_u */ + 12, /* bxaddr */ + 16, /* bxaddi */ + 12, /* bxaddr_u */ + 12, /* bxaddi_u */ + 12, /* bosubr */ + 16, /* bosubi */ + 12, /* bosubr_u */ + 16, /* bosubi_u */ + 12, /* bxsubr */ + 16, /* bxsubi */ + 12, /* bxsubr_u */ + 16, /* bxsubi_u */ + 8, /* jmpr */ + 4, /* jmpi */ + 12, /* callr */ + 36, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 124, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 28, /* addi_f */ + 4, /* subr_f */ + 28, /* subi_f */ + 28, /* rsbi_f */ + 4, /* mulr_f */ + 28, /* muli_f */ + 4, /* divr_f */ + 28, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 12, /* ltr_f */ + 36, /* lti_f */ + 16, /* ler_f */ + 40, /* lei_f */ + 12, /* eqr_f */ + 36, /* eqi_f */ + 16, /* ger_f */ + 40, /* gei_f */ + 12, /* gtr_f */ + 36, /* gti_f */ + 16, /* ner_f */ + 40, /* nei_f */ + 16, /* unltr_f */ + 40, /* unlti_f */ + 16, /* unler_f */ + 40, /* unlei_f */ + 16, /* uneqr_f */ + 40, /* uneqi_f */ + 16, /* unger_f */ + 40, /* ungei_f */ + 16, /* ungtr_f */ + 40, /* ungti_f */ + 16, /* ltgtr_f */ + 40, /* ltgti_f */ + 16, /* ordr_f */ + 40, /* ordi_f */ + 12, /* unordr_f */ + 36, /* unordi_f */ + 12, /* truncr_f_i */ + 12, /* truncr_f_l */ + 12, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 24, /* movi_f */ + 4, /* ldr_f */ + 24, /* ldi_f */ + 4, /* ldxr_f */ + 12, /* ldxi_f */ + 4, /* str_f */ + 24, /* sti_f */ + 4, /* stxr_f */ + 12, /* stxi_f */ + 8, /* bltr_f */ + 32, /* blti_f */ + 12, /* bler_f */ + 36, /* blei_f */ + 8, /* beqr_f */ + 32, /* beqi_f */ + 12, /* bger_f */ + 36, /* bgei_f */ + 8, /* bgtr_f */ + 32, /* bgti_f */ + 8, /* bner_f */ + 32, /* bnei_f */ + 12, /* bunltr_f */ + 36, /* bunlti_f */ + 8, /* bunler_f */ + 32, /* bunlei_f */ + 12, /* buneqr_f */ + 36, /* buneqi_f */ + 8, /* bunger_f */ + 32, /* bungei_f */ + 12, /* bungtr_f */ + 36, /* bungti_f */ + 12, /* bltgtr_f */ + 36, /* bltgti_f */ + 8, /* bordr_f */ + 32, /* bordi_f */ + 8, /* bunordr_f */ + 32, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 28, /* addi_d */ + 4, /* subr_d */ + 28, /* subi_d */ + 32, /* rsbi_d */ + 4, /* mulr_d */ + 28, /* muli_d */ + 4, /* divr_d */ + 28, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 12, /* ltr_d */ + 40, /* lti_d */ + 16, /* ler_d */ + 44, /* lei_d */ + 12, /* eqr_d */ + 40, /* eqi_d */ + 16, /* ger_d */ + 44, /* gei_d */ + 12, /* gtr_d */ + 40, /* gti_d */ + 16, /* ner_d */ + 44, /* nei_d */ + 16, /* unltr_d */ + 44, /* unlti_d */ + 16, /* unler_d */ + 44, /* unlei_d */ + 16, /* uneqr_d */ + 44, /* uneqi_d */ + 16, /* unger_d */ + 44, /* ungei_d */ + 16, /* ungtr_d */ + 44, /* ungti_d */ + 16, /* ltgtr_d */ + 44, /* ltgti_d */ + 16, /* ordr_d */ + 44, /* ordi_d */ + 12, /* unordr_d */ + 40, /* unordi_d */ + 12, /* truncr_d_i */ + 12, /* truncr_d_l */ + 12, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 32, /* movi_d */ + 4, /* ldr_d */ + 24, /* ldi_d */ + 4, /* ldxr_d */ + 12, /* ldxi_d */ + 4, /* str_d */ + 24, /* sti_d */ + 4, /* stxr_d */ + 12, /* stxi_d */ + 8, /* bltr_d */ + 32, /* blti_d */ + 12, /* bler_d */ + 36, /* blei_d */ + 8, /* beqr_d */ + 40, /* beqi_d */ + 12, /* bger_d */ + 40, /* bgei_d */ + 8, /* bgtr_d */ + 36, /* bgti_d */ + 8, /* bner_d */ + 36, /* bnei_d */ + 12, /* bunltr_d */ + 36, /* bunlti_d */ + 8, /* bunler_d */ + 32, /* bunlei_d */ + 12, /* buneqr_d */ + 36, /* buneqi_d */ + 8, /* bunger_d */ + 36, /* bungei_d */ + 12, /* bungtr_d */ + 40, /* bungti_d */ + 12, /* bltgtr_d */ + 40, /* bltgti_d */ + 8, /* bordr_d */ + 36, /* bordi_d */ + 8, /* bunordr_d */ + 32, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __BYTE_ORDER */ +#endif /* __powerpc__ */ +#endif /* __WORDSIZE */ diff --git a/deps/lightning/lib/jit_ppc.c b/deps/lightning/lib/jit_ppc.c new file mode 100644 index 0000000..0826f4e --- /dev/null +++ b/deps/lightning/lib/jit_ppc.c @@ -0,0 +1,1912 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 8) +#if !_CALL_SYSV +# define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 13) +#else +# define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 8) +# if __WORDSIZE == 32 +# define va_gp_shift 2 +# else +# define va_gp_shift 3 +# endif +# define va_gp_increment sizeof(jit_word_t) +# define first_gp_argument r3 +# define first_gp_offset offsetof(jit_va_list_t, \ + first_gp_argument) +# define va_fp_increment sizeof(jit_float64_t) +# define first_fp_argument f1 +# define first_fp_offset offsetof(jit_va_list_t, \ + first_fp_argument) +#endif +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define C_DISP 0 +# define S_DISP 0 +# define I_DISP 0 +# define F_DISP 0 +#else +# define C_DISP (__WORDSIZE >> 3) - sizeof(jit_int8_t) +# define S_DISP (__WORDSIZE >> 3) - sizeof(jit_int16_t) +# define I_DISP (__WORDSIZE >> 3) - sizeof(jit_int32_t) +# define F_DISP (__WORDSIZE >> 3) - sizeof(jit_float32_t) +#endif + +/* + * Types + */ +#if _CALL_SYSV +typedef struct jit_va_list { + jit_uint8_t ngpr; + jit_uint8_t nfpr; + jit_uint16_t _pad; +# if __WORDSIZE == 64 + jit_uint32_t _pad2; +# endif + jit_pointer_t over; + jit_pointer_t save; +# if __WORDSIZE == 32 + jit_word_t _pad2; +# endif + jit_word_t r3; + jit_word_t r4; + jit_word_t r5; + jit_word_t r6; + jit_word_t r7; + jit_word_t r8; + jit_word_t r9; + jit_word_t r10; + jit_float64_t f1; + jit_float64_t f2; + jit_float64_t f3; + jit_float64_t f4; + jit_float64_t f5; + jit_float64_t f6; + jit_float64_t f7; + jit_float64_t f8; +} jit_va_list_t; +#else +typedef jit_pointer_t jit_va_list_t; +#endif + +/* + * Prototypes + */ +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); + +/* libgcc */ +extern void __clear_cache(void *, void *); + +#define PROTO 1 +# include "jit_ppc-cpu.c" +# include "jit_ppc-fpu.c" +#undef PROTO + +/* + * Initialization + */ +jit_register_t _rvs[] = { + { rc(sav) | 0, "r0" }, + { rc(sav) | 11, "r11" }, /* env */ + { rc(sav) | 12, "r12" }, /* exception */ + { rc(sav) | 13, "r13" }, /* thread */ + { rc(sav) | 2, "r2" }, /* toc */ + { rc(sav) | rc(gpr) | 14, "r14" }, + { rc(sav) | rc(gpr) | 15, "r15" }, + { rc(sav) | rc(gpr) | 16, "r16" }, + { rc(sav) | rc(gpr) | 17, "r17" }, + { rc(sav) | rc(gpr) | 18, "r18" }, + { rc(sav) | rc(gpr) | 19, "r19" }, + { rc(sav) | rc(gpr) | 20, "r20" }, + { rc(sav) | rc(gpr) | 21, "r21" }, + { rc(sav) | rc(gpr) | 22, "r22" }, + { rc(sav) | rc(gpr) | 23, "r23" }, + { rc(sav) | rc(gpr) | 24, "r24" }, + { rc(sav) | rc(gpr) | 25, "r25" }, + { rc(sav) | rc(gpr) | 26, "r26" }, + { rc(sav) | rc(gpr) | 27, "r27" }, + { rc(sav) | rc(gpr) | 28, "r28" }, + { rc(sav) | rc(gpr) | 29, "r29" }, + { rc(sav) | rc(gpr) | 30, "r30" }, + { rc(sav) | 1, "r1" }, + { rc(sav) | 31, "r31" }, + { rc(arg) | rc(gpr) | 10, "r10" }, + { rc(arg) | rc(gpr) | 9, "r9" }, + { rc(arg) | rc(gpr) | 8, "r8" }, + { rc(arg) | rc(gpr) | 7, "r7" }, + { rc(arg) | rc(gpr) | 6, "r6" }, + { rc(arg) | rc(gpr) | 5, "r5" }, + { rc(arg) | rc(gpr) | 4, "r4" }, + { rc(arg) | rc(gpr) | 3, "r3" }, + { rc(fpr) | 0, "f0" }, + { rc(sav) | rc(fpr) | 14, "f14" }, + { rc(sav) | rc(fpr) | 15, "f15" }, + { rc(sav) | rc(fpr) | 16, "f16" }, + { rc(sav) | rc(fpr) | 17, "f17" }, + { rc(sav) | rc(fpr) | 18, "f18" }, + { rc(sav) | rc(fpr) | 19, "f19" }, + { rc(sav) | rc(fpr) | 20, "f20" }, + { rc(sav) | rc(fpr) | 21, "f21" }, + { rc(sav) | rc(fpr) | 22, "f22" }, + { rc(sav) | rc(fpr) | 23, "f23" }, + { rc(sav) | rc(fpr) | 24, "f24" }, + { rc(sav) | rc(fpr) | 25, "f25" }, + { rc(sav) | rc(fpr) | 26, "f26" }, + { rc(sav) | rc(fpr) | 27, "f27" }, + { rc(sav) | rc(fpr) | 28, "f28" }, + { rc(sav) | rc(fpr) | 29, "f29" }, + { rc(sav) | rc(fpr) | 30, "f30" }, + { rc(sav) | rc(fpr) | 31, "f31" }, +#if !_CALL_SYSV + { rc(arg) | rc(fpr) | 13, "f13" }, + { rc(arg) | rc(fpr) | 12, "f12" }, + { rc(arg) | rc(fpr) | 11, "f11" }, + { rc(arg) | rc(fpr) | 10, "f10" }, + { rc(arg) | rc(fpr) | 9, "f9" }, +#else + { rc(fpr) | 13, "f13" }, + { rc(fpr) | 12, "f12" }, + { rc(fpr) | 11, "f11" }, + { rc(fpr) | 10, "f10" }, + { rc(fpr) | 9, "f9" }, +#endif + { rc(arg) | rc(fpr) | 8, "f8" }, + { rc(arg) | rc(fpr) | 7, "f7" }, + { rc(arg) | rc(fpr) | 6, "f6" }, + { rc(arg) | rc(fpr) | 5, "f5" }, + { rc(arg) | rc(fpr) | 4, "f4" }, + { rc(arg) | rc(fpr) | 3, "f3" }, + { rc(arg) | rc(fpr) | 2, "f2" }, + { rc(arg) | rc(fpr) | 1, "f1" }, + { _NOREG, "<none>" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ +} + +void +_jit_init(jit_state_t *_jit) +{ + _jitc->reglen = jit_size(_rvs) - 1; +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + _jitc->function->self.size = params_offset; + _jitc->function->self.argi = _jitc->function->self.argf = + _jitc->function->self.alen = 0; + /* float conversion */ + _jitc->function->self.aoff = alloca_offset - 8; + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + assert(_jitc->function); + switch (length) { + case 0: case 1: break; + case 2: _jitc->function->self.aoff &= -2; break; + case 3: case 4: _jitc->function->self.aoff &= -4; break; + default: _jitc->function->self.aoff &= -8; break; + } + _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } + return (_jitc->function->self.aoff); +} + +void +_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) +{ + jit_int32_t r0, r1; + assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); + if (!_jitc->function->allocar) { + _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); + _jitc->function->allocar = 1; + } + r0 = jit_get_reg(jit_class_gpr); + r1 = jit_get_reg(jit_class_gpr); + jit_ldr(r0, JIT_SP); + jit_negr(r1, v); + jit_andi(r1, r1, -16); + jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); + jit_addr(u, u, r1); + jit_addr(JIT_SP, JIT_SP, r1); + jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); + jit_str(JIT_SP, r0); + jit_unget_reg(r1); + jit_unget_reg(r0); + jit_dec_synth(); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + assert(_jitc->function); + jit_inc_synth(ret); + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr, u); + if (JIT_RET != u) + jit_movr(JIT_RET, u); + jit_live(JIT_RET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti(jit_state_t *_jit, jit_word_t u) +{ + jit_inc_synth_w(reti, u); + jit_movi(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_f, u); + if (JIT_RET != u) + jit_movr_f(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_inc_synth_f(reti_f, u); + jit_movi_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_d, u); + if (JIT_FRET != u) + jit_movr_d(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_inc_synth_d(reti_d, u); + jit_movi_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_epilog(jit_state_t *_jit) +{ + assert(_jitc->function); + assert(_jitc->function->epilog->next == NULL); + jit_link(_jitc->function->epilog); + _jitc->function = NULL; +} + +jit_bool_t +_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) +{ + if (u->code == jit_code_arg) + return (jit_arg_reg_p(u->u.w)); + assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d); + return (jit_arg_f_reg_p(u->u.w)); +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + jit_inc_synth(ellipsis); + if (_jitc->prepare) { + jit_link_prepare(); + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; + } + else { + jit_link_prolog(); + assert(!(_jitc->function->self.call & jit_call_varargs)); + _jitc->function->self.call |= jit_call_varargs; +#if _CALL_SYSV + /* Allocate va_list like object in the stack. + * If applicable, with enough space to save all argument + * registers, and use fixed offsets for them. */ + _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t)); +#endif + _jitc->function->vagp = _jitc->function->self.argi; + _jitc->function->vafp = _jitc->function->self.argf; + } + jit_dec_synth(); +} + +void +_jit_va_push(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(va_push, u); + jit_pushargr(u); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + jit_bool_t incr = 1; + assert(_jitc->function); + if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi++; +#if _CALL_SYSV + incr = 0; +#endif + } + else + offset = _jitc->function->self.size; + if (incr) + _jitc->function->self.size += sizeof(jit_word_t); + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + jit_bool_t incr = 1; + assert(_jitc->function); + if (jit_arg_f_reg_p(_jitc->function->self.argf)) { + offset = _jitc->function->self.argf++; +#if _CALL_SYSV + incr = 0; +#endif + } + else + offset = _jitc->function->self.size + F_DISP; +#if !_CALL_SYSV + if (jit_arg_reg_p(_jitc->function->self.argi)) { +# if __WORDSIZE == 32 + _jitc->function->self.argi += 2; +# else + _jitc->function->self.argi++; +# endif + } +#endif + if (incr) + _jitc->function->self.size += sizeof(jit_word_t); + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + jit_bool_t incr = 1; + assert(_jitc->function); + if (jit_arg_f_reg_p(_jitc->function->self.argf)) { + offset = _jitc->function->self.argf++; +#if _CALL_SYSV + incr = 0; +#endif + } + else { +#if _CALL_SYSV + if (_jitc->function->self.size & 7) + _jitc->function->self.size += 4; +#endif + offset = _jitc->function->self.size; + } +#if !_CALL_SYSV + if (jit_arg_reg_p(_jitc->function->self.argi)) { +# if __WORDSIZE == 32 + _jitc->function->self.argi += 2; +# else + _jitc->function->self.argi++; +# endif + } +#endif + if (incr) + _jitc->function->self.size += sizeof(jit_float64_t); + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +void +_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_c(u, JIT_RA0 - v->u.w); + else + jit_ldxi_c(u, JIT_FP, v->u.w + C_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_uc(u, JIT_RA0 - v->u.w); + else + jit_ldxi_uc(u, JIT_FP, v->u.w + C_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_s(u, JIT_RA0 - v->u.w); + else + jit_ldxi_s(u, JIT_FP, v->u.w + S_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_us(u, JIT_RA0 - v->u.w); + else + jit_ldxi_us(u, JIT_FP, v->u.w + S_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); + if (jit_arg_reg_p(v->u.w)) { +#if __WORDSIZE == 32 + jit_movr(u, JIT_RA0 - v->u.w); +#else + jit_extr_i(u, JIT_RA0 - v->u.w); +#endif + } + else + jit_ldxi_i(u, JIT_FP, v->u.w + I_DISP); + jit_dec_synth(); +} + +#if __WORDSIZE == 64 +void +_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_ui(u, JIT_RA0 - v->u.w); + else + jit_ldxi_ui(u, JIT_FP, v->u.w + I_DISP); + jit_dec_synth(); +} + +void +_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(u, JIT_RA0 - v->u.w); + else + jit_ldxi_l(u, JIT_FP, v->u.w); + jit_dec_synth(); +} +#endif + +void +_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(JIT_RA0 - v->u.w, u); + else + jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) +{ + jit_int32_t regno; + jit_inc_synth_wp(putargi, u, v); + assert(v->code == jit_code_arg); + if (jit_arg_reg_p(v->u.w)) + jit_movi(JIT_RA0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(u, JIT_FA0 - v->u.w); + else + jit_ldxi_f(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(JIT_FA0 - v->u.w, u); + else + jit_stxi_f(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movi_d(JIT_FA0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_f(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(u, JIT_FA0 - v->u.w); + else + jit_ldxi_d(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(JIT_FA0 - v->u.w, u); + else + jit_stxi_d(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movi_d(JIT_FA0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + jit_bool_t incr = 1; + assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; +#if _CALL_SYSV + incr = 0; +#endif + } + else + jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, u); + if (incr) + _jitc->function->call.size += sizeof(jit_word_t); + jit_dec_synth(); +} + +void +_jit_pushargi(jit_state_t *_jit, jit_word_t u) +{ + jit_int32_t regno; + jit_bool_t incr = 1; + assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; +#if _CALL_SYSV + incr = 0; +#endif + } + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size + params_offset, JIT_SP, regno); + jit_unget_reg(regno); + } + if (incr) + _jitc->function->call.size += sizeof(jit_word_t); + jit_dec_synth(); +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_bool_t incr = 1; + assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) +#if !_CALL_SYSV + && !(_jitc->function->call.call & jit_call_varargs) +#endif + ) { + jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; +#if !_CALL_SYSV + /* in case of excess arguments */ + if (jit_arg_reg_p(_jitc->function->call.argi)) { +# if __WORDSIZE == 32 + _jitc->function->call.argi += 2; + if (!jit_arg_reg_p(_jitc->function->call.argi - 1)) + --_jitc->function->call.argi; +# else + _jitc->function->call.argi++; +# endif + } +#elif _CALL_SYSV + incr = 0; +#endif + } +#if !_CALL_SYSV + else if (jit_arg_reg_p(_jitc->function->call.argi +# if __WORDSIZE == 32 + + 1 +# endif + )) { + /* use reserved 8 bytes area */ + jit_stxi_d(alloca_offset - 8, JIT_FP, u); + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + alloca_offset - 8); + _jitc->function->call.argi++; +# if __WORDSIZE == 32 + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + alloca_offset - 4); + _jitc->function->call.argi++; +# endif + } +#endif + else + jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP, + JIT_SP, u); + if (incr) + _jitc->function->call.size += sizeof(jit_word_t); + jit_dec_synth(); +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_bool_t incr = 1; + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) +#if !_CALL_SYSV + && !(_jitc->function->call.call & jit_call_varargs) +#endif + ) { + jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; +#if !_CALL_SYSV + /* in case of excess arguments */ +# if __WORDSIZE == 32 + _jitc->function->call.argi += 2; + if (!jit_arg_reg_p(_jitc->function->call.argi - 1)) + --_jitc->function->call.argi; +# else + _jitc->function->call.argi++; +# endif +#elif _CALL_SYSV + incr = 0; +#endif + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); +#if !_CALL_SYSV + if (jit_arg_reg_p(_jitc->function->call.argi +# if __WORDSIZE == 32 + + 1 +# endif + )) { + /* use reserved 8 bytes area */ + jit_stxi_d(alloca_offset - 8, JIT_FP, regno); + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + alloca_offset - 8); + _jitc->function->call.argi++; +# if __WORDSIZE == 32 + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + alloca_offset - 4); + _jitc->function->call.argi++; +# endif + } + else +#endif + jit_stxi_f(_jitc->function->call.size + params_offset + F_DISP, + JIT_SP, regno); + jit_unget_reg(regno); + } + if (incr) + _jitc->function->call.size += sizeof(jit_word_t); + jit_dec_synth(); +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_bool_t incr = 1; + assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) +#if !_CALL_SYSV + && !(_jitc->function->call.call & jit_call_varargs) +#endif + ) { + jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; +#if !_CALL_SYSV + /* in case of excess arguments */ +# if __WORDSIZE == 32 + _jitc->function->call.argi += 2; + if (!jit_arg_reg_p(_jitc->function->call.argi - 1)) + --_jitc->function->call.argi; +# else + _jitc->function->call.argi++; +# endif +#else /* _CALL_SYSV */ + incr = 0; +#endif + } +#if !_CALL_SYSV + else if (jit_arg_reg_p(_jitc->function->call.argi +# if __WORDSIZE == 32 + + 1 +# endif + )) { + /* use reserved 8 bytes area */ + jit_stxi_d(alloca_offset - 8, JIT_FP, u); + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + alloca_offset - 8); + _jitc->function->call.argi++; +# if __WORDSIZE == 32 + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + alloca_offset - 4); + _jitc->function->call.argi++; +# endif + } + else +#endif /* !_CALL_SYSV */ + { +#if _CALL_SYSV + if (_jitc->function->call.size & 7) + _jitc->function->call.size += 4; +#endif + jit_stxi_d(_jitc->function->call.size + params_offset, JIT_SP, u); +#if !_CALL_SYSV && __WORDSIZE == 32 + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_SP, + _jitc->function->call.size + params_offset); + _jitc->function->call.argi++; + } +#endif + } + if (incr) + _jitc->function->call.size += sizeof(jit_float64_t); + jit_dec_synth(); +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; + jit_bool_t incr = 1; + assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) +#if !_CALL_SYSV + && !(_jitc->function->call.call & jit_call_varargs) +#endif + ) { + jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; +#if !_CALL_SYSV + /* in case of excess arguments */ + if (jit_arg_reg_p(_jitc->function->call.argi)) { +# if __WORDSIZE == 32 + _jitc->function->call.argi += 2; + if (!jit_arg_reg_p(_jitc->function->call.argi - 1)) + --_jitc->function->call.argi; +# else + _jitc->function->call.argi++; +# endif + } +#else /* _CALL_SYSV */ + incr = 0; +#endif + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); +#if !_CALL_SYSV + if (jit_arg_reg_p(_jitc->function->call.argi +# if __WORDSIZE == 32 + + 1 +# endif + )) { + /* use reserved 8 bytes area */ + jit_stxi_d(alloca_offset - 8, JIT_FP, regno); + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + alloca_offset - 8); + _jitc->function->call.argi++; +# if __WORDSIZE == 32 + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_FP, + alloca_offset - 4); + _jitc->function->call.argi++; +# endif + } + else +#endif /* !_CALL_SYSV */ + { +#if _CALL_SYSV + if (_jitc->function->call.size & 7) + _jitc->function->call.size += 4; +#endif + jit_stxi_d(_jitc->function->call.size + params_offset, + JIT_SP, regno); +#if !_CALL_SYSV && __WORDSIZE == 32 + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_ldxi(JIT_RA0 - _jitc->function->call.argi, JIT_SP, + _jitc->function->call.size + params_offset); + _jitc->function->call.argi++; + } +#endif + } + jit_unget_reg(regno); + } + if (incr) + _jitc->function->call.size += sizeof(jit_float64_t); + jit_dec_synth(); +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + jit_int32_t spec; + spec = jit_class(_rvs[regno].spec); + if (spec & jit_class_arg) { + if (spec & jit_class_gpr) { + regno = JIT_RA0 - regno; + if (regno >= 0 && regno < node->v.w) + return (1); + } + else if (spec & jit_class_fpr) { + regno = JIT_FA0 - regno; + if (regno >= 0 && regno < node->w.w) + return (1); + } + } + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_node_t *call; + assert(_jitc->function); + jit_inc_synth_w(finishr, r0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + call = jit_callr(r0); + call->v.w = _jitc->function->call.argi; + call->w.w = _jitc->function->call.argf; +#if _CALL_SYSV + /* If passing float arguments in registers */ + if ((_jitc->function->call.call & jit_call_varargs) && call->w.w) + call->flag |= jit_flag_varargs; +#endif + _jitc->function->call.argi = _jitc->function->call.argf = 0; + _jitc->prepare = 0; + jit_dec_synth(); +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_calli(i0); + node->v.w = _jitc->function->call.argi; + node->w.w = _jitc->function->call.argf; +#if _CALL_SYSV + if ((_jitc->function->call.call & jit_call_varargs) && node->w.w) + node->flag |= jit_flag_varargs; +#endif + _jitc->function->call.argi = _jitc->function->call.argf = 0; + _jitc->prepare = 0; + jit_dec_synth(); + return (node); +} + +void +_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth(retval_c); + jit_extr_c(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth(retval_uc); + jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth(retval_s); + jit_extr_s(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth(retval_us); + jit_extr_us(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth(retval_i); +#if __WORDSIZE == 32 + if (r0 != JIT_RET) + jit_movr(r0, JIT_RET); +#else + jit_extr_i(r0, JIT_RET); +#endif + jit_dec_synth(); +} + +#if __WORDSIZE == 64 +void +_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth(retval_ui); + jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth(retval_l); + if (r0 != JIT_RET) + jit_movr(r0, JIT_RET); + jit_dec_synth(); +} +#endif + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth(retval_f); + jit_retval_d(r0); + jit_dec_synth(); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth(retval_d); + if (r0 != JIT_FRET) + jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_int32_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + jit_word_t patch_offset; +#if _CALL_AIXDESC + jit_word_t prolog_offset; +#endif + } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + + _jitc->function = NULL; + + jit_reglive_setup(); + + undo.word = 0; + undo.node = NULL; + undo.patch_offset = 0; + +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif +#if _CALL_AIXDESC + undo.prolog_offset = 0; + for (node = _jitc->head; node; node = node->next) + if (node->code != jit_code_label && + node->code != jit_code_note && + node->code != jit_code_name) + break; + if (node && (node->code != jit_code_prolog || + !(_jitc->functions.ptr + node->w.w)->assume_frame)) { + /* code may start with a jump so add an initial function descriptor */ + word = _jit->pc.w + sizeof(void*) * 3; + iw(word); /* addr */ + iw(0); /* toc */ + iw(0); /* env */ + } +#endif + +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_rrf(name, type, size) \ + case jit_code_##name##i##type: \ + assert(node->flag & jit_flag_data); \ + name##i##type(rn(node->u.w), rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type(_jit->pc.w, \ + rn(node->v.w), rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break +#define case_brf(name, type, size) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + else { \ + word = name##i##type(_jit->pc.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + patch(word, node); \ + } \ + break + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end) + return (NULL); + +#if DEVEL_DISASSEMBLER + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; +#endif + value = jit_classify(node->code); + jit_regarg_set(node, value); + switch (node->code) { + case jit_code_align: + assert(!(node->u.w & (node->u.w - 1)) && + node->u.w <= sizeof(jit_word_t)); + if (node->u.w == sizeof(jit_word_t) && + (word = _jit->pc.w & (sizeof(jit_word_t) - 1))) + nop(sizeof(jit_word_t) - word); + break; + case jit_code_note: case jit_code_name: + node->u.w = _jit->pc.w; + break; + case jit_code_label: + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + break; + case_rrr(add,); + case_rrw(add,); + case_rrr(addc,); + case_rrw(addc,); + case_rrr(addx,); + case_rrw(addx,); + case_rrr(sub,); + case_rrw(sub,); + case_rrr(subc,); + case_rrw(subc,); + case_rrr(subx,); + case_rrw(subx,); + case_rrw(rsb,); + case_rrr(mul,); + case_rrw(mul,); + case_rrrr(qmul,); + case_rrrw(qmul,); + case_rrrr(qmul, _u); + case_rrrw(qmul, _u); + case_rrr(div,); + case_rrw(div,); + case_rrr(div, _u); + case_rrw(div, _u); + case_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); +# if __WORDSIZE == 64 + case_rr(ext, _i); + case_rr(ext, _ui); +# endif + case_rr(hton, _us); + case_rr(hton, _ui); +# if __WORDSIZE == 64 + case_rr(hton, _ul); +# endif + case_rr(neg,); + case_rr(com,); + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), node->v.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rr(trunc, _f_i); + case_rr(trunc, _d_i); +# if __WORDSIZE == 64 + case_rr(trunc, _f_l); + case_rr(trunc, _d_l); +# endif + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_rr(ld, _c); + case_rw(ld, _c); + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rr(ld, _i); + case_rw(ld, _i); + case_rrr(ldx, _i); + case_rrw(ldx, _i); +#if __WORDSIZE == 64 + case_rr(ld, _ui); + case_rw(ld, _ui); + case_rrr(ldx, _ui); + case_rrw(ldx, _ui); + case_rr(ld, _l); + case_rw(ld, _l); + case_rrr(ldx, _l); + case_rrw(ldx, _l); +#endif + case_rr(st, _c); + case_wr(st, _c); + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rr(st, _i); + case_wr(st, _i); + case_rrr(stx, _i); + case_wrr(stx, _i); +#if __WORDSIZE == 64 + case_rr(st, _l); + case_wr(st, _l); + case_rrr(stx, _l); + case_wrr(stx, _l); +#endif + case_rr(mov, _f); + case jit_code_movi_f: + assert(node->flag & jit_flag_data); + movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); + break; + case_rr(ext, _f); + case_rr(ext, _d_f); + case_rr(abs, _f); + case_rr(neg, _f); + case_rr(sqrt, _f); + case_rrr(add, _f); + case_rrf(add, _f, 32); + case_rrr(sub, _f); + case_rrf(sub, _f, 32); + case_rrf(rsb, _f, 32); + case_rrr(mul, _f); + case_rrf(mul, _f, 32); + case_rrr(div, _f); + case_rrf(div, _f, 32); + case_rrr(lt, _f); + case_rrf(lt, _f, 32); + case_rrr(le, _f); + case_rrf(le, _f, 32); + case_rrr(eq, _f); + case_rrf(eq, _f, 32); + case_rrr(ge, _f); + case_rrf(ge, _f, 32); + case_rrr(gt, _f); + case_rrf(gt, _f, 32); + case_rrr(ne, _f); + case_rrf(ne, _f, 32); + case_rrr(unlt, _f); + case_rrf(unlt, _f, 32); + case_rrr(unle, _f); + case_rrf(unle, _f, 32); + case_rrr(uneq, _f); + case_rrf(uneq, _f, 32); + case_rrr(unge, _f); + case_rrf(unge, _f, 32); + case_rrr(ungt, _f); + case_rrf(ungt, _f, 32); + case_rrr(ltgt, _f); + case_rrf(ltgt, _f, 32); + case_rrr(ord, _f); + case_rrf(ord, _f, 32); + case_rrr(unord, _f); + case_rrf(unord, _f, 32); + case_brr(blt, _f); + case_brf(blt, _f, 32); + case_brr(ble, _f); + case_brf(ble, _f, 32); + case_brr(beq, _f); + case_brf(beq, _f, 32); + case_brr(bge, _f); + case_brf(bge, _f, 32); + case_brr(bgt, _f); + case_brf(bgt, _f, 32); + case_brr(bne, _f); + case_brf(bne, _f, 32); + case_brr(bunlt, _f); + case_brf(bunlt, _f, 32); + case_brr(bunle, _f); + case_brf(bunle, _f, 32); + case_brr(buneq, _f); + case_brf(buneq, _f, 32); + case_brr(bunge, _f); + case_brf(bunge, _f, 32); + case_brr(bungt, _f); + case_brf(bungt, _f, 32); + case_brr(bltgt, _f); + case_brf(bltgt, _f, 32); + case_brr(bord, _f); + case_brf(bord, _f, 32); + case_brr(bunord, _f); + case_brf(bunord, _f, 32); + case_rr(ld, _f); + case_rw(ld, _f); + case_rrr(ldx, _f); + case_rrw(ldx, _f); + case_rr(st, _f); + case_wr(st, _f); + case_rrr(stx, _f); + case_wrr(stx, _f); + case_rr(mov, _d); + case jit_code_movi_d: + assert(node->flag & jit_flag_data); + movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w); + break; + case_rr(ext, _d); + case_rr(ext, _f_d); + case_rr(abs, _d); + case_rr(neg, _d); + case_rr(sqrt, _d); + case_rrr(add, _d); + case_rrf(add, _d, 64); + case_rrr(sub, _d); + case_rrf(sub, _d, 64); + case_rrf(rsb, _d, 64); + case_rrr(mul, _d); + case_rrf(mul, _d, 64); + case_rrr(div, _d); + case_rrf(div, _d, 64); + case_rrr(lt, _d); + case_rrf(lt, _d, 64); + case_rrr(le, _d); + case_rrf(le, _d, 64); + case_rrr(eq, _d); + case_rrf(eq, _d, 64); + case_rrr(ge, _d); + case_rrf(ge, _d, 64); + case_rrr(gt, _d); + case_rrf(gt, _d, 64); + case_rrr(ne, _d); + case_rrf(ne, _d, 64); + case_rrr(unlt, _d); + case_rrf(unlt, _d, 64); + case_rrr(unle, _d); + case_rrf(unle, _d, 64); + case_rrr(uneq, _d); + case_rrf(uneq, _d, 64); + case_rrr(unge, _d); + case_rrf(unge, _d, 64); + case_rrr(ungt, _d); + case_rrf(ungt, _d, 64); + case_rrr(ltgt, _d); + case_rrf(ltgt, _d, 64); + case_rrr(ord, _d); + case_rrf(ord, _d, 64); + case_rrr(unord, _d); + case_rrf(unord, _d, 64); + case_brr(blt, _d); + case_brf(blt, _d, 64); + case_brr(ble, _d); + case_brf(ble, _d, 64); + case_brr(beq, _d); + case_brf(beq, _d, 64); + case_brr(bge, _d); + case_brf(bge, _d, 64); + case_brr(bgt, _d); + case_brf(bgt, _d, 64); + case_brr(bne, _d); + case_brf(bne, _d, 64); + case_brr(bunlt, _d); + case_brf(bunlt, _d, 64); + case_brr(bunle, _d); + case_brf(bunle, _d, 64); + case_brr(buneq, _d); + case_brf(buneq, _d, 64); + case_brr(bunge, _d); + case_brf(bunge, _d, 64); + case_brr(bungt, _d); + case_brf(bungt, _d, 64); + case_brr(bltgt, _d); + case_brf(bltgt, _d, 64); + case_brr(bord, _d); + case_brf(bord, _d, 64); + case_brr(bunord, _d); + case_brf(bunord, _d, 64); + case_rr(ld, _d); + case_rw(ld, _d); + case_rrr(ldx, _d); + case_rrw(ldx, _d); + case_rr(st, _d); + case_wr(st, _d); + case_rrr(stx, _d); + case_wrr(stx, _d); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + break; + case jit_code_jmpi: + if (node->flag & jit_flag_node) { +#if _CALL_AIXDESC + if (_jit->pc.uc == _jit->code.ptr + sizeof(void*) * 3) + _jitc->jump = 1; +#endif + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi(_jit->pc.w); + patch(word, node); + } + } + else + (void)jmpi_p(node->u.w); + break; + case jit_code_callr: + callr(rn(node->u.w) +#if _CALL_SYSV + , !!(node->flag & jit_flag_varargs) +#endif + ); + break; + case jit_code_calli: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = calli_p(temp->u.w +#if _CALL_SYSV + , !!(node->flag & jit_flag_varargs) +#endif + ); + if (!(temp->flag & jit_flag_patch)) + patch(word, node); + } + else + calli(node->u.w +#if _CALL_SYSV + , !!(node->flag & jit_flag_varargs) +#endif + ); + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif + undo.patch_offset = _jitc->patches.offset; +#if _CALL_AIXDESC + undo.prolog_offset = _jitc->prolog.offset; +#endif + restart_function: + _jitc->again = 0; +#if _CALL_AIXDESC + if (_jitc->jump && !_jitc->function->assume_frame) { + /* remember prolog to hide offset adjustment for a jump + * to the start of a function, what is expected to be + * a common practice as first jit instruction */ + if (_jitc->prolog.offset >= _jitc->prolog.length) { + _jitc->prolog.length += 16; + jit_realloc((jit_pointer_t *)&_jitc->prolog.ptr, + (_jitc->prolog.length - 16) * + sizeof(jit_word_t), + _jitc->prolog.length * sizeof(jit_word_t)); + } + _jitc->prolog.ptr[_jitc->prolog.offset++] = _jit->pc.w; + /* function descriptor */ + word = _jit->pc.w + sizeof(void*) * 3; + iw(word); /* addr */ + iw(0); /* toc */ + iw(0); /* env */ + } +#endif + prolog(node); + break; + case jit_code_epilog: + assert(_jitc->function == _jitc->functions.ptr + node->w.w); + if (_jitc->again) { + for (temp = undo.node->next; + temp != node; temp = temp->next) { + if (temp->code == jit_code_label || + temp->code == jit_code_epilog) + temp->flag &= ~jit_flag_patch; + } + temp->flag &= ~jit_flag_patch; + node = undo.node; + _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif + _jitc->patches.offset = undo.patch_offset; +#if _CALL_AIXDESC + _jitc->prolog.offset = undo.prolog_offset; +#endif + goto restart_function; + } + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + epilog(node); + _jitc->function = NULL; + break; + case jit_code_va_start: + vastart(rn(node->u.w)); + break; + case jit_code_va_arg: + vaarg(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_va_arg_d: + vaarg_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_live: + case jit_code_arg: case jit_code_ellipsis: + case jit_code_va_push: + case jit_code_allocai: case jit_code_allocar: + case jit_code_arg_f: case jit_code_arg_d: + case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: +#if __WORDSIZE == 64 + case jit_code_getarg_ui: case jit_code_getarg_l: +#endif + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: +#if __WORDSIZE == 64 + case jit_code_retval_ui: case jit_code_retval_l: +#endif + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: + break; + default: + abort(); + } + jit_regarg_clr(node, value); + assert(_jitc->regarg == 0 && _jitc->synth == 0); + /* update register live state */ + jit_reglive(node); + } +#undef case_brf +#undef case_brw +#undef case_brr +#undef case_wrr +#undef case_rrf +#undef case_rrw +#undef case_rrr +#undef case_wr +#undef case_rw +#undef case_rr + + for (offset = 0; offset < _jitc->patches.offset; offset++) { + node = _jitc->patches.ptr[offset].node; + word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(_jitc->patches.ptr[offset].inst, word); + } + + jit_flush(_jit->code.ptr, _jit->pc.uc); + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_ppc-cpu.c" +# include "jit_ppc-fpu.c" +#undef CODE + +void +jit_flush(void *fptr, void *tptr) +{ +#if defined(__GNUC__) + jit_word_t f, t, s; + + s = sysconf(_SC_PAGE_SIZE); + f = (jit_word_t)fptr & -s; + t = (((jit_word_t)tptr) + s - 1) & -s; + __clear_cache((void *)f, (void *)t); +#endif +} + +void +_emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ +#if __WORDSIZE == 32 + ldxi_i(rn(r0), rn(r1), i0); +#else + ldxi_l(rn(r0), rn(r1), i0); +#endif +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ +#if __WORDSIZE == 32 + stxi_i(i0, rn(r0), rn(r1)); +#else + stxi_l(i0, rn(r0), rn(r1)); +#endif +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi_d(rn(r0), rn(r1), i0); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi_d(i0, rn(r0), rn(r1)); +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) + flag = node->v.n->flag; + else + flag = node->u.n->flag; + assert(!(flag & jit_flag_patch)); + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} diff --git a/deps/lightning/lib/jit_print.c b/deps/lightning/lib/jit_print.c new file mode 100644 index 0000000..3d7c0ac --- /dev/null +++ b/deps/lightning/lib/jit_print.c @@ -0,0 +1,367 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include <lightning.h> +#include <lightning/jit_private.h> + +#define print_chr(value) fputc(value, stdout) +#define print_hex(value) fprintf(stdout, "0x%lx", value) +#define print_dec(value) fprintf(stdout, "%ld", value) +#define print_flt(value) fprintf(stdout, "%g", value) +#define print_str(value) fprintf(stdout, "%s", value) +#define print_ptr(value) fprintf(stdout, "%p", value) +#define print_reg(value) \ + do { \ + if ((value) & jit_regno_patch) \ + print_chr('?'); \ + print_str(_rvs[jit_regno(value)].name); \ + } while (0) +#define print_arg(value) \ + do { \ + print_chr('#'); \ + if (value) \ + print_dec((value)->v.w); \ + else \ + print_chr('?'); \ + } while (0) + +/* + * Initialization + */ +#include "jit_names.c" + +/* + * Implementation + */ +void +_jit_print(jit_state_t *_jit) +{ + jit_node_t *node; + + if ((node = _jitc->head)) { + jit_print_node(node); + for (node = node->next; node; node = node->next) { + print_chr('\n'); + jit_print_node(node); + } + print_chr('\n'); + } +} + +void +_jit_print_node(jit_state_t *_jit, jit_node_t *node) +{ + jit_block_t *block; + jit_int32_t value; + jit_int32_t offset; + + if (node->code == jit_code_label || + node->code == jit_code_prolog || node->code == jit_code_epilog) { + print_chr('L'); + print_dec(node->v.w); + print_chr(':'); + block = _jitc->blocks.ptr + node->v.w; + for (offset = 0; offset < _jitc->reglen; offset++) { + if (jit_regset_tstbit(&block->reglive, offset)) { + print_chr(' '); + print_reg(offset); + } + } + if (node->code == jit_code_prolog || + node->code == jit_code_epilog) { + print_str(" /* "); + print_str(code_name[node->code]); + print_str(" */"); + } + return; + } + value = jit_classify(node->code) & + (jit_cc_a0_int|jit_cc_a0_flt|jit_cc_a0_dbl|jit_cc_a0_jmp| + jit_cc_a0_reg|jit_cc_a0_rlh|jit_cc_a0_arg| + jit_cc_a1_reg|jit_cc_a1_int|jit_cc_a1_flt|jit_cc_a1_dbl|jit_cc_a1_arg| + jit_cc_a2_reg|jit_cc_a2_int|jit_cc_a2_flt|jit_cc_a2_dbl); + if (!(node->flag & jit_flag_synth) && ((value & jit_cc_a0_jmp) || + node->code == jit_code_finishr || + node->code == jit_code_finishi)) + print_str(" "); + else + print_chr('\t'); + if (node->flag & jit_flag_synth) + print_str(" \\__ "); + print_str(code_name[node->code]); + switch (node->code) { + r: + print_chr(' '); print_reg(node->u.w); return; + w: + print_chr(' '); print_hex(node->u.w); return; + f: + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float32_t *)node->u.n->u.w); + else + print_flt(node->u.f); + return; + d: + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float64_t *)node->u.n->u.w); + else + print_flt(node->u.d); + return; + n: + print_chr(' '); + if (!(node->flag & jit_flag_node)) + print_ptr(node->u.p); + else { + print_chr('L'); + print_dec(node->u.n->v.w); + } + return; + a: + print_chr(' '); print_arg(node); return; + r_r: + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_reg(node->v.w); return; + r_w: + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_hex(node->v.w); return; + r_f: + print_chr(' '); print_reg(node->u.w); + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float32_t *)node->v.n->u.w); + else + print_flt(node->v.f); + return; + r_d: + print_chr(' '); print_reg(node->u.w); + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float64_t *)node->v.n->u.w); + else + print_flt(node->v.d); + return; + r_a: + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_arg(node->v.n); + return; + w_r: + print_chr(' '); print_hex(node->u.w); + print_chr(' '); print_reg(node->v.w); return; + w_w: + print_chr(' '); print_hex(node->u.w); + print_chr(' '); print_hex(node->v.w); return; + w_a: + print_chr(' '); print_hex(node->u.w); + print_chr(' '); print_arg(node->v.n); + return; + f_a: + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float32_t *)node->u.n->u.w); + else + print_flt(node->u.f); + print_chr(' '); print_arg(node->v.n); + return; + d_a: + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float64_t *)node->u.n->u.w); + else + print_flt(node->u.d); + print_chr(' '); print_arg(node->v.n); + return; + r_r_r: + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_reg(node->w.w); return; + r_r_w: + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_hex(node->w.w); return; + q_r_r: + print_str(" ("); print_reg(node->u.q.l); + print_chr(' '); print_reg(node->u.q.h); + print_str(") "); print_reg(node->v.w); + print_chr(' '); print_reg(node->w.w); return; + q_r_w: + print_str(" ("); print_reg(node->u.q.l); + print_chr(' '); print_reg(node->u.q.h); + print_str(") "); print_reg(node->v.w); + print_chr(' '); print_hex(node->w.w); return; + r_r_f: + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_reg(node->v.w); + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float32_t *)node->w.n->u.w); + else + print_flt(node->w.f); + return; + r_r_d: + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_reg(node->v.w); + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float64_t *)node->w.n->u.w); + else + print_flt(node->w.d); + return; + w_r_r: + print_chr(' '); print_hex(node->u.w); + print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_reg(node->w.w); return; + n_r_r: + print_chr(' '); + if (!(node->flag & jit_flag_node)) + print_ptr(node->u.p); + else { + print_chr('L'); + print_dec(node->u.n->v.w); + } + print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_reg(node->w.w); return; + n_r_w: + print_chr(' '); + if (!(node->flag & jit_flag_node)) + print_ptr(node->u.p); + else { + print_chr('L'); + print_dec(node->u.n->v.w); + } + print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_hex(node->w.w); return; + n_r_f: + print_chr(' '); + if (!(node->flag & jit_flag_node)) + print_ptr(node->u.p); + else{ + print_chr('L'); + print_dec(node->u.n->v.w); + } + print_chr(' '); print_reg(node->v.w); + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float32_t *)node->w.n->u.w); + else + print_flt(node->w.f); + return; + n_r_d: + print_chr(' '); + if (!(node->flag & jit_flag_node)) + print_ptr(node->u.p); + else { + print_chr('L'); + print_dec(node->u.n->v.w); + } + print_chr(' '); print_reg(node->v.w); + print_chr(' '); + if (node->flag & jit_flag_data) + print_flt(*(jit_float64_t *)node->w.n->u.w); + else + print_flt(node->w.d); + return; + case jit_code_name: + print_chr(' '); + if (node->v.p && _jitc->emit) + print_str(node->v.n->u.p); + break; + case jit_code_note: + print_chr(' '); + if (node->v.p && _jitc->emit) + print_str(node->v.n->u.p); + if (node->v.p && _jitc->emit && node->w.w) + print_chr(':'); + if (node->w.w) + print_dec(node->w.w); + break; + case jit_code_data: + case jit_code_label: + case jit_code_ellipsis: + case jit_code_prolog: case jit_code_epilog: + case jit_code_ret: case jit_code_prepare: + break; + case jit_code_save: case jit_code_load: + goto r; + default: + switch (value) { + case jit_cc_a0_reg: + case jit_cc_a0_reg|jit_cc_a0_chg: + case jit_cc_a0_reg|jit_cc_a0_jmp: + goto r; + case jit_cc_a0_int: + goto w; + case jit_cc_a0_flt: + goto f; + case jit_cc_a0_dbl: + goto d; + case jit_cc_a0_jmp: + goto n; + case jit_cc_a0_int|jit_cc_a0_arg: + goto a; + case jit_cc_a0_reg|jit_cc_a1_reg: + goto r_r; + case jit_cc_a0_reg|jit_cc_a1_int: + goto r_w; + case jit_cc_a0_reg|jit_cc_a1_flt: + goto r_f; + case jit_cc_a0_reg|jit_cc_a1_dbl: + goto r_d; + case jit_cc_a0_reg|jit_cc_a1_arg: + goto r_a; + case jit_cc_a0_int|jit_cc_a1_reg: + goto w_r; + case jit_cc_a0_int|jit_cc_a1_int: + goto w_w; + case jit_cc_a0_int|jit_cc_a1_arg: + goto w_a; + case jit_cc_a0_flt|jit_cc_a1_arg: + goto f_a; + case jit_cc_a0_dbl|jit_cc_a1_arg: + goto d_a; + case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_reg: + goto r_r_r; + case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_int: + goto r_r_w; + case jit_cc_a0_reg|jit_cc_a0_rlh| + jit_cc_a1_reg|jit_cc_a2_reg: + goto q_r_r; + case jit_cc_a0_reg|jit_cc_a0_rlh| + jit_cc_a1_reg|jit_cc_a2_int: + goto q_r_w; + case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_flt: + goto r_r_f; + case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_dbl: + goto r_r_d; + case jit_cc_a0_int|jit_cc_a1_reg|jit_cc_a2_reg: + goto w_r_r; + case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_reg: + goto n_r_r; + case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_int: + goto n_r_w; + case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_flt: + goto n_r_f; + case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_dbl: + goto n_r_d; + default: + abort(); + } + break; + } +} diff --git a/deps/lightning/lib/jit_rewind.c b/deps/lightning/lib/jit_rewind.c new file mode 100644 index 0000000..5ef1be5 --- /dev/null +++ b/deps/lightning/lib/jit_rewind.c @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2015-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include <lightning.h> +#include <lightning/jit_private.h> + +#if PROTO +# define free_synth_list(node) _free_synth_list(_jit,node) +static jit_node_t *_free_synth_list(jit_state_t*,jit_node_t*); +#define rewind_prolog() _rewind_prolog(_jit) +static void _rewind_prolog(jit_state_t*); +#define rewind_prepare() _rewind_prepare(_jit) +static void _rewind_prepare(jit_state_t*); +#endif + +#if CODE +/* + * Implementation + */ +static jit_node_t * +_free_synth_list(jit_state_t *_jit, jit_node_t *node) +{ + jit_node_t *next; + next = node->next; + free_node(node); + for (node = next; node && (node->flag & jit_flag_synth); node = next) { + next = node->next; + free_node(node); + } + return (next); +} + +static void +_rewind_prolog(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *next; + _jitc->function->self.size = stack_framesize; +#if __arm__ + assert(jit_cpu.abi); + _jitc->function->self.size += 64; +#endif +#if __mips__ && NEW_ABI + /* Only add extra stack space if there are varargs + * arguments in registers. */ + assert(jit_arg_reg_p(_jitc->function->self.argi)); + _jitc->function->self.size += 64; +#endif + _jitc->function->self.argi = + _jitc->function->self.argf = _jitc->function->self.argn = 0; + _jitc->tail = _jitc->function->prolog; + node = _jitc->tail->next; + _jitc->tail->next = (jit_node_t *)0; + _jitc->tail->link = (jit_node_t *)0; + for (; node; node = next) { + next = node->next; + switch (node->code) { + case jit_code_arg: + node->next = (jit_node_t *)0; + jit_make_arg(node); + break; + case jit_code_arg_f: + node->next = (jit_node_t *)0; + jit_make_arg_f(node); + break; + case jit_code_arg_d: + node->next = (jit_node_t *)0; + jit_make_arg_d(node); + break; + case jit_code_getarg_c: + jit_getarg_c(node->u.w, node->v.n); + next = free_synth_list(node); + break; + case jit_code_getarg_uc: + jit_getarg_uc(node->u.w, node->v.n); + next = free_synth_list(node); + break; + case jit_code_getarg_s: + jit_getarg_s(node->u.w, node->v.n); + next = free_synth_list(node); + break; + case jit_code_getarg_us: + jit_getarg_us(node->u.w, node->v.n); + next = free_synth_list(node); + break; + case jit_code_getarg_i: + jit_getarg_i(node->u.w, node->v.n); + next = free_synth_list(node); + break; + case jit_code_getarg_f: + jit_getarg_f(node->u.w, node->v.n); + next = free_synth_list(node); + break; + case jit_code_getarg_d: + jit_getarg_d(node->u.w, node->v.n); + next = free_synth_list(node); + break; + case jit_code_putargr: + jit_putargr(node->u.w, node->v.n); + next = free_synth_list(node); + break; + case jit_code_putargi: + jit_putargi(node->u.w, node->v.n); + next = free_synth_list(node); + break; + case jit_code_putargr_f: + jit_putargr_f(node->u.w, node->v.n); + next = free_synth_list(node); + break; + case jit_code_putargi_f: + jit_putargi_f(node->u.f, node->v.n); + next = free_synth_list(node); + break; + case jit_code_putargr_d: + jit_putargr_d(node->u.w, node->v.n); + next = free_synth_list(node); + break; + case jit_code_putargi_d: + jit_putargi_d(node->u.d, node->v.n); + next = free_synth_list(node); + break; + default: + node->next = (jit_node_t *)0; + link_node(node); + break; + } + } +} + +static void +_rewind_prepare(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *next; + _jitc->function->call.argi = + _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->tail = _jitc->prepare; + node = _jitc->tail->next; + _jitc->tail->next = (jit_node_t *)0; + _jitc->tail->link = (jit_node_t *)0; + for (; node; node = next) { + next = node->next; + switch (node->code) { + case jit_code_pushargr: + jit_pushargr(node->u.w); + next = free_synth_list(node); + break; + case jit_code_pushargi: + jit_pushargi(node->u.w); + next = free_synth_list(node); + break; + case jit_code_pushargr_f: + jit_pushargr_f(node->u.w); + next = free_synth_list(node); + break; + case jit_code_pushargi_f: + jit_pushargi_f(node->u.f); + next = free_synth_list(node); + break; + case jit_code_pushargr_d: + jit_pushargr_d(node->u.w); + next = free_synth_list(node); + break; + case jit_code_pushargi_d: + jit_pushargi_d(node->u.d); + next = free_synth_list(node); + break; + default: + node->next = (jit_node_t *)0; + link_node(node); + break; + } + } +} +#endif diff --git a/deps/lightning/lib/jit_riscv-cpu.c b/deps/lightning/lib/jit_riscv-cpu.c new file mode 100644 index 0000000..388489f --- /dev/null +++ b/deps/lightning/lib/jit_riscv-cpu.c @@ -0,0 +1,2378 @@ +/* + * Copyright (C) 2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +#define _ZERO_REGNO 0 +#define _RA_REGNO 1 +#define _SP_REGNO 2 +#define _FP_REGNO 8 +typedef union { +# define ui jit_uint32_t + struct { + ui opcode : 7; + ui rd : 5; + ui funct3 : 3; + ui rs1 : 5; + ui rs2 : 5; + ui funct7 : 7; + } R; + struct { + ui opcode : 7; + ui rd : 5; + ui funct3 : 3; + ui rs1 : 5; + ui rs2 : 5; + ui funct2 : 2; + ui rs3 : 5; + } R4; + struct { + ui opcode : 7; + ui rd : 5; + ui funct3 : 3; + ui rs1 : 5; + ui imm11_0 : 12; + } I; +# if __WORDSIZE == 64 + struct { + ui opcode : 7; + ui rd : 5; + ui funct3 : 3; + ui rs1 : 5; + ui shamt : 6; + ui imm6_0 : 6; + } IS; +# endif + struct { + ui opcode : 7; + ui imm4_0 : 5; + ui funct3 : 3; + ui rs1 : 5; + ui rs2 : 5; + ui imm11_5 : 7; + } S; + struct { + ui opcode : 7; + ui imm11 : 1; + ui imm4_1 : 4; + ui funct3 : 3; + ui rs1 : 5; + ui rs2 : 5; + ui imm10_5 : 6; + ui imm12 : 1; + } B; + struct { + ui opcode : 7; + ui rd : 5; + ui imm12_31 : 20; + } U; + struct { + ui opcode : 7; + ui rd : 5; + ui imm19_12 : 8; + ui imm11 : 1; + ui imm10_1 : 10; + ui imm20 : 1; + } J; + jit_int32_t w; +# undef ui +} instr_t; +# define ii(i) *_jit->pc.ui++ = i +/* FIXME could jit_rewind_prolog() to only use extra 64 bytes + * if a variadic jit function that have variadic arguments in + * registers */ +# define stack_framesize (200 + 64) +# define ldr(r0, r1) ldr_l(r0, r1) +# define ldi(r0, im) ldi_l(r0, im) +# define ldxr(r0, r1, r2) ldxr_l(r0, r1, r2) +# define ldxi(r0, r1, im) ldxi_l(r0, r1, im) +# define str(r0, r1) str_l(r0, r1) +# define sti(im, r0) sti_l(im, r0) +# define stxr(r0, r1, r2) stxr_l(r0, r1, r2) +# define stxi(im, r0, r1) stxi_l(im, r0, r1) +# define simm6_p(im) ((im) <= 31 && (im) >= -32) +# define simm12_p(im) ((im) <= 2047 && (im) >= -2048) +# define simm20_p(im) ((im) <= 524287 && (im) >= -524288) +# define simm32_p(im) ((im) <= 2147483647LL && (im) >= -2147483648LL) + +/* + * RV32I Base Instruction Set + */ +# define LUI(rd, imm) Utype(55, rd, imm) +# define AUIPC(rd, imm) Utype(23, rd, imm) +# define JAL(rd, imm) Jtype(111, rd, imm) +# define JALR(rd, rs1, imm) Itype(103, rd, 0, rs1, imm) +# define BEQ(rs1, rs2, imm) Btype(99, 0, rs1, rs2, imm) +# define BNE(rs1, rs2, imm) Btype(99, 1, rs1, rs2, imm) +# define BLT(rs1, rs2, imm) Btype(99, 4, rs1, rs2, imm) +# define BGE(rs1, rs2, imm) Btype(99, 5, rs1, rs2, imm) +# define BLTU(rs1, rs2, imm) Btype(99, 6, rs1, rs2, imm) +# define BGEU(rs1, rs2, imm) Btype(99, 7, rs1, rs2, imm) +# define LB(rd, rs1, imm) Itype(3, rd, 0, rs1, imm) +# define LH(rd, rs1, imm) Itype(3, rd, 1, rs1, imm) +# define LW(rd, rs1, imm) Itype(3, rd, 2, rs1, imm) +# define LBU(rd, rs1, imm) Itype(3, rd, 4, rs1, imm) +# define LHU(rd, rs1, imm) Itype(3, rd, 5, rs1, imm) +# define SB(rs1, rs2, imm) Stype(35, 0, rs1, rs2, imm) +# define SH(rs1, rs2, imm) Stype(35, 1, rs1, rs2, imm) +# define SW(rs1, rs2, imm) Stype(35, 2, rs1, rs2, imm) +# define ADDI(rd, rs1, imm) Itype(19, rd, 0, rs1, imm) +# define SLTI(rd, rs1, imm) Itype(19, rd, 2, rs1, imm) +# define SLTIU(rd, rs1, imm) Itype(19, rd, 3, rs1, imm) +# define XORI(rd, rs1, imm) Itype(19, rd, 4, rs1, imm) +# define ORI(rd, rs1, imm) Itype(19, rd, 6, rs1, imm) +# define ANDI(rd, rs1, imm) Itype(19, rd, 7, rs1, imm) +# if __WORDSIZE == 32 +# define SLLI(rd, rs1, imm) Rtype(19, rd, 1, rs1, imm, 0) +# define SRLI(rd, rs1, imm) Rtype(19, rd, 5, rs1, imm, 0) +# define SRAI(rd, rs1, imm) Rtype(19, rd, 5, rs1, imm, 32) +# endif +# define ADD(rd, rs1, rs2) Rtype(51, rd, 0, rs1, rs2, 0) +# define SUB(rd, rs1, rs2) Rtype(51, rd, 0, rs1, rs2, 32) +# define SLL(rd, rs1, rs2) Rtype(51, rd, 1, rs1, rs2, 0) +# define SLT(rd, rs1, rs2) Rtype(51, rd, 2, rs1, rs2, 0) +# define SLTU(rd, rs1, rs2) Rtype(51, rd, 3, rs1, rs2, 0) +# define XOR(rd, rs1, rs2) Rtype(51, rd, 4, rs1, rs2, 0) +# define SRL(rd, rs1, rs2) Rtype(51, rd, 5, rs1, rs2, 0) +# define SRA(rd, rs1, rs2) Rtype(51, rd, 5, rs1, rs2, 32) +# define OR(rd, rs1, rs2) Rtype(51, rd, 6, rs1, rs2, 0) +# define AND(rd, rs1, rs2) Rtype(51, rd, 7, rs1, rs2, 0) +# define FENCE(imm) Itype(15, 0, 0, 0, im) +# define FENCE_I(imm) Itype(15, 0, 1, 0, im) +# define ECALL() Itype(115, 0, 0, 0, 0) +# define EBREAK() Itype(115, 0, 0, 0, 1) +# define CSRRW(rd, rs1, csr) Itype(115, rd, 1, rs1, csr) +# define CSRRS(rd, rs1, csr) Itype(115, rd, 2, rs1, csr) +# define CSRRC(rd, rs1, csr) Itype(115, rd, 3, rs1, csr) +# define CSRRWI(rd, zimm, csr) Itype(115, rd, 5, zimm, csr) +# define CSRRSI(rd, zimm, csr) Itype(115, rd, 6, zimm, csr) +# define CSRRCI(rd, zimm, csr) Itype(115, rd, 7, zimm, csr) +/* + * RV64I Base Instruction Set (in addition to RV32I) + */ +# define LWU(rd, rs1, imm) Itype(3, rd, 6, rs1, imm) +# define LD(rd, rs1, imm) Itype(3, rd, 3, rs1, imm) +# define SD(rs1, rs2, imm) Stype(35, 3, rs1, rs2, imm) +# if __WORDSIZE == 64 +# define SLLI(rd, rs1, sh) IStype(19, rd, 1, rs1, sh, 0) +# define SRLI(rd, rs1, sh) IStype(19, rd, 5, rs1, sh, 0) +# define SRAI(rd, rs1, sh) IStype(19, rd, 5, rs1, sh, 16) +# endif +# define ADDIW(rd, rs1, imm) Itype(27, rd, 0, rs1, imm) +# define SLLIW(rd, rs1, imm) Rtype(27, rd, 1, rs1, imm, 0) +# define SRLIW(rd, rs1, imm) Rtype(27, rd, 3, rs1, imm, 0) +# define SRAIW(rd, rs1, imm) Rtype(27, rd, 3, rs1, imm, 32) +# define ADDW(rd, rs1, imm) Rtype(59, rd, 0, rs1, imm, 0) +# define SUBW(rd, rs1, imm) Rtype(59, rd, 0, rs1, imm, 32) +# define SLLW(rd, rs1, imm) Rtype(59, rd, 1, rs1, imm, 0) +# define SRLW(rd, rs1, imm) Rtype(59, rd, 5, rs1, imm, 0) +# define SRAW(rd, rs1, imm) Rtype(59, rd, 5, rs1, imm, 32) +/* + * RV32M Standard Extension + */ +# define MUL(rd, rs1, rs2) Rtype(51, rd, 0, rs1, rs2, 1) +# define MULH(rd, rs1, rs2) Rtype(51, rd, 1, rs1, rs2, 1) +# define MULHSU(rd, rs1, rs2) Rtype(51, rd, 2, rs1, rs2, 1) +# define MULHU(rd, rs1, rs2) Rtype(51, rd, 3, rs1, rs2, 1) +# define DIV(rd, rs1, rs2) Rtype(51, rd, 4, rs1, rs2, 1) +# define DIVU(rd, rs1, rs2) Rtype(51, rd, 5, rs1, rs2, 1) +# define REM(rd, rs1, rs2) Rtype(51, rd, 6, rs1, rs2, 1) +# define REMU(rd, rs1, rs2) Rtype(51, rd, 7, rs1, rs2, 1) +/* + * RV64M Standard Extension (in addition to RV32M) + */ +# define MULW(rd, rs1, rs2) Rtype(59, rd, 0, rs1, rs2, 1) +# define DIVW(rd, rs1, rs2) Rtype(59, rd, 4, rs1, rs2, 1) +# define DIVUW(rd, rs1, rs2) Rtype(59, rd, 5, rs1, rs2, 1) +# define REMW(rd, rs1, rs2) Rtype(59, rd, 6, rs1, rs2, 1) +# define REMUW(rd, rs1, rs2) Rtype(59, rd, 7, rs1, rs2, 1) +/* + * RV32A Standard Extension + */ +# define LR_W(rd, rs1) R4type(47, rd, 2, rs1, 0, 0, 2) +# define SC_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 3) +# define AMOSWAP_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 1) +# define AMOADD_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 0) +# define AMOXOR_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 4) +# define AMOAND_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 12) +# define AMOOR_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 8) +# define AMOMIN_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 16) +# define AMOMAX_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 20) +# define AMOMINU_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 24) +# define AMOMAXU_W(rd, rs1, rs2) R4type(47, rd, 2, rs1, rs2, 0, 28) +/* + * RV64A Standard Extension (in addition to RV32A) + */ +# define LR_D(rd, rs1) R4type(47, rd, 3, rs1, 0, 0, 2) +# define SC_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 3) +# define AMOSWAP_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 1) +# define AMOADD_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 0) +# define AMOXOR_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 4) +# define AMOAND_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 12) +# define AMOOR_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 8) +# define AMOMIN_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 16) +# define AMOMAX_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 20) +# define AMOMINU_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 24) +# define AMOMAXU_D(rd, rs1, rs2) R4type(47, rd, 3, rs1, rs2, 0, 28) +/* + * Pseudo Instructions + */ +# define NOP() ADDI(_ZERO_REGNO, _ZERO_REGNO, 0) +# define MV(r0, r1) ADDI(r0, r1, 0) +# define NOT(r0, r1) XORI(r0, r1, -1) +# define NEG(r0, r1) SUB(r0, _ZERO_REGNO, r1) +# define NEGW(r0, r1) SUBW(r0, _ZERO_REGNO, r1) +# define SEXT_W(r0, r1) ADDIW(r0, r1, 0) +# define RET() JALR(0, 1, 0) + +/* + * Enconding functions + */ +# define Rtype(op, rd, fct, rs1, rs2, fct2) \ + _Rtype(_jit, op, rd, fct, rs1, rs2, fct2) +static void _Rtype(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t); +# define R4type(op, rd, fct, rs1,rs2,fct2,rs3) \ + _R4type(_jit, op, rd, fct, rs1, rs2, fct2, rs3) +static void _R4type(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, + jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t); +# define Itype(op, rd, fct, rs1, imm) \ + _Itype(_jit, op, rd, fct, rs1, imm) +static void _Itype(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t, jit_int32_t, jit_int32_t); +# if __WORDSIZE == 64 +# define IStype(op, rd, fct, rs1, sh, imm) \ + _IStype(_jit, op, rd, fct, rs1, sh, imm) +static void _IStype(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t, jit_int32_t, jit_int32_t,jit_int32_t); +# endif +# define Stype(op, fct, rs1, rs2, imm) \ + _Stype(_jit, op, fct, rs1, rs2, imm) +static void _Stype(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t, jit_int32_t, jit_int32_t); +# define Btype(op, fct, rs1, rs2, imm) \ + _Btype(_jit, op, fct, rs1, rs2, imm) +static void _Btype(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t, jit_int32_t, jit_int32_t); +# define Utype(op, rd, imm) _Utype(_jit, op, rd, imm) +static void _Utype(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define Jtype(op, rd, imm) _Jtype(_jit, op, rd, imm) +static void _Jtype(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +/* + * Lightning instructions + */ +# define nop(im) _nop(_jit, im) +static void _nop(jit_state_t*, jit_int32_t); +# define addr(r0, r1, r2) ADD(r0, r1, r2) +# define addi(r0, r1, im) _addi(_jit, r0, r1, im) +static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addcr(r0, r1, r2) _addcr(_jit, r0, r1, r2) +static void _addcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addci(r0, r1, im) _addci(_jit, r0, r1, im) +static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addxr(r0, r1, r2) _addxr(_jit, r0, r1, r2) +static void _addxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addxi(r0, r1, im) _addxi(_jit, r0, r1, im) +static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subr(r0, r1, r2) SUB(r0, r1, r2) +# define subi(r0, r1, im) _subi(_jit, r0, r1, im) +static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subcr(r0, r1, r2) _subcr(_jit, r0, r1, r2) +static void _subcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subci(r0, r1, im) _subci(_jit, r0, r1, im) +static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subxr(r0, r1, r2) _subxr(_jit, r0, r1, r2) +static void _subxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subxi(r0, r1, im) _subxi(_jit, r0, r1, im) +static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rsbi(r0, r1, im) _rsbi(_jit, r0, r1, im) +static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define mulr(r0, r1, r2) MUL(r0, r1, r2) +# define muli(r0, r1, im) _muli(_jit, r0, r1, im) +static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define divr(r0, r1, r2) DIV(r0, r1, r2) +# define divi(r0, r1, im) _divi(_jit, r0, r1, im) +static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define divr_u(r0, r1, r2) DIVU(r0, r1, r2) +# define divi_u(r0, r1, im) _divi_u(_jit, r0, r1, im) +static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define remr(r0, r1, r2) REM(r0, r1, r2) +# define remi(r0, r1, im) _remi(_jit, r0, r1, im) +static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define remr_u(r0, r1, r2) REMU(r0, r1, r2) +# define remi_u(r0, r1, im) _remi_u(_jit, r0, r1, im) +static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr(r0, r1, r2, r3) _qmulr(_jit,r0,r1,r2,r3) +static void _qmulr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define qmuli(r0, r1, r2, i0) _qmuli(_jit,r0,r1,r2,i0) +static void _qmuli(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr_u(r0, r1, r2, r3) _qmulr_u(_jit,r0,r1,r2,r3) +static void _qmulr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define qmuli_u(r0, r1, r2, i0) _qmuli_u(_jit,r0,r1,r2,i0) +static void _qmuli_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +static void _iqdivr(jit_state_t*,jit_bool_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define qdivr(r0,r1,r2,r3) _iqdivr(_jit,1,r0,r1,r2,r3) +# define qdivr_u(r0,r1,r2,r3) _iqdivr(_jit,0,r0,r1,r2,r3) +static void _iqdivr(jit_state_t*,jit_bool_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define qdivi(r0,r1,r2,i0) _qdivi(_jit,r0,r1,r2,i0) +static void _qdivi(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define qdivi_u(r0,r1,r2,i0) _qdivi_u(_jit,r0,r1,r2,i0) +static void _qdivi_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define lshr(r0, r1, r2) SLL(r0, r1, r2) +# define lshi(r0, r1, im) _lshi(_jit, r0, r1, im) +static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr(r0, r1, r2) SRA(r0, r1, r2) +# define rshi(r0, r1, im) _rshi(_jit, r0, r1, im) +static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr_u(r0, r1, r2) SRL(r0, r1, r2) +# define rshi_u(r0, r1, im) _rshi_u(_jit, r0, r1, im) +static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define negr(r0, r1) NEG(r0, r1) +# define comr(r0, r1) NOT(r0, r1) +# define andr(r0, r1, r2) AND(r0, r1, r2) +# define andi(r0, r1, im) _andi(_jit, r0, r1, im) +static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define orr(r0, r1, r2) OR(r0, r1, r2) +# define ori(r0, r1, im) _ori(_jit, r0, r1, im) +static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define xorr(r0, r1, r2) XOR(r0, r1, r2) +# define xori(r0, r1, im) _xori(_jit, r0, r1, im) +static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_c(r0, r1) LB(r0, r1, 0) +# define ldi_c(r0, im) _ldi_c(_jit, r0, im) +static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_uc(r0, r1) LBU(r0, r1, 0) +# define ldi_uc(r0, im) _ldi_uc(_jit, r0, im) +static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_s(r0, r1) LH(r0, r1, 0) +# define ldi_s(r0, im) _ldi_s(_jit, r0, im) +static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_us(r0, r1) LHU(r0, r1, 0) +# define ldi_us(r0, im) _ldi_us(_jit, r0, im) +static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_i(r0, r1) LW(r0, r1, 0) +# define ldi_i(r0, im) _ldi_i(_jit, r0, im) +static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_ui(r0, r1) LWU(r0, r1, 0) +# define ldi_ui(r0, im) _ldi_ui(_jit, r0, im) +static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_l(r0, r1) LD(r0, r1, 0) +# define ldi_l(r0, im) _ldi_l(_jit, r0, im) +static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_c(r0, r1, r2) _ldxr_c(_jit, r0, r1, r2) +static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_c(r0, r1, im) _ldxi_c(_jit, r0, r1, im) +static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_uc(r0, r1, r2) _ldxr_uc(_jit, r0, r1, r2) +static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_uc(r0, r1, im) _ldxi_uc(_jit, r0, r1, im) +static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_s(r0, r1, r2) _ldxr_s(_jit, r0, r1, r2) +static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_s(r0, r1, im) _ldxi_s(_jit, r0, r1, im) +static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_us(r0, r1, r2) _ldxr_us(_jit, r0, r1, r2) +static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_us(r0, r1, im) _ldxi_us(_jit, r0, r1, im) +static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_i(r0, r1, r2) _ldxr_i(_jit, r0, r1, r2) +static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_i(r0, r1, im) _ldxi_i(_jit, r0, r1, im) +static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_ui(r0, r1, r2) _ldxr_ui(_jit, r0, r1, r2) +static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_ui(r0, r1, im) _ldxi_ui(_jit, r0, r1, im) +static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_l(r0, r1, r2) _ldxr_l(_jit, r0, r1, r2) +static void _ldxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_l(r0, r1, im) _ldxi_l(_jit, r0, r1, im) +static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_c(r0, r1) SB(r0, r1, 0) +# define sti_c(im, r0) _sti_c(_jit, im, r0) +static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t); +# define str_s(r0, r1) SH(r0, r1, 0) +# define sti_s(im, r0) _sti_s(_jit, im, r0) +static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t); +# define str_i(r0, r1) SW(r0, r1, 0) +# define sti_i(im, r0) _sti_i(_jit, im, r0) +static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); +# define str_l(r0, r1) SD(r0, r1, 0) +# define sti_l(im, r0) _sti_l(_jit, im, r0) +static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_c(r0, r1, r2) _stxr_c(_jit, r0, r1, r2) +static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_c(i0, r0, r1) _stxi_c(_jit, i0, r0, r1) +static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_s(r0, r1, r2) _stxr_s(_jit, r0, r1, r2) +static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_s(i0, r0, r1) _stxi_s(_jit, i0, r0, r1) +static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_i(r0, r1, r2) _stxr_i(_jit, r0, r1, r2) +static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_i(i0, r0, r1) _stxi_i(_jit, i0, r0, r1) +static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_l(r0, r1, r2) _stxr_l(_jit, r0, r1, r2) +static void _stxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_l(i0, r0, r1) _stxi_l(_jit, i0, r0, r1) +static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define htonr_us(r0, r1) _htonr_us(_jit, r0, r1) +static void _htonr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define htonr_ui(r0, r1) _htonr_ui(_jit, r0, r1) +static void _htonr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# define htonr_ul(r0, r1) _htonr_ul(_jit, r0, r1) +static void _htonr_ul(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_c(r0, r1) _extr_c(_jit, r0, r1) +static void _extr_c(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_uc(r0, r1) andi(r0, r1, 0xff) +# define extr_s(r0, r1) _extr_s(_jit, r0, r1) +static void _extr_s(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_us(r0, r1) _extr_us(_jit, r0, r1) +static void _extr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_i(r0, r1) SEXT_W(r0, r1) +# define extr_ui(r0, r1) _extr_ui(_jit, r0, r1) +static void _extr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# define movr(r0, r1) MV(r0, r1) +# define movi(r0, im) _movi(_jit, r0, im) +static void _movi(jit_state_t*,jit_int32_t,jit_word_t); +# define movi_p(r0, im) _movi_p(_jit, r0, im) +static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t); +# define ltr(r0, r1, r2) SLT(r0, r1, r2) +# define lti(r0, r1, im) _lti(_jit, r0, r1, im) +static void _lti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ltr_u(r0, r1, r2) SLTU(r0, r1, r2) +# define lti_u(r0, r1, im) _lti_u(_jit, r0, r1, im) +static void _lti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ler(r0, r1, r2) _ler(_jit, r0, r1, r2) +static void _ler(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lei(r0, r1, im) _lei(_jit, r0, r1, im) +static void _lei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ler_u(r0, r1, r2) _ler_u(_jit, r0, r1, r2) +static void _ler_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lei_u(r0, r1, im) _lei_u(_jit, r0, r1, im) +static void _lei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define eqr(r0, r1, r2) _eqr(_jit, r0, r1, r2) +static void _eqr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define eqi(r0, r1, im) _eqi(_jit, r0, r1, im) +static void _eqi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ger(r0, r1, r2) _ger(_jit, r0, r1, r2) +static void _ger(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gei(r0, r1, r2) _gei(_jit, r0, r1, r2) +static void _gei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ger_u(r0, r1, r2) _ger_u(_jit, r0, r1, r2) +static void _ger_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gei_u(r0, r1, im) _gei_u(_jit, r0, r1, im) +static void _gei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define gtr(r0, r1, r2) SLT(r0, r2, r1) +# define gti(r0, r1, im) _gti(_jit, r0, r1, im) +static void _gti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define gtr_u(r0, r1, r2) SLTU(r0, r2, r1) +# define gti_u(r0, r1, im) _gti_u(_jit, r0, r1, im) +static void _gti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ner(r0, r1, r2) _ner(_jit, r0, r1, r2) +static void _ner(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define nei(r0, r1, im) _nei(_jit, r0, r1, im) +static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define bltr(br, r0, r1) _bltr(_jit, br, r0, r1) +static jit_word_t _bltr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blti(br, r0, im) _blti(_jit, br, r0, im) +static jit_word_t _blti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bltr_u(br, r0, r1) _bltr_u(_jit, br, r0, r1) +static jit_word_t _bltr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blti_u(br, r0, im) _blti_u(_jit, br, r0, im) +static jit_word_t _blti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bler(br, r0, r1) _bler(_jit, br, r0, r1) +static jit_word_t _bler(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blei(br, r0, im) _blei(_jit, br, r0, im) +static jit_word_t _blei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bler_u(br, r0, r1) _bler_u(_jit, br, r0, r1) +static jit_word_t _bler_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blei_u(br, r0, im) _blei_u(_jit, br, r0, im) +static jit_word_t _blei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define beqr(br, r0, r1) _beqr(_jit, br, r0, r1) +static jit_word_t _beqr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define beqi(br, r0, im) _beqi(_jit, br, r0, im) +static jit_word_t _beqi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bger(br, r0, r1) _bger(_jit, br, r0, r1) +static jit_word_t _bger(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgei(br, r0, im) _bgei(_jit, br, r0, im) +static jit_word_t _bgei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bger_u(br, r0, r1) _bger_u(_jit, br, r0, r1) +static jit_word_t _bger_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgei_u(br, r0, im) _bgei_u(_jit, br, r0, im) +static jit_word_t _bgei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bgtr(br, r0, r1) _bgtr(_jit, br, r0, r1) +static jit_word_t _bgtr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgti(br, r0, im) _bgti(_jit, br, r0, im) +static jit_word_t _bgti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bgtr_u(br, r0, r1) _bgtr_u(_jit, br, r0, r1) +static jit_word_t _bgtr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgti_u(br, r0, im) _bgti_u(_jit, br, r0, im) +static jit_word_t _bgti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bner(br, r0, r1) _bner(_jit, br, r0, r1) +static jit_word_t _bner(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bnei(br, r0, im) _bnei(_jit, br, r0, im) +static jit_word_t _bnei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define boaddr(br, r0, r1) _boaddr(_jit, br, r0, r1) +# define boaddi(br, r0, im) _boaddi(_jit, br, r0, im) +static jit_word_t _boaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +static jit_word_t _boaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define boaddr_u(br, r0, r1) _boaddr_u(_jit, br, r0, r1) +# define boaddi_u(br, r0, im) _boaddi_u(_jit, br, r0, im) +static jit_word_t _boaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +static jit_word_t _boaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bxaddr(br, r0, r1) _bxaddr(_jit, br, r0, r1) +# define bxaddi(br, r0, im) _bxaddi(_jit, br, r0, im) +static jit_word_t _bxaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +static jit_word_t _bxaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bxaddr_u(br, r0, r1) _bxaddr_u(_jit, br, r0, r1) +# define bxaddi_u(br, r0, im) _bxaddi_u(_jit, br, r0, im) +static jit_word_t _bxaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +static jit_word_t _bxaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bosubr(br, r0, r1) _bosubr(_jit, br, r0, r1) +# define bosubi(br, r0, im) _bosubi(_jit, br, r0, im) +static jit_word_t _bosubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +static jit_word_t _bosubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bosubr_u(br, r0, r1) _bosubr_u(_jit, br, r0, r1) +# define bosubi_u(br, r0, im) _bosubi_u(_jit, br, r0, im) +static jit_word_t _bosubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +static jit_word_t _bosubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bxsubr(br, r0, r1) _bxsubr(_jit, br, r0, r1) +# define bxsubi(br, r0, im) _bxsubi(_jit, br, r0, im) +static jit_word_t _bxsubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +static jit_word_t _bxsubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bxsubr_u(br, r0, r1) _bxsubr_u(_jit, br, r0, r1) +# define bxsubi_u(br, r0, im) _bxsubi_u(_jit, br, r0, im) +static jit_word_t _bxsubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +static jit_word_t _bxsubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bmsr(br, r0, r1) _bmsr(_jit, br, r0, r1) +# define bmsi(br, r0, im) _bmsi(_jit, br, r0, im) +static jit_word_t _bmsr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +static jit_word_t _bmsi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bmcr(br, r0, r1) _bmcr(_jit, br, r0, r1) +# define bmci(br, r0, im) _bmci(_jit, br, r0, im) +static jit_word_t _bmcr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +static jit_word_t _bmci(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define jmpr(r0) JALR(_ZERO_REGNO, r0, 0) +# define jmpi(im) _jmpi(_jit, im) +static void _jmpi(jit_state_t*,jit_word_t); +# define jmpi_p(im) _jmpi_p(_jit, im) +static jit_word_t _jmpi_p(jit_state_t*,jit_word_t); +# define callr(r0) JALR(_RA_REGNO, r0, 0) +# define calli(im) _calli(_jit, im) +static void _calli(jit_state_t*,jit_word_t); +# define calli_p(im) _calli_p(_jit, im) +static jit_word_t _calli_p(jit_state_t*,jit_word_t); +# define prolog(i0) _prolog(_jit,i0) +static void _prolog(jit_state_t*,jit_node_t*); +# define epilog(i0) _epilog(_jit,i0) +static void _epilog(jit_state_t*,jit_node_t*); +# define vastart(r0) _vastart(_jit, r0) +static void _vastart(jit_state_t*, jit_int32_t); +# define vaarg(r0, r1) _vaarg(_jit, r0, r1) +static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t); +#define patch_abs(instr,label) _patch_at(_jit,instr,label) +#define patch_at(instr,label) _patch_at(_jit,instr,label) +static void _patch_at(jit_state_t*,jit_word_t,jit_word_t); +#endif /* PROTO */ + +#if CODE +static void +_Rtype(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, + jit_int32_t fct, jit_int32_t rs1, jit_int32_t rs2, jit_int32_t fct2) +{ + instr_t i; + assert(!(op & ~0x7f)); + assert(!(rd & ~0x1f)); + assert(!(fct & ~0x07)); + assert(!(rs1 & ~0x1f)); + assert(!(rs2 & ~0x1f)); + assert(!(fct2 & ~0x7f)); + i.R.opcode = op; + i.R.rd = rd; + i.R.funct3 = fct; + i.R.rs1 = rs1; + i.R.rs2 = rs2; + i.R.funct7 = fct2; + ii(i.w); +} + +static void +_R4type(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, jit_int32_t fct, + jit_int32_t rs1, jit_int32_t rs2, jit_int32_t fct2, jit_int32_t rs3) +{ + instr_t i; + assert(!(op & ~0x7f)); + assert(!(rd & ~0x1f)); + assert(!(fct & ~0x07)); + assert(!(rs1 & ~0x1f)); + assert(!(rs2 & ~0x1f)); + assert(!(fct2 & ~0x03)); + assert(!(rs3 & ~0x1f)); + i.R4.opcode = op; + i.R4.rd = rd; + i.R4.funct3 = fct; + i.R4.rs1 = rs1; + i.R4.rs2 = rs2; + i.R4.funct2 = fct2; + i.R4.rs3 = rs3; + ii(i.w); +} + +static void +_Itype(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, + jit_int32_t fct, jit_int32_t rs1, jit_int32_t imm) +{ + instr_t i; + assert(!(op & ~0x7f)); + assert(!(rd & ~0x1f)); + assert(!(fct & ~0x07)); + assert(!(rs1 & ~0x1f)); + assert(simm12_p(imm)); + i.I.opcode = op; + i.I.rd = rd; + i.I.funct3 = fct; + i.I.rs1 = rs1; + i.I.imm11_0 = imm; + ii(i.w); +} + +# if __WORDSIZE == 64 +static void +_IStype(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, + jit_int32_t fct, jit_int32_t rs1, jit_int32_t sh, jit_int32_t imm) +{ + instr_t i; + assert(!(op & ~0x7f)); + assert(!(rd & ~0x1f)); + assert(!(fct & ~0x07)); + assert(!(rs1 & ~0x1f)); + assert(!(sh & ~0x3f)); + assert(simm6_p(imm)); + i.IS.opcode = op; + i.IS.rd = rd; + i.IS.funct3 = fct; + i.IS.rs1 = rs1; + i.IS.shamt = sh; + i.IS.imm6_0 = imm; + ii(i.w); +} +# endif + +static void +_Stype(jit_state_t *_jit, jit_int32_t op, jit_int32_t fct, + jit_int32_t rs1, jit_int32_t rs2, jit_int32_t imm) +{ + instr_t i; + assert(!(op & ~0x7f)); + assert(!(fct & ~0x07)); + assert(!(rs1 & ~0x1f)); + assert(!(rs2 & ~0x1f)); + assert(simm12_p(imm)); + i.S.opcode = op; + i.S.imm4_0 = imm & 0x1f; + i.S.funct3 = fct; + i.S.rs1 = rs1; + i.S.rs2 = rs2; + i.S.imm11_5 = (imm >> 5) & 0x7f; + ii(i.w); +} + +static void +_Btype(jit_state_t *_jit, jit_int32_t op, jit_int32_t fct, + jit_int32_t rs1, jit_int32_t rs2, jit_int32_t imm) +{ + instr_t i; + assert(!(op & ~0x7f)); + assert(!(fct & ~0x07)); + assert(!(rs1 & ~0x1f)); + assert(!(rs2 & ~0x1f)); + assert(!(imm & 1) && simm12_p(imm)); + i.B.opcode = op; + i.B.imm11 = (imm >> 11) & 0x1; + i.B.imm4_1 = (imm >> 1) & 0xf; + i.B.funct3 = fct; + i.B.rs1 = rs1; + i.B.rs2 = rs2; + i.B.imm10_5 = (imm >> 5) & 0x3f; + i.B.imm12 = (imm >> 12) & 0x1; + ii(i.w); +} + +static void +_Utype(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, jit_int32_t imm) +{ + instr_t i; + assert(!(op & ~0x7f)); + assert(!(rd & ~0x1f)); + assert(simm20_p(imm)); + i.U.opcode = op; + i.U.rd = rd; + i.U.imm12_31= imm; + ii(i.w); +} + +static void +_Jtype(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, jit_int32_t imm) +{ + instr_t i; + assert(!(op & ~0x7f)); + assert(!(rd & ~0x1f)); + assert(!(imm & 1) && imm <= 1048575 && imm >= -1048576); + i.J.opcode = op; + i.J.rd = rd; + i.J.imm19_12= (imm >> 12) & 0xff; + i.J.imm11 = (imm >> 11) & 0x1; + i.J.imm10_1 = (imm >> 1) & 0x3ff; + i.J.imm20 = (imm >> 20) & 0x1; + ii(i.w); +} + +static void +_nop(jit_state_t *_jit, jit_int32_t im) +{ + for (; im > 0; im -= 4) + NOP(); + assert(im == 0); +} + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (simm12_p(i0)) + ADDI(r0, r1, i0); + else { + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + addr(r0, r1, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + t0 = jit_get_reg(jit_class_gpr); + addr(rn(t0), r1, r2); + SLTU(rn(jit_carry), rn(t0), r1); + movr(r0, rn(t0)); + jit_unget_reg(t0); + } + else { + addr(r0, r1, r2); + SLTU(rn(jit_carry), r0, r1); + } +} + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + t0 = jit_get_reg(jit_class_gpr); + addi(rn(t0), r1, i0); + SLTU(rn(jit_carry), rn(t0), r1); + movr(r0, rn(t0)); + jit_unget_reg(t0); + } + else { + addi(r0, r1, i0); + SLTU(rn(jit_carry), r0, r1); + } +} + +static void +_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + assert(jit_carry != _NOREG); + t0 = jit_get_reg(jit_class_gpr); + movr(rn(t0), rn(jit_carry)); + addcr(r0, r1, r2); + addcr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + assert(jit_carry != _NOREG); + t0 = jit_get_reg(jit_class_gpr); + movr(rn(t0), rn(jit_carry)); + addci(r0, r1, i0); + addcr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (simm12_p(-i0)) + ADDI(r0, r1, -i0); + else { + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + subr(r0, r1, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + t0 = jit_get_reg(jit_class_gpr); + subr(rn(t0), r1, r2); + SLTU(rn(jit_carry), r1, rn(t0)); + movr(r0, rn(t0)); + jit_unget_reg(t0); + } + else { + subr(r0, r1, r2); + SLTU(rn(jit_carry), r1, r0); + } +} + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + t0 = jit_get_reg(jit_class_gpr); + subi(rn(t0), r1, i0); + SLTU(rn(jit_carry), r1, rn(t0)); + movr(r0, rn(t0)); + jit_unget_reg(t0); + } + else { + subi(r0, r1, i0); + SLTU(rn(jit_carry), r1, r0); + } +} + +static void +_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + assert(jit_carry != _NOREG); + t0 = jit_get_reg(jit_class_gpr); + movr(rn(t0), rn(jit_carry)); + subcr(r0, r1, r2); + subcr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + assert(jit_carry != _NOREG); + t0 = jit_get_reg(jit_class_gpr); + movr(rn(t0), rn(jit_carry)); + subci(r0, r1, i0); + subcr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + subi(r0, r1, i0); + negr(r0, r0); +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + mulr(r0, r1, rn(t0)); + jit_unget_reg(t0); +} + +static void +_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + divr(r0, r1, rn(t0)); + jit_unget_reg(t0); +} + +static void +_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + divr_u(r0, r1, rn(t0)); + jit_unget_reg(t0); +} + +static void +_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + remr(r0, r1, rn(t0)); + jit_unget_reg(t0); +} + +static void +_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + remr_u(r0, r1, rn(t0)); + jit_unget_reg(t0); +} + +static void +_qmulr(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t t0; + if (r0 == r2 || r0 == r3) { + t0 = jit_get_reg(jit_class_gpr); + mulr(rn(t0), r2, r3); + } + else + mulr(r0, r2, r3); + MULH(r1, r2, r3); + if (r0 == r2 || r0 == r3) { + movr(r0, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_qmuli(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + qmulr(r0, r1, r2, rn(t0)); + jit_unget_reg(t0); +} + +static void +_qmulr_u(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t t0; + if (r0 == r2 || r0 == r3) { + t0 = jit_get_reg(jit_class_gpr); + mulr(rn(t0), r2, r3); + } + else + mulr(r0, r2, r3); + MULHU(r1, r2, r3); + if (r0 == r2 || r0 == r3) { + movr(r0, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_qmuli_u(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + qmulr_u(r0, r1, r2, rn(t0)); + jit_unget_reg(t0); +} + +static void +_iqdivr(jit_state_t *_jit, jit_bool_t sign, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t sv0, rg0; + jit_int32_t sv1, rg1; + if (r0 == r2 || r0 == r3) { + sv0 = jit_get_reg(jit_class_gpr); + rg0 = rn(sv0); + } + else + rg0 = r0; + if (r1 == r2 || r1 == r3) { + sv1 = jit_get_reg(jit_class_gpr); + rg1 = rn(sv1); + } + else + rg1 = r1; + if (sign) + divr(rg0, r2, r3); + else + divr_u(rg0, r2, r3); + mulr(rg1, r3, rg0); + subr(rg1, r2, rg1); + if (rg0 != r0) { + movr(r0, rg0); + jit_unget_reg(sv0); + } + if (rg1 != r1) { + movr(r1, rg1); + jit_unget_reg(sv1); + } +} + +static void +_qdivi(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + qdivr(r0, r1, r2, rn(t0)); + jit_unget_reg(t0); +} + +static void +_qdivi_u(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + qdivr_u(r0, r1, r2, rn(t0)); + jit_unget_reg(t0); +} + +static void +_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0 == 0) + movr(r0, r1); + else { + assert(i0 > 0 && i0 < 64); + SLLI(r0, r1, i0); + } +} + +static void +_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0 == 0) + movr(r0, r1); + else { + assert(i0 > 0 && i0 < 64); + SRAI(r0, r1, i0); + } +} + +static void +_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0 == 0) + movr(r0, r1); + else { + assert(i0 > 0 && i0 < 64); + SRLI(r0, r1, i0); + } +} + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (simm12_p(i0)) + ANDI(r0, r1, i0); + else { + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + andr(r0, r1, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (simm12_p(i0)) + ORI(r0, r1, i0); + else { + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + orr(r0, r1, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (simm12_p(i0)) + XORI(r0, r1, i0); + else { + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + xorr(r0, r1, rn(t0)); + jit_unget_reg(t0); + } +} + +# define DEFLD(T,O) \ +static void \ +_ldi_##T(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) \ +{ \ + if (simm12_p(i0)) \ + L##O(r0, _ZERO_REGNO, i0); \ + else { \ + jit_int32_t t0; \ + t0 = jit_get_reg(jit_class_gpr); \ + movi(rn(t0), i0); \ + ldr_##T(r0, rn(t0)); \ + jit_unget_reg(t0); \ + } \ +} \ + \ +static void \ +_ldxr_##T(jit_state_t *_jit,jit_int32_t r0,jit_int32_t r1,jit_int32_t r2)\ +{ \ + jit_int32_t t0; \ + t0 = jit_get_reg(jit_class_gpr); \ + addr(rn(t0), r1, r2); \ + ldr_##T(r0, rn(t0)); \ + jit_unget_reg(t0); \ +} \ + \ +static void \ +_ldxi_##T(jit_state_t *_jit,jit_int32_t r0,jit_int32_t r1,jit_word_t i0)\ +{ \ + if (simm12_p(i0)) \ + L##O(r0, r1, i0); \ + else { \ + jit_int32_t t0; \ + t0 = jit_get_reg(jit_class_gpr); \ + addi(rn(t0), r1, i0); \ + ldr_##T(r0, rn(t0)); \ + jit_unget_reg(t0); \ + } \ +} + +DEFLD(c,B) +DEFLD(uc,BU) +DEFLD(s,H) +DEFLD(us,HU) +DEFLD(i,W) +DEFLD(ui,WU) +DEFLD(l,D) + +# define DEFST(T, O) \ +static void \ +_sti_##T(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) \ +{ \ + if (simm12_p(i0)) \ + S##O(_ZERO_REGNO, r0, i0); \ + else { \ + jit_int32_t t0; \ + t0 = jit_get_reg(jit_class_gpr); \ + movi(rn(t0), i0); \ + str_##T(rn(t0), r0); \ + jit_unget_reg(t0); \ + } \ +} \ + \ +static void \ +_stxr_##T(jit_state_t *_jit,jit_int32_t r0,jit_int32_t r1,jit_int32_t r2)\ +{ \ + jit_int32_t t0; \ + t0 = jit_get_reg(jit_class_gpr); \ + addr(rn(t0), r0, r1); \ + str_##T(rn(t0), r2); \ + jit_unget_reg(t0); \ +} \ + \ +static void \ +_stxi_##T(jit_state_t *_jit,jit_word_t i0,jit_int32_t r0,jit_int32_t r1)\ +{ \ + if (simm12_p(i0)) \ + S##O(r0, r1, i0); \ + else { \ + jit_int32_t t0; \ + t0 = jit_get_reg(jit_class_gpr); \ + addi(rn(t0), r0, i0); \ + str_##T(rn(t0), r1); \ + jit_unget_reg(t0); \ + } \ +} + +DEFST(c, B) +DEFST(s, H) +DEFST(i, W) +DEFST(l, D) + +static void +_htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + rshi(rn(t0), r1, 8); + andi(r0, r1, 0xff); + andi(rn(t0), rn(t0), 0xff); + lshi(r0, r0, 8); + orr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr); + t2 = jit_get_reg(jit_class_gpr); + rshi(rn(t0), r1, 24); + rshi(rn(t1), r1, 16); + rshi(rn(t2), r1, 8); + andi(rn(t0), rn(t0), 0xff); + andi(rn(t1), rn(t1), 0xff); + andi(rn(t2), rn(t2), 0xff); + andi(r0, r1, 0xff); + lshi(r0, r0, 24); + lshi(rn(t1), rn(t1), 8); + orr(r0, r0, rn(t0)); + lshi(rn(t2), rn(t2), 16); + orr(r0, r0, rn(t1)); + orr(r0, r0, rn(t2)); + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); +} + +static void +_htonr_ul(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + rshi_u(rn(t0), r1, 32); + htonr_ui(r0, r1); + htonr_ui(rn(t0), rn(t0)); + lshi(r0, r0, 32); + orr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_extr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 56); + rshi(r0, r0, 56); +} + +static void +_extr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 48); + rshi(r0, r0, 48); +} + +static void +_extr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 48); + rshi_u(r0, r0, 48); +} + +static void +_extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 32); + rshi_u(r0, r0, 32); +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + if (simm32_p(i0)) { + jit_int32_t lo = (jit_int32_t)i0 << 20 >> 20; + jit_int32_t hi = i0 - lo; + if (hi) { + LUI(r0, hi >> 12); + if (lo) + ADDIW(r0, r0, lo); + } + else + ADDIW(r0, _ZERO_REGNO, lo); + } + else { + jit_int32_t lo = i0 << 32 >> 32; + jit_word_t hi = i0 - lo; + jit_int32_t t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), (jit_int32_t)(hi >> 32)); + movi(r0, lo); + lshi(rn(t0), rn(t0), 32); + addr(r0, r0, rn(t0)); + jit_unget_reg(t0); + } +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t ww = i0 << 32 >> 32; + jit_int32_t lo = ww << 20 >> 20; + jit_int32_t hi = ww - lo; + w = _jit->pc.w; + t0 = jit_get_reg(jit_class_gpr); + LUI(r0, hi >> 12); + ADDIW(r0, r0, lo); + ww = i0 >> 32; + lo = ww << 20 >> 20; + hi = ww - lo; + LUI(rn(t0), hi >> 12); + ADDIW(rn(t0), rn(t0), lo); + SLLI(rn(t0), rn(t0), 32); + ADD(r0, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static void +_lti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (simm12_p(i0)) + SLTI(r0, r1, i0); + else { + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(r0, i0); + ltr(r0, r1, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_lti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (simm12_p(i0)) + SLTIU(r0, r1, i0); + else { + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(r0, i0); + ltr_u(r0, r1, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_ler(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SLT(r0, r2, r1); + XORI(r0, r0, 1); +} + +static void +_lei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + if (i0 == 0) { + SLT(r0, _ZERO_REGNO, r1); + XORI(r0, r0, 1); + } + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + ler(r0, r1, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_ler_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SLTU(r0, r2, r1); + XORI(r0, r0, 1); +} + +static void +_lei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + if (i0 == 0) { + SLTU(r0, _ZERO_REGNO, r1); + XORI(r0, r0, 1); + } + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + ler_u(r0, r1, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_eqr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + subr(r0, r1, r2); + SLTU(r0, _ZERO_REGNO, r0); + XORI(r0, r0, 1); +} + +static void +_eqi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0) { + subi(r0, r1, i0); + SLTU(r0, _ZERO_REGNO, r0); + } + else + SLTU(r0, _ZERO_REGNO, r1); + XORI(r0, r0, 1); +} + +static void +_ger(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SLT(r0, r1, r2); + XORI(r0, r0, 1); +} + +static void +_gei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + ger(r0, r1, rn(t0)); + jit_unget_reg(t0); +} + +static void +_ger_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SLTU(r0, r1, r2); + XORI(r0, r0, 1); +} + +static void +_gei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + ger_u(r0, r1, rn(t0)); + jit_unget_reg(t0); +} + +static void +_gti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(r0, i0); + ltr(r0, rn(t0), r1); + jit_unget_reg(t0); +} + +static void +_gti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + movi(r0, i0); + ltr_u(r0, rn(t0), r1); + jit_unget_reg(t0); +} + +static void +_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + subr(r0, r1, r2); + SLTU(r0, _ZERO_REGNO, r0); +} + +static void +_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0) { + subi(r0, r1, i0); + SLTU(r0, _ZERO_REGNO, r0); + } + else + SLTU(r0, _ZERO_REGNO, r1); +} + +static jit_word_t +_bltr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BLT(r0, r1, br - w); + return (w); +} + +static jit_word_t +_blti(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_reg_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bltr(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bltr_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BLTU(r0, r1, br - w); + return (w); +} + +static jit_word_t +_blti_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_reg_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bltr_u(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bler(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BGE(r1, r0, br - w); + return (w); +} + +static jit_word_t +_blei(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_reg_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bler(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bler_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BGEU(r1, r0, br - w); + return (w); +} + +static jit_word_t +_blei_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_reg_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bler_u(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_beqr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BEQ(r1, r0, br - w); + return (w); +} + +static jit_word_t +_beqi(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_reg_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = beqr(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bger(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BGE(r0, r1, br - w); + return (w); +} + +static jit_word_t +_bgei(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_reg_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bger(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bger_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BGEU(r0, r1, br - w); + return (w); +} + +static jit_word_t +_bgei_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_reg_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bger_u(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bgtr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BLT(r1, r0, br - w); + return (w); +} + +static jit_word_t +_bgti(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_reg_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bgtr(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bgtr_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BLTU(r1, r0, br - w); + return (w); +} + +static jit_word_t +_bgti_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_reg_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bgtr_u(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bner(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BNE(r1, r0, br - w); + return (w); +} + +static jit_word_t +_bnei(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_reg_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bner(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_boaddr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, jal; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + /* t0 = r1 < 0; */ + SLT(rn(t0), r1, _ZERO_REGNO); + /* t1 = r0 */ + movr(rn(t1), r0); + /* r0 = r0 + r1 */ + addr(r0, r0, r1); + /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */ + w = _jit->pc.w; + BNE(rn(t0), _ZERO_REGNO, 0); + /* r1 >= 0 */ + SLT(rn(t1), r0, rn(t1)); + jal = _jit->pc.w; + JAL(_ZERO_REGNO, 0); + /* r1 < 0 */ + patch_at(w, _jit->pc.w); + SLT(rn(t1), rn(t1), r0); + /**/ + patch_at(jal, _jit->pc.w); + w = _jit->pc.w; + BNE(rn(t1), _ZERO_REGNO, br - w); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_boaddi(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = boaddr(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_boaddr_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addr(rn(t0), r0, r1); + SLTU(rn(t1), rn(t0), r0); + movr(r0, rn(t0)); + w = _jit->pc.w; + BNE(_ZERO_REGNO, rn(t1), br - w); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_boaddi_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = boaddr_u(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxaddr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, jal; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + /* t0 = r1 < 0; */ + SLT(rn(t0), r1, _ZERO_REGNO); + /* t1 = r0 */ + movr(rn(t1), r0); + /* r0 = r0 + r1 */ + addr(r0, r0, r1); + /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */ + w = _jit->pc.w; + BNE(rn(t0), _ZERO_REGNO, 0); + /* r1 >= 0 */ + SLT(rn(t1), r0, rn(t1)); + jal = _jit->pc.w; + JAL(_ZERO_REGNO, 0); + /* r1 < 0 */ + patch_at(w, _jit->pc.w); + SLT(rn(t1), rn(t1), r0); + /**/ + patch_at(jal, _jit->pc.w); + w = _jit->pc.w; + BEQ(rn(t1), _ZERO_REGNO, br - w); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxaddi(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bxaddr(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxaddr_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addr(rn(t0), r0, r1); + SLTU(rn(t1), rn(t0), r0); + movr(r0, rn(t0)); + w = _jit->pc.w; + BEQ(_ZERO_REGNO, rn(t1), br - w); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxaddi_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bxaddr_u(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bosubr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, jal; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + /* t0 = 0 < r1; */ + SLT(rn(t0), _ZERO_REGNO, r1); + /* t1 = r0 */ + movr(rn(t1), r0); + /* r0 = r0 - r1 */ + subr(r0, r0, r1); + /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */ + w = _jit->pc.w; + BNE(rn(t0), _ZERO_REGNO, 0); + /* r1 >= 0 */ + SLT(rn(t1), r0, rn(t1)); + jal = _jit->pc.w; + JAL(_ZERO_REGNO, 0); + /* r1 < 0 */ + patch_at(w, _jit->pc.w); + SLT(rn(t1), rn(t1), r0); + /**/ + patch_at(jal, _jit->pc.w); + w = _jit->pc.w; + BNE(rn(t1), _ZERO_REGNO, br - w); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bosubi(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bosubr(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bosubr_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + subr(rn(t0), r0, r1); + SLTU(rn(t1), r0, rn(t0)); + movr(r0, rn(t0)); + w = _jit->pc.w; + BNE(_ZERO_REGNO, rn(t1), br - w); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bosubi_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bosubr_u(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxsubr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, jal; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + /* t0 = r1 < 0; */ + SLT(rn(t0), _ZERO_REGNO, r1); + /* t1 = r0 */ + movr(rn(t1), r0); + /* r0 = r0 - r1 */ + subr(r0, r0, r1); + /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */ + w = _jit->pc.w; + BNE(rn(t0), _ZERO_REGNO, 0); + /* r1 >= 0 */ + SLT(rn(t1), r0, rn(t1)); + jal = _jit->pc.w; + JAL(_ZERO_REGNO, 0); + /* r1 < 0 */ + patch_at(w, _jit->pc.w); + SLT(rn(t1), rn(t1), r0); + /**/ + patch_at(jal, _jit->pc.w); + w = _jit->pc.w; + BEQ(rn(t1), _ZERO_REGNO, br - w); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxsubi(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bxsubr(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxsubr_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + subr(rn(t0), r0, r1); + SLTU(rn(t1), r0, rn(t0)); + movr(r0, rn(t0)); + w = _jit->pc.w; + BEQ(_ZERO_REGNO, rn(t1), br - w); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxsubi_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bxsubr_u(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bmsr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + AND(rn(t0), r0, r1); + w = _jit->pc.w; + BNE(_ZERO_REGNO, rn(t0), br - w); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bmsi(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bmsr(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bmcr(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + AND(rn(t0), r0, r1); + w = _jit->pc.w; + BEQ(_ZERO_REGNO, rn(t0), br - w); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bmci(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bmcr(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static void +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_int32_t t0; + jit_word_t dsp; + dsp = i0 - _jit->pc.w; + if (simm20_p(dsp)) + JAL(_ZERO_REGNO, dsp); + else { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + jmpr(rn(t0)); + jit_unget_reg(t0); + } +} + +static jit_word_t +_jmpi_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + w = movi_p(rn(t0), i0); + jmpr(rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static void +_calli(jit_state_t *_jit, jit_word_t i0) +{ + jit_int32_t t0; + jit_word_t dsp; + dsp = i0 - _jit->pc.w; + if (simm20_p(dsp)) + JAL(_RA_REGNO, dsp); + else { + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + callr(rn(t0)); + jit_unget_reg(t0); + } +} + +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + w = movi_p(rn(t0), i0); + callr(rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static void +_prolog(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t reg; + if (_jitc->function->define_frame || _jitc->function->assume_frame) { + jit_int32_t frame = -_jitc->function->frame; + assert(_jitc->function->self.aoff >= frame); + if (_jitc->function->assume_frame) + return; + _jitc->function->self.aoff = frame; + } + if (_jitc->function->allocar) + _jitc->function->self.aoff &= -16; + _jitc->function->stack = ((_jitc->function->self.alen - + /* align stack at 16 bytes */ + _jitc->function->self.aoff) + 15) & -16; + subi(_SP_REGNO, _SP_REGNO, stack_framesize); + stxi(0, _SP_REGNO, _RA_REGNO); + stxi(8, _SP_REGNO, _FP_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _S1)) + stxi(16, _SP_REGNO, 9); + if (jit_regset_tstbit(&_jitc->function->regset, _S2)) + stxi(24, _SP_REGNO, 18); + if (jit_regset_tstbit(&_jitc->function->regset, _S3)) + stxi(32, _SP_REGNO, 19); + if (jit_regset_tstbit(&_jitc->function->regset, _S4)) + stxi(40, _SP_REGNO, 20); + if (jit_regset_tstbit(&_jitc->function->regset, _S5)) + stxi(48, _SP_REGNO, 21); + if (jit_regset_tstbit(&_jitc->function->regset, _S6)) + stxi(56, _SP_REGNO, 22); + if (jit_regset_tstbit(&_jitc->function->regset, _S7)) + stxi(64, _SP_REGNO, 23); + if (jit_regset_tstbit(&_jitc->function->regset, _S8)) + stxi(72, _SP_REGNO, 24); + if (jit_regset_tstbit(&_jitc->function->regset, _S9)) + stxi(80, _SP_REGNO, 25); + if (jit_regset_tstbit(&_jitc->function->regset, _S10)) + stxi(88, _SP_REGNO, 26); + if (jit_regset_tstbit(&_jitc->function->regset, _S11)) + stxi(96, _SP_REGNO, 27); + if (jit_regset_tstbit(&_jitc->function->regset, _FS0)) + stxi_d(104, _SP_REGNO, 8); + if (jit_regset_tstbit(&_jitc->function->regset, _FS1)) + stxi_d(112, _SP_REGNO, 9); + if (jit_regset_tstbit(&_jitc->function->regset, _FS2)) + stxi_d(120, _SP_REGNO, 18); + if (jit_regset_tstbit(&_jitc->function->regset, _FS3)) + stxi_d(128, _SP_REGNO, 19); + if (jit_regset_tstbit(&_jitc->function->regset, _FS4)) + stxi_d(136, _SP_REGNO, 20); + if (jit_regset_tstbit(&_jitc->function->regset, _FS5)) + stxi_d(144, _SP_REGNO, 21); + if (jit_regset_tstbit(&_jitc->function->regset, _FS6)) + stxi_d(152, _SP_REGNO, 22); + if (jit_regset_tstbit(&_jitc->function->regset, _FS7)) + stxi_d(160, _SP_REGNO, 23); + if (jit_regset_tstbit(&_jitc->function->regset, _FS8)) + stxi_d(168, _SP_REGNO, 24); + if (jit_regset_tstbit(&_jitc->function->regset, _FS9)) + stxi_d(176, _SP_REGNO, 25); + if (jit_regset_tstbit(&_jitc->function->regset, _FS10)) + stxi_d(184, _SP_REGNO, 26); + if (jit_regset_tstbit(&_jitc->function->regset, _FS11)) + stxi_d(192, _SP_REGNO, 27); + movr(_FP_REGNO, _SP_REGNO); + if (_jitc->function->stack) + subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack); + if (_jitc->function->allocar) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), _jitc->function->self.aoff); + stxi_i(_jitc->function->aoffoff, _FP_REGNO, rn(reg)); + jit_unget_reg(reg); + } + if (_jitc->function->self.call & jit_call_varargs) { + for (reg = _jitc->function->vagp; jit_arg_reg_p(reg); ++reg) + stxi(stack_framesize - ((8 - reg) * 8), + _FP_REGNO, rn(JIT_RA0 - reg)); + } +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *node) +{ + if (_jitc->function->assume_frame) + return; + movr(_SP_REGNO, _FP_REGNO); + ldxi(_RA_REGNO, _SP_REGNO, 0); + ldxi(_FP_REGNO, _SP_REGNO, 8); + if (jit_regset_tstbit(&_jitc->function->regset, _S1)) + ldxi(9, _SP_REGNO, 16); + if (jit_regset_tstbit(&_jitc->function->regset, _S2)) + ldxi(18, _SP_REGNO, 24); + if (jit_regset_tstbit(&_jitc->function->regset, _S3)) + ldxi(19, _SP_REGNO, 32); + if (jit_regset_tstbit(&_jitc->function->regset, _S4)) + ldxi(20, _SP_REGNO, 40); + if (jit_regset_tstbit(&_jitc->function->regset, _S5)) + ldxi(21, _SP_REGNO, 48); + if (jit_regset_tstbit(&_jitc->function->regset, _S6)) + ldxi(22, _SP_REGNO, 56); + if (jit_regset_tstbit(&_jitc->function->regset, _S7)) + ldxi(23, _SP_REGNO, 64); + if (jit_regset_tstbit(&_jitc->function->regset, _S8)) + ldxi(24, _SP_REGNO, 72); + if (jit_regset_tstbit(&_jitc->function->regset, _S9)) + ldxi(25, _SP_REGNO, 80); + if (jit_regset_tstbit(&_jitc->function->regset, _S10)) + ldxi(26, _SP_REGNO, 88); + if (jit_regset_tstbit(&_jitc->function->regset, _S11)) + ldxi(27, _SP_REGNO, 96); + if (jit_regset_tstbit(&_jitc->function->regset, _FS0)) + ldxi_d(8, _SP_REGNO, 104); + if (jit_regset_tstbit(&_jitc->function->regset, _FS1)) + ldxi_d(9, _SP_REGNO, 112); + if (jit_regset_tstbit(&_jitc->function->regset, _FS2)) + ldxi_d(18, _SP_REGNO, 120); + if (jit_regset_tstbit(&_jitc->function->regset, _FS3)) + ldxi_d(19, _SP_REGNO, 128); + if (jit_regset_tstbit(&_jitc->function->regset, _FS4)) + ldxi_d(20, _SP_REGNO, 136); + if (jit_regset_tstbit(&_jitc->function->regset, _FS5)) + ldxi_d(21, _SP_REGNO, 144); + if (jit_regset_tstbit(&_jitc->function->regset, _FS6)) + ldxi_d(22, _SP_REGNO, 152); + if (jit_regset_tstbit(&_jitc->function->regset, _FS7)) + ldxi_d(23, _SP_REGNO, 160); + if (jit_regset_tstbit(&_jitc->function->regset, _FS8)) + ldxi_d(24, _SP_REGNO, 168); + if (jit_regset_tstbit(&_jitc->function->regset, _FS9)) + ldxi_d(25, _SP_REGNO, 176); + if (jit_regset_tstbit(&_jitc->function->regset, _FS10)) + ldxi_d(26, _SP_REGNO, 184); + if (jit_regset_tstbit(&_jitc->function->regset, _FS11)) + ldxi_d(27, _SP_REGNO, 192); + addi(_SP_REGNO, _SP_REGNO, stack_framesize); + RET(); +} + +static void +_vastart(jit_state_t *_jit, jit_int32_t r0) +{ + assert(_jitc->function->self.call & jit_call_varargs); + /* Initialize va_list to the first stack argument. */ + if (jit_arg_reg_p(_jitc->function->vagp)) + addi(r0, _FP_REGNO, stack_framesize - ((8 - _jitc->function->vagp) * 8)); + else + addi(r0, _FP_REGNO, _jitc->function->self.size); +} + +static void +_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(_jitc->function->self.call & jit_call_varargs); + /* Load argument. */ + ldr(r0, r1); + /* Update va_list. */ + addi(r1, r1, sizeof(jit_word_t)); +} + +static void +_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label) +{ + instr_t i; + union { + jit_int32_t *i; + jit_word_t w; + } u; + u.w = instr; + i.w = u.i[0]; + /* movi_p? */ + if (i.U.opcode == 55) { /* LUI */ + jit_int32_t ww = label << 32 >> 32; + jit_int32_t lo = ww << 20 >> 20; + jit_int32_t hi = ww - lo; + i.U.imm12_31 = hi >> 12; + u.i[0] = i.w; + i.w = u.i[1]; + if (i.I.opcode == 27 && i.I.funct3 == 0) { /* ADDIW */ + i.I.imm11_0 = lo & 0xfff; + u.i[1] = i.w; + i.w = u.i[2]; + if (i.U.opcode == 55) { /* LUI */ + ww = label >> 32; + lo = ww << 20 >> 20; + hi = ww - lo; + i.U.imm12_31 = hi >> 12; + u.i[2] = i.w; + i.w = u.i[3]; + if (i.I.opcode == 27 && i.I.funct3 == 0) { /* ADDIW */ + i.I.imm11_0 = lo & 0xfff; + u.i[3] = i.w; + i.w = u.i[4]; + assert(i.IS.opcode == 19); /* SLLI */ + assert(i.IS.shamt == 32); + i.w = u.i[5]; + assert(i.R.opcode == 51); /* ADD */ + } + else + abort(); + } + else + abort(); + } + else + abort(); + } + /* b{lt,le,eq,ge,gt,ne}{,_u}? */ + else if (i.B.opcode == 99) { /* B{EQ,NE,LT,GE,LTU,GEU} */ + jit_word_t jmp = label - instr; + assert(simm12_p(jmp)); + i.B.imm11 = (jmp >> 11) & 0x1; + i.B.imm4_1 = (jmp >> 1) & 0xf; + i.B.imm10_5 = (jmp >> 5) & 0x3f; + i.B.imm12 = (jmp >> 12) & 0x1; + u.i[0] = i.w; + } + else if (i.J.opcode == 111) { /* JAL */ + jit_word_t jmp = label - instr; + i.J.imm19_12 = (jmp >> 12) & 0xff; + i.J.imm11 = (jmp >> 11) & 0x1; + i.J.imm10_1 = (jmp >> 1) & 0x3ff; + i.J.imm20 = (jmp >> 20) & 0x1; + u.i[0] = i.w; + } + else + abort(); +} +#endif /* CODE */ diff --git a/deps/lightning/lib/jit_riscv-fpu.c b/deps/lightning/lib/jit_riscv-fpu.c new file mode 100644 index 0000000..367975e --- /dev/null +++ b/deps/lightning/lib/jit_riscv-fpu.c @@ -0,0 +1,1271 @@ +/* + * Copyright (C) 2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +/* + * RV32F Standard Extension + */ +# define FLW(rd, rs1, im) Itype(7, rd, 2, rs1, im) +# define FSW(rs1, rs2, imm) Stype(39, 2, rs1, rs2, imm) +# define FMADD_S(rd, rs1, rs2, rs3) R4type(67, rd, 0, rs1, rs2, 0, rs3) +# define FMSUB_S(rd, rs1, rs2, rs3) R4type(71, rd, 0, rs1, rs2, 0, rs3) +# define FNMSUB_S(rd, rs1, rs2, rs3) R4type(75, rd, 0, rs1, rs2, 0, rs3) +# define FNMADD_S(rd, rs1, rs2, rs3) R4type(79, rd, 0, rs1, rs2, 0, rs3) +# define FADD_S(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 0) +# define FSUB_S(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 4) +# define FMUL_S(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 8) +# define FDIV_S(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 12) +# define FSQRT_S(rd, rs1) Rtype(83, rd, 0, rs1, 0, 44) +# define FSGNJ_S(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 16) +# define FSGNJN_S(rd, rs1, rs2) Rtype(83, rd, 1, rs1, rs2, 16) +# define FSGNJX_S(rd, rs1, rs2) Rtype(83, rd, 2, rs1, rs2, 16) +# define FMIN_S(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 20) +# define FMAX_S(rd, rs1, rs2) Rtype(83, rd, 1, rs1, rs2, 20) +# define FCVT_W_S(rd, rs1) Rtype(83, rd, 0, rs1, 0, 96) +# define FCVT_WU_S(rd, rs1) Rtype(83, rd, 1, rs1, 1, 96) +# define FMV_X_W(rd, rs1) Rtype(83, rd, 0, rs1, 0, 112) +# define FEQ_S(rd, rs1, rs2) Rtype(83, rd, 2, rs1, rs2, 80) +# define FLT_S(rd, rs1, rs2) Rtype(83, rd, 1, rs1, rs2, 80) +# define FLE_S(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 80) +# define FCLASS_S(rd, rs1) Rtype(83, rd, 1, rs1, 0, 112) +# define FCVT_S_W(rd, rs1) Rtype(83, rd, 0, rs1, 0, 104) +# define FCVT_S_WU(rd, rs1) Rtype(83, rd, 0, rs1, 1, 104) +# define FMV_W_X(rd, rs1) Rtype(83, rd, 0, rs1, 0, 120) +/* + * RV64F Standard Extension (in addition to RV32F) + */ +# define FCVT_L_S(rd, rs1) Rtype(83, rd, 0, rs1, 2, 96) +# define FCVT_LU_S(rd, rs1) Rtype(83, rd, 0, rs1, 3, 96) +# define FCVT_S_L(rd, rs1) Rtype(83, rd, 0, rs1, 2, 104) +# define FCVT_S_LU(rd, rs1) Rtype(83, rd, 0, rs1, 3, 104) +/* + * RV32D Standard Extension + */ +# define FLD(rd, rs1, im) Itype(7, rd, 3, rs1, im) +# define FSD(rs1, rs2, imm) Stype(39, 3, rs1, rs2, imm) +# define FMADD_D(rd, rs1, rs2, rs3) R4type(67, rd, 0, rs1, rs2, 1, rs3) +# define FMSUB_D(rd, rs1, rs2, rs3) R4type(71, rd, 0, rs1, rs2, 1, rs3) +# define FNMSUB_D(rd, rs1, rs2, rs3) R4type(75, rd, 0, rs1, rs2, 1, rs3) +# define FNMADD_D(rd, rs1, rs2, rs3) R4type(79, rd, 0, rs1, rs2, 1, rs3) +# define FADD_D(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 1) +# define FSUB_D(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 5) +# define FMUL_D(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 9) +# define FDIV_D(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 13) +# define FSQRT_D(rd, rs1) Rtype(83, rd, 0, rs1, 0, 45) +# define FSGNJ_D(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 17) +# define FSGNJN_D(rd, rs1, rs2) Rtype(83, rd, 1, rs1, rs2, 17) +# define FSGNJX_D(rd, rs1, rs2) Rtype(83, rd, 2, rs1, rs2, 17) +# define FMIN_D(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 21) +# define FMAX_D(rd, rs1, rs2) Rtype(83, rd, 1, rs1, rs2, 21) +# define FCVT_S_D(rd, rs1) Rtype(83, rd, 0, rs1, 1, 32) +# define FCVT_D_S(rd, rs1) Rtype(83, rd, 0, rs1, 0, 33) +# define FEQ_D(rd, rs1, rs2) Rtype(83, rd, 2, rs1, rs2, 81) +# define FLT_D(rd, rs1, rs2) Rtype(83, rd, 1, rs1, rs2, 81) +# define FLE_D(rd, rs1, rs2) Rtype(83, rd, 0, rs1, rs2, 81) +# define FCLASS_D(rd, rs1) Rtype(83, rd, 1, rs1, 0, 113) +# define FCVT_W_D(rd, rs1) Rtype(83, rd, 0, rs1, 0, 97) +# define FCVT_WU_D(rd, rs1) Rtype(83, rd, 0, rs1, 1, 97) +# define FCVT_D_W(rd, rs1) Rtype(83, rd, 0, rs1, 0, 105) +# define FCVT_D_WU(rd, rs1) Rtype(83, rd, 0, rs1, 1, 105) +/* + * RV64D Standard Extension (in addition to RV32D) + */ +# define FCVT_L_D(rd, rs1) Rtype(83, rd, 0, rs1, 2, 97) +# define FCVT_LU_D(rd, rs1) Rtype(83, rd, 0, rs1, 3, 97) +# define FMV_X_D(rd, rs1) Rtype(83, rd, 0, rs1, 0, 113) +# define FCVT_D_L(rd, rs1) Rtype(83, rd, 0, rs1, 2, 105) +# define FCVT_D_LU(rd, rs1) Rtype(83, rd, 0, rs1, 3, 105) +# define FMV_D_X(rd, rs1) Rtype(83, rd, 0, rs1, 0, 121) +/* + * Pseudo instructions + */ +# define FMV_S(r0, r1) FSGNJ_S(r0, r1, r1) +# define FABS_S(r0, r1) FSGNJX_S(r0, r1, r1) +# define FNEG_S(r0, r1) FSGNJN_S(r0, r1, r1) +# define FMV_D(r0, r1) FSGNJ_D(r0, r1, r1) +# define FABS_D(r0, r1) FSGNJX_D(r0, r1, r1) +# define FNEG_D(r0, r1) FSGNJN_D(r0, r1, r1) + +/* + * Lightning instructions + */ +# define truncr_f_i(r0, r1) FCVT_W_S(r0, r1) +# define truncr_d_i(r0, r1) FCVT_W_D(r0, r1) +# define truncr_f_l(r0, r1) FCVT_L_S(r0, r1) +# define truncr_d_l(r0, r1) FCVT_L_D(r0, r1) +# define addr_f(r0, r1, r2) FADD_S(r0, r1, r2) +# define addi_f(r0, r1, im) _addi_f(_jit, r0, r1, im) +static void _addi_f(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float32_t); +# define subr_f(r0, r1, r2) FSUB_S(r0, r1, r2) +# define subi_f(r0, r1, im) _subi_f(_jit, r0, r1, im) +static void _subi_f(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float32_t); +# define rsbr_f(r0, r1, r2) FSUB_S(r0, r2, r1) +# define rsbi_f(r0, r1, im) _rsbi_f(_jit, r0, r1, im) +static void _rsbi_f(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float32_t); +# define mulr_f(r0, r1, r2) FMUL_S(r0, r1, r2) +# define muli_f(r0, r1, im) _muli_f(_jit, r0, r1, im) +static void _muli_f(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float32_t); +# define divr_f(r0, r1, r2) FDIV_S(r0, r1, r2) +# define divi_f(r0, r1, im) _divi_f(_jit, r0, r1, im) +static void _divi_f(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float32_t); +# define absr_f(r0, r1) FABS_S(r0, r1) +# define negr_f(r0, r1) FNEG_S(r0, r1) +# define sqrtr_f(r0, r1) FSQRT_S(r0, r1) +# define extr_f(r0, r1) FCVT_S_L(r0, r1) +# define ldr_f(r0, r1) FLW(r0, r1, 0) +# define ldi_f(r0, im) _ldi_f(_jit, r0, im) +static void _ldi_f(jit_state_t*, jit_int32_t, jit_word_t); +# define ldxr_f(r0, r1, r2) _ldxr_f(_jit, r0, r1, r2) +static void _ldxr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ldxi_f(r0, r1, i0) _ldxi_f(_jit, r0, r1, i0) +static void _ldxi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define str_f(r0, r1) FSW(r0, r1, 0) +# define sti_f(im, r0) _sti_f(_jit, im, r0) +static void _sti_f(jit_state_t*, jit_word_t, jit_int32_t); +# define stxr_f(r0, r1, r2) _stxr_f(_jit, r0, r1, r2) +static void _stxr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define stxi_f(im, r0, r1) _stxi_f(_jit, im, r0, r1) +static void _stxi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define movr_f(r0, r1) FMV_S(r0, r1) +# define movi_f(r0, im) _movi_f(_jit, r0, im) +static void _movi_f(jit_state_t*, jit_int32_t, jit_float32_t); +# define movr_f_w(r0, r1) FMV_X_W(r0, r1) +# define movi_f_w(r0, im) _movi_f_w(_jit, r0, im) +static void _movi_f_w(jit_state_t*, jit_int32_t, jit_float32_t); +# define movr_w_f(r0, r1) FMV_W_X(r0, r1) +# define extr_d_f(r0, r1) FCVT_S_D(r0, r1) +# define ltr_f(r0, r1, r2) FLT_S(r0, r1, r2) +# define lti_f(r0, r1, im) _lti_f(_jit, r0, r1, im) +static void _lti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define ler_f(r0, r1, r2) FLE_S(r0, r1, r2) +# define lei_f(r0, r1, im) _lei_f(_jit, r0, r1, im) +static void _lei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define eqr_f(r0, r1, r2) FEQ_S(r0, r1, r2) +# define eqi_f(r0, r1, im) _eqi_f(_jit, r0, r1, im) +static void _eqi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define ger_f(r0, r1, r2) FLE_S(r0, r2, r1) +# define gei_f(r0, r1, im) _gei_f(_jit, r0, r1, im) +static void _gei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define gtr_f(r0, r1, r2) FLT_S(r0, r2, r1) +# define gti_f(r0, r1, im) _gti_f(_jit, r0, r1, im) +static void _gti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define ner_f(r0, r1, r2) _ner_f(_jit, r0, r1, r2) +static void _ner_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define nei_f(r0, r1, im) _nei_f(_jit, r0, r1, im) +static void _nei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define unltr_f(r0, r1, r2) _unltr_f(_jit, r0, r1, r2) +static void _unltr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define unlti_f(r0, r1, im) _unlti_f(_jit, r0, r1, im) +static void _unlti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define unler_f(r0, r1, r2) _unler_f(_jit, r0, r1, r2) +static void _unler_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define unlei_f(r0, r1, im) _unlei_f(_jit, r0, r1, im) +static void _unlei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define uneqr_f(r0, r1, r2) _uneqr_f(_jit, r0, r1, r2) +static void _uneqr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define uneqi_f(r0, r1, im) _uneqi_f(_jit, r0, r1, im) +static void _uneqi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define unger_f(r0, r1, r2) _unger_f(_jit, r0, r1, r2) +static void _unger_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ungei_f(r0, r1, im) _ungei_f(_jit, r0, r1, im) +static void _ungei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define ungtr_f(r0, r1, r2) _ungtr_f(_jit, r0, r1, r2) +static void _ungtr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ungti_f(r0, r1, im) _ungti_f(_jit, r0, r1, im) +static void _ungti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define ltgtr_f(r0, r1, r2) _ltgtr_f(_jit, r0, r1, r2) +static void _ltgtr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ltgti_f(r0, r1, im) _ltgti_f(_jit, r0, r1, im) +static void _ltgti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define ordr_f(r0, r1, r2) _ordr_f(_jit, r0, r1, r2) +static void _ordr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ordi_f(r0, r1, im) _ordi_f(_jit, r0, r1, im) +static void _ordi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define unordr_f(r0, r1, r2) _unordr_f(_jit, r0, r1, r2) +static void _unordr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define unordi_f(r0, r1, im) _unordi_f(_jit, r0, r1, im) +static void _unordi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define bltr_f(br, r0, r1) _bltr_f(_jit,br,r0,r1) +static jit_word_t _bltr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blti_f(br, r0, im) _blti_f(_jit,br,r0,im) +static jit_word_t _blti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define bler_f(br, r0, r1) _bler_f(_jit,br,r0,r1) +static jit_word_t _bler_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blei_f(br, r0, im) _blei_f(_jit,br,r0,im) +static jit_word_t _blei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define beqr_f(br, r0, r1) _beqr_f(_jit,br,r0,r1) +static jit_word_t _beqr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define beqi_f(br, r0, im) _beqi_f(_jit,br,r0,im) +static jit_word_t _beqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define bger_f(br, r0, r1) _bger_f(_jit,br,r0,r1) +static jit_word_t _bger_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgei_f(br, r0, im) _bgei_f(_jit,br,r0,im) +static jit_word_t _bgei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define bgtr_f(br, r0, r1) _bgtr_f(_jit,br,r0,r1) +static jit_word_t _bgtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgti_f(br, r0, im) _bgti_f(_jit,br,r0,im) +static jit_word_t _bgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define bner_f(br, r0, r1) _bner_f(_jit,br,r0,r1) +static jit_word_t _bner_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bnei_f(br, r0, im) _bnei_f(_jit,br,r0,im) +static jit_word_t _bnei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define bunltr_f(br, r0, r1) _bunltr_f(_jit,br,r0,r1) +static jit_word_t _bunltr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlti_f(br, r0, im) _bunlti_f(_jit,br,r0,im) +static jit_word_t _bunlti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define bunler_f(br, r0, r1) _bunler_f(_jit,br,r0,r1) +static jit_word_t _bunler_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlei_f(br, r0, im) _bunlei_f(_jit,br,r0,im) +static jit_word_t _bunlei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define buneqr_f(br, r0, r1) _buneqr_f(_jit,br,r0,r1) +static jit_word_t _buneqr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define buneqi_f(br, r0, im) _buneqi_f(_jit,br,r0,im) +static jit_word_t _buneqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define bunger_f(br, r0, r1) _bunger_f(_jit,br,r0,r1) +static jit_word_t _bunger_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungei_f(br, r0, im) _bungei_f(_jit,br,r0,im) +static jit_word_t _bungei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define bungtr_f(br, r0, r1) _bungtr_f(_jit,br,r0,r1) +static jit_word_t _bungtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungti_f(br, r0, im) _bungti_f(_jit,br,r0,im) +static jit_word_t _bungti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define bltgtr_f(br, r0, r1) _bltgtr_f(_jit,br,r0,r1) +static jit_word_t _bltgtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bltgti_f(br, r0, im) _bltgti_f(_jit,br,r0,im) +static jit_word_t _bltgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define bordr_f(br, r0, r1) _bordr_f(_jit,br,r0,r1) +static jit_word_t _bordr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bordi_f(br, r0, im) _bordi_f(_jit,br,r0,im) +static jit_word_t _bordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define bunordr_f(br, r0, r1) _bunordr_f(_jit,br,r0,r1) +static jit_word_t _bunordr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunordi_f(br, r0, im) _bunordi_f(_jit,br,r0,im) +static jit_word_t _bunordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define addr_d(r0, r1, r2) FADD_D(r0, r1, r2) +# define addi_d(r0, r1, im) _addi_d(_jit, r0, r1, im) +static void _addi_d(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float64_t); +# define subr_d(r0, r1, r2) FSUB_D(r0, r1, r2) +# define subi_d(r0, r1, im) _subi_d(_jit, r0, r1, im) +static void _subi_d(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float64_t); +# define rsbr_d(r0, r1, r2) FSUB_D(r0, r2, r1) +# define rsbi_d(r0, r1, im) _rsbi_d(_jit, r0, r1, im) +static void _rsbi_d(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float64_t); +# define mulr_d(r0, r1, r2) FMUL_D(r0, r1, r2) +# define muli_d(r0, r1, im) _muli_d(_jit, r0, r1, im) +static void _muli_d(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float64_t); +# define divr_d(r0, r1, r2) FDIV_D(r0, r1, r2) +# define divi_d(r0, r1, im) _divi_d(_jit, r0, r1, im) +static void _divi_d(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float64_t); +# define absr_d(r0, r1) FABS_D(r0, r1) +# define negr_d(r0, r1) FNEG_D(r0, r1) +# define sqrtr_d(r0, r1) FSQRT_D(r0, r1) +# define extr_d(r0, r1) FCVT_D_L(r0, r1) +# define ldr_d(r0, r1) FLD(r0, r1, 0) +# define ldi_d(r0, im) _ldi_d(_jit, r0, im) +static void _ldi_d(jit_state_t*, jit_int32_t, jit_word_t); +# define ldxr_d(r0, r1, r2) _ldxr_d(_jit, r0, r1, r2) +static void _ldxr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ldxi_d(r0, r1, i0) _ldxi_d(_jit, r0, r1, i0) +static void _ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define str_d(r0, r1) FSD(r0, r1, 0) +# define sti_d(im, r0) _sti_d(_jit, im, r0) +static void _sti_d(jit_state_t*, jit_word_t, jit_int32_t); +# define stxr_d(r0, r1, r2) _stxr_d(_jit, r0, r1, r2) +static void _stxr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define stxi_d(im, r0, r1) _stxi_d(_jit, im, r0, r1) +static void _stxi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define movr_d(r0, r1) FMV_D(r0, r1) +# define movi_d(r0, im) _movi_d(_jit, r0, im) +static void _movi_d(jit_state_t*, jit_int32_t, jit_float64_t); +# define movr_d_w(r0, r1) FMV_X_D(r0, r1) +# define movi_d_w(r0, im) _movi_d_w(_jit, r0, im) +static void _movi_d_w(jit_state_t*, jit_int32_t, jit_float64_t); +# define movr_w_d(r0, r1) FMV_D_X(r0, r1) +# define extr_f_d(r0, r1) FCVT_D_S(r0, r1) +# define ltr_d(r0, r1, r2) FLT_D(r0, r1, r2) +# define lti_d(r0, r1, r2) _lti_d(_jit, r0, r1, r2) +static void _lti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define ler_d(r0, r1, r2) FLE_D(r0, r1, r2) +# define lei_d(r0, r1, r2) _lei_d(_jit, r0, r1, r2) +static void _lei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define eqr_d(r0, r1, r2) FEQ_D(r0, r1, r2) +# define eqi_d(r0, r1, r2) _eqi_d(_jit, r0, r1, r2) +static void _eqi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define ger_d(r0, r1, r2) FLE_D(r0, r2, r1) +# define gei_d(r0, r1, r2) _gei_d(_jit, r0, r1, r2) +static void _gei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define gtr_d(r0, r1, r2) FLT_D(r0, r2, r1) +# define gti_d(r0, r1, r2) _gti_d(_jit, r0, r1, r2) +static void _gti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define ner_d(r0, r1, r2) _ner_d(_jit, r0, r1, r2) +static void _ner_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define nei_d(r0, r1, r2) _nei_d(_jit, r0, r1, r2) +static void _nei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define unltr_d(r0, r1, r2) _unltr_d(_jit, r0, r1, r2) +static void _unltr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define unlti_d(r0, r1, im) _unlti_d(_jit, r0, r1, im) +static void _unlti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define unler_d(r0, r1, r2) _unler_d(_jit, r0, r1, r2) +static void _unler_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define unlei_d(r0, r1, im) _unlei_d(_jit, r0, r1, im) +static void _unlei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define uneqr_d(r0, r1, r2) _uneqr_d(_jit, r0, r1, r2) +static void _uneqr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define uneqi_d(r0, r1, im) _uneqi_d(_jit, r0, r1, im) +static void _uneqi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define unger_d(r0, r1, r2) _unger_d(_jit, r0, r1, r2) +static void _unger_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ungei_d(r0, r1, im) _ungei_d(_jit, r0, r1, im) +static void _ungei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define ungtr_d(r0, r1, r2) _ungtr_d(_jit, r0, r1, r2) +static void _ungtr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ungti_d(r0, r1, im) _ungti_d(_jit, r0, r1, im) +static void _ungti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define ltgtr_d(r0, r1, r2) _ltgtr_d(_jit, r0, r1, r2) +static void _ltgtr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ltgti_d(r0, r1, im) _ltgti_d(_jit, r0, r1, im) +static void _ltgti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define ordr_d(r0, r1, r2) _ordr_d(_jit, r0, r1, r2) +static void _ordr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ordi_d(r0, r1, im) _ordi_d(_jit, r0, r1, im) +static void _ordi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define unordr_d(r0, r1, r2) _unordr_d(_jit, r0, r1, r2) +static void _unordr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define unordi_d(r0, r1, im) _unordi_d(_jit, r0, r1, im) +static void _unordi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define bltr_d(br, r0, r1) _bltr_d(_jit,br,r0,r1) +static jit_word_t _bltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blti_d(br, r0, im) _blti_d(_jit,br,r0,im) +static jit_word_t _blti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define bler_d(br, r0, r1) _bler_d(_jit,br,r0,r1) +static jit_word_t _bler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blei_d(br, r0, im) _blei_d(_jit,br,r0,im) +static jit_word_t _blei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define beqr_d(br, r0, r1) _beqr_d(_jit,br,r0,r1) +static jit_word_t _beqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define beqi_d(br, r0, im) _beqi_d(_jit,br,r0,im) +static jit_word_t _beqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define bger_d(br, r0, r1) _bger_d(_jit,br,r0,r1) +static jit_word_t _bger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgei_d(br, r0, im) _bgei_d(_jit,br,r0,im) +static jit_word_t _bgei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define bgtr_d(br, r0, r1) _bgtr_d(_jit,br,r0,r1) +static jit_word_t _bgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgti_d(br, r0, im) _bgti_d(_jit,br,r0,im) +static jit_word_t _bgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define bner_d(br, r0, r1) _bner_d(_jit,br,r0,r1) +static jit_word_t _bner_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bnei_d(br, r0, im) _bnei_d(_jit,br,r0,im) +static jit_word_t _bnei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define bunltr_d(br, r0, r1) _bunltr_d(_jit,br,r0,r1) +static jit_word_t _bunltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlti_d(br, r0, im) _bunlti_d(_jit,br,r0,im) +static jit_word_t _bunlti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define bunler_d(br, r0, r1) _bunler_d(_jit,br,r0,r1) +static jit_word_t _bunler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlei_d(br, r0, im) _bunlei_d(_jit,br,r0,im) +static jit_word_t _bunlei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define buneqr_d(br, r0, r1) _buneqr_d(_jit,br,r0,r1) +static jit_word_t _buneqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define buneqi_d(br, r0, im) _buneqi_d(_jit,br,r0,im) +static jit_word_t _buneqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define bunger_d(br, r0, r1) _bunger_d(_jit,br,r0,r1) +static jit_word_t _bunger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungei_d(br, r0, im) _bungei_d(_jit,br,r0,im) +static jit_word_t _bungei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define bungtr_d(br, r0, r1) _bungtr_d(_jit,br,r0,r1) +static jit_word_t _bungtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungti_d(br, r0, im) _bungti_d(_jit,br,r0,im) +static jit_word_t _bungti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define bltgtr_d(br, r0, r1) _bltgtr_d(_jit,br,r0,r1) +static jit_word_t _bltgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bltgti_d(br, r0, im) _bltgti_d(_jit,br,r0,im) +static jit_word_t _bltgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define bordr_d(br, r0, r1) _bordr_d(_jit,br,r0,r1) +static jit_word_t _bordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bordi_d(br, r0, im) _bordi_d(_jit,br,r0,im) +static jit_word_t _bordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define bunordr_d(br, r0, r1) _bunordr_d(_jit,br,r0,r1) +static jit_word_t _bunordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunordi_d(br, r0, im) _bunordi_d(_jit,br,r0,im) +static jit_word_t _bunordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1) +static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t); +#endif /* PROTO */ + +#if CODE +# define fpr_opi(name, type, size) \ +static void \ +_##name##i_##type(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, \ + jit_float##size##_t i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr); \ + movi_##type(rn(reg), i0); \ + name##r_##type(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +# define fopi(name) fpr_opi(name, f, 32) +# define dopi(name) fpr_opi(name, d, 64) + +fopi(add) +fopi(sub) +fopi(rsb) +fopi(mul) +fopi(div) + +static void +_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t t0; + if (simm12_p(i0)) + FLW(r0, _ZERO_REGNO, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + ldr_f(r0, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + addr(rn(t0), r1, r2); + ldr_f(r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + if (simm12_p(i0)) + FLW(r0, r1, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + addi(rn(t0), r1, i0); + ldr_f(r0, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t t0; + if (simm12_p(i0)) + FSW(r0, _ZERO_REGNO, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + str_f(rn(t0), r0); + jit_unget_reg(t0); + } +} + +static void +_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + addr(rn(t0), r0, r1); + str_f(rn(t0), r2); + jit_unget_reg(t0); +} + +static void +_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + if (simm12_p(i0)) + FSW(r0, r1, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + addi(rn(t0), r0, i0); + str_f(rn(t0), r1); + jit_unget_reg(t0); + } +} + +static void +_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_int32_t reg; + data.f = i0; + if (data.i == 0) + movr_w_f(r0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.i); + movr_w_f(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_movi_f_w(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + data.f = i0; + movi(r0, data.i); +} + +fopi(lt) +fopi(le) +fopi(eq) +fopi(ge) +fopi(gt) + +static void +_ner_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + eqr_f(r0, r1, r2); + xori(r0, r0, 1); +} +fopi(ne) + +# define fpr_bopi(name, type, size) \ +static jit_word_t \ +_b##name##i_##type(jit_state_t *_jit, \ + jit_word_t i0, jit_int32_t r0, \ + jit_float##size##_t i1) \ +{ \ + jit_word_t word; \ + jit_int32_t reg = jit_get_reg(jit_class_fpr| \ + jit_class_nospill); \ + movi_##type(rn(reg), i1); \ + word = b##name##r_##type(i0, r0, rn(reg)); \ + jit_unget_reg(reg); \ + return (word); \ +} +# define fbopi(name) fpr_bopi(name, f, 32) +# define dbopi(name) fpr_bopi(name, d, 64) + +# define unop(CLASS, OP) \ + jit_word_t w; \ + jit_int32_t t0, t1; \ + t0 = jit_get_reg(jit_class_gpr); \ + FCLASS_##CLASS(rn(t0), r1); \ + t1 = jit_get_reg(jit_class_gpr); \ + FCLASS_##CLASS(rn(t1), r2); \ + orr(rn(t0), rn(t0), rn(t1)); \ + jit_unget_reg(t1); \ + rshi(rn(t0), rn(t0), 8); \ + ltr(r0, _ZERO_REGNO, rn(t0)); \ + jit_unget_reg(t0); \ + w = _jit->pc.w; \ + BLT(_ZERO_REGNO, r0, 0); \ + OP(r0, r1, r2); \ + patch_at(w, _jit->pc.w) + +static void +_unltr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + unop(S, ltr_f); +} +fopi(unlt) + +static void +_unler_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + unop(S, ler_f); +} +fopi(unle) + +static void +_uneqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + unop(S, eqr_f); +} +fopi(uneq) + +static void +_unger_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + unop(S, ger_f); +} +fopi(unge) + +static void +_ungtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + unop(S, gtr_f); +} +fopi(ungt) + +static void +_ltgtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w0, w1; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr); + FCLASS_S(rn(t0), r1); + t1 = jit_get_reg(jit_class_gpr); + FCLASS_S(rn(t1), r2); + orr(rn(t0), rn(t0), rn(t1)); + jit_unget_reg(t1); + rshi(rn(t0), rn(t0), 8); + ltr(r0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + w0 = _jit->pc.w; + BEQ(_ZERO_REGNO, r0, 0); + movr(r0, _ZERO_REGNO); + w1 = _jit->pc.w; + JAL(_ZERO_REGNO, 0); + patch_at(w0, _jit->pc.w); + ner_f(r0, r1, r2); + patch_at(w1, _jit->pc.w); +} +fopi(ltgt) + +static void +_ordr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr); + FCLASS_S(rn(t0), r1); + t1 = jit_get_reg(jit_class_gpr); + FCLASS_S(rn(t1), r2); + orr(rn(t0), rn(t0), rn(t1)); + jit_unget_reg(t1); + rshi(rn(t0), rn(t0), 8); + eqr(r0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); +} +fopi(ord) + +static void +_unordr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr); + FCLASS_S(rn(t0), r1); + t1 = jit_get_reg(jit_class_gpr); + FCLASS_S(rn(t1), r2); + orr(rn(t0), rn(t0), rn(t1)); + jit_unget_reg(t1); + rshi(rn(t0), rn(t0), 8); + ltr(r0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); +} +fopi(unord) + +static jit_word_t +_bltr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + ltr_f(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(lt) + +static jit_word_t +_bler_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + ler_f(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(le) + +static jit_word_t +_beqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + eqr_f(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(eq) + +static jit_word_t +_bger_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + ger_f(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(ge) + +static jit_word_t +_bgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + gtr_f(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(gt) + +static jit_word_t +_bner_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + eqr_f(rn(t0), r1, r2); + w = beqr(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(ne) + +static jit_word_t +_bunltr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + unltr_f(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(unlt) + +static jit_word_t +_bunler_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + unler_f(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(unle) + +static jit_word_t +_buneqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + uneqr_f(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(uneq) + +static jit_word_t +_bunger_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + unger_f(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(unge) + +static jit_word_t +_bungtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + ungtr_f(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(ungt) + +static jit_word_t +_bltgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + ltgtr_f(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(ltgt) + +static jit_word_t +_bordr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + ordr_f(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(ord) + +static jit_word_t +_bunordr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + unordr_f(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +fbopi(unord) + +dopi(add) +dopi(sub) +dopi(rsb) +dopi(mul) +dopi(div) + +static void +_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t t0; + if (simm12_p(i0)) + FLD(r0, _ZERO_REGNO, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + ldr_d(r0, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + addr(rn(t0), r1, r2); + ldr_d(r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + if (simm12_p(i0)) + FLD(r0, r1, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + addi(rn(t0), r1, i0); + ldr_d(r0, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t t0; + if (simm12_p(i0)) + FSD(r0, _ZERO_REGNO, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + str_d(rn(t0), r0); + jit_unget_reg(t0); + } +} + +static void +_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr); + addr(rn(t0), r0, r1); + str_d(rn(t0), r2); + jit_unget_reg(t0); +} + +static void +_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + if (simm12_p(i0)) + FSD(r0, r1, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + addi(rn(t0), r0, i0); + str_d(rn(t0), r1); + jit_unget_reg(t0); + } +} + +static void +_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0) +{ + union { + jit_word_t w; + jit_float64_t d; + } data; + jit_int32_t reg; + data.d = i0; + if (data.w == 0) + movr_w_d(r0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.w); + movr_w_d(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_movi_d_w(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0) +{ + union { + jit_int64_t l; + jit_float64_t d; + } data; + data.d = i0; + movi(r0, data.l); +} + +dopi(lt) +dopi(le) +dopi(eq) +dopi(ge) +dopi(gt) + +static void +_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + eqr_d(r0, r1, r2); + xori(r0, r0, 1); +} +dopi(ne) + +static void +_unltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + unop(D, ltr_d); +} +dopi(unlt) + +static void +_unler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + unop(D, ler_d); +} +dopi(unle) + +static void +_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + unop(D, eqr_d); +} +dopi(uneq) + +static void +_unger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + unop(D, ger_d); +} +dopi(unge) + +static void +_ungtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + unop(D, gtr_d); +} +dopi(ungt) + +static void +_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w0, w1; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr); + FCLASS_D(rn(t0), r1); + t1 = jit_get_reg(jit_class_gpr); + FCLASS_D(rn(t1), r2); + orr(rn(t0), rn(t0), rn(t1)); + jit_unget_reg(t1); + rshi(rn(t0), rn(t0), 8); + ltr(r0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + w0 = _jit->pc.w; + BEQ(_ZERO_REGNO, r0, 0); + movr(r0, _ZERO_REGNO); + w1 = _jit->pc.w; + JAL(_ZERO_REGNO, 0); + patch_at(w0, _jit->pc.w); + ner_d(r0, r1, r2); + patch_at(w1, _jit->pc.w); +} +dopi(ltgt) + +static void +_ordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr); + FCLASS_D(rn(t0), r1); + t1 = jit_get_reg(jit_class_gpr); + FCLASS_D(rn(t1), r2); + orr(rn(t0), rn(t0), rn(t1)); + jit_unget_reg(t1); + rshi(rn(t0), rn(t0), 8); + eqr(r0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); +} +dopi(ord) + +static void +_unordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr); + FCLASS_D(rn(t0), r1); + t1 = jit_get_reg(jit_class_gpr); + FCLASS_D(rn(t1), r2); + orr(rn(t0), rn(t0), rn(t1)); + jit_unget_reg(t1); + rshi(rn(t0), rn(t0), 8); + ltr(r0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); +} +dopi(unord) + +static jit_word_t +_bltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + ltr_d(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(lt) + +static jit_word_t +_bler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + ler_d(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(le) + +static jit_word_t +_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + eqr_d(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(eq) + +static jit_word_t +_bger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + ger_d(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(ge) + +static jit_word_t +_bgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + gtr_d(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(gt) + +static jit_word_t +_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + eqr_d(rn(t0), r1, r2); + w = beqr(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(ne) + +static jit_word_t +_bunltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + unltr_d(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(unlt) + +static jit_word_t +_bunler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + unler_d(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(unle) + +static jit_word_t +_buneqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + uneqr_d(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(uneq) + +static jit_word_t +_bunger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + unger_d(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(unge) + +static jit_word_t +_bungtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + ungtr_d(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(ungt) + +static jit_word_t +_bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + ltgtr_d(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(ltgt) + +static jit_word_t +_bordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + ordr_d(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(ord) + +static jit_word_t +_bunordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + unordr_d(rn(t0), r1, r2); + w = bner(i0, _ZERO_REGNO, rn(t0)); + jit_unget_reg(t0); + return (w); +} +dbopi(unord) + +static void +_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(_jitc->function->self.call & jit_call_varargs); + /* Load argument. */ + ldr_d(r0, r1); + /* Update va_list. */ + addi(r1, r1, sizeof(jit_float64_t)); +} + +#endif /* CODE */ diff --git a/deps/lightning/lib/jit_riscv-sz.c b/deps/lightning/lib/jit_riscv-sz.c new file mode 100644 index 0000000..2f1d725 --- /dev/null +++ b/deps/lightning/lib/jit_riscv-sz.c @@ -0,0 +1,401 @@ +#if __WORDSIZE == 64 +#define JIT_INSTR_MAX 116 + 0, /* data */ + 0, /* live */ + 4, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 112, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 8, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 20, /* addi */ + 12, /* addcr */ + 28, /* addci */ + 28, /* addxr */ + 28, /* addxi */ + 4, /* subr */ + 20, /* subi */ + 12, /* subcr */ + 28, /* subci */ + 28, /* subxr */ + 28, /* subxi */ + 28, /* rsbi */ + 4, /* mulr */ + 20, /* muli */ + 12, /* qmulr */ + 24, /* qmuli */ + 12, /* qmulr_u */ + 24, /* qmuli_u */ + 4, /* divr */ + 20, /* divi */ + 4, /* divr_u */ + 20, /* divi_u */ + 20, /* qdivr */ + 16, /* qdivi */ + 20, /* qdivr_u */ + 16, /* qdivi_u */ + 4, /* remr */ + 20, /* remi */ + 4, /* remr_u */ + 20, /* remi_u */ + 4, /* andr */ + 20, /* andi */ + 4, /* orr */ + 20, /* ori */ + 4, /* xorr */ + 20, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 4, /* ltr */ + 4, /* lti */ + 4, /* ltr_u */ + 4, /* lti_u */ + 8, /* ler */ + 12, /* lei */ + 8, /* ler_u */ + 12, /* lei_u */ + 12, /* eqr */ + 12, /* eqi */ + 8, /* ger */ + 12, /* gei */ + 8, /* ger_u */ + 12, /* gei_u */ + 4, /* gtr */ + 8, /* gti */ + 4, /* gtr_u */ + 8, /* gti_u */ + 8, /* ner */ + 8, /* nei */ + 4, /* movr */ + 24, /* movi */ + 8, /* extr_c */ + 4, /* extr_uc */ + 8, /* extr_s */ + 8, /* extr_us */ + 4, /* extr_i */ + 8, /* extr_ui */ + 20, /* htonr_us */ + 52, /* htonr_ui */ + 116, /* htonr_ul */ + 4, /* ldr_c */ + 12, /* ldi_c */ + 4, /* ldr_uc */ + 12, /* ldi_uc */ + 4, /* ldr_s */ + 12, /* ldi_s */ + 4, /* ldr_us */ + 12, /* ldi_us */ + 4, /* ldr_i */ + 12, /* ldi_i */ + 4, /* ldr_ui */ + 12, /* ldi_ui */ + 4, /* ldr_l */ + 12, /* ldi_l */ + 8, /* ldxr_c */ + 16, /* ldxi_c */ + 8, /* ldxr_uc */ + 16, /* ldxi_uc */ + 8, /* ldxr_s */ + 16, /* ldxi_s */ + 8, /* ldxr_us */ + 16, /* ldxi_us */ + 8, /* ldxr_i */ + 16, /* ldxi_i */ + 8, /* ldxr_ui */ + 16, /* ldxi_ui */ + 8, /* ldxr_l */ + 16, /* ldxi_l */ + 4, /* str_c */ + 12, /* sti_c */ + 4, /* str_s */ + 12, /* sti_s */ + 4, /* str_i */ + 12, /* sti_i */ + 4, /* str_l */ + 12, /* sti_l */ + 8, /* stxr_c */ + 16, /* stxi_c */ + 8, /* stxr_s */ + 16, /* stxi_s */ + 8, /* stxr_i */ + 16, /* stxi_i */ + 8, /* stxr_l */ + 16, /* stxi_l */ + 4, /* bltr */ + 8, /* blti */ + 4, /* bltr_u */ + 8, /* blti_u */ + 4, /* bler */ + 8, /* blei */ + 4, /* bler_u */ + 8, /* blei_u */ + 4, /* beqr */ + 28, /* beqi */ + 4, /* bger */ + 8, /* bgei */ + 4, /* bger_u */ + 8, /* bgei_u */ + 4, /* bgtr */ + 8, /* bgti */ + 4, /* bgtr_u */ + 8, /* bgti_u */ + 4, /* bner */ + 20, /* bnei */ + 8, /* bmsr */ + 12, /* bmsi */ + 8, /* bmcr */ + 12, /* bmci */ + 32, /* boaddr */ + 36, /* boaddi */ + 16, /* boaddr_u */ + 20, /* boaddi_u */ + 32, /* bxaddr */ + 36, /* bxaddi */ + 16, /* bxaddr_u */ + 20, /* bxaddi_u */ + 32, /* bosubr */ + 36, /* bosubi */ + 16, /* bosubr_u */ + 20, /* bosubi_u */ + 32, /* bxsubr */ + 36, /* bxsubi */ + 16, /* bxsubr_u */ + 20, /* bxsubi_u */ + 4, /* jmpr */ + 28, /* jmpi */ + 4, /* callr */ + 28, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 112, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 12, /* addi_f */ + 4, /* subr_f */ + 12, /* subi_f */ + 12, /* rsbi_f */ + 4, /* mulr_f */ + 12, /* muli_f */ + 4, /* divr_f */ + 12, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 4, /* ltr_f */ + 12, /* lti_f */ + 4, /* ler_f */ + 12, /* lei_f */ + 4, /* eqr_f */ + 12, /* eqi_f */ + 4, /* ger_f */ + 12, /* gei_f */ + 4, /* gtr_f */ + 12, /* gti_f */ + 8, /* ner_f */ + 16, /* nei_f */ + 28, /* unltr_f */ + 36, /* unlti_f */ + 28, /* unler_f */ + 36, /* unlei_f */ + 28, /* uneqr_f */ + 36, /* uneqi_f */ + 28, /* unger_f */ + 36, /* ungei_f */ + 28, /* ungtr_f */ + 36, /* ungti_f */ + 40, /* ltgtr_f */ + 48, /* ltgti_f */ + 28, /* ordr_f */ + 36, /* ordi_f */ + 20, /* unordr_f */ + 28, /* unordi_f */ + 4, /* truncr_f_i */ + 4, /* truncr_f_l */ + 4, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 8, /* movi_f */ + 4, /* ldr_f */ + 12, /* ldi_f */ + 8, /* ldxr_f */ + 16, /* ldxi_f */ + 4, /* str_f */ + 12, /* sti_f */ + 8, /* stxr_f */ + 16, /* stxi_f */ + 8, /* bltr_f */ + 16, /* blti_f */ + 8, /* bler_f */ + 16, /* blei_f */ + 8, /* beqr_f */ + 16, /* beqi_f */ + 8, /* bger_f */ + 16, /* bgei_f */ + 8, /* bgtr_f */ + 16, /* bgti_f */ + 8, /* bner_f */ + 16, /* bnei_f */ + 32, /* bunltr_f */ + 40, /* bunlti_f */ + 32, /* bunler_f */ + 40, /* bunlei_f */ + 32, /* buneqr_f */ + 40, /* buneqi_f */ + 32, /* bunger_f */ + 40, /* bungei_f */ + 32, /* bungtr_f */ + 40, /* bungti_f */ + 44, /* bltgtr_f */ + 52, /* bltgti_f */ + 32, /* bordr_f */ + 40, /* bordi_f */ + 24, /* bunordr_f */ + 32, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 24, /* addi_d */ + 4, /* subr_d */ + 24, /* subi_d */ + 24, /* rsbi_d */ + 4, /* mulr_d */ + 24, /* muli_d */ + 4, /* divr_d */ + 24, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 4, /* ltr_d */ + 24, /* lti_d */ + 4, /* ler_d */ + 24, /* lei_d */ + 4, /* eqr_d */ + 24, /* eqi_d */ + 4, /* ger_d */ + 24, /* gei_d */ + 4, /* gtr_d */ + 24, /* gti_d */ + 8, /* ner_d */ + 28, /* nei_d */ + 28, /* unltr_d */ + 48, /* unlti_d */ + 28, /* unler_d */ + 48, /* unlei_d */ + 28, /* uneqr_d */ + 48, /* uneqi_d */ + 28, /* unger_d */ + 48, /* ungei_d */ + 28, /* ungtr_d */ + 48, /* ungti_d */ + 40, /* ltgtr_d */ + 60, /* ltgti_d */ + 28, /* ordr_d */ + 48, /* ordi_d */ + 20, /* unordr_d */ + 40, /* unordi_d */ + 4, /* truncr_d_i */ + 4, /* truncr_d_l */ + 4, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 20, /* movi_d */ + 4, /* ldr_d */ + 12, /* ldi_d */ + 8, /* ldxr_d */ + 16, /* ldxi_d */ + 4, /* str_d */ + 12, /* sti_d */ + 8, /* stxr_d */ + 16, /* stxi_d */ + 8, /* bltr_d */ + 28, /* blti_d */ + 8, /* bler_d */ + 28, /* blei_d */ + 8, /* beqr_d */ + 28, /* beqi_d */ + 8, /* bger_d */ + 28, /* bgei_d */ + 8, /* bgtr_d */ + 28, /* bgti_d */ + 8, /* bner_d */ + 28, /* bnei_d */ + 32, /* bunltr_d */ + 52, /* bunlti_d */ + 32, /* bunler_d */ + 52, /* bunlei_d */ + 32, /* buneqr_d */ + 52, /* buneqi_d */ + 32, /* bunger_d */ + 52, /* bungei_d */ + 32, /* bungtr_d */ + 52, /* bungti_d */ + 44, /* bltgtr_d */ + 64, /* bltgti_d */ + 32, /* bordr_d */ + 52, /* bordi_d */ + 24, /* bunordr_d */ + 44, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 4, /* movr_w_f */ + 0, /* movr_ww_d */ + 4, /* movr_w_d */ + 0, /* movr_f_w */ + 4, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 4, /* movr_d_w */ + 16, /* movi_d_w */ +#endif /* __WORDSIZE */ diff --git a/deps/lightning/lib/jit_riscv.c b/deps/lightning/lib/jit_riscv.c new file mode 100644 index 0000000..55b2391 --- /dev/null +++ b/deps/lightning/lib/jit_riscv.c @@ -0,0 +1,1615 @@ +/* + * Copyright (C) 2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 8) +#define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 8) + +/* + * Types + */ +typedef jit_pointer_t jit_va_list_t; + +/* + * Prototypes + */ +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); + +#define PROTO 1 +# include "jit_riscv-cpu.c" +# include "jit_riscv-fpu.c" +#undef PROTO + +/* + * Initialization + */ +jit_register_t _rvs[] = { + { 0x00, "zero" }, + { 0x01, "ra" }, + { 0x02, "sp" }, + { 0x03, "gp" }, +#if 0 /* Pretend it does not exist, so _NOREG can be used in + * a 64 bit bitmask */ + { 0x04, "tp" }, +#endif + { rc(gpr) | 0x05, "t0" }, + { rc(gpr) | 0x06, "t1" }, + { rc(gpr) | 0x07, "t2" }, + { rc(gpr) | 0x1c, "t3" }, + { rc(gpr) | 0x1d, "t4" }, + { rc(gpr) | 0x1e, "t5" }, + { rc(gpr) | 0x1f, "t6" }, + { 0x08, "fp" }, + { rc(sav) | rc(gpr) | 0x09, "s1" }, + { rc(sav) | rc(gpr) | 0x12, "s2" }, + { rc(sav) | rc(gpr) | 0x13, "s3" }, + { rc(sav) | rc(gpr) | 0x14, "s4" }, + { rc(sav) | rc(gpr) | 0x15, "s5" }, + { rc(sav) | rc(gpr) | 0x16, "s6" }, + { rc(sav) | rc(gpr) | 0x17, "s7" }, + { rc(sav) | rc(gpr) | 0x18, "s8" }, + { rc(sav) | rc(gpr) | 0x19, "s9" }, + { rc(sav) | rc(gpr) | 0x1a, "s10" }, + { rc(sav) | rc(gpr) | 0x1b, "s11" }, + { rc(arg) | rc(gpr) | 0x11, "a7" }, + { rc(arg) | rc(gpr) | 0x10, "a6" }, + { rc(arg) | rc(gpr) | 0x0f, "a5" }, + { rc(arg) | rc(gpr) | 0x0e, "a4" }, + { rc(arg) | rc(gpr) | 0x0d, "a3" }, + { rc(arg) | rc(gpr) | 0x0c, "a2" }, + { rc(arg) | rc(gpr) | 0x0b, "a1" }, + { rc(arg) | rc(gpr) | 0x0a, "a0" }, + { rc(fpr) | 0x00, "ft0" }, + { rc(fpr) | 0x01, "ft1" }, + { rc(fpr) | 0x02, "ft2" }, + { rc(fpr) | 0x03, "ft3" }, + { rc(fpr) | 0x04, "ft4" }, + { rc(fpr) | 0x05, "ft5" }, + { rc(fpr) | 0x06, "ft6" }, + { rc(fpr) | 0x07, "ft7" }, + { rc(fpr) | 0x1c, "ft8" }, + { rc(fpr) | 0x1d, "ft9" }, + { rc(fpr) | 0x1e, "ft10" }, + { rc(fpr) | 0x1f, "ft11" }, + { rc(sav) | rc(fpr) | 0x08, "fs0" }, + { rc(sav) | rc(fpr) | 0x09, "fs1" }, + { rc(sav) | rc(fpr) | 0x12, "fs2" }, + { rc(sav) | rc(fpr) | 0x13, "fs3" }, + { rc(sav) | rc(fpr) | 0x14, "fs4" }, + { rc(sav) | rc(fpr) | 0x15, "fs5" }, + { rc(sav) | rc(fpr) | 0x16, "fs6" }, + { rc(sav) | rc(fpr) | 0x17, "fs7" }, + { rc(sav) | rc(fpr) | 0x18, "fs8" }, + { rc(sav) | rc(fpr) | 0x19, "fs9" }, + { rc(sav) | rc(fpr) | 0x1a, "fs10" }, + { rc(sav) | rc(fpr) | 0x1b, "fs11" }, + { rc(arg) | rc(fpr) | 0x11, "fa7" }, + { rc(arg) | rc(fpr) | 0x10, "fa6" }, + { rc(arg) | rc(fpr) | 0x0f, "fa5" }, + { rc(arg) | rc(fpr) | 0x0e, "fa4" }, + { rc(arg) | rc(fpr) | 0x0d, "fa3" }, + { rc(arg) | rc(fpr) | 0x0c, "fa2" }, + { rc(arg) | rc(fpr) | 0x0b, "fa1" }, + { rc(arg) | rc(fpr) | 0x0a, "fa0" }, + { _NOREG, "<none>" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ +} + +void +_jit_init(jit_state_t *_jit) +{ + _jitc->reglen = jit_size(_rvs) - 1; + jit_carry = _NOREG; +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + _jitc->function->self.size = stack_framesize; + _jitc->function->self.argi = _jitc->function->self.argf = + _jitc->function->self.alen = 0; + _jitc->function->self.aoff = 0; + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + assert(_jitc->function); + switch (length) { + case 0: case 1: break; + case 2: _jitc->function->self.aoff &= -2; break; + case 3: case 4: _jitc->function->self.aoff &= -4; break; + default: _jitc->function->self.aoff &= -8; break; + } + _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } + return (_jitc->function->self.aoff); +} + +void +_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) +{ + jit_int32_t r0; + assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); + if (!_jitc->function->allocar) { + _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); + _jitc->function->allocar = 1; + } + r0 = jit_get_reg(jit_class_gpr); + jit_negr(r0, v); + jit_andi(r0, r0, -16); + jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); + jit_addr(u, u, r0); + jit_addr(JIT_SP, JIT_SP, r0); + jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); + jit_unget_reg(r0); + jit_dec_synth(); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + assert(_jitc->function); + jit_inc_synth(ret); + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr, u); + if (JIT_RET != u) + jit_movr(JIT_RET, u); + jit_live(JIT_RET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti(jit_state_t *_jit, jit_word_t u) +{ + jit_inc_synth_w(reti, u); + jit_movi(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_f, u); + if (u != JIT_FRET) + jit_movr_f(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_inc_synth_f(reti_f, u); + jit_movi_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_d, u); + if (u != JIT_FRET) + jit_movr_d(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_inc_synth_d(reti_d, u); + jit_movi_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_epilog(jit_state_t *_jit) +{ + assert(_jitc->function); + assert(_jitc->function->epilog->next == NULL); + jit_link(_jitc->function->epilog); + _jitc->function = NULL; +} + +jit_bool_t +_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) +{ + if (u->code == jit_code_arg) + return (jit_arg_reg_p(u->u.w)); + assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d); + return (jit_arg_f_reg_p(u->u.w)); +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + jit_inc_synth(ellipsis); + if (_jitc->prepare) { + jit_link_prepare(); + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; + } + else { + jit_link_prolog(); + assert(!(_jitc->function->self.call & jit_call_varargs)); + _jitc->function->self.call |= jit_call_varargs; + _jitc->function->vagp = _jitc->function->self.argi; + } + jit_dec_synth(); +} + +void +_jit_va_push(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(va_push, u); + jit_pushargr(u); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + assert(!(_jitc->function->self.call & jit_call_varargs)); + if (jit_arg_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + assert(!(_jitc->function->self.call & jit_call_varargs)); + if (jit_arg_f_reg_p(_jitc->function->self.argf)) + offset = _jitc->function->self.argf++; + else if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi++; + offset += 8; + } + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + assert(!(_jitc->function->self.call & jit_call_varargs)); + if (jit_arg_f_reg_p(_jitc->function->self.argf)) + offset = _jitc->function->self.argf++; + else if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi++; + offset += 8; + } + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +void +_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_c(u, JIT_RA0 - v->u.w); + else + jit_ldxi_c(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_uc(u, JIT_RA0 - v->u.w); + else + jit_ldxi_uc(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_s(u, JIT_RA0 - v->u.w); + else + jit_ldxi_s(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_us(u, JIT_RA0 - v->u.w); + else + jit_ldxi_us(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_i(u, JIT_RA0 - v->u.w); + else + jit_ldxi_i(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_ui(u, JIT_RA0 - v->u.w); + else + jit_ldxi_ui(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(u, JIT_RA0 - v->u.w); + else + jit_ldxi_l(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(JIT_RA0 - v->u.w, u); + else + jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movi(JIT_RA0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_f(u, JIT_FA0 - v->u.w); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_w_f(u, JIT_RA0 - (v->u.w - 8)); + else + jit_ldxi_f(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_f(JIT_FA0 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_f_w(JIT_RA0 - (v->u.w - 8), u); + else + jit_stxi_f(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movi_f(JIT_FA0 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) { + union { + jit_float32_t f; + jit_int32_t i; + } uu; + uu.f = u; + jit_movi(JIT_RA0 - (v->u.w - 8), uu.i); + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(u, JIT_FA0 - v->u.w); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_w_d(u, JIT_RA0 - (v->u.w - 8)); + else + jit_ldxi_d(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr_d(JIT_FA0 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_d_w(JIT_RA0 - (v->u.w - 8), u); + else + jit_stxi_d(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movi_d(JIT_FA0 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) { + union { + jit_float64_t d; + jit_int64_t w; + } uu; + uu.d = u; + jit_movi(JIT_RA0 - (v->u.w - 8), uu.w); + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi(jit_state_t *_jit, jit_word_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) && + !(_jitc->function->call.call & jit_call_varargs)) { + jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr_f_w(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi_f(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) && + !(_jitc->function->call.call & jit_call_varargs)) { + jit_movi_f(JIT_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi_f_w(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) && + !(_jitc->function->call.call & jit_call_varargs)) { + jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr_d_w(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi_d(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) && + !(_jitc->function->call.call & jit_call_varargs)) { + jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi_d_w(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + jit_int32_t spec; + spec = jit_class(_rvs[regno].spec); + if (spec & jit_class_arg) { + regno = JIT_RA0 - regno; + if (regno >= 0 && regno < node->v.w) + return (1); + if (spec & jit_class_fpr) { + regno = JIT_FA0 - regno; + if (regno >= 0 && regno < node->w.w) + return (1); + } + } + + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishr, r0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_callr(r0); + node->v.w = _jitc->function->self.argi; + node->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_calli(i0); + node->v.w = _jitc->function->call.argi; + node->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); + return (node); +} + +void +_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_c, r0); + jit_extr_c(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_uc, r0); + jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_s, r0); + jit_extr_s(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_us, r0); + jit_extr_us(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_i, r0); + jit_extr_i(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_ui, r0); + jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_l, r0); + if (r0 != JIT_RET) + jit_movr(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_f, r0); + if (r0 != JIT_FRET) + jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_d, r0); + if (r0 != JIT_FRET) + jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_word_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_uint8_t *data; + jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + jit_int32_t const_offset; + jit_int32_t patch_offset; + } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + + _jitc->function = NULL; + + jit_reglive_setup(); + + undo.word = 0; + undo.node = NULL; + undo.const_offset = undo.patch_offset = 0; +# define assert_data(node) /**/ +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_rrf(name) \ + case jit_code_##name##i_f: \ + assert_data(node); \ + name##i_f(rn(node->u.w), rn(node->v.w), node->w.f); \ + break +#define case_rrd(name) \ + case jit_code_##name##i_d: \ + assert_data(node); \ + name##i_d(rn(node->u.w), rn(node->v.w), node->w.d); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type(_jit->pc.w, \ + rn(node->v.w), rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break; +#define case_brf(name) \ + case jit_code_##name##i_f: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i_f(temp->u.w, rn(node->v.w), node->w.f); \ + else { \ + word = name##i_f(_jit->pc.w, rn(node->v.w), \ + node->w.f); \ + patch(word, node); \ + } \ + break +#define case_brd(name) \ + case jit_code_##name##i_d: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i_d(temp->u.w, rn(node->v.w), node->w.d); \ + else { \ + word = name##i_d(_jit->pc.w, rn(node->v.w), \ + node->w.d); \ + patch(word, node); \ + } \ + break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end) + return (NULL); + +#if DEVEL_DISASSEMBLER + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; +#endif + value = jit_classify(node->code); + jit_regarg_set(node, value); + switch (node->code) { + case jit_code_align: + assert(!(node->u.w & (node->u.w - 1)) && + node->u.w <= sizeof(jit_word_t)); + if (node->u.w == sizeof(jit_word_t) && + (word = _jit->pc.w & (sizeof(jit_word_t) - 1))) + nop(sizeof(jit_word_t) - word); + break; + case jit_code_note: case jit_code_name: + node->u.w = _jit->pc.w; + break; + case jit_code_label: + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + break; + case_rrr(add,); + case_rrw(add,); + case_rrr(addc,); + case_rrw(addc,); + case_rrr(addx,); + case_rrw(addx,); + case_rrr(sub,); + case_rrw(sub,); + case_rrr(subc,); + case_rrw(subc,); + case_rrr(subx,); + case_rrw(subx,); + case_rrw(rsb,); + case_rrr(mul,); + case_rrw(mul,); + case_rrrr(qmul,); + case_rrrw(qmul,); + case_rrrr(qmul, _u); + case_rrrw(qmul, _u); + case_rrr(div,); + case_rrw(div,); + case_rrr(div, _u); + case_rrw(div, _u); + case_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rr(neg,); + case_rr(com,); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_rr(trunc, _f_i); + case_rr(trunc, _d_i); + case_rr(trunc, _f_l); + case_rr(trunc, _d_l); + case_rr(ld, _c); + case_rw(ld, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rr(ld, _i); + case_rw(ld, _i); + case_rr(ld, _ui); + case_rw(ld, _ui); + case_rr(ld, _l); + case_rw(ld, _l); + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rrr(ldx, _i); + case_rrw(ldx, _i); + case_rrr(ldx, _ui); + case_rrw(ldx, _ui); + case_rrr(ldx, _l); + case_rrw(ldx, _l); + case_rr(st, _c); + case_wr(st, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rr(st, _i); + case_wr(st, _i); + case_rr(st, _l); + case_wr(st, _l); + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rrr(stx, _i); + case_wrr(stx, _i); + case_rrr(stx, _l); + case_wrr(stx, _l); + case_rr(hton, _us); + case_rr(hton, _ui); + case_rr(hton, _ul); + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); + case_rr(ext, _i); + case_rr(ext, _ui); + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), temp->u.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_rrr(add, _f); + case_rrf(add); + case_rrr(sub, _f); + case_rrf(sub); + case_rrf(rsb); + case_rrr(mul, _f); + case_rrf(mul); + case_rrr(div, _f); + case_rrf(div); + case_rr(abs, _f); + case_rr(neg, _f); + case_rr(sqrt, _f); + case_rr(ext, _f); + case_rr(ld, _f); + case_rw(ld, _f); + case_rrr(ldx, _f); + case_rrw(ldx, _f); + case_rr(st, _f); + case_wr(st, _f); + case_rrr(stx, _f); + case_wrr(stx, _f); + case_rr(mov, _f); + case jit_code_movi_f: + assert_data(node); + movi_f(rn(node->u.w), node->v.f); + break; + case_rr(ext, _d_f); + case_rrr(lt, _f); + case_rrf(lt); + case_rrr(le, _f); + case_rrf(le); + case_rrr(eq, _f); + case_rrf(eq); + case_rrr(ge, _f); + case_rrf(ge); + case_rrr(gt, _f); + case_rrf(gt); + case_rrr(ne, _f); + case_rrf(ne); + case_rrr(unlt, _f); + case_rrf(unlt); + case_rrr(unle, _f); + case_rrf(unle); + case_rrr(uneq, _f); + case_rrf(uneq); + case_rrr(unge, _f); + case_rrf(unge); + case_rrr(ungt, _f); + case_rrf(ungt); + case_rrr(ltgt, _f); + case_rrf(ltgt); + case_rrr(ord, _f); + case_rrf(ord); + case_rrr(unord, _f); + case_rrf(unord); + case_brr(blt, _f); + case_brf(blt); + case_brr(ble, _f); + case_brf(ble); + case_brr(beq, _f); + case_brf(beq); + case_brr(bge, _f); + case_brf(bge); + case_brr(bgt, _f); + case_brf(bgt); + case_brr(bne, _f); + case_brf(bne); + case_brr(bunlt, _f); + case_brf(bunlt); + case_brr(bunle, _f); + case_brf(bunle); + case_brr(buneq, _f); + case_brf(buneq); + case_brr(bunge, _f); + case_brf(bunge); + case_brr(bungt, _f); + case_brf(bungt); + case_brr(bltgt, _f); + case_brf(bltgt); + case_brr(bord, _f); + case_brf(bord); + case_brr(bunord, _f); + case_brf(bunord); + case_rrr(add, _d); + case_rrd(add); + case_rrr(sub, _d); + case_rrd(sub); + case_rrd(rsb); + case_rrr(mul, _d); + case_rrd(mul); + case_rrr(div, _d); + case_rrd(div); + case_rr(abs, _d); + case_rr(neg, _d); + case_rr(sqrt, _d); + case_rr(ext, _d); + case_rr(ld, _d); + case_rw(ld, _d); + case_rrr(ldx, _d); + case_rrw(ldx, _d); + case_rr(st, _d); + case_wr(st, _d); + case_rrr(stx, _d); + case_wrr(stx, _d); + case_rr(mov, _d); + case jit_code_movi_d: + assert_data(node); + movi_d(rn(node->u.w), node->v.d); + break; + case_rr(ext, _f_d); + case_rrr(lt, _d); + case_rrd(lt); + case_rrr(le, _d); + case_rrd(le); + case_rrr(eq, _d); + case_rrd(eq); + case_rrr(ge, _d); + case_rrd(ge); + case_rrr(gt, _d); + case_rrd(gt); + case_rrr(ne, _d); + case_rrd(ne); + case_rrr(unlt, _d); + case_rrd(unlt); + case_rrr(unle, _d); + case_rrd(unle); + case_rrr(uneq, _d); + case_rrd(uneq); + case_rrr(unge, _d); + case_rrd(unge); + case_rrr(ungt, _d); + case_rrd(ungt); + case_rrr(ltgt, _d); + case_rrd(ltgt); + case_rrr(ord, _d); + case_rrd(ord); + case_rrr(unord, _d); + case_rrd(unord); + case_brr(blt, _d); + case_brd(blt); + case_brr(ble, _d); + case_brd(ble); + case_brr(beq, _d); + case_brd(beq); + case_brr(bge, _d); + case_brd(bge); + case_brr(bgt, _d); + case_brd(bgt); + case_brr(bne, _d); + case_brd(bne); + case_brr(bunlt, _d); + case_brd(bunlt); + case_brr(bunle, _d); + case_brd(bunle); + case_brr(buneq, _d); + case_brd(buneq); + case_brr(bunge, _d); + case_brd(bunge); + case_brr(bungt, _d); + case_brd(bungt); + case_brr(bltgt, _d); + case_brd(bltgt); + case_brr(bord, _d); + case_brd(bord); + case_brr(bunord, _d); + case_brd(bunord); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + break; + case jit_code_jmpi: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } + } + else + jmpi(node->u.w); + break; + case jit_code_callr: + callr(rn(node->u.w)); + break; + case jit_code_calli: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + calli(temp->u.w); + else { + word = calli_p(_jit->pc.w); + patch(word, node); + } + } + else + calli(node->u.w); + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif + undo.patch_offset = _jitc->patches.offset; + restart_function: + _jitc->again = 0; + prolog(node); + break; + case jit_code_epilog: + assert(_jitc->function == _jitc->functions.ptr + node->w.w); + if (_jitc->again) { + for (temp = undo.node->next; + temp != node; temp = temp->next) { + if (temp->code == jit_code_label || + temp->code == jit_code_epilog) + temp->flag &= ~jit_flag_patch; + } + temp->flag &= ~jit_flag_patch; + node = undo.node; + _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif + _jitc->patches.offset = undo.patch_offset; + goto restart_function; + } + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + epilog(node); + _jitc->function = NULL; + break; + case jit_code_movr_w_f: + movr_w_f(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movr_f_w: + movr_f_w(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movi_f_w: + assert_data(node); + movi_f_w(rn(node->u.w), node->v.f); + break; + case jit_code_movr_w_d: + movr_w_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movr_d_w: + movr_d_w(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movi_d_w: + assert_data(node); + movi_d_w(rn(node->u.w), node->v.d); + break; + case jit_code_va_start: + vastart(rn(node->u.w)); + break; + case jit_code_va_arg: + vaarg(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_va_arg_d: + vaarg_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_live: case jit_code_ellipsis: + case jit_code_va_push: + case jit_code_allocai: case jit_code_allocar: + case jit_code_arg: + case jit_code_arg_f: case jit_code_arg_d: + case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: case jit_code_getarg_ui: + case jit_code_getarg_l: + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: + case jit_code_retval_ui: case jit_code_retval_l: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: + break; + default: + abort(); + } + if (jit_carry != _NOREG) { + switch (node->code) { + case jit_code_note: + case jit_code_addcr: case jit_code_addci: + case jit_code_addxr: case jit_code_addxi: + case jit_code_subcr: case jit_code_subci: + case jit_code_subxr: case jit_code_subxi: + break; + default: + jit_unget_reg(jit_carry); + jit_carry = _NOREG; + break; + } + } + jit_regarg_clr(node, value); + assert(_jitc->regarg == 0 || + (jit_carry != _NOREG && _jitc->regarg == (1 << jit_carry))); + assert(_jitc->synth == 0); + /* update register live state */ + jit_reglive(node); + } +#undef case_brw +#undef case_brr +#undef case_wrr +#undef case_rrw +#undef case_rrr +#undef case_wr +#undef case_rw +#undef case_rr + + for (offset = 0; offset < _jitc->patches.offset; offset++) { + node = _jitc->patches.ptr[offset].node; + word = _jitc->patches.ptr[offset].inst; + value = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(word, value); + } + + jit_flush(_jit->code.ptr, _jit->pc.uc); + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_riscv-cpu.c" +# include "jit_riscv-fpu.c" +#undef CODE + +void +jit_flush(void *fptr, void *tptr) +{ +#if defined(__GNUC__) + jit_word_t f, t, s; + + s = sysconf(_SC_PAGE_SIZE); + f = (jit_word_t)fptr & -s; + t = (((jit_word_t)tptr) + s - 1) & -s; + __clear_cache((void *)f, (void *)t); +#endif +} + +void +_emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi(rn(r0), rn(r1), i0); +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi(i0, rn(r0), rn(r1)); +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi_d(rn(r0), rn(r1), i0); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi_d(i0, rn(r0), rn(r1)); +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) + flag = node->v.n->flag; + else + flag = node->u.n->flag; + assert(!(flag & jit_flag_patch)); + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} diff --git a/deps/lightning/lib/jit_s390-cpu.c b/deps/lightning/lib/jit_s390-cpu.c new file mode 100644 index 0000000..02cac60 --- /dev/null +++ b/deps/lightning/lib/jit_s390-cpu.c @@ -0,0 +1,3848 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# if __WORDSIZE == 32 +# define ldr(r0,r1) ldr_i(r0,r1) +# define ldxr(r0,r1,r2) ldxr_i(r0,r1,r2) +# define ldxi(r0,r1,i0) ldxi_i(r0,r1,i0) +# define stxi(i0,r0,r1) stxi_i(i0,r0,r1) +# else +# define ldr(r0,r1) ldr_l(r0,r1) +# define ldxr(r0,r1,r2) ldxr_l(r0,r1,r2) +# define ldxi(r0,r1,i0) ldxi_l(r0,r1,i0) +# define stxi(i0,r0,r1) stxi_l(i0,r0,r1) +# endif +# define is(i) *_jit->pc.us++ = i +# if __WORDSIZE == 32 +# define stack_framesize 96 +# else +# define stack_framesize 160 +# endif +# define _R0_REGNO 0 +# define _R1_REGNO 1 +# define _R7_REGNO 7 +# define _R13_REGNO 13 +# define _FP_REGNO _R13_REGNO +# define _R14_REGNO 14 +# define _R15_REGNO 15 +# define u12_p(i0) ((i0) >= 0 && (i0) <= 4095) +# define s16_p(i0) ((i0) >= -32768 && (i0) <= 32767) +# define x16(i0) ((i0) & 0xffff) +# define s20_p(i0) ((i0) >= -524288 && (i0) <= 524287) +# define x20(i0) ((i0) & 0xfffff) +# if __WORDSIZE == 32 +# define s32_p(i0) 1 +# else +# define s32_p(i0) \ + ((i0) >= -2147483648L && (i0) < 2147483647L) +# endif + +/* + Condition Code Instruction (Mask) Bit Mask Value + 0 8 8 + 1 9 4 + 2 10 2 + 3 11 1 + +AGR: + 0 Zero + 1 < zero + 2 > zero + 3 Overflow +-- +1 -> overflow CC_O +14 -> no overflow CC_NO + +ALGR: + 0 Zero, no carry + 1 Not zero, no carry + 2 Zero, carry + 3 Not zero, carry +-- +2|1 -> carry CC_NLE +8|4 -> no carry CC_LE + +SGR: + 0 Zero + 1 < zero + 2 > zero + 3 Overflow +-- +1 -> overflow CC_O +14 -> no overflow CC_NO + +SLGR: + 0 -- + 1 Not zero, borrow + 2 Zero, no borrow + 3 Not zero, no borrow +-- +4 -> borrow CC_L +11 -> no borrow CC_NL + */ + +# define CC_NV 0x0 +# define CC_O 0x1 +# define CC_H 0x2 +# define CC_NLE 0x3 +# define CC_L 0x4 +# define CC_NHE 0x5 +# define CC_LH 0x6 +# define CC_NE 0x7 +# define CC_E 0x8 +# define CC_NLH 0x9 +# define CC_HE 0xA +# define CC_NL 0xB +# define CC_LE 0xC +# define CC_NH 0xD +# define CC_NO 0xE +# define CC_AL 0xF +# define _us jit_uint16_t +# define _ui jit_uint32_t +# define E_(Op) _E(_jit,Op) +static void _E(jit_state_t*,_ui); +# define I_(Op,I) _I(_jit,Op,I) +static void _I(jit_state_t*,_ui,_ui); +# define RR_(Op,R1,R2) _RR(_jit,Op,R1,R2) +static void _RR(jit_state_t*,_ui,_ui,_ui); +# define RRE_(Op,R1,R2) _RRE(_jit,Op,R1,R2) +static void _RRE(jit_state_t*,_ui,_ui,_ui); +# define RRF_(Op,R3,M4,R1,R2) _RRF(_jit,Op,R3,M4,R1,R2) +static void _RRF(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# define RX_(Op,R1,X2,B2,D2) _RX(_jit,Op,R1,X2,B2,D2) +static void _RX(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# define RXE_(Op,R1,X2,B2,D2,Op2) _RXE(_jit,Op,R1,X2,B2,D2,Op2) +static void _RXE(jit_state_t*,_ui,_ui,_ui,_ui,_ui,_ui); +# define RXF_(Op,R3,X2,B2,D2,R1,Op2) _RXF(_jit,Op,R3,X2,B2,D2,R1,Op2) +static void _RXF(jit_state_t*,_ui,_ui,_ui,_ui,_ui,_ui,_ui); +# define RXY_(Op,R1,X2,B2,D2,Op2) _RXY(_jit,Op,R1,X2,B2,D2,Op2) +static void _RXY(jit_state_t*,_ui,_ui,_ui,_ui,_ui,_ui); +# define RS_(Op,R1,R3,B2,D2) _RS(_jit,Op,R1,R3,B2,D2) +static void _RS(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# define RSY_(Op,R1,R3,B2,D2,Op2) RXY_(Op,R1,R3,B2,D2,Op2) +# define RSL_(Op,L1,B1,D1,Op2) _RSL(_jit,Op,L1,B1,D1,Op2) +static void _RSL(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# define RSI_(Op,R1,R3,I2) _RSI(_jit,Op,R1,R3,I2) +static void _RSI(jit_state_t*,_ui,_ui,_ui,_ui); +# define RI_(Op,R1,Op2,I2) RSI_(Op,R1,Op2,I2) +# define RIE_(Op,R1,R3,I2,Op2) _RIE(_jit,Op,R1,R3,I2,Op2) +static void _RIE(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# define RIL_(Op,R1,Op2,I2) _RIL(_jit,Op,R1,Op2,I2) +static void _RIL(jit_state_t*,_ui,_ui,_ui,_ui); +# define SI_(Op,I2,B1,D1) _SI(_jit,Op,I2,B1,D1) +static void _SI(jit_state_t*,_ui,_ui,_ui,_ui); +# define SIY_(Op,I2,B1,D1,Op2) _SIY(_jit,Op,I2,B1,D1,Op2) +static void _SIY(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# define S_(Op,B2,D2) _S(_jit,Op,B2,D2) +static void _S(jit_state_t*,_ui,_ui,_ui); +# define SSL_(Op,L,B1,D1,B2,D2) SS_(Op,(L)>>4,(L)&0xF,B1,D1,B2,D2) +# define SS_(Op,LL,LH,B1,D1,B2,D2) _SS(_jit,Op,LL,LH,B1,D1,B2,D2) +static void _SS(jit_state_t*,_ui,_ui,_ui,_ui,_ui,_ui,_ui); +# define SSE_(Op,B1,D1,B2,D2) _SSE(_jit,Op,B1,D1,B2,D2) +static void _SSE(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# undef _us +# undef _ui +# define nop(c) _nop(_jit,c) +static void _nop(jit_state_t*,jit_int32_t); +# if __WORDSIZE == 32 +# define ADD_(r0,r1) AR(r0,r1) +# define ADDI_(r0,i0) AHI(r0,i0) +# define ADDC_(r0,r1) ALR(r0,r1) +# define ADDX_(r0,r1) ALCR(r0,r1) +# define AND_(r0,r1) NR(r0,r1) +# define CMP_(r0,r1) CR(r0,r1) +# define CMPU_(r0,r1) CLR(r0,r1) +# define DIVREM_(r0,r1) DR(r0,r1) +# define DIVREMU_(r0,r1) DLR(r0,r1) +# define OR_(r0,r1) OR(r0,r1) +# define MUL_(r0,r1) MSR(r0,r1) +# define MULI_(r0,i0) MHI(r0,i0) +# define MULU_(r0,r1) MLR(r0,r1) +# define SUB_(r0,r1) SR(r0,r1) +# define SUBC_(r0,r1) SLR(r0,r1) +# define SUBX_(r0,r1) SLBR(r0,r1) +# define TEST_(r0,r1) LTR(r0,r1) +# define XOR_(r0,r1) XR(r0,r1) +# else +# define ADD_(r0,r1) AGR(r0,r1) +# define ADDI_(r0,i0) AGHI(r0,i0) +# define ADDC_(r0,r1) ALGR(r0,r1) +# define ADDX_(r0,r1) ALCGR(r0,r1) +# define AND_(r0,r1) NGR(r0,r1) +# define CMP_(r0,r1) CGR(r0,r1) +# define CMPU_(r0,r1) CLGR(r0,r1) +# define DIVREM_(r0,r1) DSGR(r0,r1) +# define DIVREMU_(r0,r1) DLGR(r0,r1) +# define MUL_(r0,r1) MSGR(r0,r1) +# define MULI_(r0,i0) MGHI(r0,i0) +# define MULU_(r0,r1) MLGR(r0,r1) +# define OR_(r0,r1) OGR(r0,r1) +# define SUB_(r0,r1) SGR(r0,r1) +# define SUBC_(r0,r1) SLGR(r0,r1) +# define SUBX_(r0,r1) SLBGR(r0,r1) +# define TEST_(r0,r1) LTGR(r0,r1) +# define XOR_(r0,r1) XGR(r0,r1) +# endif +/**************************************************************** + * General Instructions * + ****************************************************************/ +/* ADD */ +# define AR(R1,R2) RR_(0x1A,R1,R2) +# define AGR(R1,R2) RRE_(0xB908,R1,R2) +# define AGFR(R1,R2) RRE_(0xB918,R1,R2) +# define A(R1,D2,X2,B2) RX_(0x5A,R1,X2,B2,D2) +# define AY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x5A) +# define AG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x08) +# define AGF(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x18) +/* ADD HALFWORD */ +# define AH(R1,D2,X2,B2) RX_(0x4A,R1,X2,B2,D2) +# define AHY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x7A) +/* ADD HALFWORD IMMEDIATE */ +# define AHI(R1,I2) RI_(0xA7,R1,0xA,I2) +# define AGHI(R1,I2) RI_(0xA7,R1,0xB,I2) +/* ADD LOGICAL */ +# define ALR(R1,R2) RR_(0x1E,R1,R2) +# define ALGR(R1,R2) RRE_(0xB90A,R1,R2) +# define ALGFR(R1,R2) RRE_(0xB91A,R1,R2) +# define AL(R1,D2,X2,B2) RX_(0x5E,R1,X2,B2,D2) +# define ALY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x5E) +# define ALG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x0A) +# define ALGF(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x1A) +/* ADD LOGICAL WITH CARRY */ +# define ALCR(R1,R2) RRE_(0xB998,R1,R2) +# define ALCGR(R1,R2) RRE_(0xB988,R1,R2) +# define ALC(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x98) +# define ALCG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x88) +/* AND */ +# define NR(R1,R2) RR_(0x14,R1,R2) +# define NGR(R1,R2) RRE_(0xB980,R1,R2) +# define N(R1,D2,X2,B2) RX_(0x54,R1,X2,B2,D2) +# define NY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x54) +# define NG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x80) +# define NI(D1,B1,I2) SI_(0x94,I2,B1,D1) +# define NIY(D1,B1,I2) SIY_(0xEB,I2,B1,D1,0x54) +# define NC(D1,L,B1,D2,B2) SSL_(0xD4,L,B1,D1,B2,D2) +/* AND IMMEDIATE */ +# define NIHH(R1,I2) RI_(0xA5,R1,0x4,I2) +# define NIHL(R1,I2) RI_(0xA5,R1,0x5,I2) +# define NILH(R1,I2) RI_(0xA5,R1,0x6,I2) +# define NILL(R1,I2) RI_(0xA5,R1,0x7,I2) +/* BRANCH AND LINK */ +# define BALR(R1,R2) RR_(0x05,R1,R2) +# define BAL(R1,D2,X2,B2) RX_(0x45,R1,X2,B2,D2) +/* BRANCH AND SAVE */ +# define BASR(R1,R2) RR_(0x0D,R1,R2) +# define BAS(R1,D2,X2,B2) RX_(0x4D,R1,X2,B2,D2) +/* BRANCH AND SAVE AND SET MODE */ +# define BASSM(R1,R2) RR_(0x0C,R1,R2) +/* BRANCH AND SET MODE */ +# define BSM(R1,R2) RR_(0x0B,R1,R2) +/* BRANCH ON CONDITION */ +# define BCR(M1,R2) RR_(0x07,M1,R2) +# define BR(R2) BCR(CC_AL,R2) +# define NOPR(R2) BCR(CC_NV,R2) +# define BC(M1,D2,X2,B2) RX_(0x47,M1,X2,B2,D2) +/* BRANCH ON COUNT */ +# define BCTR(R1,R2) RR_(0x06,R1,R2) +# define BCTGR(R1,R2) RRE_(0xB946,R1,R2) +# define BCT(R1,D2,X2,B2) RX_(0x46,R1,X2,B2,D2) +# define BCTG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x46) +/* BRANCH ON INDEX HIGH */ +# define BXH(R1,R3,D2,B2) RS_(0x86,R1,R3,B2,D2) +# define BXHG(R1,R3,B2,D2) RSY_(0xEB,R1,R3,B2,D2,0x44) +/* BRANCH ON INDEX LOW OR EQUAL */ +# define BXLE(R1,R3,D2,B2) RS_(0x87,R1,R3,B2,D2) +# define BXLEG(R1,R3,B2,D2) RSY_(0xEB,R1,R3,B2,D2,0x45) +/* BRANCH RELATIVE AND SAVE */ +# define BRAS(R1,I2) RI_(0xA7,R1,0x5,I2) +/* BRANCH RELATIVE AND SAVE LONG */ +# define BRASL(R1,I2) RIL_(0xC0,R1,0x5,I2) +/* BRANCH RELATIVE ON CONDITION */ +# define BRC(M1,I2) RI_(0xA7,M1,0x4,I2) +# define J(I2) BRC(CC_AL,I2) +/* BRANCH RELATIVE ON CONDITION LONG */ +# define BRCL(M1,I2) RIL_(0xC0,M1,0x4,I2) +# define BRL(I2) BRCL(CC_AL,I2) +/* BRANCH RELATIVE ON COUNT */ +# define BRCT(M1,I2) RI_(0xA7,M1,0x6,I2) +# define BRCTG(M1,I2) RI_(0xA7,M1,0x7,I2) +/* BRANCH RELATIVE ON INDEX HIGH */ +# define BRXH(R1,R3,I2) RSI_(0x84,R1,R3,I2) +# define BRXHG(R1,R3,I2) RIE_(0xEC,R1,R3,I2,0x44) +/* BRANCH RELATIVE ON INDEX LOW OR EQUAL */ +# define BRXLE(R1,R3,I2) RSI_(0x85,R1,R3,I2) +# define BRXLEG(R1,R3,I2) RIE_(0xEC,R1,R3,I2,0x45) +/* CHECKSUM */ +# define CKSUM(R1,R2) RRE_(0xB241,R1,R2) +/* CIPHER MESAGE (KM) */ +# define KM(R1,R2) RRE_(0xB92E,R1,R2) +/* CIPHER MESAGE WITH CHAINING (KMC) */ +# define KMC(R1,R2) RRE_(0xB92F,R1,R2) +/* COMPARE */ +# define CR(R1,R2) RR_(0x19,R1,R2) +# define CGR(R1,R2) RRE_(0xB920,R1,R2) +# define CGFR(R1,R2) RRE_(0xB930,R1,R2) +# define C(R1,D2,X2,B2) RX_(0x59,R1,X2,B2,D2) +# define CY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x59) +# define CG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x20) +# define CGF(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x30) +/* COMPARE AND FORM CODEWORD */ +# define CFC(D2,B2) S_(0xB21A,B2,D2) +/* COMPARE AND SWAP */ +# define CS(R1,R3,D2,B2) RS_(0xBA,R1,R3,B2,D2) +# define CSY(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x14) +# define CSG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x30) +/* COMPARE DOUBLE AND SWAP */ +# define CDS(R1,R3,D2,B2) RS_(0xBB,R1,R3,B2,D2) +# define CSDY(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x31) +# define CSDG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x3E) +/* COMPARE HALFWORD */ +# define CH(R1,D2,X2,B2) RX_(0x49,R1,X2,B2,D2) +# define CHY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x79) +/* COMPARE HALFWORD IMMEDIATE */ +# define CHI(R1,I2) RI_(0xA7,R1,0xE,I2) +# define CGHI(R1,I2) RI_(0xA7,R1,0xF,I2) +/* COMPARE LOGICAL */ +# define CLR(R1,R2) RR_(0x15,R1,R2) +# define CLGR(R1,R2) RRE_(0xB921,R1,R2) +# define CLGFR(R1,R2) RRE_(0xB931,R1,R2) +# define CL(R1,D2,X2,B2) RX_(0x55,R1,X2,B2,D2) +# define CLY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x55) +# define CLG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x21) +# define CLGF(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x31) +# define CLI(D1,B1,I2) SI_(0x95,I2,B1,D1) +# define CLIY(D1,B1,I2) SIY_(0xEB,I2,B1,D1,0x55) +# define CLC(D1,L,B1,D2,B2) SSL_(0xD5,L,B1,D1,B2,D2) +/* COMPARE LOGICAL CHARACTERS UNDER MASK */ +# define CLM(R1,M3,D2,B2) RS_(0xBD,R1,M3,B2,D2) +# define CLMY(R1,M3,D2,B2) RSY_(0xEB,R1,M3,B2,D2,0x21) +# define CLMH(R1,M3,D2,B2) RSY_(0xEB,R1,M3,B2,D2,0x20) +/* COMPARE LOGICAL LONG */ +# define CLCL(R1,R2) RR_(0x0F,R1,R2) +/* COMPARE LOGICAL LONG EXTENDED */ +# define CLCLE(R1,R3,D2,B2) RS_(0xA9,R1,R3,B2,D2) +/* COMPARE LOGICAL LONG UNICODE */ +# define CLCLU(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x8F) +/* COMPARE LOGICAL STRING */ +# define CLST(R1,R2) RRE_(0xB25D,R1,R2) +/* COMPARE UNTIL SUBSTRING EQUAL */ +# define CUSE(R1,R2) RRE_(0xB257,R1,R2) +/* COMPRESSION CALL */ +# define CMPSC(R1,R2) RRE_(0xB263,R1,R2) +/* COMPUTE INTERMEDIATE MESSAGE DIGEST (KIMD) */ +# define KIMD(R1,R2) RRE_(0xB93E,R1,R2) +/* COMPUTE LAST MESSAGE DIGEST (KIMD) */ +# define KLMD(R1,R2) RRE_(0xB93F,R1,R2) +/* COMPUTE MESSAGE AUTHENTICATION CODE (KMAC) */ +# define KMAC(R1,R2) RRE_(0xB91E,R1,R2) +/* CONVERT TO BINARY */ +# define CVB(R1,D2,X2,B2) RX_(0x4F,R1,X2,B2,D2) +# define CVBY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x06) +# define CVBG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x0e) +/* CONVERT TO DECIMAL */ +# define CVD(R1,D2,X2,B2) RX_(0x4E,R1,X2,B2,D2) +# define CVDY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x26) +# define CVDG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x2E) +/* CONVERT UNICODE TO UTF-8 */ +# define CUUTF(R1,R2) RRE_(0xB2A6,R1,R2) +/* CONVERT UTF-8 TO UNICODE */ +# define CUTFU(R1,R2) RRE_(0xB2A7,R1,R2) +/* COPY ACCESS */ +# define CPYA(R1,R2) RRE_(0xB24D,R1,R2) +/* DIVIDE */ +# define DR(R1,R2) RR_(0x1D,R1,R2) +# define D(R1,D2,X2,B2) RX_(0x5D,R1,X2,B2,D2) +/* DIVIDE LOGICAL */ +# define DLR(R1,R2) RRE_(0xB997,R1,R2) +# define DLGR(R1,R2) RRE_(0xB987,R1,R2) +# define DL(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x97) +# define DLG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x87) +/* DIVIDE SINGLE */ +# define DSGR(R1,R2) RRE_(0xB90D,R1,R2) +# define DSGFR(R1,R2) RRE_(0xB91D,R1,R2) +# define DSG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x0D) +# define DSGF(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x1D) +/* EXCLUSIVE OR */ +# define XR(R1,R2) RR_(0x17,R1,R2) +# define XGR(R1,R2) RRE_(0xB982,R1,R2) +# define X(R1,D2,X2,B2) RX_(0x57,R1,X2,B2,D2) +# define XY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x57) +# define XG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x82) +# define XI(D1,B1,I2) SI_(0x97,I2,B1,D1) +# define XIY(D1,B1,I2) SIY_(0xEB,I2,B1,D1,0x57) +# define XC(D1,L,B1,D2,B2) SSL_(0xD7,L,B1,D1,B2,D2) +/* EXECUTE */ +# define EX(R1,D2,X2,B2) RX_(0x44,R1,X2,B2,D2) +/* EXTRACT ACCESS */ +# define EAR(R1,R2) RRE_(0xB24F,R1,R2) +/* EXTRACT PSW */ +# define EPSW(R1,R2) RRE_(0xB98D,R1,R2) +/* INSERT CHARACTER */ +# define IC(R1,D2,X2,B2) RX_(0x43,R1,X2,B2,D2) +# define ICY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x73) +/* INSERT CHARACTERS UNDER MASK */ +# define ICM(R1,M3,D2,B2) RS_(0xBF,R1,M3,B2,D2) +# define ICMY(R1,M3,D2,B2) RSY_(0xEB,R1,M3,B2,D2,0x81) +# define ICMH(R1,M3,D2,B2) RSY_(0xEB,R1,M3,B2,D2,0x80) +/* INSERT IMMEDIATE */ +# define IIHH(R1,I2) RI_(0xA5,R1,0x0,I2) +# define IIHL(R1,I2) RI_(0xA5,R1,0x1,I2) +# define IILH(R1,I2) RI_(0xA5,R1,0x2,I2) +# define IILL(R1,I2) RI_(0xA5,R1,0x3,I2) +/* INSERT PROGRAM MASK */ +# define IPM(R1) RRE_(0xB222,R1,0) +/* LOAD */ +# define LR(R1,R2) RR_(0x18,R1,R2) +# define LGR(R1,R2) RRE_(0xB904,R1,R2) +# define LGFR(R1,R2) RRE_(0xB914,R1,R2) +# define L(R1,D2,X2,B2) RX_(0x58,R1,X2,B2,D2) +# define LY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x58) +# define LG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x04) +# define LGF(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x14) +/* LOAD ACCESS MULTIPLE */ +# define LAM(R1,R3,D2,B2) RS_(0x9A,R1,R3,B2,D2) +# define LAMY(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x9A) +/* LOAD ADDRESS */ +# define LA(R1,D2,X2,B2) RX_(0x41,R1,X2,B2,D2) +# define LAY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x71) +/* LOAD ADDRESS EXTENDED */ +# define LAE(R1,D2,X2,B2) RX_(0x51,R1,X2,B2,D2) +/* LOAD ADDRESS RELATIVE LONG */ +# define LARL(R1,I2) RIL_(0xC0,R1,0x0,I2) +/* LOAD AND TEST */ +# define LTR(R1,R2) RR_(0x12,R1,R2) +# define LTGR(R1,R2) RRE_(0xB902,R1,R2) +# define LTGFR(R1,R2) RRE_(0xB912,R1,R2) +/* LOAD BYTE */ +# define LGBR(R1,R2) RRE_(0xB906,R1,R2) /* disasm */ +# define LB(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x76) +# define LGB(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x77) +/* LOAD COMPLEMENT */ +# define LCR(R1,R2) RR_(0x13,R1,R2) +# define LCGR(R1,R2) RRE_(0xB903,R1,R2) +# define LCGFR(R1,R2) RRE_(0xB913,R1,R2) +/* LOAD HALFWORD */ +# define LH(R1,D2,X2,B2) RX_(0x48,R1,X2,B2,D2) +# define LHY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x78) +# define LGHR(R1,R2) RRE_(0xB907,R1,R2) /* disasm */ +# define LGH(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x15) +/* LOAD HALFWORD IMMEDIATE */ +# define LHI(R1,I2) RI_(0xA7,R1,0x8,I2) +# define LGHI(R1,I2) RI_(0xA7,R1,0x9,I2) +/* LOAD LOGICAL */ +# define LLGFR(R1,R2) RRE_(0xB916,R1,R2) +# define LLGF(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x16) +/* LOAD LOGICAL CHARACTER */ +# define LLGCR(R1,R2) RRE_(0xB984,R1,R2) /* disasm */ +# define LLGC(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x90) +/* LOAD LOGICAL HALFWORD */ +# define LLGHR(R1,R2) RRE_(0xB985,R1,R2) /* disasm */ +# define LLGH(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x91) +/* LOAD LOGICAL IMMEDIATE */ +# define LLIHH(R1,I2) RI_(0xA5,R1,0xC,I2) +# define LLIHL(R1,I2) RI_(0xA5,R1,0xD,I2) +# define LLILH(R1,I2) RI_(0xA5,R1,0xE,I2) +# define LLILL(R1,I2) RI_(0xA5,R1,0xF,I2) +/* LOAD LOGICAL THIRTY ONE BITS */ +# define LLGTR(R1,R2) RRE_(0xB917,R1,R2) +# define LLGT(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x17) +/* LOAD MULTIPLE */ +# define LM(R1,R3,D2,B2) RS_(0x98,R1,R3,B2,D2) +# define LMY(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x98) +# define LMG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x04) +/* LOAD MULTIPLE DISJOINT */ +# define LMD(R1,R3,D2,B2,D4,B4) SS_(0xEF,R1,R3,B2,D2,B4,D4) +/* LOAD MULTIPLE HIGH */ +# define LMH(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x96) +/* LOAD NEGATIVE */ +# define LNR(R1,R2) RR_(0x11,R1,R2) +# define LNGR(R1,R2) RRE_(0xB901,R1,R2) +# define LNGFR(R1,R2) RRE_(0xB911,R1,R2) +/* LOAD PAIR FROM QUADWORD */ +# define LPQ(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x8F) +/* LOAD POSITIVE */ +# define LPR(R1,R2) RR_(0x10,R1,R2) +# define LPGR(R1,R2) RRE_(0xB900,R1,R2) +# define LPGFR(R1,R2) RRE_(0xB910,R1,R2) +/* LOAD REVERSED */ +# define LRVR(R1,R2) RRE_(0xB91F,R1,R2) +# define LRVGR(R1,R2) RRE_(0xB90F,R1,R2) +# define LRVH(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x1F) +# define LRV(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x1E) +# define LRVG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x0F) +/* MONITOR CALL */ +# define MC(D1,B1,I2) SI_(0xAF,I2,B1,D1) +/* MOVE */ +# define MVI(D1,B1,I2) SI_(0x92,I2,B1,D1) +# define MVIY(D1,B1,I2) SIY_(0xEB,I2,B1,D1,0x52) +# define MVC(D1,L,B1,D2,B2) SSL_(0xD2,L,B1,D1,B2,D2) +/* MOVE INVERSE */ +# define MVCIN(D1,L,B1,D2,B2) SSL_(0xE8,L,B1,D1,B2,D2) +/* MOVE LONG */ +# define MVCL(R1,R2) RR_(0x0E,R1,R2) +/* MOVE LONG EXTENDED */ +# define MVCLE(R1,R3,D2,B2) RS_(0xA8,R1,R3,B2,D2) +/* MOVE LONG UNICODE */ +# define MVCLU(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x8E) +/* MOVE NUMERICS */ +# define MVN(D1,L,B1,D2,B2) SSL_(0xD1,L,B1,D1,B2,D2) +/* MOVE STRING */ +# define MVST(R1,R2) RRE_(0xB255,R1,R2) +/* MOVE WITH OFFSET */ +# define MVO(D1,L1,B1,D2,L2,B2) SS_(0xF1,L1,L2,B1,D1,B2,D2) +/* MOVE ZONES */ +# define MVZ(D1,L,B1,D2,B2) SSL_(0xD3,L,B1,D1,B2,D2) +/* MULTIPLY */ +# define MR(R1,R2) RR_(0x1C,R1,R2) +# define M(R1,D2,X2,B2) RX_(0x5C,R1,X2,B2,D2) +/* MULTIPLY HALFWORD */ +# define MH(R1,D2,X2,B2) RX_(0x4C,R1,X2,B2,D2) +/* MULTIPLY HALFWORD IMMEDIATE */ +# define MHI(R1,I2) RI_(0xA7,R1,0xC,I2) +# define MGHI(R1,I2) RI_(0xA7,R1,0xD,I2) +/* MULTIPLY LOGICAL */ +# define MLR(R1,R2) RRE_(0xB996,R1,R2) +# define MLGR(R1,R2) RRE_(0xB986,R1,R2) +# define ML(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x96) +# define MLG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x86) +/* MULTIPLY SINGLE */ +# define MSR(R1,R2) RRE_(0xB252,R1,R2) +# define MSGR(R1,R2) RRE_(0xB90C,R1,R2) +# define MSGFR(R1,R2) RRE_(0xB91C,R1,R2) +# define MS(R1,D2,X2,B2) RX_(0x71,R1,X2,B2,D2) +# define MSY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x51) +# define MSG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x0C) +# define MSGF(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x1C) +/* OR */ +# define OR(R1,R2) RR_(0x16,R1,R2) +# define OGR(R1,R2) RRE_(0xB981,R1,R2) +# define O(R1,D2,X2,B2) RX_(0x56,R1,X2,B2,D2) +# define OY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x56) +# define OG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x81) +# define OI(D1,B1,I2) SI_(0x96,I2,B1,D1) +# define OIY(D1,B1,I2) SIY_(0xEB,I2,B1,D1,0x56) +# define OC(D1,L,B1,D2,B2) SSL_(0xD6,L,B1,D1,B2,D2) +/* OR IMMEDIATE */ +# define OIHH(R1,I2) RI_(0xA5,R1,0x8,I2) +# define OIHL(R1,I2) RI_(0xA5,R1,0x9,I2) +# define OILH(R1,I2) RI_(0xA5,R1,0xA,I2) +# define OILL(R1,I2) RI_(0xA5,R1,0xB,I2) +/* PACK */ +# define PACK(D1,L1,B1,D2,L2,B2) SS_(0xF2,L1,L2,B1,D1,B2,D2) +/* PACK ASCII */ +# define PKA(D1,B1,D2,L2,B2) SSL_(0xE9,L2,B1,D1,B2,D2) +/* PACK UNICODE */ +# define PKU(D1,B1,D2,L2,B2) SSL_(0xE1,L2,B1,D1,B2,D2) +/* PERFORM LOCKED OPERATION */ +# define PLO(R1,D2,B2,R3,D4,B4) SS_(0xEE,R1,R3,B2,D2,B4,D4) +/* ROTATE LEFT SINGLE LOGICAL */ +# define RLL(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x1D) +# define RLLG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x1C) +/* SEARCH STRING */ +# define SRST(R1,R2) RRE_(0xB25E,R1,R2) +/* SET ACCESS */ +# define SAR(R1,R2) RRE_(0xB24E,R1,R2) +/* SET ADDRESSING MODE */ +# define SAM24() E_(0x10C) +# define SAM31() E_(0x10D) +# define SAM64() E_(0x10E) +/* SET PROGRAM MASK */ +# define SPM(R1) RR_(0x04,R1,0) +/* SHIFT LEFT DOUBLE */ +# define SLDA(R1,D2,B2) RS_(0x8F,R1,0,B2,D2) +/* SHIFT LEFT DOUBLE LOGICAL */ +# define SLDL(R1,D2,B2) RS_(0x8D,R1,0,B2,D2) +/* SHIFT LEFT SINGLE */ +# define SLA(R1,D2,B2) RS_(0x8B,R1,0,B2,D2) +# define SLAG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x0B) +/* SHIFT LEFT SINGLE LOGICAL */ +# define SLL(R1,D2,B2) RS_(0x89,R1,0,B2,D2) +# define SLLG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x0D) +/* SHIFT RIGHT DOUBLE */ +# define SRDA(R1,D2,B2) RS_(0x8E,R1,0,B2,D2) +/* SHIFT RIGHT DOUBLE LOGICAL */ +# define SRDL(R1,D2,B2) RS_(0x8C,R1,0,B2,D2) +/* SHIFT RIGHT SINGLE */ +# define SRA(R1,D2,B2) RS_(0x8A,R1,0,B2,D2) +# define SRAG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x0A) +/* SHIFT RIGHT SINGLE LOGICAL */ +# define SRL(R1,D2,B2) RS_(0x88,R1,0,B2,D2) +# define SRLG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x0C) +/* STORE */ +# define ST(R1,D2,X2,B2) RX_(0x50,R1,X2,B2,D2) +# define STY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x50) +# define STG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x24) +/* STORE ACCESS MULTIPLE */ +# define STAM(R1,R3,D2,B2) RS_(0x9B,R1,R3,B2,D2) +# define STAMY(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x9B) +/* STORE CHARACTER */ +# define STC(R1,D2,X2,B2) RX_(0x42,R1,X2,B2,D2) +# define STCY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x72) +/* STORE CHARACTERS UNDER MASK */ +# define STCM(R1,M3,D2,B2) RS_(0xBE,R1,M3,B2,D2) +# define STCMY(R1,M3,D2,B2) RSY_(0xEB,R1,M3,B2,D2,0x2D) +# define STCMH(R1,M3,D2,B2) RSY_(0xEB,R1,M3,B2,D2,0x2C) +/* STORE CLOCK */ +# define STCK(D2,B2) S_(0xB205,B2,D2) +/* STORE CLOCK EXTENDED */ +# define STCKE(D2,B2) S_(0xB278,B2,D2) +/* STORE HALFWORD */ +# define STH(R1,D2,X2,B2) RX_(0x40,R1,X2,B2,D2) +# define STHY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x70) +/* STORE MULTIPLE */ +# define STM(R1,R3,D2,B2) RS_(0x90,R1,R3,B2,D2) +# define STMY(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x90) +# define STMG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x24) +/* STORE MULTIPLE HIGH */ +# define STMH(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x26) +/* STORE PAIR TO QUADWORD */ +# define STPQ(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x8E) +/* STORE REVERSED */ +# define STRVH(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x3F) +# define STRV(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x3E) +# define STRVG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x2F) +/* SUBTRACT */ +# define SR(R1,R2) RR_(0x1B,R1,R2) +# define SGR(R1,R2) RRE_(0xB909,R1,R2) +# define SGFR(R1,R2) RRE_(0xB919,R1,R2) +# define S(R1,D2,X2,B2) RX_(0x5B,R1,X2,B2,D2) +# define SY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x5B) +# define SG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x09) +# define SGF(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x19) +/* SUBTRACT HALFWORD */ +# define SH(R1,D2,X2,B2) RX_(0x4B,R1,X2,B2,D2) +# define SHY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x7B) +/* SUBTRACT LOGICAL */ +# define SLR(R1,R2) RR_(0x1F,R1,R2) +# define SLGR(R1,R2) RRE_(0xB90B,R1,R2) +# define SLGFR(R1,R2) RRE_(0xB91B,R1,R2) +# define SL(R1,D2,X2,B2) RX_(0x5F,R1,X2,B2,D2) +# define SLY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x5F) +# define SLG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x0B) +# define SLGF(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x1B) +/* SUBTRACT LOGICAL WITH BORROW */ +# define SLBR(R1,R2) RRE_(0xB999,R1,R2) +# define SLBGR(R1,R2) RRE_(0xB989,R1,R2) +# define SLB(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x99) +# define SLBG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x89) +/* SUPERVISOR CALL */ +# define SVC(I) I_(0xA,I) +/* TEST ADDRESSING MODE */ +# define TAM() E_(0x10B) +/* TEST AND SET */ +# define TS(D2,B2) RS_(0x93,0,0,B2,D2) +/* TEST UNDER MASK (TEST UNDER MASK HIGH, TEST UNDER MASK LOW) */ +# define TM(D1,B1,I2) SI_(0x91,I2,B1,D1) +# define TMY(D1,B1,I2) SIY_(0xEB,I2,B1,D1,0x51) +# define TMHH(R1,I2) RI_(0xA7,R1,0x2,I2) +# define TMHL(R1,I2) RI_(0xA7,R1,0x3,I2) +# define TMLH(R1,I2) RI_(0xA7,R1,0x0,I2) +# define TMH(R1,I2) TMLH(R1,I2) +# define TMLL(R1,I2) RI_(0xA7,R1,0x1,I2) +# define TML(R1,I2) TMLL(R1,I2) +/* TRANSLATE */ +# define TR(D1,L,B1,D2,B2) SSL_(0xDC,L,B1,D1,B2,D2) +/* TRANSLATE AND TEST */ +# define TRT(D1,L,B1,D2,B2) SSL_(0xDD,L,B1,D1,B2,D2) +/* TRANSLATE EXTENDED */ +# define TRE(R1,R2) RRE_(0xB2A5,R1,R2) +/* TRANSLATE ONE TO ONE */ +# define TROO(R1,R2) RRE_(0xB993,R1,R2) +/* TRANSLATE ONE TO TWO */ +# define TROT(R1,R2) RRE_(0xB992,R1,R2) +/* TRANSLATE TWO TO ONE */ +# define TRTO(R1,R2) RRE_(0xB991,R1,R2) +/* TRANSLATE TWO TO TWO */ +# define TRTT(R1,R2) RRE_(0xB990,R1,R2) +/* UNPACK */ +# define UNPK(D1,L1,B1,D2,L2,B2) SS_(0xF3,L1,L2,B1,D1,B2,D2) +/* UNPACK ASCII */ +# define UNPKA(D1,L1,B1,D2,L2,B2) SS_(0xEA,L1,L2,B1,D1,B2,D2) +/* UNPACK UNICODE */ +# define UNPKU(D1,L1,B1,D2,L2,B2) SS_(0xE2,L1,L2,B1,D1,B2,D2) +/* UPDATE TREE */ +# define UPT() E_(0x0102) +/**************************************************************** + * Decimal Instructions * + ****************************************************************/ +/* ADD DECIMAL */ +# define AP(D1,L1,B1,D2,L2,B2) SS_(0xFA,L1,L2,B1,D1,B2,D2) +/* COMPARE DECIMAL */ +# define CP(D1,L1,B1,D2,L2,B2) SS_(0xF9,L1,L2,B1,D1,B2,D2) +/* DIVIDE DECIMAL */ +# define DP(D1,L1,B1,D2,L2,B2) SS_(0xFD,L1,L2,B1,D1,B2,D2) +/* EDIT */ +# define ED(D1,L,B1,D2,B2) SSL_(0xDE,L,B1,D1,B2,D2) +/* EDIT AND MARK */ +# define EDMK(D1,L,B1,D2,B2) SSL_(0xDE,L,B1,D1,B2,D2) +/* MULTIPLY DECIMAL */ +# define MP(D1,L1,B1,D2,L2,B2) SS_(0xFC,L1,L2,B1,D1,B2,D2) +/* SHIFT AND ROUND DECIMAL */ +# define SRP(D1,L1,B1,D2,L2,B2) SS_(0xF0,L1,L2,B1,D1,B2,D2) +/* SUBTRACE DECIMAL */ +# define SP(D1,L1,B1,D2,L2,B2) SS_(0xFB,L1,L2,B1,D1,B2,D2) +/* TEST DECIMAL */ +# define TP(D1,L1,B1) RSL_(0xEB,L1,B1,D1,0xC0) +/* ZERO AND ADD */ +# define ZAP(D1,L1,B1,D2,L2,B2) SS_(0xF8,L1,L2,B1,D1,B2,D2) +/**************************************************************** + * Control Instructions * + ****************************************************************/ +/* BRANCH AND SET AUTHORITY */ +# define BSA(R1,R2) RRE_(0xB25A,R1,R2) +/* BRANCH AND STACK */ +# define BAKR(R1,R2) RRE_(0xB240,R1,R2) +/* BRANCH IN SUBSPACE GROUP */ +# define BSG(R1,R2) RRE_(0xB258,R1,R2) +/* COMPARE AND SWAP AND PURGE */ +# define CSP(R1,R2) RRE_(0xB250,R1,R2) +# define CSPG(R1,R2) RRE_(0xB98A,R1,R2) +/* DIAGNOSE */ +# define DIAG() SI_(0x83,0,0,0) +/* EXTRACT AND SET EXTENDED AUTHORITY */ +# define ESEA(R1) RRE_(0xB99D,R1,0) +/* EXTRACT PRIMARY ASN */ +# define EPAR(R1) RRE_(0xB226,R1,0) +/* EXTRACT SECONDARY ASN */ +# define ESAR(R1) RRE_(0xB227,R1,0) +/* EXTRACT STACKED REGISTERS */ +# define EREG(R1,R2) RRE_(0xB249,R1,R2) +# define EREGG(R1,R2) RRE_(0xB90E,R1,R2) +/* EXTRACT STACKED STATE */ +# define ESTA(R1,R2) RRE_(0xB24A,R1,R2) +/* INSERT ADDRESS SPACE CONTROL */ +# define IAC(R1) RRE_(0xB224,R1,0) +/* INSERT PSW KEY */ +# define IPK() S_(0xB20B,0,0) +/* INSERT STORAGE KEY EXTENDED */ +# define ISKE(R1,R2) RRE_(0xB229,R1,R2) +/* INSERT VIRTUAL STORAGE KEY */ +# define IVSK(R1,R2) RRE_(0xB223,R1,R2) +/* INVALIDATE DAT TABLE ENTRY */ +# define IDTE(R1,R2,R3) RRF_(0xB98E,R3,0,R1,R2) +/* INVALIDATE PAGE TABLE ENTRY */ +# define IPTE(R1,R2) RRE_(0xB221,R1,R2) +/* LOAD ADDRESS SPACE PARAMETER */ +# define LASP(D1,B1,D2,B2) SSE_(0xE500,B1,D1,B2,D2) +/* LOAD CONTROL */ +# define LCTL(R1,R3,D2,B2) RS_(0xB7,R1,R3,B2,D2) +# define LCTLG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x2F) +/* LOAD PSW */ +# define LPSW(D2,B2) SI_(0x82,0,B2,D2) +/* LOAD PSW EXTENDED */ +# define LPSWE(D2,B2) S_(0xB2B2,B2,D2) +/* LOAD REAL ADDRESS */ +# define LRA(R1,D2,X2,B2) RX_(0xB1,R1,X2,B2,D2) +# define LRAY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x13) +# define LRAG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x03) +/* LOAD USING REAL ADDRESS */ +# define LURA(R1,R2) RRE_(0xB24B,R1,R2) +# define LURAG(R1,R2) RRE_(0xB905,R1,R2) +/* MODIFY STACKED STATE */ +# define MSTA(R1) RRE_(0xB247,R1,0) +/* MOVE PAGE */ +# define MVPG(R1,R2) RRE_(0xB254,R1,R2) +/* MOVE TO PRIMARY */ +# define MVCP(D1,R1,B1,D2,B2,R3) SS_(0xDA,R1,R3,B1,D1,B2,D2) +/* MOVE TO SECONDARY */ +# define MVCS(D1,R1,B1,D2,B2,R3) SS_(0xDB,R1,R3,B1,D1,B2,D2) +/* MOVE WITH DESTINATION KEY */ +# define MVCDK(D1,B1,D2,B2) SSE_(0xE50F,B1,D1,B2,D2) +/* MOVE WITH KEY */ +# define MVCK(D1,R1,B1,D2,B2,R3) SS_(0xD9,R1,R3,B1,D1,B2,D2) +/* MOVE WITH SOURCE KEY */ +# define MVCSK(D1,B1,D2,B2) SSE_(0xE50E,B1,D1,B2,D2) +/* PAGE IN */ +# define PGIN(R1,R2) RRE_(0xB22E,R1,R2) +/* PAGE OUT */ +# define PGOUT(R1,R2) RRE_(0xB22F,R1,R2) +/* PROGRAM CALL */ +# define PC(D2,B2) S_(0xB218,B2,D2) +/* PROGRAM RETURN */ +# define PR() E_(0x0101) +/* PROGRAM TRANSFER */ +# define PT(R1,R2) RRE_(0xB228,R1,R2) +/* PURGE ALB */ +# define PALB() RRE_(0xB248,0,0) +/* PURGE TLB */ +# define PTLB() S_(0xB20D,0,0) +/* RESET REFERENCE BIT EXTENDED */ +# define RRBE(R1,R2) RRE_(0xB22A,R1,R2) +/* RESUME PROGRAM */ +# define RP(D2,B2) S_(0xB277,B2,D2) +/* SET ADDRESS SPACE CONTROL */ +# define SAC(D2,B2) S_(0xB219,B2,D2) +/* SET ADDRESS SPACE CONTROL FAST */ +# define SACF(D2,B2) S_(0xB279,B2,D2) +/* SET CLOCK */ +# define SCK(D2,B2) S_(0xB204,B2,D2) +/* SET CLOCK COMPARATOR */ +# define SCKC(D2,B2) S_(0xB206,B2,D2) +/* SET CLOCK PROGRAMMABLE FIELD */ +# define SCKPF() E_(0x0107) +/* SET CPU TIMER */ +# define SPT(D2,B2) S_(0xB208,B2,D2) +/* SET PREFIX */ +# define SPX(D2,B2) S_(0xB210,B2,D2) +/* SET PSW FROM ADDRESS */ +# define SPKA(D2,B2) S_(0xB20A,B2,D2) +/* SET SECONDARY ASN */ +# define SSAR(R1) RRE_(0xB225,R1,0) +/* SET STORAGE KEY EXTENDED */ +# define SSKE(R1,R2) RRE_(0xB22B,R1,R2) +/* SET SYSTEM MASK */ +# define SSM(D2,B2) SI_(0x80,0,B2,D2) +/* SIGNAL PROCESSOR */ +# define SIGP(R1,R3,D2,B2) RS_(0xAE,R1,R3,B2,D2) +/* STORE CLOCK COMPARATOR */ +# define STCKC(D2,B2) S_(0xB207,B2,D2) +/* STORE CONTROL */ +# define STCTL(R1,R3,D2,B2) RS_(0xB6,R1,R3,B2,D2) +# define STCTG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x25) +/* STORE CPU ADDRESS */ +# define STAP(D2,B2) S_(0xB212,B2,D2) +/* STORE CPU ID */ +# define STIDP(D2,B2) S_(0xB202,B2,D2) +/* STORE CPU TIMER */ +# define STPT(D2,B2) S_(0xB209,B2,D2) +/* STORE FACILITY LIST */ +# define STFL(D2,B2) S_(0xB2B1,B2,D2) +/* STORE PREFIX */ +# define STPX(D2,B2) S_(0xB211,B2,D2) +/* STORE REAL ADDRES */ +# define STRAG(D1,B1,D2,B2) SSE_(0xE502,B1,D1,B2,D2) +/* STORE SYSTEM INFORMATION */ +# define STSI(D2,B2) S_(0xB27D,B2,D2) +/* STORE THEN AND SYSTEM MASK */ +# define STNSM(D1,B1,I2) SI_(0xAC,I2,B1,D1) +/* STORE THEN OR SYSTEM MASK */ +# define STOSM(D1,B1,I2) SI_(0xAD,I2,B1,D1) +/* STORE USING REAL ADDRESS */ +# define STURA(R1,R2) RRE_(0xB246,R1,R2) +# define STURG(R1,R2) RRE_(0xB925,R1,R2) +/* TEST ACCESS */ +# define TAR(R1,R2) RRE_(0xB24C,R1,R2) +/* TEST BLOCK */ +# define TB(R1,R2) RRE_(0xB22C,R1,R2) +/* TEST PROTECTION */ +# define TPROT(D1,B1,D2,B2) SSE_(0xE501,B1,D1,B2,D2) +/* TRACE */ +# define TRACE(R1,R3,D2,B2) RS_(0x99,R1,R3,B2,D2) +# define TRACG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x0F) +/* TRAP */ +# define TRAP2() E_(0x01FF) +# define TRAP4(D2,B2) S_(0xB2FF,B2,D2) +/**************************************************************** + * I/O Instructions * + ****************************************************************/ +/* CANCEL SUBCHANNEL */ +# define XSCH() S_(0xB276,0,0) +/* CLEAR SUBCHANNEL */ +# define CSCH() S_(0xB230,0,0) +/* HALT SUBCHANNEL */ +# define HSCH() S_(0xB231,0,0) +/* MODIFY SUBCHANNEL */ +# define MSCH(D2,B2) S_(0xB232,B2,D2) +/* RESET CHANNEL PATH */ +# define RCHP() S_(0xB23B,0,0) +/* RESUME SUBCHANNEL */ +# define RSCH() S_(0xB238,0,0) +/* SET ADDRESS LIMIT */ +# define SAL() S_(0xB237,0,0) +/* SET CHANNEL MONITOR */ +# define SCHM() S_(0xB23C,0,0) +/* START SUBCHANNEL */ +# define SSCH(D2,B2) S_(0xB233,B2,D2) +/* STORE CHANNEL PATH STATUS */ +# define STCPS(D2,B2) S_(0xB23A,B2,D2) +/* STORE CHANNEL REPORT WORD */ +# define STCRW(D2,B2) S_(0xB239,B2,D2) +/* STORE SUBCHANNEL */ +# define STSCH(D2,B2) S_(0xB234,B2,D2) +/* TEST PENDING INTERRUPTION */ +# define TPI(D2,B2) S_(0xB236,B2,D2) +/* TEST SUBCHANNEL */ +# define TSCH(D2,B2) S_(0xB235,B2,D2) +# define xdivr(r0,r1) _xdivr(_jit,r0,r1) +static jit_int32_t _xdivr(jit_state_t*,jit_int32_t,jit_int32_t); +# define xdivr_u(r0,r1) _xdivr_u(_jit,r0,r1) +static jit_int32_t _xdivr_u(jit_state_t*,jit_int32_t,jit_int32_t); +# define xdivi(r0,i0) _xdivi(_jit,r0,i0) +static jit_int32_t _xdivi(jit_state_t*,jit_int32_t,jit_word_t); +# define xdivi_u(r0,i0) _xdivi_u(_jit,r0,i0) +static jit_int32_t _xdivi_u(jit_state_t*,jit_int32_t,jit_word_t); +# define crr(cc,r0,r1,r2) _crr(_jit,cc,r0,r1,r2) +static void _crr(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define cri(cc,r0,r1,i0) _cri(_jit,cc,r0,r1,i0) +static void _cri(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +# define crr_u(cc,r0,r1,r2) _crr_u(_jit,cc,r0,r1,r2) +static void _crr_u(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define cri_u(cc,r0,r1,i0) _cri_u(_jit,cc,r0,r1,i0) +static void _cri_u(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +# define brr(cc,i0,r0,r1) _brr(_jit,cc,i0,r0,r1) +static void _brr(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define brr_p(cc,i0,r0,r1) _brr_p(_jit,cc,i0,r0,r1) +static jit_word_t _brr_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bri(cc,i0,r0,i1) _bri(_jit,cc,i0,r0,i1) +static void _bri(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bri_p(cc,i0,r0,i1) _bri_p(_jit,cc,i0,r0,i1) +static jit_word_t _bri_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define brr_u(cc,i0,r0,r1) _brr_u(_jit,cc,i0,r0,r1) +static void _brr_u(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define brr_u_p(cc,i0,r0,r1) _brr_u_p(_jit,cc,i0,r0,r1) +static jit_word_t _brr_u_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bri_u(cc,i0,r0,i1) _bri_u(_jit,cc,i0,r0,i1) +static void _bri_u(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bri_u_p(cc,i0,r0,i1) _bri_u_p(_jit,cc,i0,r0,i1) +static jit_word_t _bri_u_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define baddr(c,s,i0,r0,r1) _baddr(_jit,c,s,i0,r0,r1) +static void _baddr(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define baddr_p(c,s,i0,r0,r1) _baddr_p(_jit,c,s,i0,r0,r1) +static jit_word_t _baddr_p(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define baddi(c,s,i0,r0,i1) _baddi(_jit,c,s,i0,r0,i1) +static void _baddi(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_word_t); +# define baddi_p(c,s,i0,r0,i1) _baddi_p(_jit,c,s,i0,r0,i1) +static jit_word_t _baddi_p(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bsubr(c,s,i0,r0,r1) _bsubr(_jit,c,s,i0,r0,r1) +static void _bsubr(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bsubr_p(c,s,i0,r0,r1) _bsubr_p(_jit,c,s,i0,r0,r1) +static jit_word_t _bsubr_p(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bsubi(c,s,i0,r0,i1) _bsubi(_jit,c,s,i0,r0,i1) +static void _bsubi(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bsubi_p(c,s,i0,r0,i1) _bsubi_p(_jit,c,s,i0,r0,i1) +static jit_word_t _bsubi_p(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bmxr(cc,i0,r0,r1) _bmxr(_jit,cc,i0,r0,r1) +static void _bmxr(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bmxr_p(cc,i0,r0,r1) _bmxr_p(_jit,cc,i0,r0,r1) +static jit_word_t _bmxr_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bmxi(cc,i0,r0,i1) _bmxi(_jit,cc,i0,r0,i1) +static void _bmxi(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bmxi_p(cc,i0,r0,i1) _bmxi_p(_jit,cc,i0,r0,i1) +static jit_word_t _bmxi_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define movr(r0,r1) _movr(_jit,r0,r1) +static void _movr(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi(r0,i0) _movi(_jit,r0,i0) +static void _movi(jit_state_t*,jit_int32_t,jit_word_t); +# define movi_p(r0,i0) _movi_p(_jit,r0,i0) +static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t); +# define addr(r0,r1,r2) _addr(_jit,r0,r1,r2) +static void _addr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0) +static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addcr(r0,r1,r2) _addcr(_jit,r0,r1,r2) +static void _addcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addci(r0,r1,i0) _addci(_jit,r0,r1,i0) +static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addxr(r0,r1,r2) _addxr(_jit,r0,r1,r2) +static void _addxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0) +static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subr(r0,r1,r2) _subr(_jit,r0,r1,r2) +static void _subr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subi(r0,r1,i0) _subi(_jit,r0,r1,i0) +static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subcr(r0,r1,r2) _subcr(_jit,r0,r1,r2) +static void _subcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subci(r0,r1,i0) _subci(_jit,r0,r1,i0) +static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subxr(r0,r1,r2) _subxr(_jit,r0,r1,r2) +static void _subxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subxi(r0,r1,i0) _subxi(_jit,r0,r1,i0) +static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0) +static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define mulr(r0,r1,r2) _mulr(_jit,r0,r1,r2) +static void _mulr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define muli(r0,r1,i0) _muli(_jit,r0,r1,i0) +static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr(r0,r1,r2,r3) _qmulr(_jit,r0,r1,r2,r3) +static void _qmulr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qmuli(r0,r1,r2,i0) _qmuli(_jit,r0,r1,r2,i0) +static void _qmuli(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr_u(r0,r1,r2,r3) _qmulr_u(_jit,r0,r1,r2,r3) +static void _qmulr_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qmuli_u(r0,r1,r2,i0) _qmuli_u(_jit,r0,r1,r2,i0) +static void _qmuli_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define divr(r0,r1,r2) _divr(_jit,r0,r1,r2) +static void _divr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi(r0,r1,i0) _divi(_jit,r0,r1,i0) +static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define divr_u(r0,r1,r2) _divr_u(_jit,r0,r1,r2) +static void _divr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0) +static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define remr(r0,r1,r2) _remr(_jit,r0,r1,r2) +static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi(r0,r1,i0) _remi(_jit,r0,r1,i0) +static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2) +static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0) +static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qdivr(r0,r1,r2,r3) _qdivr(_jit,r0,r1,r2,r3) +static void _qdivr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qdivi(r0,r1,r2,i0) _qdivi(_jit,r0,r1,r2,i0) +static void _qdivi(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define qdivr_u(r0,r1,r2,r3) _qdivr_u(_jit,r0,r1,r2,r3) +static void _qdivr_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qdivi_u(r0,r1,r2,i0) _qdivi_u(_jit,r0,r1,r2,i0) +static void _qdivi_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define lshr(r0,r1,r2) _lshr(_jit,r0,r1,r2) +static void _lshr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# else +# define lshr(r0,r1,r2) SLLG(r0,r1,0,r2) +# endif +# define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0) +static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define rshr(r0,r1,r2) _rshr(_jit,r0,r1,r2) +static void _rshr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# else +# define rshr(r0,r1,r2) SRAG(r0,r1,0,r2) +# endif +# define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0) +static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define rshr_u(r0,r1,r2) _rshr_u(_jit,r0,r1,r2) +static void _rshr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# else +# define rshr_u(r0,r1,r2) SRLG(r0,r1,0,r2) +# endif +# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0) +static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define negr(r0,r1) LCR(r0,r1) +# else +# define negr(r0,r1) LCGR(r0,r1) +# endif +# define comr(r0,r1) _comr(_jit,r0,r1) +static void _comr(jit_state_t*,jit_int32_t,jit_int32_t); +# define andr(r0,r1,r2) _andr(_jit,r0,r1,r2) +static void _andr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0) +static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define orr(r0,r1,r2) _orr(_jit,r0,r1,r2) +static void _orr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ori(r0,r1,i0) _ori(_jit,r0,r1,i0) +static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define xorr(r0,r1,r2) _xorr(_jit,r0,r1,r2) +static void _xorr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define xori(r0,r1,i0) _xori(_jit,r0,r1,i0) +static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define htonr_us(r0,r1) extr_us(r0,r1) +# if __WORDSIZE == 32 +# define htonr_ui(r0,r1) movr(r0,r1) +# else +# define htonr_ui(r0,r1) extr_ui(r0,r1) +# define htonr_ul(r0,r1) movr(r0,r1) +# endif +# define extr_c(r0,r1) LGBR(r0,r1) +# define extr_uc(r0,r1) LLGCR(r0,r1) +# define extr_s(r0,r1) LGHR(r0,r1) +# define extr_us(r0,r1) LLGHR(r0,r1) +# if __WORDSIZE == 64 +# define extr_i(r0,r1) LGFR(r0,r1) +# define extr_ui(r0,r1) LLGFR(r0,r1) +# endif +# define ldr_c(r0,r1) LGB(r0,0,0,r1) +# define ldi_c(r0,i0) _ldi_c(_jit,r0,i0) +static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_c(r0,r1,r2) _ldxr_c(_jit,r0,r1,r2) +static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0) +static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_uc(r0,r1) LLGC(r0,0,0,r1) +# define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0) +static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_uc(r0,r1,r2) _ldxr_uc(_jit,r0,r1,r2) +static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0) +static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define ldr_s(r0,r1) LH(r0,0,0,r1) +# else +# define ldr_s(r0,r1) LGH(r0,0,0,r1) +# endif +# define ldi_s(r0,i0) _ldi_s(_jit,r0,i0) +static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_s(r0,r1,r2) _ldxr_s(_jit,r0,r1,r2) +static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0) +static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_us(r0,r1) LLGH(r0,0,0,r1) +# define ldi_us(r0,i0) _ldi_us(_jit,r0,i0) +static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_us(r0,r1,r2) _ldxr_us(_jit,r0,r1,r2) +static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0) +static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define ldr_i(r0,r1) LLGF(r0,0,0,r1) +# else +# define ldr_i(r0,r1) LGF(r0,0,0,r1) +# endif +# define ldi_i(r0,i0) _ldi_i(_jit,r0,i0) +static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_i(r0,r1,r2) _ldxr_i(_jit,r0,r1,r2) +static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_i(r0,r1,i0) _ldxi_i(_jit,r0,r1,i0) +static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 64 +# define ldr_ui(r0,r1) LLGF(r0,0,0,r1) +# define ldi_ui(r0,i0) _ldi_ui(_jit,r0,i0) +static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_ui(r0,r1,r2) _ldxr_ui(_jit,r0,r1,r2) +static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_ui(r0,r1,i0) _ldxi_ui(_jit,r0,r1,i0) +static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_l(r0,r1) LG(r0,0,0,r1) +# define ldi_l(r0,i0) _ldi_l(_jit,r0,i0) +static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_l(r0,r1,r2) _ldxr_l(_jit,r0,r1,r2) +static void _ldxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_l(r0,r1,i0) _ldxi_l(_jit,r0,r1,i0) +static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# endif +# define str_c(r0,r1) STC(r1,0,0,r0) +# define sti_c(i0,r0) _sti_c(_jit,i0,r0) +static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_c(r0,r1,r2) _stxr_c(_jit,r0,r1,r2) +static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_c(i0,r0,r1) _stxi_c(_jit,i0,r0,r1) +static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define str_s(r0,r1) STH(r1,0,0,r0) +# define sti_s(i0,r0) _sti_s(_jit,i0,r0) +static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_s(r0,r1,r2) _stxr_s(_jit,r0,r1,r2) +static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_s(i0,r0,r1) _stxi_s(_jit,i0,r0,r1) +static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define str_i(r0,r1) ST(r1,0,0,r0) +# define sti_i(i0,r0) _sti_i(_jit,i0,r0) +static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_i(r0,r1,r2) _stxr_i(_jit,r0,r1,r2) +static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_i(i0,r0,r1) _stxi_i(_jit,i0,r0,r1) +static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# if __WORDSIZE == 64 +# define str_l(r0,r1) STG(r1,0,0,r0) +# define sti_l(i0,r0) _sti_l(_jit,i0,r0) +static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_l(r0,r1,r2) _stxr_l(_jit,r0,r1,r2) +static void _stxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1) +static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# endif +# define ltr(r0,r1,r2) crr(CC_L,r0,r1,r2) +# define lti(r0,r1,i0) cri(CC_L,r0,r1,i0) +# define ltr_u(r0,r1,r2) crr_u(CC_L,r0,r1,r2) +# define lti_u(r0,r1,i0) cri_u(CC_L,r0,r1,i0) +# define ler(r0,r1,r2) crr(CC_LE,r0,r1,r2) +# define lei(r0,r1,i0) cri(CC_LE,r0,r1,i0) +# define ler_u(r0,r1,r2) crr_u(CC_LE,r0,r1,r2) +# define lei_u(r0,r1,i0) cri_u(CC_LE,r0,r1,i0) +# define eqr(r0,r1,r2) crr(CC_E,r0,r1,r2) +# define eqi(r0,r1,i0) cri(CC_E,r0,r1,i0) +# define ger(r0,r1,r2) crr(CC_HE,r0,r1,r2) +# define gei(r0,r1,i0) cri(CC_HE,r0,r1,i0) +# define ger_u(r0,r1,r2) crr_u(CC_HE,r0,r1,r2) +# define gei_u(r0,r1,i0) cri_u(CC_HE,r0,r1,i0) +# define gtr(r0,r1,r2) crr(CC_H,r0,r1,r2) +# define gti(r0,r1,i0) cri(CC_H,r0,r1,i0) +# define gtr_u(r0,r1,r2) crr_u(CC_H,r0,r1,r2) +# define gti_u(r0,r1,i0) cri_u(CC_H,r0,r1,i0) +# define ner(r0,r1,r2) crr(CC_NE,r0,r1,r2) +# define nei(r0,r1,i0) cri(CC_NE,r0,r1,i0) +# define bltr(i0,r0,r1) brr(CC_L,i0,r0,r1) +# define bltr_p(i0,r0,r1) brr_p(CC_L,i0,r0,r1) +# define blti(i0,r0,i1) bri(CC_L,i0,r0,i1) +# define blti_p(i0,r0,i1) bri_p(CC_L,i0,r0,i1) +# define bltr_u(i0,r0,r1) brr_u(CC_L,i0,r0,r1) +# define bltr_u_p(i0,r0,r1) brr_u_p(CC_L,i0,r0,r1) +# define blti_u(i0,r0,i1) bri_u(CC_L,i0,r0,i1) +# define blti_u_p(i0,r0,i1) bri_u_p(CC_L,i0,r0,i1) +# define bler(i0,r0,r1) brr(CC_LE,i0,r0,r1) +# define bler_p(i0,r0,r1) brr_p(CC_LE,i0,r0,r1) +# define blei(i0,r0,i1) bri(CC_LE,i0,r0,i1) +# define blei_p(i0,r0,i1) bri_p(CC_LE,i0,r0,i1) +# define bler_u(i0,r0,r1) brr_u(CC_LE,i0,r0,r1) +# define bler_u_p(i0,r0,r1) brr_u_p(CC_LE,i0,r0,r1) +# define blei_u(i0,r0,i1) bri_u(CC_LE,i0,r0,i1) +# define blei_u_p(i0,r0,i1) bri_u_p(CC_LE,i0,r0,i1) +# define beqr(i0,r0,r1) brr(CC_E,i0,r0,r1) +# define beqr_p(i0,r0,r1) brr_p(CC_E,i0,r0,r1) +# define beqi(i0,r0,i1) bri(CC_E,i0,r0,i1) +# define beqi_p(i0,r0,i1) bri_p(CC_E,i0,r0,i1) +# define bger(i0,r0,r1) brr(CC_HE,i0,r0,r1) +# define bger_p(i0,r0,r1) brr_p(CC_HE,i0,r0,r1) +# define bgei(i0,r0,i1) bri(CC_HE,i0,r0,i1) +# define bgei_p(i0,r0,i1) bri_p(CC_HE,i0,r0,i1) +# define bger_u(i0,r0,r1) brr_u(CC_HE,i0,r0,r1) +# define bger_u_p(i0,r0,r1) brr_u_p(CC_HE,i0,r0,r1) +# define bgei_u(i0,r0,i1) bri_u(CC_HE,i0,r0,i1) +# define bgei_u_p(i0,r0,i1) bri_u_p(CC_HE,i0,r0,i1) +# define bgtr(i0,r0,r1) brr(CC_H,i0,r0,r1) +# define bgtr_p(i0,r0,r1) brr_p(CC_H,i0,r0,r1) +# define bgti(i0,r0,i1) bri(CC_H,i0,r0,i1) +# define bgti_p(i0,r0,i1) bri_p(CC_H,i0,r0,i1) +# define bgtr_u(i0,r0,r1) brr_u(CC_H,i0,r0,r1) +# define bgtr_u_p(i0,r0,r1) brr_u_p(CC_H,i0,r0,r1) +# define bgti_u(i0,r0,i1) bri_u(CC_H,i0,r0,i1) +# define bgti_u_p(i0,r0,i1) bri_u_p(CC_H,i0,r0,i1) +# define bner(i0,r0,r1) brr(CC_NE,i0,r0,r1) +# define bner_p(i0,r0,r1) brr_p(CC_NE,i0,r0,r1) +# define bnei(i0,r0,i1) bri(CC_NE,i0,r0,i1) +# define bnei_p(i0,r0,i1) bri_p(CC_NE,i0,r0,i1) +# define boaddr(i0,r0,r1) baddr(CC_O,1,i0,r0,r1) +# define boaddr_p(i0,r0,r1) baddr_p(CC_O,1,i0,r0,r1) +# define boaddi(i0,r0,i1) baddi(CC_O,1,i0,r0,i1) +# define boaddi_p(i0,r0,i1) baddi_p(CC_O,1,i0,r0,i1) +# define boaddr_u(i0,r0,r1) baddr(CC_NLE,0,i0,r0,r1) +# define boaddr_u_p(i0,r0,r1) baddr_p(CC_NLE,0,i0,r0,r1) +# define boaddi_u(i0,r0,i1) baddi(CC_NLE,0,i0,r0,i1) +# define boaddi_u_p(i0,r0,i1) baddi_p(CC_NLE,0,i0,r0,i1) +# define bxaddr(i0,r0,r1) baddr(CC_NO,1,i0,r0,r1) +# define bxaddr_p(i0,r0,r1) baddr_p(CC_NO,1,i0,r0,r1) +# define bxaddi(i0,r0,i1) baddi(CC_NO,1,i0,r0,i1) +# define bxaddi_p(i0,r0,i1) baddi_p(CC_NO,1,i0,r0,i1) +# define bxaddr_u(i0,r0,r1) baddr(CC_LE,0,i0,r0,r1) +# define bxaddr_u_p(i0,r0,r1) baddr_p(CC_LE,0,i0,r0,r1) +# define bxaddi_u(i0,r0,i1) baddi(CC_LE,0,i0,r0,i1) +# define bxaddi_u_p(i0,r0,i1) baddi_p(CC_LE,0,i0,r0,i1) +# define bosubr(i0,r0,r1) bsubr(CC_O,1,i0,r0,r1) +# define bosubr_p(i0,r0,r1) bsubr_p(CC_O,1,i0,r0,r1) +# define bosubi(i0,r0,i1) bsubi(CC_O,1,i0,r0,i1) +# define bosubi_p(i0,r0,i1) bsubi_p(CC_O,1,i0,r0,i1) +# define bosubr_u(i0,r0,r1) bsubr(CC_L,0,i0,r0,r1) +# define bosubr_u_p(i0,r0,r1) bsubr_p(CC_L,0,i0,r0,r1) +# define bosubi_u(i0,r0,i1) bsubi(CC_L,0,i0,r0,i1) +# define bosubi_u_p(i0,r0,i1) bsubi_p(CC_L,0,i0,r0,i1) +# define bxsubr(i0,r0,r1) bsubr(CC_NO,1,i0,r0,r1) +# define bxsubr_p(i0,r0,r1) bsubr_p(CC_NO,1,i0,r0,r1) +# define bxsubi(i0,r0,i1) bsubi(CC_NO,1,i0,r0,i1) +# define bxsubi_p(i0,r0,i1) bsubi_p(CC_NO,1,i0,r0,i1) +# define bxsubr_u(i0,r0,r1) bsubr(CC_NL,0,i0,r0,r1) +# define bxsubr_u_p(i0,r0,r1) bsubr_p(CC_NL,0,i0,r0,r1) +# define bxsubi_u(i0,r0,i1) bsubi(CC_NL,0,i0,r0,i1) +# define bxsubi_u_p(i0,r0,i1) bsubi_p(CC_NL,0,i0,r0,i1) +# define bmsr(i0,r0,r1) bmxr(CC_NE,i0,r0,r1) +# define bmsr_p(i0,r0,r1) bmxr_p(CC_NE,i0,r0,r1) +# define bmsi(i0,r0,i1) bmxi(CC_NE,i0,r0,i1) +# define bmsi_p(i0,r0,i1) bmxi_p(CC_NE,i0,r0,i1) +# define bmcr(i0,r0,r1) bmxr(CC_E,i0,r0,r1) +# define bmcr_p(i0,r0,r1) bmxr_p(CC_E,i0,r0,r1) +# define bmci(i0,r0,i1) bmxi(CC_E,i0,r0,i1) +# define bmci_p(i0,r0,i1) bmxi_p(CC_E,i0,r0,i1) +# define jmpr(r0) BR(r0) +# define jmpi(i0) _jmpi(_jit,i0) +static void _jmpi(jit_state_t*,jit_word_t); +# define jmpi_p(i0) _jmpi_p(_jit,i0) +static jit_word_t _jmpi_p(jit_state_t*,jit_word_t); +# define callr(r0) BALR(_R14_REGNO,r0) +# define calli(i0) _calli(_jit,i0) +static void _calli(jit_state_t*,jit_word_t); +# define calli_p(i0) _calli_p(_jit,i0) +static jit_word_t _calli_p(jit_state_t*,jit_word_t); +# define prolog(i0) _prolog(_jit,i0) +static void _prolog(jit_state_t*,jit_node_t*); +# define epilog(i0) _epilog(_jit,i0) +static void _epilog(jit_state_t*,jit_node_t*); +# define vastart(r0) _vastart(_jit, r0) +static void _vastart(jit_state_t*, jit_int32_t); +# define vaarg(r0, r1) _vaarg(_jit, r0, r1) +static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t); +# define patch_at(instr,label) _patch_at(_jit,instr,label) +static void _patch_at(jit_state_t*,jit_word_t,jit_word_t); +#endif + +#if CODE +# define _us jit_uint16_t +# define _ui jit_uint32_t +static void +_E(jit_state_t *_jit, _ui Op) +{ + union { + struct { + _us op; + } b; + _us s; + } i0; + i0.b.op = Op; + assert(i0.b.op == Op); + is(i0.s); +} + +static void +_I(jit_state_t *_jit, _ui Op, _ui I) +{ + union { + struct { + _us op : 8; + _us i : 8; + } b; + _us s; + } i0; + i0.b.op = Op; + i0.b.i = I; + assert(i0.b.op == Op); + assert(i0.b.i == I); + is(i0.s); +} + +static void +_RR(jit_state_t *_jit, _ui Op, _ui R1, _ui R2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us r2 : 4; + } b; + _us s; + } i0; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.r2 = R2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.r2 == R2); + is(i0.s); +} + +static void +_RRE(jit_state_t *_jit, _ui Op, _ui R1, _ui R2) +{ + union { + struct { + _us op; + } b; + _us s; + } i0; + union { + struct { + _us _ : 8; + _us r1 : 4; + _us r2 : 4; + } b; + _us s; + } i1; + i0.b.op = Op; + i1.b._ = 0; + i1.b.r1 = R1; + i1.b.r2 = R2; + assert(i0.b.op == Op); + assert(i1.b.r1 == R1); + assert(i1.b.r2 == R2); + is(i0.s); + is(i1.s); +} + +static void +_RRF(jit_state_t *_jit, _ui Op, _ui R3, _ui M4, _ui R1, _ui R2) +{ + union { + struct { + _us op; + } b; + _us s; + } i0; + union { + struct { + _us r3 : 4; + _us m4 : 4; + _us r1 : 4; + _us r2 : 4; + } b; + _us s; + } i1; + i0.b.op = Op; + i1.b.r3 = R3; + i1.b.m4 = M4; + i1.b.r1 = R1; + i1.b.r2 = R2; + assert(i0.b.op == Op); + assert(i1.b.r3 == R3); + assert(i1.b.m4 == M4); + assert(i1.b.r1 == R1); + assert(i1.b.r2 == R2); + is(i0.s); + is(i1.s); +} + +static void +_RX(jit_state_t *_jit, _ui Op, _ui R1, _ui X2, _ui B2, _ui D2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us x2 : 4; + } b; + _us s; + } i0; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _us s; + } i1; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.x2 = X2; + i1.b.b2 = B2; + i1.b.d2 = D2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.x2 == X2); + assert(i1.b.b2 == B2); + assert(i1.b.d2 == D2); + is(i0.s); + is(i1.s); +} + +static void +_RXE(jit_state_t *_jit, _ui Op, _ui R1, _ui X2, _ui B2, _ui D2, _ui Op2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us x2 : 4; + } b; + _us s; + } i0; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _ui s; + } i1; + union { + struct { + _us _ : 8; + _us op : 8; + } b; + _us s; + } i2; + i2.b._ = 0; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.x2 = X2; + i1.b.b2 = B2; + i1.b.d2 = D2; + i2.b.op = Op2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.x2 == X2); + assert(i1.b.b2 == B2); + assert(i1.b.d2 == D2); + assert(i2.b.op == Op2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_RXF(jit_state_t *_jit, _ui Op, _ui R3, _ui X2, _ui B2, _ui D2, _ui R1, _ui Op2) +{ + union { + struct { + _us op : 8; + _us r3 : 4; + _us x2 : 4; + } b; + _us s; + } i0; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _us s; + } i1; + union { + struct { + _us r1 : 4; + _us _ : 4; + _us op : 8; + } b; + _us s; + } i2; + i2.b._ = 0; + i0.b.op = Op; + i0.b.r3 = R3; + i0.b.x2 = X2; + i1.b.b2 = B2; + i1.b.d2 = D2; + i2.b.r1 = R1; + i2.b.op = Op2; + assert(i0.b.op == Op); + assert(i0.b.r3 == R3); + assert(i0.b.x2 == X2); + assert(i1.b.b2 == B2); + assert(i1.b.d2 == D2); + assert(i2.b.r1 == R1); + assert(i2.b.op == Op2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_RXY(jit_state_t *_jit, _ui Op, _ui R1, _ui X2, _ui B2, _ui D2, _ui Op2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us x2 : 4; + } b; + _us s; + } i0; + union { + struct { + _us b2 : 4; + _us dl : 12; + } b; + _us s; + } i1; + union { + struct { + _us dh : 8; + _us op : 8; + } b; + _us s; + } i2; + i0.s = i1.s = i2.s = 0; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.x2 = X2; + i1.b.b2 = B2; + i1.b.dl = D2 & 0xfff; + i2.b.dh = D2 >> 12; + i2.b.op = Op2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.x2 == X2); + assert(i1.b.b2 == B2); + assert(i2.b.dh == D2 >> 12); + assert(i2.b.op == Op2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_RS(jit_state_t *_jit, _ui Op, _ui R1, _ui R3, _ui B2, _ui D2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us r3 : 4; + } b; + _us s; + } i0; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _us s; + } i1; + i0.s = i1.s = 0; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.r3 = R3; + i1.b.b2 = B2; + i1.b.d2 = D2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.r3 == R3); + assert(i1.b.b2 == B2); + assert(i1.b.d2 == D2); + is(i0.s); + is(i1.s); +} + +static void +_RSL(jit_state_t *_jit, _ui Op, _ui L1, _ui B1, _ui D1, _ui Op2) +{ + union { + struct { + _us op : 8; + _us l1 : 4; + _us _ : 4; + } b; + _us s; + } i0; + union { + struct { + _us b1 : 4; + _us d1 : 12; + } b; + _us s; + } i1; + union { + struct { + _us _ : 8; + _us op : 8; + } b; + _us s; + } i2; + i0.b._ = 0; + i2.b._ = 0; + i0.b.op = Op; + i0.b.l1 = L1; + i1.b.b1 = B1; + i1.b.d1 = D1; + i2.b.op = Op2; + assert(i0.b.op == Op); + assert(i0.b.l1 == L1); + assert(i1.b.b1 == B1); + assert(i1.b.d1 == D1); + assert(i2.b.op == Op2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_RSI(jit_state_t *_jit, _ui Op, _ui R1, _ui R3, _ui I2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us r3 : 4; + } b; + _us s; + } i0; + union { + struct { + _us i2; + } b; + _us s; + } i1; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.r3 = R3; + i1.b.i2 = I2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.r3 == R3); + assert(i1.b.i2 == I2); + is(i0.s); + is(i1.s); +} + +static void +_RIE(jit_state_t *_jit, _ui Op, _ui R1, _ui R3, _ui I2, _ui Op2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us r3 : 4; + } b; + _us s; + } i0; + union { + struct { + _us i2; + } b; + _us s; + } i1; + union { + struct { + _us _ : 8; + _us op : 8; + } b; + _us s; + } i2; + i2.b._ = 0; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.r3 = R3; + i1.b.i2 = I2; + i2.b.op = Op2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.r3 == R3); + assert(i1.b.i2 == I2); + assert(i2.b.op == Op2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_RIL(jit_state_t *_jit, _ui Op, _ui R1, _ui Op2, _ui I2) +{ + union { + struct { + _us o1 : 8; + _us r1 : 4; + _us o2 : 4; + } b; + _us s; + } i0; + union { + struct { + _ui ih : 16; + _ui il : 16; + } b; + _ui i; + } i12; + i0.b.o1 = Op; + i0.b.r1 = R1; + i0.b.o2 = Op2; + i12.i = I2; + assert(i0.b.o1 == Op); + assert(i0.b.r1 == R1); + assert(i0.b.o2 == Op2); + is(i0.s); + is(i12.b.ih); + is(i12.b.il); +} + +static void +_SI(jit_state_t *_jit, _ui Op, _ui I2, _ui B1, _ui D1) +{ + union { + struct { + _us op : 8; + _us i2 : 8; + } b; + _us s; + } i0; + union { + struct { + _us b1 : 4; + _us d1 : 12; + } b; + _us s; + } i1; + i0.b.op = Op; + i0.b.i2 = I2; + i1.b.b1 = B1; + i1.b.d1 = D1; + assert(i0.b.op == Op); + assert(i0.b.i2 == I2); + assert(i1.b.b1 == B1); + assert(i1.b.d1 == D1); + is(i0.s); + is(i1.s); +} + +static void +_SIY(jit_state_t *_jit, _ui Op, _ui I2, _ui B1, _ui D1, _ui Op2) +{ + union { + struct { + _us op : 8; + _us i2 : 8; + } b; + _us s; + } i0; + union { + struct { + _us b1 : 4; + _us dl : 12; + } b; + _us s; + } i1; + union { + struct { + _us dh : 8; + _us op : 8; + } b; + _us s; + } i2; + i0.b.op = Op; + i0.b.i2 = I2; + i1.b.b1 = B1; + i1.b.dl = D1 & 0xfff; + i2.b.dh = D1 >> 8; + i2.b.op = Op2; + assert(i0.b.op == Op); + assert(i0.b.i2 == I2); + assert(i1.b.b1 == B1); + assert(i2.b.dh == D1 >> 8); + assert(i2.b.op == Op2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_S(jit_state_t *_jit, _ui Op, _ui B2, _ui D2) +{ + union { + struct { + _us op; + } b; + _us s; + } i0; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _us s; + } i1; + i0.b.op = Op; + i1.b.b2 = B2; + i1.b.d2 = D2; + assert(i0.b.op == Op); + assert(i1.b.b2 == B2); + assert(i1.b.d2 == D2); + is(i0.s); + is(i1.s); +} + +static void +_SS(jit_state_t *_jit, _ui Op, _ui LL, _ui LH, _ui B1, _ui D1, _ui B2, _ui D2) +{ + union { + struct { + _us op : 8; + _us ll : 4; + _us lh : 4; + } b; + _us s; + } i0; + union { + struct { + _us b1 : 4; + _us d1 : 12; + } b; + _us s; + } i1; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _us s; + } i2; + i0.b.op = Op; + i0.b.ll = LL; + i0.b.lh = LH; + i1.b.b1 = B1; + i1.b.d1 = D1; + i2.b.b2 = B2; + i2.b.d2 = D2; + assert(i0.b.op == Op); + assert(i0.b.ll == LL); + assert(i0.b.lh == LH); + assert(i1.b.b1 == B1); + assert(i1.b.d1 == D1); + assert(i2.b.b2 == B2); + assert(i2.b.d2 == D2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_SSE(jit_state_t *_jit, _ui Op, _ui B1, _ui D1, _ui B2, _ui D2) +{ + union { + struct { + _us op; + } b; + _us s; + } i0; + union { + struct { + _us b1 : 4; + _us d1 : 12; + } b; + _us s; + } i1; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _us s; + } i2; + i0.b.op = Op; + i1.b.b1 = B1; + i1.b.d1 = D1; + i2.b.b2 = B2; + i2.b.d2 = D2; + assert(i0.b.op == Op); + assert(i1.b.b1 == B1); + assert(i1.b.d1 == D1); + assert(i2.b.b2 == B2); + assert(i2.b.d2 == D2); + is(i0.s); + is(i1.s); + is(i2.s); +} +# undef _us +# undef _ui + +static void +_nop(jit_state_t *_jit, jit_int32_t c) +{ + assert(c >= 0 && !(c & 1)); + while (c) { + NOPR(_R7_REGNO); + c -= 2; + } +} + +static jit_int32_t +_xdivr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t regno; + regno = jit_get_reg_pair(); +#if __WORDSIZE == 32 + movr(rn(regno), r0); + SRDA(rn(regno), 32, 0); +#else + movr(rn(regno) + 1, r0); +#endif + DIVREM_(rn(regno), r1); + jit_unget_reg_pair(regno); + return (regno); +} + +static jit_int32_t +_xdivr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t regno; + regno = jit_get_reg_pair(); +#if __WORDSIZE == 32 + movr(rn(regno), r0); + SRDL(rn(regno), 32, 0); +#else + movr(rn(regno) + 1, r0); +#endif + movi(rn(regno), 0); + DIVREMU_(rn(regno), r1); + jit_unget_reg_pair(regno); + return (regno); +} + +static jit_int32_t +_xdivi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t imm, regno; + regno = jit_get_reg_pair(); + imm = jit_get_reg(jit_class_gpr); +#if __WORDSIZE == 32 + movr(rn(regno), r0); + SRDA(rn(regno), 32, 0); +#else + movr(rn(regno) + 1, r0); +#endif + movi(rn(imm), i0); + DIVREM_(rn(regno), rn(imm)); + jit_unget_reg(imm); + jit_unget_reg_pair(regno); + return (regno); +} + +static jit_int32_t +_xdivi_u(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + /* cannot overlap because operand is 128-bit */ + jit_int32_t imm, regno; + regno = jit_get_reg_pair(); + imm = jit_get_reg(jit_class_gpr); +#if __WORDSIZE == 32 + movr(rn(regno), r0); + SRDL(rn(regno), 32, 0); +#else + movr(rn(regno) + 1, r0); +#endif + movi(rn(regno), 0); + movi(rn(imm), i0); + DIVREMU_(rn(regno), rn(imm)); + jit_unget_reg(imm); + jit_unget_reg_pair(regno); + return (regno); +} + +static void +_crr(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t reg, rg; + if (r0 == r1 || r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + rg = rn(reg); + } + else + rg = r0; + movi(rg, 1); + CMP_(r1, r2); + w = _jit->pc.w; + BRC(cc, 0); + movi(rg, 0); + patch_at(w, _jit->pc.w); + if (r0 == r1 || r0 == r2) { + movr(r0, rg); + jit_unget_reg(reg); + } +} + +static void +_cri(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + crr(cc, r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_crr_u(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t reg, rg; + if (r0 == r1 || r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + rg = rn(reg); + } + else + rg = r0; + movi(rg, 1); + CMPU_(r1, r2); + w = _jit->pc.w; + BRC(cc, 0); + movi(rg, 0); + patch_at(w, _jit->pc.w); + if (r0 == r1 || r0 == r2) { + movr(r0, rg); + jit_unget_reg(reg); + } +} + +static void +_cri_u(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + crr_u(cc, r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_brr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + CMP_(r0, r1); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(cc, x16(d)); + else { + assert(s32_p(d)); + BRCL(cc, d); + } +} + +static jit_word_t +_brr_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CMP_(r0, r1); + w = _jit->pc.w; + BRCL(cc, 0); + return (w); +} + +static void +_bri(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + brr(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static jit_word_t +_bri_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = brr_p(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_brr_u(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + CMPU_(r0, r1); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(cc, x16(d)); + else { + assert(s32_p(d)); + BRCL(cc, d); + } +} + +static jit_word_t +_brr_u_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CMPU_(r0, r1); + w = _jit->pc.w; + BRCL(cc, 0); + return (w); +} + +static void +_bri_u(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + brr_u(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static jit_word_t +_bri_u_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = brr_u_p(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_baddr(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + if (s) addr(r0, r0, r1); + else addcr(r0, r0, r1); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(c, x16(d)); + else { + assert(s32_p(d)); + BRCL(c, d); + } +} + +static void +_baddi(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + baddr(c, s, i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static jit_word_t +_baddr_p(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + if (s) addr(r0, r0, r1); + else addcr(r0, r0, r1); + d = (i0 - _jit->pc.w) >> 1; + w = _jit->pc.w; + BRCL(c, d); + return (w); +} + +static jit_word_t +_baddi_p(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = baddr_p(c, s, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_bsubr(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + if (s) subr(r0, r0, r1); + else subcr(r0, r0, r1); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(c, x16(d)); + else { + assert(s32_p(d)); + BRCL(c, d); + } +} + +static void +_bsubi(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + bsubr(c, s, i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static jit_word_t +_bsubr_p(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + if (s) subr(r0, r0, r1); + else subcr(r0, r0, r1); + d = (i0 - _jit->pc.w) >> 1; + w = _jit->pc.w; + BRCL(c, d); + return (w); +} + +static jit_word_t +_bsubi_p(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bsubr_p(c, s, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_bmxr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r0); + andr(rn(reg), rn(reg), r1); + TEST_(rn(reg), rn(reg)); + jit_unget_reg(reg); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(cc, x16(d)); + else { + assert(s32_p(d)); + BRCL(cc, d); + } +} + +static jit_word_t +_bmxr_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r0); + andr(rn(reg), rn(reg), r1); + TEST_(rn(reg), rn(reg)); + jit_unget_reg(reg); + w = _jit->pc.w; + BRCL(cc, 0); + return (w); +} + +static void +_bmxi(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t d; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + andr(rn(reg), rn(reg), r0); + TEST_(rn(reg), rn(reg)); + jit_unget_reg(reg); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(cc, x16(d)); + else { + assert(s32_p(d)); + BRCL(cc, d); + } +} + +static jit_word_t +_bmxi_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + andr(rn(reg), rn(reg), r0); + TEST_(rn(reg), rn(reg)); + jit_unget_reg(reg); + w = _jit->pc.w; + BRCL(cc, 0); + return (w); +} + +static void +_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ +#if __WORDSIZE == 32 + if (r0 != r1) + LR(r0, r1); +#else + if (r0 != r1) + LGR(r0, r1); +#endif +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t d; +#if __WORDSIZE == 64 + jit_int32_t bits; +#endif + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(i0)) { +#if __WORDSIZE == 32 + LHI(r0, x16(i0)); +#else + LGHI(r0, x16(i0)); +#endif + } + /* easy way of loading a large amount of 32 bit values and + * usually address of constants */ + else if (!(i0 & 1) && +#if __WORDSIZE == 32 + i0 > 0 +#else + s32_p(d) +#endif + ) + LARL(r0, d); + else { +#if __WORDSIZE == 32 + LHI(r0, x16(i0)); + IILH(r0, x16((jit_uword_t)i0 >> 16)); +#else + bits = 0; + if (i0 & 0xffffL) bits |= 1; + if (i0 & 0xffff0000L) bits |= 2; + if (i0 & 0xffff00000000L) bits |= 4; + if (i0 & 0xffff000000000000L) bits |= 8; + if (bits != 15) LGHI(r0, 0); + if (bits & 1) IILL(r0, x16(i0)); + if (bits & 2) IILH(r0, x16((jit_uword_t)i0 >> 16)); + if (bits & 4) IIHL(r0, x16((jit_uword_t)i0 >> 32)); + if (bits & 8) IIHH(r0, x16((jit_uword_t)i0 >> 48)); +#endif + } +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + w = _jit->pc.w; +#if __WORDSIZE == 32 + LHI(r0, x16(i0)); +#else + IILL(r0, x16(i0)); +#endif + IILH(r0, x16((jit_uword_t)i0 >> 16)); +#if __WORDSIZE == 64 + IIHL(r0, x16((jit_uword_t)i0 >> 32)); + IIHH(r0, x16((jit_uword_t)i0 >> 48)); +#endif + return (w); +} + +static void +_addr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + ADD_(r0, r1); + else { + movr(r0, r1); + ADD_(r0, r2); + } +} + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (r0 == r1 && s16_p(i0)) + ADDI_(r0, x16(i0)); +#if __WORDSIZE == 64 + else if (s20_p(i0)) + LAY(r0, x20(i0), 0, r1); +#endif + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + ADDC_(r0, r1); + else { + movr(r0, r1); + ADDC_(r0, r2); + } +} + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addcr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + ADDX_(r0, r1); + else { + movr(r0, r1); + ADDX_(r0, r2); + } +} + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addxr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r2); + movr(r0, r1); + SUB_(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr(r0, r1); + SUB_(r0, r2); + } +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (r0 == r1 && s16_p(-i0)) + ADDI_(r0, x16(-i0)); +#if __WORDSIZE == 64 + else if (s20_p(-i0)) + LAY(r0, x20(-i0), 0, r1); +#endif + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r2); + movr(r0, r1); + SUBC_(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr(r0, r1); + SUBC_(r0, r2); + } +} + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subcr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r2); + movr(r0, r1); + SUBX_(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr(r0, r1); + SUBX_(r0, r2); + } +} + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subxr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + subi(r0, r1, i0); + negr(r0, r0); +} + +static void +_mulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + MUL_(r0, r1); + else { + movr(r0, r1); + MUL_(r0, r2); + } +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s16_p(i0)) { + movr(r0, r1); + MULI_(r0, x16(i0)); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + mulr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_qmulr(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t reg; + /* The only invalid condition is r0 == r1 */ + jit_int32_t t2, t3, s2, s3; + if (r2 == r0 || r2 == r1) { + s2 = jit_get_reg(jit_class_gpr); + t2 = rn(s2); + movr(t2, r2); + } + else + t2 = r2; + if (r3 == r0 || r3 == r1) { + s3 = jit_get_reg(jit_class_gpr); + t3 = rn(s3); + movr(t3, r3); + } + else + t3 = r3; + qmulr_u(r0, r1, r2, r3); + reg = jit_get_reg(jit_class_gpr); + /**/ + rshi(rn(reg), t2, 63); + mulr(rn(reg), rn(reg), t3); + addr(r1, r1, rn(reg)); + /**/ + rshi(rn(reg), t3, 63); + mulr(rn(reg), rn(reg), t2); + addr(r1, r1, rn(reg)); + jit_unget_reg(reg); + if (t2 != r2) + jit_unget_reg(s2); + if (t3 != r3) + jit_unget_reg(s3); +} + +static void +_qmuli(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + qmulr(r0, r1, r2, rn(reg)); + jit_unget_reg(reg); +} + +static void +_qmulr_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t regno; + regno = jit_get_reg_pair(); + movr(rn(regno) + 1, r2); + MULU_(rn(regno), r3); + movr(r0, rn(regno) + 1); + movr(r1, rn(regno)); + jit_unget_reg_pair(regno); +} + +static void +_qmuli_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t regno; + regno = jit_get_reg_pair(); + movr(rn(regno) + 1, r2); + movi(rn(regno), i0); + MULU_(rn(regno), rn(regno)); + movr(r0, rn(regno) + 1); + movr(r1, rn(regno)); + jit_unget_reg_pair(regno); +} + +static void +_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t regno; + regno = xdivr(r1, r2); + movr(r0, rn(regno) + 1); +} + +static void +_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t regno; + regno = xdivi(r1, i0); + movr(r0, rn(regno) + 1); +} + +static void +_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t regno; + regno = xdivr_u(r1, r2); + movr(r0, rn(regno) + 1); +} + +static void +_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t regno; + regno = xdivi_u(r1, i0); + movr(r0, rn(regno) + 1); +} + +static void +_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t regno; + regno = xdivr(r1, r2); + movr(r0, rn(regno)); +} + +static void +_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t regno; + regno = xdivi(r1, i0); + movr(r0, rn(regno)); +} + +static void +_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t regno; + regno = xdivr_u(r1, r2); + movr(r0, rn(regno)); +} + +static void +_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t regno; + regno = xdivi_u(r1, i0); + movr(r0, rn(regno)); +} + +static void +_qdivr(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t regno; + regno = xdivr(r2, r3); + movr(r0, rn(regno) + 1); + movr(r1, rn(regno)); +} + +static void +_qdivi(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t regno; + regno = xdivi(r2, i0); + movr(r0, rn(regno) + 1); + movr(r1, rn(regno)); +} + +static void +_qdivr_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t regno; + regno = xdivr_u(r2, r3); + movr(r0, rn(regno) + 1); + movr(r1, rn(regno)); +} + +static void +_qdivi_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t regno; + regno = xdivi_u(r2, i0); + movr(r0, rn(regno) + 1); + movr(r1, rn(regno)); +} + +# if __WORDSIZE == 32 +static void +_lshr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg_but_zero(0); + movr(rn(reg), r2); + movr(r0, r1); + SLL(r0, 0, rn(reg)); + jit_unget_reg_but_zero(reg); + } + else { + movr(r0, r1); + SLL(r0, 0, r2); + } +} +#endif + +static void +_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + lshr(r0, r1, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +# if __WORDSIZE == 32 +static void +_rshr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg_but_zero(0); + movr(rn(reg), r2); + movr(r0, r1); + SRA(r0, 0, rn(reg)); + jit_unget_reg_but_zero(reg); + } + else { + movr(r0, r1); + SRA(r0, 0, r2); + } +} +#endif + +static void +_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + rshr(r0, r1, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +# if __WORDSIZE == 32 +static void +_rshr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg_but_zero(0); + movr(rn(reg), r2); + movr(r0, r1); + SRL(r0, 0, rn(reg)); + jit_unget_reg_but_zero(reg); + } + else { + movr(r0, r1); + SRL(r0, 0, r2); + } +} +#endif + +static void +_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + rshr_u(r0, r1, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +static void +_comr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), -1); + movr(r0, r1); + XOR_(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_andr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + AND_(r0, r1); + else { + movr(r0, r1); + AND_(r0, r2); + } +} + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(r0, r1); + NILL(r0, x16(i0)); + NILH(r0, x16((jit_uword_t)i0 >> 16)); +#if __WORDSIZE == 64 + NIHL(r0, x16((jit_uword_t)i0 >> 32)); + NIHH(r0, x16((jit_uword_t)i0 >> 48)); +#endif +} + +static void +_orr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + OR_(r0, r1); + else { + movr(r0, r1); + OR_(r0, r2); + } +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(r0, r1); + OILL(r0, x16(i0)); + OILH(r0, x16((jit_uword_t)i0 >> 16)); +#if __WORDSIZE == 64 + OIHL(r0, x16((jit_uword_t)i0 >> 32)); + OIHH(r0, x16((jit_uword_t)i0 >> 48)); +#endif +} + +static void +_xorr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + XOR_(r0, r1); + else { + movr(r0, r1); + XOR_(r0, r2); + } +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + xorr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_c(r0, r0); +} + +static void +_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + addr(r0, r0, r1); + ldr_c(r0, r0); + } + else { + movr(r0, r1); + addr(r0, r0, r2); + ldr_c(r0, r0); + } +} + +static void +_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s20_p(i0)) { +#if __WORDSIZE == 32 + LB(r0, x20(i0), 0, r1); +#else + LGB(r0, x20(i0), 0, r1); +#endif + } + else if (r0 != r1) { + movi(r0, i0); + addr(r0, r0, r1); + ldr_c(r0, r0); + } + else { + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + addr(rn(reg), rn(reg), r1); + ldr_c(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_uc(r0, r0); +} + +static void +_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + addr(r0, r0, r1); + ldr_uc(r0, r0); + } + else { + movr(r0, r1); + addr(r0, r0, r2); + ldr_uc(r0, r0); + } +} + +static void +_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s20_p(i0)) + LLGC(r0, x20(i0), 0, r1); + else if (r0 != r1) { + movi(r0, i0); + addr(r0, r0, r1); + ldr_uc(r0, r0); + } + else { + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + addr(rn(reg), rn(reg), r1); + ldr_uc(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_s(r0, r0); +} + +static void +_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + addr(r0, r0, r1); + ldr_s(r0, r0); + } + else { + movr(r0, r1); + addr(r0, r0, r2); + ldr_s(r0, r0); + } +} + +static void +_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; +#if __WORDSIZE == 32 + if (u12_p(i0)) + LH(r0, i0, 0, r1); + else +#endif + if (s20_p(i0)) { +#if __WORDSIZE == 32 + LHY(r0, x20(i0), 0, r1); +#else + LGH(r0, x20(i0), 0, r1); +#endif + } + else if (r0 != r1) { + movi(r0, i0); + addr(r0, r0, r1); + ldr_s(r0, r0); + } + else { + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + addr(rn(reg), rn(reg), r1); + ldr_s(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_us(r0, r0); +} + +static void +_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + addr(r0, r0, r1); + ldr_us(r0, r0); + } + else { + movr(r0, r1); + addr(r0, r0, r2); + ldr_us(r0, r0); + } +} + +static void +_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s20_p(i0)) + LLGH(r0, x20(i0), 0, r1); + else if (r0 != r1) { + movi(r0, i0); + addr(r0, r0, r1); + ldr_us(r0, r0); + } + else { + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + addr(rn(reg), rn(reg), r1); + ldr_us(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_i(r0, r0); +} + +static void +_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + addr(r0, r0, r1); + ldr_i(r0, r0); + } + else { + movr(r0, r1); + addr(r0, r0, r2); + ldr_i(r0, r0); + } +} + +static void +_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s20_p(i0)) + LGF(r0, x20(i0), 0, r1); + else if (r0 != r1) { + movi(r0, i0); + addr(r0, r0, r1); + ldr_i(r0, r0); + } + else { + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + addr(rn(reg), rn(reg), r1); + ldr_i(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +#if __WORDSIZE == 64 +static void +_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_ui(r0, r0); +} + +static void +_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + addr(r0, r0, r1); + ldr_ui(r0, r0); + } + else { + movr(r0, r1); + addr(r0, r0, r2); + ldr_ui(r0, r0); + } +} + +static void +_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s20_p(i0)) + LLGF(r0, x20(i0), 0, r1); + else if (r0 != r1) { + movi(r0, i0); + addr(r0, r0, r1); + ldr_ui(r0, r0); + } + else { + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + addr(rn(reg), rn(reg), r1); + ldr_ui(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_l(r0, r0); +} + +static void +_ldxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + addr(r0, r0, r1); + ldr_l(r0, r0); + } + else { + movr(r0, r1); + addr(r0, r0, r2); + ldr_l(r0, r0); + } +} + +static void +_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s20_p(i0)) + LG(r0, x20(i0), 0, r1); + else if (r0 != r1) { + movi(r0, i0); + addr(r0, r0, r1); + ldr_l(r0, r0); + } + else { + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + addr(rn(reg), rn(reg), r1); + ldr_l(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} +#endif + +static void +_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + str_c(rn(reg), r0); + jit_unget_reg_but_zero(reg); +} + +static void +_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movr(rn(reg), r0); + addr(rn(reg), rn(reg), r1); + str_c(rn(reg), r2); + jit_unget_reg_but_zero(reg); +} + +static void +_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (u12_p(i0)) + STC(r1, i0, 0, r0); + else if (s20_p(i0)) + STCY(r1, x20(i0), 0, r0); + else { + reg = jit_get_reg_but_zero(0); + addi(rn(reg), r0, i0); + str_c(rn(reg), r1); + jit_unget_reg_but_zero(reg); + } +} + +static void +_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + str_s(rn(reg), r0); + jit_unget_reg_but_zero(reg); +} + +static void +_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movr(rn(reg), r0); + addr(rn(reg), rn(reg), r1); + str_s(rn(reg), r2); + jit_unget_reg_but_zero(reg); +} + +static void +_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (u12_p(i0)) + STH(r1, i0, 0, r0); + else if (s20_p(i0)) + STHY(r1, x20(i0), 0, r0); + else { + reg = jit_get_reg_but_zero(0); + addi(rn(reg), r0, i0); + str_s(rn(reg), r1); + jit_unget_reg_but_zero(reg); + } +} + +static void +_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + str_i(rn(reg), r0); + jit_unget_reg_but_zero(reg); +} + +static void +_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movr(rn(reg), r0); + addr(rn(reg), rn(reg), r1); + str_i(rn(reg), r2); + jit_unget_reg_but_zero(reg); +} + +static void +_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (u12_p(i0)) + ST(r1, i0, 0, r0); + else if (s20_p(i0)) + STY(r1, x20(i0), 0, r0); + else { + reg = jit_get_reg_but_zero(0); + addi(rn(reg), r0, i0); + str_i(rn(reg), r1); + jit_unget_reg_but_zero(reg); + } +} + +#if __WORDSIZE == 64 +static void +_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + str_l(rn(reg), r0); + jit_unget_reg_but_zero(reg); +} + +static void +_stxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movr(rn(reg), r0); + addr(rn(reg), rn(reg), r1); + str_l(rn(reg), r2); + jit_unget_reg_but_zero(reg); +} + +static void +_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (s20_p(i0)) + STG(r1, x20(i0), 0, r0); + else { + reg = jit_get_reg_but_zero(0); + addi(rn(reg), r0, i0); + str_l(rn(reg), r1); + jit_unget_reg_but_zero(reg); + } +} +#endif + +static void +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t d; + jit_int32_t reg; + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + J(x16(d)); + else if (s32_p(d)) + BRL(d); + else { + reg = jit_get_reg_but_zero(jit_class_nospill); + movi(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static jit_word_t +_jmpi_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg_but_zero(jit_class_nospill); + w = movi_p(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg_but_zero(reg); + return (w); +} + +static void +_calli(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t d; + jit_int32_t reg; + d = (i0 - _jit->pc.w) >> 1; + if (s32_p(d)) + BRASL(_R14_REGNO, d); + else { + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + callr(rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + w = movi_p(rn(reg), i0); + callr(rn(reg)); + jit_unget_reg_but_zero(reg); + return (w); +} + +static jit_int32_t gprs[] = { + _R2, _R3, _R4, _R5, + _R6, _R7, _R8, _R9, _R10, _R11, _R12, _R13 +}; + +static void +_prolog(jit_state_t *_jit, jit_node_t *i0) +{ + jit_int32_t regno, offset; + if (_jitc->function->define_frame || _jitc->function->assume_frame) { + jit_int32_t frame = -_jitc->function->frame; + assert(_jitc->function->self.aoff >= frame); + if (_jitc->function->assume_frame) + return; + _jitc->function->self.aoff = frame; + } + if (_jitc->function->allocar) + _jitc->function->self.aoff &= -8; + _jitc->function->stack = ((_jitc->function->self.alen - + /* align stack at 8 bytes */ + _jitc->function->self.aoff) + 7) & -8; + /* *IFF* a non variadic function, + * Lightning does not reserve stack space for spilling arguments + * in registers. + * S390x, as per gcc, has 8 stack slots for spilling arguments, + * (%r6 is callee save) and uses an alloca like approach to save + * callee save fpr registers. + * Since argument registers are not saved in any lightning port, + * use the 8 slots to spill any modified fpr register, and still + * use the same stack frame logic as gcc. + * Save at least %r13 to %r15, as %r13 is used as frame pointer. + * *IFF* a variadic function, a "standard" stack frame, with + * fpr registers saved in an alloca'ed area, is used. + */ + if ((_jitc->function->self.call & jit_call_varargs) && + jit_arg_reg_p(_jitc->function->vagp)) + regno = _jitc->function->vagp; + else { + for (regno = 4; regno < jit_size(gprs) - 1; regno++) { + if (jit_regset_tstbit(&_jitc->function->regset, gprs[regno])) + break; + } + } +#if __WORDSIZE == 32 +# define FP_OFFSET 64 + if (_jitc->function->self.call & jit_call_varargs) + offset = regno * 4 + 8; + else + offset = (regno - 4) * 4 + 32; + STM(rn(gprs[regno]), _R15_REGNO, x20(offset), _R15_REGNO); +#else +# define FP_OFFSET 128 + if (_jitc->function->self.call & jit_call_varargs) + offset = regno * 8 + 16; + else + offset = (regno - 4) * 8 + 48; + STMG(rn(gprs[regno]), _R15_REGNO, x20(offset), _R15_REGNO); +#endif + +#define SPILL(R, O) \ + do { \ + if (jit_regset_tstbit(&_jitc->function->regset, R)) \ + stxi_d(O, _R15_REGNO, rn(R)); \ + } while (0) + if (_jitc->function->self.call & jit_call_varargs) { + for (regno = _jitc->function->vafp; jit_arg_f_reg_p(regno); ++regno) + stxi_d(FP_OFFSET + regno * 8, _R15_REGNO, rn(_F0 - regno)); + SPILL(_F8, _jitc->function->vaoff + offsetof(jit_va_list_t, f8)); + SPILL(_F9, _jitc->function->vaoff + offsetof(jit_va_list_t, f9)); + SPILL(_F10, _jitc->function->vaoff + offsetof(jit_va_list_t, f10)); + SPILL(_F11, _jitc->function->vaoff + offsetof(jit_va_list_t, f11)); + SPILL(_F12, _jitc->function->vaoff + offsetof(jit_va_list_t, f12)); + SPILL(_F13, _jitc->function->vaoff + offsetof(jit_va_list_t, f13)); + SPILL(_F14, _jitc->function->vaoff + offsetof(jit_va_list_t, f14)); + } + else { + /* First 4 in low address */ +#if __WORDSIZE == 32 + SPILL(_F10, 0); + SPILL(_F11, 8); + SPILL(_F12, 16); + SPILL(_F13, 24); + /* gpr registers here */ + SPILL(_F14, 72); + SPILL(_F8, 80); + SPILL(_F9, 88); +#else + SPILL(_F10, 16); + SPILL(_F11, 24); + SPILL(_F12, 32); + SPILL(_F13, 48); + /* Last 3 in high address */ + SPILL(_F14, 136); + SPILL(_F8, 144); + SPILL(_F9, 152); +#endif + } +#undef SPILL + movr(_R13_REGNO, _R15_REGNO); + subi(_R15_REGNO, _R15_REGNO, stack_framesize + _jitc->function->stack); + if (_jitc->function->allocar) { + regno = jit_get_reg(jit_class_gpr); + movi(rn(regno), _jitc->function->self.aoff); + stxi_i(_jitc->function->aoffoff, _R13_REGNO, rn(regno)); + jit_unget_reg(regno); + } +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *i0) +{ + jit_int32_t regno, offset; + if (_jitc->function->assume_frame) + return; + if ((_jitc->function->self.call & jit_call_varargs) && + jit_arg_reg_p(_jitc->function->vagp)) + regno = _jitc->function->vagp; + else { + for (regno = 4; regno < jit_size(gprs) - 1; regno++) { + if (jit_regset_tstbit(&_jitc->function->regset, gprs[regno])) + break; + } + } +#if __WORDSIZE == 32 + if (_jitc->function->self.call & jit_call_varargs) + offset = regno * 4 + 8; + else + offset = (regno - 4) * 4 + 32; +#else + if (_jitc->function->self.call & jit_call_varargs) + offset = regno * 8 + 16; + else + offset = (regno - 4) * 8 + 48; +#endif + movr(_R15_REGNO, _R13_REGNO); + +#define LOAD(R, O) \ + do { \ + if (jit_regset_tstbit(&_jitc->function->regset, R)) \ + ldxi_d(rn(R), _R15_REGNO, O); \ + } while (0) + if (_jitc->function->self.call & jit_call_varargs) { + LOAD(_F8, _jitc->function->vaoff + offsetof(jit_va_list_t, f8)); + LOAD(_F9, _jitc->function->vaoff + offsetof(jit_va_list_t, f9)); + LOAD(_F10, _jitc->function->vaoff + offsetof(jit_va_list_t, f10)); + LOAD(_F11, _jitc->function->vaoff + offsetof(jit_va_list_t, f11)); + LOAD(_F12, _jitc->function->vaoff + offsetof(jit_va_list_t, f12)); + LOAD(_F13, _jitc->function->vaoff + offsetof(jit_va_list_t, f13)); + LOAD(_F14, _jitc->function->vaoff + offsetof(jit_va_list_t, f14)); + } + else { +#if __WORDSIZE == 32 + LOAD(_F10, 0); + LOAD(_F11, 8); + LOAD(_F12, 16); + LOAD(_F13, 24); + LOAD(_F14, 72); + LOAD(_F8, 80); + LOAD(_F9, 88); +#else + LOAD(_F10, 16); + LOAD(_F11, 24); + LOAD(_F12, 32); + LOAD(_F13, 48); + LOAD(_F14, 136); + LOAD(_F8, 144); + LOAD(_F9, 152); +#endif + } +#undef LOAD +#if __WORDSIZE == 32 + LM(rn(gprs[regno]), _R15_REGNO, x20(offset), _R15_REGNO); +#else + LMG(rn(gprs[regno]), _R15_REGNO, x20(offset), _R15_REGNO); +#endif + BR(_R14_REGNO); +} + +static void +_vastart(jit_state_t *_jit, jit_int32_t r0) +{ + jit_int32_t reg; + + assert(_jitc->function->self.call & jit_call_varargs); + + /* Return jit_va_list_t in the register argument */ + addi(r0, _R13_REGNO, _jitc->function->vaoff); + reg = jit_get_reg(jit_class_gpr); + + /* Initialize gp offset in the save area. */ + movi(rn(reg), _jitc->function->vagp); + stxi(offsetof(jit_va_list_t, gpoff), r0, rn(reg)); + + /* Initialize fp offset in the save area. */ + movi(rn(reg), _jitc->function->vafp); + stxi(offsetof(jit_va_list_t, fpoff), r0, rn(reg)); + + /* Initialize overflow pointer to the first stack argument. */ + addi(rn(reg), _R13_REGNO, _jitc->function->self.size); + stxi(offsetof(jit_va_list_t, over), r0, rn(reg)); + + /* Initialize register save area pointer. */ + stxi(offsetof(jit_va_list_t, save), r0, _R13_REGNO); + + jit_unget_reg(reg); +} + +static void +_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t rg0; + jit_int32_t rg1; + jit_int32_t rg2; + jit_word_t ge_code; + jit_word_t lt_code; + + assert(_jitc->function->self.call & jit_call_varargs); + + rg0 = jit_get_reg_but_zero(0); + rg1 = jit_get_reg_but_zero(0); + + /* Load the gp offset in save area in the first temporary. */ + ldxi(rn(rg0), r1, offsetof(jit_va_list_t, gpoff)); + + /* Jump over if there are no remaining arguments in the save area. */ + ge_code = bgei_p(_jit->pc.w, rn(rg0), 5); + + /* Load the save area pointer in the second temporary. */ + ldxi(rn(rg1), r1, offsetof(jit_va_list_t, save)); + + /* Scale offset */ + rg2 = jit_get_reg_but_zero(0); + lshi(rn(rg2), rn(rg0), +#if __WORDSIZE == 32 + 2 +#else + 3 +#endif + ); + /* Add offset to saved area. */ + addi(rn(rg2), rn(rg2), 2 * sizeof(jit_word_t)); + + /* Load the vararg argument in the first argument. */ + ldxr(r0, rn(rg1), rn(rg2)); + jit_unget_reg_but_zero(rg2); + + /* Update the gp offset. */ + addi(rn(rg0), rn(rg0), 1); + stxi(offsetof(jit_va_list_t, gpoff), r1, rn(rg0)); + + /* Will only need one temporary register below. */ + jit_unget_reg_but_zero(rg1); + + /* Jump over overflow code. */ + lt_code = jmpi_p(_jit->pc.w); + + /* Where to land if argument is in overflow area. */ + patch_at(ge_code, _jit->pc.w); + + /* Load overflow pointer. */ + ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over)); + + /* Load argument. */ + ldr(r0, rn(rg0)); + + /* Update overflow pointer. */ + addi(rn(rg0), rn(rg0), sizeof(jit_word_t)); + stxi(offsetof(jit_va_list_t, over), r1, rn(rg0)); + + /* Where to land if argument is in save area. */ + patch_at(lt_code, _jit->pc.w); + + jit_unget_reg_but_zero(rg0); +} + +static void +_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label) +{ + jit_word_t d; + union { + jit_uint16_t *s; + jit_word_t w; + } u; + u.w = instr; + union { + struct { + jit_uint16_t op : 8; + jit_uint16_t r1 : 4; + jit_uint16_t r3 : 4; + } b; + jit_uint16_t s; + } i0; + union { + struct { + jit_uint16_t i2; + } b; + jit_uint16_t s; + } i1; + union { + struct { + jit_uint32_t ih : 16; + jit_uint32_t il : 16; + } b; + jit_uint32_t i; + } i12; + i0.s = u.s[0]; + /* movi_p */ + if (i0.b.op == +#if __WORDSIZE == 32 + 0xA7 && i0.b.r3 == 8 +#else + 0xA5 +#endif + ) { +#if __WORDSIZE == 64 + assert(i0.b.r3 == 3); +#endif + i1.b.i2 = (jit_uword_t)label; + u.s[1] = i1.s; + i0.s = u.s[2]; + assert(i0.b.op == 0xA5 && i0.b.r3 == 2); + i1.b.i2 = (jit_uword_t)label >> 16; + u.s[3] = i1.s; +#if __WORDSIZE == 64 + i0.s = u.s[4]; + assert(i0.b.op == 0xA5 && i0.b.r3 == 1); + i1.b.i2 = (jit_uword_t)label >> 32; + u.s[5] = i1.s; + i0.s = u.s[6]; + assert(i0.b.op == 0xA5 && i0.b.r3 == 0); + i1.b.i2 = (jit_uword_t)label >> 48; + u.s[7] = i1.s; +#endif + } + /* BRC */ + else if (i0.b.op == 0xA7) { + assert(i0.b.r3 == 0x4); + d = (label - instr) >> 1; + assert(s16_p(d)); + i1.b.i2 = d; + u.s[1] = i1.s; + } + /* BRCL */ + else if (i0.b.op == 0xC0) { + assert(i0.b.r3 == 0x4); + d = (label - instr) >> 1; + assert(s32_p(d)); + i12.i = d; + u.s[1] = i12.b.ih; + u.s[2] = i12.b.il; + } + else + abort(); +} +#endif diff --git a/deps/lightning/lib/jit_s390-fpu.c b/deps/lightning/lib/jit_s390-fpu.c new file mode 100644 index 0000000..6d60513 --- /dev/null +++ b/deps/lightning/lib/jit_s390-fpu.c @@ -0,0 +1,1316 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# define RND_CUR 0 +# define RND_BIAS_NEAR 1 +# define RND_NEAR 4 +# define RND_ZERO 5 +# define RND_POS_INF 6 +# define RND_NEG_INF 7 +/**************************************************************** + * Floating Point Instructions * + ****************************************************************/ +/* CONVERT BFP TO HFP */ +# define THDER(R1,R2) RRE_(0xB358,R1,R2) +# define THDR(R1,R2) RRE_(0xB359,R1,R2) +/* CONVERT HFP TO BFP */ +# define TBEDR(R1,R2) RRE_(0xB350,R1,R2) +# define TBDR(R1,R2) RRE_(0xB351,R1,R2) +/* LOAD */ +# define LER(R1,R2) RR_(0x38,R1,R2) +# define LDR(R1,R2) RR_(0x28,R1,R2) +# define LXR(R1,R2) RRE_(0xB365,R1,R2) +# define LE(R1,D2,X2,B2) RX_(0x78,R1,X2,B2,D2) +# define LD(R1,D2,X2,B2) RX_(0x68,R1,X2,B2,D2) +# define LEY(R1,D2,X2,B2) RXY_(0xED,R1,X2,B2,D2,0x64) +# define LDY(R1,D2,X2,B2) RXY_(0xED,R1,X2,B2,D2,0x65) +/* LOAD ZERO */ +# define LZER(R1) RRE_(0xB374,R1,0) +# define LZDR(R1) RRE_(0xB375,R1,0) +# define LZXR(R1) RRE_(0xB376,R1,0) +/* STORE */ +# define STE(R1,D2,X2,B2) RX_(0x70,R1,X2,B2,D2) +# define STD(R1,D2,X2,B2) RX_(0x60,R1,X2,B2,D2) +# define STEY(R1,D2,X2,B2) RXY_(0xED,R1,X2,B2,D2,0x66) +# define STDY(R1,D2,X2,B2) RXY_(0xED,R1,X2,B2,D2,0x67) +/**************************************************************** + * Hexadecimal Floating Point Instructions * + ****************************************************************/ +/* ADD NORMALIZED */ +# define AER(R1,R2) RR_(0x3A,R1,R2) +# define ADR(R1,R2) RR_(0x2A,R1,R2) +# define AXR(R1,R2) RR_(0x36,R1,R2) +# define AE(R1,D2,X2,B2) RX_(0x7A,R1,X2,B2,D2) +# define AD(R1,D2,X2,B2) RX_(0x6A,R1,X2,B2,D2) +/* ADD UNNORMALIZED */ +# define AUR(R1,R2) RR_(0x3E,R1,R2) +# define AWR(R1,R2) RR_(0x2E,R1,R2) +# define AU(R1,D2,X2,B2) RX_(0x7E,R1,X2,B2,D2) +# define AW(R1,D2,X2,B2) RX_(0x6E,R1,X2,B2,D2) +/* COMPARE */ +# define CER(R1,R2) RR_(0x39,R1,R2) +# define CDR(R1,R2) RR_(0x29,R1,R2) +# define CXR(R1,R2) RRE_(0xB369,R1,R2) +# define CE(R1,D2,X2,B2) RX_(0x79,R1,X2,B2,D2) +# define CD(R1,D2,X2,B2) RX_(0x69,R1,X2,B2,D2) +/* CONVERT FROM FIXED */ +# define CEFR(R1,R2) RRE_(0xB3B4,R1,R2) +# define CDFR(R1,R2) RRE_(0xB3B5,R1,R2) +# define CXFR(R1,R2) RRE_(0xB3B6,R1,R2) +# define CEGR(R1,R2) RRE_(0xB3C4,R1,R2) +# define CDGR(R1,R2) RRE_(0xB3C5,R1,R2) +# define CXGR(R1,R2) RRE_(0xB3C6,R1,R2) +/* CONVERT TO FIXED */ +# define CFER(R1,R2) RRE_(0xB3B8,R1,R2) +# define CFDR(R1,R2) RRE_(0xB3B9,R1,R2) +# define CFXR(R1,R2) RRE_(0xB3BA,R1,R2) +# define CGER(R1,R2) RRE_(0xB3C8,R1,R2) +# define CGDR(R1,R2) RRE_(0xB3C9,R1,R2) +# define CGXR(R1,R2) RRE_(0xB3CA,R1,R2) +/* DIVIDE */ +# define DER(R1,R2) RR_(0x3D,R1,R2) +# define DDR(R1,R2) RR_(0x2D,R1,R2) +# define DXR(R1,R2) RRE_(0xB22D,R1,R2) +# define DE(R1,D2,X2,B2) RX_(0x7D,R1,X2,B2,D2) +# define DD(R1,D2,X2,B2) RX_(0x6D,R1,X2,B2,D2) +/* HALVE */ +# define HER(R1,R2) RR_(0x34,R1,R2) +# define HDR(R1,R2) RR_(0x24,R1,R2) +/* LOAD AND TEST */ +# define LTER(R1,R2) RR_(0x32,R1,R2) +# define LTDR(R1,R2) RR_(0x22,R1,R2) +# define LTXR(R1,R2) RRE_(0xB362,R1,R2) +/* LOAD COMPLEMENT */ +# define LCER(R1,R2) RR_(0x33,R1,R2) +# define LCDR(R1,R2) RR_(0x23,R1,R2) +# define LCXR(R1,R2) RRE_(0xB363,R1,R2) +/* LOAD FP INTEGER */ +# define FIER(R1,R2) RRE_(0xB377,R1,R2) +# define FIDR(R1,R2) RRE_(0xB37F,R1,R2) +# define FIXR(R1,R2) RRE_(0xB367,R1,R2) +/* LOAD LENGHTENED */ +# define LDER(R1,R2) RRE_(0xB324,R1,R2) +# define LXDR(R1,R2) RRE_(0xB325,R1,R2) +# define LXER(R1,R2) RRE_(0xB326,R1,R2) +# define LDE(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x24) +# define LXD(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x25) +# define LXE(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x26) +/* LOAD NEGATIVE */ +# define LNER(R1,R2) RR_(0x31,R1,R2) +# define LNDR(R1,R2) RR_(0x21,R1,R2) +# define LNXR(R1,R2) RRE_(0xB361,R1,R2) +/* LOAD POSITIVE */ +# define LPER(R1,R2) RR_(0x30,R1,R2) +# define LPDR(R1,R2) RR_(0x20,R1,R2) +# define LPXR(R1,R2) RRE_(0xB360,R1,R2) +/* LOAD ROUNDED */ +# define LEDR(R1,R2) RR_(0x35,R1,R2) +# define LDXR(R1,R2) RR_(0x25,R1,R2) +# define LRER(R1,R2) LEDR(R1,R2) +# define LRDR(R1,R2) LDXR(R1,R2) +# define LRXR(R1,R2) RRE_(0xB366,R1,R2) +/* MULTIPLY */ +# define MEER(R1,R2) RRE_(0xB337,R1,R2) +# define MDR(R1,R2) RR_(0x2C,R1,R2) +# define MXR(R1,R2) RR_(0x26,R1,R2) +# define MDER(R1,R2) RR_(0x3C,R1,R2) +# define MXDR(R1,R2) RR_(0x27,R1,R2) +# define MER(R1,R2) MDER(R1,R2) +# define MEE(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x37) +# define MD(R1,D2,X2,B2) RX_(0x6C,R1,X2,B2,D2) +# define MDE(R1,D2,X2,B2) RX_(0x7C,R1,X2,B2,D2) +# define MXD(R1,D2,X2,B2) RX_(0x67,R1,X2,B2,D2) +# define ME(R1,D2,X2,B2) MDE(R1,D2,X2,B2) +/* MULTIPLY AND ADD */ +# define MAER(R1,R3,R2) RRF_(0xB32E,R1,0,R3,R2) +# define MADR(R1,R3,R2) RRF_(0xB33E,R1,0,R3,R2) +# define MAE(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x2E) +# define MAD(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x3E) +/* MULTIPLY AND SUBTRACT */ +# define MSER(R1,R3,R2) RRF_(0xB32F,R1,0,R3,R2) +# define MSDR(R1,R3,R2) RRF_(0xB33F,R1,0,R3,R2) +# define MSE(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x2F) +# define MSD(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x3F) +/* SQUARE ROOT */ +# define SQER(R1,R2) RRE_(0xB245,R1,R2) +# define SQDR(R1,R2) RRE_(0xB244,R1,R2) +# define SQXR(R1,R2) RRE_(0xB336,R1,R2) +# define SQE(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x34) +# define SQD(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x35) +/* SUBTRACT NORMALIZED */ +# define SER(R1,R2) RR_(0x3B,R1,R2) +# define SDR(R1,R2) RR_(0x2B,R1,R2) +# define SXR(R1,R2) RR_(0x37,R1,R2) +# define SE(R1,D2,X2,B2) RX_(0x7B,R1,X2,B2,D2) +# define SD(R1,D2,X2,B2) RX_(0x6B,R1,X2,B2,D2) +/* SUBTRACT UNNORMALIZED */ +# define SUR(R1,R2) RR_(0x3F,R1,R2) +# define SWR(R1,R2) RR_(0x2F,R1,R2) +# define SU(R1,D2,X2,B2) RX_(0x7F,R1,X2,B2,D2) +# define SW(R1,D2,X2,B2) RX_(0x6F,R1,X2,B2,D2) +/**************************************************************** + * Binary Floating Point Instructions * + ****************************************************************/ +/* ADD */ +# define AEBR(R1,R2) RRE_(0xB30A,R1,R2) +# define ADBR(R1,R2) RRE_(0xB31A,R1,R2) +# define AXBR(R1,R2) RRE_(0xB34A,R1,R2) +# define AEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x0A) +# define ADB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x1A) +/* COMPARE */ +# define CEBR(R1,R2) RRE_(0xB309,R1,R2) +# define CDBR(R1,R2) RRE_(0xB319,R1,R2) +# define CXBR(R1,R2) RRE_(0xB349,R1,R2) +# define CEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x09) +# define CDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x19) +/* COMPARE AND SIGNAL */ +# define KEBR(R1,R2) RRE_(0xB308,R1,R2) +# define KDBR(R1,R2) RRE_(0xB318,R1,R2) +# define KXBR(R1,R2) RRE_(0xB348,R1,R2) +# define KEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x08) +# define KDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x18) +/* CONVERT FROM FIXED */ +# define CEFBR(R1,R2) RRE_(0xB394,R1,R2) +# define CDFBR(R1,R2) RRE_(0xB395,R1,R2) +# define CXFBR(R1,R2) RRE_(0xB396,R1,R2) +# define CEGBR(R1,R2) RRE_(0xB3A4,R1,R2) +# define CDGBR(R1,R2) RRE_(0xB3A5,R1,R2) +# define CXGBR(R1,R2) RRE_(0xB3A6,R1,R2) +/* CONVERT TO FIXED */ +# define CFEBR(R1,M3,R2) RRF_(0xB398,M3,0,R1,R2) +# define CFDBR(R1,M3,R2) RRF_(0xB399,M3,0,R1,R2) +# define CFXBR(R1,M3,R2) RRF_(0xB39A,M3,0,R1,R2) +# define CGEBR(R1,M3,R2) RRF_(0xB3A8,M3,0,R1,R2) +# define CGDBR(R1,M3,R2) RRF_(0xB3A9,M3,0,R1,R2) +# define CGXBR(R1,M3,R2) RRF_(0xB3AA,M3,0,R1,R2) +/* DIVIDE */ +# define DEBR(R1,R2) RRE_(0xB30D,R1,R2) +# define DDBR(R1,R2) RRE_(0xB31D,R1,R2) +# define DXBR(R1,R2) RRE_(0xB34D,R1,R2) +# define DEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x0D) +# define DDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x1D) +/* DIVIDE TO INTEGER */ +# define DIEBR(R1,R3,R2,M4) RRF_(0xB353,R3,M4,R1,R2) +# define DIDBR(R1,R3,R2,M4) RRF_(0xB35B,R3,M4,R1,R2) +/* EXTRACT FPC */ +# define EFPC(R1) RRE_(0xB38C,R1,0) +/* LOAD AND TEST */ +# define LTEBR(R1,R2) RRE_(0xB302,R1,R2) +# define LTDBR(R1,R2) RRE_(0xB312,R1,R2) +# define LTXBR(R1,R2) RRE_(0xB342,R1,R2) +/* LOAD COMPLEMENT */ +# define LCEBR(R1,R2) RRE_(0xB303,R1,R2) +# define LCDBR(R1,R2) RRE_(0xB313,R1,R2) +# define LCXBR(R1,R2) RRE_(0xB343,R1,R2) +/* LOAD FP INTEGER */ +# define FIEBR(R1,M3,R2) RRF_(0xB357,M3,0,R1,R2) +# define FIDBR(R1,M3,R2) RRF_(0xB35F,M3,0,R1,R2) +# define FIXBR(R1,M3,R2) RRF_(0xB347,M3,0,R1,R2) +/* LOAD FPC */ +# define LFPC(D2,B2) S_(0xB29D,B2,D2) +/* LOAD LENGTHENED */ +# define LDEBR(R1,R2) RRE_(0xB304,R1,R2) +# define LXDBR(R1,R2) RRE_(0xB305,R1,R2) +# define LXEBR(R1,R2) RRE_(0xB306,R1,R2) +# define LDEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x04) +# define LXDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x05) +# define LXEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x06) +/* LOAD NEGATIVE */ +# define LNEBR(R1,R2) RRE_(0xB301,R1,R2) +# define LNDBR(R1,R2) RRE_(0xB311,R1,R2) +# define LNXBR(R1,R2) RRE_(0xB341,R1,R2) +/* LOAD POSITIVE */ +# define LPEBR(R1,R2) RRE_(0xB300,R1,R2) +# define LPDBR(R1,R2) RRE_(0xB310,R1,R2) +# define LPXBR(R1,R2) RRE_(0xB340,R1,R2) +/* LOAD ROUNDED */ +# define LEDBR(R1,R2) RRE_(0xB344,R1,R2) +# define LDXBR(R1,R2) RRE_(0xB345,R1,R2) +# define LEXBR(R1,R2) RRE_(0xB346,R1,R2) +/* MULTIPLY */ +# define MEEBR(R1,R2) RRE_(0xB317,R1,R2) +# define MDBR(R1,R2) RRE_(0xB31C,R1,R2) +# define MXBR(R1,R2) RRE_(0xB34C,R1,R2) +# define MDEBR(R1,R2) RRE_(0xB30C,R1,R2) +# define MXDBR(R1,R2) RRE_(0xB307,R1,R2) +# define MEEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x17) +# define MDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x1C) +# define MDEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x0C) +# define MXDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x07) +/* MULTIPLY AND ADD */ +# define MAEBR(R1,R3,R2) RRF_(0xB30E,R1,0,R3,R2) +# define MADBR(R1,R3,R2) RRF_(0xB31E,R1,0,R3,R2) +# define MAEB(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x0E) +# define MADB(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x1E) +/* MULTIPLY AND SUBTRACT */ +# define MSEBR(R1,R3,R2) RRF_(0xB30F,R1,0,R3,R2) +# define MSDBR(R1,R3,R2) RRF_(0xB31F,R1,0,R3,R2) +# define MSEB(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x0F) +# define MSDB(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x1F) +/* SET FPC */ +# define SFPC(R1) RRE_(0xB384,R1,0) +/* SET ROUNDING MODE */ +# define SRNM(D2,B2) S_(0xB299,B2,D2) +/* SQUARE ROOT */ +# define SQEBR(R1,R2) RRE_(0xB314,R1,R2) +# define SQDBR(R1,R2) RRE_(0xB315,R1,R2) +# define SQXBR(R1,R2) RRE_(0xB316,R1,R2) +/* STORE FPC */ +# define STFPC(D2,B2) S_(0xB29C,B2,D2) +/* SUBTRACT */ +# define SEBR(R1,R2) RRE_(0xB30B,R1,R2) +# define SDBR(R1,R2) RRE_(0xB31B,R1,R2) +# define SXBR(R1,R2) RRE_(0xB34B,R1,R2) +# define SEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x0B) +# define SDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x1B) +/* TEST DATA CLASS */ +# define TCEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x10) +# define TCDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x11) +# define TCXB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x12) +# define fp(code,r0,r1,i0) _fp(_jit,jit_code_##code##i_f,r0,r1,i0) +static void _fp(jit_state_t*,jit_code_t, + jit_int32_t,jit_int32_t,jit_float32_t*); +# define dp(code,r0,r1,i0) _dp(_jit,jit_code_##code##i_d,r0,r1,i0) +static void _dp(jit_state_t*,jit_code_t, + jit_int32_t,jit_int32_t,jit_float64_t*); +# define fr(cc,r0,r1,r2) _fr(_jit,cc,r0,r1,r2) +static void _fr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define dr(cc,r0,r1,r2) _dr(_jit,cc,r0,r1,r2) +static void _dr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define fi(cc,r0,r1,i0) _fi(_jit,cc,r0,r1,i0) +static void _fi(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_float32_t*); +# define di(cc,r0,r1,i0) _di(_jit,cc,r0,r1,i0) +static void _di(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_float64_t*); +# define bfr(cc,i0,r0,r1) _bfr(_jit,cc,i0,r0,r1) +static void _bfr(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bdr(cc,i0,r0,r1) _bdr(_jit,cc,i0,r0,r1) +static void _bdr(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bfr_p(cc,i0,r0,r1) _bfr_p(_jit,cc,i0,r0,r1) +static jit_word_t _bfr_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bdr_p(cc,i0,r0,r1) _bdr_p(_jit,cc,i0,r0,r1) +static jit_word_t _bdr_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bfi(cc,i0,r0,i1) _bfi(_jit,cc,i0,r0,i1) +static void _bfi(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_float32_t*); +# define bdi(cc,i0,r0,i1) _bdi(_jit,cc,i0,r0,i1) +static void _bdi(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_float64_t*); +# define bfi_p(cc,i0,r0,i1) _bfi_p(_jit,cc,i0,r0,i1) +static jit_word_t _bfi_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_float32_t*); +# define bdi_p(cc,i0,r0,i1) _bdi_p(_jit,cc,i0,r0,i1) +static jit_word_t _bdi_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_float64_t*); +# define buneqr(db,i0,r0,r1) _buneqr(_jit,db,i0,r0,r1) +static jit_word_t _buneqr(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define buneqi(db,i0,r0,i1) _buneqi(_jit,db,i0,r0,(jit_word_t)i1) +static jit_word_t _buneqi(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bltgtr(db,i0,r0,r1) _bltgtr(_jit,db,i0,r0,r1) +static jit_word_t _bltgtr(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bltgti(db,i0,r0,i1) _bltgti(_jit,db,i0,r0,(jit_word_t)i1) +static jit_word_t _bltgti(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define movr_f(r0,r1) _movr_f(_jit,r0,r1) +static void _movr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi_f(r0,i0) _movi_f(_jit,r0,i0) +static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*); +# define movr_d(r0,r1) _movr_d(_jit,r0,r1) +static void _movr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi_d(r0,i0) _movi_d(_jit,r0,i0) +static void _movi_d(jit_state_t*,jit_int32_t,jit_float64_t*); +# define absr_f(r0,r1) LPEBR(r0,r1) +# define absr_d(r0,r1) LPDBR(r0,r1) +# define negr_f(r0,r1) LCEBR(r0,r1) +# define negr_d(r0,r1) LCDBR(r0,r1) +# define sqrtr_f(r0,r1) SQEBR(r0,r1) +# define sqrtr_d(r0,r1) SQDBR(r0,r1) +# define truncr_f_i(r0,r1) CFEBR(r0,RND_ZERO,r1) +# define truncr_d_i(r0,r1) CFDBR(r0,RND_ZERO,r1) +# if __WORDSIZE == 64 +# define truncr_f_l(r0,r1) CGEBR(r0,RND_ZERO,r1) +# define truncr_d_l(r0,r1) CGDBR(r0,RND_ZERO,r1) +# endif +# if __WORDSIZE == 32 +# define extr_f(r0,r1) CEFBR(r0,r1) +# define extr_d(r0,r1) CDFBR(r0,r1) +# else +# define extr_f(r0,r1) CEGBR(r0,r1) +# define extr_d(r0,r1) CDGBR(r0,r1) +# endif +# define extr_d_f(r0,r1) LEDBR(r0,r1) +# define extr_f_d(r0,r1) LDEBR(r0,r1) +# define addr_f(r0,r1,r2) _addr_f(_jit,r0,r1,r2) +static void _addr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addi_f(r0,r1,i0) fp(add,r0,r1,i0) +# define addr_d(r0,r1,r2) _addr_d(_jit,r0,r1,r2) +static void _addr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addi_d(r0,r1,i0) dp(add,r0,r1,i0) +# define subr_f(r0,r1,r2) _subr_f(_jit,r0,r1,r2) +static void _subr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subi_f(r0,r1,i0) fp(sub,r0,r1,i0) +# define subr_d(r0,r1,r2) _subr_d(_jit,r0,r1,r2) +static void _subr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subi_d(r0,r1,i0) dp(sub,r0,r1,i0) +# define rsbr_f(r0,r1,r2) subr_f(r0,r2,r1) +# define rsbi_f(r0,r1,i0) fp(rsb,r0,r1,i0) +# define rsbr_d(r0,r1,r2) subr_d(r0,r2,r1) +# define rsbi_d(r0,r1,i0) dp(rsb,r0,r1,i0) +# define mulr_f(r0,r1,r2) _mulr_f(_jit,r0,r1,r2) +static void _mulr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define muli_f(r0,r1,i0) fp(mul,r0,r1,i0) +# define mulr_d(r0,r1,r2) _mulr_d(_jit,r0,r1,r2) +static void _mulr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define muli_d(r0,r1,i0) dp(mul,r0,r1,i0) +# define divr_f(r0,r1,r2) _divr_f(_jit,r0,r1,r2) +static void _divr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_f(r0,r1,i0) fp(div,r0,r1,i0) +# define divr_d(r0,r1,r2) _divr_d(_jit,r0,r1,r2) +static void _divr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_d(r0,r1,i0) dp(div,r0,r1,i0) +# define ldr_f(r0,r1) LE(r0,0,0,r1) +# define ldr_d(r0,r1) LD(r0,0,0,r1) +# define ldi_f(r0,i0) _ldi_f(_jit,r0,i0) +static void _ldi_f(jit_state_t*,jit_int32_t,jit_word_t); +# define ldi_d(r0,i0) _ldi_d(_jit,r0,i0) +static void _ldi_d(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_f(r0,r1,r2) _ldxr_f(_jit,r0,r1,r2) +static void _ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxr_d(r0,r1,r2) _ldxr_d(_jit,r0,r1,r2) +static void _ldxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_f(r0,r1,i0) _ldxi_f(_jit,r0,r1,i0) +static void _ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxi_d(r0,r1,i0) _ldxi_d(_jit,r0,r1,i0) +static void _ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_f(r0,r1) STE(r1,0,0,r0) +# define str_d(r0,r1) STD(r1,0,0,r0) +# define sti_f(i0,r0) _sti_f(_jit,i0,r0) +static void _sti_f(jit_state_t*,jit_word_t,jit_int32_t); +# define sti_d(i0,r0) _sti_d(_jit,i0,r0) +static void _sti_d(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_f(r0,r1,r2) _stxr_f(_jit,r0,r1,r2) +static void _stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxr_d(r0,r1,r2) _stxr_d(_jit,r0,r1,r2) +static void _stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_f(i0,r0,r1) _stxi_f(_jit,i0,r0,r1) +static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxi_d(i0,r0,r1) _stxi_d(_jit,i0,r0,r1) +static void _stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define ltr_f(r0,r1,r2) fr(CC_L,r0,r1,r2) +# define ltr_d(r0,r1,r2) dr(CC_L,r0,r1,r2) +# define lti_f(r0,r1,i0) fi(CC_L,r0,r1,i0) +# define lti_d(r0,r1,i0) di(CC_L,r0,r1,i0) +# define ler_f(r0,r1,r2) fr(CC_LE,r0,r1,r2) +# define ler_d(r0,r1,r2) dr(CC_LE,r0,r1,r2) +# define lei_f(r0,r1,i0) fi(CC_LE,r0,r1,i0) +# define lei_d(r0,r1,i0) di(CC_LE,r0,r1,i0) +# define eqr_f(r0,r1,r2) fr(CC_E,r0,r1,r2) +# define eqr_d(r0,r1,r2) dr(CC_E,r0,r1,r2) +# define eqi_f(r0,r1,i0) fi(CC_E,r0,r1,i0) +# define eqi_d(r0,r1,i0) di(CC_E,r0,r1,i0) +# define ger_f(r0,r1,r2) fr(CC_HE,r0,r1,r2) +# define ger_d(r0,r1,r2) dr(CC_HE,r0,r1,r2) +# define gei_f(r0,r1,i0) fi(CC_HE,r0,r1,i0) +# define gei_d(r0,r1,i0) di(CC_HE,r0,r1,i0) +# define gtr_f(r0,r1,r2) fr(CC_H,r0,r1,r2) +# define gtr_d(r0,r1,r2) dr(CC_H,r0,r1,r2) +# define gti_f(r0,r1,i0) fi(CC_H,r0,r1,i0) +# define gti_d(r0,r1,i0) di(CC_H,r0,r1,i0) +# define ner_f(r0,r1,r2) fr(CC_NE,r0,r1,r2) +# define ner_d(r0,r1,r2) dr(CC_NE,r0,r1,r2) +# define nei_f(r0,r1,i0) fi(CC_NE,r0,r1,i0) +# define nei_d(r0,r1,i0) di(CC_NE,r0,r1,i0) +# define unltr_f(r0,r1,r2) fr(CC_NHE,r0,r1,r2) +# define unltr_d(r0,r1,r2) dr(CC_NHE,r0,r1,r2) +# define unlti_f(r0,r1,i0) fi(CC_NHE,r0,r1,i0) +# define unlti_d(r0,r1,i0) di(CC_NHE,r0,r1,i0) +# define unler_f(r0,r1,r2) fr(CC_NH,r0,r1,r2) +# define unler_d(r0,r1,r2) dr(CC_NH,r0,r1,r2) +# define unlei_f(r0,r1,i0) fi(CC_NH,r0,r1,i0) +# define unlei_d(r0,r1,i0) di(CC_NH,r0,r1,i0) +# define uneqr_f(r0,r1,r2) _uneqr_f(_jit,r0,r1,r2) +static void _uneqr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define uneqr_d(r0,r1,r2) _uneqr_d(_jit,r0,r1,r2) +static void _uneqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define uneqi_f(r0,r1,i0) fp(uneq,r0,r1,i0) +# define uneqi_d(r0,r1,i0) dp(uneq,r0,r1,i0) +# define unger_f(r0,r1,r2) fr(CC_NL,r0,r1,r2) +# define unger_d(r0,r1,r2) dr(CC_NL,r0,r1,r2) +# define ungei_f(r0,r1,i0) fi(CC_NL,r0,r1,i0) +# define ungei_d(r0,r1,i0) di(CC_NL,r0,r1,i0) +# define ungtr_f(r0,r1,r2) fr(CC_NLE,r0,r1,r2) +# define ungtr_d(r0,r1,r2) dr(CC_NLE,r0,r1,r2) +# define ungti_f(r0,r1,i0) fi(CC_NLE,r0,r1,i0) +# define ungti_d(r0,r1,i0) di(CC_NLE,r0,r1,i0) +# define ltgtr_f(r0,r1,r2) _ltgtr_f(_jit,r0,r1,r2) +static void _ltgtr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ltgtr_d(r0,r1,r2) _ltgtr_d(_jit,r0,r1,r2) +static void _ltgtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ltgti_f(r0,r1,i0) fp(ltgt,r0,r1,i0) +# define ltgti_d(r0,r1,i0) dp(ltgt,r0,r1,i0) +# define ordr_f(r0,r1,r2) fr(CC_NO,r0,r1,r2) +# define ordr_d(r0,r1,r2) dr(CC_NO,r0,r1,r2) +# define ordi_f(r0,r1,i0) fi(CC_NO,r0,r1,i0) +# define ordi_d(r0,r1,i0) di(CC_NO,r0,r1,i0) +# define unordr_f(r0,r1,r2) fr(CC_O,r0,r1,r2) +# define unordr_d(r0,r1,r2) dr(CC_O,r0,r1,r2) +# define unordi_f(r0,r1,i0) fi(CC_O,r0,r1,i0) +# define unordi_d(r0,r1,i0) di(CC_O,r0,r1,i0) +# define bltr_f(i0,r0,r1) bfr(CC_L,i0,r0,r1) +# define bltr_d(i0,r0,r1) bdr(CC_L,i0,r0,r1) +# define blti_f(i0,r0,i1) bfi(CC_L,i0,r0,i1) +# define blti_d(i0,r0,i1) bdi(CC_L,i0,r0,i1) +# define bltr_f_p(i0,r0,r1) bfr_p(CC_L,i0,r0,r1) +# define bltr_d_p(i0,r0,r1) bdr_p(CC_L,i0,r0,r1) +# define blti_f_p(i0,r0,i1) bfi_p(CC_L,i0,r0,i1) +# define blti_d_p(i0,r0,i1) bdi_p(CC_L,i0,r0,i1) +# define bler_f(i0,r0,r1) bfr(CC_LE,i0,r0,r1) +# define bler_d(i0,r0,r1) bdr(CC_LE,i0,r0,r1) +# define blei_f(i0,r0,i1) bfi(CC_LE,i0,r0,i1) +# define blei_d(i0,r0,i1) bdi(CC_LE,i0,r0,i1) +# define bler_f_p(i0,r0,r1) bfr_p(CC_LE,i0,r0,r1) +# define bler_d_p(i0,r0,r1) bdr_p(CC_LE,i0,r0,r1) +# define blei_f_p(i0,r0,i1) bfi_p(CC_LE,i0,r0,i1) +# define blei_d_p(i0,r0,i1) bdi_p(CC_LE,i0,r0,i1) +# define beqr_f(i0,r0,r1) bfr(CC_E,i0,r0,r1) +# define beqr_d(i0,r0,r1) bdr(CC_E,i0,r0,r1) +# define beqi_f(i0,r0,i1) bfi(CC_E,i0,r0,i1) +# define beqi_d(i0,r0,i1) bdi(CC_E,i0,r0,i1) +# define beqr_f_p(i0,r0,r1) bfr_p(CC_E,i0,r0,r1) +# define beqr_d_p(i0,r0,r1) bdr_p(CC_E,i0,r0,r1) +# define beqi_f_p(i0,r0,i1) bfi_p(CC_E,i0,r0,i1) +# define beqi_d_p(i0,r0,i1) bdi_p(CC_E,i0,r0,i1) +# define bger_f(i0,r0,r1) bfr(CC_HE,i0,r0,r1) +# define bger_d(i0,r0,r1) bdr(CC_HE,i0,r0,r1) +# define bgei_f(i0,r0,i1) bfi(CC_HE,i0,r0,i1) +# define bgei_d(i0,r0,i1) bdi(CC_HE,i0,r0,i1) +# define bger_f_p(i0,r0,r1) bfr_p(CC_HE,i0,r0,r1) +# define bger_d_p(i0,r0,r1) bdr_p(CC_HE,i0,r0,r1) +# define bgei_f_p(i0,r0,i1) bfi_p(CC_HE,i0,r0,i1) +# define bgei_d_p(i0,r0,i1) bdi_p(CC_HE,i0,r0,i1) +# define bgtr_f(i0,r0,r1) bfr(CC_H,i0,r0,r1) +# define bgtr_d(i0,r0,r1) bdr(CC_H,i0,r0,r1) +# define bgti_f(i0,r0,i1) bfi(CC_H,i0,r0,i1) +# define bgti_d(i0,r0,i1) bdi(CC_H,i0,r0,i1) +# define bgtr_f_p(i0,r0,r1) bfr_p(CC_H,i0,r0,r1) +# define bgtr_d_p(i0,r0,r1) bdr_p(CC_H,i0,r0,r1) +# define bgti_f_p(i0,r0,i1) bfi_p(CC_H,i0,r0,i1) +# define bgti_d_p(i0,r0,i1) bdi_p(CC_H,i0,r0,i1) +# define bner_f(i0,r0,r1) bfr(CC_NE,i0,r0,r1) +# define bner_d(i0,r0,r1) bdr(CC_NE,i0,r0,r1) +# define bnei_f(i0,r0,i1) bfi(CC_NE,i0,r0,i1) +# define bnei_d(i0,r0,i1) bdi(CC_NE,i0,r0,i1) +# define bner_f_p(i0,r0,r1) bfr_p(CC_NE,i0,r0,r1) +# define bner_d_p(i0,r0,r1) bdr_p(CC_NE,i0,r0,r1) +# define bnei_f_p(i0,r0,i1) bfi_p(CC_NE,i0,r0,i1) +# define bnei_d_p(i0,r0,i1) bdi_p(CC_NE,i0,r0,i1) +# define bunltr_f(i0,r0,r1) bfr(CC_NHE,i0,r0,r1) +# define bunltr_d(i0,r0,r1) bdr(CC_NHE,i0,r0,r1) +# define bunlti_f(i0,r0,i1) bfi(CC_NHE,i0,r0,i1) +# define bunlti_d(i0,r0,i1) bdi(CC_NHE,i0,r0,i1) +# define bunltr_f_p(i0,r0,r1) bfr_p(CC_NHE,i0,r0,r1) +# define bunltr_d_p(i0,r0,r1) bdr_p(CC_NHE,i0,r0,r1) +# define bunlti_f_p(i0,r0,i1) bfi_p(CC_NHE,i0,r0,i1) +# define bunlti_d_p(i0,r0,i1) bdi_p(CC_NHE,i0,r0,i1) +# define bunler_f(i0,r0,r1) bfr(CC_NH,i0,r0,r1) +# define bunler_d(i0,r0,r1) bdr(CC_NH,i0,r0,r1) +# define bunlei_f(i0,r0,i1) bfi(CC_NH,i0,r0,i1) +# define bunlei_d(i0,r0,i1) bdi(CC_NH,i0,r0,i1) +# define bunler_f_p(i0,r0,r1) bfr_p(CC_NH,i0,r0,r1) +# define bunler_d_p(i0,r0,r1) bdr_p(CC_NH,i0,r0,r1) +# define bunlei_f_p(i0,r0,i1) bfi_p(CC_NH,i0,r0,i1) +# define bunlei_d_p(i0,r0,i1) bdi_p(CC_NH,i0,r0,i1) +# define buneqr_f(i0,r0,r1) buneqr(0,i0,r0,r1) +# define buneqr_d(i0,r0,r1) buneqr(1,i0,r0,r1) +# define buneqi_f(i0,r0,i1) buneqi(0,i0,r0,i1) +# define buneqi_d(i0,r0,i1) buneqi(1,i0,r0,i1) +# define buneqr_f_p(i0,r0,r1) buneqr(0,i0,r0,r1) +# define buneqr_d_p(i0,r0,r1) buneqr(1,i0,r0,r1) +# define buneqi_f_p(i0,r0,i1) buneqi(0,i0,r0,i1) +# define buneqi_d_p(i0,r0,i1) buneqi(1,i0,r0,i1) +# define bunger_f(i0,r0,r1) bfr(CC_NL,i0,r0,r1) +# define bunger_d(i0,r0,r1) bdr(CC_NL,i0,r0,r1) +# define bungei_f(i0,r0,i1) bfi(CC_NL,i0,r0,i1) +# define bungei_d(i0,r0,i1) bdi(CC_NL,i0,r0,i1) +# define bunger_f_p(i0,r0,r1) bfr_p(CC_NL,i0,r0,r1) +# define bunger_d_p(i0,r0,r1) bdr_p(CC_NL,i0,r0,r1) +# define bungei_f_p(i0,r0,i1) bfi_p(CC_NL,i0,r0,i1) +# define bungei_d_p(i0,r0,i1) bdi_p(CC_NL,i0,r0,i1) +# define bungtr_f(i0,r0,r1) bfr(CC_NLE,i0,r0,r1) +# define bungtr_d(i0,r0,r1) bdr(CC_NLE,i0,r0,r1) +# define bungti_f(i0,r0,i1) bfi(CC_NLE,i0,r0,i1) +# define bungti_d(i0,r0,i1) bdi(CC_NLE,i0,r0,i1) +# define bungtr_f_p(i0,r0,r1) bfr_p(CC_NLE,i0,r0,r1) +# define bungtr_d_p(i0,r0,r1) bdr_p(CC_NLE,i0,r0,r1) +# define bungti_f_p(i0,r0,i1) bfi_p(CC_NLE,i0,r0,i1) +# define bungti_d_p(i0,r0,i1) bdi_p(CC_NLE,i0,r0,i1) +# define bltgtr_f(i0,r0,r1) bltgtr(0,i0,r0,r1) +# define bltgtr_d(i0,r0,r1) bltgtr(1,i0,r0,r1) +# define bltgti_f(i0,r0,i1) bltgti(0,i0,r0,i1) +# define bltgti_d(i0,r0,i1) bltgti(1,i0,r0,i1) +# define bltgtr_f_p(i0,r0,r1) bltgtr(0,i0,r0,r1) +# define bltgtr_d_p(i0,r0,r1) bltgtr(1,i0,r0,r1) +# define bltgti_f_p(i0,r0,i1) bltgti(0,i0,r0,i1) +# define bltgti_d_p(i0,r0,i1) bltgti(1,i0,r0,i1) +# define bordr_f(i0,r0,r1) bfr(CC_NO,i0,r0,r1) +# define bordr_d(i0,r0,r1) bdr(CC_NO,i0,r0,r1) +# define bordi_f(i0,r0,i1) bfi(CC_NO,i0,r0,i1) +# define bordi_d(i0,r0,i1) bdi(CC_NO,i0,r0,i1) +# define bordr_f_p(i0,r0,r1) bfr_p(CC_NO,i0,r0,r1) +# define bordr_d_p(i0,r0,r1) bdr_p(CC_NO,i0,r0,r1) +# define bordi_f_p(i0,r0,i1) bfi_p(CC_NO,i0,r0,i1) +# define bordi_d_p(i0,r0,i1) bdi_p(CC_NO,i0,r0,i1) +# define bunordr_f(i0,r0,r1) bfr(CC_O,i0,r0,r1) +# define bunordr_d(i0,r0,r1) bdr(CC_O,i0,r0,r1) +# define bunordi_f(i0,r0,i1) bfi(CC_O,i0,r0,i1) +# define bunordi_d(i0,r0,i1) bdi(CC_O,i0,r0,i1) +# define bunordr_f_p(i0,r0,r1) bfr_p(CC_O,i0,r0,r1) +# define bunordr_d_p(i0,r0,r1) bdr_p(CC_O,i0,r0,r1) +# define bunordi_f_p(i0,r0,i1) bfi_p(CC_O,i0,r0,i1) +# define bunordi_d_p(i0,r0,i1) bdi_p(CC_O,i0,r0,i1) +# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1) +static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t); +#endif + +#if CODE +static void +_fp(jit_state_t *_jit, jit_code_t code, + jit_int32_t r0, jit_int32_t r1, jit_float32_t *i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + movi_f(rn(reg), i0); + switch (code) { + case jit_code_addi_f: addr_f(r0, r1, rn(reg)); break; + case jit_code_subi_f: subr_f(r0, r1, rn(reg)); break; + case jit_code_rsbi_f: rsbr_f(r0, r1, rn(reg)); break; + case jit_code_muli_f: mulr_f(r0, r1, rn(reg)); break; + case jit_code_divi_f: divr_f(r0, r1, rn(reg)); break; + case jit_code_uneqi_f: uneqr_f(r0, r1, rn(reg)); break; + case jit_code_ltgti_f: ltgtr_f(r0, r1, rn(reg)); break; + default: abort(); + } + jit_unget_reg(reg); +} + +static void +_dp(jit_state_t *_jit, jit_code_t code, + jit_int32_t r0, jit_int32_t r1, jit_float64_t *i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + movi_d(rn(reg), i0); + switch (code) { + case jit_code_addi_d: addr_d(r0, r1, rn(reg)); break; + case jit_code_subi_d: subr_d(r0, r1, rn(reg)); break; + case jit_code_rsbi_d: rsbr_d(r0, r1, rn(reg)); break; + case jit_code_muli_d: mulr_d(r0, r1, rn(reg)); break; + case jit_code_divi_d: divr_d(r0, r1, rn(reg)); break; + case jit_code_uneqi_d: uneqr_d(r0, r1, rn(reg)); break; + case jit_code_ltgti_d: ltgtr_d(r0, r1, rn(reg)); break; + default: abort(); + } + jit_unget_reg(reg); +} + +static void +_fr(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + LGHI(r0, 1); + CEBR(r1, r2); + w = _jit->pc.w; + BRC(cc, 0); + LGHI(r0, 0); + patch_at(w, _jit->pc.w); +} + +static void +_dr(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + LGHI(r0, 1); + CDBR(r1, r2); + w = _jit->pc.w; + BRC(cc, 0); + LGHI(r0, 0); + patch_at(w, _jit->pc.w); +} + +static void +_fi(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_float32_t *i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi_f(rn(reg), i0); + fr(cc, r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_di(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_float64_t *i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi_d(rn(reg), i0); + dr(cc, r0, r1, rn(reg)); + jit_unget_reg(reg); +} + + +static void +_bfr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + CEBR(r0, r1); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(cc, x16(d)); + else { + assert(s32_p(d)); + BRCL(cc, d); + } +} + +static void +_bdr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + CDBR(r0, r1); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(cc, x16(d)); + else { + assert(s32_p(d)); + BRCL(cc, d); + } +} + +static jit_word_t +_bfr_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CEBR(r0, r1); + w = _jit->pc.w; + BRCL(cc, 0); + return (w); +} + +static jit_word_t +_bdr_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CDBR(r0, r1); + w = _jit->pc.w; + BRCL(cc, 0); + return (w); +} + +static void +_bfi(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_float32_t *i1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi_f(rn(reg), i1); + bfr(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_bdi(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_float64_t *i1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi_d(rn(reg), i1); + bdr(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static jit_word_t +_bfi_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_float32_t *i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi_f(rn(reg), i1); + w = bfr_p(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bdi_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_float64_t *i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi_d(rn(reg), i1); + w = bdr_p(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_buneqr(jit_state_t *_jit, jit_int32_t db, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t unord, ne, w; + if (db) CDBR(r0, r1); + else CEBR(r0, r1); + unord = _jit->pc.w; + BRC(CC_O, 0); /* unord satisfies condition */ + ne = _jit->pc.w; + BRC(CC_NE, 0); /* ne does not satisfy condition */ + patch_at(unord, _jit->pc.w); + w = _jit->pc.w; + BRCL(CC_AL, (i0 - _jit->pc.w) >> 1); + patch_at(ne, _jit->pc.w); + return (w); +} + +static jit_word_t +_buneqi(jit_state_t *_jit, jit_int32_t db, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + if (db) + movi_d(rn(reg), (jit_float64_t *)i1); + else + movi_f(rn(reg), (jit_float32_t *)i1); + w = buneqr(db, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bltgtr(jit_state_t *_jit, jit_int32_t db, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t unord, eq, w; + if (db) CDBR(r0, r1); + else CEBR(r0, r1); + unord = _jit->pc.w; + BRC(CC_O, 0); /* unord does not satisfy condition */ + eq = _jit->pc.w; + BRC(CC_E, 0); /* eq does not satisfy condition */ + w = _jit->pc.w; + BRCL(CC_AL, (i0 - _jit->pc.w) >> 1); + patch_at(unord, _jit->pc.w); + patch_at(eq, _jit->pc.w); + return (w); +} + +static jit_word_t +_bltgti(jit_state_t *_jit, jit_int32_t db, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + if (db) + movi_d(rn(reg), (jit_float64_t *)i1); + else + movi_f(rn(reg), (jit_float32_t *)i1); + w = bltgtr(db, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_movr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + LER(r0, r1); +} + +static void +_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_int32_t reg; + + if (*(jit_int32_t *)i0 == 0) + LZER(r0); + else if (_jitc->no_data) { + data.f = *i0; + reg = jit_get_reg_but_zero(0); + movi(rn(reg), data.i & 0xffffffff); + stxi_i(-4, _FP_REGNO, rn(reg)); + jit_unget_reg_but_zero(reg); + ldxi_f(r0, _FP_REGNO, -4); + } + else + ldi_f(r0, (jit_word_t)i0); +} + +static void +_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + LDR(r0, r1); +} + +static void +_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + union { +#if __WORDSIZE == 32 + jit_int32_t i[2]; +#else + jit_int64_t l; +#endif + jit_float64_t d; + } data; + jit_int32_t reg; + + if (*(jit_int64_t *)i0 == 0) + LZDR(r0); + else if (_jitc->no_data) { + data.d = *i0; + reg = jit_get_reg_but_zero(0); +#if __WORDSIZE == 32 + movi(rn(reg), data.i[0]); + stxi_i(-8, _FP_REGNO, rn(reg)); + movi(rn(reg), data.i[1]); + stxi_i(-4, _FP_REGNO, rn(reg)); +#else + movi(rn(reg), data.l); + stxi_l(-8, _FP_REGNO, rn(reg)); +#endif + jit_unget_reg_but_zero(reg); + ldxi_d(r0, _FP_REGNO, -8); + } + else + ldi_d(r0, (jit_word_t)i0); +} + +static void +_addr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + AEBR(r0, r1); + else { + movr_f(r0, r1); + AEBR(r0, r2); + } +} + +static void +_addr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + ADBR(r0, r1); + else { + movr_d(r0, r1); + ADBR(r0, r2); + } +} + +static void +_subr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_fpr); + movr_f(rn(reg), r2); + movr_f(r0, r1); + SEBR(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr_f(r0, r1); + SEBR(r0, r2); + } +} + +static void +_subr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_fpr); + movr_d(rn(reg), r2); + movr_d(r0, r1); + SDBR(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr_d(r0, r1); + SDBR(r0, r2); + } +} + +static void +_mulr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + MEEBR(r0, r1); + else { + movr_f(r0, r1); + MEEBR(r0, r2); + } +} + +static void +_mulr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + MDBR(r0, r1); + else { + movr_d(r0, r1); + MDBR(r0, r2); + } +} + +static void +_divr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_fpr); + movr_f(rn(reg), r2); + movr_f(r0, r1); + DEBR(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr_f(r0, r1); + DEBR(r0, r2); + } +} + +static void +_divr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_fpr); + movr_d(rn(reg), r2); + movr_d(r0, r1); + DDBR(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr_d(r0, r1); + DDBR(r0, r2); + } +} + +static void +_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + ldr_f(r0, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +static void +_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + ldr_d(r0, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +static void +_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movr(rn(reg), r1); + addr(rn(reg), rn(reg), r2); + ldr_f(r0, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +static void +_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movr(rn(reg), r1); + addr(rn(reg), rn(reg), r2); + ldr_d(r0, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +static void +_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (u12_p(i0)) + LE(r0, i0, 0, r1); + else if (s20_p(i0)) + LEY(r0, x20(i0), 0, r1); + else { + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + addr(rn(reg), rn(reg), r1); + ldr_f(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (u12_p(i0)) + LD(r0, i0, 0, r1); + else if (s20_p(i0)) + LDY(r0, x20(i0), 0, r1); + else { + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + addr(rn(reg), rn(reg), r1); + ldr_d(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + str_f(rn(reg), r0); + jit_unget_reg_but_zero(reg); +} + +static void +_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + str_d(rn(reg), r0); + jit_unget_reg_but_zero(reg); +} + +static void +_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movr(rn(reg), r0); + addr(rn(reg), rn(reg), r1); + str_f(rn(reg), r2); + jit_unget_reg_but_zero(reg); +} + +static void +_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(0); + movr(rn(reg), r0); + addr(rn(reg), rn(reg), r1); + str_d(rn(reg), r2); + jit_unget_reg_but_zero(reg); +} + +static void +_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (u12_p(i0)) + STE(r1, i0, 0, r0); + else if (s20_p(i0)) + STEY(r1, x20(i0), 0, r0); + else { + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + addr(rn(reg), rn(reg), r0); + str_f(rn(reg), r1); + jit_unget_reg_but_zero(reg); + } +} + +static void +_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (u12_p(i0)) + STD(r1, i0, 0, r0); + else if (s20_p(i0)) + STDY(r1, x20(i0), 0, r0); + else { + reg = jit_get_reg_but_zero(0); + movi(rn(reg), i0); + addr(rn(reg), rn(reg), r0); + str_d(rn(reg), r1); + jit_unget_reg_but_zero(reg); + } +} + +static void +_uneqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t unord, eq; + movi(r0, 1); /* set to one */ + CEBR(r1, r2); + unord = _jit->pc.w; /* keep set to one if unord */ + BRC(CC_O, 0); + eq = _jit->pc.w; + BRC(CC_E, 0); /* keep set to one if eq */ + movi(r0, 0); /* set to zero */ + patch_at(unord, _jit->pc.w); + patch_at(eq, _jit->pc.w); +} + +static void +_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t unord, eq; + movi(r0, 1); /* set to one */ + CDBR(r1, r2); + unord = _jit->pc.w; /* keep set to one if unord */ + BRC(CC_O, 0); + eq = _jit->pc.w; + BRC(CC_E, 0); /* keep set to one if eq */ + movi(r0, 0); /* set to zero */ + patch_at(unord, _jit->pc.w); + patch_at(eq, _jit->pc.w); +} + +static void +_ltgtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t unord, eq; + movi(r0, 0); /* set to zero */ + CEBR(r1, r2); + unord = _jit->pc.w; /* keep set to zero if unord */ + BRC(CC_O, 0); + eq = _jit->pc.w; + BRC(CC_E, 0); /* keep set to zero if eq */ + movi(r0, 1); /* set to one */ + patch_at(unord, _jit->pc.w); + patch_at(eq, _jit->pc.w); +} + +static void +_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t unord, eq; + movi(r0, 0); /* set to zero */ + CDBR(r1, r2); + unord = _jit->pc.w; /* keep set to zero if unord */ + BRC(CC_O, 0); + eq = _jit->pc.w; + BRC(CC_E, 0); /* keep set to zero if eq */ + movi(r0, 1); /* set to one */ + patch_at(unord, _jit->pc.w); + patch_at(eq, _jit->pc.w); +} + +static void +_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t rg0; + jit_int32_t rg1; + jit_int32_t rg2; + jit_word_t ge_code; + jit_word_t lt_code; + + assert(_jitc->function->self.call & jit_call_varargs); + + rg0 = jit_get_reg_but_zero(jit_class_gpr); + rg1 = jit_get_reg_but_zero(jit_class_gpr); + + /* Load the fp offset in save area in the first temporary. */ + ldxi(rn(rg0), r1, offsetof(jit_va_list_t, fpoff)); + + /* Jump over if there are no remaining arguments in the save area. */ + ge_code = bgei_p(_jit->pc.w, rn(rg0), NUM_FLOAT_REG_ARGS); + + /* Load the save area pointer in the second temporary. */ + ldxi(rn(rg1), r1, offsetof(jit_va_list_t, save)); + + /* Scale offset. */ + rg2 = jit_get_reg_but_zero(0); + lshi(rn(rg2), rn(rg0), 3); + /* Add offset to saved area */ + addi(rn(rg2), rn(rg2), 16 * sizeof(jit_word_t)); + + /* Load the vararg argument in the first argument. */ + ldxr_d(r0, rn(rg1), rn(rg2)); + jit_unget_reg_but_zero(rg2); + + /* Update the fp offset. */ + addi(rn(rg0), rn(rg0), 1); + stxi(offsetof(jit_va_list_t, fpoff), r1, rn(rg0)); + + /* Will only need one temporary register below. */ + jit_unget_reg_but_zero(rg1); + + /* Jump over overflow code. */ + lt_code = jmpi_p(_jit->pc.w); + + /* Where to land if argument is in overflow area. */ + patch_at(ge_code, _jit->pc.w); + + /* Load overflow pointer. */ + ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over)); + + /* Load argument. */ + ldr_d(r0, rn(rg0)); + + /* Update overflow pointer. */ + addi(rn(rg0), rn(rg0), sizeof(jit_float64_t)); + stxi(offsetof(jit_va_list_t, over), r1, rn(rg0)); + + /* Where to land if argument is in save area. */ + patch_at(lt_code, _jit->pc.w); + + jit_unget_reg_but_zero(rg0); +} +#endif diff --git a/deps/lightning/lib/jit_s390-sz.c b/deps/lightning/lib/jit_s390-sz.c new file mode 100644 index 0000000..bb8b2dc --- /dev/null +++ b/deps/lightning/lib/jit_s390-sz.c @@ -0,0 +1,804 @@ + +#if __WORDSIZE == 32 +#define JIT_INSTR_MAX 104 + 0, /* data */ + 0, /* live */ + 6, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 2, /* label */ + 42, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 44, /* va_start */ + 104, /* va_arg */ + 100, /* va_arg_d */ + 0, /* va_end */ + 8, /* addr */ + 24, /* addi */ + 8, /* addcr */ + 20, /* addci */ + 8, /* addxr */ + 12, /* addxi */ + 12, /* subr */ + 24, /* subi */ + 12, /* subcr */ + 20, /* subci */ + 12, /* subxr */ + 12, /* subxi */ + 28, /* rsbi */ + 8, /* mulr */ + 24, /* muli */ + 60, /* qmulr */ + 68, /* qmuli */ + 16, /* qmulr_u */ + 32, /* qmuli_u */ + 12, /* divr */ + 28, /* divi */ + 16, /* divr_u */ + 32, /* divi_u */ + 16, /* qdivr */ + 20, /* qdivi */ + 20, /* qdivr_u */ + 24, /* qdivi_u */ + 12, /* remr */ + 28, /* remi */ + 16, /* remr_u */ + 32, /* remi_u */ + 8, /* andr */ + 20, /* andi */ + 8, /* orr */ + 20, /* ori */ + 8, /* xorr */ + 24, /* xori */ + 6, /* lshr */ + 10, /* lshi */ + 6, /* rshr */ + 10, /* rshi */ + 6, /* rshr_u */ + 10, /* rshi_u */ + 4, /* negr */ + 12, /* comr */ + 20, /* ltr */ + 24, /* lti */ + 20, /* ltr_u */ + 24, /* lti_u */ + 20, /* ler */ + 24, /* lei */ + 20, /* ler_u */ + 24, /* lei_u */ + 20, /* eqr */ + 24, /* eqi */ + 20, /* ger */ + 24, /* gei */ + 20, /* ger_u */ + 24, /* gei_u */ + 20, /* gtr */ + 24, /* gti */ + 20, /* gtr_u */ + 24, /* gti_u */ + 20, /* ner */ + 24, /* nei */ + 4, /* movr */ + 16, /* movi */ + 4, /* extr_c */ + 4, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 4, /* extr_i */ + 4, /* extr_ui */ + 4, /* htonr_us */ + 4, /* htonr_ui */ + 4, /* htonr_ul */ + 6, /* ldr_c */ + 18, /* ldi_c */ + 6, /* ldr_uc */ + 18, /* ldi_uc */ + 6, /* ldr_s */ + 18, /* ldi_s */ + 6, /* ldr_us */ + 18, /* ldi_us */ + 6, /* ldr_i */ + 18, /* ldi_i */ + 6, /* ldr_ui */ + 18, /* ldi_ui */ + 6, /* ldr_l */ + 18, /* ldi_l */ + 14, /* ldxr_c */ + 26, /* ldxi_c */ + 14, /* ldxr_uc */ + 26, /* ldxi_uc */ + 14, /* ldxr_s */ + 26, /* ldxi_s */ + 14, /* ldxr_us */ + 26, /* ldxi_us */ + 14, /* ldxr_i */ + 26, /* ldxi_i */ + 14, /* ldxr_ui */ + 26, /* ldxi_ui */ + 14, /* ldxr_l */ + 26, /* ldxi_l */ + 4, /* str_c */ + 16, /* sti_c */ + 4, /* str_s */ + 16, /* sti_s */ + 4, /* str_i */ + 16, /* sti_i */ + 6, /* str_l */ + 18, /* sti_l */ + 12, /* stxr_c */ + 28, /* stxi_c */ + 12, /* stxr_s */ + 28, /* stxi_s */ + 12, /* stxr_i */ + 28, /* stxi_i */ + 14, /* stxr_l */ + 30, /* stxi_l */ + 10, /* bltr */ + 14, /* blti */ + 10, /* bltr_u */ + 14, /* blti_u */ + 10, /* bler */ + 14, /* blei */ + 10, /* bler_u */ + 14, /* blei_u */ + 10, /* beqr */ + 26, /* beqi */ + 10, /* bger */ + 14, /* bgei */ + 10, /* bger_u */ + 14, /* bgei_u */ + 10, /* bgtr */ + 14, /* bgti */ + 10, /* bgtr_u */ + 14, /* bgti_u */ + 10, /* bner */ + 26, /* bnei */ + 18, /* bmsr */ + 18, /* bmsi */ + 18, /* bmcr */ + 18, /* bmci */ + 10, /* boaddr */ + 14, /* boaddi */ + 10, /* boaddr_u */ + 14, /* boaddi_u */ + 10, /* bxaddr */ + 14, /* bxaddi */ + 10, /* bxaddr_u */ + 14, /* bxaddi_u */ + 10, /* bosubr */ + 14, /* bosubi */ + 10, /* bosubr_u */ + 14, /* bosubi_u */ + 10, /* bxsubr */ + 14, /* bxsubi */ + 10, /* bxsubr_u */ + 14, /* bxsubi_u */ + 2, /* jmpr */ + 18, /* jmpi */ + 2, /* callr */ + 18, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 40, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 6, /* addr_f */ + 26, /* addi_f */ + 8, /* subr_f */ + 26, /* subi_f */ + 28, /* rsbi_f */ + 6, /* mulr_f */ + 26, /* muli_f */ + 8, /* divr_f */ + 26, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 16, /* ltr_f */ + 36, /* lti_f */ + 16, /* ler_f */ + 36, /* lei_f */ + 16, /* eqr_f */ + 36, /* eqi_f */ + 16, /* ger_f */ + 36, /* gei_f */ + 16, /* gtr_f */ + 36, /* gti_f */ + 16, /* ner_f */ + 36, /* nei_f */ + 16, /* unltr_f */ + 36, /* unlti_f */ + 16, /* unler_f */ + 36, /* unlei_f */ + 20, /* uneqr_f */ + 40, /* uneqi_f */ + 16, /* unger_f */ + 36, /* ungei_f */ + 16, /* ungtr_f */ + 36, /* ungti_f */ + 20, /* ltgtr_f */ + 40, /* ltgti_f */ + 16, /* ordr_f */ + 36, /* ordi_f */ + 16, /* unordr_f */ + 36, /* unordi_f */ + 4, /* truncr_f_i */ + 4, /* truncr_f_l */ + 4, /* extr_f */ + 4, /* extr_d_f */ + 2, /* movr_f */ + 20, /* movi_f */ + 4, /* ldr_f */ + 16, /* ldi_f */ + 12, /* ldxr_f */ + 24, /* ldxi_f */ + 4, /* str_f */ + 16, /* sti_f */ + 12, /* stxr_f */ + 24, /* stxi_f */ + 10, /* bltr_f */ + 30, /* blti_f */ + 10, /* bler_f */ + 30, /* blei_f */ + 10, /* beqr_f */ + 30, /* beqi_f */ + 10, /* bger_f */ + 30, /* bgei_f */ + 10, /* bgtr_f */ + 30, /* bgti_f */ + 10, /* bner_f */ + 30, /* bnei_f */ + 10, /* bunltr_f */ + 30, /* bunlti_f */ + 10, /* bunler_f */ + 30, /* bunlei_f */ + 18, /* buneqr_f */ + 38, /* buneqi_f */ + 10, /* bunger_f */ + 30, /* bungei_f */ + 10, /* bungtr_f */ + 30, /* bungti_f */ + 18, /* bltgtr_f */ + 38, /* bltgti_f */ + 10, /* bordr_f */ + 30, /* bordi_f */ + 10, /* bunordr_f */ + 30, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 6, /* addr_d */ + 26, /* addi_d */ + 8, /* subr_d */ + 26, /* subi_d */ + 28, /* rsbi_d */ + 6, /* mulr_d */ + 26, /* muli_d */ + 8, /* divr_d */ + 26, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 16, /* ltr_d */ + 36, /* lti_d */ + 16, /* ler_d */ + 36, /* lei_d */ + 16, /* eqr_d */ + 36, /* eqi_d */ + 16, /* ger_d */ + 36, /* gei_d */ + 16, /* gtr_d */ + 36, /* gti_d */ + 16, /* ner_d */ + 36, /* nei_d */ + 16, /* unltr_d */ + 36, /* unlti_d */ + 16, /* unler_d */ + 36, /* unlei_d */ + 20, /* uneqr_d */ + 40, /* uneqi_d */ + 16, /* unger_d */ + 36, /* ungei_d */ + 16, /* ungtr_d */ + 36, /* ungti_d */ + 20, /* ltgtr_d */ + 40, /* ltgti_d */ + 16, /* ordr_d */ + 36, /* ordi_d */ + 16, /* unordr_d */ + 36, /* unordi_d */ + 4, /* truncr_d_i */ + 4, /* truncr_d_l */ + 4, /* extr_d */ + 4, /* extr_f_d */ + 2, /* movr_d */ + 24, /* movi_d */ + 4, /* ldr_d */ + 16, /* ldi_d */ + 12, /* ldxr_d */ + 24, /* ldxi_d */ + 4, /* str_d */ + 16, /* sti_d */ + 12, /* stxr_d */ + 24, /* stxi_d */ + 10, /* bltr_d */ + 30, /* blti_d */ + 10, /* bler_d */ + 30, /* blei_d */ + 10, /* beqr_d */ + 34, /* beqi_d */ + 10, /* bger_d */ + 30, /* bgei_d */ + 10, /* bgtr_d */ + 30, /* bgti_d */ + 10, /* bner_d */ + 30, /* bnei_d */ + 10, /* bunltr_d */ + 30, /* bunlti_d */ + 10, /* bunler_d */ + 30, /* bunlei_d */ + 18, /* buneqr_d */ + 38, /* buneqi_d */ + 10, /* bunger_d */ + 30, /* bungei_d */ + 10, /* bungtr_d */ + 30, /* bungti_d */ + 18, /* bltgtr_d */ + 38, /* bltgti_d */ + 10, /* bordr_d */ + 30, /* bordi_d */ + 10, /* bunordr_d */ + 30, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __WORDSIZE */ + +#if __WORDSIZE == 64 +#define JIT_INSTR_MAX 104 + 0, /* data */ + 0, /* live */ + 6, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 2, /* label */ + 42, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 44, /* va_start */ + 104, /* va_arg */ + 100, /* va_arg_d */ + 0, /* va_end */ + 8, /* addr */ + 24, /* addi */ + 8, /* addcr */ + 20, /* addci */ + 8, /* addxr */ + 12, /* addxi */ + 12, /* subr */ + 24, /* subi */ + 12, /* subcr */ + 20, /* subci */ + 12, /* subxr */ + 12, /* subxi */ + 28, /* rsbi */ + 8, /* mulr */ + 24, /* muli */ + 60, /* qmulr */ + 68, /* qmuli */ + 16, /* qmulr_u */ + 32, /* qmuli_u */ + 12, /* divr */ + 28, /* divi */ + 16, /* divr_u */ + 32, /* divi_u */ + 16, /* qdivr */ + 20, /* qdivi */ + 20, /* qdivr_u */ + 24, /* qdivi_u */ + 12, /* remr */ + 28, /* remi */ + 16, /* remr_u */ + 32, /* remi_u */ + 8, /* andr */ + 20, /* andi */ + 8, /* orr */ + 20, /* ori */ + 8, /* xorr */ + 24, /* xori */ + 6, /* lshr */ + 10, /* lshi */ + 6, /* rshr */ + 10, /* rshi */ + 6, /* rshr_u */ + 10, /* rshi_u */ + 4, /* negr */ + 12, /* comr */ + 20, /* ltr */ + 24, /* lti */ + 20, /* ltr_u */ + 24, /* lti_u */ + 20, /* ler */ + 24, /* lei */ + 20, /* ler_u */ + 24, /* lei_u */ + 20, /* eqr */ + 24, /* eqi */ + 20, /* ger */ + 24, /* gei */ + 20, /* ger_u */ + 24, /* gei_u */ + 20, /* gtr */ + 24, /* gti */ + 20, /* gtr_u */ + 24, /* gti_u */ + 20, /* ner */ + 24, /* nei */ + 4, /* movr */ + 16, /* movi */ + 4, /* extr_c */ + 4, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 4, /* extr_i */ + 4, /* extr_ui */ + 4, /* htonr_us */ + 4, /* htonr_ui */ + 4, /* htonr_ul */ + 6, /* ldr_c */ + 18, /* ldi_c */ + 6, /* ldr_uc */ + 18, /* ldi_uc */ + 6, /* ldr_s */ + 18, /* ldi_s */ + 6, /* ldr_us */ + 18, /* ldi_us */ + 6, /* ldr_i */ + 18, /* ldi_i */ + 6, /* ldr_ui */ + 18, /* ldi_ui */ + 6, /* ldr_l */ + 18, /* ldi_l */ + 14, /* ldxr_c */ + 26, /* ldxi_c */ + 14, /* ldxr_uc */ + 26, /* ldxi_uc */ + 14, /* ldxr_s */ + 26, /* ldxi_s */ + 14, /* ldxr_us */ + 26, /* ldxi_us */ + 14, /* ldxr_i */ + 26, /* ldxi_i */ + 14, /* ldxr_ui */ + 26, /* ldxi_ui */ + 14, /* ldxr_l */ + 26, /* ldxi_l */ + 4, /* str_c */ + 16, /* sti_c */ + 4, /* str_s */ + 16, /* sti_s */ + 4, /* str_i */ + 16, /* sti_i */ + 6, /* str_l */ + 18, /* sti_l */ + 12, /* stxr_c */ + 28, /* stxi_c */ + 12, /* stxr_s */ + 28, /* stxi_s */ + 12, /* stxr_i */ + 28, /* stxi_i */ + 14, /* stxr_l */ + 30, /* stxi_l */ + 10, /* bltr */ + 14, /* blti */ + 10, /* bltr_u */ + 14, /* blti_u */ + 10, /* bler */ + 14, /* blei */ + 10, /* bler_u */ + 14, /* blei_u */ + 10, /* beqr */ + 26, /* beqi */ + 10, /* bger */ + 14, /* bgei */ + 10, /* bger_u */ + 14, /* bgei_u */ + 10, /* bgtr */ + 14, /* bgti */ + 10, /* bgtr_u */ + 14, /* bgti_u */ + 10, /* bner */ + 26, /* bnei */ + 18, /* bmsr */ + 18, /* bmsi */ + 18, /* bmcr */ + 18, /* bmci */ + 10, /* boaddr */ + 14, /* boaddi */ + 10, /* boaddr_u */ + 14, /* boaddi_u */ + 10, /* bxaddr */ + 14, /* bxaddi */ + 10, /* bxaddr_u */ + 14, /* bxaddi_u */ + 10, /* bosubr */ + 14, /* bosubi */ + 10, /* bosubr_u */ + 14, /* bosubi_u */ + 10, /* bxsubr */ + 14, /* bxsubi */ + 10, /* bxsubr_u */ + 14, /* bxsubi_u */ + 2, /* jmpr */ + 18, /* jmpi */ + 2, /* callr */ + 18, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 40, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 6, /* addr_f */ + 26, /* addi_f */ + 8, /* subr_f */ + 26, /* subi_f */ + 28, /* rsbi_f */ + 6, /* mulr_f */ + 26, /* muli_f */ + 8, /* divr_f */ + 26, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 16, /* ltr_f */ + 36, /* lti_f */ + 16, /* ler_f */ + 36, /* lei_f */ + 16, /* eqr_f */ + 36, /* eqi_f */ + 16, /* ger_f */ + 36, /* gei_f */ + 16, /* gtr_f */ + 36, /* gti_f */ + 16, /* ner_f */ + 36, /* nei_f */ + 16, /* unltr_f */ + 36, /* unlti_f */ + 16, /* unler_f */ + 36, /* unlei_f */ + 20, /* uneqr_f */ + 40, /* uneqi_f */ + 16, /* unger_f */ + 36, /* ungei_f */ + 16, /* ungtr_f */ + 36, /* ungti_f */ + 20, /* ltgtr_f */ + 40, /* ltgti_f */ + 16, /* ordr_f */ + 36, /* ordi_f */ + 16, /* unordr_f */ + 36, /* unordi_f */ + 4, /* truncr_f_i */ + 4, /* truncr_f_l */ + 4, /* extr_f */ + 4, /* extr_d_f */ + 2, /* movr_f */ + 20, /* movi_f */ + 4, /* ldr_f */ + 16, /* ldi_f */ + 12, /* ldxr_f */ + 24, /* ldxi_f */ + 4, /* str_f */ + 16, /* sti_f */ + 12, /* stxr_f */ + 24, /* stxi_f */ + 10, /* bltr_f */ + 30, /* blti_f */ + 10, /* bler_f */ + 30, /* blei_f */ + 10, /* beqr_f */ + 30, /* beqi_f */ + 10, /* bger_f */ + 30, /* bgei_f */ + 10, /* bgtr_f */ + 30, /* bgti_f */ + 10, /* bner_f */ + 30, /* bnei_f */ + 10, /* bunltr_f */ + 30, /* bunlti_f */ + 10, /* bunler_f */ + 30, /* bunlei_f */ + 18, /* buneqr_f */ + 38, /* buneqi_f */ + 10, /* bunger_f */ + 30, /* bungei_f */ + 10, /* bungtr_f */ + 30, /* bungti_f */ + 18, /* bltgtr_f */ + 38, /* bltgti_f */ + 10, /* bordr_f */ + 30, /* bordi_f */ + 10, /* bunordr_f */ + 30, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 6, /* addr_d */ + 26, /* addi_d */ + 8, /* subr_d */ + 26, /* subi_d */ + 28, /* rsbi_d */ + 6, /* mulr_d */ + 26, /* muli_d */ + 8, /* divr_d */ + 26, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 16, /* ltr_d */ + 36, /* lti_d */ + 16, /* ler_d */ + 36, /* lei_d */ + 16, /* eqr_d */ + 36, /* eqi_d */ + 16, /* ger_d */ + 36, /* gei_d */ + 16, /* gtr_d */ + 36, /* gti_d */ + 16, /* ner_d */ + 36, /* nei_d */ + 16, /* unltr_d */ + 36, /* unlti_d */ + 16, /* unler_d */ + 36, /* unlei_d */ + 20, /* uneqr_d */ + 40, /* uneqi_d */ + 16, /* unger_d */ + 36, /* ungei_d */ + 16, /* ungtr_d */ + 36, /* ungti_d */ + 20, /* ltgtr_d */ + 40, /* ltgti_d */ + 16, /* ordr_d */ + 36, /* ordi_d */ + 16, /* unordr_d */ + 36, /* unordi_d */ + 4, /* truncr_d_i */ + 4, /* truncr_d_l */ + 4, /* extr_d */ + 4, /* extr_f_d */ + 2, /* movr_d */ + 24, /* movi_d */ + 4, /* ldr_d */ + 16, /* ldi_d */ + 12, /* ldxr_d */ + 24, /* ldxi_d */ + 4, /* str_d */ + 16, /* sti_d */ + 12, /* stxr_d */ + 24, /* stxi_d */ + 10, /* bltr_d */ + 30, /* blti_d */ + 10, /* bler_d */ + 30, /* blei_d */ + 10, /* beqr_d */ + 34, /* beqi_d */ + 10, /* bger_d */ + 30, /* bgei_d */ + 10, /* bgtr_d */ + 30, /* bgti_d */ + 10, /* bner_d */ + 30, /* bnei_d */ + 10, /* bunltr_d */ + 30, /* bunlti_d */ + 10, /* bunler_d */ + 30, /* bunlei_d */ + 18, /* buneqr_d */ + 38, /* buneqi_d */ + 10, /* bunger_d */ + 30, /* bungei_d */ + 10, /* bungtr_d */ + 30, /* bungti_d */ + 18, /* bltgtr_d */ + 38, /* bltgti_d */ + 10, /* bordr_d */ + 30, /* bordi_d */ + 10, /* bunordr_d */ + 30, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __WORDSIZE */ diff --git a/deps/lightning/lib/jit_s390.c b/deps/lightning/lib/jit_s390.c new file mode 100644 index 0000000..7cd1d7f --- /dev/null +++ b/deps/lightning/lib/jit_s390.c @@ -0,0 +1,1690 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include <lightning.h> +#include <lightning/jit_private.h> + +#if __WORDSIZE == 32 +# define NUM_FLOAT_REG_ARGS 2 +#else +# define NUM_FLOAT_REG_ARGS 4 +#endif +#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 5) +#define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < NUM_FLOAT_REG_ARGS) + +/* + * Types + */ +typedef struct jit_va_list { + /* The offsets are "1" based, as addresses are fixed in the + * standard stack frame format. */ + jit_word_t gpoff; + jit_word_t fpoff; + + /* Easier when there is an explicitly defined type... +(gdb) ptype ap +type = struct __va_list_tag { + long __gpr; + long __fpr; + void *__overflow_arg_area; + void *__reg_save_area; + + Note that gopff (__gpr) and fpoff (__fpr) are jit_word_t equivalent + and, again, "1" (unit) based, so must be adjusted at va_arg time. + */ + jit_pointer_t over; + jit_pointer_t save; + + /* For variadic functions, always allocate space to save callee + * save fpr registers. + * Note that s390 has a standard stack frame format that lightning + * does not fully comply with, but for variadic functions it must, + * for those (variadic) do not use the "empty" spaces for any + * callee save fpr register, but save them after the va_list + * space; and use the standard stack frame format, as required + * by variadic functions (and have a compatible va_list pointer). */ + jit_float64_t f8; + jit_float64_t f9; + jit_float64_t f10; + jit_float64_t f11; + jit_float64_t f12; + jit_float64_t f13; + jit_float64_t f14; + jit_float64_t f15; +} jit_va_list_t; + +/* + * Prototypes + */ +#define jit_get_reg_pair() _jit_get_reg_pair(_jit) +static jit_int32_t _jit_get_reg_pair(jit_state_t*); +#define jit_unget_reg_pair(regno) _jit_unget_reg_pair(_jit,regno) +static void _jit_unget_reg_pair(jit_state_t*,jit_int32_t); +#define jit_get_reg_but_zero(flags) _jit_get_reg_but_zero(_jit,flags) +static jit_int32_t _jit_get_reg_but_zero(jit_state_t*,jit_int32_t); +#define jit_unget_reg_but_zero(reg) jit_unget_reg(reg) +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); + +/* libgcc */ +extern void __clear_cache(void *, void *); + +#define PROTO 1 +# include "jit_s390-cpu.c" +# include "jit_s390-fpu.c" +#undef PROTO + +/* + * Initialization + */ +jit_register_t _rvs[] = { + { rc(gpr) | 0x0, "%r0" }, + { rc(gpr) | 0x1, "%r1" }, + { rc(gpr) | rc(sav) | 0xc, "%r12" }, + { rc(gpr) | rc(sav) | 0xb, "%r11" }, + { rc(gpr) | rc(sav) | 0xa, "%r10" }, + { rc(gpr) | rc(sav) | 0x9, "%r9" }, + { rc(gpr) | rc(sav) | 0x8, "%r8" }, + { rc(gpr) | rc(sav) | 0x7, "%r7" }, + { rc(gpr) | rc(arg) | rc(sav) | 0x6,"%r6" }, + { rc(gpr) | rc(arg) | 0x5, "%r5" }, + { rc(gpr) | rc(arg) | 0x4, "%r4" }, + { rc(gpr) | rc(arg) | 0x3, "%r3" }, + { rc(gpr) | rc(arg) | 0x2, "%r2" }, + { rc(sav) | 0xd, "%r13" }, /* used as JIT_FP */ + { 0xe, "%r14" }, + { rc(sav) | 0xf, "%r15" }, + { rc(fpr) | 0x1, "%f1" }, + { rc(fpr) | 0x3, "%f3" }, + { rc(fpr) | 0x5, "%f5" }, + { rc(fpr) | 0x7, "%f7" }, + { rc(fpr) | rc(sav) | 0xe, "%f14" }, + /* Do not use as temporary to simplify stack layout */ + { 0xf, "%f15" }, + { rc(fpr) | rc(sav) | 0x8, "%f8" }, + { rc(fpr) | rc(sav) | 0x9, "%f9" }, + { rc(fpr) | rc(sav) | 0xa, "%f10" }, + { rc(fpr) | rc(sav) | 0xb, "%f11" }, + { rc(fpr) | rc(sav) | 0xc, "%f12" }, + { rc(fpr) | rc(sav) | 0xd, "%f13" }, + { rc(fpr) | rc(arg) | 0x6, "%f6" }, + { rc(fpr) | rc(arg) | 0x4, "%f4" }, + { rc(fpr) | rc(arg) | 0x2, "%f2" }, + { rc(fpr) | rc(arg) | 0x0, "%f0" }, + { _NOREG, "<none>" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ +} + +void +_jit_init(jit_state_t *_jit) +{ + _jitc->reglen = jit_size(_rvs) - 1; +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + _jitc->function->self.size = stack_framesize; + _jitc->function->self.argi = _jitc->function->self.argf = + _jitc->function->self.aoff = _jitc->function->self.alen = 0; + /* preallocate 8 bytes if not using a constant data buffer */ + if (_jitc->no_data) + _jitc->function->self.aoff = -8; + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + assert(_jitc->function); + switch (length) { + case 0: case 1: break; + case 2: _jitc->function->self.aoff &= -2; break; + case 3: case 4: _jitc->function->self.aoff &= -4; break; + default: _jitc->function->self.aoff &= -8; break; + } + _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } + return (_jitc->function->self.aoff); +} + +void +_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) +{ + jit_int32_t reg; + assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); + if (!_jitc->function->allocar) { + _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); + _jitc->function->allocar = 1; + } + reg = jit_get_reg(jit_class_gpr); + jit_negr(reg, v); + jit_andi(reg, reg, -8); + jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); + jit_addr(u, u, reg); + jit_addr(JIT_SP, JIT_SP, reg); + jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); + jit_unget_reg(reg); + jit_dec_synth(); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + assert(_jitc->function); + jit_inc_synth(ret); + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr, u); + jit_movr(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti(jit_state_t *_jit, jit_word_t u) +{ + jit_inc_synth_w(reti, u); + jit_movi(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_f, u); + jit_movr_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_inc_synth_f(reti_f, u); + jit_movi_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_d, u); + jit_movr_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_inc_synth_d(reti_d, u); + jit_movi_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_epilog(jit_state_t *_jit) +{ + assert(_jitc->function); + assert(_jitc->function->epilog->next == NULL); + jit_link(_jitc->function->epilog); + _jitc->function = NULL; +} + +jit_bool_t +_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) +{ + if (u->code == jit_code_arg) + return (jit_arg_reg_p(u->u.w)); + assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d); + return (jit_arg_f_reg_p(u->u.w)); +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + jit_inc_synth(ellipsis); + if (_jitc->prepare) { + jit_link_prepare(); + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; + } + else { + jit_link_prolog(); + assert(!(_jitc->function->self.call & jit_call_varargs)); + _jitc->function->self.call |= jit_call_varargs; + + /* Allocate va_list like object in the stack. */ + _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t)); + + /* Initialize gp offset in save area. */ + if (jit_arg_reg_p(_jitc->function->self.argi)) + _jitc->function->vagp = _jitc->function->self.argi; + else + _jitc->function->vagp = 5; + + /* Initialize fp offset in save area. */ + if (jit_arg_f_reg_p(_jitc->function->self.argf)) + _jitc->function->vafp = _jitc->function->self.argf; + else + _jitc->function->vafp = NUM_FLOAT_REG_ARGS; + } + jit_dec_synth(); +} + +void +_jit_va_push(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(va_push, u); + jit_pushargr(u); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + if (jit_arg_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + if (jit_arg_f_reg_p(_jitc->function->self.argf)) + offset = _jitc->function->self.argf++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + if (jit_arg_f_reg_p(_jitc->function->self.argf)) + offset = _jitc->function->self.argf++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_float64_t); + } + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +void +_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_c(u, _R2 - v->u.w); + else + jit_ldxi_c(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t)); + jit_dec_synth(); +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_uc(u, _R2 - v->u.w); + else + jit_ldxi_uc(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t)); + jit_dec_synth(); +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_s(u, _R2 - v->u.w); + else + jit_ldxi_s(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t)); + jit_dec_synth(); +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_us(u, _R2 - v->u.w); + else + jit_ldxi_us(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t)); + jit_dec_synth(); +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); + if (jit_arg_reg_p(v->u.w)) { +#if __WORDSIZE == 32 + jit_movr(u, _R2 - v->u.w); +#else + jit_extr_i(u, _R2 - v->u.w); +#endif + } + else + jit_ldxi_i(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t)); + jit_dec_synth(); +} + +#if __WORDSIZE == 64 +void +_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_ui(u, _R2 - v->u.w); + else + jit_ldxi_ui(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint32_t)); + jit_dec_synth(); +} + +void +_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(u, _R2 - v->u.w); + else + jit_ldxi_l(u, JIT_FP, v->u.w); + jit_dec_synth(); +} +#endif + +void +_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(_R2 - v->u.w, u); + else + jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movi(_R2 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_f(u, _F0 - v->u.w); + else + jit_ldxi_f(u, JIT_FP, + v->u.w +#if __WORDSIZE == 64 + + (__WORDSIZE >> 3) - sizeof(jit_float32_t) +#endif + ); + jit_dec_synth(); +} + +void +_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_f(_F0 - v->u.w, u); + else + jit_stxi_f(v->u.w +#if __WORDSIZE == 64 + + (__WORDSIZE >> 3) - sizeof(jit_float32_t) +#endif + , JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movi_f(_F0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(v->u.w +#if __WORDSIZE == 64 + + (__WORDSIZE >> 3) - sizeof(jit_float32_t) +#endif + , JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(u, _F0 - v->u.w); + else + jit_ldxi_d(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(_F0 - v->u.w, u); + else + jit_stxi_d(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movi_d(_F0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr(_R2 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi(jit_state_t *_jit, jit_word_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi(_R2 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_movr_f(_F0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else { + jit_stxi_f(_jitc->function->call.size + stack_framesize +#if __WORDSIZE == 64 + + (__WORDSIZE >> 3) - sizeof(jit_float32_t) +#endif + , JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_movi_f(_F0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(_jitc->function->call.size + stack_framesize +#if __WORDSIZE == 64 + + (__WORDSIZE >> 3) - sizeof(jit_float32_t) +#endif + , JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_movr_d(_F0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else { + jit_stxi_d(_jitc->function->call.size + stack_framesize, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_float64_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_movi_d(_F0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(_jitc->function->call.size + stack_framesize, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_float64_t); + } + jit_dec_synth(); +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + jit_int32_t spec; + spec = jit_class(_rvs[regno].spec); + if (spec & jit_class_arg) { + regno = _R2 - regno; + if (regno >= 0 && regno < node->v.w) + return (1); + if (spec & jit_class_fpr) { + regno = _F0 - regno; + if (regno >= 0 && regno < node->w.w) + return (1); + } + } + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_node_t *call; + assert(_jitc->function); + jit_inc_synth_w(finishr, r0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + call = jit_callr(r0); + call->v.w = _jitc->function->call.argi; + call->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_calli(i0); + node->v.w = _jitc->function->call.argi; + node->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); + return (node); +} + +void +_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_c, r0); + jit_extr_c(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_uc, r0); + jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_s, r0); + jit_extr_s(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_us, r0); + jit_extr_us(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_i, r0); +#if __WORDSIZE == 64 + jit_extr_i(r0, JIT_RET); +#else + jit_movr(r0, JIT_RET); +#endif + jit_dec_synth(); +} + +#if __WORDSIZE == 64 +void +_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_ui, r0); + jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_l, r0); + jit_movr(r0, JIT_RET); + jit_dec_synth(); +} +#endif + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_f, r0); + jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_d, r0); + jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_int32_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + jit_int32_t patch_offset; + } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + + _jitc->function = NULL; + + jit_reglive_setup(); + + undo.word = 0; + undo.node = NULL; + undo.patch_offset = 0; + +#define assert_data(node) /**/ +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_rrf(name) \ + case jit_code_##name##i_f: \ + assert_data(node); \ + name##i_f(rn(node->u.w), rn(node->v.w), \ + (jit_float32_t *)node->w.n->u.w); \ + break +#define case_rrd(name) \ + case jit_code_##name##i_d: \ + assert_data(node); \ + name##i_d(rn(node->u.w), rn(node->v.w), \ + (jit_float64_t *)node->w.n->u.w); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type##_p(_jit->pc.w, \ + rn(node->v.w), \ + rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type##_p(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break; +#define case_brf(name) \ + case jit_code_##name##i_f: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i_f(temp->u.w, rn(node->v.w), \ + (jit_float32_t *)node->w.n->u.w); \ + else { \ + word = name##i_f_p(_jit->pc.w, rn(node->v.w), \ + (jit_float32_t *)node->w.n->u.w);\ + patch(word, node); \ + } \ + break +#define case_brd(name) \ + case jit_code_##name##i_d: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i_d(temp->u.w, rn(node->v.w), \ + (jit_float64_t *)node->w.n->u.w); \ + else { \ + word = name##i_d_p(_jit->pc.w, rn(node->v.w), \ + (jit_float64_t *)node->w.n->u.w);\ + patch(word, node); \ + } \ + break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end) + return (NULL); + +#if DEVEL_DISASSEMBLER + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; +#endif + value = jit_classify(node->code); + jit_regarg_set(node, value); + switch (node->code) { + case jit_code_align: + assert(!(node->u.w & (node->u.w - 1)) && + node->u.w <= sizeof(jit_word_t)); + if (node->u.w == sizeof(jit_word_t) && + (word = _jit->pc.w & (sizeof(jit_word_t) - 1))) + nop(sizeof(jit_word_t) - word); + break; + case jit_code_note: case jit_code_name: + node->u.w = _jit->pc.w; + break; + case jit_code_label: + if ((node->link || (node->flag & jit_flag_use)) && + (word = _jit->pc.w & 3)) + nop(4 - word); + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + break; + case_rrr(add,); + case_rrw(add,); + case_rrr(addc,); + case_rrw(addc,); + case_rrr(addx,); + case_rrw(addx,); + case_rrr(sub,); + case_rrw(sub,); + case_rrr(subc,); + case_rrw(subc,); + case_rrr(subx,); + case_rrw(subx,); + case_rrw(rsb,); + case_rrr(mul,); + case_rrw(mul,); + case_rrrr(qmul,); + case_rrrw(qmul,); + case_rrrr(qmul, _u); + case_rrrw(qmul, _u); + case_rrr(div,); + case_rrw(div,); + case_rrr(div, _u); + case_rrw(div, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rr(neg,); + case_rr(com,); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_rr(trunc, _f_i); + case_rr(trunc, _d_i); +#if __WORDSIZE == 64 + case_rr(trunc, _f_l); + case_rr(trunc, _d_l); +#endif + case_rr(ld, _c); + case_rw(ld, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rr(ld, _i); + case_rw(ld, _i); +#if __WORDSIZE == 64 + case_rr(ld, _ui); + case_rw(ld, _ui); + case_rr(ld, _l); + case_rw(ld, _l); +#endif + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rrr(ldx, _i); + case_rrw(ldx, _i); +#if __WORDSIZE == 64 + case_rrr(ldx, _ui); + case_rrw(ldx, _ui); + case_rrr(ldx, _l); + case_rrw(ldx, _l); +#endif + case_rr(st, _c); + case_wr(st, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rr(st, _i); + case_wr(st, _i); +#if __WORDSIZE == 64 + case_rr(st, _l); + case_wr(st, _l); +#endif + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rrr(stx, _i); + case_wrr(stx, _i); +#if __WORDSIZE == 64 + case_rrr(stx, _l); + case_wrr(stx, _l); +#endif + case_rr(hton, _us); + case_rr(hton, _ui); +#if __WORDSIZE == 64 + case_rr(hton, _ul); +#endif + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); +#if __WORDSIZE == 64 + case_rr(ext, _i); + case_rr(ext, _ui); +#endif + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), temp->u.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_rrr(add, _f); + case_rrf(add); + case_rrr(sub, _f); + case_rrf(sub); + case_rrf(rsb); + case_rrr(mul, _f); + case_rrf(mul); + case_rrr(div, _f); + case_rrf(div); + case_rr(abs, _f); + case_rr(neg, _f); + case_rr(sqrt, _f); + case_rr(ext, _f); + case_rr(ld, _f); + case_rw(ld, _f); + case_rrr(ldx, _f); + case_rrw(ldx, _f); + case_rr(st, _f); + case_wr(st, _f); + case_rrr(stx, _f); + case_wrr(stx, _f); + case_rr(mov, _f); + case jit_code_movi_f: + assert_data(node); + movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); + break; + case_rr(ext, _d_f); + case_rrr(lt, _f); + case_rrf(lt); + case_rrr(le, _f); + case_rrf(le); + case_rrr(eq, _f); + case_rrf(eq); + case_rrr(ge, _f); + case_rrf(ge); + case_rrr(gt, _f); + case_rrf(gt); + case_rrr(ne, _f); + case_rrf(ne); + case_rrr(unlt, _f); + case_rrf(unlt); + case_rrr(unle, _f); + case_rrf(unle); + case_rrr(uneq, _f); + case_rrf(uneq); + case_rrr(unge, _f); + case_rrf(unge); + case_rrr(ungt, _f); + case_rrf(ungt); + case_rrr(ltgt, _f); + case_rrf(ltgt); + case_rrr(ord, _f); + case_rrf(ord); + case_rrr(unord, _f); + case_rrf(unord); + case_brr(blt, _f); + case_brf(blt); + case_brr(ble, _f); + case_brf(ble); + case_brr(beq, _f); + case_brf(beq); + case_brr(bge, _f); + case_brf(bge); + case_brr(bgt, _f); + case_brf(bgt); + case_brr(bne, _f); + case_brf(bne); + case_brr(bunlt, _f); + case_brf(bunlt); + case_brr(bunle, _f); + case_brf(bunle); + case_brr(buneq, _f); + case_brf(buneq); + case_brr(bunge, _f); + case_brf(bunge); + case_brr(bungt, _f); + case_brf(bungt); + case_brr(bltgt, _f); + case_brf(bltgt); + case_brr(bord, _f); + case_brf(bord); + case_brr(bunord, _f); + case_brf(bunord); + case_rrr(add, _d); + case_rrd(add); + case_rrr(sub, _d); + case_rrd(sub); + case_rrd(rsb); + case_rrr(mul, _d); + case_rrd(mul); + case_rrr(div, _d); + case_rrd(div); + case_rr(abs, _d); + case_rr(neg, _d); + case_rr(sqrt, _d); + case_rr(ext, _d); + case_rr(ld, _d); + case_rw(ld, _d); + case_rrr(ldx, _d); + case_rrw(ldx, _d); + case_rr(st, _d); + case_wr(st, _d); + case_rrr(stx, _d); + case_wrr(stx, _d); + case_rr(mov, _d); + case jit_code_movi_d: + assert_data(node); + movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w); + break; + case_rr(ext, _f_d); + case_rrr(lt, _d); + case_rrd(lt); + case_rrr(le, _d); + case_rrd(le); + case_rrr(eq, _d); + case_rrd(eq); + case_rrr(ge, _d); + case_rrd(ge); + case_rrr(gt, _d); + case_rrd(gt); + case_rrr(ne, _d); + case_rrd(ne); + case_rrr(unlt, _d); + case_rrd(unlt); + case_rrr(unle, _d); + case_rrd(unle); + case_rrr(uneq, _d); + case_rrd(uneq); + case_rrr(unge, _d); + case_rrd(unge); + case_rrr(ungt, _d); + case_rrd(ungt); + case_rrr(ltgt, _d); + case_rrd(ltgt); + case_rrr(ord, _d); + case_rrd(ord); + case_rrr(unord, _d); + case_rrd(unord); + case_brr(blt, _d); + case_brd(blt); + case_brr(ble, _d); + case_brd(ble); + case_brr(beq, _d); + case_brd(beq); + case_brr(bge, _d); + case_brd(bge); + case_brr(bgt, _d); + case_brd(bgt); + case_brr(bne, _d); + case_brd(bne); + case_brr(bunlt, _d); + case_brd(bunlt); + case_brr(bunle, _d); + case_brd(bunle); + case_brr(buneq, _d); + case_brd(buneq); + case_brr(bunge, _d); + case_brd(bunge); + case_brr(bungt, _d); + case_brd(bungt); + case_brr(bltgt, _d); + case_brd(bltgt); + case_brr(bord, _d); + case_brd(bord); + case_brr(bunord, _d); + case_brd(bunord); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + break; + case jit_code_jmpi: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } + } + else + jmpi(node->u.w); + break; + case jit_code_callr: + callr(rn(node->u.w)); + break; + case jit_code_calli: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + calli(temp->u.w); + else { + word = calli_p(_jit->pc.w); + patch(word, node); + } + } + else + calli(node->u.w); + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif + undo.patch_offset = _jitc->patches.offset; + restart_function: + _jitc->again = 0; + prolog(node); + break; + case jit_code_epilog: + assert(_jitc->function == _jitc->functions.ptr + node->w.w); + if (_jitc->again) { + for (temp = undo.node->next; + temp != node; temp = temp->next) { + if (temp->code == jit_code_label || + temp->code == jit_code_epilog) + temp->flag &= ~jit_flag_patch; + } + temp->flag &= ~jit_flag_patch; + node = undo.node; + _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif + _jitc->patches.offset = undo.patch_offset; + goto restart_function; + } + if (node->link && (word = _jit->pc.w & 3)) + nop(4 - word); + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + epilog(node); + _jitc->function = NULL; + break; + case jit_code_va_start: + vastart(rn(node->u.w)); + break; + case jit_code_va_arg: + vaarg(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_va_arg_d: + vaarg_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_live: case jit_code_ellipsis: + case jit_code_va_push: + case jit_code_allocai: case jit_code_allocar: + case jit_code_arg: + case jit_code_arg_f: case jit_code_arg_d: + case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: +#if __WORDSIZE == 64 + case jit_code_getarg_ui: case jit_code_getarg_l: +#endif + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: +#if __WORDSIZE == 64 + case jit_code_retval_ui: case jit_code_retval_l: +#endif + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: + break; + default: + abort(); + } + jit_regarg_clr(node, value); + assert(_jitc->regarg == 0 && _jitc->synth == 0); + /* update register live state */ + jit_reglive(node); + } +#undef case_brw +#undef case_brr +#undef case_wrr +#undef case_rrw +#undef case_rrr +#undef case_wr +#undef case_rw +#undef case_rr + + for (offset = 0; offset < _jitc->patches.offset; offset++) { + node = _jitc->patches.ptr[offset].node; + word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(_jitc->patches.ptr[offset].inst, word); + } + + jit_flush(_jit->code.ptr, _jit->pc.uc); + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_s390-cpu.c" +# include "jit_s390-fpu.c" +#undef CODE + +void +jit_flush(void *fptr, void *tptr) +{ +#if defined(__GNUC__) + jit_word_t f, t, s; + + s = sysconf(_SC_PAGE_SIZE); + f = (jit_word_t)fptr & -s; + t = (((jit_word_t)tptr) + s - 1) & -s; + __clear_cache((void *)f, (void *)t); +#endif +} + +void +_emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0) +{ + ldxi(rn(r0), rn(r1), i0); +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1) +{ + stxi(i0, rn(r0), rn(r1)); +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0) +{ + ldxi_d(rn(r0), rn(r1), i0); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1) +{ + stxi_d(i0, rn(r0), rn(r1)); +} + +static jit_int32_t +_jit_get_reg_pair(jit_state_t *_jit) +{ + jit_int32_t r1, r2; + /* Try to find a register pair for use with operations that + * require a odd based register pair. Search for the best + * match to avoid spills or at least a valid operation. + */ + + /* Try non callee save first */ + if (jit_reg_free_p(_R0) && jit_reg_free_p(_R1)) + r1 = _R0, r2 = _R1; + else if (jit_reg_free_p(_R2) && jit_reg_free_p(_R3)) + r1 = _R2, r2 = _R3; + else if (jit_reg_free_p(_R4) && jit_reg_free_p(_R5)) + r1 = _R4, r2 = _R5; + /* Try callee save registers */ + else if (jit_reg_free_p(_R10) && jit_reg_free_p(_R11)) + r1 = _R10, r2 = _R11; + else if (jit_reg_free_p(_R8) && jit_reg_free_p(_R9)) + r1 = _R8, r2 = _R9; + else if (jit_reg_free_p(_R6) && jit_reg_free_p(_R7)) + r1 = _R6, r2 = _R7; + + /* We *must* find a register pair */ + else if (jit_reg_free_if_spill_p(_R0) && jit_reg_free_if_spill_p(_R1)) + r1 = _R0, r2 = _R1; + else if (jit_reg_free_if_spill_p(_R2) && jit_reg_free_if_spill_p(_R3)) + r1 = _R2, r2 = _R3; + else if (jit_reg_free_if_spill_p(_R4) && jit_reg_free_if_spill_p(_R5)) + r1 = _R4, r2 = _R5; + else if (jit_reg_free_if_spill_p(_R10) && jit_reg_free_if_spill_p(_R11)) + r1 = _R10, r2 = _R11; + else if (jit_reg_free_if_spill_p(_R8) && jit_reg_free_if_spill_p(_R9)) + r1 = _R8, r2 = _R9; + else if (jit_reg_free_if_spill_p(_R6) && jit_reg_free_if_spill_p(_R7)) + r1 = _R6, r2 = _R7; + else + /* Do not jit_get_reg() all registers to avoid it */ + abort(); + + (void)jit_get_reg(jit_class_gpr|jit_class_named|r1); + (void)jit_get_reg(jit_class_gpr|jit_class_named|r2); + + return (r1); +} + +static void +_jit_unget_reg_pair(jit_state_t *_jit, jit_int32_t reg) +{ + jit_int32_t r1, r2; + r1 = reg; + switch (r1) { + case _R0: r2 = _R1; break; + case _R2: r2 = _R3; break; + case _R4: r2 = _R5; break; + case _R6: r2 = _R7; break; + case _R8: r2 = _R9; break; + case _R10: r2 = _R11; break; + default: abort(); + } + jit_unget_reg(r1); + jit_unget_reg(r2); +} + +static jit_int32_t +_jit_get_reg_but_zero(jit_state_t *_jit, jit_int32_t flags) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + if (reg == _R0) { + reg = jit_get_reg(jit_class_gpr|flags); + jit_unget_reg(_R0); + } + return (reg); +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) + flag = node->v.n->flag; + else + flag = node->u.n->flag; + assert(!(flag & jit_flag_patch)); + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} diff --git a/deps/lightning/lib/jit_size.c b/deps/lightning/lib/jit_size.c new file mode 100644 index 0000000..61f1aa4 --- /dev/null +++ b/deps/lightning/lib/jit_size.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include <lightning.h> +#include <lightning/jit_private.h> +#if GET_JIT_SIZE +# include <stdio.h> +#endif + +/* + * Initialization + */ +static jit_int16_t _szs[jit_code_last_code] = { +#if GET_JIT_SIZE +# define JIT_INSTR_MAX 256 +#else +# if defined(__i386__) || defined(__x86_64__) +# include "jit_x86-sz.c" +# elif defined(__mips__) +# include "jit_mips-sz.c" +# elif defined(__arm__) +# include "jit_arm-sz.c" +# elif defined(__powerpc__) +# include "jit_ppc-sz.c" +# elif defined(__sparc__) +# include "jit_sparc-sz.c" +# elif defined(__ia64__) +# include "jit_ia64-sz.c" +# elif defined(__hppa__) +# include "jit_hppa-sz.c" +# elif defined(__aarch64__) +# include "jit_aarch64-sz.c" +# elif defined(__s390__) || defined(__s390x__) +# include "jit_s390-sz.c" +# elif defined(__alpha__) +# include "jit_alpha-sz.c" +# elif defined(__riscv) +# include "jit_riscv-sz.c" +# endif +#endif +}; + +/* + * Implementation + */ +void +jit_init_size(void) +{ +#if DEBUG +# if !GET_JIT_SIZE + jit_word_t offset; + + for (offset = 0; offset < jit_size(_szs); offset++) + if (_szs[offset] != 0) + return; + /* Ensure data was collected */ + abort(); +# endif +#endif +} + +#if GET_JIT_SIZE +void +_jit_size_prepare(jit_state_t *_jit) +{ + _jitc->cptr = _jit->code.ptr; + _jitc->size = _jit->pc.w; +} + +void +_jit_size_collect(jit_state_t *_jit, jit_node_t *node) +{ + jit_word_t length; + + if (_jitc->cptr == _jit->code.ptr) { + length = _jit->pc.w - _jitc->size; + if (_szs[node->code] < length) + _szs[node->code] = length; + } +} + +#else +jit_word_t +_jit_get_size(jit_state_t *_jit) +{ + jit_word_t size; + jit_node_t *node; + + for (size = JIT_INSTR_MAX, node = _jitc->head; node; node = node->next) + size += _szs[node->code]; + + return ((size + 4095) & -4096); +} +#endif + +jit_word_t +jit_get_max_instr(void) +{ + return (JIT_INSTR_MAX >= 144 ? JIT_INSTR_MAX : 144); +} + +void +jit_finish_size(void) +{ +#if GET_JIT_SIZE + FILE *fp; + jit_word_t offset; + + /* Define a single path */ + fp = fopen(JIT_SIZE_PATH, "a"); + assert(fp); + for (offset = 0; offset < jit_size(_szs); offset++) + fprintf(fp, "%d %d\n", offset, _szs[offset]); + fclose(fp); +#endif +} diff --git a/deps/lightning/lib/jit_sparc-cpu.c b/deps/lightning/lib/jit_sparc-cpu.c new file mode 100644 index 0000000..051647a --- /dev/null +++ b/deps/lightning/lib/jit_sparc-cpu.c @@ -0,0 +1,2568 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# define _G2_REGNO 0x02 +# define _G3_REGNO 0x03 +# define _G4_REGNO 0x04 +# define _O0_REGNO 0x08 +# define _O1_REGNO 0x09 +# define _SP_REGNO 0x0e +# define _FP_REGNO 0x1e +# define _O7_REGNO 0x0f +# define _L0_REGNO 0x10 +# define _L1_REGNO 0x11 +# define _L2_REGNO 0x12 +# define _L3_REGNO 0x13 +# define _L4_REGNO 0x14 +# define _L5_REGNO 0x15 +# define _L6_REGNO 0x16 +# define _L7_REGNO 0x17 +# define _I7_REGNO 0x1f +/* + * - previous stack frame + * fp ---- + * fp- local variables (in lightning, 8 bytes space for float conversion) + * fp- alloca + * sp+ stack arguments + * sp+ 6 words to save register arguments + * sp+ 1 word for hidden address of aggregate return value (32 bits only) + * sp+ 16 words for in and local registers + * sp ---- + * decreasing memory address - next stack frame (not yet allocated) + */ +# define stack_framesize ((16 + (__WORDSIZE == 32) + 6) * sizeof(jit_word_t)) +typedef union { + struct { jit_uint32_t b: 2; } op; + struct { jit_uint32_t _: 2; jit_uint32_t b: 1; } a; + struct { jit_uint32_t _: 2; jit_uint32_t b: 5; } rd; + struct { jit_uint32_t _: 2; jit_uint32_t b: 30; } disp30; + struct { jit_uint32_t _: 3; jit_uint32_t b: 4; } cond; + struct { jit_uint32_t _: 7; jit_uint32_t b: 3; } op2; + struct { jit_uint32_t _: 7; jit_uint32_t b: 6; } op3; + struct { jit_uint32_t _: 10; jit_uint32_t b: 1; } cc1; + struct { jit_uint32_t _: 10; jit_uint32_t b: 22; } imm22; + struct { jit_uint32_t _: 10; jit_uint32_t b: 22; } disp22; + struct { jit_uint32_t _: 11; jit_uint32_t b: 1; } cc0; + struct { jit_uint32_t _: 12; jit_uint32_t b: 1; } p; + struct { jit_uint32_t _: 13; jit_uint32_t b: 19; } disp19; + struct { jit_uint32_t _: 13; jit_uint32_t b: 5; } rs1; + struct { jit_uint32_t _: 18; jit_uint32_t b: 1; } i; + struct { jit_uint32_t _: 18; jit_uint32_t b: 9; } opf; + struct { jit_uint32_t _: 19; jit_uint32_t b: 1; } x; + struct { jit_uint32_t _: 19; jit_uint32_t b: 8; } asi; + struct { jit_uint32_t _: 19; jit_uint32_t b: 6; } res; + struct { jit_uint32_t _: 19; jit_uint32_t b: 13; } simm13; + struct { jit_uint32_t _: 20; jit_uint32_t b: 7; } asix; + struct { jit_uint32_t _: 20; jit_uint32_t b: 6; } asis; + struct { jit_uint32_t _: 26; jit_uint32_t b: 6; } shim; + struct { jit_uint32_t _: 25; jit_uint32_t b: 7; } imm7; + struct { jit_uint32_t _: 27; jit_uint32_t b: 5; } rs2; + jit_int32_t v; +} jit_instr_t; +# define ii(i) *_jit->pc.ui++ = i +# define s7_p(imm) ((imm) <= 63 && (imm) >= -64) +# define s13_p(imm) ((imm) <= 4095 && (imm) >= -4096) +# define s19_p(imm) ((imm) <= 262143 && (imm) >= -262144) +# define s22_p(imm) ((imm) <= 2097151 && (imm) >= -20971512) +# define s30_p(imm) ((imm) <= 536870911 && (imm) >= -536870912) +# define f1(op, disp30) _f1(_jit, op, disp30) +static void _f1(jit_state_t*,jit_int32_t,jit_int32_t); +# define f2r(op, rd, op2, imm22) _f2r(_jit, op, rd, op2, imm22) +static void _f2r(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define f2b(op, a, cond, op2, disp22) _f2b(_jit, op, a, cond, op2, disp22) +static void +_f2b(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# if __WORDSIZE == 64 +# define f2bp(op,a,cond,op2,cc1,cc0,p,disp19) \ + _f2bp(_jit,op,a,cond,op2,cc1,cc0,p,disp19) +static void +_f2bp(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# endif +# define f3r(op, rd, op3, rs1, rs2) _f3r(_jit, op, rd, op3, rs1, rs2) +static void _f3r(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# if __WORDSIZE == 64 +# define f3rx(op, rd, op3, rs1, rs2) _f3rx(_jit, op, rd, op3, rs1, rs2) +static void _f3rx(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# endif +# define f3i(op, rd, op3, rs1, simm13) _f3i(_jit, op, rd, op3, rs1, simm13) +static void _f3i(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define f3s(op, rd, op3, rs1, simm13) _f3s(_jit, op, rd, op3, rs1, simm13) +static void _f3s(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define f3t(cond, rs1, i, ri) _f3t(_jit, cond, rs1, i, ri) +static void _f3t(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) + maybe_unused; +# define f3a(op, rd, op3, rs1, rs2) _f3a(_jit, op, rd, op3, rs1, asi, rs2) +static void _f3a(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t) + maybe_unused; +# define LDSB(rs1, rs2, rd) f3r(3, rd, 9, rs1, rs2) +# define LDSBI(rs1, imm, rd) f3i(3, rd, 9, rs1, imm) +# define LDSH(rs1, rs2, rd) f3r(3, rd, 10, rs1, rs2) +# define LDSHI(rs1, imm, rd) f3i(3, rd, 10, rs1, imm) +# define LDUB(rs1, rs2, rd) f3r(3, rd, 1, rs1, rs2) +# define LDUBI(rs1, imm, rd) f3i(3, rd, 1, rs1, imm) +# define LDUH(rs1, rs2, rd) f3r(3, rd, 2, rs1, rs2) +# define LDUHI(rs1, imm, rd) f3i(3, rd, 2, rs1, imm) +# if __WORDSIZE == 32 +# define LD(rs1, rs2, rd) f3r(3, rd, 0, rs1, rs2) +# define LDI(rs1, imm, rd) f3i(3, rd, 0, rs1, imm) +# define LDD(rs1, rs2, rd) f3r(3, rd, 3, rs1, rs2) +# define LDDI(rs1, imm, rd) f3i(3, rd, 3, rs1, imm) +# else +# define LDSW(rs1, rs2, rd) f3r(3, rd, 8, rs1, rs2) +# define LDSWI(rs1, imm, rd) f3i(3, rd, 8, rs1, imm) +# define LDUW(rs1, rs2, rd) f3r(3, rd, 0, rs1, rs2) +# define LDUWI(rs1, imm, rd) f3i(3, rd, 0, rs1, imm) +# define LDX(rs1, rs2, rd) f3r(3, rd, 11, rs1, rs2) +# define LDXI(rs1, imm, rd) f3i(3, rd, 11, rs1, imm) +# endif +# define LDSBA(rs1, rs2, asi, rd) f3a(3, rd, 25, rs1, asi, rs2) +# define LDSHA(rs1, rs2, asi, rd) f3a(3, rd, 26, rs1, asi, rs2) +# define LDUBA(rs1, rs2, asi, rd) f3a(3, rd, 17, rs1, asi, rs2) +# define LDUHA(rs1, rs2, asi, rd) f3a(3, rd, 18, rs1, asi, rs2) +# if __WORDSIZE == 32 +# define LDA(rs1, rs2, asi, rd) f3a(3, rd, 16, rs1, asi, rs2) +# define LDDA(rs1, rs2, asi, rd) f3a(3, rd, 19, rs1, asi, rs2) +# else +# define LDSWA(rs1, rs2, asi, rd) f3a(3, rd, 24, rs1, asi, rs2) +# define LDUWA(rs1, rs2, asi, rd) f3a(3, rd, 16, rs1, asi, rs2) +# define LDXA(rs1, rs2, asi, rd) f3a(3, rd, 27, rs1, asi, rs2) +# endif +# define LDC(rs1, rs2, rd) f3r(3, rd, 48, rs1, rs2) +# define LDCI(rs1, imm, rd) f3i(3, rd, 48, rs1, imm) +# define LDDC(rs1, rs2, rd) f3r(3, rd, 51, rs1, rs2) +# define LDDCI(rs1, imm, rd) f3i(3, rd, 51, rs1, imm) +# define LDCSR(rs1, rs2, rd) f3r(3, rd, 49, rs1, rs2) +# define LDCSRI(rs1, imm, rd) f3i(3, rd, 49, rs1, imm) +# define STB(rd, rs1, rs2) f3r(3, rd, 5, rs1, rs2) +# define STBI(rd, rs1, imm) f3i(3, rd, 5, rs1, imm) +# define STH(rd, rs1, rs2) f3r(3, rd, 6, rs1, rs2) +# define STHI(rd, rs1, imm) f3i(3, rd, 6, rs1, imm) +# if __WORDSIZE == 32 +# define ST(rd, rs1, rs2) f3r(3, rd, 4, rs1, rs2) +# define STI(rd, rs1, imm) f3i(3, rd, 4, rs1, imm) +# define STD(rrd, s1, rs2) f3r(3, rd, 7, rs1, rs2) +# define STDI(rd, rs1, imm) f3i(3, rd, 7, rs1, imm) +# else +# define STW(rd, rs1, rs2) f3r(3, rd, 4, rs1, rs2) +# define STWI(rd, rs1, imm) f3i(3, rd, 4, rs1, imm) +# define STX(rd, rs1, rs2) f3r(3, rd, 14, rs1, rs2) +# define STXI(rd, rs1, imm) f3i(3, rd, 14, rs1, imm) +# endif +# define STBA(rd, rs1, rs2) f3a(3, rd, 21, rs1, asi, rs2) +# define STHA(rd, rs1, rs2) f3a(3, rd, 22, rs1, asi, rs2) +# if __WORDSIZE == 32 +# define STA(rd, rs1, rs2) f3a(3, rd, 20, rs1, asi, rs2) +# define STDA(rd, rs1, rs2) f3a(3, rd, 23, rs1, asi, rs2) +# else +# define STWA(rd, rs1, rs2) f3a(3, rd, 20, rs1, asi, rs2) +# define STXA(rd, rs1, rs2) f3a(3, rd, 30, rs1, asi, rs2) +# endif +# define STC(rd, rs1, rs2) f3r(3, rd, 52, rs1, rs2) +# define STCI(rd, rs1, imm) f3i(3, rd, 52, rs1, imm) +# define STDC(rd, rs1, rs2) f3r(3, rd, 55, rs1, rs2) +# define STDCI(rd, rs1, imm) f3i(3, rd, 55, rs1, imm) +# define STCSR(rd, rs1, rs2) f3r(3, rd, 53, rs1, rs2) +# define STCSRI(rd, rs1, imm) f3i(3, rd, 53, rs1, imm) +# define STDCQ(rd, rs1, rs2) f3r(3, rd, 54, rs1, rs2) +# define STDCQI(rd, rs1, imm) f3i(3, rd, 54, rs1, imm) +# define LDSTUB(rs1, rs2, rd) f3r(3, rd, 13, rs1, rs2) +# define LDSTUBI(rs1, imm, rd) f3r(3, rd, 13, rs1, imm) +# define LDSTUBA(rs1, rs2, asi, rd) f3a(3, rd, 21, rs1, asi, rs2) +# define SWAP(rs1, rs2, rd) f3r(3, rd, 15, rs1, rs2) +# define SWAPI(rs1, imm, rd) f3r(3, rd, 15, rs1, imm) +# define SWAPA(rs1, rs2, asi, rd) f3a(3, rd, 23, rs1, asi, rs2) +# define NOP() SETHI(0, 0) +# define HI(im) ((im) >> 10) +# define LO(im) ((im) & 0x3ff) +# define SETHI(im, rd) f2r(0, rd, 4, im) +# define AND(rs1, rs2, rd) f3r(2, rd, 1, rs1, rs2) +# define ANDI(rs1, imm, rd) f3i(2, rd, 1, rs1, imm) +# define ANDcc(rs1, rs2, rd) f3r(2, rd, 17, rs1, rs2) +# define ANDIcc(rs1, imm, rd) f3i(2, rd, 17, rs1, imm) +# define BTST(rs1, rs2) ANDcc(rs1, rs2, 0) +# define BTSTI(rs1, imm) ANDIcc(rs1, imm, 0) +# define ANDN(rs1, rs2, rd) f3r(2, rd, 5, rs1, rs2) +# define ANDNI(rs1, imm, rd) f3i(2, rd, 5, rs1, imm) +# define ANDNcc(rs1, rs2, rd) f3r(2, rd, 21, rs1, rs2) +# define ANDNIcc(rs1, imm, rd) f3i(2, rd, 21, rs1, imm) +# define OR(rs1, rs2, rd) f3r(2, rd, 2, rs1, rs2) +# define ORI(rs1, imm, rd) f3i(2, rd, 2, rs1, imm) +# define ORcc(rs1, rs2, rd) f3r(2, rd, 18, rs1, rs2) +# define ORIcc(rs1, imm, rd) f3i(2, rd, 18, rs1, imm) +# define ORN(rs1, rs2, rd) f3r(2, rd, 6, rs1, rs2) +# define ORNI(rs1, imm, rd) f3i(2, rd, 6, rs1, imm) +# define ORNcc(rs1, rs2, rd) f3r(2, rd, 22, rs1, rs2) +# define ORNIcc(rs1, imm, rd) f3i(2, rd, 22, rs1, imm) +# define XOR(rs1, rs2, rd) f3r(2, rd, 3, rs1, rs2) +# define XORI(rs1, imm, rd) f3i(2, rd, 3, rs1, imm) +# define XORcc(rs1, rs2, rd) f3r(2, rd, 19, rs1, rs2) +# define XORIcc(rs1, imm, rd) f3i(2, rd, 19, rs1, imm) +# define XNOR(rs1, rs2, rd) f3r(2, rd, 7, rs1, rs2) +# define XNORI(rs1, imm, rd) f3i(2, rd, 7, rs1, imm) +# define XNORcc(rs1, rs2, rd) f3r(2, rd, 23, rs1, rs2) +# define XNORIcc(rs1, imm, rd) f3i(2, rd, 23, rs1, imm) +# define SLL(rs1, rs2, rd) f3r(2, rd, 37, rs1, rs2) +# define SLLI(rs1, imm, rd) f3i(2, rd, 37, rs1, imm) +# define SRL(rs1, rs2, rd) f3r(2, rd, 38, rs1, rs2) +# define SRLI(rs1, imm, rd) f3i(2, rd, 38, rs1, imm) +# define SRA(rs1, rs2, rd) f3r(2, rd, 39, rs1, rs2) +# define SRAI(rs1, imm, rd) f3i(2, rd, 39, rs1, imm) +# if __WORDSIZE == 64 +# define SLLX(rs1, rs2, rd) f3rx(2, rd, 37, rs1, rs2) +# define SLLXI(rs1, imm, rd) f3s(2, rd, 37, rs1, imm) +# define SRLX(rs1, rs2, rd) f3rx(2, rd, 38, rs1, rs2) +# define SRLXI(rs1, imm, rd) f3s(2, rd, 38, rs1, imm) +# define SRAX(rs1, rs2, rd) f3rx(2, rd, 39, rs1, rs2) +# define SRAXI(rs1, imm, rd) f3s(2, rd, 39, rs1, imm) +# endif +# define ADD(rs1, rs2, rd) f3r(2, rd, 0, rs1, rs2) +# define ADDI(rs1, imm, rd) f3i(2, rd, 0, rs1, imm) +# define ADDcc(rs1, rs2, rd) f3r(2, rd, 16, rs1, rs2) +# define ADDIcc(rs1, imm, rd) f3i(2, rd, 16, rs1, imm) +# define ADDX(rs1, rs2, rd) f3r(2, rd, 8, rs1, rs2) +# define ADDXI(rs1, imm, rd) f3i(2, rd, 8, rs1, imm) +# define ADDXcc(rs1, rs2, rd) f3r(2, rd, 24, rs1, rs2) +# define ADDXIcc(rs1, imm, rd) f3i(2, rd, 24, rs1, imm) +# define TADDcc(rs1, rs2, rd) f3r(2, rd, 32, rs1, rs2) +# define TADDIcc(rs1, imm, rd) f3i(2, rd, 32, rs1, imm) +# define TADDccTV(rs1, rs2, rd) f3r(2, rd, 34, rs1, rs2) +# define TADDIccTV(rs1, imm, rd) f3i(2, rd, 34, rs1, imm) +# define SUB(rs1, rs2, rd) f3r(2, rd, 4, rs1, rs2) +# define NEG(rs1, rd) SUB(0, rs1, rd) +# define SUBI(rs1, imm, rd) f3i(2, rd, 4, rs1, imm) +# define SUBcc(rs1, rs2, rd) f3r(2, rd, 20, rs1, rs2) +# define SUBIcc(rs1, imm, rd) f3i(2, rd, 20, rs1, imm) +# define CMP(rs1, rs2) SUBcc(rs1, rs2, 0) +# define CMPI(rs1, imm) SUBIcc(rs1, imm, 0) +# define SUBX(rs1, rs2, rd) f3r(2, rd, 12, rs1, rs2) +# define SUBXI(rs1, imm, rd) f3i(2, rd, 12, rs1, imm) +# define SUBXcc(rs1, rs2, rd) f3r(2, rd, 28, rs1, rs2) +# define SUBXIcc(rs1, imm, rd) f3i(2, rd, 28, rs1, imm) +# define TSUBcc(rs1, rs2, rd) f3r(2, rd, 33, rs1, rs2) +# define TDADDIcc(rs1, imm, rd) f3i(2, rd, 33, rs1, imm) +# define TSUBccTV(rs1, rs2, rd) f3r(2, rd, 35, rs1, rs2) +# define TSUBIccTV(rs1, imm, rd) f3i(2, rd, 35, rs1, imm) +# define MULScc(rs1, rs2, rd) f3r(2, rd, 36, rs1, rs2) +# define MULSIcc(rs1, imm, rd) f3i(2, rd, 36, rs1, imm) +# define UMUL(rs1, rs2, rd) f3r(2, rd, 10, rs1, rs2) +# define UMULI(rs1, imm, rd) f3i(2, rd, 10, rs1, imm) +# define SMUL(rs1, rs2, rd) f3r(2, rd, 11, rs1, rs2) +# define SMULI(rs1, imm, rd) f3i(2, rd, 11, rs1, imm) +# define UMULcc(rs1, rs2, rd) f3r(2, rd, 26, rs1, rs2) +# define UMULIcc(rs1, imm, rd) f3i(2, rd, 26, rs1, imm) +# define SMULcc(rs1, rs2, rd) f3r(2, rd, 27, rs1, rs2) +# define SMULIcc(rs1, imm, rd) f3i(2, rd, 27, rs1, imm) +# define UDIV(rs1, rs2, rd) f3r(2, rd, 14, rs1, rs2) +# define UDIVI(rs1, imm, rd) f3i(2, rd, 14, rs1, imm) +# define SDIV(rs1, rs2, rd) f3r(2, rd, 15, rs1, rs2) +# define SDIVI(rs1, imm, rd) f3i(2, rd, 15, rs1, imm) +# define UDIVcc(rs1, rs2, rd) f3r(2, rd, 30, rs1, rs2) +# define UDIVIcc(rs1, imm, rd) f3i(2, rd, 30, rs1, imm) +# define SDIVcc(rs1, rs2, rd) f3r(2, rd, 31, rs1, rs2) +# define SDIVIcc(rs1, imm, rd) f3i(2, rd, 31, rs1, imm) +# if __WORDSIZE == 64 +# define MULX(rs1, rs2, rd) f3r(2, rd, 9, rs1, rs2) +# define MULXI(rs1, imm, rd) f3i(2, rd, 9, rs1, imm) +# define SDIVX(rs1, rs2, rd) f3r(2, rd, 45, rs1, rs2) +# define SDIVXI(rs1, imm, rd) f3i(2, rd, 45, rs1, imm) +# define UDIVX(rs1, rs2, rd) f3r(2, rd, 13, rs1, rs2) +# define UDIVXI(rs1, imm, rd) f3i(2, rd, 13, rs1, imm) +# endif +# define SAVE(rs1, rs2, rd) f3r(2, rd, 60, rs1, rs2) +# define SAVEI(rs1, imm, rd) f3i(2, rd, 60, rs1, imm) +# define RESTORE(rs1, rs2, rd) f3r(2, rd, 61, rs1, rs2) +# define RESTOREI(rs1, imm, rd) f3i(2, rd, 61, rs1, imm) +# define SPARC_BA 8 /* always */ +# define SPARC_BN 0 /* never */ +# define SPARC_BNE 9 /* not equal - not Z */ +# define SPARC_BNZ SPARC_BNE +# define SPARC_BE 1 /* equal - Z */ +# define SPARC_BZ SPARC_BE +# define SPARC_BG 10 /* greater - not (Z or (N xor V)) */ +# define SPARC_BLE 2 /* less or equal - Z or (N xor V) */ +# define SPARC_BGE 11 /* greater or equal - not (N xor V) */ +# define SPARC_BL 3 /* less - N xor V */ +# define SPARC_BGU 12 /* greater unsigned - not (C or Z) */ +# define SPARC_BLEU 4 /* less or equal unsigned - C or Z */ +# define SPARC_BCC 13 /* carry clear - not C */ +# define SPARC_BGEU SPARC_BCC +# define SPARC_BCS 5 /* carry set - C */ +# define SPARC_BLU SPARC_BCS +# define SPARC_BPOS 14 /* positive - not N */ +# define SPARC_BNEG 6 /* negative - N */ +# define SPARC_BVC 15 /* overflow clear - not V */ +# define SPARC_BVS 7 /* overflow set - V */ +/* Preferred BPcc integer branch opcodes */ +# if __WORDSIZE == 64 +# define SPARC_BPA 8 /* always - 1 */ +# define SPARC_BPN 0 /* never - 0 */ +# define SPARC_BPNE 9 /* not equal - not Z */ +# define SPARC_BPE 1 /* equal - Z */ +# define SPARC_BPG 10 /* greater - not (Z or (N xor V)) */ +# define SPARC_BPLE 2 /* less or equal - Z or (N xor V) */ +# define SPARC_BPGE 11 /* greater or equal - not (N xor V) */ +# define SPARC_BPL 3 /* less - N xor V */ +# define SPARC_BPGU 12 /* greater unsigned - not (C or V) */ +# define SPARC_BPLEU 4 /* less or equal unsigned - C or Z */ +# define SPARC_BPCC 13 /* carry clear (greater than or equal, unsigned) - not C */ +# define SPARC_BPCS 5 /* carry set (less than, unsigned) - C */ +# define SPARC_BPPOS 14 /* positive - not N */ +# define SPARC_BPNEG 6 /* negative - N */ +# define SPARC_BPVC 15 /* overflow clear - not V */ +# define SPARC_BPVS 7 /* overflow set - V */ +# endif +# define B(cc, imm) f2b(0, 0, cc, 2, imm) +# define Ba(cc, imm) f2b(0, 1, cc, 2, imm) +# define BA(imm) B(SPARC_BA, imm) +# define BAa(imm) Ba(SPARC_BA, imm) +# define BN(imm) B(SPARC_BN, imm) +# define BNa(imm) Ba(SPARC_BN, imm) +# define BNE(imm) B(SPARC_BNE, imm) +# define BNEa(imm) Ba(SPARC_BNE, imm) +# define BNZ(imm) BNE(imm) +# define BNZa(imm) BNEa(imm) +# define BE(imm) B(SPARC_BE, imm) +# define BEa(imm) Ba(SPARC_BE, imm) +# define BZ(imm) BE(imm) +# define BZa(imm) BEa(imm) +# define BG(imm) B(SPARC_BG, imm) +# define BGa(imm) Ba(SPARC_BG, imm) +# define BLE(imm) B(SPARC_BLE, imm) +# define BLEa(imm) Ba(SPARC_BLE, imm) +# define BGE(imm) B(SPARC_BGE, imm) +# define BGEa(imm) Ba(SPARC_BGE, imm) +# define BL(imm) B(SPARC_BL, imm) +# define BLa(imm) Ba(SPARC_BL, imm) +# define BGU(imm) B(SPARC_BGU, imm) +# define BGUa(imm) Ba(SPARC_BGU, imm) +# define BLEU(imm) B(SPARC_BLEU, imm) +# define BLEUa(imm) Ba(SPARC_BLEU, imm) +# define BCC(imm) B(SPARC_BCC, imm) +# define BCCa(imm) Ba(SPARC_BCC, imm) +# define BGEU(imm) BCC(imm) +# define BGEUa(imm) BCCa(imm) +# define BCS(imm) B(SPARC_BCS, imm) +# define BCSa(imm) Ba(SPARC_BCS, imm) +# define BLU(imm) BCS(imm) +# define BLUa(imm) BCSa(imm) +# define BPOS(imm) B(SPARC_BPOS, imm) +# define BPOSa(imm) Ba(SPARC_BPOS, imm) +# define BNEG(imm) B(SPARC_BNEG, imm) +# define BNEGa(imm) Ba(SPARC_BNEG, imm) +# define BVC(imm) B(SPARC_BVC, imm) +# define BVCa(imm) Ba(SPARC_BVC, imm) +# define BVS(imm) B(SPARC_BVS, imm) +# define BVSa(imm) Ba(SPARC_BVS, imm) +# if __WORDSIZE == 64 +# define BPccap(cc,a,cc1, cc2,p,imm) f2bp(0, a, cc, 1, cc1, cc0, p, imm) +# define BPap(cc, imm) f2bp(0, 1, cc, 1, 1, 0, p, imm) +# define BPa(cc, imm) f2bp(0, 1, cc, 1, 1, 0, 1, imm) +# define BP(cc, imm) f2bp(0, 0, cc, 1, 1, 0, 1, imm) +# define BPA(imm) BP(SPARC_BPA, imm) +# define BPN(imm) BP(SPARC_BPN, imm) +# define BNPE(imm) BP(SPARC_BPNE, imm) +# define BPE(imm) BP(SPARC_BPE, imm) +# define BPG(imm) BP(SPARC_BPG, imm) +# define BPLE(imm) BP(SPARC_BPLE, imm) +# define BPGE(imm) BP(SPARC_BPGE, imm) +# define BPL(imm) BP(SPARC_BPL, imm) +# define BPGU(imm) BP(SPARC_BPGU, imm) +# define BPLEU(imm) BP(SPARC_BPLEU, imm) +# define BPCC(imm) BP(SPARC_BPCC, imm) +# define BPCS(imm) BP(SPARC_BPCS, imm) +# define BPPOS(imm) BP(SPARC_BPPOS, imm) +# define BPNEG(imm) BP(SPARC_BPNEG, imm) +# define BPVC(imm) BP(SPARC_BPVC, imm) +# define BPVS(imm) BP(SPARC_BPVS, imm) +# endif +# define SPARC_CBA 8 /* always */ +# define SPARC_CBN 0 /* never */ +# define SPARC_CB3 7 /* 3 */ +# define SPARC_CB2 6 /* 2 */ +# define SPARC_CB23 5 /* 2 or 3 */ +# define SPARC_CB1 4 /* 1 */ +# define SPARC_CB13 3 /* 1 or 3 */ +# define SPARC_CB12 2 /* 1 or 2 */ +# define SPARC_CB123 1 /* 1 or 2 or 3 */ +# define SPARC_CB0 9 /* 0 */ +# define SPARC_CB03 10 /* 0 or 3 */ +# define SPARC_CB02 11 /* 0 or 2 */ +# define SPARC_CB023 12 /* 0 or 2 or 3 */ +# define SPARC_CB01 13 /* 0 or 1 */ +# define SPARC_CB013 14 /* 0 or 1 or 3 */ +# define SPARC_CB012 15 /* 0 or 1 or 2 */ +# define CB(cc, imm) f2b(0, 0, cc, 7, imm) +# define CBa(cc, imm) f2b(0, 1, cc, 7, imm) +# define CBA(imm) CB(SPARC_CBA, imm) +# define CBAa(imm) CBa(SPARC_CBA, imm) +# define CBN(imm) CB(SPARC_CBN, imm) +# define CBNa(imm) CBa(SPARC_CBN, imm) +# define CB3(imm) CB(SPARC_CB3, imm) +# define CB3a(imm) CBa(SPARC_CB3, imm) +# define CB2(imm) CB(SPARC_CB2, imm) +# define CB2a(imm) CBa(SPARC_CB2, imm) +# define CB23(imm) CB(SPARC_CB23, imm) +# define CB23a(imm) CBa(SPARC_CB23, imm) +# define CB1(imm) CB(SPARC_CB1, imm) +# define CB1a(imm) CBa(SPARC_CB1, imm) +# define CB13(imm) CB(SPARC_CB13, imm) +# define CB13a(imm) CBa(SPARC_CB13, imm) +# define CB12(imm) CB(SPARC_CB12, imm) +# define CB12a(imm) CBa(SPARC_CB12, imm) +# define CB123(imm) CB(SPARC_CB123, imm) +# define CB123a(imm) CBa(SPARC_CB123, imm) +# define CB0(imm) CB(SPARC_CB0, imm) +# define CB0a(imm) CBa(SPARC_CB0, imm) +# define CB03(imm) CB(SPARC_CB03, imm) +# define CB03a(imm) CBa(SPARC_CB03, imm) +# define CB02(imm) CB(SPARC_CB02, imm) +# define CB02a(imm) CBa(SPARC_CB02, imm) +# define CB023(imm) CB(SPARC_CB103, imm) +# define CB023a(imm) CBa(SPARC_CB023, imm) +# define CB01(imm) CB(SPARC_CB01, imm) +# define CB01a(imm) CBa(SPARC_CB01, imm) +# define CB013(imm) CB(SPARC_CB013, imm) +# define CB013a(imm) CBa(SPARC_CB013, imm) +# define CB012(imm) CB(SPARC_CB012, imm) +# define CB012a(imm) CBa(SPARC_CB012, imm) +# define CALLI(imm) f1(1, imm) +# define CALL(r0) JMPL(_O7_REGNO, r0, 0) +# define RETL() JMPLI(0, _O7_REGNO, 8) +# define RET() JMPLI(0, _I7_REGNO, 8) +# define JMPL(rd, rs1, rs2) f3r(2, rd, 56, rs1, rs2) +# define JMPLI(rd, rs1, imm) f3i(2, rd, 56, rs1, imm) +# define RETT(rs1, rs2) f3r(2, 0, 57, rs1, rs2) +# define RETTI(rs1, imm) f3i(2, 0, 57, rs1, imm) +# define SPARC_TA 8 /* always */ +# define SPARC_TN 0 /* never */ +# define SPARC_TNE 9 /* not equal - not Z */ +# define SPARC_TNZ SPARC_BNE +# define SPARC_TE 1 /* equal - Z */ +# define SPARC_TZ SPARC_BE +# define SPARC_TG 10 /* greater - not (Z or (N xor V)) */ +# define SPARC_TLE 2 /* less or equal - Z or (N xor V) */ +# define SPARC_TGE 11 /* greater or equal - not (N xor V) */ +# define SPARC_TL 3 /* less - N xor V */ +# define SPARC_TGU 12 /* greater unsigned - not (C or Z) */ +# define SPARC_TLEU 4 /* less or equal unsigned - C or Z */ +# define SPARC_TCC 13 /* carry clear - not C */ +# define SPARC_TGEU SPARC_BCC +# define SPARC_TCS 5 /* carry set - C */ +# define SPARC_TLU SPARC_BCS +# define SPARC_TPOS 14 /* positive - not N */ +# define SPARC_TNEG 6 /* negative - N */ +# define SPARC_TVC 15 /* overflow clear - not V */ +# define SPARC_TVS 7 /* overflow set - V */ +# define T(cc, rs1, rs2) f3t(cc, rs1, 0, rs2) +# define TI(cc, rs1, imm) f3t(cc, rs1, 1, imm) +# define TA(rs1, rs2) T(SPARC_TA, rs1, rs2) +# define TAI(rs1, imm) TI(SPARC_TA, rs1, imm) +# define TN(rs1, rs2) T(SPARC_TN, rs1, rs2) +# define TNI(rs1, imm) TI(SPARC_TN, rs1, imm) +# define TNE(rs1, rs2) T(SPARC_TNE, rs1, rs2) +# define TNEI(rs1, imm) TI(SPARC_TNE, rs1, imm) +# define TNZ(rs1, rs2) TNE(rs1, rs2) +# define TNZI(rs1, imm) TNEI(rs1, imm) +# define TE(rs1, rs2) T(SPARC_TE, rs1, rs2) +# define TEI(rs1, imm) TI(SPARC_TE, rs1, imm) +# define TZ(rs1, rs2) TE(rs1, rs2) +# define TZI(rs1, imm) TEI(rs1, imm) +# define TG(rs1, rs2) T(SPARC_TG, rs1, rs2) +# define TGI(rs1, imm) TI(SPARC_TG, rs1, imm) +# define TLE(rs1, rs2) T(SPARC_TLE, rs1, rs2) +# define TLEI(rs1, imm) TI(SPARC_TLE, rs1, imm) +# define TGE(rs1, rs2) T(SPARC_TGE, rs1, rs2) +# define TGEI(rs1, imm) TI(SPARC_TGE, rs1, imm) +# define TL(rs1, rs2) T(SPARC_TL, rs1, rs2) +# define TLI(rs1, imm) TI(SPARC_TL, rs1, imm) +# define TGU(rs1, rs2) T(SPARC_TGU, rs1, rs2) +# define TGUI(rs1, imm) TI(SPARC_TGU, rs1, imm) +# define TLEU(rs1, rs2) T(SPARC_TLEU, rs1, rs2) +# define TLEUI(rs1, imm) TI(SPARC_TLEU, rs1, imm) +# define TCC(rs1, rs2) T(SPARC_TCC, rs1, rs2) +# define TCCI(rs1, imm) TI(SPARC_TCC, rs1, imm) +# define TGEU(rs1, rs2) TCC(rs1, rs2) +# define TGEUI(rs1, imm) TCCI(rs1, imm) +# define TCS(rs1, rs2) T(SPARC_TCC, rs1, rs2) +# define TCSI(rs1, imm) TI(SPARC_TCC, rs1, imm) +# define TLU(rs1, rs2) TCS(rs1, rs2) +# define TLUI(rs1, imm) TCSI(rs1, imm) +# define TPOS(rs1, rs2) T(SPARC_TPOS, rs1, rs2) +# define TPOSI(rs1, imm) TI(SPARC_TPOS, rs1, imm) +# define TNEG(rs1, rs2) T(SPARC_TNEG, rs1, rs2) +# define TNEGI(rs1, imm) TI(SPARC_TNEG, rs1, imm) +# define TVC(rs1, rs2) T(SPARC_TVC, rs1, rs2) +# define TVCI(rs1, imm) TI(SPARC_TVC, rs1, imm) +# define TVS(rs1, rs2) T(SPARC_TVS, rs1, rs2) +# define TVSI(rs1, imm) TI(SPARC_TVS, rs1, imm) +# define RDY(rd) f3r(2, rd, 40, 0, 0) +# define RDASR(rs1, rd) f3r(2, rd, 40, rs1, 0) +# define RDPSR(rd) f3r(2, rd, 41, 0, 0) +# define RDWIM(rd) f3r(2, rd, 42, 0, 0) +# define RDTBR(rd) f3r(2, rd, 43, 0, 0) +# define WRY(rs1, rs2) f3r(2, 0, 48, rs1, rs2) +# define WRYI(rs1, imm) f3i(2, 0, 48, rs1, imm) +# define WRASR(rs1, rs2, rd) f3r(2, rd, 48, rs1, rs2) +# define WRASRI(rs1, imm, rd) f3i(2, rd, 48, rs1, imm) +# define WRPSR(rs1, rs2, rd) f3r(2, rd, 49, rs1, rs2) +# define WRPSRI(rs1, imm, rd) f3i(2, rd, 49, rs1, imm) +# define WRWIM(rs1, rs2, rd) f3r(2, rd, 50, rs1, rs2) +# define WRWIMI(rs1, imm, rd) f3i(2, rd, 50, rs1, imm) +# define WRTBR(rs1, rs2, rd) f3r(2, rd, 51, rs1, rs2) +# define WRTBRI(rs1, imm, rd) f3i(2, rd, 51, rs1, imm) +# define STBAR() f3i(2, 0, 40, 15, 0) +# define UNIMP(imm) f2r(0, 0, 0, imm) +# define FLUSH(rs1, rs2) f3r(2, 0, 59, rs1, rs2) +# define FLUSHI(rs1, im) f3i(2, 0, 59, rs1, imm) +# define nop(i0) _nop(_jit, i0) +static void _nop(jit_state_t*, jit_int32_t); +# define movr(r0, r1) _movr(_jit, r0, r1) +static void _movr(jit_state_t*, jit_int32_t, jit_int32_t); +# define movi(r0, i0) _movi(_jit, r0, i0) +static void _movi(jit_state_t*, jit_int32_t, jit_word_t); +# define movi_p(r0, i0) _movi_p(_jit, r0, i0) +static jit_word_t _movi_p(jit_state_t*, jit_int32_t, jit_word_t); +# define comr(r0, r1) XNOR(r1, 0, r0) +# define negr(r0, r1) NEG(r1, r0) +# define addr(r0, r1, r2) ADD(r1, r2, r0) +# define addi(r0, r1, i0) _addi(_jit, r0, r1, i0) +static void _addi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# if __WORDSIZE == 32 +# define addcr(r0, r1, r2) ADDcc(r1, r2, r0) +# else +# define addcr(r0, r1, r2) _addcr(_jit, r0, r1, r2) +static void _addcr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# endif +# define addci(r0, r1, i0) _addci(_jit, r0, r1, i0) +static void _addci(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# if __WORDSIZE == 32 +# define addxr(r0, r1, r2) ADDXcc(r1, r2, r0) +# else +# define addxr(r0, r1, r2) _addxr(_jit, r0, r1, r2) +static void _addxr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# endif +# define addxi(r0, r1, i0) _addxi(_jit, r0, r1, i0) +static void _addxi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define subr(r0, r1, r2) SUB(r1, r2, r0) +# define subi(r0, r1, i0) _subi(_jit, r0, r1, i0) +static void _subi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# if __WORDSIZE == 32 +# define subcr(r0, r1, r2) SUBcc(r1, r2, r0) +# else +# define subcr(r0, r1, r2) _subcr(_jit, r0, r1, r2) +static void _subcr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# endif +# define subci(r0, r1, i0) _subci(_jit, r0, r1, i0) +static void _subci(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# if __WORDSIZE == 32 +# define subxr(r0, r1, r2) SUBXcc(r1, r2, r0) +# else +# define subxr(r0, r1, r2) _subxr(_jit, r0, r1, r2) +static void _subxr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# endif +# define subxi(r0, r1, i0) _subxi(_jit, r0, r1, i0) +static void _subxi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0) +static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define mulr(r0, r1, r2) UMUL(r1, r2, r0) +# else +# define mulr(r0, r1, r2) MULX(r1, r2, r0) +# endif +# define muli(r0, r1, i0) _muli(_jit, r0, r1, i0) +static void _muli(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# if __WORDSIZE == 32 +# define qmulr(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,1) +# define qmulr_u(r0,r1,r2,r3) iqmulr(r0,r1,r2,r3,0) +# define iqmulr(r0,r1,r2,r3,cc) _iqmulr(_jit,r0,r1,r2,r3,cc) +static void _iqmulr(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_bool_t); +# define qmuli(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,1) +# define qmuli_u(r0,r1,r2,i0) iqmuli(r0,r1,r2,i0,0) +# define iqmuli(r0,r1,r2,i0,cc) _iqmuli(_jit,r0,r1,r2,i0,cc) +static void _iqmuli(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_word_t,jit_bool_t); +# else +# define qmulr(r0,r1,r2,r3) _qmulr(_jit,r0,r1,r2,r3) +static void _qmulr(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t); +# define qmuli(r0,r1,r2,i0) _qmuli(_jit,r0,r1,r2,i0) +static void _qmuli(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_word_t); +# define qmulr_u(r0,r1,r2,r3) _qmulr_u(_jit,r0,r1,r2,r3) +static void _qmulr_u(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t); +# define qmuli_u(r0,r1,r2,i0) _qmuli_u(_jit,r0,r1,r2,i0) +static void _qmuli_u(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_word_t); +# endif +# define divr(r0, r1, r2) _divr(_jit, r0, r1, r2) +static void _divr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define divi(r0, r1, i0) _divi(_jit, r0, r1, i0) +static void _divi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define divr_u(r0, r1, r2) _divr_u(_jit, r0, r1, r2) +static void _divr_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define divi_u(r0, r1, i0) _divi_u(_jit, r0, r1, i0) +static void _divi_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define qdivr(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,1) +# define qdivr_u(r0,r1,r2,r3) iqdivr(r0,r1,r2,r3,0) +# define iqdivr(r0,r1,r2,r3,cc) _iqdivr(_jit,r0,r1,r2,r3,cc) +static void _iqdivr(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_bool_t); +# define qdivi(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,1) +# define qdivi_u(r0,r1,r2,i0) iqdivi(r0,r1,r2,i0,0) +# define iqdivi(r0,r1,r2,i0,cc) _iqdivi(_jit,r0,r1,r2,i0,cc) +static void _iqdivi(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_word_t,jit_bool_t); +# define remr(r0, r1, r2) _remr(_jit, r0, r1, r2) +static void _remr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define remi(r0, r1, i0) _remi(_jit, r0, r1, i0) +static void _remi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define remr_u(r0, r1, r2) _remr_u(_jit, r0, r1, r2) +static void _remr_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define remi_u(r0, r1, i0) _remi_u(_jit, r0, r1, i0) +static void _remi_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define andr(r0, r1, r2) AND(r1, r2, r0) +# define andi(r0, r1, i0) _andi(_jit, r0, r1, i0) +static void _andi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define orr(r0, r1, r2) OR(r1, r2, r0) +# define ori(r0, r1, i0) _ori(_jit, r0, r1, i0) +static void _ori(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define xorr(r0, r1, r2) XOR(r1, r2, r0) +# define xori(r0, r1, i0) _xori(_jit, r0, r1, i0) +static void _xori(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# if __WORDSIZE == 32 +# define lshr(r0, r1, r2) SLL(r1, r2, r0) +# define lshi(r0, r1, i0) SLLI(r1, i0, r0) +# define rshr(r0, r1, r2) SRA(r1, r2, r0) +# define rshi(r0, r1, i0) SRAI(r1, i0, r0) +# define rshr_u(r0, r1, r2) SRL(r1, r2, r0) +# define rshi_u(r0, r1, i0) SRLI(r1, i0, r0) +# else +# define lshr(r0, r1, r2) SLLX(r1, r2, r0) +# define lshi(r0, r1, i0) SLLXI(r1, i0, r0) +# define rshr(r0, r1, r2) SRAX(r1, r2, r0) +# define rshi(r0, r1, i0) SRAXI(r1, i0, r0) +# define rshr_u(r0, r1, r2) SRLX(r1, r2, r0) +# define rshi_u(r0, r1, i0) SRLXI(r1, i0, r0) +# endif +# define htonr_us(r0,r1) extr_us(r0,r1) +# define extr_c(r0,r1) _extr_c(_jit,r0,r1) +static void _extr_c(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_uc(r0,r1) andi(r0, r1, 0xff) +# define extr_s(r0,r1) _extr_s(_jit,r0,r1) +static void _extr_s(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_us(r0,r1) _extr_us(_jit,r0,r1) +static void _extr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# if __WORDSIZE == 32 +# define htonr_ui(r0,r1) movr(r0,r1) +# else +# define htonr_ui(r0,r1) extr_ui(r0,r1) +# define htonr_ul(r0,r1) movr(r0,r1) +# define extr_i(r0,r1) _extr_i(_jit,r0,r1) +static void _extr_i(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_ui(r0,r1) _extr_ui(_jit,r0,r1) +static void _extr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# endif +# define cr(cc, r0, r1, r2) _cr(_jit, cc, r0, r1, r2) +static void _cr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define cw(cc, r0, r1, i0) _cw(_jit, cc, r0, r1, i0) +static void _cw(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define ltr(r0, r1, r2) cr(SPARC_BL, r0, r1, r2) +# define lti(r0, r1, i0) cw(SPARC_BL, r0, r1, i0) +# define ltr_u(r0, r1, r2) cr(SPARC_BLU, r0, r1, r2) +# define lti_u(r0, r1, i0) cw(SPARC_BLU, r0, r1, i0) +# define ler(r0, r1, r2) cr(SPARC_BLE, r0, r1, r2) +# define lei(r0, r1, i0) cw(SPARC_BLE, r0, r1, i0) +# define ler_u(r0, r1, r2) cr(SPARC_BLEU, r0, r1, r2) +# define lei_u(r0, r1, i0) cw(SPARC_BLEU, r0, r1, i0) +# define eqr(r0, r1, r2) cr(SPARC_BE, r0, r1, r2) +# define eqi(r0, r1, i0) cw(SPARC_BE, r0, r1, i0) +# define ger(r0, r1, r2) cr(SPARC_BGE, r0, r1, r2) +# define gei(r0, r1, i0) cw(SPARC_BGE, r0, r1, i0) +# define ger_u(r0, r1, r2) cr(SPARC_BGEU, r0, r1, r2) +# define gei_u(r0, r1, i0) cw(SPARC_BGEU, r0, r1, i0) +# define gtr(r0, r1, r2) cr(SPARC_BG, r0, r1, r2) +# define gti(r0, r1, i0) cw(SPARC_BG, r0, r1, i0) +# define gtr_u(r0, r1, r2) cr(SPARC_BGU, r0, r1, r2) +# define gti_u(r0, r1, i0) cw(SPARC_BGU, r0, r1, i0) +# define ner(r0, r1, r2) cr(SPARC_BNE, r0, r1, r2) +# define nei(r0, r1, i0) cw(SPARC_BNE, r0, r1, i0) +# else +# define ltr(r0, r1, r2) cr(SPARC_BPL, r0, r1, r2) +# define lti(r0, r1, i0) cw(SPARC_BPL, r0, r1, i0) +# define ltr_u(r0, r1, r2) cr(SPARC_BPCS, r0, r1, r2) +# define lti_u(r0, r1, i0) cw(SPARC_BPCS, r0, r1, i0) +# define ler(r0, r1, r2) cr(SPARC_BPLE, r0, r1, r2) +# define lei(r0, r1, i0) cw(SPARC_BPLE, r0, r1, i0) +# define ler_u(r0, r1, r2) cr(SPARC_BPLEU, r0, r1, r2) +# define lei_u(r0, r1, i0) cw(SPARC_BPLEU, r0, r1, i0) +# define eqr(r0, r1, r2) cr(SPARC_BPE, r0, r1, r2) +# define eqi(r0, r1, i0) cw(SPARC_BPE, r0, r1, i0) +# define ger(r0, r1, r2) cr(SPARC_BPGE, r0, r1, r2) +# define gei(r0, r1, i0) cw(SPARC_BPGE, r0, r1, i0) +# define ger_u(r0, r1, r2) cr(SPARC_BPCC, r0, r1, r2) +# define gei_u(r0, r1, i0) cw(SPARC_BPCC, r0, r1, i0) +# define gtr(r0, r1, r2) cr(SPARC_BPG, r0, r1, r2) +# define gti(r0, r1, i0) cw(SPARC_BPG, r0, r1, i0) +# define gtr_u(r0, r1, r2) cr(SPARC_BPGU, r0, r1, r2) +# define gti_u(r0, r1, i0) cw(SPARC_BPGU, r0, r1, i0) +# define ner(r0, r1, r2) cr(SPARC_BPNE, r0, r1, r2) +# define nei(r0, r1, i0) cw(SPARC_BPNE, r0, r1, i0) +# endif +# define ldr_c(r0, r1) LDSB(r1, 0, r0) +# define ldi_c(r0, i0) _ldi_c(_jit, r0, i0) +static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_uc(r0, r1) LDUB(r1, 0, r0) +# define ldi_uc(r0, i0) _ldi_uc(_jit, r0, i0) +static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_s(r0, r1) LDSH(r1, 0, r0) +# define ldi_s(r0, i0) _ldi_s(_jit, r0, i0) +static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_us(r0, r1) LDUH(r1, 0, r0) +# define ldi_us(r0, i0) _ldi_us(_jit, r0, i0) +static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define ldr_i(r0, r1) LD(r1, 0, r0) +# define ldr(u, v) ldr_i(u, v) +# define ldi(u, v) ldi_i(u, v) +# else +# define ldr_i(r0, r1) LDSW(r1, 0, r0) +# define ldr_ui(r0, r1) LDUW(r1, 0, r0) +# define ldr_l(r0, r1) LDX(r1, 0, r0) +# define ldr(u, v) ldr_l(u, v) +# define ldi(u, v) ldi_l(u, v) +# endif +# define ldi_i(r0, i0) _ldi_i(_jit, r0, i0) +static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t); +# if __WORDSIZE == 64 +# define ldi_ui(r0, i0) _ldi_ui(_jit, r0, i0) +static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t); +# define ldi_l(r0, i0) _ldi_l(_jit, r0, i0) +static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t); +# endif +# define ldxr_c(r0, r1, r2) LDSB(r1, r2, r0) +# define ldxi_c(r0, r1, i0) _ldxi_c(_jit, r0, r1, i0) +static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_uc(r0, r1, r2) LDUB(r1, r2, r0) +# define ldxi_uc(r0, r1, i0) _ldxi_uc(_jit, r0, r1, i0) +static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_s(r0, r1, r2) LDSH(r1, r2, r0) +# define ldxi_s(r0, r1, i0) _ldxi_s(_jit, r0, r1, i0) +static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_us(r0, r1, r2) LDUH(r1, r2, r0) +# define ldxi_us(r0, r1, i0) _ldxi_us(_jit, r0, r1, i0) +static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define ldxr(u, v, w) ldxr_i(u, v, w) +# define ldxr_i(r0, r1, r2) LD(r1, r2, r0) +# define ldxi(u, v, w) ldxi_i(u, v, w) +# else +# define ldxr(u, v, w) ldxr_l(u, v, w) +# define ldxr_i(r0, r1, r2) LDSW(r1, r2, r0) +# define ldxr_ui(r0, r1, r2) LDUW(r1, r2, r0) +# define ldxr_l(r0, r1, r2) LDX(r1, r2, r0) +# define ldxi(u, v, w) ldxi_l(u, v, w) +# endif +# define ldxi_i(r0, r1, i0) _ldxi_i(_jit, r0, r1, i0) +static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 64 +# define ldxi_ui(r0, r1, i0) _ldxi_ui(_jit, r0, r1, i0) +static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxi_l(r0, r1, i0) _ldxi_l(_jit, r0, r1, i0) +static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# endif +# define str_c(r0, r1) STB(r1, r0, 0) +# define sti_c(i0, r0) _sti_c(_jit, i0, r0) +static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t); +# define str_s(r0, r1) STH(r1, r0, 0) +# define sti_s(i0, r0) _sti_s(_jit, i0, r0) +static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t); +# if __WORDSIZE == 32 +# define str(u, v) str_i(u, v) +# define str_i(r0, r1) STI(r1, r0, 0) +# define sti(u, v) sti_i(u, v) +# else +# define str(u, v) str_l(u, v) +# define str_i(r0, r1) STW(r1, r0, 0) +# define str_l(r0, r1) STX(r1, r0, 0) +# define sti(u, v) sti_l(u, v) +# endif +# define sti_i(i0, r0) _sti_i(_jit, i0, r0) +static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); +# if __WORDSIZE == 64 +# define sti_l(i0, r0) _sti_l(_jit, i0, r0) +static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t); +# endif +# define stxr_c(r0, r1, r2) STB(r2, r1, r0) +# define stxi_c(i0, r0, r1) _stxi_c(_jit, i0, r0, r1) +static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_s(r0, r1, r2) STH(r2, r1, r0) +# define stxi_s(i0, r0, r1) _stxi_s(_jit, i0, r0, r1) +static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# if __WORDSIZE == 32 +# define stxr(u, v, w) stxr_i(u, v, w) +# define stxr_i(r0, r1, r2) ST(r2, r1, r0) +# define stxi(u, v, w) stxi_i(u, v, w) +# else +# define stxr(u, v, w) stxr_l(u, v, w) +# define stxr_i(r0, r1, r2) STW(r2, r1, r0) +# define stxi(u, v, w) stxi_l(u, v, w) +# define stxr_l(r0, r1, r2) STX(r2, r1, r0) +# endif +# define stxi_i(i0, r0, r1) _stxi_i(_jit, i0, r0, r1) +static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# if __WORDSIZE == 64 +# define stxi_l(i0, r0, r1) _stxi_l(_jit, i0, r0, r1) +static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# endif +# define br(cc, i0, r0, r1) _br(_jit, cc, i0, r0, r1) +static jit_word_t +_br(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t); +# define bw(cc, i0, r0, i1) _bw(_jit, cc, i0, r0, i1) +static jit_word_t +_bw(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define bltr(i0, r0, r1) br(SPARC_BL, i0, r0, r1) +# define blti(i0, r0, i1) bw(SPARC_BL, i0, r0, i1) +# define bltr_u(i0, r0, r1) br(SPARC_BLU, i0, r0, r1) +# define blti_u(i0, r0, i1) bw(SPARC_BLU, i0, r0, i1) +# define bler(i0, r0, r1) br(SPARC_BLE, i0, r0, r1) +# define blei(i0, r0, i1) bw(SPARC_BLE, i0, r0, i1) +# define bler_u(i0, r0, r1) br(SPARC_BLEU, i0, r0, r1) +# define blei_u(i0, r0, i1) bw(SPARC_BLEU, i0, r0, i1) +# define beqr(i0, r0, r1) br(SPARC_BE, i0, r0, r1) +# define beqi(i0, r0, i1) bw(SPARC_BE, i0, r0, i1) +# define bger(i0, r0, r1) br(SPARC_BGE, i0, r0, r1) +# define bgei(i0, r0, i1) bw(SPARC_BGE, i0, r0, i1) +# define bger_u(i0, r0, r1) br(SPARC_BGEU, i0, r0, r1) +# define bgei_u(i0, r0, i1) bw(SPARC_BGEU, i0, r0, i1) +# define bgtr(i0, r0, r1) br(SPARC_BG, i0, r0, r1) +# define bgti(i0, r0, i1) bw(SPARC_BG, i0, r0, i1) +# define bgtr_u(i0, r0, r1) br(SPARC_BGU, i0, r0, r1) +# define bgti_u(i0, r0, i1) bw(SPARC_BGU, i0, r0, i1) +# define bner(i0, r0, r1) br(SPARC_BNE, i0, r0, r1) +# define bnei(i0, r0, i1) bw(SPARC_BNE, i0, r0, i1) +# else +# define bltr(i0, r0, r1) br(SPARC_BPL, i0, r0, r1) +# define blti(i0, r0, i1) bw(SPARC_BPL, i0, r0, i1) +# define bltr_u(i0, r0, r1) br(SPARC_BPCS, i0, r0, r1) +# define blti_u(i0, r0, i1) bw(SPARC_BPCS, i0, r0, i1) +# define bler(i0, r0, r1) br(SPARC_BPLE, i0, r0, r1) +# define blei(i0, r0, i1) bw(SPARC_BPLE, i0, r0, i1) +# define bler_u(i0, r0, r1) br(SPARC_BPLEU, i0, r0, r1) +# define blei_u(i0, r0, i1) bw(SPARC_BPLEU, i0, r0, i1) +# define beqr(i0, r0, r1) br(SPARC_BPE, i0, r0, r1) +# define beqi(i0, r0, i1) bw(SPARC_BPE, i0, r0, i1) +# define bger(i0, r0, r1) br(SPARC_BPGE, i0, r0, r1) +# define bgei(i0, r0, i1) bw(SPARC_BPGE, i0, r0, i1) +# define bger_u(i0, r0, r1) br(SPARC_BPCC, i0, r0, r1) +# define bgei_u(i0, r0, i1) bw(SPARC_BPCC, i0, r0, i1) +# define bgtr(i0, r0, r1) br(SPARC_BPG, i0, r0, r1) +# define bgti(i0, r0, i1) bw(SPARC_BPG, i0, r0, i1) +# define bgtr_u(i0, r0, r1) br(SPARC_BPGU, i0, r0, r1) +# define bgti_u(i0, r0, i1) bw(SPARC_BPGU, i0, r0, i1) +# define bner(i0, r0, r1) br(SPARC_BPNE, i0, r0, r1) +# define bnei(i0, r0, i1) bw(SPARC_BPNE, i0, r0, i1) +# endif +# define b_asr(jif,add,sgn,i0,r0,r1) _b_asr(_jit,jif,add,sgn,i0,r0,r1) +static jit_word_t +_b_asr(jit_state_t*,jit_bool_t,jit_bool_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define b_asw(jif,add,sgn,i0,r0,i1) _b_asw(_jit,jif,add,sgn,i0,r0,i1) +static jit_word_t +_b_asw(jit_state_t*,jit_bool_t,jit_bool_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_word_t); +# define boaddr(i0, r0, r1) b_asr(1, 1, 1, i0, r0, r1) +# define boaddi(i0, r0, i1) b_asw(1, 1, 1, i0, r0, i1) +# define boaddr_u(i0, r0, r1) b_asr(1, 1, 0, i0, r0, r1) +# define boaddi_u(i0, r0, i1) b_asw(1, 1, 0, i0, r0, i1) +# define bxaddr(i0, r0, r1) b_asr(0, 1, 1, i0, r0, r1) +# define bxaddi(i0, r0, i1) b_asw(0, 1, 1, i0, r0, i1) +# define bxaddr_u(i0, r0, r1) b_asr(0, 1, 0, i0, r0, r1) +# define bxaddi_u(i0, r0, i1) b_asw(0, 1, 0, i0, r0, i1) +# define bosubr(i0, r0, r1) b_asr(1, 0, 1, i0, r0, r1) +# define bosubi(i0, r0, i1) b_asw(1, 0, 1, i0, r0, i1) +# define bosubr_u(i0, r0, r1) b_asr(1, 0, 0, i0, r0, r1) +# define bosubi_u(i0, r0, i1) b_asw(1, 0, 0, i0, r0, i1) +# define bxsubr(i0, r0, r1) b_asr(0, 0, 1, i0, r0, r1) +# define bxsubi(i0, r0, i1) b_asw(0, 0, 1, i0, r0, i1) +# define bxsubr_u(i0, r0, r1) b_asr(0, 0, 0, i0, r0, r1) +# define bxsubi_u(i0, r0, i1) b_asw(0, 0, 0, i0, r0, i1) +# define bm_r(set, i0, r0, r1) _bm_r(_jit,set,i0,r0,r1) +static jit_word_t +_bm_r(jit_state_t*,jit_bool_t,jit_word_t,jit_int32_t,jit_int32_t); +# define bm_w(set,i0,r0,i1) _bm_w(_jit,set,i0,r0,i1) +static jit_word_t +_bm_w(jit_state_t*,jit_bool_t,jit_word_t,jit_int32_t,jit_word_t); +# define bmsr(i0, r0, r1) bm_r(1, i0, r0, r1) +# define bmsi(i0, r0, i1) bm_w(1, i0, r0, i1) +# define bmcr(i0, r0, r1) bm_r(0, i0, r0, r1) +# define bmci(i0, r0, i1) bm_w(0, i0, r0, i1) +# define jmpr(r0) _jmpr(_jit, r0) +static void _jmpr(jit_state_t*,jit_int32_t); +# define jmpi(i0) _jmpi(_jit, i0) +static void _jmpi(jit_state_t*,jit_word_t); +# define jmpi_p(i0) _jmpi_p(_jit, i0) +static jit_word_t _jmpi_p(jit_state_t*,jit_word_t); +# define callr(r0) _callr(_jit, r0) +static void _callr(jit_state_t*,jit_int32_t); +# define calli(i0) _calli(_jit, i0) +static void _calli(jit_state_t*,jit_word_t); +# define calli_p(i0) _calli_p(_jit, i0) +static jit_word_t _calli_p(jit_state_t*,jit_word_t); +# define prolog(node) _prolog(_jit, node) +static void _prolog(jit_state_t*,jit_node_t*); +# define epilog(node) _epilog(_jit, node) +static void _epilog(jit_state_t*,jit_node_t*); +#define vastart(r0) _vastart(_jit, r0) +static void _vastart(jit_state_t*, jit_int32_t); +#define vaarg(r0, r1) _vaarg(_jit, r0, r1) +static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t); +#define patch_at(jump, label) _patch_at(_jit, jump, label) +static void _patch_at(jit_state_t*,jit_word_t,jit_word_t); +#endif + +#if CODE +static void +_f2r(jit_state_t *_jit, + jit_int32_t op, jit_int32_t rd, jit_int32_t op2, jit_int32_t imm22) +{ + jit_instr_t v; + assert(!(op & 0xfffffffc)); + assert(!(rd & 0xffffffe0)); + assert(!(op2 & 0xfffffff8)); + assert(s22_p(imm22)); + v.op.b = op; + v.rd.b = rd; + v.op2.b = op2; + v.imm22.b = imm22; + ii(v.v); +} + +static void +_f2b(jit_state_t *_jit, + jit_int32_t op, jit_int32_t a, jit_int32_t cond, jit_int32_t op2, + jit_int32_t disp22) +{ + jit_instr_t v; + assert(!(op & 0xfffffffc)); + assert(!(a & 0xfffffffe)); + assert(!(cond & 0xfffffff0)); + assert(!(op2 & 0xfffffff8)); + assert(s22_p(disp22)); + v.op.b = op; + v.a.b = a; + v.cond.b = cond; + v.op2.b = op2; + v.disp22.b = disp22; + ii(v.v); +} + +# if __WORDSIZE == 64 +static void +_f2bp(jit_state_t *_jit, + jit_int32_t op, jit_int32_t a, jit_int32_t cond, jit_int32_t op2, + jit_int32_t cc1, jit_int32_t cc0, jit_int32_t p, jit_int32_t disp19) +{ + jit_instr_t v; + assert(!(op & 0xfffffffc)); + assert(!(a & 0xfffffffe)); + assert(!(cond & 0xfffffff0)); + assert(!(op2 & 0xfffffff8)); + assert(s19_p(disp19)); + v.op.b = op; + v.a.b = a; + v.cond.b = cond; + v.op2.b = op2; + v.cc1.b = cc1; + v.cc0.b = cc0; + v.p.b = p; + v.disp19.b = disp19; + ii(v.v); +} +# endif + +static void +_f3r(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, + jit_int32_t op3, jit_int32_t rs1, jit_int32_t rs2) +{ + jit_instr_t v; + assert(!(op & 0xfffffffc)); + assert(!(rd & 0xffffffe0)); + assert(!(op3 & 0xffffffc0)); + assert(!(rs1 & 0xffffffe0)); + assert(!(rs2 & 0xffffffe0)); + v.op.b = op; + v.rd.b = rd; + v.op3.b = op3; + v.rs1.b = rs1; + v.i.b = 0; + v.asi.b = 0; + v.rs2.b = rs2; + ii(v.v); +} + +# if __WORDSIZE == 64 +static void +_f3rx(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, + jit_int32_t op3, jit_int32_t rs1, jit_int32_t rs2) +{ + jit_instr_t v; + assert(!(op & 0xfffffffc)); + assert(!(rd & 0xffffffe0)); + assert(!(op3 & 0xffffffc0)); + assert(!(rs1 & 0xffffffe0)); + assert(!(rs2 & 0xffffffe0)); + v.op.b = op; + v.rd.b = rd; + v.op3.b = op3; + v.rs1.b = rs1; + v.i.b = 0; + v.x.b = 1; + v.asix.b = 0; + v.rs2.b = rs2; + ii(v.v); +} + +static void +_f3s(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, + jit_int32_t op3, jit_int32_t rs1, jit_int32_t shim) +{ + jit_instr_t v; + assert(!(op & 0xfffffffc)); + assert(!(rd & 0xffffffe0)); + assert(!(op3 & 0xffffffc0)); + assert(!(rs1 & 0xffffffe0)); + assert(!(shim & 0xffffffc0)); + v.op.b = op; + v.rd.b = rd; + v.op3.b = op3; + v.rs1.b = rs1; + v.i.b = 1; + v.x.b = 1; + v.asis.b = 0; + v.shim.b = shim; + ii(v.v); +} +# endif + +static void +_f3i(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, + jit_int32_t op3, jit_int32_t rs1, jit_int32_t simm13) +{ + jit_instr_t v; + assert(!(op & 0xfffffffc)); + assert(!(rd & 0xffffffe0)); + assert(!(op3 & 0xffffffc0)); + assert(!(rs1 & 0xffffffe0)); + assert(s13_p(simm13)); + v.op.b = op; + v.rd.b = rd; + v.op3.b = op3; + v.rs1.b = rs1; + v.i.b = 1; + v.simm13.b = simm13; + ii(v.v); +} + +static void +_f3t(jit_state_t *_jit, jit_int32_t cond, + jit_int32_t rs1, jit_int32_t i, jit_int32_t rs2_imm7) +{ + jit_instr_t v; + assert(!(cond & 0xfffffff0)); + assert(!(i & 0xfffffffe)); + assert(!(rs1 & 0xffffffe0)); + v.op.b = 2; + v.rd.b = cond; + v.op3.b = 58; + v.i.b = i; + if (i) { + assert(s7_p(rs2_imm7)); + v.res.b = 0; + v.imm7.b = rs2_imm7; + } + else { + assert(!(rs2_imm7 & 0xffffffe0)); + v.asi.b = 0; + v.rs2.b = rs2_imm7; + } + ii(v.v); +} + +static void +_f3a(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd, + jit_int32_t op3, jit_int32_t rs1, jit_int32_t asi, jit_int32_t rs2) +{ + jit_instr_t v; + assert(!(op & 0xfffffffc)); + assert(!(rd & 0xffffffe0)); + assert(!(op3 & 0xffffffc0)); + assert(!(rs1 & 0xffffffe0)); + assert(!(asi & 0xffffff00)); + assert(!(rs2 & 0xffffffe0)); + v.op.b = op; + v.rd.b = rd; + v.op3.b = op3; + v.rs1.b = rs1; + v.i.b = 0; + v.asi.b = asi; + v.rs2.b = rs2; + ii(v.v); +} + +static void +_f1(jit_state_t *_jit, jit_int32_t op, jit_int32_t disp30) +{ + jit_instr_t v; + assert(!(op & 0xfffffffc)); + assert(s30_p(disp30)); + v.op.b = op; + v.disp30.b = disp30; + ii(v.v); +} + +static void +_nop(jit_state_t *_jit, jit_int32_t i0) +{ + for (; i0 > 0; i0 -= 4) + NOP(); + assert(i0 == 0); +} + +static void +_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + ORI(r1, 0, r0); +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + if (s13_p(i0)) + ORI(0, i0, r0); + else { +# if __WORDSIZE == 64 + if (i0 & 0xffffffff00000000) { + jit_int32_t reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), (i0 >> 32) & 0xffffffff); + movi(r0, i0 & 0xffffffff); + lshi(rn(reg), rn(reg), 32); + OR(rn(reg), r0, r0); + jit_unget_reg(reg); + } + else { +# endif + SETHI(HI((int)i0), r0); + if (LO(i0)) + ORI(r0, LO(i0), r0); +# if __WORDSIZE == 64 + } +# endif + } +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; +# if __WORDSIZE == 64 + jit_int32_t reg; +# endif + w = _jit->pc.w; +# if __WORDSIZE == 64 + reg = jit_get_reg(jit_class_gpr); + SETHI(HI((int)i0), r0); + ORI(r0, LO(i0), r0); + i0 = (int)(i0 >> 32); + SETHI(HI(i0), rn(reg)); + ORI(rn(reg), LO(i0), rn(reg)); + SLLXI(rn(reg), 32, rn(reg)); + OR(rn(reg), r0, r0); + jit_unget_reg(reg); +# else + SETHI(HI(i0), r0); + ORI(r0, LO(i0), r0); +# endif + return (w); +} + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + ADDI(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +# if __WORDSIZE == 64 +static void +_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ltr_u(rn(jit_carry), rn(reg), r1); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + addr(r0, r1, r2); + ltr_u(rn(jit_carry), r0, r1); + } +} +# endif + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ +# if __WORDSIZE == 32 + jit_int32_t reg; + if (s13_p(i0)) + ADDIcc(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addcr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +# else + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ltr_u(rn(jit_carry), rn(reg), r1); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + addi(r0, r1, i0); + ltr_u(rn(jit_carry), r0, r1); + } +# endif +} + +# if __WORDSIZE == 64 +static void +_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + addcr(r0, r1, r2); + addcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} +# endif + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ +# if __WORDSIZE == 32 + jit_int32_t reg; + if (s13_p(i0)) + ADDXIcc(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addxr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +# else + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + addci(r0, r1, i0); + addcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +# endif +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + SUBI(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +# if __WORDSIZE == 64 +static void +_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + subr(rn(reg), r1, r2); + ltr_u(rn(jit_carry), r1, rn(reg)); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + subr(r0, r1, r2); + ltr_u(rn(jit_carry), r1, r0); + } +} +# endif + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ +# if __WORDSIZE == 32 + jit_int32_t reg; + if (s13_p(i0)) + SUBIcc(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subcr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +# else + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, -i0); + ltr_u(rn(jit_carry), r1, rn(reg)); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + addi(r0, r1, -i0); + ltr_u(rn(jit_carry), r1, r0); + } +# endif +} + +# if __WORDSIZE == 64 +static void +_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + subcr(r0, r1, r2); + subcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} +#endif + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ +# if __WORDSIZE == 32 + jit_int32_t reg; + if (s13_p(i0)) + SUBXIcc(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subxr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +# else + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + subci(r0, r1, i0); + subcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +# endif +} + +static void +_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + subi(r0, r1, i0); + negr(r0, r0); +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) { +# if __WORDSIZE == 32 + UMULI(r1, i0, r0); +# else + MULXI(r1, i0, r0); +# endif + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + mulr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +# if __WORDSIZE == 32 +static void +_iqmulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + if (sign) + SMUL(r2, r3, r0); + else + UMUL(r2, r3, r0); + RDY(r1); +} + +static void +_iqmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + if (s13_p(i0)) { + if (sign) + SMULI(r2, i0, r0); + else + UMULI(r2, i0, r0); + RDY(r1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iqmulr(r0, r1, r2, rn(reg), sign); + jit_unget_reg(reg); + } +} + +# else +static __int128_t __llmul(jit_word_t a, jit_word_t b) +{ + return (__int128_t)a * (__int128_t)b; +} + +# define QMUL_PROLOG() \ + do { \ + (void)jit_get_reg(_O0|jit_class_gpr|jit_class_named); \ + (void)jit_get_reg(_O1|jit_class_gpr|jit_class_named); \ + if (r0 != _G2_REGNO && r1 != _G2_REGNO) \ + stxi(BIAS(-8), _FP_REGNO, _G2_REGNO); \ + if (r0 != _G3_REGNO && r1 != _G3_REGNO) \ + stxi(BIAS(-16), _FP_REGNO, _G3_REGNO); \ + if (r0 != _G4_REGNO && r1 != _G4_REGNO) \ + stxi(BIAS(-24), _FP_REGNO, _G4_REGNO); \ + } while (0) + +# define QMUL_EPILOG() \ + do { \ + if (r0 != _G2_REGNO && r1 != _G2_REGNO) \ + ldxi(_G2_REGNO, _FP_REGNO, BIAS(-8)); \ + if (r0 != _G3_REGNO && r1 != _G3_REGNO) \ + ldxi(_G3_REGNO, _FP_REGNO, BIAS(-16)); \ + if (r0 != _G4_REGNO && r1 != _G4_REGNO) \ + ldxi(_G4_REGNO, _FP_REGNO, BIAS(-24)); \ + (void)jit_unget_reg(_O0); \ + (void)jit_unget_reg(_O1); \ + } while (0) + +static void +_qmulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3) +{ + QMUL_PROLOG(); + movr(_O0_REGNO, r3); + movr(_O1_REGNO, r2); + calli((jit_word_t)__llmul); + movr(r0, _O1_REGNO); + movr(r1, _O0_REGNO); + QMUL_EPILOG(); +} + +static void +_qmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0) +{ + QMUL_PROLOG(); + movi(_O0_REGNO, i0); + movr(_O1_REGNO, r2); + calli((jit_word_t)__llmul); + movr(r0, _O1_REGNO); + movr(r1, _O0_REGNO); + QMUL_EPILOG(); +} + +static __uint128_t __ullmul(jit_uword_t a, jit_uword_t b) +{ + return (__uint128_t)a * (__uint128_t)b; +} + +static void +_qmulr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3) +{ + QMUL_PROLOG(); + movr(_O0_REGNO, r3); + movr(_O1_REGNO, r2); + calli((jit_word_t)__ullmul); + movr(r0, _O1_REGNO); + movr(r1, _O0_REGNO); + QMUL_EPILOG(); +} + +static void +_qmuli_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0) +{ + QMUL_PROLOG(); + movi(_O0_REGNO, i0); + movr(_O1_REGNO, r2); + calli((jit_word_t)__ullmul); + movr(r0, _O1_REGNO); + movr(r1, _O0_REGNO); + QMUL_EPILOG(); +} +# endif + +static void +_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +# if __WORDSIZE == 32 + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + rshi(rn(reg), r1, 31); + WRY(rn(reg), 0); + SDIV(r1, r2, r0); + jit_unget_reg(reg); +# else + SDIVX(r1, r2, r0); +# endif +} + +static void +_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; +# if __WORDSIZE == 32 + reg = jit_get_reg(jit_class_gpr); +# endif + if (s13_p(i0)) { +# if __WORDSIZE == 32 + rshi(rn(reg), r1, 31); + WRY(rn(reg), 0); + SDIVI(r1, i0, r0); +# else + SDIVXI(r1, i0, r0); +# endif + } + else { +# if __WORDSIZE == 64 + reg = jit_get_reg(jit_class_gpr); +# endif + movi(rn(reg), i0); + divr(r0, r1, rn(reg)); +# if __WORDSIZE == 64 + jit_unget_reg(reg); +# endif + } +# if __WORDSIZE == 32 + jit_unget_reg(reg); +# endif +} + +static void +_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +# if __WORDSIZE == 32 + WRYI(0, 0); + UDIV(r1, r2, r0); +# else + UDIVX(r1, r2, r0); +# endif +} + +static void +_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) { +# if __WORDSIZE == 32 + WRYI(0, 0); + UDIVI(r1, i0, r0); +# else + UDIVXI(r1, i0, r0); +# endif + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + divr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_iqdivr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + jit_int32_t sv0, rg0; + jit_int32_t sv1, rg1; + + if (r0 == r2 || r0 == r3) { + sv0 = jit_get_reg(jit_class_gpr); + rg0 = rn(sv0); + } + else + rg0 = r0; + if (r1 == r2 || r1 == r3) { + sv1 = jit_get_reg(jit_class_gpr); + rg1 = rn(sv1); + } + else + rg1 = r1; + + if (sign) + divr(rg0, r2, r3); + else + divr_u(rg0, r2, r3); + mulr(rg1, r3, rg0); + subr(rg1, r2, rg1); + if (rg0 != r0) { + movr(r0, rg0); + jit_unget_reg(sv0); + } + if (rg1 != r1) { + movr(r1, rg1); + jit_unget_reg(sv1); + } +} + +static void +_iqdivi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iqdivr(r0, r1, r2, rn(reg), sign); + jit_unget_reg(reg); +} + +static void +_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r1 || r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + divr(rn(reg), r1, r2); + mulr(rn(reg), r2, rn(reg)); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + else { + divr(r0, r1, r2); + mulr(r0, r2, r0); + subr(r0, r1, r0); + } +} + +static void +_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r1 || r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + divr_u(rn(reg), r1, r2); + mulr(rn(reg), r2, rn(reg)); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } + else { + divr_u(r0, r1, r2); + mulr(r0, r2, r0); + subr(r0, r1, r0); + } +} + +static void +_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + ANDI(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + andr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + ORI(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + orr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + XORI(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + xorr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_extr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, __WORDSIZE - 8); + rshi(r0, r0, __WORDSIZE - 8); +} + +static void +_extr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, __WORDSIZE - 16); + rshi(r0, r0, __WORDSIZE - 16); +} + +static void +_extr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, __WORDSIZE - 16); + rshi_u(r0, r0, __WORDSIZE - 16); +} + +#if __WORDSIZE == 64 +static void +_extr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, __WORDSIZE - 32); + rshi(r0, r0, __WORDSIZE - 32); +} + +static void +_extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, __WORDSIZE - 32); + rshi_u(r0, r0, __WORDSIZE - 32); +} +#endif + +static void +_cr(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMP(r1, r2); +# if __WORDSIZE == 32 + Ba(cc, 3); +# else + BPa(cc, 3); +# endif + movi(r0, 1); + movi(r0, 0); +} + +static void +_cw(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) { + CMPI(r1, i0); +# if __WORDSIZE == 32 + Ba(cc, 3); +# else + BPa(cc, 3); +# endif + movi(r0, 1); + movi(r0, 0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + cr(cc, r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDSBI(0, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDUBI(0, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDSHI(0, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDUHI(0, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) { +# if __WORDSIZE == 32 + LDI(0, i0, r0); +# else + LDSWI(0, i0, r0); +# endif + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +# if __WORDSIZE == 64 +static void +_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDUWI(0, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDXI(0, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); + } +} +# endif + +static void +_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDSBI(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_c(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDUBI(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_uc(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDSHI(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_s(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDUHI(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_us(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) { +# if __WORDSIZE == 32 + LDI(r1, i0, r0); +# else + LDSWI(r1, i0, r0); +# endif + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_i(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +# if __WORDSIZE == 64 +static void +_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDUWI(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_ui(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDXI(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_l(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} +# endif + +static void +_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (s13_p(i0)) + STBI(r0, 0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_c(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (s13_p(i0)) + STHI(r0, 0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_s(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (s13_p(i0)) { +# if __WORDSIZE == 32 + STI(r0, 0, i0); +# else + STWI(r0, 0, i0); +# endif + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_i(rn(reg), r0); + jit_unget_reg(reg); + } +} + +# if __WORDSIZE == 64 +static void +_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (s13_p(i0)) + STXI(r0, 0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_l(rn(reg), r0); + jit_unget_reg(reg); + } +} +# endif + +static void +_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (s13_p(i0)) + STBI(r1, r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_c(r0, rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (s13_p(i0)) + STHI(r1, r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_s(r0, rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (s13_p(i0)) { +# if __WORDSIZE == 32 + STI(r1, r0, i0); +# else + STWI(r1, r0, i0); +# endif + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_i(r0, rn(reg), r1); + jit_unget_reg(reg); + } +} + +# if __WORDSIZE == 64 +static void +_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (s13_p(i0)) + STXI(r1, r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_l(r0, rn(reg), r1); + jit_unget_reg(reg); + } +} +# endif + +static jit_word_t +_br(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CMP(r0, r1); + w = _jit->pc.w; +# if __WORDSIZE == 32 + B(cc, (i0 - w) >> 2); +# else + BP(cc, (i0 - w) >> 2); +# endif + NOP(); + return (w); +} + +static jit_word_t +_bw(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (s13_p(i1)) { + CMPI(r0, i1); + w = _jit->pc.w; +# if __WORDSIZE == 32 + B(cc, (i0 - w) >> 2); +# else + B(cc, (i0 - w) >> 2); +# endif + NOP(); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = br(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_b_asr(jit_state_t *_jit, jit_bool_t jif, jit_bool_t add, jit_bool_t sgn, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + if (add) + ADDcc(r0, r1, r0); + else + SUBcc(r0, r1, r0); + w = _jit->pc.w; +# if __WORDSIZE == 32 + B(sgn ? + (jif ? SPARC_BVS : SPARC_BVC) : + (jif ? SPARC_BCS : SPARC_BCC), + (i0 - w) >> 2); +# else + BP(sgn ? + (jif ? SPARC_BPVS : SPARC_BPVC) : + (jif ? SPARC_BPCS : SPARC_BPCC), + (i0 - w) >> 2); +# endif + NOP(); + return (w); +} + +static jit_word_t +_b_asw(jit_state_t *_jit, jit_bool_t jif, jit_bool_t add, jit_bool_t sgn, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (s13_p(i1)) { + if (add) + ADDIcc(r0, i1, r0); + else + SUBIcc(r0, i1, r0); + w = _jit->pc.w; +# if __WORDSIZE == 32 + B(sgn ? + (jif ? SPARC_BVS : SPARC_BVC) : + (jif ? SPARC_BCS : SPARC_BCC), + (i0 - w) >> 2); +# else + BP(sgn ? + (jif ? SPARC_BPVS : SPARC_BPVC) : + (jif ? SPARC_BPCS : SPARC_BPCC), + (i0 - w) >> 2); +# endif + NOP(); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = b_asr(jif, add, sgn, i0, r0, rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bm_r(jit_state_t *_jit, jit_bool_t set, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + BTST(r0, r1); + w = _jit->pc.w; +# if __WORDSIZE == 32 + B(set ? SPARC_BNZ : SPARC_BZ, (i0 - w) >> 2); +# else + BP(set ? SPARC_BPNE : SPARC_BPE, (i0 - w) >> 2); +# endif + NOP(); + return (w); +} + +static jit_word_t +_bm_w(jit_state_t *_jit, jit_bool_t set, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (s13_p(i1)) { + BTSTI(r0, i1); + w = _jit->pc.w; +# if __WORDSIZE == 32 + B(set ? SPARC_BNZ : SPARC_BZ, (i0 - w) >> 2); +# else + BP(set ? SPARC_BPNE : SPARC_BPE, (i0 - w) >> 2); +# endif + NOP(); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bm_r(set, i0, r0, rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +static void +_jmpr(jit_state_t *_jit, jit_int32_t r0) +{ + JMPL(0, r0, 0); + NOP(); +} + +static void +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + w = (i0 - _jit->pc.w) >> 2; + if (s22_p(w)) { + BA(w); + NOP(); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + } +} + +static jit_word_t +_jmpi_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + w = movi_p(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_callr(jit_state_t *_jit, jit_int32_t r0) +{ + CALL(r0); + NOP(); +} + +static void +_calli(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + w = (i0 - _jit->pc.w) >> 2; + CALLI(w); + NOP(); +} + +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + w = movi_p(rn(reg), i0); + callr(rn(reg)); + jit_unget_reg(reg); + return (w); +} + +#define OFF(n) BIAS(((n) * sizeof(jit_word_t))) +static void +_prolog(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t reg; + if (_jitc->function->define_frame || _jitc->function->assume_frame) { + jit_int32_t frame = -_jitc->function->frame; + assert(_jitc->function->self.aoff >= frame); + if (_jitc->function->assume_frame) + return; + _jitc->function->self.aoff = frame; + } + if (_jitc->function->allocar) + _jitc->function->self.aoff &= -16; + /* align at 16 bytes boundary */ + _jitc->function->stack = ((stack_framesize + + _jitc->function->self.alen - + _jitc->function->self.aoff) + 15) & -16; + SAVEI(_SP_REGNO, -_jitc->function->stack, _SP_REGNO); + + /* (most) other backends do not save incoming arguments, so, + * only save locals here */ + if (jit_regset_tstbit(&_jitc->function->regset, _L0)) + stxi(OFF(0), _SP_REGNO, _L0_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _L1)) + stxi(OFF(1), _SP_REGNO, _L1_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _L2)) + stxi(OFF(2), _SP_REGNO, _L2_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _L3)) + stxi(OFF(3), _SP_REGNO, _L3_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _L4)) + stxi(OFF(4), _SP_REGNO, _L4_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _L5)) + stxi(OFF(5), _SP_REGNO, _L5_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _L6)) + stxi(OFF(6), _SP_REGNO, _L6_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _L7)) + stxi(OFF(7), _SP_REGNO, _L7_REGNO); + + if (_jitc->function->allocar) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), BIAS(_jitc->function->self.aoff)); + /* Already "biased" by allocai */ + stxi_i(_jitc->function->aoffoff, _FP_REGNO, rn(reg)); + jit_unget_reg(reg); + } + + if (_jitc->function->self.call & jit_call_varargs) { + for (reg = _jitc->function->vagp; jit_arg_reg_p(reg); ++reg) + stxi(BIAS((16 + (__WORDSIZE == 32)) * sizeof(jit_word_t) + + reg * sizeof(jit_word_t)), _FP_REGNO, rn(_I0 + reg)); + } +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *node) +{ + if (_jitc->function->assume_frame) + return; + /* (most) other backends do not save incoming arguments, so, + * only save locals here */ + if (jit_regset_tstbit(&_jitc->function->regset, _L0)) + ldxi(_L0_REGNO, _FP_REGNO, _jitc->function->stack + OFF(0)); + if (jit_regset_tstbit(&_jitc->function->regset, _L1)) + ldxi(_L1_REGNO, _FP_REGNO, _jitc->function->stack + OFF(1)); + if (jit_regset_tstbit(&_jitc->function->regset, _L2)) + ldxi(_L2_REGNO, _FP_REGNO, _jitc->function->stack + OFF(2)); + if (jit_regset_tstbit(&_jitc->function->regset, _L3)) + ldxi(_L3_REGNO, _FP_REGNO, _jitc->function->stack + OFF(3)); + if (jit_regset_tstbit(&_jitc->function->regset, _L4)) + ldxi(_L4_REGNO, _FP_REGNO, _jitc->function->stack + OFF(4)); + if (jit_regset_tstbit(&_jitc->function->regset, _L5)) + ldxi(_L5_REGNO, _FP_REGNO, _jitc->function->stack + OFF(5)); + if (jit_regset_tstbit(&_jitc->function->regset, _L6)) + ldxi(_L6_REGNO, _FP_REGNO, _jitc->function->stack + OFF(6)); + if (jit_regset_tstbit(&_jitc->function->regset, _L7)) + ldxi(_L7_REGNO, _FP_REGNO, _jitc->function->stack + OFF(7)); + RESTOREI(0, 0, 0); + RETL(); + NOP(); +} + +static void +_vastart(jit_state_t *_jit, jit_int32_t r0) +{ + /* Initialize stack pointer to the first stack argument. */ + if (jit_arg_reg_p(_jitc->function->vagp)) + addi(r0, _FP_REGNO, BIAS((16 + (__WORDSIZE == 32) + + _jitc->function->vagp) * + sizeof(jit_word_t))); + else + addi(r0, _FP_REGNO, BIAS(_jitc->function->self.size)); +} + +static void +_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(_jitc->function->self.call & jit_call_varargs); + + /* Load argument. */ + ldr(r0, r1); + + /* Update vararg stack pointer. */ + addi(r1, r1, sizeof(jit_word_t)); +} + +static void +_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label) +{ + jit_instr_t i; + union { + jit_int32_t *i; + jit_word_t w; + } u; + + u.w = instr; + i.v = u.i[0]; + + if (i.op.b == 0) { /* conditional branch */ + if (i.op2.b == 2 || i.op2.b == 6) { /* int or float condition */ + i.disp22.b = (label - instr) >> 2; + u.i[0] = i.v; + } +# if __WORDSIZE == 64 + else if (i.op2.b == 1) { + i.disp19.b = (label - instr) >> 2; + u.i[0] = i.v; + } +# endif + else if (i.op2.b == 4) { /* movi_p */ + /* SETHI */ + i.imm22.b = HI((int)label); + u.i[0] = i.v; + i.v = u.i[1]; + if (i.op.b == 2 && i.op3.b == 2) { + /* ORI */ + i.simm13.b = LO(label); + u.i[1] = i.v; +# if __WORDSIZE == 64 + i.v = u.i[2]; + assert(i.op2.b == 4); + label = (label >> 32) & 0xffffffff; + i.imm22.b = HI((int)label); + u.i[2] = i.v; + i.v = u.i[3]; + assert(i.op.b == 2 && i.op3.b == 2); + /* ORI */ + i.simm13.b = LO(label); + u.i[3] = i.v; +# endif + } + else + abort(); + } + else + abort(); + } + else + abort(); +} +#endif diff --git a/deps/lightning/lib/jit_sparc-fpu.c b/deps/lightning/lib/jit_sparc-fpu.c new file mode 100644 index 0000000..ae2cbab --- /dev/null +++ b/deps/lightning/lib/jit_sparc-fpu.c @@ -0,0 +1,1499 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# if __WORDSIZE == 32 +# define FPR(r) (r) +# define CLASS_SNG jit_class_fpr +# define CLASS_DBL jit_class_fpr +# else +# define single_precision_p(r) ((r) >= 0 && (r) <= 31) +# define FPR(r) ((r) > 31 ? (r) - 31 : (r)) +# define CLASS_SNG (jit_class_fpr | jit_class_sng) +# define CLASS_DBL (jit_class_fpr | jit_class_dbl) +# endif +# define LDF(rs1, rs2, rd) f3r(3, FPR(rd), 32, FPR(rs1), FPR(rs2)) +# define LDFI(rs1, imm, rd) f3i(3, FPR(rd), 32, FPR(rs1), imm) +# define LDDF(rs1, rs2, rd) f3r(3, FPR(rd), 35, FPR(rs1), FPR(rs2)) +# define LDDFI(rs1, imm, rd) f3i(3, FPR(rd), 35, FPR(rs1), imm) +# define LDFSR(rs1, rs2, rd) f3r(3, FPR(rd), 33, FPR(rs1), FPR(rs2)) +# define LDFSRI(rs1, imm, rd) f3i(3, FPR(rd), 33, FPR(rs1), imm) +# define STF(rd, rs1, rs2) f3r(3, FPR(rd), 36, FPR(rs1), FPR(rs2)) +# define STFI(rd, rs1, imm) f3i(3, FPR(rd), 36, FPR(rs1), imm) +# define STDF(rd, rs1, rs2) f3r(3, FPR(rd), 39, FPR(rs1), FPR(rs2)) +# define STDFI(rd, rs1, imm) f3i(3, FPR(rd), 39, FPR(rs1), imm) +# define STFSR(rd, rs1, rs2) f3r(3, FPR(rd), 37, FPR(rs1), FPR(rs2)) +# define STFSRI(rd, rs1, imm) f3i(3, FPR(rd), 37, FPR(rs1), imm) +# define STDFQ(rd, rs1, rs2) f3r(3, FPR(rd), 38, FPR(rs1), FPR(rs2)) +# define STFDFQ(rd, rs1, imm) f3i(3, FPR(rd), 38, FPR(rs1), imm) +# define SPARC_FBA 8 /* always - 1 */ +# define SPARC_FBN 0 /* never - 0 */ +# define SPARC_FBU 7 /* unordered - U */ +# define SPARC_FBG 6 /* greater - G */ +# define SPARC_FBUG 5 /* unordered or greater - G or U */ +# define SPARC_FBL 4 /* less - L */ +# define SPARC_FBUL 3 /* unordered or less - L or U */ +# define SPARC_FBLG 2 /* less or greater - L or G */ +# define SPARC_FBNE 1 /* not equal - L or G or U */ +# define SPARC_FBNZ SPARC_FBNE +# define SPARC_FBE 9 /* equal - E */ +# define SPARC_FBZ SPARC_FBE +# define SPARC_FBUE 10 /* unordered or equal - E or U */ +# define SPARC_FBGE 11 /* greater or equal - E or G */ +# define SPARC_FBUGE 12 /* unordered or greater or equal - E or G or U */ +# define SPARC_FBLE 13 /* less or equal - E or L */ +# define SPARC_FBULE 14 /* unordered or less or equal - E or L or U */ +# define SPARC_FBO 15 /* ordered - E or L or G */ +# define FB(cc, imm) f2b(0, 0, cc, 6, imm) +# define FBa(cc, imm) f2b(0, 1, cc, 6, imm) +# define FBA(imm) FB(SPARC_FBA, imm) +# define FBAa(imm) FBa(SPARC_FBA, imm) +# define FBN(imm) FB(SPARC_FBN, imm) +# define FBNa(imm) FBa(SPARC_FBN, imm) +# define FBU(imm) FB(SPARC_FBU, imm) +# define FBUa(imm) FBa(SPARC_FBU, imm) +# define FBG(imm) FB(SPARC_FBG, imm) +# define FBGa(imm) FBa(SPARC_FBG, imm) +# define FBUG(imm) FB(SPARC_FBUG, imm) +# define FBUGa(imm) FBa(SPARC_FBUG, imm) +# define FBL(imm) FB(SPARC_FBL, imm) +# define FBLa(imm) FBa(SPARC_FBL, imm) +# define FBUL(imm) FB(SPARC_FBUL, imm) +# define FBULa(imm) FBa(SPARC_FBUL, imm) +# define FBLG(imm) FB(SPARC_FBLG, imm) +# define FBLGa(imm) FBa(SPARC_FBLG, imm) +# define FBNE(imm) FB(SPARC_FBNE, imm) +# define FBNEa(imm) FBa(SPARC_FBNE, imm) +# define FBE(imm) FB(SPARC_FBE, imm) +# define FBEa(imm) FBa(SPARC_FBE, imm) +# define FBUE(imm) FB(SPARC_FBUE, imm) +# define FBUEa(imm) FBa(SPARC_FBUE, imm) +# define FBLE(imm) FB(SPARC_FBLE, imm) +# define FBLEa(imm) FBa(SPARC_FBLE, imm) +# define FBO(imm) FB(SPARC_FBO, imm) +# define FBOa(imm) FBa(SPARC_FBO, imm) +# define FPop1(rd, rs1, opf, rs2) f3f(rd, 52, rs1, opf, rs2) +# define FPop2(rd, rs1, opf, rs2) f3f(rd, 53, rs1, opf, rs2) +# define f3f(rd, op3, rs1, opf, rs2) _f3f(_jit, rd, op3, rs1, opf, rs2) +static void +_f3f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t, jit_int32_t,jit_int32_t); +# define FITOS(rs2, rd) FPop1(rd, 0, 196, rs2) +# define FITOD(rs2, rd) FPop1(rd, 0, 200, rs2) +# define FITOQ(rs2, rd) FPop1(rd, 0, 204, rs2) +# if __WORDSIZE == 64 +# define FXTOS(rs2, rd) FPop1(rd, 0, 132, rs2) +# define FXTOD(rs2, rd) FPop1(rd, 0, 136, rs2) +# define FxTOQ(rs2, rd) FPop1(rd, 0, 140, rs2) +# endif +# define FSTOI(rs2, rd) FPop1(rd, 0, 209, rs2) +# define FDTOI(rs2, rd) FPop1(rd, 0, 210, rs2) +# define FQTOI(rs2, rd) FPop1(rd, 0, 211, rs2) +# define FSTOX(rs2, rd) FPop1(rd, 0, 129, rs2) +# define FDTOX(rs2, rd) FPop1(rd, 0, 130, rs2) +# define FQTOX(rs2, rd) FPop1(rd, 0, 131, rs2) +# define FSTOD(rs2, rd) FPop1(rd, 0, 201, rs2) +# define FSTOQ(rs2, rd) FPop1(rd, 0, 205, rs2) +# define FDTOS(rs2, rd) FPop1(rd, 0, 198, rs2) +# define FDTOQ(rs2, rd) FPop1(rd, 0, 206, rs2) +# define FQTOS(rs2, rd) FPop1(rd, 0, 199, rs2) +# define FQTOD(rs2, rd) FPop1(rd, 0, 203, rs2) +# define FMOVS(rs2, rd) FPop1(rd, 0, 1, rs2) +# define FMOVD(rs2, rd) FPop1(rd, 0, 2, rs2) +# define FMOVQ(rs2, rd) FPop1(rd, 0, 3, rs2) +# define FNEGS(rs2, rd) FPop1(rd, 0, 5, rs2) +# define FNEGD(rs2, rd) FPop1(rd, 0, 6, rs2) +# define FNEGQ(rs2, rd) FPop1(rd, 0, 7, rs2) +# define FABSS(rs2, rd) FPop1(rd, 0, 9, rs2) +# define FABSD(rs2, rd) FPop1(rd, 0, 10, rs2) +# define FABSQ(rs2, rd) FPop1(rd, 0, 11, rs2) +# define FSQRTS(rs2, rd) FPop1(rd, 0, 41, rs2) +# define FSQRTD(rs2, rd) FPop1(rd, 0, 42, rs2) +# define FSQRTQ(rs2, rd) FPop1(rd, 0, 43, rs2) +# define SPARC_FADDS 65 +# define SPARC_FADDD 66 +# define SPARC_FADDQ 67 +# define SPARC_FSUBS 69 +# define SPARC_FSUBD 70 +# define SPARC_FSUBQ 71 +# define SPARC_FMULS 73 +# define SPARC_FMULD 74 +# define SPARC_FMULQ 75 +# define SPARC_FSMULD 105 +# define SPARC_FDMULQ 110 +# define SPARC_FDIVS 77 +# define SPARC_FDIVD 78 +# define SPARC_FDIVQ 79 +# define FADDS(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FADDS, rs2) +# define FADDD(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FADDD, rs2) +# define FADDQ(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FADDQ, rs2) +# define FSUBS(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FSUBS, rs2) +# define FSUBD(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FSUBD, rs2) +# define FSUBQ(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FSUBQ, rs2) +# define FMULS(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FMULS, rs2) +# define FMULD(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FMULD, rs2) +# define FMULQ(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FMULQ, rs2) +# define FSMULD(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FSMULD, rs2) +# define FDMULQ(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FDMULQ, rs2) +# define FDIVS(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FDIVS, rs2) +# define FDIVD(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FDIVD, rs2) +# define FDIVQ(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FDIVQ, rs2) +# define SPARC_FCMPS 81 +# define SPARC_FCMPD 82 +# define SPARC_FCMPQ 83 +# define SPARC_FCMPES 85 +# define SPARC_FCMPED 86 +# define SPARC_FCMPEQ 87 +# define FCMPS(rs1, rs2) FPop2(0, rs1, SPARC_FCMPS, rs2) +# define FCMPD(rs1, rs2) FPop2(0, rs1, SPARC_FCMPD, rs2) +# define FCMPQ(rs1, rs2) FPop2(0, rs1, SPARC_FCMPQ, rs2) +# define FCMPES(rs1, rs2) FPop2(0, rs1, SPARC_FCMPES, rs2) +# define FCMPED(rs1, rs2) FPop2(0, rs1, SPARC_FCMPED, rs2) +# define FCMPEQ(rs1, rs2) FPop2(0, rs1, SPARC_FCMPEQ, rs2) +# define CPop1(rd, rs1, opc, rs2) f3f(rd, 54, rs1, opf, rs2) +# define CPop2(rd, rs1, opc, rs2) f3f(rd, 55, rs1, opf, rs2) +# define extr_f(r0, r1) _extr_f(_jit, r0, r1) +static void _extr_f(jit_state_t*, jit_int32_t, jit_int32_t); +# if __WORDSIZSE == 32 +# define truncr_f(r0, r1) truncr_f_i(r0, r1) +# define truncr_d(r0, r1) truncr_d_i(r0, r1) +# else +# define truncr_f(r0, r1) truncr_f_l(r0, r1) +# define truncr_d(r0, r1) truncr_d_l(r0, r1) +# endif +# define truncr_f_i(r0, r1) _truncr_f_i(_jit, r0, r1) +static void _truncr_f_i(jit_state_t*, jit_int32_t, jit_int32_t); +# if __WORDSIZE == 64 +# define truncr_f_l(r0, r1) _truncr_f_l(_jit, r0, r1) +static void _truncr_f_l(jit_state_t*, jit_int32_t, jit_int32_t); +# endif +# if __WORDSIZE == 32 +# define extr_d_f(r0, r1) FDTOS(r1, r0) +# else +# define extr_d_f(r0, r1) _extr_d_f(_jit, r0, r1) +static void _extr_d_f(jit_state_t*, jit_int32_t, jit_int32_t); +# endif +# define movi_f(r0, i0) _movi_f(_jit, r0, i0) +# if __WORDSIZE == 32 +# define movr_f(r0, r1) FMOVS(r1, r0) +# else +# define movr_f(r0, r1) _movr_f(_jit, r0, r1) +static void _movr_f(jit_state_t*, jit_int32_t, jit_int32_t); +# endif +static void _movi_f(jit_state_t*, jit_int32_t, jit_float32_t*); +# if __WORDSIZE == 32 +# define negr_f(r0, r1) FNEGS(r1, r0) +# define absr_f(r0, r1) FABSS(r1, r0) +# define sqrtr_f(r0, r1) FSQRTS(r1, r0) +# else +# define negr_f(r0, r1) _negr_f(_jit, r0, r1) +static void _negr_f(jit_state_t*, jit_int32_t, jit_int32_t); +# define absr_f(r0, r1) _absr_f(_jit, r0, r1) +static void _absr_f(jit_state_t*, jit_int32_t, jit_int32_t); +# define sqrtr_f(r0, r1) _sqrtr_f(_jit, r0, r1) +static void _sqrtr_f(jit_state_t*, jit_int32_t, jit_int32_t); +# endif +# define extr_d(r0, r1) _extr_d(_jit, r0, r1) +static void _extr_d(jit_state_t*, jit_int32_t, jit_int32_t); +# define truncr_d_i(r0, r1) _truncr_d_i(_jit, r0, r1) +static void _truncr_d_i(jit_state_t*, jit_int32_t, jit_int32_t); +# if __WORDSIZE == 64 +# define truncr_d_l(r0, r1) _truncr_d_l(_jit, r0, r1) +static void _truncr_d_l(jit_state_t*, jit_int32_t, jit_int32_t); +# endif +# if __WORDSIZE == 32 +# define extr_f_d(r0, r1) FSTOD(r1, r0) +# else +# define extr_f_d(r0, r1) _extr_f_d(_jit, r0, r1) +static void _extr_f_d(jit_state_t*, jit_int32_t, jit_int32_t); +# endif +# define movi_d(r0, i0) _movi_d(_jit, r0, i0) +static void _movi_d(jit_state_t*, jit_int32_t, jit_float64_t*); +# if __WORDSIZE == 32 +# define movr_d(r0, r1) _movr_d(_jit, r0, r1) +static void _movr_d(jit_state_t*, jit_int32_t, jit_int32_t); +# define negr_d(r0, r1) _negr_d(_jit, r0, r1) +static void _negr_d(jit_state_t*, jit_int32_t, jit_int32_t); +# define absr_d(r0, r1) _absr_d(_jit, r0, r1) +static void _absr_d(jit_state_t*, jit_int32_t, jit_int32_t); +# else +# define movr_d(r0, r1) FMOVD(r1, r0) +# define negr_d(r0, r1) FNEGD(r1, r0) +# define absr_d(r0, r1) FABSD(r1, r0) +# endif +# define sqrtr_d(r0, r1) FSQRTD(r1, r0) +# define fop1f(op, r0, r1, i0) _fop1f(_jit, op, r0, r1, i0) +static void _fop1f(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_float32_t*); +# define rfop1f(op, r0, r1, i0) _rfop1f(_jit, op, r0, r1, i0) +static void _rfop1f(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_float32_t*); +# define fop1d(op, r0, r1, i0) _fop1d(_jit, op, r0, r1, i0) +static void _fop1d(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_float64_t*); +# define rfop1d(op, r0, r1, i0) _rfop1d(_jit, op, r0, r1, i0) +static void _rfop1d(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_float64_t*); +# if __WORDSIZE == 32 +# define addr_f(r0, r1, r2) FADDS(r1, r2, r0) +# define subr_f(r0, r1, r2) FSUBS(r1, r2, r0) +# define mulr_f(r0, r1, r2) FMULS(r1, r2, r0) +# define divr_f(r0, r1, r2) FDIVS(r1, r2, r0) +# else +# define fop2f(op, r0, r1, r2) _fop2f(_jit, op, r0, r1, r2) +static void _fop2f(jit_state_t*, jit_int32_t, + jit_int32_t, jit_int32_t, jit_int32_t); +# define addr_f(r0, r1, r2) fop2f(SPARC_FADDS, r0, r1, r2) +# define subr_f(r0, r1, r2) fop2f(SPARC_FSUBS, r0, r1, r2) +# define mulr_f(r0, r1, r2) fop2f(SPARC_FMULS, r0, r1, r2) +# define divr_f(r0, r1, r2) fop2f(SPARC_FDIVS, r0, r1, r2) +# endif +# define addi_f(r0, r1, i0) fop1f(SPARC_FADDS, r0, r1, i0) +# define subi_f(r0, r1, i0) fop1f(SPARC_FSUBS, r0, r1, i0) +# define rsbr_f(r0, r1, r2) subr_f(r0, r2, r1) +# define rsbi_f(r0, r1, i0) rfop1f(SPARC_FSUBS, r0, r1, i0) +# define rsbr_d(r0, r1, r2) subr_d(r0, r2, r1) +# define rsbi_d(r0, r1, i0) rfop1d(SPARC_FSUBD, r0, r1, i0) +# define muli_f(r0, r1, i0) fop1f(SPARC_FMULS, r0, r1, i0) +# define divi_f(r0, r1, i0) fop1f(SPARC_FDIVS, r0, r1, i0) +# define addr_d(r0, r1, r2) FADDD(r1, r2, r0) +# define addi_d(r0, r1, i0) fop1d(SPARC_FADDD, r0, r1, i0) +# define subr_d(r0, r1, r2) FSUBD(r1, r2, r0) +# define subi_d(r0, r1, i0) fop1d(SPARC_FSUBD, r0, r1, i0) +# define rsbr_d(r0, r1, r2) subr_d(r0, r2, r1) +# define rsbi_d(r0, r1, i0) rfop1d(SPARC_FSUBD, r0, r1, i0) +# define mulr_d(r0, r1, r2) FMULD(r1, r2, r0) +# define muli_d(r0, r1, i0) fop1d(SPARC_FMULD, r0, r1, i0) +# define divr_d(r0, r1, r2) FDIVD(r1, r2, r0) +# define divi_d(r0, r1, i0) fop1d(SPARC_FDIVD, r0, r1, i0) +#define fcr(cc, r0, r1, r2) _fcr(_jit, cc, r0, r1, r2) +static void _fcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define fcw(cc, r0, r1, i0) _fcw(_jit, cc, r0, r1, i0) +static void +_fcw(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ltr_f(r0, r1, r2) fcr(SPARC_FBL, r0, r1, r2) +# define lti_f(r0, r1, i0) fcw(SPARC_FBL, r0, r1, i0) +# define ler_f(r0, r1, r2) fcr(SPARC_FBLE, r0, r1, r2) +# define lei_f(r0, r1, i0) fcw(SPARC_FBLE, r0, r1, i0) +# define eqr_f(r0, r1, r2) fcr(SPARC_FBE, r0, r1, r2) +# define eqi_f(r0, r1, i0) fcw(SPARC_FBE, r0, r1, i0) +# define ger_f(r0, r1, r2) fcr(SPARC_FBGE, r0, r1, r2) +# define gei_f(r0, r1, i0) fcw(SPARC_FBGE, r0, r1, i0) +# define gtr_f(r0, r1, r2) fcr(SPARC_FBG, r0, r1, r2) +# define gti_f(r0, r1, i0) fcw(SPARC_FBG, r0, r1, i0) +# define ner_f(r0, r1, r2) fcr(SPARC_FBNE, r0, r1, r2) +# define nei_f(r0, r1, i0) fcw(SPARC_FBNE, r0, r1, i0) +# define unltr_f(r0, r1, r2) fcr(SPARC_FBUL, r0, r1, r2) +# define unlti_f(r0, r1, i0) fcw(SPARC_FBUL, r0, r1, i0) +# define unler_f(r0, r1, r2) fcr(SPARC_FBULE, r0, r1, r2) +# define unlei_f(r0, r1, i0) fcw(SPARC_FBULE, r0, r1, i0) +# define uneqr_f(r0, r1, r2) fcr(SPARC_FBUE, r0, r1, r2) +# define uneqi_f(r0, r1, i0) fcw(SPARC_FBUE, r0, r1, i0) +# define unger_f(r0, r1, r2) fcr(SPARC_FBUGE, r0, r1, r2) +# define ungei_f(r0, r1, i0) fcw(SPARC_FBUGE, r0, r1, i0) +# define ungtr_f(r0, r1, r2) fcr(SPARC_FBUG, r0, r1, r2) +# define ungti_f(r0, r1, i0) fcw(SPARC_FBUG, r0, r1, i0) +# define ltgtr_f(r0, r1, r2) fcr(SPARC_FBLG, r0, r1, r2) +# define ltgti_f(r0, r1, i0) fcw(SPARC_FBLG, r0, r1, i0) +# define ordr_f(r0, r1, r2) fcr(SPARC_FBO, r0, r1, r2) +# define ordi_f(r0, r1, i0) fcw(SPARC_FBO, r0, r1, i0) +# define unordr_f(r0, r1, r2) fcr(SPARC_FBU, r0, r1, r2) +# define unordi_f(r0, r1, i0) fcw(SPARC_FBU, r0, r1, i0) +#define dcr(cc, r0, r1, r2) _dcr(_jit, cc, r0, r1, r2) +static void _dcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +#define dcw(cc, r0, r1, i0) _dcw(_jit, cc, r0, r1, i0) +static void +_dcw(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ltr_d(r0, r1, r2) dcr(SPARC_FBL, r0, r1, r2) +# define lti_d(r0, r1, i0) dcw(SPARC_FBL, r0, r1, i0) +# define ler_d(r0, r1, r2) dcr(SPARC_FBLE, r0, r1, r2) +# define lei_d(r0, r1, i0) dcw(SPARC_FBLE, r0, r1, i0) +# define eqr_d(r0, r1, r2) dcr(SPARC_FBE, r0, r1, r2) +# define eqi_d(r0, r1, i0) dcw(SPARC_FBE, r0, r1, i0) +# define ger_d(r0, r1, r2) dcr(SPARC_FBGE, r0, r1, r2) +# define gei_d(r0, r1, i0) dcw(SPARC_FBGE, r0, r1, i0) +# define gtr_d(r0, r1, r2) dcr(SPARC_FBG, r0, r1, r2) +# define gti_d(r0, r1, i0) dcw(SPARC_FBG, r0, r1, i0) +# define ner_d(r0, r1, r2) dcr(SPARC_FBNE, r0, r1, r2) +# define nei_d(r0, r1, i0) dcw(SPARC_FBNE, r0, r1, i0) +# define unltr_d(r0, r1, r2) dcr(SPARC_FBUL, r0, r1, r2) +# define unlti_d(r0, r1, i0) dcw(SPARC_FBUL, r0, r1, i0) +# define unler_d(r0, r1, r2) dcr(SPARC_FBULE, r0, r1, r2) +# define unlei_d(r0, r1, i0) dcw(SPARC_FBULE, r0, r1, i0) +# define uneqr_d(r0, r1, r2) dcr(SPARC_FBUE, r0, r1, r2) +# define uneqi_d(r0, r1, i0) dcw(SPARC_FBUE, r0, r1, i0) +# define unger_d(r0, r1, r2) dcr(SPARC_FBUGE, r0, r1, r2) +# define ungei_d(r0, r1, i0) dcw(SPARC_FBUGE, r0, r1, i0) +# define ungtr_d(r0, r1, r2) dcr(SPARC_FBUG, r0, r1, r2) +# define ungti_d(r0, r1, i0) dcw(SPARC_FBUG, r0, r1, i0) +# define ltgtr_d(r0, r1, r2) dcr(SPARC_FBLG, r0, r1, r2) +# define ltgti_d(r0, r1, i0) dcw(SPARC_FBLG, r0, r1, i0) +# define ordr_d(r0, r1, r2) dcr(SPARC_FBO, r0, r1, r2) +# define ordi_d(r0, r1, i0) dcw(SPARC_FBO, r0, r1, i0) +# define unordr_d(r0, r1, r2) dcr(SPARC_FBU, r0, r1, r2) +# define unordi_d(r0, r1, i0) dcw(SPARC_FBU, r0, r1, i0) +# if __WORDSIZE == 32 +# define ldr_f(r0, r1) LDF(r1, 0, r0) +# else +# define ldr_f(r0, r1) _ldr_f(_jit, r0, r1) +static void _ldr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# endif +# define ldi_f(r0, i0) _ldi_f(_jit, r0, i0) +static void _ldi_f(jit_state_t*,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define ldxr_f(r0, r1, r2) LDF(r1, r2, r0) +# else +# define ldxr_f(r0, r1, r2) _ldxr_f(_jit, r0, r1, r2) +static void _ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# endif +# define ldxi_f(r0, r1, i0) _ldxi_f(_jit, r0, r1, i0) +static void _ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# if __WORDSIZE == 32 +# define str_f(r0, r1) STF(r1, r0, 0) +# else +# define str_f(r0, r1) _str_f(_jit, r0, r1) +static void _str_f(jit_state_t*,jit_int32_t,jit_int32_t); +# endif +# define sti_f(r0, i0) _sti_f(_jit, r0, i0) +static void _sti_f(jit_state_t*,jit_word_t,jit_int32_t); +# if __WORDSIZE == 32 +# define stxr_f(r0, r1, r2) STF(r2, r1, r0) +# else +# define stxr_f(r0, r1, r2) _stxr_f(_jit, r0, r1, r2) +static void _stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# endif +# define stxi_f(r0, r1, i0) _stxi_f(_jit, r0, r1, i0) +static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define ldr_d(r0, r1) LDDF(r1, 0, r0) +# define ldi_d(r0, i0) _ldi_d(_jit, r0, i0) +static void _ldi_d(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_d(r0, r1, r2) LDDF(r1, r2, r0) +# define ldxi_d(r0, r1, i0) _ldxi_d(_jit, r0, r1, i0) +static void _ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define str_d(r0, r1) STDF(r1, r0, 0) +# define sti_d(r0, i0) _sti_d(_jit, r0, i0) +static void _sti_d(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_d(r0, r1, r2) STDF(r2, r1, r0) +# define stxi_d(r0, r1, i0) _stxi_d(_jit, r0, r1, i0) +static void _stxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define fbr(cc, i0, r0, r1) _fbr(_jit, cc, i0, r0, r1) +static jit_word_t +_fbr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t); +# define fbw(cc, i0, r0, i1) _fbw(_jit, cc, i0, r0, i1) +static jit_word_t +_fbw(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_float32_t*); +# define bltr_f(i0, r0, r1) fbr(SPARC_FBL, i0, r0, r1) +# define blti_f(i0, r0, i1) fbw(SPARC_FBL, i0, r0, i1) +# define bler_f(i0, r0, r1) fbr(SPARC_FBLE, i0, r0, r1) +# define blei_f(i0, r0, i1) fbw(SPARC_FBLE, i0, r0, i1) +# define beqr_f(i0, r0, r1) fbr(SPARC_FBE, i0, r0, r1) +# define beqi_f(i0, r0, i1) fbw(SPARC_FBE, i0, r0, i1) +# define bger_f(i0, r0, r1) fbr(SPARC_FBGE, i0, r0, r1) +# define bgei_f(i0, r0, i1) fbw(SPARC_FBGE, i0, r0, i1) +# define bgtr_f(i0, r0, r1) fbr(SPARC_FBG, i0, r0, r1) +# define bgti_f(i0, r0, i1) fbw(SPARC_FBG, i0, r0, i1) +# define bner_f(i0, r0, r1) fbr(SPARC_FBNE, i0, r0, r1) +# define bnei_f(i0, r0, i1) fbw(SPARC_FBNE, i0, r0, i1) +# define bunltr_f(i0, r0, r1) fbr(SPARC_FBUL, i0, r0, r1) +# define bunlti_f(i0, r0, i1) fbw(SPARC_FBUL, i0, r0, i1) +# define bunler_f(i0, r0, r1) fbr(SPARC_FBULE, i0, r0, r1) +# define bunlei_f(i0, r0, i1) fbw(SPARC_FBULE, i0, r0, i1) +# define buneqr_f(i0, r0, r1) fbr(SPARC_FBUE, i0, r0, r1) +# define buneqi_f(i0, r0, i1) fbw(SPARC_FBUE, i0, r0, i1) +# define bunger_f(i0, r0, r1) fbr(SPARC_FBUGE, i0, r0, r1) +# define bungei_f(i0, r0, i1) fbw(SPARC_FBUGE, i0, r0, i1) +# define bungtr_f(i0, r0, r1) fbr(SPARC_FBUG, i0, r0, r1) +# define bungti_f(i0, r0, i1) fbw(SPARC_FBUG, i0, r0, i1) +# define bltgtr_f(i0, r0, r1) fbr(SPARC_FBLG, i0, r0, r1) +# define bltgti_f(i0, r0, i1) fbw(SPARC_FBLG, i0, r0, i1) +# define bordr_f(i0, r0, r1) fbr(SPARC_FBO, i0, r0, r1) +# define bordi_f(i0, r0, i1) fbw(SPARC_FBO, i0, r0, i1) +# define bunordr_f(i0, r0, r1) fbr(SPARC_FBU, i0, r0, r1) +# define bunordi_f(i0, r0, i1) fbw(SPARC_FBU, i0, r0, i1) +# define dbr(cc, i0, r0, r1) _dbr(_jit, cc, i0, r0, r1) +static jit_word_t +_dbr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t); +# define dbw(cc, i0, r0, i1) _dbw(_jit, cc, i0, r0, i1) +static jit_word_t +_dbw(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_float64_t*); +# define bltr_d(i0, r0, r1) dbr(SPARC_FBL, i0, r0, r1) +# define blti_d(i0, r0, i1) dbw(SPARC_FBL, i0, r0, i1) +# define bler_d(i0, r0, r1) dbr(SPARC_FBLE, i0, r0, r1) +# define blei_d(i0, r0, i1) dbw(SPARC_FBLE, i0, r0, i1) +# define beqr_d(i0, r0, r1) dbr(SPARC_FBE, i0, r0, r1) +# define beqi_d(i0, r0, i1) dbw(SPARC_FBE, i0, r0, i1) +# define bger_d(i0, r0, r1) dbr(SPARC_FBGE, i0, r0, r1) +# define bgei_d(i0, r0, i1) dbw(SPARC_FBGE, i0, r0, i1) +# define bgtr_d(i0, r0, r1) dbr(SPARC_FBG, i0, r0, r1) +# define bgti_d(i0, r0, i1) dbw(SPARC_FBG, i0, r0, i1) +# define bner_d(i0, r0, r1) dbr(SPARC_FBNE, i0, r0, r1) +# define bnei_d(i0, r0, i1) dbw(SPARC_FBNE, i0, r0, i1) +# define bunltr_d(i0, r0, r1) dbr(SPARC_FBUL, i0, r0, r1) +# define bunlti_d(i0, r0, i1) dbw(SPARC_FBUL, i0, r0, i1) +# define bunler_d(i0, r0, r1) dbr(SPARC_FBULE, i0, r0, r1) +# define bunlei_d(i0, r0, i1) dbw(SPARC_FBULE, i0, r0, i1) +# define buneqr_d(i0, r0, r1) dbr(SPARC_FBUE, i0, r0, r1) +# define buneqi_d(i0, r0, i1) dbw(SPARC_FBUE, i0, r0, i1) +# define bunger_d(i0, r0, r1) dbr(SPARC_FBUGE, i0, r0, r1) +# define bungei_d(i0, r0, i1) dbw(SPARC_FBUGE, i0, r0, i1) +# define bungtr_d(i0, r0, r1) dbr(SPARC_FBUG, i0, r0, r1) +# define bungti_d(i0, r0, i1) dbw(SPARC_FBUG, i0, r0, i1) +# define bltgtr_d(i0, r0, r1) dbr(SPARC_FBLG, i0, r0, r1) +# define bltgti_d(i0, r0, i1) dbw(SPARC_FBLG, i0, r0, i1) +# define bordr_d(i0, r0, r1) dbr(SPARC_FBO, i0, r0, r1) +# define bordi_d(i0, r0, i1) dbw(SPARC_FBO, i0, r0, i1) +# define bunordr_d(i0, r0, r1) dbr(SPARC_FBU, i0, r0, r1) +# define bunordi_d(i0, r0, i1) dbw(SPARC_FBU, i0, r0, i1) +# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1) +static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t); +#endif + +#if CODE +static void +_f3f(jit_state_t *_jit, jit_int32_t rd, + jit_int32_t op3, jit_int32_t rs1, jit_int32_t opf, jit_int32_t rs2) +{ + jit_instr_t v; +# if __WORDSIZE == 64 + if (rd > 31) { + assert(rd <= 63 && (rd & 1) == 0); + rd -= 31; + } + if (rs1 > 31) { + assert(rs1 <= 63 && (rs1 & 1) == 0); + rs1 -= 31; + } + if (rs2 > 31) { + assert(rs2 <= 63 && (rs2 & 1) == 0); + rs2 -= 31; + } +# endif + assert(!(rd & 0xffffffe0)); + assert(!(op3 & 0xffffffc0)); + assert(!(rs1 & 0xffffffe0)); + assert(!(opf & 0xfffffe00)); + assert(!(rs2 & 0xffffffe0)); + v.op.b = 2; + v.rd.b = rd; + v.op3.b = op3; + v.rs1.b = rs1; + v.opf.b = opf; + v.rs2.b = rs2; + ii(v.v); +} + +# if __WORDSIZE == 64 +static void +_movr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0, t1; + if (r0 != r1) { + if (single_precision_p(r0)) { + if (single_precision_p(r1)) + FMOVS(r1, r0); + else { + t1 = jit_get_reg(CLASS_SNG); + movr_d(rn(t1), r1); + FMOVS(rn(t1), r0); + jit_unget_reg(t1); + } + } + else { + if (single_precision_p(r1)) { + t0 = jit_get_reg(CLASS_SNG); + FMOVS(r1, rn(t0)); + movr_d(r0, rn(t0)); + jit_unget_reg(t0); + } + else { + t1 = jit_get_reg(CLASS_SNG); + movr_d(rn(t1), r1); + FMOVS(rn(t1), rn(t1)); + movr_d(r0, rn(t1)); + jit_unget_reg(t1); + } + } + } +} + +static void +_negr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0, t1; + if (single_precision_p(r0)) { + if (single_precision_p(r1)) + FNEGS(r1, r0); + else { + t1 = jit_get_reg(CLASS_SNG); + movr_d(rn(t1), r1); + FNEGS(rn(t1), r0); + jit_unget_reg(t1); + } + } + else { + if (single_precision_p(r1)) { + t0 = jit_get_reg(CLASS_SNG); + FNEGS(r1, rn(t0)); + movr_d(r0, rn(t0)); + jit_unget_reg(t0); + } + else { + t1 = jit_get_reg(CLASS_SNG); + movr_d(rn(t1), r1); + FNEGS(rn(t1), rn(t1)); + movr_d(r0, rn(t1)); + jit_unget_reg(t1); + } + } +} + +static void +_absr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0, t1; + if (single_precision_p(r0)) { + if (single_precision_p(r1)) + FABSS(r1, r0); + else { + t1 = jit_get_reg(CLASS_SNG); + movr_d(rn(t1), r1); + FABSS(rn(t1), r0); + jit_unget_reg(t1); + } + } + else { + if (single_precision_p(r1)) { + t0 = jit_get_reg(CLASS_SNG); + FABSS(r1, rn(t0)); + movr_d(r0, rn(t0)); + jit_unget_reg(t0); + } + else { + t1 = jit_get_reg(CLASS_SNG); + movr_d(rn(t1), r1); + FABSS(rn(t1), rn(t1)); + movr_d(r0, rn(t1)); + jit_unget_reg(t1); + } + } +} + +static void +_sqrtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0, t1; + if (single_precision_p(r0)) { + if (single_precision_p(r1)) + FSQRTS(r1, r0); + else { + t1 = jit_get_reg(CLASS_SNG); + movr_d(rn(t1), r1); + FSQRTS(rn(t1), r0); + jit_unget_reg(t1); + } + } + else { + if (single_precision_p(r1)) { + t0 = jit_get_reg(CLASS_SNG); + FSQRTS(r1, rn(t0)); + movr_d(r0, rn(t0)); + jit_unget_reg(t0); + } + else { + t1 = jit_get_reg(CLASS_SNG); + movr_d(rn(t1), r1); + FSQRTS(rn(t1), rn(t1)); + movr_d(r0, rn(t1)); + jit_unget_reg(t1); + } + } +} +# endif + +# if __WORDSIZE == 64 +static void +_extr_d_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (!single_precision_p(r0)) { + reg = jit_get_reg(CLASS_SNG); + movr_d(rn(reg), r0); + FDTOS(r1, rn(reg)); + movr_d(r0, rn(reg)); + jit_unget_reg(reg); + } + else + FDTOS(r1, r0); +} +# endif + +static void +_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_int32_t reg; + + if (_jitc->no_data) { + data.f = *i0; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.i & 0xffffffff); + stxi_i(BIAS(-8), _FP_REGNO, rn(reg)); + jit_unget_reg(reg); + ldxi_f(r0, _FP_REGNO, BIAS(-8)); + } + else + ldi_f(r0, (jit_word_t)i0); +} + +# if __WORDSIZE == 64 +static void +_extr_f_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (!single_precision_p(r1)) { + reg = jit_get_reg(CLASS_SNG); + movr_d(rn(reg), r1); + FSTOD(rn(reg), r0); + jit_unget_reg(reg); + } + else + FSTOD(r1, r0); +} +# endif + +static void +_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + union { +# if __WORDSIZE == 32 + jit_int32_t i[2]; +# else + jit_word_t w; +# endif + jit_float64_t d; + } data; + jit_int32_t reg; + + if (_jitc->no_data) { + data.d = *i0; + reg = jit_get_reg(jit_class_gpr); +# if __WORDSIZE == 32 + movi(rn(reg), data.i[0]); +# else + movi(rn(reg), data.w); +# endif + stxi(BIAS(-8), _FP_REGNO, rn(reg)); +# if __WORDSIZE == 32 + movi(rn(reg), data.i[1]); + stxi_i(BIAS(-4), _FP_REGNO, rn(reg)); +# endif + jit_unget_reg(reg); + ldxi_d(r0, _FP_REGNO, BIAS(-8)); + } + else + ldi_d(r0, (jit_word_t)i0); +} + +# if __WORDSIZE == 32 +static void +_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(!(r0 & 1)); + assert(!(r1 & 1)); + if (r0 != r1) { + FMOVS(r1, r0); + FMOVS(r1 + 1, r0 + 1); + } +} + +static void +_negr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(!(r0 & 1)); + assert(!(r1 & 1)); + FNEGS(r1, r0); + if (r0 != r1) + FMOVS(r1 + 1, r0 + 1); +} + +static void +_absr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(!(r0 & 1)); + assert(!(r1 & 1)); + FABSS(r1, r0); + if (r0 != r1) + FMOVS(r1 + 1, r0 + 1); +} +# endif + +# if __WORDSIZE == 64 +# define single_rrr(NAME, CODE) \ +static void \ +NAME(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) \ +{ \ + jit_int32_t x0, t0, x1, t1, x2, t2, mask = 0; \ + if (!single_precision_p(r0)) { \ + mask |= 1; \ + t0 = jit_get_reg(CLASS_SNG); \ + x0 = rn(t0); \ + if (r0 == r1) { \ + x1 = x0; \ + movr_d(x1, r1); \ + if (r0 == r2) \ + x2 = x0; \ + } \ + else if (r0 == r2) { \ + x2 = x0; \ + movr_d(x2, r2); \ + } \ + } \ + else \ + x0 = r0; \ + if (!single_precision_p(r1)) { \ + if (r0 != r1) { \ + mask |= 2; \ + t1 = jit_get_reg(CLASS_SNG); \ + x1 = rn(t1); \ + movr_d(x1, r1); \ + if (r1 == r2) \ + x2 = x1; \ + } \ + } \ + else \ + x1 = r1; \ + if (!single_precision_p(r2)) { \ + if (r0 != r2 && r1 != r2) { \ + mask |= 4; \ + t2 = jit_get_reg(CLASS_SNG); \ + x2 = rn(t2); \ + movr_d(x2, r2); \ + } \ + } \ + else \ + x2 = r2; \ + CODE(x1, x2, x0); \ + if (mask & 1) { \ + movr_d(r0, x0); \ + jit_unget_reg(t0); \ + } \ + if (mask & 2) \ + jit_unget_reg(t1); \ + if (mask & 4) \ + jit_unget_reg(t2); \ +} + +static void +_fop2f(jit_state_t *_jit, jit_int32_t op, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t x0, t0, x1, t1, x2, t2, mask = 0; + if (!single_precision_p(r0)) { + mask |= 1; + t0 = jit_get_reg(CLASS_SNG); + x0 = rn(t0); + if (r0 == r1) { + x1 = x0; + movr_d(x1, r1); + if (r0 == r2) + x2 = x0; + } + else if (r0 == r2) { + x2 = x0; + movr_d(x2, r2); + } + } + else + x0 = r0; + if (!single_precision_p(r1)) { + if (r0 != r1) { + mask |= 2; + t1 = jit_get_reg(CLASS_SNG); + x1 = rn(t1); + movr_d(x1, r1); + if (r1 == r2) + x2 = x1; + } + } + else + x1 = r1; + if (!single_precision_p(r2)) { + if (r0 != r2 && r1 != r2) { + mask |= 4; + t2 = jit_get_reg(CLASS_SNG); + x2 = rn(t2); + movr_d(x2, r2); + } + } + else + x2 = r2; + FPop1(x0, x1, op, x2); + if (mask & 1) { + movr_d(r0, x0); + jit_unget_reg(t0); + } + if (mask & 2) + jit_unget_reg(t1); + if (mask & 4) + jit_unget_reg(t2); +} +# endif + +static void +_fop1f(jit_state_t *_jit, jit_int32_t op, + jit_int32_t r0, jit_int32_t r1, jit_float32_t *i0) +{ + jit_int32_t reg; +# if __WORDSIZE == 64 + jit_int32_t x0, t0, x1, t1, mask = 0; +# endif + reg = jit_get_reg(CLASS_SNG); + movi_f(rn(reg), i0); +# if __WORDSIZE == 64 + if (!single_precision_p(r0)) { + mask |= 1; + t0 = jit_get_reg(CLASS_SNG); + x0 = rn(t0); + if (r0 == r1) { + x1 = x0; + movr_d(x1, r1); + } + } + else + x0 = r0; + if (!single_precision_p(r1)) { + if (r0 != r1) { + mask |= 2; + t1 = jit_get_reg(CLASS_SNG); + x1 = rn(t1); + movr_d(x1, r1); + } + } + else + x1 = r1; + FPop1(x0, x1, op, rn(reg)); + if (mask & 1) { + movr_d(r0, x0); + jit_unget_reg(t0); + } + if (mask & 2) + jit_unget_reg(t1); +# else + FPop1(r0, r1, op, rn(reg)); +# endif + jit_unget_reg(reg); +} + +static void +_rfop1f(jit_state_t *_jit, jit_int32_t op, + jit_int32_t r0, jit_int32_t r1, jit_float32_t *i0) +{ + jit_int32_t reg; +# if __WORDSIZE == 64 + jit_int32_t x0, t0, x1, t1, mask = 0; +# endif + reg = jit_get_reg(CLASS_SNG); + movi_f(rn(reg), i0); +# if __WORDSIZE == 64 + if (!single_precision_p(r0)) { + mask |= 1; + t0 = jit_get_reg(CLASS_SNG); + x0 = rn(t0); + if (r0 == r1) { + x1 = x0; + movr_d(x1, r1); + } + } + else + x0 = r0; + if (!single_precision_p(r1)) { + if (r0 != r1) { + mask |= 2; + t1 = jit_get_reg(CLASS_SNG); + x1 = rn(t1); + movr_d(x1, r1); + } + } + else + x1 = r1; + FPop1(x0, rn(reg), op, x1); + if (mask & 1) { + movr_d(r0, x0); + jit_unget_reg(t0); + } + if (mask & 2) + jit_unget_reg(t1); +# else + FPop1(r0, rn(reg), op, r1); +# endif + jit_unget_reg(reg); +} + +static void +_fop1d(jit_state_t *_jit, jit_int32_t op, + jit_int32_t r0, jit_int32_t r1, jit_float64_t *i0) +{ + jit_int32_t reg; + reg = jit_get_reg(CLASS_DBL); + movi_d(rn(reg), i0); + FPop1(r0, r1, op, rn(reg)); + jit_unget_reg(reg); +} + +static void +_rfop1d(jit_state_t *_jit, jit_int32_t op, + jit_int32_t r0, jit_int32_t r1, jit_float64_t *i0) +{ + jit_int32_t reg; + reg = jit_get_reg(CLASS_DBL); + movi_d(rn(reg), i0); + FPop1(r0, rn(reg), op, r1); + jit_unget_reg(reg); +} + +static void +_extr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + stxi(BIAS(-8), _FP_REGNO, r1); +# if __WORDSIZE == 32 + ldxi_f(r0, _FP_REGNO, BIAS(-8)); + FITOS(r0, r0); +# else + ldxi_d(r0, _FP_REGNO, BIAS(-8)); + if (!single_precision_p(r0)) { + jit_int32_t reg; + reg = jit_get_reg(CLASS_SNG); + movr_d(rn(reg), r0); + FXTOS(rn(reg), rn(reg)); + movr_d(r0, rn(reg)); + jit_unget_reg(reg); + } + else + FXTOS(r0, r0); +# endif +} + +static void +_truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(CLASS_SNG); +# if __WORDSIZE == 64 + if (!single_precision_p(r1)) { + movr_d(rn(reg), r1); + FSTOI(rn(reg), rn(reg)); + } + else +# endif + FSTOI(r1, rn(reg)); + stxi_f(BIAS(-8), _FP_REGNO, rn(reg)); + ldxi_i(r0, _FP_REGNO, BIAS(-8)); + jit_unget_reg(reg); +} + +# if __WORDSIZE == 64 +static void +_truncr_f_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(CLASS_SNG); +# if __WORDSIZE == 64 + if (!single_precision_p(r1)) { + movr_d(rn(reg), r1); + FSTOX(rn(reg), rn(reg)); + } + else +# endif + FSTOX(r1, rn(reg)); + stxi_d(BIAS(-8), _FP_REGNO, rn(reg)); + ldxi_l(r0, _FP_REGNO, BIAS(-8)); + jit_unget_reg(reg); +} +# endif + +static void +_fcr(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +# if __WORDSIZE == 64 + jit_int32_t x0, t0, x1, t1, mask = 0; + if (!single_precision_p(r1)) { + mask |= 1; + t0 = jit_get_reg(CLASS_SNG); + x0 = rn(t0); + movr_d(x0, r1); + } + else + x0 = r1; + if (r1 == r2) + x1 = x0; + else if (!single_precision_p(r2)) { + mask |= 2; + t1 = jit_get_reg(CLASS_SNG); + x1 = rn(t1); + movr_d(x1, r2); + } + else + x1 = r2; + FCMPS(x0, x1); + if (mask & 1) + jit_unget_reg(t0); + if (mask & 2) + jit_unget_reg(t1); +# else + FCMPS(r1, r2); +# endif + FBa(cc, 3); + movi(r0, 1); + movi(r0, 0); +} + +static void +_fcw(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_float32_t *i0) +{ + jit_int32_t reg; +# if __WORDSIZE == 64 + jit_int32_t x0, t0, mask = 0; + if (!single_precision_p(r1)) { + mask |= 1; + t0 = jit_get_reg(CLASS_SNG); + x0 = rn(t0); + movr_d(x0, r1); + } + else + x0 = r1; +# endif + reg = jit_get_reg(CLASS_SNG); + movi_f(rn(reg), i0); +# if __WORDSIZE == 64 + FCMPS(x0, rn(reg)); + if (mask & 1) + jit_unget_reg(t0); +# else + FCMPS(r1, rn(reg)); +# endif + jit_unget_reg(reg); + FBa(cc, 3); + movi(r0, 1); + movi(r0, 0); +} + +static void +_dcr(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMPD(r1, r2); + FBa(cc, 3); + movi(r0, 1); + movi(r0, 0); +} + +static void +_dcw(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_float64_t *i0) +{ + jit_int32_t reg; + reg = jit_get_reg(CLASS_DBL); + movi_d(rn(reg), i0); + FCMPD(r1, rn(reg)); + jit_unget_reg(reg); + FBa(cc, 3); + movi(r0, 1); + movi(r0, 0); +} + +# if __WORDSIZE == 64 +static void +_ldr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (!single_precision_p(r0)) { + reg = jit_get_reg(CLASS_SNG); + LDF(r1, 0, rn(reg)); + movr_d(r0, rn(reg)); + jit_unget_reg(reg); + } + else + LDF(r1, 0, r0); +} +# endif + +static void +_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) { +# if __WORDSIZE == 64 + if (!single_precision_p(r0)) { + reg = jit_get_reg(CLASS_SNG); + LDFI(0, i0, rn(reg)); + movr_d(r0, rn(reg)); + jit_unget_reg(reg); + } + else +# endif + LDFI(0, i0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +# if __WORDSIZE == 64 +static void +_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (!single_precision_p(r0)) { + reg = jit_get_reg(CLASS_SNG); + LDF(r1, r2, rn(reg)); + movr_d(r0, rn(reg)); + jit_unget_reg(reg); + } + else + LDF(r1, r2, r0); +} +# endif + +static void +_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) { +# if __WORDSIZE == 64 + if (!single_precision_p(r0)) { + reg = jit_get_reg(CLASS_SNG); + LDFI(r1, i0, rn(reg)); + movr_d(r0, rn(reg)); + jit_unget_reg(reg); + } + else +# endif + LDFI(r1, i0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_f(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +# if __WORDSIZE == 64 +static void +_str_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (!single_precision_p(r1)) { + reg = jit_get_reg(CLASS_SNG); + movr_d(rn(reg), r1); + STF(rn(reg), r0, 0); + jit_unget_reg(reg); + } + else + STF(r1, r0, 0); +} +# endif + +static void +_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (s13_p(i0)) { +# if __WORDSIZE == 64 + if (!single_precision_p(r0)) { + reg = jit_get_reg(CLASS_SNG); + movr_d(rn(reg), r0); + STFI(rn(reg), 0, i0); + jit_unget_reg(reg); + } + else +# endif + STFI(r0, 0, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_f(rn(reg), r0); + jit_unget_reg(reg); + } +} + +# if __WORDSIZE == 64 +static void +_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (!single_precision_p(r2)) { + reg = jit_get_reg(CLASS_SNG); + movr_d(rn(reg), r2); + STF(rn(reg), r1, r0); + jit_unget_reg(reg); + } + else + STF(r2, r1, r0); +} +# endif + +static void +_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (s13_p(i0)) { +# if __WORDSIZE == 64 + if (!single_precision_p(r1)) { + reg = jit_get_reg(CLASS_SNG); + movr_d(rn(reg), r1); + STFI(rn(reg), r0, i0); + jit_unget_reg(reg); + } + else +# endif + STFI(r1, r0, i0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_f(rn(reg), r0, r1); + jit_unget_reg(reg); + } +} + +static void +_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + stxi(BIAS(-8), _FP_REGNO, r1); +# if __WORDSIZE == 32 + stxi(BIAS(-4), _FP_REGNO, 0); +# endif + ldxi_d(r0, _FP_REGNO, BIAS(-8)); +# if __WORDSIZE == 32 + FITOD(r0, r0); +# else + FXTOD(r0, r0); +# endif +} + +static void +_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(CLASS_SNG); +# if __WORDSIZE == 64 + if (!single_precision_p(r1)) { + movr_d(rn(reg), r1); + FDTOI(rn(reg), rn(reg)); + } + else +# endif + FDTOI(r1, rn(reg)); + stxi_d(BIAS(-8), _FP_REGNO, rn(reg)); + ldxi_i(r0, _FP_REGNO, BIAS(-8)); + jit_unget_reg(reg); +} + +# if __WORDSIZE == 64 +static void +_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(CLASS_DBL); + FDTOX(r1, rn(reg)); + stxi_d(BIAS(-8), _FP_REGNO, rn(reg)); + ldxi_l(r0, _FP_REGNO, BIAS(-8)); + jit_unget_reg(reg); +} +# endif + +static void +_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDDFI(0, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t i0) +{ + jit_int32_t reg; + if (s13_p(i0)) + LDDFI(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_d(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (s13_p(i0)) + STDFI(r0, 0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_d(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_stxi_d(jit_state_t *_jit, jit_int32_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (s13_p(i0)) + STDFI(r1, r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_d(rn(reg), r0, r1); + jit_unget_reg(reg); + } +} + +static jit_word_t +_fbr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0,jit_int32_t r1) +{ +# if __WORDSIZE == 64 + jit_int32_t x0, t0, x1, t1, mask = 0; +# endif + jit_word_t w; +# if __WORDSIZE == 64 + if (!single_precision_p(r0)) { + mask |= 1; + t0 = jit_get_reg(CLASS_SNG); + x0 = rn(t0); + movr_d(x0, r0); + } + else + x0 = r0; + if (r0 == r1) + x1 = x0; + else if (!single_precision_p(r1)) { + mask |= 2; + t1 = jit_get_reg(CLASS_SNG); + x1 = rn(t1); + movr_d(x1, r1); + } + else + x1 = r1; + FCMPS(x0, x1); + if (mask & 1) + jit_unget_reg(t0); + if (mask & 2) + jit_unget_reg(t1); +# else + FCMPS(r0, r1); +# endif + w = _jit->pc.w; + FB(cc, (i0 - w) >> 2); + NOP(); + return (w); +} + +static jit_word_t +_fbw(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_float32_t *i1) +{ + jit_word_t w; + jit_int32_t reg; +# if __WORDSIZE == 64 + jit_int32_t x0, t0, mask = 0; + if (!single_precision_p(r0)) { + mask |= 1; + t0 = jit_get_reg(CLASS_SNG); + x0 = rn(t0); + movr_d(x0, r0); + } + else + x0 = r0; +# endif + reg = jit_get_reg(CLASS_SNG); + movi_f(rn(reg), i1); +# if __WORDSIZE == 64 + FCMPS(x0, rn(reg)); + if (mask & 1) + jit_unget_reg(t0); +# else + FCMPS(r0, rn(reg)); +# endif + jit_unget_reg(reg); + w = _jit->pc.w; + FB(cc, (i0 - w) >> 2); + NOP(); + return (w); +} + +static jit_word_t +_dbr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + FCMPD(r0, r1); + w = _jit->pc.w; + FB(cc, (i0 - w) >> 2); + NOP(); + return (w); +} + +static jit_word_t +_dbw(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_float64_t *i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(CLASS_DBL); + movi_d(rn(reg), i1); + FCMPD(r0, rn(reg)); + jit_unget_reg(reg); + w = _jit->pc.w; + FB(cc, (i0 - w) >> 2); + NOP(); + return (w); +} + +static void +_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(_jitc->function->self.call & jit_call_varargs); + + /* Load argument. */ + ldr_d(r0, r1); + + /* Update vararg stack pointer. */ + addi(r1, r1, 8); +} +#endif diff --git a/deps/lightning/lib/jit_sparc-sz.c b/deps/lightning/lib/jit_sparc-sz.c new file mode 100644 index 0000000..ac683b6 --- /dev/null +++ b/deps/lightning/lib/jit_sparc-sz.c @@ -0,0 +1,803 @@ +#if __WORDSIZE == 32 +#define JIT_INSTR_MAX 44 + 0, /* data */ + 0, /* live */ + 0, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 36, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 8, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 12, /* addi */ + 4, /* addcr */ + 12, /* addci */ + 4, /* addxr */ + 4, /* addxi */ + 4, /* subr */ + 12, /* subi */ + 4, /* subcr */ + 12, /* subci */ + 4, /* subxr */ + 4, /* subxi */ + 16, /* rsbi */ + 4, /* mulr */ + 12, /* muli */ + 8, /* qmulr */ + 16, /* qmuli */ + 8, /* qmulr_u */ + 16, /* qmuli_u */ + 12, /* divr */ + 20, /* divi */ + 8, /* divr_u */ + 16, /* divi_u */ + 28, /* qdivr */ + 24, /* qdivi */ + 24, /* qdivr_u */ + 20, /* qdivi_u */ + 20, /* remr */ + 28, /* remi */ + 16, /* remr_u */ + 24, /* remi_u */ + 4, /* andr */ + 12, /* andi */ + 4, /* orr */ + 12, /* ori */ + 4, /* xorr */ + 12, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 16, /* ltr */ + 16, /* lti */ + 16, /* ltr_u */ + 16, /* lti_u */ + 16, /* ler */ + 16, /* lei */ + 16, /* ler_u */ + 16, /* lei_u */ + 16, /* eqr */ + 16, /* eqi */ + 16, /* ger */ + 16, /* gei */ + 16, /* ger_u */ + 16, /* gei_u */ + 16, /* gtr */ + 16, /* gti */ + 16, /* gtr_u */ + 16, /* gti_u */ + 16, /* ner */ + 16, /* nei */ + 4, /* movr */ + 8, /* movi */ + 8, /* extr_c */ + 4, /* extr_uc */ + 8, /* extr_s */ + 8, /* extr_us */ + 0, /* extr_i */ + 0, /* extr_ui */ + 8, /* htonr_us */ + 4, /* htonr_ui */ + 0, /* htonr_ul */ + 4, /* ldr_c */ + 12, /* ldi_c */ + 4, /* ldr_uc */ + 12, /* ldi_uc */ + 4, /* ldr_s */ + 12, /* ldi_s */ + 4, /* ldr_us */ + 12, /* ldi_us */ + 4, /* ldr_i */ + 12, /* ldi_i */ + 0, /* ldr_ui */ + 0, /* ldi_ui */ + 0, /* ldr_l */ + 0, /* ldi_l */ + 4, /* ldxr_c */ + 8, /* ldxi_c */ + 4, /* ldxr_uc */ + 8, /* ldxi_uc */ + 4, /* ldxr_s */ + 8, /* ldxi_s */ + 4, /* ldxr_us */ + 8, /* ldxi_us */ + 4, /* ldxr_i */ + 8, /* ldxi_i */ + 0, /* ldxr_ui */ + 0, /* ldxi_ui */ + 0, /* ldxr_l */ + 0, /* ldxi_l */ + 4, /* str_c */ + 12, /* sti_c */ + 4, /* str_s */ + 12, /* sti_s */ + 4, /* str_i */ + 12, /* sti_i */ + 0, /* str_l */ + 0, /* sti_l */ + 4, /* stxr_c */ + 8, /* stxi_c */ + 4, /* stxr_s */ + 8, /* stxi_s */ + 4, /* stxr_i */ + 8, /* stxi_i */ + 0, /* stxr_l */ + 0, /* stxi_l */ + 12, /* bltr */ + 12, /* blti */ + 12, /* bltr_u */ + 12, /* blti_u */ + 12, /* bler */ + 12, /* blei */ + 12, /* bler_u */ + 12, /* blei_u */ + 12, /* beqr */ + 20, /* beqi */ + 12, /* bger */ + 12, /* bgei */ + 12, /* bger_u */ + 12, /* bgei_u */ + 12, /* bgtr */ + 12, /* bgti */ + 12, /* bgtr_u */ + 12, /* bgti_u */ + 12, /* bner */ + 20, /* bnei */ + 12, /* bmsr */ + 12, /* bmsi */ + 12, /* bmcr */ + 12, /* bmci */ + 12, /* boaddr */ + 12, /* boaddi */ + 12, /* boaddr_u */ + 12, /* boaddi_u */ + 12, /* bxaddr */ + 12, /* bxaddi */ + 12, /* bxaddr_u */ + 12, /* bxaddi_u */ + 12, /* bosubr */ + 12, /* bosubi */ + 12, /* bosubr_u */ + 12, /* bosubi_u */ + 12, /* bxsubr */ + 12, /* bxsubi */ + 12, /* bxsubr_u */ + 12, /* bxsubi_u */ + 8, /* jmpr */ + 16, /* jmpi */ + 8, /* callr */ + 16, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 44, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 16, /* addi_f */ + 4, /* subr_f */ + 16, /* subi_f */ + 16, /* rsbi_f */ + 4, /* mulr_f */ + 16, /* muli_f */ + 4, /* divr_f */ + 16, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 16, /* ltr_f */ + 32, /* lti_f */ + 16, /* ler_f */ + 32, /* lei_f */ + 16, /* eqr_f */ + 32, /* eqi_f */ + 16, /* ger_f */ + 32, /* gei_f */ + 16, /* gtr_f */ + 32, /* gti_f */ + 16, /* ner_f */ + 32, /* nei_f */ + 16, /* unltr_f */ + 32, /* unlti_f */ + 16, /* unler_f */ + 32, /* unlei_f */ + 16, /* uneqr_f */ + 32, /* uneqi_f */ + 16, /* unger_f */ + 32, /* ungei_f */ + 16, /* ungtr_f */ + 32, /* ungti_f */ + 16, /* ltgtr_f */ + 32, /* ltgti_f */ + 16, /* ordr_f */ + 32, /* ordi_f */ + 16, /* unordr_f */ + 32, /* unordi_f */ + 12, /* truncr_f_i */ + 0, /* truncr_f_l */ + 12, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 16, /* movi_f */ + 4, /* ldr_f */ + 12, /* ldi_f */ + 4, /* ldxr_f */ + 8, /* ldxi_f */ + 4, /* str_f */ + 12, /* sti_f */ + 4, /* stxr_f */ + 8, /* stxi_f */ + 12, /* bltr_f */ + 24, /* blti_f */ + 12, /* bler_f */ + 24, /* blei_f */ + 12, /* beqr_f */ + 24, /* beqi_f */ + 12, /* bger_f */ + 24, /* bgei_f */ + 12, /* bgtr_f */ + 24, /* bgti_f */ + 12, /* bner_f */ + 28, /* bnei_f */ + 12, /* bunltr_f */ + 28, /* bunlti_f */ + 12, /* bunler_f */ + 28, /* bunlei_f */ + 12, /* buneqr_f */ + 28, /* buneqi_f */ + 12, /* bunger_f */ + 28, /* bungei_f */ + 12, /* bungtr_f */ + 28, /* bungti_f */ + 12, /* bltgtr_f */ + 24, /* bltgti_f */ + 12, /* bordr_f */ + 24, /* bordi_f */ + 12, /* bunordr_f */ + 28, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 24, /* addi_d */ + 4, /* subr_d */ + 24, /* subi_d */ + 24, /* rsbi_d */ + 4, /* mulr_d */ + 24, /* muli_d */ + 4, /* divr_d */ + 24, /* divi_d */ + 8, /* negr_d */ + 8, /* absr_d */ + 4, /* sqrtr_d */ + 16, /* ltr_d */ + 40, /* lti_d */ + 16, /* ler_d */ + 40, /* lei_d */ + 16, /* eqr_d */ + 40, /* eqi_d */ + 16, /* ger_d */ + 40, /* gei_d */ + 16, /* gtr_d */ + 40, /* gti_d */ + 16, /* ner_d */ + 40, /* nei_d */ + 16, /* unltr_d */ + 40, /* unlti_d */ + 16, /* unler_d */ + 40, /* unlei_d */ + 16, /* uneqr_d */ + 40, /* uneqi_d */ + 16, /* unger_d */ + 40, /* ungei_d */ + 16, /* ungtr_d */ + 40, /* ungti_d */ + 16, /* ltgtr_d */ + 40, /* ltgti_d */ + 16, /* ordr_d */ + 40, /* ordi_d */ + 16, /* unordr_d */ + 40, /* unordi_d */ + 12, /* truncr_d_i */ + 0, /* truncr_d_l */ + 16, /* extr_d */ + 4, /* extr_f_d */ + 8, /* movr_d */ + 24, /* movi_d */ + 4, /* ldr_d */ + 12, /* ldi_d */ + 4, /* ldxr_d */ + 8, /* ldxi_d */ + 4, /* str_d */ + 12, /* sti_d */ + 4, /* stxr_d */ + 8, /* stxi_d */ + 12, /* bltr_d */ + 32, /* blti_d */ + 12, /* bler_d */ + 32, /* blei_d */ + 12, /* beqr_d */ + 32, /* beqi_d */ + 12, /* bger_d */ + 32, /* bgei_d */ + 12, /* bgtr_d */ + 32, /* bgti_d */ + 12, /* bner_d */ + 36, /* bnei_d */ + 12, /* bunltr_d */ + 36, /* bunlti_d */ + 12, /* bunler_d */ + 36, /* bunlei_d */ + 12, /* buneqr_d */ + 36, /* buneqi_d */ + 12, /* bunger_d */ + 36, /* bungei_d */ + 12, /* bungtr_d */ + 36, /* bungti_d */ + 12, /* bltgtr_d */ + 32, /* bltgti_d */ + 12, /* bordr_d */ + 32, /* bordi_d */ + 12, /* bunordr_d */ + 36, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __WORDSIZE */ + +#if __WORDSIZE == 64 +#define JIT_INSTR_MAX 64 + 0, /* data */ + 0, /* live */ + 4, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 4, /* label */ + 36, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 8, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 28, /* addi */ + 24, /* addcr */ + 48, /* addci */ + 52, /* addxr */ + 52, /* addxi */ + 4, /* subr */ + 28, /* subi */ + 24, /* subcr */ + 48, /* subci */ + 52, /* subxr */ + 52, /* subxi */ + 32, /* rsbi */ + 4, /* mulr */ + 28, /* muli */ + 48, /* qmulr */ + 64, /* qmuli */ + 48, /* qmulr_u */ + 64, /* qmuli_u */ + 4, /* divr */ + 28, /* divi */ + 4, /* divr_u */ + 28, /* divi_u */ + 20, /* qdivr */ + 16, /* qdivi */ + 20, /* qdivr_u */ + 16, /* qdivi_u */ + 12, /* remr */ + 36, /* remi */ + 12, /* remr_u */ + 36, /* remi_u */ + 4, /* andr */ + 28, /* andi */ + 4, /* orr */ + 28, /* ori */ + 4, /* xorr */ + 28, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 16, /* ltr */ + 16, /* lti */ + 16, /* ltr_u */ + 16, /* lti_u */ + 16, /* ler */ + 16, /* lei */ + 16, /* ler_u */ + 16, /* lei_u */ + 16, /* eqr */ + 16, /* eqi */ + 16, /* ger */ + 16, /* gei */ + 16, /* ger_u */ + 16, /* gei_u */ + 16, /* gtr */ + 16, /* gti */ + 16, /* gtr_u */ + 16, /* gti_u */ + 16, /* ner */ + 16, /* nei */ + 4, /* movr */ + 24, /* movi */ + 8, /* extr_c */ + 4, /* extr_uc */ + 8, /* extr_s */ + 8, /* extr_us */ + 8, /* extr_i */ + 8, /* extr_ui */ + 8, /* htonr_us */ + 8, /* htonr_ui */ + 4, /* htonr_ul */ + 4, /* ldr_c */ + 28, /* ldi_c */ + 4, /* ldr_uc */ + 28, /* ldi_uc */ + 4, /* ldr_s */ + 28, /* ldi_s */ + 4, /* ldr_us */ + 28, /* ldi_us */ + 4, /* ldr_i */ + 28, /* ldi_i */ + 4, /* ldr_ui */ + 28, /* ldi_ui */ + 4, /* ldr_l */ + 28, /* ldi_l */ + 4, /* ldxr_c */ + 24, /* ldxi_c */ + 4, /* ldxr_uc */ + 24, /* ldxi_uc */ + 4, /* ldxr_s */ + 24, /* ldxi_s */ + 4, /* ldxr_us */ + 24, /* ldxi_us */ + 4, /* ldxr_i */ + 24, /* ldxi_i */ + 4, /* ldxr_ui */ + 24, /* ldxi_ui */ + 4, /* ldxr_l */ + 24, /* ldxi_l */ + 4, /* str_c */ + 28, /* sti_c */ + 4, /* str_s */ + 28, /* sti_s */ + 4, /* str_i */ + 28, /* sti_i */ + 4, /* str_l */ + 28, /* sti_l */ + 4, /* stxr_c */ + 24, /* stxi_c */ + 4, /* stxr_s */ + 24, /* stxi_s */ + 4, /* stxr_i */ + 24, /* stxi_i */ + 4, /* stxr_l */ + 24, /* stxi_l */ + 12, /* bltr */ + 12, /* blti */ + 12, /* bltr_u */ + 12, /* blti_u */ + 12, /* bler */ + 12, /* blei */ + 12, /* bler_u */ + 12, /* blei_u */ + 12, /* beqr */ + 36, /* beqi */ + 12, /* bger */ + 12, /* bgei */ + 12, /* bger_u */ + 12, /* bgei_u */ + 12, /* bgtr */ + 12, /* bgti */ + 12, /* bgtr_u */ + 12, /* bgti_u */ + 12, /* bner */ + 36, /* bnei */ + 12, /* bmsr */ + 12, /* bmsi */ + 12, /* bmcr */ + 12, /* bmci */ + 12, /* boaddr */ + 12, /* boaddi */ + 12, /* boaddr_u */ + 12, /* boaddi_u */ + 12, /* bxaddr */ + 12, /* bxaddi */ + 12, /* bxaddr_u */ + 12, /* bxaddi_u */ + 12, /* bosubr */ + 12, /* bosubi */ + 12, /* bosubr_u */ + 12, /* bosubi_u */ + 12, /* bxsubr */ + 12, /* bxsubi */ + 12, /* bxsubr_u */ + 12, /* bxsubi_u */ + 8, /* jmpr */ + 32, /* jmpi */ + 8, /* callr */ + 32, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 44, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 16, /* addr_f */ + 40, /* addi_f */ + 24, /* subr_f */ + 40, /* subi_f */ + 40, /* rsbi_f */ + 16, /* mulr_f */ + 40, /* muli_f */ + 16, /* divr_f */ + 40, /* divi_f */ + 12, /* negr_f */ + 12, /* absr_f */ + 12, /* sqrtr_f */ + 24, /* ltr_f */ + 48, /* lti_f */ + 24, /* ler_f */ + 48, /* lei_f */ + 24, /* eqr_f */ + 48, /* eqi_f */ + 24, /* ger_f */ + 48, /* gei_f */ + 24, /* gtr_f */ + 48, /* gti_f */ + 24, /* ner_f */ + 48, /* nei_f */ + 24, /* unltr_f */ + 48, /* unlti_f */ + 24, /* unler_f */ + 48, /* unlei_f */ + 24, /* uneqr_f */ + 48, /* uneqi_f */ + 24, /* unger_f */ + 48, /* ungei_f */ + 24, /* ungtr_f */ + 48, /* ungti_f */ + 24, /* ltgtr_f */ + 48, /* ltgti_f */ + 24, /* ordr_f */ + 48, /* ordi_f */ + 24, /* unordr_f */ + 48, /* unordi_f */ + 16, /* truncr_f_i */ + 16, /* truncr_f_l */ + 20, /* extr_f */ + 12, /* extr_d_f */ + 16, /* movr_f */ + 32, /* movi_f */ + 8, /* ldr_f */ + 32, /* ldi_f */ + 8, /* ldxr_f */ + 28, /* ldxi_f */ + 8, /* str_f */ + 32, /* sti_f */ + 8, /* stxr_f */ + 28, /* stxi_f */ + 20, /* bltr_f */ + 44, /* blti_f */ + 20, /* bler_f */ + 44, /* blei_f */ + 28, /* beqr_f */ + 60, /* beqi_f */ + 20, /* bger_f */ + 44, /* bgei_f */ + 20, /* bgtr_f */ + 44, /* bgti_f */ + 20, /* bner_f */ + 44, /* bnei_f */ + 20, /* bunltr_f */ + 44, /* bunlti_f */ + 20, /* bunler_f */ + 44, /* bunlei_f */ + 20, /* buneqr_f */ + 44, /* buneqi_f */ + 20, /* bunger_f */ + 44, /* bungei_f */ + 20, /* bungtr_f */ + 44, /* bungti_f */ + 20, /* bltgtr_f */ + 44, /* bltgti_f */ + 20, /* bordr_f */ + 44, /* bordi_f */ + 20, /* bunordr_f */ + 44, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 32, /* addi_d */ + 4, /* subr_d */ + 32, /* subi_d */ + 32, /* rsbi_d */ + 4, /* mulr_d */ + 32, /* muli_d */ + 4, /* divr_d */ + 32, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 16, /* ltr_d */ + 48, /* lti_d */ + 16, /* ler_d */ + 48, /* lei_d */ + 16, /* eqr_d */ + 48, /* eqi_d */ + 16, /* ger_d */ + 48, /* gei_d */ + 16, /* gtr_d */ + 48, /* gti_d */ + 16, /* ner_d */ + 48, /* nei_d */ + 16, /* unltr_d */ + 48, /* unlti_d */ + 16, /* unler_d */ + 48, /* unlei_d */ + 16, /* uneqr_d */ + 48, /* uneqi_d */ + 16, /* unger_d */ + 48, /* ungei_d */ + 16, /* ungtr_d */ + 48, /* ungti_d */ + 16, /* ltgtr_d */ + 48, /* ltgti_d */ + 16, /* ordr_d */ + 48, /* ordi_d */ + 16, /* unordr_d */ + 48, /* unordi_d */ + 16, /* truncr_d_i */ + 12, /* truncr_d_l */ + 12, /* extr_d */ + 8, /* extr_f_d */ + 4, /* movr_d */ + 32, /* movi_d */ + 4, /* ldr_d */ + 28, /* ldi_d */ + 4, /* ldxr_d */ + 24, /* ldxi_d */ + 4, /* str_d */ + 28, /* sti_d */ + 4, /* stxr_d */ + 24, /* stxi_d */ + 12, /* bltr_d */ + 40, /* blti_d */ + 12, /* bler_d */ + 40, /* blei_d */ + 12, /* beqr_d */ + 40, /* beqi_d */ + 12, /* bger_d */ + 40, /* bgei_d */ + 12, /* bgtr_d */ + 40, /* bgti_d */ + 12, /* bner_d */ + 44, /* bnei_d */ + 12, /* bunltr_d */ + 44, /* bunlti_d */ + 12, /* bunler_d */ + 44, /* bunlei_d */ + 12, /* buneqr_d */ + 44, /* buneqi_d */ + 12, /* bunger_d */ + 44, /* bungei_d */ + 12, /* bungtr_d */ + 44, /* bungti_d */ + 12, /* bltgtr_d */ + 40, /* bltgti_d */ + 12, /* bordr_d */ + 40, /* bordi_d */ + 12, /* bunordr_d */ + 44, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __WORDSIZE */ diff --git a/deps/lightning/lib/jit_sparc.c b/deps/lightning/lib/jit_sparc.c new file mode 100644 index 0000000..158c09d --- /dev/null +++ b/deps/lightning/lib/jit_sparc.c @@ -0,0 +1,1924 @@ +/* + * Copyright (C) 2013-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 6) +#if __WORDSIZE == 32 +# define jit_arg_d_reg_p(i) ((i) >= 0 && (i) < 5) +# define BIAS(n) (n) +#else +# define jit_arg_d_reg_p(i) ((i) >= 0 && (i) < 16) +# define BIAS(n) ((n) + 2047) +#endif + +/* + * Types + */ +typedef jit_pointer_t jit_va_list_t; + +/* + * Prototypes + */ +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); + +#define PROTO 1 +# include "jit_sparc-cpu.c" +# include "jit_sparc-fpu.c" +#undef PROTO + +/* + * Initialization + */ +jit_register_t _rvs[] = { + { 0x00, "%g0" }, + { 0x01, "%g1" }, + { rc(gpr) | 0x02, "%g2" }, + { rc(gpr) | 0x03, "%g3" }, + { rc(gpr) | 0x04, "%g4" }, + { 0x05, "%g5" }, + { 0x06, "%g6" }, + { 0x07, "%g7" }, + { rc(arg) | rc(gpr) | 0x08, "%o0" }, + { rc(arg) | rc(gpr) | 0x09, "%o1" }, + { rc(arg) | rc(gpr) | 0x0a, "%o2" }, + { rc(arg) | rc(gpr) | 0x0b, "%o3" }, + { rc(arg) | rc(gpr) | 0x0c, "%o4" }, + { rc(arg) | rc(gpr) | 0x0d, "%o5" }, + { rc(sav) | 0x0e, "%sp" }, + { 0x0f, "%o7" }, + { rc(sav) | rc(gpr) | 0x10, "%l0" }, + { rc(sav) | rc(gpr) | 0x11, "%l1" }, + { rc(sav) | rc(gpr) | 0x12, "%l2" }, + { rc(sav) | rc(gpr) | 0x13, "%l3" }, + { rc(sav) | rc(gpr) | 0x14, "%l4" }, + { rc(sav) | rc(gpr) | 0x15, "%l5" }, + { rc(sav) | rc(gpr) | 0x16, "%l6" }, + { rc(sav) | rc(gpr) | 0x17, "%l7" }, + { 0x18, "%i0" }, + { 0x19, "%i1" }, + { 0x1a, "%i2" }, + { 0x1b, "%i3" }, + { 0x1c, "%i4" }, + { 0x1d, "%i5" }, + { rc(sav) | 0x1e, "%fp" }, + { 0x1f, "%i7" }, +# if __WORDSIZE == 32 + { rc(fpr) | 0x00, "%f0" }, + { 0x01, "%f1" }, + { rc(fpr) | 0x02, "%f2" }, + { 0x03, "%f3" }, + { rc(fpr) | 0x04, "%f4" }, + { 0x05, "%f5" }, + { rc(fpr) | 0x06, "%f6" }, + { 0x07, "%f7" }, + { rc(fpr) | 0x08, "%f8" }, + { 0x09, "%f9" }, + { rc(fpr) | 0x0a, "%f10" }, + { 0x0b, "%f11" }, + { rc(fpr) | 0x0c, "%f12" }, + { 0x0d, "%f13" }, + { rc(fpr) | 0x0e, "%f14" }, + { 0x0f, "%f15" }, +# else + { rc(fpr) | rc(dbl) | 0x3e, "%f62" }, + { rc(fpr) | rc(dbl) | 0x3c, "%f60" }, + { rc(fpr) | rc(dbl) | 0x3a, "%f58" }, + { rc(fpr) | rc(dbl) | 0x38, "%f56" }, + { rc(fpr) | rc(dbl) | 0x36, "%f54" }, + { rc(fpr) | rc(dbl) | 0x34, "%f52" }, + { rc(fpr) | rc(dbl) | 0x32, "%f50" }, + { rc(fpr) | rc(dbl) | 0x30, "%f48" }, + { rc(fpr) | rc(dbl) | 0x2e, "%f46" }, + { rc(fpr) | rc(dbl) | 0x2c, "%f44" }, + { rc(fpr) | rc(dbl) | 0x2a, "%f42" }, + { rc(fpr) | rc(dbl) | 0x28, "%f40" }, + { rc(fpr) | rc(dbl) | 0x26, "%f38" }, + { rc(fpr) | rc(dbl) | 0x24, "%f36" }, + { rc(fpr) | rc(dbl) | 0x22, "%f34" }, + { rc(fpr) | rc(dbl) | 0x20, "%f32" }, + { 0x1f, "%f31" }, + { rc(arg)|rc(fpr)|rc(sng)|0x1e, "%f30" }, + { 0x1d, "%f29" }, + { rc(arg)|rc(fpr)|rc(sng)|0x1c, "%f28" }, + { 0x1b, "%f27" }, + { rc(arg)|rc(fpr)|rc(sng)|0x1a, "%f26" }, + { 0x19, "%f25" }, + { rc(arg)|rc(fpr)|rc(sng)|0x18, "%f24" }, + { 0x17, "%f23" }, + { rc(arg)|rc(fpr)|rc(sng)|0x16, "%f22" }, + { 0x15, "%f21" }, + { rc(arg)|rc(fpr)|rc(sng)|0x14, "%f20" }, + { 0x13, "%f19" }, + { rc(arg)|rc(fpr)|rc(sng)|0x12, "%f18" }, + { 0x11, "%f17" }, + { rc(arg)|rc(fpr)|rc(sng)|0x10, "%f16" }, + { 0x0f, "%f15" }, + { rc(arg)|rc(fpr)|rc(sng)|0x0e, "%f14" }, + { 0x0d, "%f13" }, + { rc(arg)|rc(fpr)|rc(sng)|0x0c, "%f12" }, + { 0x0b, "%f11" }, + { rc(arg)|rc(fpr)|rc(sng)|0x0a, "%f10" }, + { 0x09, "%f9" }, + { rc(arg)|rc(fpr)|rc(sng)|0x08, "%f8" }, + { 0x07, "%f7" }, + { rc(arg)|rc(fpr)|rc(sng)|0x06, "%f6" }, + { 0x05, "%f5" }, + { rc(arg)|rc(fpr)|rc(sng)|0x04, "%f4" }, + { 0x03, "%f3" }, + { rc(arg)|rc(fpr)|rc(sng)|0x02, "%f2" }, + { 0x01, "%f1" }, + { rc(arg)|rc(fpr)|rc(sng)|0x00, "%f0" }, +# endif + { _NOREG, "<none>" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ +} + +void +_jit_init(jit_state_t *_jit) +{ + _jitc->reglen = jit_size(_rvs) - 1; +# if __WORDSIZE == 64 + jit_carry = _NOREG; +# endif +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + _jitc->function->self.size = stack_framesize; + _jitc->function->self.argi = _jitc->function->self.argf = + _jitc->function->self.aoff = _jitc->function->self.alen = 0; + /* float conversion */ +# if __WORDSIZE == 32 + _jitc->function->self.aoff = -8; +# else + /* extra slots in case qmul is called */ + _jitc->function->self.aoff = -24; +# endif + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + assert(_jitc->function); + switch (length) { + case 0: case 1: break; + case 2: _jitc->function->self.aoff &= -2; break; + case 3: case 4: _jitc->function->self.aoff &= -4; break; + default: _jitc->function->self.aoff &= -8; break; + } + _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } + return (BIAS(_jitc->function->self.aoff)); +} + +void +_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) +{ + jit_int32_t reg; + assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); + if (!_jitc->function->allocar) { + _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); + _jitc->function->allocar = 1; + } + reg = jit_get_reg(jit_class_gpr); + jit_negr(reg, v); + jit_andi(reg, reg, -16); + jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); + jit_addr(u, u, reg); + jit_addr(_SP, _SP, reg); + jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); + jit_unget_reg(reg); + jit_dec_synth(); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + assert(_jitc->function); + jit_inc_synth(ret); + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr, u); + if (JIT_RET != u) + jit_movr(JIT_RET, u); + jit_live(JIT_RET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti(jit_state_t *_jit, jit_word_t u) +{ + jit_inc_synth_w(reti, u); + jit_movi(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_f, u); + if (JIT_FRET != u) + jit_movr_f(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_inc_synth_f(reti_f, u); + jit_movi_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_d, u); + if (JIT_FRET != u) + jit_movr_d(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_inc_synth_d(reti_d, u); + jit_movi_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_epilog(jit_state_t *_jit) +{ + assert(_jitc->function); + assert(_jitc->function->epilog->next == NULL); + jit_link(_jitc->function->epilog); + _jitc->function = NULL; +} + +jit_bool_t +_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) +{ +# if __WORDSIZE == 32 + if (u->code == jit_code_arg || u->code == jit_code_arg_f) + return (jit_arg_reg_p(u->u.w)); + assert(u->code == jit_code_arg_d); + return (jit_arg_d_reg_p(u->u.w)); +# else + if (u->code == jit_code_arg) + return (jit_arg_reg_p(u->u.w)); + assert(u->code == jit_code_arg_d || u->code == jit_code_arg_f); + return (jit_arg_d_reg_p(u->u.w)); +# endif +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + jit_inc_synth(ellipsis); + if (_jitc->prepare) { + jit_link_prepare(); + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; + } + else { + jit_link_prolog(); + assert(!(_jitc->function->self.call & jit_call_varargs)); + _jitc->function->self.call |= jit_call_varargs; + + _jitc->function->vagp = _jitc->function->self.argi; + } + jit_dec_synth(); +} + +void +_jit_va_push(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(va_push, u); + jit_pushargr(u); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + if (jit_arg_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else { +# if __WORDSIZE == 64 + if (jit_arg_d_reg_p(_jitc->function->self.argi)) + ++_jitc->function->self.argi; +# endif + offset = BIAS(_jitc->function->self.size); + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; +# if __WORDSIZE == 64 + jit_bool_t inc; +# endif + assert(_jitc->function); +# if __WORDSIZE == 32 + if (jit_arg_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } +# else + inc = !jit_arg_reg_p(_jitc->function->self.argi); + if (jit_arg_d_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else + offset = BIAS(_jitc->function->self.size); + if (inc) + _jitc->function->self.size += sizeof(jit_word_t); +# endif + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; +# if __WORDSIZE == 64 + jit_bool_t inc; +# endif + assert(_jitc->function); +# if __WORDSIZE == 32 + if (jit_arg_d_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi; + _jitc->function->self.argi += 2; + } + else if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi++; + _jitc->function->self.size += sizeof(jit_float32_t); + } + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_float64_t); + } +# else + inc = !jit_arg_reg_p(_jitc->function->self.argi); + if (jit_arg_d_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else + offset = BIAS(_jitc->function->self.size); + if (inc) + _jitc->function->self.size += sizeof(jit_word_t); +# endif + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +void +_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_c(u, _I0 + v->u.w); + else + jit_ldxi_c(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t)); + jit_dec_synth(); +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_uc(u, _I0 + v->u.w); + else + jit_ldxi_uc(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t)); + jit_dec_synth(); +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_s(u, _I0 + v->u.w); + else + jit_ldxi_s(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t)); + jit_dec_synth(); +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_us(u, _I0 + v->u.w); + else + jit_ldxi_us(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t)); + jit_dec_synth(); +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); + if (jit_arg_reg_p(v->u.w)) { +# if __WORDSIZE == 64 + jit_extr_i(u, _I0 + v->u.w); +# else + jit_movr(u, _I0 + v->u.w); +# endif + } + else + jit_ldxi_i(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t)); + jit_dec_synth(); +} + +# if __WORDSIZE == 64 +void +_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_ui(u, _I0 + v->u.w); + else + jit_ldxi_ui(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t)); + jit_dec_synth(); +} + +void +_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(u, _I0 + v->u.w); + else + jit_ldxi_l(u, JIT_FP, v->u.w); + jit_dec_synth(); +} +# endif + +void +_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(_I0 + v->u.w, u); + else + jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movi(_I0 + v->u.w, u); + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + assert(_jitc->function); + jit_inc_synth_wp(getarg_f, u, v); +# if __WORDSIZE == 32 + if (jit_arg_reg_p(v->u.w)) { + jit_stxi_i(-4, JIT_FP, _I0 + v->u.w); + jit_ldxi_f(u, JIT_FP, -4); + } +# else + if (jit_arg_d_reg_p(v->u.w)) { + jit_live(_F0 - (v->u.w << 1)); /* pair of registers is live */ + jit_movr_f(u, (_F0 - (v->u.w << 1)) - 1); + } +# endif + else + jit_ldxi_f(u, JIT_FP, v->u.w + (__WORDSIZE >> 3) - + sizeof(jit_float32_t)); + jit_dec_synth(); +} + +void +_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); +# if __WORDSIZE == 32 + if (jit_arg_reg_p(v->u.w)) { + jit_stxi_f(-4, JIT_FP, u); + jit_ldxi_i(_I0 + v->u.w, JIT_FP, -4); + } +# else + if (jit_arg_d_reg_p(v->u.w)) { + jit_live(_F0 - (v->u.w << 1)); /* pair of registers is live */ + jit_movr_f((_F0 - (v->u.w << 1)) - 1, u); + } +# endif + else + jit_stxi_f(v->u.w + (__WORDSIZE >> 3) - + sizeof(jit_float32_t), JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); +# if __WORDSIZE == 32 + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + if (jit_arg_reg_p(v->u.w)) { + jit_stxi_f(-4, JIT_FP, regno); + jit_ldxi_i(_I0 + v->u.w, JIT_FP, -4); + } + else + jit_stxi_f(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); +# else + if (jit_arg_d_reg_p(v->u.w)) { + jit_live(_F0 - (v->u.w << 1)); /* pair of registers is live */ + jit_movi_f((_F0 - (v->u.w << 1)) - 1, u); + } + else { + regno = jit_get_reg(jit_class_fpr | jit_class_sng); + jit_movi_f(regno, u); + jit_stxi_f(v->u.w + (__WORDSIZE >> 3) - + sizeof(jit_float32_t), JIT_FP, regno); + jit_unget_reg(regno); + } +# endif + jit_dec_synth(); +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + assert(_jitc->function); + jit_inc_synth_wp(getarg_d, u, v); + if (jit_arg_d_reg_p(v->u.w)) { +# if __WORDSIZE == 32 + jit_stxi(-8, JIT_FP, _I0 + v->u.w); + jit_stxi(-4, JIT_FP, _I0 + v->u.w + 1); + jit_ldxi_d(u, JIT_FP, -8); +# else + jit_movr_d(u, _F0 - (v->u.w << 1)); +# endif + } +# if __WORDSIZE == 32 + else if (jit_arg_reg_p(v->u.w)) { + jit_stxi(-8, JIT_FP, _I0 + v->u.w); + jit_ldxi_f(u, JIT_FP, -8); + jit_ldxi_f(u + 1, JIT_FP, stack_framesize); + } +# endif + else { +# if __WORDSIZE == 32 + jit_ldxi_f(u, JIT_FP, v->u.w); + jit_ldxi_f(u + 1, JIT_FP, v->u.w + 4); +# else + jit_ldxi_d(u, JIT_FP, v->u.w); +# endif + } + jit_dec_synth(); +} + +void +_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); +# if __WORDSIZE == 32 + if (jit_arg_d_reg_p(v->u.w)) { + jit_stxi_d(-8, JIT_FP, u); + jit_ldxi(_I0 + v->u.w, JIT_FP, -8); + jit_ldxi(_I0 + v->u.w + 1, JIT_FP, -4); + } + else if (jit_arg_reg_p(v->u.w)) { + regno = jit_get_reg(jit_class_gpr); + jit_stxi_d(-8, JIT_FP, u); + jit_ldxi(_I0 + v->u.w, JIT_FP, -8); + jit_ldxi(regno, JIT_FP, -4); + jit_stxi(stack_framesize, JIT_FP, regno); + jit_unget_reg(regno); + } + else if ((v->u.w & 7) == 0) + jit_stxi_d(v->u.w, JIT_FP, u); + else { + jit_stxi_d(-8, JIT_FP, u); + regno = jit_get_reg(jit_class_gpr); + jit_ldxi(regno, JIT_FP, -8); + jit_stxi(v->u.w, JIT_FP, regno); + jit_ldxi(regno, JIT_FP, -4); + jit_stxi(v->u.w + 4, JIT_FP, regno); + jit_unget_reg(regno); + } +# else + if (jit_arg_d_reg_p(v->u.w)) + jit_movr_d(_F0 - (v->u.w << 1), u); + else + jit_stxi_d(v->u.w, JIT_FP, u); +# endif + jit_dec_synth(); +} + +void +_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) +{ +# if __WORDSIZE == 32 + jit_int32_t gpr; +# endif + jit_int32_t regno; + assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); +# if __WORDSIZE == 32 + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + if (jit_arg_d_reg_p(v->u.w)) { + jit_stxi_d(-8, JIT_FP, regno); + jit_ldxi(_I0 + v->u.w, JIT_FP, -8); + jit_ldxi(_I0 + v->u.w + 1, JIT_FP, -4); + } + else if (jit_arg_reg_p(v->u.w)) { + gpr = jit_get_reg(jit_class_gpr); + jit_stxi_d(-8, JIT_FP, regno); + jit_ldxi(_I0 + v->u.w, JIT_FP, -8); + jit_ldxi(gpr, JIT_FP, -4); + jit_stxi(stack_framesize, JIT_FP, gpr); + jit_unget_reg(gpr); + } + else if ((v->u.w & 7) == 0) + jit_stxi_d(v->u.w, JIT_FP, regno); + else { + jit_stxi_d(-8, JIT_FP, regno); + gpr = jit_get_reg(jit_class_gpr); + jit_ldxi(gpr, JIT_FP, -8); + jit_stxi(v->u.w, JIT_FP, gpr); + jit_ldxi(gpr, JIT_FP, -4); + jit_stxi(v->u.w + 4, JIT_FP, gpr); + jit_unget_reg(gpr); + } + jit_unget_reg(regno); +# else + if (jit_arg_d_reg_p(v->u.w)) + jit_movi_d(_F0 - (v->u.w << 1), u); + else { + regno = jit_get_reg(jit_class_fpr | jit_class_dbl); + jit_movi_d(regno, u); + jit_stxi_d(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } +# endif + jit_dec_synth(); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr(_O0 + _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { +# if __WORDSIZE == 64 + if (jit_arg_d_reg_p(_jitc->function->call.argi)) + ++_jitc->function->call.argi; +# endif + jit_stxi(BIAS(_jitc->function->call.size + stack_framesize), + JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi(jit_state_t *_jit, jit_word_t u) +{ + jit_int32_t regno; + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi(_O0 + _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { +# if __WORDSIZE == 64 + if (jit_arg_d_reg_p(_jitc->function->call.argi)) + ++_jitc->function->call.argi; +# endif + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(BIAS(_jitc->function->call.size + stack_framesize), + JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); +# if __WORDSIZE == 32 + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_stxi_f(-8, JIT_FP, u); + jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8); + ++_jitc->function->call.argi; + } + else { + jit_stxi_f(_jitc->function->call.size + stack_framesize, + JIT_SP, u); + _jitc->function->call.size += sizeof(jit_float32_t); + } +# else + if ((_jitc->function->call.call & jit_call_varargs) && + jit_arg_reg_p(_jitc->function->call.argi)) { + jit_stxi_f(BIAS(-8), JIT_FP, u); + jit_ldxi_i(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8)); + ++_jitc->function->call.argi; + } + else if (!(_jitc->function->call.call & jit_call_varargs) && + jit_arg_d_reg_p(_jitc->function->call.argi)) { + /* pair of registers is live */ + jit_live(_F0 - (_jitc->function->call.argi << 1)); + jit_movr_f((_F0 - (_jitc->function->call.argi << 1)) - 1, u); + if (!jit_arg_reg_p(_jitc->function->call.argi)) + _jitc->function->call.size += sizeof(jit_float64_t); + ++_jitc->function->call.argi; + } + else { + jit_stxi_f(BIAS(_jitc->function->call.size + stack_framesize + 4), + JIT_SP, u); + _jitc->function->call.size += sizeof(jit_float64_t); + } +# endif + jit_dec_synth(); +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_int32_t regno; + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); +# if __WORDSIZE == 32 + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_stxi_f(-8, JIT_FP, regno); + jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8); + _jitc->function->call.argi++; + } + else { + jit_stxi_f(_jitc->function->call.size + stack_framesize, + JIT_SP, regno); + _jitc->function->call.size += sizeof(jit_float32_t); + } + jit_unget_reg(regno); +# else + if ((_jitc->function->call.call & jit_call_varargs) && + jit_arg_reg_p(_jitc->function->call.argi)) { + regno = jit_get_reg(jit_class_fpr | jit_class_sng); + jit_movi_f(regno, u); + jit_stxi_f(BIAS(-8), JIT_FP, regno); + jit_ldxi_i(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8)); + ++_jitc->function->call.argi; + jit_unget_reg(regno); + } + else if (!(_jitc->function->call.call & jit_call_varargs) && + jit_arg_d_reg_p(_jitc->function->call.argi)) { + /* pair of registers is live */ + jit_live(_F0 - (_jitc->function->call.argi << 1)); + jit_movi_f((_F0 - (_jitc->function->call.argi << 1)) - 1, u); + if (!jit_arg_reg_p(_jitc->function->call.argi)) + _jitc->function->call.size += sizeof(jit_float64_t); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr | jit_class_sng); + jit_movi_f(regno, u); + jit_stxi_f(BIAS(_jitc->function->call.size + stack_framesize + 4), + JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_float64_t); + } +# endif + jit_dec_synth(); +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); +# if __WORDSIZE == 32 + if (jit_arg_d_reg_p(_jitc->function->call.argi)) { + jit_stxi_d(BIAS(-8), JIT_FP, u); + jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8)); + jit_ldxi(_O0 + _jitc->function->call.argi + 1, JIT_FP, -4); + _jitc->function->call.argi += 2; + } + else if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_stxi_f(-8, JIT_FP, u); + jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8); + ++_jitc->function->call.argi; + jit_stxi_f(stack_framesize, JIT_SP, u + 1); + _jitc->function->call.size += sizeof(jit_float32_t); + } + else { + jit_stxi_f(_jitc->function->call.size + stack_framesize, + JIT_SP, u); + jit_stxi_f(_jitc->function->call.size + stack_framesize + 4, + JIT_SP, u + 1); + _jitc->function->call.size += sizeof(jit_float64_t); + } +# else + if ((_jitc->function->call.call & jit_call_varargs) && + jit_arg_reg_p(_jitc->function->call.argi)) { + jit_stxi_d(BIAS(-8), JIT_FP, u); + jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8)); + ++_jitc->function->call.argi; + } + else if (!(_jitc->function->call.call & jit_call_varargs) && + jit_arg_d_reg_p(_jitc->function->call.argi)) { + jit_movr_d(_F0 - (_jitc->function->call.argi << 1), u); + if (!jit_arg_reg_p(_jitc->function->call.argi)) + _jitc->function->call.size += sizeof(jit_float64_t); + ++_jitc->function->call.argi; + } + else { + jit_stxi_d(BIAS(_jitc->function->call.size + stack_framesize), + JIT_SP, u); + _jitc->function->call.size += sizeof(jit_float64_t); + } +# endif + jit_dec_synth(); +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); +# if __WORDSIZE == 32 + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + if (jit_arg_d_reg_p(_jitc->function->call.argi)) { + jit_stxi_d(BIAS(-8), JIT_FP, regno); + jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8)); + jit_ldxi(_O0 + _jitc->function->call.argi + 1, JIT_FP, -4); + _jitc->function->call.argi += 2; + } + else if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_stxi_f(-8, JIT_FP, regno); + jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8); + ++_jitc->function->call.argi; + jit_stxi_f(stack_framesize, JIT_SP, u + 1); + _jitc->function->call.size += sizeof(jit_float32_t); + } + else { + jit_stxi_f(_jitc->function->call.size + stack_framesize, + JIT_SP, regno); + jit_stxi_f(_jitc->function->call.size + stack_framesize + 4, + JIT_SP, regno + 1); + _jitc->function->call.size += sizeof(jit_float64_t); + } + jit_unget_reg(regno); +# else + if ((_jitc->function->call.call & jit_call_varargs) && + jit_arg_reg_p(_jitc->function->call.argi)) { + regno = jit_get_reg(jit_class_fpr | jit_class_dbl); + jit_movi_d(regno, u); + jit_stxi_d(BIAS(-8), JIT_FP, regno); + jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, BIAS(-8)); + ++_jitc->function->call.argi; + jit_unget_reg(regno); + } + else if (!(_jitc->function->call.call & jit_call_varargs) && + jit_arg_d_reg_p(_jitc->function->call.argi)) { + jit_movi_d(_F0 - (_jitc->function->call.argi << 1), u); + if (!jit_arg_reg_p(_jitc->function->call.argi)) + _jitc->function->call.size += sizeof(jit_float64_t); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr | jit_class_dbl); + jit_movi_d(regno, u); + jit_stxi_d(BIAS(_jitc->function->call.size + stack_framesize), + JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_float64_t); + } +# endif + jit_dec_synth(); +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + jit_int32_t spec; + + spec = jit_class(_rvs[regno].spec); + if ((spec & (jit_class_arg|jit_class_gpr)) == + (jit_class_arg|jit_class_gpr)) { + regno -= _O0; + if (regno >= 0 && regno < node->v.w) + return (1); + } +# if __WORDSIZE == 64 + if ((spec & (jit_class_arg|jit_class_fpr)) == + (jit_class_arg|jit_class_fpr)) { + regno = _F0 - (regno >> 1); + if (regno >= 0 && regno < node->v.w) + return (1); + } +# endif + + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_node_t *call; + assert(_jitc->function); + jit_inc_synth_w(finishr, r0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + call = jit_callr(r0); + call->v.w = _jitc->function->self.argi; + call->w.w = _jitc->function->self.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_calli(i0); + node->v.w = _jitc->function->call.argi; + node->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); + return (node); +} + +void +_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_c, r0); + jit_extr_c(r0, _O0); + jit_dec_synth(); +} + +void +_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_uc, r0); + jit_extr_uc(r0, _O0); + jit_dec_synth(); +} + +void +_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_s, r0); + jit_extr_s(r0, _O0); + jit_dec_synth(); +} + +void +_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_us, r0); + jit_extr_us(r0, _O0); + jit_dec_synth(); +} + +void +_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_i, r0); +# if __WORDSIZE == 32 + if (r0 != _O0) + jit_movr(r0, _O0); +# else + jit_extr_i(r0, _O0); +# endif + jit_dec_synth(); +} + +# if __WORDSIZE == 64 +void +_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_i, r0); + if (r0 != _O0) + jit_extr_ui(r0, _O0); + jit_dec_synth(); +} + +void +_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_i, r0); + if (r0 != _O0) + jit_movr(r0, _O0); + jit_dec_synth(); +} +# endif + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_f, r0); + if (r0 != JIT_FRET) + jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_d, r0); + if (r0 != JIT_FRET) + jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_int32_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + jit_int32_t patch_offset; + } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + + _jitc->function = NULL; + + jit_reglive_setup(); + + undo.word = 0; + undo.node = NULL; + undo.patch_offset = 0; + +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_rf(name) \ + case jit_code_##name##i##type: \ + assert(node->flag & jit_flag_data); \ + name##_f(rn(node->u.w), \ + (jit_float32_t *)node->v.n->u.w); \ + break +#define case_rd(name) \ + case jit_code_##name##i_d: \ + assert(node->flag & jit_flag_data); \ + name##_d(rn(node->u.w), \ + (jit_float64_t *)node->v.n->u.w); \ + break +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), \ + rn(node->v.w), node->w.w); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_rrf(name, type, size) \ + case jit_code_##name##i##type: \ + assert(node->flag & jit_flag_data); \ + name##i##type(rn(node->u.w), rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type(_jit->pc.w, \ + rn(node->v.w), rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break +#define case_brf(name, type, size) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + else { \ + word = name##i##type(_jit->pc.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + patch(word, node); \ + } \ + break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end) + return (NULL); + +#if DEVEL_DISASSEMBLER + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; +#endif + value = jit_classify(node->code); + jit_regarg_set(node, value); + switch (node->code) { + case jit_code_align: + assert(!(node->u.w & (node->u.w - 1)) && + node->u.w <= sizeof(jit_word_t)); + if (node->u.w == sizeof(jit_word_t) && + (word = _jit->pc.w & (sizeof(jit_word_t) - 1))) + nop(sizeof(jit_word_t) - word); + break; + case jit_code_note: case jit_code_name: + node->u.w = _jit->pc.w; + break; + case jit_code_label: + if ((node->link || (node->flag & jit_flag_use)) && + (word = _jit->pc.w & (sizeof(jit_word_t) - 1))) + nop(sizeof(jit_word_t) - word); + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + break; + case_rrr(add,); + case_rrw(add,); + case_rrr(addc,); + case_rrw(addc,); + case_rrr(addx,); + case_rrw(addx,); + case_rrr(sub,); + case_rrw(sub,); + case_rrr(subc,); + case_rrw(subc,); + case_rrr(subx,); + case_rrw(subx,); + case_rrw(rsb,); + case_rrr(mul,); + case_rrw(mul,); + case_rrrr(qmul,); + case_rrrw(qmul,); + case_rrrr(qmul, _u); + case_rrrw(qmul, _u); + case_rrr(div,); + case_rrw(div,); + case_rrr(div, _u); + case_rrw(div, _u); + case_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rr(trunc, _f_i); + case_rr(trunc, _d_i); +#if __WORDSIZE == 64 + case_rr(trunc, _f_l); + case_rr(trunc, _d_l); +#endif + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_rr(ld, _c); + case_rw(ld, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rr(ld, _i); + case_rw(ld, _i); +#if __WORDSIZE == 64 + case_rr(ld, _ui); + case_rw(ld, _ui); + case_rr(ld, _l); + case_rw(ld, _l); +#endif + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rrr(ldx, _i); + case_rrw(ldx, _i); +#if __WORDSIZE == 64 + case_rrr(ldx, _ui); + case_rrw(ldx, _ui); + case_rrr(ldx, _l); + case_rrw(ldx, _l); +#endif + case_rr(st, _c); + case_wr(st, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rr(st, _i); + case_wr(st, _i); +#if __WORDSIZE == 64 + case_rr(st, _l); + case_wr(st, _l); +#endif + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rrr(stx, _i); + case_wrr(stx, _i); +#if __WORDSIZE == 64 + case_rrr(stx, _l); + case_wrr(stx, _l); +#endif + case_rr(hton, _us); + case_rr(hton, _ui); +#if __WORDSIZE == 64 + case_rr(hton, _ul); +#endif + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); +#if __WORDSIZE == 64 + case_rr(ext, _i); + case_rr(ext, _ui); +#endif + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), node->v.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rr(neg,); + case_rr(com,); + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_rrr(add, _f); + case_rrf(add, _f, 32); + case_rrr(sub, _f); + case_rrf(sub, _f, 32); + case_rrf(rsb, _f, 32); + case_rrr(mul, _f); + case_rrf(mul, _f, 32); + case_rrr(div, _f); + case_rrf(div, _f, 32); + case_rr(abs, _f); + case_rr(neg, _f); + case_rr(sqrt, _f); + case_rr(ext, _f); + case_rr(ext, _d_f); + case_rrr(lt, _f); + case_rrf(lt, _f, 32); + case_rrr(le, _f); + case_rrf(le, _f, 32); + case_rrr(eq, _f); + case_rrf(eq, _f, 32); + case_rrr(ge, _f); + case_rrf(ge, _f, 32); + case_rrr(gt, _f); + case_rrf(gt, _f, 32); + case_rrr(ne, _f); + case_rrf(ne, _f, 32); + case_rrr(unlt, _f); + case_rrf(unlt, _f, 32); + case_rrr(unle, _f); + case_rrf(unle, _f, 32); + case_rrr(uneq, _f); + case_rrf(uneq, _f, 32); + case_rrr(unge, _f); + case_rrf(unge, _f, 32); + case_rrr(ungt, _f); + case_rrf(ungt, _f, 32); + case_rrr(ltgt, _f); + case_rrf(ltgt, _f, 32); + case_rrr(ord, _f); + case_rrf(ord, _f, 32); + case_rrr(unord, _f); + case_rrf(unord, _f, 32); + case_rr(ld, _f); + case_rw(ld, _f); + case_rrr(ldx, _f); + case_rrw(ldx, _f); + case_rr(st, _f); + case_wr(st, _f); + case_rrr(stx, _f); + case_wrr(stx, _f); + case_rr(mov, _f); + case jit_code_movi_f: + assert(node->flag & jit_flag_data); + movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); + break; + case_brr(blt, _f); + case_brf(blt, _f, 32); + case_brr(ble, _f); + case_brf(ble, _f, 32); + case_brr(beq, _f); + case_brf(beq, _f, 32); + case_brr(bge, _f); + case_brf(bge, _f, 32); + case_brr(bgt, _f); + case_brf(bgt, _f, 32); + case_brr(bne, _f); + case_brf(bne, _f, 32); + case_brr(bunlt, _f); + case_brf(bunlt, _f, 32); + case_brr(bunle, _f); + case_brf(bunle, _f, 32); + case_brr(buneq, _f); + case_brf(buneq, _f, 32); + case_brr(bunge, _f); + case_brf(bunge, _f, 32); + case_brr(bungt, _f); + case_brf(bungt, _f, 32); + case_brr(bltgt, _f); + case_brf(bltgt, _f, 32); + case_brr(bord, _f); + case_brf(bord, _f, 32); + case_brr(bunord, _f); + case_brf(bunord, _f, 32); + case_rrr(add, _d); + case_rrf(add, _d, 64); + case_rrr(sub, _d); + case_rrf(sub, _d, 64); + case_rrf(rsb, _d, 64); + case_rrr(mul, _d); + case_rrf(mul, _d, 64); + case_rrr(div, _d); + case_rrf(div, _d, 64); + case_rr(abs, _d); + case_rr(neg, _d); + case_rr(sqrt, _d); + case_rr(ext, _d); + case_rr(ext, _f_d); + case_rrr(lt, _d); + case_rrf(lt, _d, 64); + case_rrr(le, _d); + case_rrf(le, _d, 64); + case_rrr(eq, _d); + case_rrf(eq, _d, 64); + case_rrr(ge, _d); + case_rrf(ge, _d, 64); + case_rrr(gt, _d); + case_rrf(gt, _d, 64); + case_rrr(ne, _d); + case_rrf(ne, _d, 64); + case_rrr(unlt, _d); + case_rrf(unlt, _d, 64); + case_rrr(unle, _d); + case_rrf(unle, _d, 64); + case_rrr(uneq, _d); + case_rrf(uneq, _d, 64); + case_rrr(unge, _d); + case_rrf(unge, _d, 64); + case_rrr(ungt, _d); + case_rrf(ungt, _d, 64); + case_rrr(ltgt, _d); + case_rrf(ltgt, _d, 64); + case_rrr(ord, _d); + case_rrf(ord, _d, 64); + case_rrr(unord, _d); + case_rrf(unord, _d, 64); + case_rr(ld, _d); + case_rw(ld, _d); + case_rrr(ldx, _d); + case_rrw(ldx, _d); + case_rr(st, _d); + case_wr(st, _d); + case_rrr(stx, _d); + case_wrr(stx, _d); + case_rr(mov, _d); + case jit_code_movi_d: + assert(node->flag & jit_flag_data); + movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w); + break; + case_brr(blt, _d); + case_brf(blt, _d, 64); + case_brr(ble, _d); + case_brf(ble, _d, 64); + case_brr(beq, _d); + case_brf(beq, _d, 64); + case_brr(bge, _d); + case_brf(bge, _d, 64); + case_brr(bgt, _d); + case_brf(bgt, _d, 64); + case_brr(bne, _d); + case_brf(bne, _d, 64); + case_brr(bunlt, _d); + case_brf(bunlt, _d, 64); + case_brr(bunle, _d); + case_brf(bunle, _d, 64); + case_brr(buneq, _d); + case_brf(buneq, _d, 64); + case_brr(bunge, _d); + case_brf(bunge, _d, 64); + case_brr(bungt, _d); + case_brf(bungt, _d, 64); + case_brr(bltgt, _d); + case_brf(bltgt, _d, 64); + case_brr(bord, _d); + case_brf(bord, _d, 64); + case_brr(bunord, _d); + case_brf(bunord, _d, 64); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + break; + case jit_code_jmpi: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } + } + else + jmpi(node->u.w); + break; + case jit_code_callr: + callr(rn(node->u.w)); + break; + case jit_code_calli: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = calli_p(temp->u.w); + if (!(temp->flag & jit_flag_patch)) + patch(word, node); + } + else + calli(node->u.w); + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif + undo.patch_offset = _jitc->patches.offset; + restart_function: + _jitc->again = 0; + prolog(node); + break; + case jit_code_epilog: + assert(_jitc->function == _jitc->functions.ptr + node->w.w); + if (_jitc->again) { + for (temp = undo.node->next; + temp != node; temp = temp->next) { + if (temp->code == jit_code_label || + temp->code == jit_code_epilog) + temp->flag &= ~jit_flag_patch; + } + temp->flag &= ~jit_flag_patch; + node = undo.node; + _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif + _jitc->patches.offset = undo.patch_offset; + goto restart_function; + } + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + epilog(node); + _jitc->function = NULL; + break; + case jit_code_va_start: + vastart(rn(node->u.w)); + break; + case jit_code_va_arg: + vaarg(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_va_arg_d: + vaarg_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_live: case jit_code_ellipsis: + case jit_code_va_push: + case jit_code_allocai: case jit_code_allocar: + case jit_code_arg: + case jit_code_arg_f: case jit_code_arg_d: + case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: +#if __WORDSIZE == 64 + case jit_code_getarg_ui: case jit_code_getarg_l: +#endif + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: +#if __WORDSIZE == 64 + case jit_code_retval_ui: case jit_code_retval_l: +#endif + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: + break; + default: + abort(); + } +# if __WORDSIZE == 64 + if (jit_carry != _NOREG) { + switch (node->code) { + case jit_code_note: + case jit_code_addcr: case jit_code_addci: + case jit_code_addxr: case jit_code_addxi: + case jit_code_subcr: case jit_code_subci: + case jit_code_subxr: case jit_code_subxi: + break; + default: + jit_unget_reg(jit_carry); + jit_carry = _NOREG; + break; + } + } +# endif + jit_regarg_clr(node, value); +# if __WORDSIZE == 64 + if (jit_regset_cmp_ui(&_jitc->regarg, 0) != 0) { + assert(jit_regset_scan1(&_jitc->regarg, 0) == jit_carry); + assert(jit_regset_scan1(&_jitc->regarg, jit_carry + 1) == ULONG_MAX); + } + assert(_jitc->synth == 0); +# else + assert(_jitc->regarg == 0 && _jitc->synth == 0); +# endif + jit_reglive(node); + } +#undef case_brf +#undef case_brw +#undef case_brr +#undef case_wrr +#undef case_rrf +#undef case_rrrw +#undef case_rrw +#undef case_rrrr +#undef case_rrr +#undef case_rf +#undef case_wr +#undef case_rw +#undef case_rr + + for (offset = 0; offset < _jitc->patches.offset; offset++) { + node = _jitc->patches.ptr[offset].node; + word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(_jitc->patches.ptr[offset].inst, word); + } + + jit_flush(_jit->code.ptr, _jit->pc.uc); + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_sparc-cpu.c" +# include "jit_sparc-fpu.c" +#undef CODE + +void +jit_flush(void *fptr, void *tptr) +{ +} + +void +_emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0) +{ + ldxi(rn(r0), rn(r1), i0); +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1) +{ + stxi(i0, rn(r0), rn(r1)); +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0) +{ + ldxi_d(rn(r0), rn(r1), i0); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1) +{ + stxi_d(i0, rn(r0), rn(r1)); +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) + flag = node->v.n->flag; + else + flag = node->u.n->flag; + assert(!(flag & jit_flag_patch)); + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + memset(_jitc->patches.ptr + _jitc->patches.length, 0, + 1024 * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} diff --git a/deps/lightning/lib/jit_x86-cpu.c b/deps/lightning/lib/jit_x86-cpu.c new file mode 100644 index 0000000..4627783 --- /dev/null +++ b/deps/lightning/lib/jit_x86-cpu.c @@ -0,0 +1,3842 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +/* avoid using it due to partial stalls */ +#define USE_INC_DEC 0 + +#if PROTO +# if __X32 || __X64_32 +# define WIDE 0 +# define ldi(u, v) ldi_i(u, v) +# define ldr(u, v) ldr_i(u, v) +# define ldxr(u, v, w) ldxr_i(u, v, w) +# define ldxi(u, v, w) ldxi_i(u, v, w) +# define sti(u, v) sti_i(u, v) +# define stxi(u, v, w) stxi_i(u, v, w) +# define can_sign_extend_int_p(im) 1 +# define can_zero_extend_int_p(im) 1 +# define fits_uint32_p(im) 1 +# else +# define WIDE 1 +# define ldi(u, v) ldi_l(u, v) +# define ldr(u, v) ldr_l(u, v) +# define ldxr(u, v, w) ldxr_l(u, v, w) +# define ldxi(u, v, w) ldxi_l(u, v, w) +# define sti(u, v) sti_l(u, v) +# define stxi(u, v, w) stxi_l(u, v, w) +# define can_sign_extend_int_p(im) \ + (((im) >= 0 && (long long)(im) <= 0x7fffffffLL) || \ + ((im) < 0 && (long long)(im) > -0x80000000LL)) +# define can_zero_extend_int_p(im) \ + ((im) >= 0 && (im) < 0x80000000LL) +# define fits_uint32_p(im) (((im) & 0xffffffff00000000LL) == 0) +# endif +# if __X32 || __CYGWIN__ || __X64_32 || _WIN32 +# define reg8_p(rn) \ + ((rn) >= _RAX_REGNO && (rn) <= _RBX_REGNO) +# else +# define reg8_p(rn) 1 +# endif +# define _RAX_REGNO 0 +# define _RCX_REGNO 1 +# define _RDX_REGNO 2 +# define _RBX_REGNO 3 +# define _RSP_REGNO 4 +# define _RBP_REGNO 5 +# define _RSI_REGNO 6 +# define _RDI_REGNO 7 +# define _R8_REGNO 8 +# define _R9_REGNO 9 +# define _R10_REGNO 10 +# define _R11_REGNO 11 +# define _R12_REGNO 12 +# define _R13_REGNO 13 +# define _R14_REGNO 14 +# define _R15_REGNO 15 +# define r7(reg) ((reg) & 7) +# define r8(reg) ((reg) & 15) +# define _SCL1 0x00 +# define _SCL2 0x01 +# define _SCL4 0x02 +# define _SCL8 0x03 +# define X86_ADD 0 +# define X86_OR 1 << 3 +# define X86_ADC 2 << 3 +# define X86_SBB 3 << 3 +# define X86_AND 4 << 3 +# define X86_SUB 5 << 3 +# define X86_XOR 6 << 3 +# define X86_CMP 7 << 3 +# define X86_ROL 0 +# define X86_ROR 1 +# define X86_RCL 2 +# define X86_RCR 3 +# define X86_SHL 4 +# define X86_SHR 5 +# define X86_SAR 7 +# define X86_NOT 2 +# define X86_NEG 3 +# define X86_MUL 4 +# define X86_IMUL 5 +# define X86_DIV 6 +# define X86_IDIV 7 +# define X86_CC_O 0x0 +# define X86_CC_NO 0x1 +# define X86_CC_NAE 0x2 +# define X86_CC_B 0x2 +# define X86_CC_C 0x2 +# define X86_CC_AE 0x3 +# define X86_CC_NB 0x3 +# define X86_CC_NC 0x3 +# define X86_CC_E 0x4 +# define X86_CC_Z 0x4 +# define X86_CC_NE 0x5 +# define X86_CC_NZ 0x5 +# define X86_CC_BE 0x6 +# define X86_CC_NA 0x6 +# define X86_CC_A 0x7 +# define X86_CC_NBE 0x7 +# define X86_CC_S 0x8 +# define X86_CC_NS 0x9 +# define X86_CC_P 0xa +# define X86_CC_PE 0xa +# define X86_CC_NP 0xb +# define X86_CC_PO 0xb +# define X86_CC_L 0xc +# define X86_CC_NGE 0xc +# define X86_CC_GE 0xd +# define X86_CC_NL 0xd +# define X86_CC_LE 0xe +# define X86_CC_NG 0xe +# define X86_CC_G 0xf +# define X86_CC_NLE 0xf +# define mrm(md, r, m) *_jit->pc.uc++ = (md<<6) | (r<<3) | m +# define sib(sc, i, b) *_jit->pc.uc++ = (sc<<6) | (i<<3) | b +# define ic(c) *_jit->pc.uc++ = c +# define is(s) *_jit->pc.us++ = s +# define ii(i) *_jit->pc.ui++ = i +# if __X64 && !__X64_32 +# define il(l) *_jit->pc.ul++ = l +# else +# define il(l) ii(l) +# endif +# define patch_abs(instr, label) \ + *(jit_word_t *)(instr - sizeof(jit_word_t)) = label +# define patch_rel(instr, label) \ + *(jit_int32_t *)(instr - 4) = label - instr +# define patch_rel_char(instr, label) \ + *(jit_int8_t *)(instr - 1) = label - instr +# define rex(l, w, r, x, b) _rex(_jit, l, w, r, x, b) +static void +_rex(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define rx(rd, md, rb, ri, ms) _rx(_jit, rd, md, rb, ri, ms) +static void +_rx(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define nop(n) _nop(_jit, n) +static void _nop(jit_state_t*, jit_int32_t); +# define emms() is(0x770f) +# define lea(md, rb, ri, ms, rd) _lea(_jit, md, rb, ri, ms, rd) +static void +_lea(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define pushr(r0) _pushr(_jit, r0) +static void _pushr(jit_state_t*, jit_int32_t) maybe_unused; +# define popr(r0) _popr(_jit, r0) +static void _popr(jit_state_t*, jit_int32_t) maybe_unused; +# define xchgr(r0, r1) _xchgr(_jit, r0, r1) +static void _xchgr(jit_state_t*, jit_int32_t, jit_int32_t); +# define testr(r0, r1) _testr(_jit, r0, r1) +static void _testr(jit_state_t*, jit_int32_t, jit_int32_t); +# define testi(r0, i0) _testi(_jit, r0, i0) +static void _testi(jit_state_t*, jit_int32_t, jit_word_t); +# define cc(code, r0) _cc(_jit, code, r0) +static void _cc(jit_state_t*, jit_int32_t, jit_int32_t); +# define icmpr(r0, r1) alur(X86_CMP, r0, r1) +# define alur(code, r0, r1) _alur(_jit, code, r0, r1) +static void _alur(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define icmpi(r0, i0) alui(X86_CMP, r0, i0) +# define alui(code, r0, i0) _alui(_jit, code, r0, i0) +static void _alui(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define iaddr(r0, r1) alur(X86_ADD, r0, r1) +# define save(r0) _save(_jit, r0) +static void _save(jit_state_t*, jit_int32_t); +# define load(r0) _load(_jit, r0) +static void _load(jit_state_t*, jit_int32_t); +# define addr(r0, r1, r2) _addr(_jit, r0, r1, r2) +static void _addr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define iaddi(r0, i0) alui(X86_ADD, r0, i0) +# define addi(r0, r1, i0) _addi(_jit, r0, r1, i0) +static void _addi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +#define addcr(r0, r1, r2) _addcr(_jit, r0, r1, r2) +static void _addcr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +#define addci(r0, r1, i0) _addci(_jit, r0, r1, i0) +static void _addci(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define iaddxr(r0, r1) alur(X86_ADC, r0, r1) +# define addxr(r0, r1, r2) _addxr(_jit, r0, r1, r2) +static void _addxr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define iaddxi(r0, i0) alui(X86_ADC, r0, i0) +# define addxi(r0, r1, i0) _addxi(_jit, r0, r1, i0) +static void _addxi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define isubr(r0, r1) alur(X86_SUB, r0, r1) +# define subr(r0, r1, r2) _subr(_jit, r0, r1, r2) +static void _subr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define isubi(r0, i0) alui(X86_SUB, r0, i0) +# define subi(r0, r1, i0) _subi(_jit, r0, r1, i0) +static void _subi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define subcr(r0, r1, r2) _subcr(_jit, r0, r1, r2) +static void _subcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subci(r0, r1, i0) _subci(_jit, r0, r1, i0) +static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define isubxr(r0, r1) alur(X86_SBB, r0, r1) +# define subxr(r0, r1, r2) _subxr(_jit, r0, r1, r2) +static void _subxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define isubxi(r0, i0) alui(X86_SBB, r0, i0) +# define subxi(r0, r1, i0) _subxi(_jit, r0, r1, i0) +static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0) +static void _rsbi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define imulr(r0, r1) _imulr(_jit, r0, r1) +static void _imulr(jit_state_t*, jit_int32_t, jit_int32_t); +# define imuli(r0, r1, i0) _imuli(_jit, r0, r1, i0) +static void _imuli(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define mulr(r0, r1, r2) _mulr(_jit, r0, r1, r2) +static void _mulr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define muli(r0, r1, i0) _muli(_jit, r0, r1, i0) +static void _muli(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define umulr(r0) unr(X86_IMUL, r0) +# define umulr_u(r0) unr(X86_MUL, r0) +# define qmulr(r0, r1, r2, r3) _iqmulr(_jit, r0, r1, r2, r3, 1) +# define qmulr_u(r0, r1, r2, r3) _iqmulr(_jit, r0, r1, r2, r3, 0) +# define iqmulr(r0, r1, r2, r3, sign) _iqmulr(_jit, r0, r1, r2, r3, sign) +static void _iqmulr(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t,jit_int32_t, jit_bool_t); +# define qmuli(r0, r1, r2, i0) _iqmuli(_jit, r0, r1, r2, i0, 1) +# define qmuli_u(r0, r1, r2, i0) _iqmuli(_jit, r0, r1, r2, i0, 0) +# define iqmuli(r0, r1, r2, i0, sign) _iqmuli(_jit, r0, r1, r2, i0, sign) +static void _iqmuli(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t,jit_word_t, jit_bool_t); +# define sign_extend_rdx_rax() _sign_extend_rdx_rax(_jit) +static void _sign_extend_rdx_rax(jit_state_t*); +# define idivr(r0) unr(X86_IDIV, r0) +# define idivr_u(r0) unr(X86_DIV, r0) +# define divremr(r0, r1, r2, i0, i1) _divremr(_jit, r0, r1, r2, i0, i1) +static void +_divremr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t, + jit_bool_t,jit_bool_t); +# define divremi(r0, r1, i0, i1, i2) _divremi(_jit, r0, r1, i0, i1, i2) +static void +_divremi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t,jit_bool_t,jit_bool_t); +# define divr(r0, r1, r2) divremr(r0, r1, r2, 1, 1) +# define divi(r0, r1, i0) divremi(r0, r1, i0, 1, 1) +# define divr_u(r0, r1, r2) divremr(r0, r1, r2, 0, 1) +# define divi_u(r0, r1, i0) divremi(r0, r1, i0, 0, 1) +# define qdivr(r0, r1, r2, r3) _iqdivr(_jit, r0, r1, r2, r3, 1) +# define qdivr_u(r0, r1, r2, r3) _iqdivr(_jit, r0, r1, r2, r3, 0) +# define iqdivr(r0, r1, r2, r3, sign) _iqdivr(_jit, r0, r1, r2, r3, sign) +static void _iqdivr(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t,jit_int32_t, jit_bool_t); +# define qdivi(r0, r1, r2, i0) _iqdivi(_jit, r0, r1, r2, i0, 1) +# define qdivi_u(r0, r1, r2, i0) _iqdivi(_jit, r0, r1, r2, i0, 0) +# define iqdivi(r0, r1, r2, i0, sign) _iqdivi(_jit, r0, r1, r2, i0, sign) +static void _iqdivi(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t,jit_word_t, jit_bool_t); +# define remr(r0, r1, r2) divremr(r0, r1, r2, 1, 0) +# define remi(r0, r1, i0) divremi(r0, r1, i0, 1, 0) +# define remr_u(r0, r1, r2) divremr(r0, r1, r2, 0, 0) +# define remi_u(r0, r1, i0) divremi(r0, r1, i0, 0, 0) +# define iandr(r0, r1) alur(X86_AND, r0, r1) +# define andr(r0, r1, r2) _andr(_jit, r0, r1, r2) +static void _andr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define iandi(r0, i0) alui(X86_AND, r0, i0) +# define andi(r0, r1, i0) _andi(_jit, r0, r1, i0) +static void _andi(jit_state_t*, jit_int32_t,jit_int32_t,jit_word_t); +# define iorr(r0, r1) alur(X86_OR, r0, r1) +# define orr(r0, r1, r2) _orr(_jit, r0, r1, r2) +static void _orr(jit_state_t*, jit_int32_t,jit_int32_t,jit_int32_t); +# define iori(r0, i0) alui(X86_OR, r0, i0) +# define ori(r0, r1, i0) _ori(_jit, r0, r1, i0) +static void _ori(jit_state_t*, jit_int32_t,jit_int32_t,jit_word_t); +# define ixorr(r0, r1) alur(X86_XOR, r0, r1) +# define xorr(r0, r1, r2) _xorr(_jit, r0, r1, r2) +static void _xorr(jit_state_t*, jit_int32_t,jit_int32_t,jit_int32_t); +# define ixori(r0, i0) alui(X86_XOR, r0, i0) +# define xori(r0, r1, i0) _xori(_jit, r0, r1, i0) +static void _xori(jit_state_t*, jit_int32_t,jit_int32_t,jit_word_t); +# define irotshr(code, r0) _irotshr(_jit, code, r0) +static void _irotshr(jit_state_t*, jit_int32_t, jit_int32_t); +# define rotshr(code, r0, r1, r2) _rotshr(_jit, code, r0, r1, r2) +static void +_rotshr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define irotshi(code, r0, i0) _irotshi(_jit, code, r0, i0) +static void _irotshi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define rotshi(code, r0, r1, i0) _rotshi(_jit, code, r0, r1, i0) +static void +_rotshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +# define lshr(r0, r1, r2) rotshr(X86_SHL, r0, r1, r2) +# define lshi(r0, r1, i0) _lshi(_jit, r0, r1, i0) +static void _lshi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define rshr(r0, r1, r2) rotshr(X86_SAR, r0, r1, r2) +# define rshi(r0, r1, i0) rotshi(X86_SAR, r0, r1, i0) +# define rshr_u(r0, r1, r2) rotshr(X86_SHR, r0, r1, r2) +# define rshi_u(r0, r1, i0) rotshi(X86_SHR, r0, r1, i0) +# define unr(code, r0) _unr(_jit, code, r0) +static void _unr(jit_state_t*, jit_int32_t, jit_int32_t); +# define inegr(r0) unr(X86_NEG, r0) +# define negr(r0, r1) _negr(_jit, r0, r1) +static void _negr(jit_state_t*, jit_int32_t, jit_int32_t); +# define icomr(r0) unr(X86_NOT, r0) +# define comr(r0, r1) _comr(_jit, r0, r1) +static void _comr(jit_state_t*, jit_int32_t, jit_int32_t); +# if USE_INC_DEC +# define incr(r0, r1) _incr(_jit, r0, r1) +static void _incr(jit_state_t*, jit_int32_t, jit_int32_t); +# define decr(r0, r1) _decr(_jit, r0, r1) +static void _decr(jit_state_t*, jit_int32_t, jit_int32_t); +# endif +# define cr(code, r0, r1, r2) _cr(_jit, code, r0, r1, r2) +static void +_cr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t); +# define ci(code, r0, r1, i0) _ci(_jit, code, r0, r1, i0) +static void +_ci(jit_state_t *_jit, jit_int32_t, jit_int32_t, jit_int32_t, jit_word_t); +# define ci0(code, r0, r1) _ci0(_jit, code, r0, r1) +static void _ci0(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ltr(r0, r1, r2) _ltr(_jit, r0, r1, r2) +static void _ltr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define lti(r0, r1, i0) _lti(_jit, r0, r1, i0) +static void _lti(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ltr_u(r0, r1, r2) _ltr_u(_jit, r0, r1, r2) +static void _ltr_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define lti_u(r0, r1, i0) ci(X86_CC_B, r0, r1, i0) +# define ler(r0, r1, r2) _ler(_jit, r0, r1, r2) +static void _ler(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define lei(r0, r1, i0) ci(X86_CC_LE, r0, r1, i0) +# define ler_u(r0, r1, r2) _ler_u(_jit, r0, r1, r2) +static void _ler_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define lei_u(r0, r1, i0) _lei_u(_jit, r0, r1, i0) +static void _lei_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define eqr(r0, r1, r2) _eqr(_jit, r0, r1, r2) +static void _eqr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define eqi(r0, r1, i0) _eqi(_jit, r0, r1, i0) +static void _eqi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ger(r0, r1, r2) _ger(_jit, r0, r1, r2) +static void _ger(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define gei(r0, r1, i0) _gei(_jit, r0, r1, i0) +static void _gei(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ger_u(r0, r1, r2) _ger_u(_jit, r0, r1, r2) +static void _ger_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define gei_u(r0, r1, i0) _gei_u(_jit, r0, r1, i0) +static void _gei_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define gtr(r0, r1, r2) _gtr(_jit, r0, r1, r2) +static void _gtr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define gti(r0, r1, i0) _ci(_jit, X86_CC_G, r0, r1, i0) +# define gtr_u(r0, r1, r2) _gtr_u(_jit, r0, r1, r2) +static void _gtr_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define gti_u(r0, r1, i0) _gti_u(_jit, r0, r1, i0) +static void _gti_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ner(r0, r1, r2) _ner(_jit, r0, r1, r2) +static void _ner(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define nei(r0, r1, i0) _nei(_jit, r0, r1, i0) +static void _nei(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define movr(r0, r1) _movr(_jit, r0, r1) +static void _movr(jit_state_t*, jit_int32_t, jit_int32_t); +# define imovi(r0, i0) _imovi(_jit, r0, i0) +static void _imovi(jit_state_t*, jit_int32_t, jit_word_t); +# define movi(r0, i0) _movi(_jit, r0, i0) +static void _movi(jit_state_t*, jit_int32_t, jit_word_t); +# define movi_p(r0, i0) _movi_p(_jit, r0, i0) +static jit_word_t _movi_p(jit_state_t*, jit_int32_t, jit_word_t); +# define movcr(r0, r1) _movcr(_jit, r0, r1) +static void _movcr(jit_state_t*,jit_int32_t,jit_int32_t); +# define movcr_u(r0, r1) _movcr_u(_jit, r0, r1) +static void _movcr_u(jit_state_t*,jit_int32_t,jit_int32_t); +# define movsr(r0, r1) _movsr(_jit, r0, r1) +static void _movsr(jit_state_t*,jit_int32_t,jit_int32_t); +# define movsr_u(r0, r1) _movsr_u(_jit, r0, r1) +static void _movsr_u(jit_state_t*,jit_int32_t,jit_int32_t); +# if __X64 && !__X64_32 +# define movir(r0, r1) _movir(_jit, r0, r1) +static void _movir(jit_state_t*,jit_int32_t,jit_int32_t); +# define movir_u(r0, r1) _movir_u(_jit, r0, r1) +static void _movir_u(jit_state_t*,jit_int32_t,jit_int32_t); +# endif +# define htonr_us(r0, r1) _htonr_us(_jit, r0, r1) +static void _htonr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define htonr_ui(r0, r1) _htonr_ui(_jit, r0, r1) +static void _htonr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# if __X64 && !__X64_32 +#define htonr_ul(r0, r1) _htonr_ul(_jit, r0, r1) +static void _htonr_ul(jit_state_t*,jit_int32_t,jit_int32_t); +#endif +# define extr_c(r0, r1) _extr_c(_jit, r0, r1) +static void _extr_c(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_uc(r0, r1) _extr_uc(_jit, r0, r1) +static void _extr_uc(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_s(r0, r1) movsr(r0, r1) +# define extr_us(r0, r1) movsr_u(r0, r1) +# if __X64 && !__X64_32 +# define extr_i(r0, r1) movir(r0, r1) +# define extr_ui(r0, r1) movir_u(r0, r1) +# endif +# define ldr_c(r0, r1) _ldr_c(_jit, r0, r1) +static void _ldr_c(jit_state_t*, jit_int32_t, jit_int32_t); +# define ldi_c(r0, i0) _ldi_c(_jit, r0, i0) +static void _ldi_c(jit_state_t*, jit_int32_t, jit_word_t); +# define ldr_uc(r0, r1) _ldr_uc(_jit, r0, r1) +static void _ldr_uc(jit_state_t*, jit_int32_t, jit_int32_t); +# define ldi_uc(r0, i0) _ldi_uc(_jit, r0, i0) +static void _ldi_uc(jit_state_t*, jit_int32_t, jit_word_t); +# define ldr_s(r0, r1) _ldr_s(_jit, r0, r1) +static void _ldr_s(jit_state_t*, jit_int32_t, jit_int32_t); +# define ldi_s(r0, i0) _ldi_s(_jit, r0, i0) +static void _ldi_s(jit_state_t*, jit_int32_t, jit_word_t); +# define ldr_us(r0, r1) _ldr_us(_jit, r0, r1) +static void _ldr_us(jit_state_t*, jit_int32_t, jit_int32_t); +# define ldi_us(r0, i0) _ldi_us(_jit, r0, i0) +static void _ldi_us(jit_state_t*, jit_int32_t, jit_word_t); +# if __X32 || !__X64_32 +# define ldr_i(r0, r1) _ldr_i(_jit, r0, r1) +static void _ldr_i(jit_state_t*, jit_int32_t, jit_int32_t); +# define ldi_i(r0, i0) _ldi_i(_jit, r0, i0) +static void _ldi_i(jit_state_t*, jit_int32_t, jit_word_t); +# endif +# if __X64 +# if __X64_32 +# define ldr_i(r0, r1) _ldr_ui(_jit, r0, r1) +# define ldi_i(r0, i0) _ldi_ui(_jit, r0, i0) +# else +# define ldr_ui(r0, r1) _ldr_ui(_jit, r0, r1) +# define ldi_ui(r0, i0) _ldi_ui(_jit, r0, i0) +# endif +static void _ldr_ui(jit_state_t*, jit_int32_t, jit_int32_t); +static void _ldi_ui(jit_state_t*, jit_int32_t, jit_word_t); +# if !__X64_32 +# define ldr_l(r0, r1) _ldr_l(_jit, r0, r1) +static void _ldr_l(jit_state_t*, jit_int32_t, jit_int32_t); +# define ldi_l(r0, i0) _ldi_l(_jit, r0, i0) +static void _ldi_l(jit_state_t*, jit_int32_t, jit_word_t); +# endif +# endif +# define ldxr_c(r0, r1, r2) _ldxr_c(_jit, r0, r1, r2) +static void _ldxr_c(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ldxi_c(r0, r1, i0) _ldxi_c(_jit, r0, r1, i0) +static void _ldxi_c(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ldxr_uc(r0, r1, r2) _ldxr_uc(_jit, r0, r1, r2) +static void _ldxr_uc(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ldxi_uc(r0, r1, i0) _ldxi_uc(_jit, r0, r1, i0) +static void _ldxi_uc(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ldxr_s(r0, r1, r2) _ldxr_s(_jit, r0, r1, r2) +static void _ldxr_s(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ldxi_s(r0, r1, i0) _ldxi_s(_jit, r0, r1, i0) +static void _ldxi_s(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ldxr_us(r0, r1, r2) _ldxr_us(_jit, r0, r1, r2) +static void _ldxr_us(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ldxi_us(r0, r1, i0) _ldxi_us(_jit, r0, r1, i0) +static void _ldxi_us(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# if __X32 || !__X64_32 +# define ldxr_i(r0, r1, r2) _ldxr_i(_jit, r0, r1, r2) +static void _ldxr_i(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ldxi_i(r0, r1, i0) _ldxi_i(_jit, r0, r1, i0) +static void _ldxi_i(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# endif +# if __X64 +# if __X64_32 +# define ldxr_i(r0, r1, r2) _ldxr_ui(_jit, r0, r1, r2) +# define ldxi_i(r0, r1, i0) _ldxi_ui(_jit, r0, r1, i0) +# else +# define ldxr_ui(r0, r1, r2) _ldxr_ui(_jit, r0, r1, r2) +# define ldxi_ui(r0, r1, i0) _ldxi_ui(_jit, r0, r1, i0) +# endif +static void _ldxr_ui(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +static void _ldxi_ui(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# if !__X64_32 +# define ldxr_l(r0, r1, r2) _ldxr_l(_jit, r0, r1, r2) +static void _ldxr_l(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ldxi_l(r0, r1, i0) _ldxi_l(_jit, r0, r1, i0) +static void _ldxi_l(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# endif +# endif +# define str_c(r0, r1) _str_c(_jit, r0, r1) +static void _str_c(jit_state_t*, jit_int32_t, jit_int32_t); +# define sti_c(i0, r0) _sti_c(_jit, i0, r0) +static void _sti_c(jit_state_t*, jit_word_t, jit_int32_t); +# define str_s(r0, r1) _str_s(_jit, r0, r1) +static void _str_s(jit_state_t*, jit_int32_t, jit_int32_t); +# define sti_s(i0, r0) _sti_s(_jit, i0, r0) +static void _sti_s(jit_state_t*, jit_word_t, jit_int32_t); +# define str_i(r0, r1) _str_i(_jit, r0, r1) +static void _str_i(jit_state_t*, jit_int32_t, jit_int32_t); +# define sti_i(i0, r0) _sti_i(_jit, i0, r0) +static void _sti_i(jit_state_t*, jit_word_t, jit_int32_t); +# if __X64 && !__X64_32 +# define str_l(r0, r1) _str_l(_jit, r0, r1) +static void _str_l(jit_state_t*, jit_int32_t, jit_int32_t); +# define sti_l(i0, r0) _sti_l(_jit, i0, r0) +static void _sti_l(jit_state_t*, jit_word_t, jit_int32_t); +# endif +# define stxr_c(r0, r1, r2) _stxr_c(_jit, r0, r1, r2) +static void _stxr_c(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define stxi_c(i0, r0, r1) _stxi_c(_jit, i0, r0, r1) +static void _stxi_c(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define stxr_s(r0, r1, r2) _stxr_s(_jit, r0, r1, r2) +static void _stxr_s(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define stxi_s(i0, r0, r1) _stxi_s(_jit, i0, r0, r1) +static void _stxi_s(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define stxr_i(r0, r1, r2) _stxr_i(_jit, r0, r1, r2) +static void _stxr_i(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define stxi_i(i0, r0, r1) _stxi_i(_jit, i0, r0, r1) +static void _stxi_i(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# if __X64 && !__X64_32 +# define stxr_l(r0, r1, r2) _stxr_l(_jit, r0, r1, r2) +static void _stxr_l(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define stxi_l(i0, r0, r1) _stxi_l(_jit, i0, r0, r1) +static void _stxi_l(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# endif +# define jcc(code, i0) _jcc(_jit, code, i0) +# define jo(i0) jcc(X86_CC_O, i0) +# define jno(i0) jcc(X86_CC_NO, i0) +# define jnae(i0) jcc(X86_CC_NAE, i0) +# define jb(i0) jcc(X86_CC_B, i0) +# define jc(i0) jcc(X86_CC_C, i0) +# define jae(i0) jcc(X86_CC_AE, i0) +# define jnb(i0) jcc(X86_CC_NB, i0) +# define jnc(i0) jcc(X86_CC_NC, i0) +# define je(i0) jcc(X86_CC_E, i0) +# define jz(i0) jcc(X86_CC_Z, i0) +# define jne(i0) jcc(X86_CC_NE, i0) +# define jnz(i0) jcc(X86_CC_NZ, i0) +# define jbe(i0) jcc(X86_CC_BE, i0) +# define jna(i0) jcc(X86_CC_NA, i0) +# define ja(i0) jcc(X86_CC_A, i0) +# define jnbe(i0) jcc(X86_CC_NBE, i0) +# define js(i0) jcc(X86_CC_S, i0) +# define jns(i0) jcc(X86_CC_NS, i0) +# define jp(i0) jcc(X86_CC_P, i0) +# define jpe(i0) jcc(X86_CC_PE, i0) +# define jnp(i0) jcc(X86_CC_NP, i0) +# define jpo(i0) jcc(X86_CC_PO, i0) +# define jl(i0) jcc(X86_CC_L, i0) +# define jnge(i0) jcc(X86_CC_NGE, i0) +# define jge(i0) jcc(X86_CC_GE, i0) +# define jnl(i0) jcc(X86_CC_NL, i0) +# define jle(i0) jcc(X86_CC_LE, i0) +# define jng(i0) jcc(X86_CC_NG, i0) +# define jg(i0) jcc(X86_CC_G, i0) +# define jnle(i0) jcc(X86_CC_NLE, i0) +static void _jcc(jit_state_t*, jit_int32_t, jit_word_t); +# define jccs(code, i0) _jccs(_jit, code, i0) +# define jos(i0) jccs(X86_CC_O, i0) +# define jnos(i0) jccs(X86_CC_NO, i0) +# define jnaes(i0) jccs(X86_CC_NAE, i0) +# define jbs(i0) jccs(X86_CC_B, i0) +# define jcs(i0) jccs(X86_CC_C, i0) +# define jaes(i0) jccs(X86_CC_AE, i0) +# define jnbs(i0) jccs(X86_CC_NB, i0) +# define jncs(i0) jccs(X86_CC_NC, i0) +# define jes(i0) jccs(X86_CC_E, i0) +# define jzs(i0) jccs(X86_CC_Z, i0) +# define jnes(i0) jccs(X86_CC_NE, i0) +# define jnzs(i0) jccs(X86_CC_NZ, i0) +# define jbes(i0) jccs(X86_CC_BE, i0) +# define jnas(i0) jccs(X86_CC_NA, i0) +# define jas(i0) jccs(X86_CC_A, i0) +# define jnbes(i0) jccs(X86_CC_NBE, i0) +# define jss(i0) jccs(X86_CC_S, i0) +# define jnss(i0) jccs(X86_CC_NS, i0) +# define jps(i0) jccs(X86_CC_P, i0) +# define jpes(i0) jccs(X86_CC_PE, i0) +# define jnps(i0) jccs(X86_CC_NP, i0) +# define jpos(i0) jccs(X86_CC_PO, i0) +# define jls(i0) jccs(X86_CC_L, i0) +# define jnges(i0) jccs(X86_CC_NGE, i0) +# define jges(i0) jccs(X86_CC_GE, i0) +# define jnls(i0) jccs(X86_CC_NL, i0) +# define jles(i0) jccs(X86_CC_LE, i0) +# define jngs(i0) jccs(X86_CC_NG, i0) +# define jgs(i0) jccs(X86_CC_G, i0) +# define jnles(i0) jccs(X86_CC_NLE, i0) +static void _jccs(jit_state_t*, jit_int32_t, jit_word_t); +# define jcr(code, i0, r0, r1) _jcr(_jit, code, i0, r0, r1) +static void _jcr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t); +# define jci(code, i0, r0, i1) _jci(_jit, code, i0, r0, i1) +static void _jci(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_word_t); +# define jci0(code, i0, r0) _jci0(_jit, code, i0, r0) +static void _jci0(jit_state_t*, jit_int32_t, jit_word_t, jit_int32_t); +# define bltr(i0, r0, r1) _bltr(_jit, i0, r0, r1) +static jit_word_t _bltr(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define blti(i0, r0, i1) _blti(_jit, i0, r0, i1) +static jit_word_t _blti(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bltr_u(i0, r0, r1) _bltr_u(_jit, i0, r0, r1) +static jit_word_t _bltr_u(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define blti_u(i0, r0, i1) _blti_u(_jit, i0, r0, i1) +static jit_word_t _blti_u(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bler(i0, r0, r1) _bler(_jit, i0, r0, r1) +static jit_word_t _bler(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define blei(i0, r0, i1) _blei(_jit, i0, r0, i1) +static jit_word_t _blei(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bler_u(i0, r0, r1) _bler_u(_jit, i0, r0, r1) +static jit_word_t _bler_u(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define blei_u(i0, r0, i1) _blei_u(_jit, i0, r0, i1) +static jit_word_t _blei_u(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define beqr(i0, r0, r1) _beqr(_jit, i0, r0, r1) +static jit_word_t _beqr(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define beqi(i0, r0, i1) _beqi(_jit, i0, r0, i1) +static jit_word_t _beqi(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bger(i0, r0, r1) _bger(_jit, i0, r0, r1) +static jit_word_t _bger(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bgei(i0, r0, i1) _bgei(_jit, i0, r0, i1) +static jit_word_t _bgei(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bger_u(i0, r0, r1) _bger_u(_jit, i0, r0, r1) +static jit_word_t _bger_u(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bgei_u(i0, r0, i1) _bgei_u(_jit, i0, r0, i1) +static jit_word_t _bgei_u(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bgtr(i0, r0, r1) _bgtr(_jit, i0, r0, r1) +static jit_word_t _bgtr(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bgti(i0, r0, i1) _bgti(_jit, i0, r0, i1) +static jit_word_t _bgti(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bgtr_u(i0, r0, r1) _bgtr_u(_jit, i0, r0, r1) +static jit_word_t _bgtr_u(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bgti_u(i0, r0, i1) _bgti_u(_jit, i0, r0, i1) +static jit_word_t _bgti_u(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bner(i0, r0, r1) _bner(_jit, i0, r0, r1) +static jit_word_t _bner(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bnei(i0, r0, i1) _bnei(_jit, i0, r0, i1) +static jit_word_t _bnei(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bmsr(i0, r0, r1) _bmsr(_jit, i0, r0, r1) +static jit_word_t _bmsr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bmsi(i0, r0, i1) _bmsi(_jit, i0, r0, i1) +static jit_word_t _bmsi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bmcr(i0, r0, r1) _bmcr(_jit, i0, r0, r1) +static jit_word_t _bmcr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bmci(i0, r0, i1) _bmci(_jit, i0, r0, i1) +static jit_word_t _bmci(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define boaddr(i0, r0, r1) _boaddr(_jit, i0, r0, r1) +static jit_word_t _boaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define boaddi(i0, r0, i1) _boaddi(_jit, i0, r0, i1) +static jit_word_t _boaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define boaddr_u(i0, r0, r1) _boaddr_u(_jit, i0, r0, r1) +static jit_word_t _boaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define boaddi_u(i0, r0, i1) _boaddi_u(_jit, i0, r0, i1) +static jit_word_t _boaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bxaddr(i0, r0, r1) _bxaddr(_jit, i0, r0, r1) +static jit_word_t _bxaddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bxaddi(i0, r0, i1) _bxaddi(_jit, i0, r0, i1) +static jit_word_t _bxaddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bxaddr_u(i0, r0, r1) _bxaddr_u(_jit, i0, r0, r1) +static jit_word_t _bxaddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bxaddi_u(i0, r0, i1) _bxaddi_u(_jit, i0, r0, i1) +static jit_word_t _bxaddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bosubr(i0, r0, r1) _bosubr(_jit, i0, r0, r1) +static jit_word_t _bosubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bosubi(i0, r0, i1) _bosubi(_jit, i0, r0, i1) +static jit_word_t _bosubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bosubr_u(i0, r0, r1) _bosubr_u(_jit, i0, r0, r1) +static jit_word_t _bosubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bosubi_u(i0, r0, i1) _bosubi_u(_jit, i0, r0, i1) +static jit_word_t _bosubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bxsubr(i0, r0, r1) _bxsubr(_jit, i0, r0, r1) +static jit_word_t _bxsubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bxsubi(i0, r0, i1) _bxsubi(_jit, i0, r0, i1) +static jit_word_t _bxsubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bxsubr_u(i0, r0, r1) _bxsubr_u(_jit, i0, r0, r1) +static jit_word_t _bxsubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bxsubi_u(i0, r0, i1) _bxsubi_u(_jit, i0, r0, i1) +static jit_word_t _bxsubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define callr(r0) _callr(_jit, r0) +static void _callr(jit_state_t*, jit_int32_t); +# define calli(i0) _calli(_jit, i0) +static jit_word_t _calli(jit_state_t*, jit_word_t); +# define jmpr(r0) _jmpr(_jit, r0) +static void _jmpr(jit_state_t*, jit_int32_t); +# define jmpi(i0) _jmpi(_jit, i0) +static jit_word_t _jmpi(jit_state_t*, jit_word_t); +# define jmpsi(i0) _jmpsi(_jit, i0) +static void _jmpsi(jit_state_t*, jit_uint8_t); +# define prolog(node) _prolog(_jit, node) +static void _prolog(jit_state_t*, jit_node_t*); +# define epilog(node) _epilog(_jit, node) +static void _epilog(jit_state_t*, jit_node_t*); +# define vastart(r0) _vastart(_jit, r0) +static void _vastart(jit_state_t*, jit_int32_t); +# define vaarg(r0, r1) _vaarg(_jit, r0, r1) +static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t); +# define vaarg_d(r0, r1, i0) _vaarg_d(_jit, r0, r1, i0) +static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_bool_t); +# define patch_at(node, instr, label) _patch_at(_jit, node, instr, label) +static void _patch_at(jit_state_t*, jit_node_t*, jit_word_t, jit_word_t); +# if !defined(HAVE_FFSL) +# if __X32 +# define ffsl(i) __builtin_ffs(i) +# else +# define ffsl(l) __builtin_ffsl(l) +# endif +# endif +#endif + +#if CODE +static void +_rex(jit_state_t *_jit, jit_int32_t l, jit_int32_t w, + jit_int32_t r, jit_int32_t x, jit_int32_t b) +{ +#if __X64 + jit_int32_t v = 0x40 | (w << 3); + + if (r != _NOREG) + v |= (r & 8) >> 1; + if (x != _NOREG) + v |= (x & 8) >> 2; + if (b != _NOREG) + v |= (b & 8) >> 3; + if (l || v != 0x40) + ic(v); +#endif +} + +static void +_rx(jit_state_t *_jit, jit_int32_t rd, jit_int32_t md, + jit_int32_t rb, jit_int32_t ri, jit_int32_t ms) +{ + if (ri == _NOREG) { + if (rb == _NOREG) { +#if __X32 + mrm(0x00, r7(rd), 0x05); +#else + mrm(0x00, r7(rd), 0x04); + sib(_SCL1, 0x04, 0x05); +#endif + ii(md); + } + else if (r7(rb) == _RSP_REGNO) { + if (md == 0) { + mrm(0x00, r7(rd), 0x04); + sib(ms, 0x04, 0x04); + } + else if ((jit_int8_t)md == md) { + mrm(0x01, r7(rd), 0x04); + sib(ms, 0x04, 0x04); + ic(md); + } + else { + mrm(0x02, r7(rd), 0x04); + sib(ms, 0x04, 0x04); + ii(md); + } + } + else { + if (md == 0 && r7(rb) != _RBP_REGNO) + mrm(0x00, r7(rd), r7(rb)); + else if ((jit_int8_t)md == md) { + mrm(0x01, r7(rd), r7(rb)); + ic(md); + } + else { + mrm(0x02, r7(rd), r7(rb)); + ii(md); + } + } + } + else if (rb == _NOREG) { + mrm(0x00, r7(rd), 0x04); + sib(ms, r7(ri), 0x05); + ii(md); + } + else if (r8(ri) != _RSP_REGNO) { + if (md == 0 && r7(rb) != _RBP_REGNO) { + mrm(0x00, r7(rd), 0x04); + sib(ms, r7(ri), r7(rb)); + } + else if ((jit_int8_t)md == md) { + mrm(0x01, r7(rd), 0x04); + sib(ms, r7(ri), r7(rb)); + ic(md); + } + else { + mrm(0x02, r7(rd), 0x04); + sib(ms, r7(ri), r7(rb)); + ic(md); + } + } + else { + fprintf(stderr, "illegal index register"); + abort(); + } +} + +static void +_nop(jit_state_t *_jit, jit_int32_t count) +{ + switch (count) { + case 0: + break; + case 1: /* NOP */ + ic(0x90); break; + case 2: /* 66 NOP */ + ic(0x66); ic(0x90); + break; + case 3: /* NOP DWORD ptr [EAX] */ + ic(0x0f); ic(0x1f); ic(0x00); + break; + case 4: /* NOP DWORD ptr [EAX + 00H] */ + ic(0x0f); ic(0x1f); ic(0x40); ic(0x00); + break; + case 5: /* NOP DWORD ptr [EAX + EAX*1 + 00H] */ + ic(0x0f); ic(0x1f); ic(0x44); ic(0x00); + ic(0x00); + break; + case 6: /* 66 NOP DWORD ptr [EAX + EAX*1 + 00H] */ + ic(0x66); ic(0x0f); ic(0x1f); ic(0x44); + ic(0x00); ic(0x00); + break; + case 7: /* NOP DWORD ptr [EAX + 00000000H] */ + ic(0x0f); ic(0x1f); ic(0x80); ii(0x0000); + break; + case 8: /* NOP DWORD ptr [EAX + EAX*1 + 00000000H] */ + ic(0x0f); ic(0x1f); ic(0x84); ic(0x00); + ii(0x0000); + break; + case 9: /* 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] */ + ic(0x66); ic(0x0f); ic(0x1f); ic(0x84); + ic(0x00); ii(0x0000); + break; + default: + abort(); + } +} + +static void +_lea(jit_state_t *_jit, jit_int32_t md, jit_int32_t rb, + jit_int32_t ri, jit_int32_t ms, jit_int32_t rd) +{ + rex(0, WIDE, rd, ri, rb); + ic(0x8d); + rx(rd, md, rb, ri, ms); +} + +static void +_pushr(jit_state_t *_jit, jit_int32_t r0) +{ + rex(0, WIDE, 0, 0, r0); + ic(0x50 | r7(r0)); +} + +static void +_popr(jit_state_t *_jit, jit_int32_t r0) +{ + rex(0, WIDE, 0, 0, r0); + ic(0x58 | r7(r0)); +} + +static void +_xchgr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, WIDE, r1, _NOREG, r0); + ic(0x87); + mrm(0x03, r7(r1), r7(r0)); +} + +static void +_testr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, WIDE, r1, _NOREG, r0); + ic(0x85); + mrm(0x03, r7(r1), r7(r0)); +} + +static void +_testi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + rex(0, WIDE, _NOREG, _NOREG, r0); + if (r0 == _RAX_REGNO) + ic(0xa9); + else { + ic(0xf7); + mrm(0x03, 0x00, r7(r0)); + } + ii(i0); +} + +static void +_cc(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0) +{ + rex(0, 0, _NOREG, _NOREG, r0); + ic(0x0f); + ic(0x90 | code); + mrm(0x03, 0x00, r7(r0)); +} + +static void +_alur(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, WIDE, r1, _NOREG, r0); + ic(code | 0x01); + mrm(0x03, r7(r1), r7(r0)); +} + +static void +_alui(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, WIDE, _NOREG, _NOREG, r0); + if ((jit_int8_t)i0 == i0) { + ic(0x83); + ic(0xc0 | code | r7(r0)); + ic(i0); + } + else { + if (r0 == _RAX_REGNO) + ic(code | 0x05); + else { + ic(0x81); + ic(0xc0 | code | r7(r0)); + } + ii(i0); + } + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + alur(code, r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_save(jit_state_t *_jit, jit_int32_t r0) +{ + if (!_jitc->function->regoff[r0]) { + _jitc->function->regoff[r0] = jit_allocai(sizeof(jit_word_t)); + _jitc->again = 1; + } + assert(!jit_regset_tstbit(&_jitc->regsav, r0)); + jit_regset_setbit(&_jitc->regsav, r0); + stxi(_jitc->function->regoff[r0], _RBP_REGNO, r0); +} + +static void +_load(jit_state_t *_jit, jit_int32_t r0) +{ + assert(_jitc->function->regoff[r0]); + assert(jit_regset_tstbit(&_jitc->regsav, r0)); + jit_regset_clrbit(&_jitc->regsav, r0); + ldxi(r0, _RBP_REGNO, _jitc->function->regoff[r0]); +} + +static void +_addr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r1) + iaddr(r0, r2); + else if (r0 == r2) + iaddr(r0, r1); + else + lea(0, r1, r2, _SCL1, r0); +} + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + movr(r0, r1); +#if USE_INC_DEC + else if (i0 == 1) + incr(r0, r1); + else if (i0 == -1) + decr(r0, r1); +#endif + else if (can_sign_extend_int_p(i0)) { + if (r0 == r1) + iaddi(r0, i0); + else + lea(i0, r1, _NOREG, _SCL1, r0); + } + else if (r0 != r1) { + movi(r0, i0); + iaddr(r0, r1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iaddr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + iaddr(r0, r1); + else { + movr(r0, r1); + iaddr(r0, r2); + } +} + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + movr(r0, r1); + iaddi(r0, i0); + } + else if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iaddr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movi(r0, i0); + iaddr(r0, r1); + } +} + +static void +_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + iaddxr(r0, r1); + else { + movr(r0, r1); + iaddxr(r0, r2); + } +} + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + movr(r0, r1); + iaddxi(r0, i0); + } + else if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iaddxr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movi(r0, i0); + iaddxr(r0, r1); + } +} + +static void +_subr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + ixorr(r0, r0); + else if (r0 == r2) { + isubr(r0, r1); + inegr(r0); + } + else { + movr(r0, r1); + isubr(r0, r2); + } +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + movr(r0, r1); +#if USE_INC_DEC + else if (i0 == 1) + decr(r0, r1); + else if (i0 == -1) + incr(r0, r1); +#endif + else if (can_sign_extend_int_p(i0)) { + if (r0 == r1) + isubi(r0, i0); + else + lea(-i0, r1, _NOREG, _SCL1, r0); + } + else if (r0 != r1) { + movi(r0, -i0); + iaddr(r0, r1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + isubr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2 && r0 != r1) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r0); + movr(r0, r1); + isubr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr(r0, r1); + isubr(r0, r2); + } +} + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + movr(r0, r1); + if (can_sign_extend_int_p(i0)) + isubi(r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + isubr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2 && r0 != r1) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r0); + movr(r0, r1); + isubxr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr(r0, r1); + isubxr(r0, r2); + } +} + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + movr(r0, r1); + if (can_sign_extend_int_p(i0)) + isubxi(r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + imovi(rn(reg), i0); + isubxr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + subi(r0, r1, i0); + negr(r0, r0); +} + +static void +_imulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, WIDE, r0, _NOREG, r1); + ic(0x0f); + ic(0xaf); + mrm(0x03, r7(r0), r7(r1)); +} + +static void +_imuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, WIDE, r0, _NOREG, r1); + if ((jit_int8_t)i0 == i0) { + ic(0x6b); + mrm(0x03, r7(r0), r7(r1)); + ic(i0); + } + else { + ic(0x69); + mrm(0x03, r7(r0), r7(r1)); + ii(i0); + } + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + imulr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_mulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r1) + imulr(r0, r2); + else if (r0 == r2) + imulr(r0, r1); + else { + movr(r0, r1); + imulr(r0, r2); + } +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + switch (i0) { + case 0: + ixorr(r0, r0); + break; + case 1: + movr(r0, r1); + break; + case -1: + negr(r0, r1); + break; + case 2: + lea(0, _NOREG, r1, _SCL2, r0); + break; + case 4: + lea(0, _NOREG, r1, _SCL4, r0); + break; + case 8: + lea(0, _NOREG, r1, _SCL8, r0); + break; + default: + if (i0 > 0 && !(i0 & (i0 - 1))) + lshi(r0, r1, ffsl(i0) - 1); + else if (can_sign_extend_int_p(i0)) + imuli(r0, r1, i0); + else if (r0 != r1) { + movi(r0, i0); + imulr(r0, r1); + } + else + imuli(r0, r0, i0); + break; + } +} + +#define savset(rn) \ + if (r0 != rn) { \ + sav |= 1 << rn; \ + if (r1 != rn && r2 != rn) \ + set |= 1 << rn; \ + } +#define isavset(rn) \ + if (r0 != rn) { \ + sav |= 1 << rn; \ + if (r1 != rn) \ + set |= 1 << rn; \ + } +#define qsavset(rn) \ + if (r0 != rn && r1 != rn) { \ + sav |= 1 << rn; \ + if (r2 != rn && r3 != rn) \ + set |= 1 << rn; \ + } +#define allocr(rn, rv) \ + if (set & (1 << rn)) \ + (void)jit_get_reg(rv|jit_class_gpr|jit_class_named); \ + if (sav & (1 << rn)) { \ + if ( jit_regset_tstbit(&_jitc->regsav, rv) || \ + !jit_regset_tstbit(&_jitc->reglive, rv)) \ + sav &= ~(1 << rn); \ + else \ + save(rv); \ + } +#define clear(rn, rv) \ + if (set & (1 << rn)) \ + jit_unget_reg(rv); \ + if (sav & (1 << rn)) \ + load(rv); +static void +_iqmulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + jit_int32_t mul; + jit_int32_t sav; + jit_int32_t set; + + sav = set = 0; + qsavset(_RDX_REGNO); + qsavset(_RAX_REGNO); + allocr(_RDX_REGNO, _RDX); + allocr(_RAX_REGNO, _RAX); + + if (r3 == _RAX_REGNO) + mul = r2; + else { + mul = r3; + movr(_RAX_REGNO, r2); + } + if (sign) + umulr(mul); + else + umulr_u(mul); + + if (r0 == _RDX_REGNO && r1 == _RAX_REGNO) + xchgr(_RAX_REGNO, _RDX_REGNO); + else { + if (r0 != _RDX_REGNO) + movr(r0, _RAX_REGNO); + movr(r1, _RDX_REGNO); + if (r0 == _RDX_REGNO) + movr(r0, _RAX_REGNO); + } + + clear(_RDX_REGNO, _RDX); + clear(_RAX_REGNO, _RAX); +} + +static void +_iqmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + + if (i0 == 0) { + ixorr(r0, r0); + ixorr(r1, r1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if (sign) + qmulr(r0, r1, r2, rn(reg)); + else + qmulr_u(r0, r1, r2, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sign_extend_rdx_rax(jit_state_t *_jit) +{ + rex(0, WIDE, 0, 0, 0); + ic(0x99); +} + +static void +_divremr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, + jit_bool_t sign, jit_bool_t divide) +{ + jit_int32_t div; + jit_int32_t reg; + jit_int32_t set; + jit_int32_t sav; + jit_int32_t use; + + sav = set = use = 0; + savset(_RDX_REGNO); + savset(_RAX_REGNO); + allocr(_RDX_REGNO, _RDX); + allocr(_RAX_REGNO, _RAX); + + if (r2 == _RAX_REGNO) { + if (r0 == _RAX_REGNO || r0 == _RDX_REGNO) { + if ((reg = jit_get_reg(jit_class_gpr|jit_class_chk)) == JIT_NOREG) + reg = jit_get_reg((r1 == _RCX_REGNO ? _RBX : _RCX) | + jit_class_gpr|jit_class_named); + use = 1; + div = rn(reg); + movr(div, _RAX_REGNO); + if (r1 != _RAX_REGNO) + movr(_RAX_REGNO, r1); + } + else { + if (r0 == r1) + xchgr(r0, _RAX_REGNO); + else { + if (r0 != _RAX_REGNO) + movr(r0, _RAX_REGNO); + if (r1 != _RAX_REGNO) + movr(_RAX_REGNO, r1); + } + div = r0; + } + } + else if (r2 == _RDX_REGNO) { + if (r0 == _RAX_REGNO || r0 == _RDX_REGNO) { + if ((reg = jit_get_reg(jit_class_gpr|jit_class_chk)) == JIT_NOREG) + reg = jit_get_reg((r1 == _RCX_REGNO ? _RBX : _RCX) | + jit_class_gpr|jit_class_named); + use = 1; + div = rn(reg); + movr(div, _RDX_REGNO); + if (r1 != _RAX_REGNO) + movr(_RAX_REGNO, r1); + } + else { + if (r1 != _RAX_REGNO) + movr(_RAX_REGNO, r1); + movr(r0, _RDX_REGNO); + div = r0; + } + } + else { + if (r1 != _RAX_REGNO) + movr(_RAX_REGNO, r1); + div = r2; + } + + if (sign) { + sign_extend_rdx_rax(); + idivr(div); + } + else { + ixorr(_RDX_REGNO, _RDX_REGNO); + idivr_u(div); + } + + if (use) + jit_unget_reg(reg); + + if (divide) + movr(r0, _RAX_REGNO); + else + movr(r0, _RDX_REGNO); + + clear(_RDX_REGNO, _RDX); + clear(_RAX_REGNO, _RAX); +} + +static void +_divremi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0, + jit_bool_t sign, jit_bool_t divide) +{ + jit_int32_t reg; + jit_int32_t div; + jit_int32_t sav; + jit_int32_t set; + jit_int32_t use; + + if (divide) { + switch (i0) { + case 1: + movr(r0, r1); + return; + case -1: + if (sign) { + negr(r0, r1); + return; + } + break; + default: + if (i0 > 0 && !(i0 & (i0 - 1))) { + movr(r0, r1); + if (sign) + rshi(r0, r0, ffsl(i0) - 1); + else + rshi_u(r0, r0, ffsl(i0) - 1); + return; + } + break; + } + } + else if (i0 == 1 || (sign && i0 == -1)) { + ixorr(r0, r0); + return; + } + else if (!sign && i0 > 0 && !(i0 & (i0 - 1))) { + if (can_sign_extend_int_p(i0)) { + movr(r0, r1); + iandi(r0, i0 - 1); + } + else if (r0 != r1) { + movi(r0, i0 - 1); + iandr(r0, r1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0 - 1); + iandr(r0, rn(reg)); + jit_unget_reg(reg); + } + return; + } + + sav = set = use = 0; + isavset(_RDX_REGNO); + isavset(_RAX_REGNO); + allocr(_RDX_REGNO, _RDX); + allocr(_RAX_REGNO, _RAX); + + if (r0 == _RAX_REGNO || r0 == _RDX_REGNO || r0 == r1) { + if ((reg = jit_get_reg(jit_class_gpr|jit_class_chk)) == JIT_NOREG) + reg = jit_get_reg((r1 == _RCX_REGNO ? _RBX : _RCX) | + jit_class_gpr|jit_class_named); + use = 1; + div = rn(reg); + } + else + div = r0; + + movi(div, i0); + movr(_RAX_REGNO, r1); + + if (sign) { + sign_extend_rdx_rax(); + idivr(div); + } + else { + ixorr(_RDX_REGNO, _RDX_REGNO); + idivr_u(div); + } + + if (use) + jit_unget_reg(reg); + + if (divide) + movr(r0, _RAX_REGNO); + else + movr(r0, _RDX_REGNO); + + clear(_RDX_REGNO, _RDX); + clear(_RAX_REGNO, _RAX); +} + +static void +_iqdivr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + jit_int32_t div; + jit_int32_t reg; + jit_int32_t sav; + jit_int32_t set; + jit_int32_t use; + + sav = set = use = 0; + qsavset(_RDX_REGNO); + qsavset(_RAX_REGNO); + allocr(_RDX_REGNO, _RDX); + allocr(_RAX_REGNO, _RAX); + if (r3 == _RAX_REGNO) { + if (r0 == _RAX_REGNO || r0 == _RDX_REGNO) { + if ((reg = jit_get_reg(jit_class_gpr|jit_class_chk)) == JIT_NOREG) + reg = jit_get_reg((r1 == _RCX_REGNO ? _RBX : _RCX) | + jit_class_gpr|jit_class_named); + use = 1; + div = rn(reg); + movr(div, _RAX_REGNO); + if (r2 != _RAX_REGNO) + movr(_RAX_REGNO, r2); + } + else { + if (r0 == r2) + xchgr(r0, _RAX_REGNO); + else { + if (r0 != _RAX_REGNO) + movr(r0, _RAX_REGNO); + if (r2 != _RAX_REGNO) + movr(_RAX_REGNO, r2); + } + div = r0; + } + } + else if (r3 == _RDX_REGNO) { + if (r0 == _RAX_REGNO || r0 == _RDX_REGNO) { + if ((reg = jit_get_reg(jit_class_gpr|jit_class_chk)) == JIT_NOREG) + reg = jit_get_reg((r1 == _RCX_REGNO ? _RBX : _RCX) | + jit_class_gpr|jit_class_named); + use = 1; + div = rn(reg); + movr(div, _RDX_REGNO); + if (r2 != _RAX_REGNO) + movr(_RAX_REGNO, r2); + } + else { + if (r2 != _RAX_REGNO) + movr(_RAX_REGNO, r2); + movr(r0, _RDX_REGNO); + div = r0; + } + } + else { + if (r2 != _RAX_REGNO) + movr(_RAX_REGNO, r2); + div = r3; + } + if (sign) { + sign_extend_rdx_rax(); + idivr(div); + } + else { + ixorr(_RDX_REGNO, _RDX_REGNO); + idivr_u(div); + } + if (use) + jit_unget_reg(reg); + + if (r0 == _RDX_REGNO && r1 == _RAX_REGNO) + xchgr(_RAX_REGNO, _RDX_REGNO); + else { + if (r0 != _RDX_REGNO) + movr(r0, _RAX_REGNO); + movr(r1, _RDX_REGNO); + if (r0 == _RDX_REGNO) + movr(r0, _RAX_REGNO); + } + + clear(_RDX_REGNO, _RDX); + clear(_RAX_REGNO, _RAX); +} + +static void +_iqdivi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + if (sign) + qdivr(r0, r1, r2, rn(reg)); + else + qdivr_u(r0, r1, r2, rn(reg)); + jit_unget_reg(reg); +} +#undef clear +#undef allocr +#undef savset + +static void +_andr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movr(r0, r1); + else if (r0 == r1) + iandr(r0, r2); + else if (r0 == r2) + iandr(r0, r1); + else { + movr(r0, r1); + iandr(r0, r2); + } +} + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + + if (i0 == 0) + ixorr(r0, r0); + else if (i0 == -1) + movr(r0, r1); + else if (r0 == r1) { + if (can_sign_extend_int_p(i0)) + iandi(r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iandr(r0, rn(reg)); + jit_unget_reg(reg); + } + } + else { + movi(r0, i0); + iandr(r0, r1); + } +} + +static void +_orr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movr(r0, r1); + else if (r0 == r1) + iorr(r0, r2); + else if (r0 == r2) + iorr(r0, r1); + else { + movr(r0, r1); + iorr(r0, r2); + } +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + movr(r0, r1); + else if (i0 == -1) + movi(r0, -1); + else if (can_sign_extend_int_p(i0)) { + movr(r0, r1); + iori(r0, i0); + } + else if (r0 != r1) { + movi(r0, i0); + iorr(r0, r1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iorr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_xorr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + ixorr(r0, r0); + else if (r0 == r1) + ixorr(r0, r2); + else if (r0 == r2) + ixorr(r0, r1); + else { + movr(r0, r1); + ixorr(r0, r2); + } +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + movr(r0, r1); + else if (i0 == -1) + comr(r0, r1); + else if (can_sign_extend_int_p(i0)) { + movr(r0, r1); + ixori(r0, i0); + } + else if (r0 != r1) { + movi(r0, i0); + ixorr(r0, r1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ixorr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_irotshr(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0) +{ + rex(0, WIDE, _RCX_REGNO, _NOREG, r0); + ic(0xd3); + mrm(0x03, code, r7(r0)); +} + +static void +_rotshr(jit_state_t *_jit, jit_int32_t code, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_int32_t use; + + if (r0 == _RCX_REGNO) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r1); + if (r2 != _RCX_REGNO) + movr(_RCX_REGNO, r2); + irotshr(code, rn(reg)); + movr(_RCX_REGNO, rn(reg)); + jit_unget_reg(reg); + } + else if (r2 != _RCX_REGNO) { + use = !jit_reg_free_p(_RCX); + if (use) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), _RCX_REGNO); + } + else + reg = 0; + if (r1 == _RCX_REGNO) { + if (r0 == r2) + xchgr(r0, _RCX_REGNO); + else { + movr(r0, r1); + movr(_RCX_REGNO, r2); + } + } + else { + movr(_RCX_REGNO, r2); + movr(r0, r1); + } + irotshr(code, r0); + if (use) { + movr(_RCX_REGNO, rn(reg)); + jit_unget_reg(reg); + } + } + else { + movr(r0, r1); + irotshr(code, r0); + } +} + +static void +_irotshi(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0, jit_word_t i0) +{ + rex(0, WIDE, _NOREG, _NOREG, r0); + if (i0 == 1) { + ic(0xd1); + mrm(0x03, code, r7(r0)); + } + else { + ic(0xc1); + mrm(0x03, code, r7(r0)); + ic(i0); + } +} + +static void +_rotshi(jit_state_t *_jit, jit_int32_t code, + jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(r0, r1); + if (i0) + irotshi(code, r0, i0); +} + +static void +_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0 == 0) + movr(r0, r1); + else if (i0 <= 3) + lea(0, _NOREG, r1, i0 == 1 ? _SCL2 : i0 == 2 ? _SCL4 : _SCL8, r0); + else + rotshi(X86_SHL, r0, r1, i0); +} + +static void +_unr(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0) +{ + rex(0, WIDE, _NOREG, _NOREG, r0); + ic(0xf7); + mrm(0x03, code, r7(r0)); +} + +static void +_negr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) + inegr(r0); + else { + ixorr(r0, r0); + isubr(r0, r1); + } +} + +static void +_comr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + movr(r0, r1); + icomr(r0); +} + +#if USE_INC_DEC +static void +_incr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + movr(r0, r1); +# if __X64 + rex(0, WIDE, _NOREG, _NOREG, r0); + ic(0xff); + ic(0xc0 | r7(r0)); +# else + ic(0x40 | r7(r0)); +# endif +} + +static void +_decr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + movr(r0, r1); +# if __X64 + rex(0, WIDE, _NOREG, _NOREG, r0); + ic(0xff); + ic(0xc8 | r7(r0)); +# else + ic(0x48 | r7(r0)); +# endif +} +#endif + +static void +_cr(jit_state_t *_jit, + jit_int32_t code, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_bool_t same; + if (reg8_p(r0)) { + same = r0 == r1 || r0 == r2; + if (!same) + ixorr(r0, r0); + icmpr(r1, r2); + if (same) + imovi(r0, 0); + cc(code, r0); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_rg8); + ixorr(rn(reg), rn(reg)); + icmpr(r1, r2); + cc(code, rn(reg)); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ci(jit_state_t *_jit, + jit_int32_t code, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + jit_bool_t same; + if (reg8_p(r0)) { + same = r0 == r1; + if (!same) + ixorr(r0, r0); + icmpi(r1, i0); + if (same) + imovi(r0, 0); + cc(code, r0); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_rg8); + ixorr(rn(reg), rn(reg)); + icmpi(r1, i0); + cc(code, rn(reg)); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ci0(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_bool_t same; + if (reg8_p(r0)) { + same = r0 == r1; + if (!same) + ixorr(r0, r0); + testr(r1, r1); + if (same) + imovi(r0, 0); + cc(code, r0); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_rg8); + ixorr(rn(reg), rn(reg)); + testr(r1, r1); + cc(code, rn(reg)); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ltr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 0); + else + cr(X86_CC_L, r0, r1, r2); +} + +static void +_lti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0) + ci(X86_CC_L, r0, r1, i0); + else + ci0(X86_CC_S, r0, r1); +} + +static void +_ltr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 0); + else + cr(X86_CC_B, r0, r1, r2); +} + +static void +_ler(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 1); + else + cr(X86_CC_LE, r0, r1, r2); +} + +static void +_ler_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 1); + else + cr(X86_CC_BE, r0, r1, r2); +} + +static void +_lei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0) + ci(X86_CC_BE, r0, r1, i0); + else + ci0(X86_CC_E, r0, r1); +} + +static void +_eqr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 1); + else + cr(X86_CC_E, r0, r1, r2); +} + +static void +_eqi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0) + ci(X86_CC_E, r0, r1, i0); + else + ci0(X86_CC_E, r0, r1); +} + +static void +_ger(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 1); + else + cr(X86_CC_GE, r0, r1, r2); +} + +static void +_gei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0) + ci(X86_CC_GE, r0, r1, i0); + else + ci0(X86_CC_NS, r0, r1); +} + +static void +_ger_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 1); + else + cr(X86_CC_AE, r0, r1, r2); +} + +static void +_gei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0) + ci(X86_CC_AE, r0, r1, i0); + else + ci0(X86_CC_NB, r0, r1); +} + +static void +_gtr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 0); + else + cr(X86_CC_G, r0, r1, r2); +} + +static void +_gtr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 0); + else + cr(X86_CC_A, r0, r1, r2); +} + +static void +_gti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0) + ci(X86_CC_A, r0, r1, i0); + else + ci0(X86_CC_NE, r0, r1); +} + +static void +_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 0); + else + cr(X86_CC_NE, r0, r1, r2); +} + +static void +_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0) + ci(X86_CC_NE, r0, r1, i0); + else + ci0(X86_CC_NE, r0, r1); +} + +static void +_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) { + rex(0, 1, r1, _NOREG, r0); + ic(0x89); + ic(0xc0 | (r1 << 3) | r7(r0)); + } +} + +static void +_imovi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ +#if __X64 +# if !__X64_32 + if (fits_uint32_p(i0)) { +# endif + rex(0, 0, _NOREG, _NOREG, r0); + ic(0xb8 | r7(r0)); + ii(i0); +# if !__X64_32 + } + else { + rex(0, 1, _NOREG, _NOREG, r0); + ic(0xb8 | r7(r0)); + il(i0); + } +# endif +#else + ic(0xb8 | r7(r0)); + ii(i0); +#endif +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + if (i0) + imovi(r0, i0); + else + ixorr(r0, r0); +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + rex(0, WIDE, _NOREG, _NOREG, r0); + ic(0xb8 | r7(r0)); + il(i0); + return (_jit->pc.w); +} + +static void +_movcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, WIDE, r0, _NOREG, r1); + ic(0x0f); + ic(0xbe); + mrm(0x03, r7(r0), r7(r1)); +} + +static void +_movcr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, WIDE, r0, _NOREG, r1); + ic(0x0f); + ic(0xb6); + mrm(0x03, r7(r0), r7(r1)); +} + +static void +_movsr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, WIDE, r0, _NOREG, r1); + ic(0x0f); + ic(0xbf); + mrm(0x03, r7(r0), r7(r1)); +} + +static void +_movsr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, WIDE, r0, _NOREG, r1); + ic(0x0f); + ic(0xb7); + mrm(0x03, r7(r0), r7(r1)); +} + +#if __X64 +static void +_movir(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, 1, r0, _NOREG, r1); + ic(0x63); + mrm(0x03, r7(r0), r7(r1)); +} + +static void +_movir_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, 0, r1, _NOREG, r0); + ic(0x89); + ic(0xc0 | (r1 << 3) | r7(r0)); +} +#endif + +static void +_htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + extr_us(r0, r1); + ic(0x66); + rex(0, 0, _NOREG, _NOREG, r0); + ic(0xc1); + mrm(0x03, X86_ROR, r7(r0)); + ic(8); +} + +static void +_htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + movr(r0, r1); + rex(0, 0, _NOREG, _NOREG, r0); + ic(0x0f); + ic(0xc8 | r7(r0)); +} + +#if __X64 && !__X64_32 +static void +_htonr_ul(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + movr(r0, r1); + rex(0, 1, _NOREG, _NOREG, r0); + ic(0x0f); + ic(0xc8 | r7(r0)); +} +#endif + +static void +_extr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (reg8_p(r1)) + movcr(r0, r1); + else { + reg = jit_get_reg(jit_class_gpr|jit_class_rg8); + movr(rn(reg), r1); + movcr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_extr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (reg8_p(r1)) + movcr_u(r0, r1); + else { + reg = jit_get_reg(jit_class_gpr|jit_class_rg8); + movr(rn(reg), r1); + movcr_u(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, WIDE, r0, _NOREG, r1); + ic(0x0f); + ic(0xbe); + rx(r0, 0, r1, _NOREG, _SCL1); +} + +static void +_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, WIDE, r0, _NOREG, _NOREG); + ic(0x0f); + ic(0xbe); + rx(r0, i0, _NOREG, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, WIDE, r0, _NOREG, r1); + ic(0x0f); + ic(0xb6); + rx(r0, 0, r1, _NOREG, _SCL1); +} + +static void +_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, WIDE, r0, _NOREG, _NOREG); + ic(0x0f); + ic(0xb6); + rx(r0, i0, _NOREG, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, WIDE, r0, _NOREG, r1); + ic(0x0f); + ic(0xbf); + rx(r0, 0, r1, _NOREG, _SCL1); +} + +static void +_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, WIDE, r0, _NOREG, _NOREG); + ic(0x0f); + ic(0xbf); + rx(r0, i0, _NOREG, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, WIDE, r0, _NOREG, r1); + ic(0x0f); + ic(0xb7); + rx(r0, 0, r1, _NOREG, _SCL1); +} + +static void +_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, WIDE, r0, _NOREG, _NOREG); + ic(0x0f); + ic(0xb7); + rx(r0, i0, _NOREG, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +#if __X32 || !__X64_32 +static void +_ldr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ +#if __X64 + rex(0, WIDE, r0, _NOREG, r1); + ic(0x63); +#else + ic(0x8b); +#endif + rx(r0, 0, r1, _NOREG, _SCL1); +} + +static void +_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { +#if __X64 + rex(0, WIDE, r0, _NOREG, _NOREG); + ic(0x63); +#else + ic(0x8b); +#endif + rx(r0, i0, _NOREG, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); + } +} +#endif + +#if __X64 +static void +_ldr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, 0, r0, _NOREG, r1); + ic(0x63); + rx(r0, 0, r1, _NOREG, _SCL1); +} + +static void +_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, 0, r0, _NOREG, _NOREG); + ic(0x63); + rx(r0, i0, _NOREG, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +# if !__X64_32 +static void +_ldr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, 1, r0, _NOREG, r1); + ic(0x8b); + rx(r0, 0, r1, _NOREG, _SCL1); +} + +static void +_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, 1, r0, _NOREG, _NOREG); + ic(0x8b); + rx(r0, i0, _NOREG, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); + } +} +# endif +#endif + +static void +_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + addr(r0, r1, r2); + ldr_c(r0, r0); +#else + rex(0, WIDE, r0, r1, r2); + ic(0x0f); + ic(0xbe); + rx(r0, 0, r2, r1, _SCL1); +#endif +} + +static void +_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, WIDE, r0, _NOREG, r1); + ic(0x0f); + ic(0xbe); + rx(r0, i0, r1, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_c(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + addr(r0, r1, r2); + ldr_uc(r0, r0); +#else + rex(0, WIDE, r0, r1, r2); + ic(0x0f); + ic(0xb6); + rx(r0, 0, r2, r1, _SCL1); +#endif +} + +static void +_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, WIDE, r0, _NOREG, r1); + ic(0x0f); + ic(0xb6); + rx(r0, i0, r1, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_uc(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + addr(r0, r1, r2); + ldr_s(r0, r0); +#else + rex(0, WIDE, r0, r1, r2); + ic(0x0f); + ic(0xbf); + rx(r0, 0, r2, r1, _SCL1); +#endif +} + +static void +_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, WIDE, r0, _NOREG, r1); + ic(0x0f); + ic(0xbf); + rx(r0, i0, r1, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_s(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + addr(r0, r1, r2); + ldr_us(r0, r0); +#else + rex(0, WIDE, r0, r1, r2); + ic(0x0f); + ic(0xb7); + rx(r0, 0, r2, r1, _SCL1); +#endif +} + +static void +_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, WIDE, r0, _NOREG, r1); + ic(0x0f); + ic(0xb7); + rx(r0, i0, r1, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_us(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +#if __X64 || !__X64_32 +static void +_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64 + rex(0, WIDE, r0, r1, r2); + ic(0x63); +#else + ic(0x8b); +#endif + rx(r0, 0, r2, r1, _SCL1); +} + +static void +_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { +#if __X64 + rex(0, WIDE, r0, _NOREG, r1); + ic(0x63); +#else + ic(0x8b); +#endif + rx(r0, i0, r1, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_i(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} +#endif + +#if __X64 +static void +_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + addr(r0, r1, r2); + /* to avoid confusion with macro renames */ + _ldr_ui(_jit, r0, r0); +#else + rex(0, 0, r0, r1, r2); + ic(0x8b); + rx(r0, 0, r2, r1, _SCL1); +#endif +} + +static void +_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, 0, r0, _NOREG, r1); + ic(0x8b); + rx(r0, i0, r1, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_ui(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +# if !__X64_32 +static void +_ldxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + rex(0, 1, r0, r1, r2); + ic(0x8b); + rx(r0, 0, r2, r1, _SCL1); +} + +static void +_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, 1, r0, _NOREG, r1); + ic(0x8b); + rx(r0, i0, r1, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldxr_l(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} +# endif +#endif + +static void +_str_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (reg8_p(r1)) { + rex(0, 0, r1, _NOREG, r0); + ic(0x88); + rx(r1, 0, r0, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_rg8); + movr(rn(reg), r1); + rex(0, 0, rn(reg), _NOREG, r0); + ic(0x88); + rx(rn(reg), 0, r0, _NOREG, _SCL1); + jit_unget_reg(reg); + } +} + +static void +_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + if (reg8_p(r0)) { + rex(0, 0, r0, _NOREG, _NOREG); + ic(0x88); + rx(r0, i0, _NOREG, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_rg8); + movr(rn(reg), r0); + rex(0, 0, rn(reg), _NOREG, _NOREG); + ic(0x88); + rx(rn(reg), i0, _NOREG, _NOREG, _SCL1); + jit_unget_reg(reg); + } + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_c(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_str_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + ic(0x66); + rex(0, 0, r1, _NOREG, r0); + ic(0x89); + rx(r1, 0, r0, _NOREG, _SCL1); +} + +static void +_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + ic(0x66); + rex(0, 0, r0, _NOREG, _NOREG); + ic(0x89); + rx(r0, i0, _NOREG, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_s(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_str_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, 0, r1, _NOREG, r0); + ic(0x89); + rx(r1, 0, r0, _NOREG, _SCL1); +} + +static void +_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, 0, r0, _NOREG, _NOREG); + ic(0x89); + rx(r0, i0, _NOREG, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_i(rn(reg), r0); + jit_unget_reg(reg); + } +} + +#if __X64 && !__X64_32 +static void +_str_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, 1, r1, _NOREG, r0); + ic(0x89); + rx(r1, 0, r0, _NOREG, _SCL1); +} + +static void +_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, 1, r0, _NOREG, _NOREG); + ic(0x89); + rx(r0, i0, _NOREG, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_l(rn(reg), r0); + jit_unget_reg(reg); + } +} +#endif + +static void +_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; +#if __X64_32 + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_c(rn(reg), r2); + jit_unget_reg(reg); +#else + if (reg8_p(r2)) { + rex(0, 0, r2, r1, r0); + ic(0x88); + rx(r2, 0, r0, r1, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_rg8); + movr(rn(reg), r2); + rex(0, 0, rn(reg), r1, r0); + ic(0x88); + rx(rn(reg), 0, r0, r1, _SCL1); + jit_unget_reg(reg); + } +#endif +} + +static void +_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + if (reg8_p(r1)) { + rex(0, 0, r1, _NOREG, r0); + ic(0x88); + rx(r1, i0, r0, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_rg8); + movr(rn(reg), r1); + rex(0, 0, rn(reg), _NOREG, r0); + ic(0x88); + rx(rn(reg), i0, r0, _NOREG, _SCL1); + jit_unget_reg(reg); + } + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_c(rn(reg), r0, r1); + jit_unget_reg(reg); + } +} + +static void +_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_s(rn(reg), r2); + jit_unget_reg(reg); +#else + ic(0x66); + rex(0, 0, r2, r1, r0); + ic(0x89); + rx(r2, 0, r0, r1, _SCL1); +#endif +} + +static void +_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + ic(0x66); + rex(0, 0, r1, _NOREG, r0); + ic(0x89); + rx(r1, i0, r0, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_s(rn(reg), r0, r1); + jit_unget_reg(reg); + } +} + +static void +_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_i(rn(reg), r2); + jit_unget_reg(reg); +#else + rex(0, 0, r2, r1, r0); + ic(0x89); + rx(r2, 0, r0, r1, _SCL1); +#endif +} + +static void +_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, 0, r1, _NOREG, r0); + ic(0x89); + rx(r1, i0, r0, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_i(rn(reg), r0, r1); + jit_unget_reg(reg); + } +} + +#if __X64 && !__X64_32 +static void +_stxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + rex(0, 1, r2, r1, r0); + ic(0x89); + rx(r2, 0, r0, r1, _SCL1); +} + +static void +_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + rex(0, 1, r1, _NOREG, r0); + ic(0x89); + rx(r1, i0, r0, _NOREG, _SCL1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + stxr_l(rn(reg), r0, r1); + jit_unget_reg(reg); + } +} +#endif + +static void +_jccs(jit_state_t *_jit, jit_int32_t code, jit_word_t i0) +{ + jit_word_t w; + ic(0x70 | code); + w = i0 - (_jit->pc.w + 1); + ic(w); +} + +static void +_jcc(jit_state_t *_jit, jit_int32_t code, jit_word_t i0) +{ + jit_word_t w; + ic(0x0f); + ic(0x80 | code); + w = i0 - (_jit->pc.w + 4); + ii(w); +} + +static void +_jcr(jit_state_t *_jit, + jit_int32_t code, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + alur(X86_CMP, r0, r1); + jcc(code, i0); +} + +static void +_jci(jit_state_t *_jit, + jit_int32_t code, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + alui(X86_CMP, r0, i1); + jcc(code, i0); +} + +static void +_jci0(jit_state_t *_jit, jit_int32_t code, jit_word_t i0, jit_int32_t r0) +{ + testr(r0, r0); + jcc(code, i0); +} + +static jit_word_t +_bltr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jcr(X86_CC_L, i0, r0, r1); + return (_jit->pc.w); +} + +static jit_word_t +_blti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + if (i1) jci (X86_CC_L, i0, r0, i1); + else jci0(X86_CC_S, i0, r0); + return (_jit->pc.w); +} + +static jit_word_t +_bltr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jcr(X86_CC_B, i0, r0, r1); + return (_jit->pc.w); +} + +static jit_word_t +_blti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + if (i1) jci (X86_CC_B, i0, r0, i1); + else jci0(X86_CC_B, i0, r0); + return (_jit->pc.w); +} + +static jit_word_t +_bler(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) jmpi(i0); + else jcr (X86_CC_LE, i0, r0, r1); + return (_jit->pc.w); +} + +static jit_word_t +_blei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + if (i1) jci (X86_CC_LE, i0, r0, i1); + else jci0(X86_CC_LE, i0, r0); + return (_jit->pc.w); +} + +static jit_word_t +_bler_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) jmpi(i0); + else jcr (X86_CC_BE, i0, r0, r1); + return (_jit->pc.w); +} + +static jit_word_t +_blei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + if (i1) jci (X86_CC_BE, i0, r0, i1); + else jci0(X86_CC_BE, i0, r0); + return (_jit->pc.w); +} + +static jit_word_t +_beqr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) jmpi(i0); + else jcr (X86_CC_E, i0, r0, r1); + return (_jit->pc.w); +} + +static jit_word_t +_beqi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + if (i1) jci (X86_CC_E, i0, r0, i1); + else jci0(X86_CC_E, i0, r0); + return (_jit->pc.w); +} + +static jit_word_t +_bger(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) jmpi(i0); + else jcr (X86_CC_GE, i0, r0, r1); + return (_jit->pc.w); +} + +static jit_word_t +_bgei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + if (i1) jci (X86_CC_GE, i0, r0, i1); + else jci0(X86_CC_NS, i0, r0); + return (_jit->pc.w); +} + +static jit_word_t +_bger_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) jmpi(i0); + else jcr (X86_CC_AE, i0, r0, r1); + return (_jit->pc.w); +} + +static jit_word_t +_bgei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + if (i1) jci (X86_CC_AE, i0, r0, i1); + else jmpi(i0); + return (_jit->pc.w); +} + +static jit_word_t +_bgtr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jcr(X86_CC_G, i0, r0, r1); + return (_jit->pc.w); +} + +static jit_word_t +_bgti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jci(X86_CC_G, i0, r0, i1); + return (_jit->pc.w); +} + +static jit_word_t +_bgtr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jcr(X86_CC_A, i0, r0, r1); + return (_jit->pc.w); +} + +static jit_word_t +_bgti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + if (i1) jci (X86_CC_A, i0, r0, i1); + else jci0(X86_CC_NE, i0, r0); + return (_jit->pc.w); +} + +static jit_word_t +_bner(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jcr(X86_CC_NE, i0, r0, r1); + return (_jit->pc.w); +} + +static jit_word_t +_bnei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + if (i1) jci (X86_CC_NE, i0, r0, i1); + else jci0(X86_CC_NE, i0, r0); + return (_jit->pc.w); +} + +static jit_word_t +_bmsr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + testr(r0, r1); + jnz(i0); + return (_jit->pc.w); +} + +static jit_word_t +_bmsi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + if (can_zero_extend_int_p(i1)) + testi(r0, i1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + testr(r0, rn(reg)); + jit_unget_reg(reg); + } + jnz(i0); + return (_jit->pc.w); +} + +static jit_word_t +_bmcr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + testr(r0, r1); + jz(i0); + return (_jit->pc.w); +} + +static jit_word_t +_bmci(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + if (can_zero_extend_int_p(i1)) + testi(r0, i1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + testr(r0, rn(reg)); + jit_unget_reg(reg); + } + jz(i0); + return (_jit->pc.w); +} + +static jit_word_t +_boaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + iaddr(r0, r1); + jo(i0); + return (_jit->pc.w); +} + +static jit_word_t +_boaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i1)) { + iaddi(r0, i1); + jo(i0); + return (_jit->pc.w); + } + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + jit_unget_reg(reg); + return (boaddr(i0, r0, rn(reg))); +} + +static jit_word_t +_boaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + iaddr(r0, r1); + jc(i0); + return (_jit->pc.w); +} + +static jit_word_t +_boaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i1)) { + iaddi(r0, i1); + jc(i0); + return (_jit->pc.w); + } + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + jit_unget_reg(reg); + return (boaddr_u(i0, r0, rn(reg))); +} + +static jit_word_t +_bxaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + iaddr(r0, r1); + jno(i0); + return (_jit->pc.w); +} + +static jit_word_t +_bxaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i1)) { + iaddi(r0, i1); + jno(i0); + return (_jit->pc.w); + } + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + jit_unget_reg(reg); + return (bxaddr(i0, r0, rn(reg))); +} + +static jit_word_t +_bxaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + iaddr(r0, r1); + jnc(i0); + return (_jit->pc.w); +} + +static jit_word_t +_bxaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i1)) { + iaddi(r0, i1); + jnc(i0); + return (_jit->pc.w); + } + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + jit_unget_reg(reg); + return (bxaddr_u(i0, r0, rn(reg))); +} + +static jit_word_t +_bosubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + isubr(r0, r1); + jo(i0); + return (_jit->pc.w); +} + +static jit_word_t +_bosubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i1)) { + isubi(r0, i1); + jo(i0); + return (_jit->pc.w); + } + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + jit_unget_reg(reg); + return (bosubr(i0, r0, rn(reg))); +} + +static jit_word_t +_bosubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + isubr(r0, r1); + jc(i0); + return (_jit->pc.w); +} + +static jit_word_t +_bosubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i1)) { + isubi(r0, i1); + jc(i0); + return (_jit->pc.w); + } + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + jit_unget_reg(reg); + return (bosubr_u(i0, r0, rn(reg))); +} + +static jit_word_t +_bxsubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + isubr(r0, r1); + jno(i0); + return (_jit->pc.w); +} + +static jit_word_t +_bxsubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i1)) { + isubi(r0, i1); + jno(i0); + return (_jit->pc.w); + } + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + jit_unget_reg(reg); + return (bxsubr(i0, r0, rn(reg))); +} + +static jit_word_t +_bxsubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + isubr(r0, r1); + jnc(i0); + return (_jit->pc.w); +} + +static jit_word_t +_bxsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i1)) { + isubi(r0, i1); + jnc(i0); + return (_jit->pc.w); + } + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + jit_unget_reg(reg); + return (bxsubr_u(i0, r0, rn(reg))); +} + +static void +_callr(jit_state_t *_jit, jit_int32_t r0) +{ + rex(0, 0, _NOREG, _NOREG, r0); + ic(0xff); + mrm(0x03, 0x02, r7(r0)); +} + +static jit_word_t +_calli(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t word; +#if __X64 + jit_int32_t reg; + + reg = jit_get_reg(jit_class_gpr); + word = movi_p(rn(reg), i0); + callr(rn(reg)); + jit_unget_reg(reg); +#else + jit_word_t w; + ic(0xe8); + w = i0 - (_jit->pc.w + 4); + ii(w); + word = _jit->pc.w; +#endif + return (word); +} + +static void +_jmpr(jit_state_t *_jit, jit_int32_t r0) +{ + rex(0, WIDE, _NOREG, _NOREG, r0); + ic(0xff); + mrm(0x03, 0x04, r7(r0)); +} + +static jit_word_t +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + ic(0xe9); + w = i0 - (_jit->pc.w + 4); + ii(w); + return (_jit->pc.w); +} + +static void +_jmpsi(jit_state_t *_jit, jit_uint8_t i0) +{ + ic(0xeb); + ic(i0); +} + +static void +_prolog(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t reg; + if (_jitc->function->define_frame || _jitc->function->assume_frame) { + jit_int32_t frame = -_jitc->function->frame; + assert(_jitc->function->self.aoff >= frame); + if (_jitc->function->assume_frame) + return; + _jitc->function->self.aoff = frame; + } + if (_jitc->function->allocar) + _jitc->function->self.aoff &= -16; +#if __X64 && (__CYGWIN__ || _WIN32) + _jitc->function->stack = (((/* first 32 bytes must be allocated */ + (_jitc->function->self.alen > 32 ? + _jitc->function->self.alen : 32) - + /* align stack at 16 bytes */ + _jitc->function->self.aoff) + 15) & -16) + + stack_adjust; +#else + _jitc->function->stack = (((_jitc->function->self.alen - + _jitc->function->self.aoff) + 15) & -16) + + stack_adjust; +#endif + subi(_RSP_REGNO, _RSP_REGNO, stack_framesize - REAL_WORDSIZE); + /* callee save registers */ +#if __X32 + if (jit_regset_tstbit(&_jitc->function->regset, _RDI)) + stxi(12, _RSP_REGNO, _RDI_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _RSI)) + stxi( 8, _RSP_REGNO, _RSI_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _RBX)) + stxi( 4, _RSP_REGNO, _RBX_REGNO); +#else +# if __CYGWIN__ || _WIN32 + if (jit_regset_tstbit(&_jitc->function->regset, _XMM15)) + sse_stxi_d(136, _RSP_REGNO, _XMM15_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM14)) + sse_stxi_d(128, _RSP_REGNO, _XMM14_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM13)) + sse_stxi_d(120, _RSP_REGNO, _XMM13_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM12)) + sse_stxi_d(112, _RSP_REGNO, _XMM12_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM11)) + sse_stxi_d(104, _RSP_REGNO, _XMM11_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM10)) + sse_stxi_d(96, _RSP_REGNO, _XMM10_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM9)) + sse_stxi_d(88, _RSP_REGNO, _XMM9_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM8)) + sse_stxi_d(80, _RSP_REGNO, _XMM8_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM7)) + sse_stxi_d(72, _RSP_REGNO, _XMM7_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM6)) + sse_stxi_d(64, _RSP_REGNO, _XMM6_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _R15)) + stxi(56, _RSP_REGNO, _R15_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _R14)) + stxi(48, _RSP_REGNO, _R14_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _R13)) + stxi(40, _RSP_REGNO, _R13_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _R12)) + stxi(32, _RSP_REGNO, _R12_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _RSI)) + stxi(24, _RSP_REGNO, _RSI_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _RDI)) + stxi(16, _RSP_REGNO, _RDI_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _RBX)) + stxi( 8, _RSP_REGNO, _RBX_REGNO); +# else + if (jit_regset_tstbit(&_jitc->function->regset, _RBX)) + stxi(40, _RSP_REGNO, _RBX_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _R12)) + stxi(32, _RSP_REGNO, _R12_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _R13)) + stxi(24, _RSP_REGNO, _R13_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _R14)) + stxi(16, _RSP_REGNO, _R14_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _R15)) + stxi( 8, _RSP_REGNO, _R15_REGNO); +# endif +#endif + stxi(0, _RSP_REGNO, _RBP_REGNO); + movr(_RBP_REGNO, _RSP_REGNO); + + /* alloca */ + subi(_RSP_REGNO, _RSP_REGNO, _jitc->function->stack); + if (_jitc->function->allocar) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), _jitc->function->self.aoff); + stxi_i(_jitc->function->aoffoff, _RBP_REGNO, rn(reg)); + jit_unget_reg(reg); + } + +#if __X64 && !(__CYGWIN__ || _WIN32) + if (_jitc->function->self.call & jit_call_varargs) { + jit_word_t nofp_code; + + /* Save gp registers in the save area, if any is a vararg */ + for (reg = first_gp_from_offset(_jitc->function->vagp); + jit_arg_reg_p(reg); ++reg) + stxi(_jitc->function->vaoff + first_gp_offset + + reg * 8, _RBP_REGNO, rn(JIT_RA0 - reg)); + + reg = first_fp_from_offset(_jitc->function->vafp); + if (jit_arg_f_reg_p(reg)) { + /* Skip over if no float registers were passed as argument */ + /* test %al, %al */ + ic(0x84); + ic(0xc0); + jes(0); + nofp_code = _jit->pc.w; + + /* Save fp registers in the save area, if any is a vararg */ + /* Note that the full 16 byte xmm is not saved, because + * lightning only handles float and double, and, while + * attempting to provide a va_list compatible pointer as + * jit_va_start return, does not guarantee it (on all ports). */ + for (; jit_arg_f_reg_p(reg); ++reg) + sse_stxi_d(_jitc->function->vaoff + first_fp_offset + + reg * va_fp_increment, _RBP_REGNO, rn(_XMM0 - reg)); + + patch_rel_char(nofp_code, _jit->pc.w); + } + } +#endif +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *node) +{ + if (_jitc->function->assume_frame) + return; + /* callee save registers */ + movr(_RSP_REGNO, _RBP_REGNO); +#if __X32 + if (jit_regset_tstbit(&_jitc->function->regset, _RDI)) + ldxi(_RDI_REGNO, _RSP_REGNO, 12); + if (jit_regset_tstbit(&_jitc->function->regset, _RSI)) + ldxi(_RSI_REGNO, _RSP_REGNO, 8); + if (jit_regset_tstbit(&_jitc->function->regset, _RBX)) + ldxi(_RBX_REGNO, _RSP_REGNO, 4); +#else +# if __CYGWIN__ || _WIN32 + if (jit_regset_tstbit(&_jitc->function->regset, _XMM15)) + sse_ldxi_d(_XMM15_REGNO, _RSP_REGNO, 136); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM14)) + sse_ldxi_d(_XMM14_REGNO, _RSP_REGNO, 128); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM13)) + sse_ldxi_d(_XMM13_REGNO, _RSP_REGNO, 120); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM12)) + sse_ldxi_d(_XMM12_REGNO, _RSP_REGNO, 112); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM11)) + sse_ldxi_d(_XMM11_REGNO, _RSP_REGNO, 104); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM10)) + sse_ldxi_d(_XMM10_REGNO, _RSP_REGNO, 96); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM9)) + sse_ldxi_d(_XMM9_REGNO, _RSP_REGNO, 88); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM8)) + sse_ldxi_d(_XMM8_REGNO, _RSP_REGNO, 80); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM7)) + sse_ldxi_d(_XMM7_REGNO, _RSP_REGNO, 72); + if (jit_regset_tstbit(&_jitc->function->regset, _XMM6)) + sse_ldxi_d(_XMM6_REGNO, _RSP_REGNO, 64); + if (jit_regset_tstbit(&_jitc->function->regset, _R15)) + ldxi(_R15_REGNO, _RSP_REGNO, 56); + if (jit_regset_tstbit(&_jitc->function->regset, _R14)) + ldxi(_R14_REGNO, _RSP_REGNO, 48); + if (jit_regset_tstbit(&_jitc->function->regset, _R13)) + ldxi(_R13_REGNO, _RSP_REGNO, 40); + if (jit_regset_tstbit(&_jitc->function->regset, _R12)) + ldxi(_R12_REGNO, _RSP_REGNO, 32); + if (jit_regset_tstbit(&_jitc->function->regset, _RSI)) + ldxi(_RSI_REGNO, _RSP_REGNO, 24); + if (jit_regset_tstbit(&_jitc->function->regset, _RDI)) + ldxi(_RDI_REGNO, _RSP_REGNO, 16); + if (jit_regset_tstbit(&_jitc->function->regset, _RBX)) + ldxi(_RBX_REGNO, _RSP_REGNO, 8); +# else + if (jit_regset_tstbit(&_jitc->function->regset, _RBX)) + ldxi(_RBX_REGNO, _RSP_REGNO, 40); + if (jit_regset_tstbit(&_jitc->function->regset, _R12)) + ldxi(_R12_REGNO, _RSP_REGNO, 32); + if (jit_regset_tstbit(&_jitc->function->regset, _R13)) + ldxi(_R13_REGNO, _RSP_REGNO, 24); + if (jit_regset_tstbit(&_jitc->function->regset, _R14)) + ldxi(_R14_REGNO, _RSP_REGNO, 16); + if (jit_regset_tstbit(&_jitc->function->regset, _R15)) + ldxi(_R15_REGNO, _RSP_REGNO, 8); +# endif +#endif + ldxi(_RBP_REGNO, _RSP_REGNO, 0); + addi(_RSP_REGNO, _RSP_REGNO, stack_framesize - REAL_WORDSIZE); + + ic(0xc3); +} + +static void +_vastart(jit_state_t *_jit, jit_int32_t r0) +{ +#if __X32 || __CYGWIN__ || _WIN32 + assert(_jitc->function->self.call & jit_call_varargs); + addi(r0, _RBP_REGNO, _jitc->function->self.size); +#else + jit_int32_t reg; + + assert(_jitc->function->self.call & jit_call_varargs); + + /* Return jit_va_list_t in the register argument */ + addi(r0, _RBP_REGNO, _jitc->function->vaoff); + reg = jit_get_reg(jit_class_gpr); + + /* Initialize gp offset in the save area. */ + movi(rn(reg), _jitc->function->vagp); + stxi_i(offsetof(jit_va_list_t, gpoff), r0, rn(reg)); + + /* Initialize fp offset in the save area. */ + movi(rn(reg), _jitc->function->vafp); + stxi_i(offsetof(jit_va_list_t, fpoff), r0, rn(reg)); + + /* Initialize overflow pointer to the first stack argument. */ + addi(rn(reg), _RBP_REGNO, _jitc->function->self.size); + stxi(offsetof(jit_va_list_t, over), r0, rn(reg)); + + /* Initialize register save area pointer. */ + addi(rn(reg), r0, first_gp_offset); + stxi(offsetof(jit_va_list_t, save), r0, rn(reg)); + + jit_unget_reg(reg); +#endif +} + +static void +_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ +#if __X32 || __CYGWIN__ || _WIN32 + assert(_jitc->function->self.call & jit_call_varargs); + ldr(r0, r1); + addi(r1, r1, va_gp_increment); +#else + jit_int32_t rg0; + jit_int32_t rg1; + jit_word_t ge_code; + jit_word_t lt_code; + + assert(_jitc->function->self.call & jit_call_varargs); + + rg0 = jit_get_reg(jit_class_gpr); + rg1 = jit_get_reg(jit_class_gpr); + + /* Load the gp offset in save area in the first temporary. */ + ldxi_i(rn(rg0), r1, offsetof(jit_va_list_t, gpoff)); + + /* Jump over if there are no remaining arguments in the save area. */ + icmpi(rn(rg0), va_gp_max_offset); + jaes(0); + ge_code = _jit->pc.w; + + /* Load the save area pointer in the second temporary. */ + ldxi(rn(rg1), r1, offsetof(jit_va_list_t, save)); + + /* Load the vararg argument in the first argument. */ + ldxr(r0, rn(rg1), rn(rg0)); + + /* Update the gp offset. */ + addi(rn(rg0), rn(rg0), 8); + stxi_i(offsetof(jit_va_list_t, gpoff), r1, rn(rg0)); + + /* Will only need one temporary register below. */ + jit_unget_reg(rg1); + + /* Jump over overflow code. */ + jmpsi(0); + lt_code = _jit->pc.w; + + /* Where to land if argument is in overflow area. */ + patch_rel_char(ge_code, _jit->pc.w); + + /* Load overflow pointer. */ + ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over)); + + /* Load argument. */ + ldr(r0, rn(rg0)); + + /* Update overflow pointer. */ + addi(rn(rg0), rn(rg0), va_gp_increment); + stxi(offsetof(jit_va_list_t, over), r1, rn(rg0)); + + /* Where to land if argument is in save area. */ + patch_rel_char(lt_code, _jit->pc.w); + + jit_unget_reg(rg0); +#endif +} + +/* The x87 boolean argument tells if will put the result in a x87 + * register if non false, in a sse register otherwise. */ +static void +_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_bool_t x87) +{ +#if __X32 || __CYGWIN__ || _WIN32 + assert(_jitc->function->self.call & jit_call_varargs); + if (x87) + x87_ldr_d(r0, r1); + else + sse_ldr_d(r0, r1); + addi(r1, r1, 8); +#else + jit_int32_t rg0; + jit_int32_t rg1; + jit_word_t ge_code; + jit_word_t lt_code; + + assert(_jitc->function->self.call & jit_call_varargs); + + rg0 = jit_get_reg(jit_class_gpr); + rg1 = jit_get_reg(jit_class_gpr); + + /* Load the fp offset in save area in the first temporary. */ + ldxi_i(rn(rg0), r1, offsetof(jit_va_list_t, fpoff)); + + /* Jump over if there are no remaining arguments in the save area. */ + icmpi(rn(rg0), va_fp_max_offset); + jaes(0); + ge_code = _jit->pc.w; + + /* Load the save area pointer in the second temporary. */ + ldxi(rn(rg1), r1, offsetof(jit_va_list_t, save)); + + /* Load the vararg argument in the first argument. */ + if (x87) + x87_ldxr_d(r0, rn(rg1), rn(rg0)); + else + sse_ldxr_d(r0, rn(rg1), rn(rg0)); + + /* Update the fp offset. */ + addi(rn(rg0), rn(rg0), va_fp_increment); + stxi_i(offsetof(jit_va_list_t, fpoff), r1, rn(rg0)); + + /* Will only need one temporary register below. */ + jit_unget_reg(rg1); + + /* Jump over overflow code. */ + jmpsi(0); + lt_code = _jit->pc.w; + + /* Where to land if argument is in overflow area. */ + patch_rel_char(ge_code, _jit->pc.w); + + /* Load overflow pointer. */ + ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over)); + + /* Load argument. */ + if (x87) + x87_ldr_d(r0, rn(rg0)); + else + sse_ldr_d(r0, rn(rg0)); + + /* Update overflow pointer. */ + addi(rn(rg0), rn(rg0), 8); + stxi(offsetof(jit_va_list_t, over), r1, rn(rg0)); + + /* Where to land if argument is in save area. */ + patch_rel_char(lt_code, _jit->pc.w); + + jit_unget_reg(rg0); +#endif +} + +static void +_patch_at(jit_state_t *_jit, jit_node_t *node, + jit_word_t instr, jit_word_t label) +{ + switch (node->code) { +# if __X64 + case jit_code_calli: +# endif + case jit_code_movi: + patch_abs(instr, label); + break; + default: + patch_rel(instr, label); + break; + } +} +#endif diff --git a/deps/lightning/lib/jit_x86-sse.c b/deps/lightning/lib/jit_x86-sse.c new file mode 100644 index 0000000..d09bda9 --- /dev/null +++ b/deps/lightning/lib/jit_x86-sse.c @@ -0,0 +1,1569 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# if __X32 +# define sse_address_p(i0) 1 +# else +# if __X64_32 +# define sse_address_p(i0) ((jit_word_t)(i0) >= 0) +# else +# define sse_address_p(i0) can_sign_extend_int_p(i0) +# endif +# endif +# define _XMM6_REGNO 6 +# define _XMM7_REGNO 7 +# define _XMM8_REGNO 8 +# define _XMM9_REGNO 9 +# define _XMM10_REGNO 10 +# define _XMM11_REGNO 11 +# define _XMM12_REGNO 12 +# define _XMM13_REGNO 13 +# define _XMM14_REGNO 14 +# define _XMM15_REGNO 15 +#define X86_SSE_MOV 0x10 +#define X86_SSE_MOV1 0x11 +#define X86_SSE_MOVLP 0x12 +#define X86_SSE_MOVHP 0x16 +#define X86_SSE_MOVA 0x28 +#define X86_SSE_CVTIS 0x2a +#define X86_SSE_CVTTSI 0x2c +#define X86_SSE_CVTSI 0x2d +#define X86_SSE_UCOMI 0x2e +#define X86_SSE_COMI 0x2f +#define X86_SSE_ROUND 0x3a +#define X86_SSE_SQRT 0x51 +#define X86_SSE_RSQRT 0x52 +#define X86_SSE_RCP 0x53 +#define X86_SSE_AND 0x54 +#define X86_SSE_ANDN 0x55 +#define X86_SSE_OR 0x56 +#define X86_SSE_XOR 0x57 +#define X86_SSE_ADD 0x58 +#define X86_SSE_MUL 0x59 +#define X86_SSE_CVTSD 0x5a +#define X86_SSE_CVTDT 0x5b +#define X86_SSE_SUB 0x5c +#define X86_SSE_MIN 0x5d +#define X86_SSE_DIV 0x5e +#define X86_SSE_MAX 0x5f +#define X86_SSE_X2G 0x6e +#define X86_SSE_EQB 0x74 +#define X86_SSE_EQW 0x75 +#define X86_SSE_EQD 0x76 +#define X86_SSE_G2X 0x7e +#define X86_SSE_MOV2 0xd6 +# define sser(c,r0,r1) _sser(_jit,c,r0,r1) +static void _sser(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ssexr(p,c,r0,r1) _ssexr(_jit,p,c,r0,r1) +static void _ssexr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define ssexi(c,r0,m,i) _ssexi(_jit,c,r0,m,i) +static void _ssexi(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define addssr(r0, r1) ssexr(0xf3, X86_SSE_ADD, r0, r1) +# define addsdr(r0, r1) ssexr(0xf2, X86_SSE_ADD, r0, r1) +# define subssr(r0, r1) ssexr(0xf3, X86_SSE_SUB, r0, r1) +# define subsdr(r0, r1) ssexr(0xf2, X86_SSE_SUB, r0, r1) +# define mulssr(r0, r1) ssexr(0xf3, X86_SSE_MUL, r0, r1) +# define mulsdr(r0, r1) ssexr(0xf2, X86_SSE_MUL, r0, r1) +# define divssr(r0, r1) ssexr(0xf3, X86_SSE_DIV, r0, r1) +# define divsdr(r0, r1) ssexr(0xf2, X86_SSE_DIV, r0, r1) +# define andpsr(r0, r1) sser( X86_SSE_AND, r0, r1) +# define andpdr(r0, r1) ssexr(0x66, X86_SSE_AND, r0, r1) +# define sse_truncr_f_i(r0, r1) ssexr(0xf3, X86_SSE_CVTTSI, r0, r1) +# define sse_truncr_d_i(r0, r1) ssexr(0xf2, X86_SSE_CVTTSI, r0, r1) +# if __X64 +# define sse_truncr_f_l(r0, r1) sselxr(0xf3, X86_SSE_CVTTSI, r0, r1) +# define sse_truncr_d_l(r0, r1) sselxr(0xf2, X86_SSE_CVTTSI, r0, r1) +# define sse_extr_f(r0, r1) sselxr(0xf3, X86_SSE_CVTIS, r0, r1) +# define sse_extr_d(r0, r1) sselxr(0xf2, X86_SSE_CVTIS, r0, r1) +# else +# define sse_extr_f(r0, r1) ssexr(0xf3, X86_SSE_CVTIS, r0, r1) +# define sse_extr_d(r0, r1) ssexr(0xf2, X86_SSE_CVTIS, r0, r1) +# endif +# define sse_extr_f_d(r0, r1) ssexr(0xf3, X86_SSE_CVTSD, r0, r1) +# define sse_extr_d_f(r0, r1) ssexr(0xf2, X86_SSE_CVTSD, r0, r1) +# define ucomissr(r0,r1) sser(X86_SSE_UCOMI,r0,r1) +# define ucomisdr(r0,r1) ssexr(0x66,X86_SSE_UCOMI,r0,r1) +# define xorpsr(r0,r1) sser(X86_SSE_XOR,r0,r1) +# define xorpdr(r0,r1) ssexr(0x66,X86_SSE_XOR,r0,r1) +# define movdlxr(r0,r1) ssexr(0x66, X86_SSE_X2G,r0,r1) +# define pcmpeqlr(r0, r1) ssexr(0x66, X86_SSE_EQD, r0, r1) +# define psrl(r0, i0) ssexi(0x72, r0, 0x02, i0) +# define psrq(r0, i0) ssexi(0x73, r0, 0x02, i0) +# define psll(r0, i0) ssexi(0x72, r0, 0x06, i0) +# define pslq(r0, i0) ssexi(0x73, r0, 0x06, i0) +# define movdqxr(r0,r1) sselxr(0x66,X86_SSE_X2G,r0,r1) +# if __X64 && !__X64_32 +# define sselxr(p,c,r0,r1) _sselxr(_jit,p,c,r0,r1) +static void +_sselxr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t); +# else +# define sselxr(p,c,r0,r1) ssexr(p,c,r0,r1) +# endif +# define ssexrx(p,c,md,rb,ri,ms,rd) _ssexrx(_jit,p,c,md,rb,ri,ms,rd) +# define movssmr(md,rb,ri,ms,rd) ssexrx(0xf3,X86_SSE_MOV,md,rb,ri,ms,rd) +# define movsdmr(md,rb,ri,ms,rd) ssexrx(0xf2,X86_SSE_MOV,md,rb,ri,ms,rd) +# define movssrm(rs,md,mb,mi,ms) ssexrx(0xf3,X86_SSE_MOV1,md,mb,mi,ms,rs) +# define movsdrm(rs,md,mb,mi,ms) ssexrx(0xf2,X86_SSE_MOV1,md,mb,mi,ms,rs) +static void +_ssexrx(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, + jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_addr_f(r0, r1, r2) _sse_addr_f(_jit, r0, r1, r2) +static void _sse_addr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define sse_addi_f(r0, r1, i0) _sse_addi_f(_jit, r0, r1, i0) +static void _sse_addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_addr_d(r0, r1, r2) _sse_addr_d(_jit, r0, r1, r2) +static void _sse_addr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define sse_addi_d(r0, r1, i0) _sse_addi_d(_jit, r0, r1, i0) +static void _sse_addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_subr_f(r0, r1, r2) _sse_subr_f(_jit, r0, r1, r2) +static void _sse_subr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define sse_subi_f(r0, r1, i0) _sse_subi_f(_jit, r0, r1, i0) +static void _sse_subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_subr_d(r0, r1, r2) _sse_subr_d(_jit, r0, r1, r2) +static void _sse_subr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define sse_subi_d(r0, r1, i0) _sse_subi_d(_jit, r0, r1, i0) +static void _sse_subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_rsbr_f(r0, r1, r2) sse_subr_f(r0, r2, r1) +# define sse_rsbi_f(r0, r1, i0) _sse_rsbi_f(_jit, r0, r1, i0) +static void _sse_rsbi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_rsbr_d(r0, r1, r2) sse_subr_d(r0, r2, r1) +# define sse_rsbi_d(r0, r1, i0) _sse_rsbi_d(_jit, r0, r1, i0) +static void _sse_rsbi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_mulr_f(r0, r1, r2) _sse_mulr_f(_jit, r0, r1, r2) +static void _sse_mulr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define sse_muli_f(r0, r1, i0) _sse_muli_f(_jit, r0, r1, i0) +static void _sse_muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_mulr_d(r0, r1, r2) _sse_mulr_d(_jit, r0, r1, r2) +static void _sse_mulr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define sse_muli_d(r0, r1, i0) _sse_muli_d(_jit, r0, r1, i0) +static void _sse_muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_divr_f(r0, r1, r2) _sse_divr_f(_jit, r0, r1, r2) +static void _sse_divr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define sse_divi_f(r0, r1, i0) _sse_divi_f(_jit, r0, r1, i0) +static void _sse_divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_divr_d(r0, r1, r2) _sse_divr_d(_jit, r0, r1, r2) +static void _sse_divr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define sse_divi_d(r0, r1, i0) _sse_divi_d(_jit, r0, r1, i0) +static void _sse_divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_absr_f(r0, r1) _sse_absr_f(_jit, r0, r1) +static void _sse_absr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define sse_absr_d(r0, r1) _sse_absr_d(_jit, r0, r1) +static void _sse_absr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define sse_negr_f(r0, r1) _sse_negr_f(_jit, r0, r1) +static void _sse_negr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define sse_negr_d(r0, r1) _sse_negr_d(_jit, r0, r1) +static void _sse_negr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define sse_sqrtr_f(r0, r1) ssexr(0xf3, X86_SSE_SQRT, r0, r1) +# define sse_sqrtr_d(r0, r1) ssexr(0xf2, X86_SSE_SQRT, r0, r1) +# define ssecmpf(code, r0, r1, r2) _ssecmp(_jit, 0, code, r0, r1, r2) +# define ssecmpd(code, r0, r1, r2) _ssecmp(_jit, 1, code, r0, r1, r2) +static void +_ssecmp(jit_state_t*, jit_bool_t, jit_int32_t, + jit_int32_t, jit_int32_t, jit_int32_t); +#define sse_movr_f(r0,r1) _sse_movr_f(_jit,r0,r1) +static void _sse_movr_f(jit_state_t*, jit_int32_t, jit_int32_t); +#define sse_movi_f(r0,i0) _sse_movi_f(_jit,r0,i0) +static void _sse_movi_f(jit_state_t*, jit_int32_t, jit_float32_t*); +# define sse_lti_f(r0, r1, i0) _sse_lti_f(_jit, r0, r1, i0) +static void _sse_lti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_ltr_f(r0, r1, r2) ssecmpf(X86_CC_A, r0, r1, r2) +# define sse_lei_f(r0, r1, i0) _sse_lei_f(_jit, r0, r1, i0) +static void _sse_lei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_ler_f(r0, r1, r2) ssecmpf(X86_CC_AE, r0, r1, r2) +# define sse_eqi_f(r0, r1, i0) _sse_eqi_f(_jit, r0, r1, i0) +static void _sse_eqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_eqr_f(r0, r1, r2) _sse_eqr_f(_jit, r0, r1, r2) +static void _sse_eqr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_gei_f(r0, r1, i0) _sse_gei_f(_jit, r0, r1, i0) +static void _sse_gei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_ger_f(r0, r1, r2) ssecmpf(X86_CC_AE, r0, r2, r1) +# define sse_gti_f(r0, r1, i0) _sse_gti_f(_jit, r0, r1, i0) +static void _sse_gti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_gtr_f(r0, r1, r2) ssecmpf(X86_CC_A, r0, r2, r1) +# define sse_nei_f(r0, r1, i0) _sse_nei_f(_jit, r0, r1, i0) +static void _sse_nei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_ner_f(r0, r1, r2) _sse_ner_f(_jit, r0, r1, r2) +static void _sse_ner_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_unlti_f(r0, r1, i0) _sse_unlti_f(_jit, r0, r1, i0) +static void _sse_unlti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_unltr_f(r0, r1, r2) ssecmpf(X86_CC_NAE, r0, r2, r1) +# define sse_unlei_f(r0, r1, i0) _sse_unlei_f(_jit, r0, r1, i0) +static void _sse_unlei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_unler_f(r0, r1, r2) _sse_unler_f(_jit, r0, r1, r2) +# define sse_uneqi_f(r0, r1, i0) _sse_uneqi_f(_jit, r0, r1, i0) +static void _sse_uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +static void _sse_unler_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_uneqr_f(r0, r1, r2) _sse_uneqr_f(_jit, r0, r1, r2) +static void _sse_uneqr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_ungei_f(r0, r1, i0) _sse_ungei_f(_jit, r0, r1, i0) +static void _sse_ungei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_unger_f(r0, r1, r2) _sse_unger_f(_jit, r0, r1, r2) +static void _sse_unger_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_ungti_f(r0, r1, i0) _sse_ungti_f(_jit, r0, r1, i0) +static void _sse_ungti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_ungtr_f(r0, r1, r2) ssecmpf(X86_CC_NAE, r0, r1, r2) +# define sse_ltgti_f(r0, r1, i0) _sse_ltgti_f(_jit, r0, r1, i0) +static void _sse_ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_ltgtr_f(r0, r1, r2) _sse_ltgtr_f(_jit, r0, r1, r2) +static void _sse_ltgtr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_ordi_f(r0, r1, i0) _sse_ordi_f(_jit, r0, r1, i0) +static void _sse_ordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_ordr_f(r0, r1, r2) ssecmpf(X86_CC_NP, r0, r2, r1) +# define sse_unordi_f(r0, r1, i0) _sse_unordi_f(_jit, r0, r1, i0) +static void _sse_unordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define sse_unordr_f(r0, r1, r2) ssecmpf(X86_CC_P, r0, r2, r1) +# define sse_ldr_f(r0, r1) movssmr(0, r1, _NOREG, _SCL1, r0) +# define sse_ldi_f(r0, i0) _sse_ldi_f(_jit, r0, i0) +static void _sse_ldi_f(jit_state_t*, jit_int32_t, jit_word_t); +# define sse_ldxr_f(r0, r1, r2) _sse_ldxr_f(_jit, r0, r1, r2) +static void _sse_ldxr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_ldxi_f(r0, r1, i0) _sse_ldxi_f(_jit, r0, r1, i0) +static void _sse_ldxi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define sse_str_f(r0, r1) movssrm(r1, 0, r0, _NOREG, _SCL1) +# define sse_sti_f(i0, r0) _sse_sti_f(_jit, i0, r0) +static void _sse_sti_f(jit_state_t*, jit_word_t,jit_int32_t); +# define sse_stxr_f(r0, r1, r2) _sse_stxr_f(_jit, r0, r1, r2) +static void _sse_stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define sse_stxi_f(i0, r0, r1) _sse_stxi_f(_jit, i0, r0, r1) +static void _sse_stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bltr_f(i0, r0, r1) _sse_bltr_f(_jit, i0, r0, r1) +static jit_word_t _sse_bltr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_blti_f(i0, r0, i1) _sse_blti_f(_jit, i0, r0, i1) +static jit_word_t +_sse_blti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define sse_bler_f(i0, r0, r1) _sse_bler_f(_jit, i0, r0, r1) +static jit_word_t _sse_bler_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_blei_f(i0, r0, i1) _sse_blei_f(_jit, i0, r0, i1) +static jit_word_t +_sse_blei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define sse_beqr_f(i0, r0, r1) _sse_beqr_f(_jit, i0, r0, r1) +static jit_word_t _sse_beqr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_beqi_f(i0, r0, i1) _sse_beqi_f(_jit, i0, r0, i1) +static jit_word_t +_sse_beqi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define sse_bger_f(i0, r0, r1) _sse_bger_f(_jit, i0, r0, r1) +static jit_word_t _sse_bger_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bgei_f(i0, r0, i1) _sse_bgei_f(_jit, i0, r0, i1) +static jit_word_t +_sse_bgei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define sse_bgtr_f(i0, r0, r1) _sse_bgtr_f(_jit, i0, r0, r1) +static jit_word_t _sse_bgtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bgti_f(i0, r0, i1) _sse_bgti_f(_jit, i0, r0, i1) +static jit_word_t +_sse_bgti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define sse_bner_f(i0, r0, r1) _sse_bner_f(_jit, i0, r0, r1) +static jit_word_t _sse_bner_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bnei_f(i0, r0, i1) _sse_bnei_f(_jit, i0, r0, i1) +static jit_word_t +_sse_bnei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define sse_bunltr_f(i0, r0, r1) _sse_bunltr_f(_jit, i0, r0, r1) +static jit_word_t _sse_bunltr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bunlti_f(i0, r0, i1) _sse_bunlti_f(_jit, i0, r0, i1) +static jit_word_t +_sse_bunlti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define sse_bunler_f(i0, r0, r1) _sse_bunler_f(_jit, i0, r0, r1) +static jit_word_t _sse_bunler_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bunlei_f(i0, r0, i1) _sse_bunlei_f(_jit, i0, r0, i1) +static jit_word_t +_sse_bunlei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define sse_buneqr_f(i0, r0, r1) _sse_buneqr_f(_jit, i0, r0, r1) +static jit_word_t _sse_buneqr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_buneqi_f(i0, r0, i1) _sse_buneqi_f(_jit, i0, r0, i1) +static jit_word_t +_sse_buneqi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define sse_bunger_f(i0, r0, r1) _sse_bunger_f(_jit, i0, r0, r1) +static jit_word_t _sse_bunger_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bungei_f(i0, r0, i1) _sse_bungei_f(_jit, i0, r0, i1) +static jit_word_t +_sse_bungei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define sse_bungtr_f(i0, r0, r1) _sse_bungtr_f(_jit, i0, r0, r1) +static jit_word_t _sse_bungtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bungti_f(i0, r0, i1) _sse_bungti_f(_jit, i0, r0, i1) +static jit_word_t +_sse_bungti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define sse_bltgtr_f(i0, r0, r1) _sse_bltgtr_f(_jit, i0, r0, r1) +static jit_word_t _sse_bltgtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bltgti_f(i0, r0, i1) _sse_bltgti_f(_jit, i0, r0, i1) +static jit_word_t +_sse_bltgti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define sse_bordr_f(i0, r0, r1) _sse_bordr_f(_jit, i0, r0, r1) +static jit_word_t _sse_bordr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bordi_f(i0, r0, i1) _sse_bordi_f(_jit, i0, r0, i1) +static jit_word_t +_sse_bordi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define sse_bunordr_f(i0, r0, r1) _sse_bunordr_f(_jit, i0, r0, r1) +static jit_word_t _sse_bunordr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bunordi_f(i0, r0, i1) _sse_bunordi_f(_jit, i0, r0, i1) +static jit_word_t +_sse_bunordi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +#define sse_movr_d(r0,r1) _sse_movr_d(_jit,r0,r1) +static void _sse_movr_d(jit_state_t*, jit_int32_t, jit_int32_t); +#define sse_movi_d(r0,i0) _sse_movi_d(_jit,r0,i0) +static void _sse_movi_d(jit_state_t*, jit_int32_t, jit_float64_t*); +# define sse_ltr_d(r0, r1, r2) ssecmpd(X86_CC_A, r0, r1, r2) +# define sse_lti_d(r0, r1, i0) _sse_lti_d(_jit, r0, r1, i0) +static void _sse_lti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_ler_d(r0, r1, r2) ssecmpd(X86_CC_AE, r0, r1, r2) +# define sse_lei_d(r0, r1, i0) _sse_lei_d(_jit, r0, r1, i0) +static void _sse_lei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_eqr_d(r0, r1, r2) _sse_eqr_d(_jit, r0, r1, r2) +static void _sse_eqr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_eqi_d(r0, r1, i0) _sse_eqi_d(_jit, r0, r1, i0) +static void _sse_eqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_ger_d(r0, r1, r2) ssecmpd(X86_CC_AE, r0, r2, r1) +# define sse_gei_d(r0, r1, i0) _sse_gei_d(_jit, r0, r1, i0) +static void _sse_gei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_gtr_d(r0, r1, r2) ssecmpd(X86_CC_A, r0, r2, r1) +# define sse_gti_d(r0, r1, i0) _sse_gti_d(_jit, r0, r1, i0) +static void _sse_gti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_ner_d(r0, r1, r2) _sse_ner_d(_jit, r0, r1, r2) +static void _sse_ner_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_nei_d(r0, r1, i0) _sse_nei_d(_jit, r0, r1, i0) +static void _sse_nei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_unltr_d(r0, r1, r2) ssecmpd(X86_CC_NAE, r0, r2, r1) +# define sse_unlti_d(r0, r1, i0) _sse_unlti_d(_jit, r0, r1, i0) +static void _sse_unlti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_unler_d(r0, r1, r2) _sse_unler_d(_jit, r0, r1, r2) +static void _sse_unler_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_unlei_d(r0, r1, i0) _sse_unlei_d(_jit, r0, r1, i0) +static void _sse_unlei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_uneqr_d(r0, r1, r2) _sse_uneqr_d(_jit, r0, r1, r2) +static void _sse_uneqr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_uneqi_d(r0, r1, i0) _sse_uneqi_d(_jit, r0, r1, i0) +static void _sse_uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_unger_d(r0, r1, r2) _sse_unger_d(_jit, r0, r1, r2) +static void _sse_unger_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_ungei_d(r0, r1, i0) _sse_ungei_d(_jit, r0, r1, i0) +static void _sse_ungei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_ungtr_d(r0, r1, r2) ssecmpd(X86_CC_NAE, r0, r1, r2) +# define sse_ungti_d(r0, r1, i0) _sse_ungti_d(_jit, r0, r1, i0) +static void _sse_ungti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_ltgtr_d(r0, r1, r2) _sse_ltgtr_d(_jit, r0, r1, r2) +static void _sse_ltgtr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_ltgti_d(r0, r1, i0) _sse_ltgti_d(_jit, r0, r1, i0) +static void _sse_ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_ordr_d(r0, r1, r2) ssecmpd(X86_CC_NP, r0, r2, r1) +# define sse_ordi_d(r0, r1, i0) _sse_ordi_d(_jit, r0, r1, i0) +static void _sse_ordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_unordr_d(r0, r1, r2) ssecmpd(X86_CC_P, r0, r2, r1) +# define sse_unordi_d(r0, r1, i0) _sse_unordi_d(_jit, r0, r1, i0) +static void _sse_unordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define sse_ldr_d(r0, r1) movsdmr(0, r1, _NOREG, _SCL1, r0) +# define sse_ldi_d(r0, i0) _sse_ldi_d(_jit, r0, i0) +static void _sse_ldi_d(jit_state_t*, jit_int32_t, jit_word_t); +# define sse_ldxr_d(r0, r1, r2) _sse_ldxr_d(_jit, r0, r1, r2) +static void _sse_ldxr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define sse_ldxi_d(r0, r1, i0) _sse_ldxi_d(_jit, r0, r1, i0) +static void _sse_ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define sse_bltr_d(i0, r0, r1) _sse_bltr_d(_jit, i0, r0, r1) +# define sse_str_d(r0, r1) movsdrm(r1, 0, r0, _NOREG, _SCL1) +# define sse_sti_d(i0, r0) _sse_sti_d(_jit, i0, r0) +static void _sse_sti_d(jit_state_t*, jit_word_t,jit_int32_t); +# define sse_stxr_d(r0, r1, r2) _sse_stxr_d(_jit, r0, r1, r2) +static void _sse_stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define sse_stxi_d(i0, r0, r1) _sse_stxi_d(_jit, i0, r0, r1) +static void _sse_stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +static jit_word_t _sse_bltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_blti_d(i0, r0, i1) _sse_blti_d(_jit, i0, r0, i1) +static jit_word_t +_sse_blti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define sse_bler_d(i0, r0, r1) _sse_bler_d(_jit, i0, r0, r1) +static jit_word_t _sse_bler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_blei_d(i0, r0, i1) _sse_blei_d(_jit, i0, r0, i1) +static jit_word_t +_sse_blei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define sse_beqr_d(i0, r0, r1) _sse_beqr_d(_jit, i0, r0, r1) +static jit_word_t _sse_beqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_beqi_d(i0, r0, i1) _sse_beqi_d(_jit, i0, r0, i1) +static jit_word_t +_sse_beqi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define sse_bger_d(i0, r0, r1) _sse_bger_d(_jit, i0, r0, r1) +static jit_word_t _sse_bger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bgei_d(i0, r0, i1) _sse_bgei_d(_jit, i0, r0, i1) +static jit_word_t +_sse_bgei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define sse_bgtr_d(i0, r0, r1) _sse_bgtr_d(_jit, i0, r0, r1) +static jit_word_t _sse_bgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bgti_d(i0, r0, i1) _sse_bgti_d(_jit, i0, r0, i1) +static jit_word_t +_sse_bgti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define sse_bner_d(i0, r0, r1) _sse_bner_d(_jit, i0, r0, r1) +static jit_word_t _sse_bner_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bnei_d(i0, r0, i1) _sse_bnei_d(_jit, i0, r0, i1) +static jit_word_t +_sse_bnei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define sse_bunltr_d(i0, r0, r1) _sse_bunltr_d(_jit, i0, r0, r1) +static jit_word_t _sse_bunltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bunlti_d(i0, r0, i1) _sse_bunlti_d(_jit, i0, r0, i1) +static jit_word_t +_sse_bunlti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define sse_bunler_d(i0, r0, r1) _sse_bunler_d(_jit, i0, r0, r1) +static jit_word_t _sse_bunler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bunlei_d(i0, r0, i1) _sse_bunlei_d(_jit, i0, r0, i1) +static jit_word_t +_sse_bunlei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define sse_buneqr_d(i0, r0, r1) _sse_buneqr_d(_jit, i0, r0, r1) +static jit_word_t _sse_buneqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_buneqi_d(i0, r0, i1) _sse_buneqi_d(_jit, i0, r0, i1) +static jit_word_t +_sse_buneqi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define sse_bunger_d(i0, r0, r1) _sse_bunger_d(_jit, i0, r0, r1) +static jit_word_t _sse_bunger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bungei_d(i0, r0, i1) _sse_bungei_d(_jit, i0, r0, i1) +static jit_word_t +_sse_bungei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define sse_bungtr_d(i0, r0, r1) _sse_bungtr_d(_jit, i0, r0, r1) +static jit_word_t _sse_bungtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bungti_d(i0, r0, i1) _sse_bungti_d(_jit, i0, r0, i1) +static jit_word_t +_sse_bungti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define sse_bltgtr_d(i0, r0, r1) _sse_bltgtr_d(_jit, i0, r0, r1) +static jit_word_t _sse_bltgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bltgti_d(i0, r0, i1) _sse_bltgti_d(_jit, i0, r0, i1) +static jit_word_t +_sse_bltgti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define sse_bordr_d(i0, r0, r1) _sse_bordr_d(_jit, i0, r0, r1) +static jit_word_t _sse_bordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bordi_d(i0, r0, i1) _sse_bordi_d(_jit, i0, r0, i1) +static jit_word_t +_sse_bordi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define sse_bunordr_d(i0, r0, r1) _sse_bunordr_d(_jit, i0, r0, r1) +static jit_word_t _sse_bunordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define sse_bunordi_d(i0, r0, i1) _sse_bunordi_d(_jit, i0, r0, i1) +static jit_word_t +_sse_bunordi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +#endif + +#if CODE +# define fpr_opi(name, type, size) \ +static void \ +_sse_##name##i_##type(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, \ + jit_float##size##_t *i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr|jit_class_xpr); \ + assert(jit_sse_reg_p(reg)); \ + sse_movi_##type(rn(reg), i0); \ + sse_##name##r_##type(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +# define fpr_bopi(name, type, size) \ +static jit_word_t \ +_sse_b##name##i_##type(jit_state_t *_jit, \ + jit_word_t i0, jit_int32_t r0, \ + jit_float##size##_t *i1) \ +{ \ + jit_word_t word; \ + jit_int32_t reg = jit_get_reg(jit_class_fpr|jit_class_xpr| \ + jit_class_nospill); \ + assert(jit_sse_reg_p(reg)); \ + sse_movi_##type(rn(reg), i1); \ + word = sse_b##name##r_##type(i0, r0, rn(reg)); \ + jit_unget_reg(reg); \ + return (word); \ +} +# define fopi(name) fpr_opi(name, f, 32) +# define fbopi(name) fpr_bopi(name, f, 32) +# define dopi(name) fpr_opi(name, d, 64) +# define dbopi(name) fpr_bopi(name, d, 64) +static void +_sser(jit_state_t *_jit, jit_int32_t c, jit_int32_t r0, jit_int32_t r1) +{ + rex(0, 0, r0, 0, r1); + ic(0x0f); + ic(c); + mrm(0x03, r7(r0), r7(r1)); +} + +static void +_ssexr(jit_state_t *_jit, jit_int32_t p, jit_int32_t c, + jit_int32_t r0, jit_int32_t r1) +{ + ic(p); + rex(0, 0, r0, 0, r1); + ic(0x0f); + ic(c); + mrm(0x03, r7(r0), r7(r1)); +} + +static void +_ssexi(jit_state_t *_jit, jit_int32_t c, jit_int32_t r0, + jit_int32_t m, jit_int32_t i) +{ + ic(0x66); + rex(0, 0, 0, 0, r0); + ic(0x0f); + ic(c); + mrm(0x03, r7(m), r7(r0)); + ic(i); +} + +#if __X64 +static void +_sselxr(jit_state_t *_jit, jit_int32_t p, jit_int32_t c, + jit_int32_t r0, jit_int32_t r1) +{ + ic(p); + rex(0, 1, r0, 0, r1); + ic(0x0f); + ic(c); + mrm(0x03, r7(r0), r7(r1)); +} +#endif + +static void +_ssexrx(jit_state_t *_jit, jit_int32_t px, jit_int32_t code, jit_int32_t md, + jit_int32_t rb, jit_int32_t ri, jit_int32_t ms, jit_int32_t rd) +{ + ic(px); + rex(0, 0, rd, ri, rb); + ic(0x0f); + ic(code); + rx(rd, md, rb, ri, ms); +} + +static void +_sse_addr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r1) + addssr(r0, r2); + else if (r0 == r2) + addssr(r0, r1); + else { + sse_movr_f(r0, r1); + addssr(r0, r2); + } +} + +fopi(add) + +static void +_sse_addr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r1) + addsdr(r0, r2); + else if (r0 == r2) + addsdr(r0, r1); + else { + sse_movr_d(r0, r1); + addsdr(r0, r2); + } +} + +dopi(add) + +static void +_sse_subr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r1) + subssr(r0, r2); + else if (r0 == r2) { + reg = jit_get_reg(jit_class_fpr|jit_class_xpr); + sse_movr_f(rn(reg), r0); + sse_movr_f(r0, r1); + subssr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + sse_movr_f(r0, r1); + subssr(r0, r2); + } +} + +fopi(sub) + +static void +_sse_subr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r1) + subsdr(r0, r2); + else if (r0 == r2) { + reg = jit_get_reg(jit_class_fpr|jit_class_xpr); + sse_movr_d(rn(reg), r0); + sse_movr_d(r0, r1); + subsdr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + sse_movr_d(r0, r1); + subsdr(r0, r2); + } +} + +dopi(sub) + +fopi(rsb) + +dopi(rsb) + +static void +_sse_mulr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r1) + mulssr(r0, r2); + else if (r0 == r2) + mulssr(r0, r1); + else { + sse_movr_f(r0, r1); + mulssr(r0, r2); + } +} + +fopi(mul) + +static void +_sse_mulr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r1) + mulsdr(r0, r2); + else if (r0 == r2) + mulsdr(r0, r1); + else { + sse_movr_d(r0, r1); + mulsdr(r0, r2); + } +} + +dopi(mul) + +static void +_sse_divr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r1) + divssr(r0, r2); + else if (r0 == r2) { + reg = jit_get_reg(jit_class_fpr|jit_class_xpr); + sse_movr_f(rn(reg), r0); + sse_movr_f(r0, r1); + divssr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + sse_movr_f(r0, r1); + divssr(r0, r2); + } +} + +fopi(div) + +static void +_sse_divr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r1) + divsdr(r0, r2); + else if (r0 == r2) { + reg = jit_get_reg(jit_class_fpr|jit_class_xpr); + sse_movr_d(rn(reg), r0); + sse_movr_d(r0, r1); + divsdr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + sse_movr_d(r0, r1); + divsdr(r0, r2); + } +} + +dopi(div) + +static void +_sse_absr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (r0 == r1) { + reg = jit_get_reg(jit_class_fpr|jit_class_xpr); + pcmpeqlr(rn(reg), rn(reg)); + psrl(rn(reg), 1); + andpsr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + pcmpeqlr(r0, r0); + psrl(r0, 1); + andpsr(r0, r1); + } +} + +static void +_sse_absr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (r0 == r1) { + reg = jit_get_reg(jit_class_fpr|jit_class_xpr); + pcmpeqlr(rn(reg), rn(reg)); + psrq(rn(reg), 1); + andpdr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + pcmpeqlr(r0, r0); + psrq(r0, 1); + andpdr(r0, r1); + } +} + +static void +_sse_negr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t freg, ireg; + ireg = jit_get_reg(jit_class_gpr); + imovi(rn(ireg), 0x80000000); + if (r0 == r1) { + freg = jit_get_reg(jit_class_fpr|jit_class_xpr); + movdlxr(rn(freg), rn(ireg)); + xorpsr(r0, rn(freg)); + jit_unget_reg(freg); + } + else { + movdlxr(r0, rn(ireg)); + xorpsr(r0, r1); + } + jit_unget_reg(ireg); +} + +static void +_sse_negr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t freg, ireg; + ireg = jit_get_reg(jit_class_gpr); + imovi(rn(ireg), 0x80000000); + if (r0 == r1) { + freg = jit_get_reg(jit_class_fpr|jit_class_xpr); + movdlxr(rn(freg), rn(ireg)); + pslq(rn(freg), 32); + xorpdr(r0, rn(freg)); + jit_unget_reg(freg); + } + else { + movdlxr(r0, rn(ireg)); + pslq(r0, 32); + xorpdr(r0, r1); + } + jit_unget_reg(ireg); +} + +static void +_ssecmp(jit_state_t *_jit, jit_bool_t d, jit_int32_t code, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_bool_t rc; + jit_int32_t reg; + if ((rc = reg8_p(r0))) + reg = r0; + else { + reg = _RAX_REGNO; + movr(r0, reg); + } + ixorr(reg, reg); + if (d) + ucomisdr(r2, r1); + else + ucomissr(r2, r1); + cc(code, reg); + if (!rc) + xchgr(r0, reg); +} + +static void +_sse_movr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + ssexr(0xf3, X86_SSE_MOV, r0, r1); +} + +static void +_sse_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_int32_t reg; + jit_bool_t ldi; + + data.f = *i0; + if (data.f == 0.0 && !(data.i & 0x80000000)) + xorpsr(r0, r0); + else { + ldi = !_jitc->no_data; +#if __X64 + /* if will allocate a register for offset, just use immediate */ + if (ldi && !sse_address_p(i0)) + ldi = 0; +#endif + if (ldi) + sse_ldi_f(r0, (jit_word_t)i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.i); + movdlxr(r0, rn(reg)); + jit_unget_reg(reg); + } + } +} + +fopi(lt) +fopi(le) + +static void +_sse_eqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_bool_t rc; + jit_int32_t reg; + jit_word_t jp_code; + if ((rc = reg8_p(r0))) + reg = r0; + else { + reg = _RAX_REGNO; + movr(r0, _RAX_REGNO); + } + ixorr(reg, reg); + ucomissr(r2, r1); + jpes(0); + jp_code = _jit->pc.w; + cc(X86_CC_E, reg); + patch_rel_char(jp_code, _jit->pc.w); + if (!rc) + xchgr(r0, reg); +} + +fopi(eq) +fopi(ge) +fopi(gt) + +static void +_sse_ner_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_bool_t rc; + jit_int32_t reg; + jit_word_t jp_code; + if ((rc = reg8_p(r0))) + reg = r0; + else { + reg = _RAX_REGNO; + movr(r0, _RAX_REGNO); + } + imovi(reg, 1); + ucomissr(r2, r1); + jpes(0); + jp_code = _jit->pc.w; + cc(X86_CC_NE, reg); + patch_rel_char(jp_code, _jit->pc.w); + if (!rc) + xchgr(r0, reg); +} + +fopi(ne) +fopi(unlt) + +static void +_sse_unler_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 1); + else + ssecmpf(X86_CC_NA, r0, r2, r1); +} + +fopi(unle) + +static void +_sse_uneqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 1); + else + ssecmpf(X86_CC_E, r0, r1, r2); +} + +fopi(uneq) + +static void +_sse_unger_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 1); + else + ssecmpf(X86_CC_NA, r0, r1, r2); +} + +fopi(unge) +fopi(ungt) + +static void +_sse_ltgtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + ixorr(r0, r0); + else + ssecmpf(X86_CC_NE, r0, r1, r2); +} + +fopi(ltgt) +fopi(ord) +fopi(unord) + +static void +_sse_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (sse_address_p(i0)) + movssmr(i0, _NOREG, _NOREG, _SCL1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + sse_ldr_f(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sse_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + sse_ldr_f(r0, rn(reg)); + jit_unget_reg(reg); +#else + movssmr(0, r1, r2, _SCL1, r0); +#endif +} + +static void +_sse_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) + movssmr(i0, r1, _NOREG, _SCL1, r0); + else { + reg = jit_get_reg(jit_class_gpr); +#if __X64_32 + addi(rn(reg), r1, i0); + sse_ldr_f(r0, rn(reg)); +#else + movi(rn(reg), i0); + sse_ldxr_f(r0, r1, rn(reg)); +#endif + jit_unget_reg(reg); + } +} + +static void +_sse_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (sse_address_p(i0)) + movssrm(r0, i0, _NOREG, _NOREG, _SCL1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + sse_str_f(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sse_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + sse_str_f(rn(reg), r2); + jit_unget_reg(reg); +#else + movssrm(r2, 0, r0, r1, _SCL1); +#endif +} + +static void +_sse_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) + movssrm(r1, i0, r0, _NOREG, _SCL1); + else { + reg = jit_get_reg(jit_class_gpr); +#if __X64_32 + addi(rn(reg), r0, i0); + sse_str_f(rn(reg), r1); +#else + movi(rn(reg), i0); + sse_stxr_f(rn(reg), r0, r1); +#endif + jit_unget_reg(reg); + } +} + +static jit_word_t +_sse_bltr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomissr(r1, r0); + ja(i0); + return (_jit->pc.w); +} +fbopi(lt) + +static jit_word_t +_sse_bler_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomissr(r1, r0); + jae(i0); + return (_jit->pc.w); +} +fbopi(le) + +static jit_word_t +_sse_beqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t jp_code; + ucomissr(r0, r1); + jps(0); + jp_code = _jit->pc.w; + je(i0); + patch_rel_char(jp_code, _jit->pc.w); + return (_jit->pc.w); +} +fbopi(eq) + +static jit_word_t +_sse_bger_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomissr(r0, r1); + jae(i0); + return (_jit->pc.w); +} +fbopi(ge) + +static jit_word_t +_sse_bgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomissr(r0, r1); + ja(i0); + return (_jit->pc.w); +} +fbopi(gt) + +static jit_word_t +_sse_bner_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t jp_code; + jit_word_t jz_code; + ucomissr(r0, r1); + jps(0); + jp_code = _jit->pc.w; + jzs(0); + jz_code = _jit->pc.w; + patch_rel_char(jp_code, _jit->pc.w); + jmpi(i0); + patch_rel_char(jz_code, _jit->pc.w); + return (_jit->pc.w); +} +fbopi(ne) + +static jit_word_t +_sse_bunltr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomissr(r0, r1); + jnae(i0); + return (_jit->pc.w); +} +fbopi(unlt) + +static jit_word_t +_sse_bunler_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) + jmpi(i0); + else { + ucomissr(r0, r1); + jna(i0); + } + return (_jit->pc.w); +} +fbopi(unle) + +static jit_word_t +_sse_buneqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) + jmpi(i0); + else { + ucomissr(r0, r1); + je(i0); + } + return (_jit->pc.w); +} +fbopi(uneq) + +static jit_word_t +_sse_bunger_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) + jmpi(i0); + else { + ucomissr(r1, r0); + jna(i0); + } + return (_jit->pc.w); +} +fbopi(unge) + +static jit_word_t +_sse_bungtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomissr(r1, r0); + jnae(i0); + return (_jit->pc.w); +} +fbopi(ungt) + +static jit_word_t +_sse_bltgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomissr(r0, r1); + jne(i0); + return (_jit->pc.w); +} +fbopi(ltgt) + +static jit_word_t +_sse_bordr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomissr(r0, r1); + jnp(i0); + return (_jit->pc.w); +} +fbopi(ord) + +static jit_word_t +_sse_bunordr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomissr(r0, r1); + jp(i0); + return (_jit->pc.w); +} +fbopi(unord) + +dopi(lt) +dopi(le) + +static void +_sse_eqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_bool_t rc; + jit_int32_t reg; + jit_word_t jp_code; + if ((rc = reg8_p(r0))) + reg = r0; + else { + reg = _RAX_REGNO; + movr(r0, _RAX_REGNO); + } + ixorr(reg, reg); + ucomisdr(r2, r1); + jpes(0); + jp_code = _jit->pc.w; + cc(X86_CC_E, reg); + patch_rel_char(jp_code, _jit->pc.w); + if (!rc) + xchgr(r0, reg); +} + +dopi(eq) +dopi(ge) +dopi(gt) + +static void +_sse_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_bool_t rc; + jit_int32_t reg; + jit_word_t jp_code; + if ((rc = reg8_p(r0))) + reg = r0; + else { + reg = _RAX_REGNO; + movr(r0, _RAX_REGNO); + } + imovi(reg, 1); + ucomisdr(r2, r1); + jpes(0); + jp_code = _jit->pc.w; + cc(X86_CC_NE, reg); + patch_rel_char(jp_code, _jit->pc.w); + if (!rc) + xchgr(r0, reg); +} + +dopi(ne) +dopi(unlt) + +static void +_sse_unler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 1); + else + ssecmpd(X86_CC_NA, r0, r2, r1); +} + +dopi(unle) + +static void +_sse_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 1); + else + ssecmpd(X86_CC_E, r0, r1, r2); +} + +dopi(uneq) + +static void +_sse_unger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 1); + else + ssecmpd(X86_CC_NA, r0, r1, r2); +} + +dopi(unge) +dopi(ungt) + +static void +_sse_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + ixorr(r0, r0); + else + ssecmpd(X86_CC_NE, r0, r1, r2); +} + +dopi(ltgt) +dopi(ord) +dopi(unord) + +static void +_sse_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + ssexr(0xf2, X86_SSE_MOV, r0, r1); +} + +static void +_sse_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + union { + jit_int32_t ii[2]; + jit_word_t w; + jit_float64_t d; + } data; + jit_int32_t reg; + jit_bool_t ldi; + + data.d = *i0; + if (data.d == 0.0 && !(data.ii[1] & 0x80000000)) + xorpdr(r0, r0); + else { + ldi = !_jitc->no_data; +#if __X64 + /* if will allocate a register for offset, just use immediate */ + if (ldi && !sse_address_p(i0)) + ldi = 0; +#endif + if (ldi) + sse_ldi_d(r0, (jit_word_t)i0); + else { + reg = jit_get_reg(jit_class_gpr); +#if __X64 && !__X64_32 + movi(rn(reg), data.w); + movdqxr(r0, rn(reg)); + jit_unget_reg(reg); +#else + movi(rn(reg), data.ii[0]); + stxi_i(CVT_OFFSET, _RBP_REGNO, rn(reg)); + movi(rn(reg), data.ii[1]); + stxi_i(CVT_OFFSET + 4, _RBP_REGNO, rn(reg)); + jit_unget_reg(reg); + sse_ldxi_d(r0, _RBP_REGNO, CVT_OFFSET); +#endif + } + } +} + +static void +_sse_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (sse_address_p(i0)) + movsdmr(i0, _NOREG, _NOREG, _SCL1, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + sse_ldr_d(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sse_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + sse_ldr_d(r0, rn(reg)); + jit_unget_reg(reg); +#else + movsdmr(0, r1, r2, _SCL1, r0); +#endif +} + +static void +_sse_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) + movsdmr(i0, r1, _NOREG, _SCL1, r0); + else { + reg = jit_get_reg(jit_class_gpr); +#if __X64_32 + addi(rn(reg), r1, i0); + sse_ldr_d(r0, rn(reg)); +#else + movi(rn(reg), i0); + sse_ldxr_d(r0, r1, rn(reg)); +#endif + jit_unget_reg(reg); + } +} + +static void +_sse_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (sse_address_p(i0)) + movsdrm(r0, i0, _NOREG, _NOREG, _SCL1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + sse_str_d(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sse_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + sse_str_d(rn(reg), r2); + jit_unget_reg(reg); +#else + movsdrm(r2, 0, r0, r1, _SCL1); +#endif +} + +static void +_sse_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) + movsdrm(r1, i0, r0, _NOREG, _SCL1); + else { + reg = jit_get_reg(jit_class_gpr); +#if __X64_32 + addi(rn(reg), r0, i0); + sse_str_d(rn(reg), r1); +#else + movi(rn(reg), i0); + sse_stxr_f(rn(reg), r0, r1); +#endif + jit_unget_reg(reg); + } +} + +static jit_word_t +_sse_bltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomisdr(r1, r0); + ja(i0); + return (_jit->pc.w); +} +dbopi(lt) + +static jit_word_t +_sse_bler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomisdr(r1, r0); + jae(i0); + return (_jit->pc.w); +} +dbopi(le) + +static jit_word_t +_sse_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t jp_code; + ucomisdr(r0, r1); + jps(0); + jp_code = _jit->pc.w; + je(i0); + patch_rel_char(jp_code, _jit->pc.w); + return (_jit->pc.w); +} +dbopi(eq) + +static jit_word_t +_sse_bger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomisdr(r0, r1); + jae(i0); + return (_jit->pc.w); +} +dbopi(ge) + +static jit_word_t +_sse_bgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomisdr(r0, r1); + ja(i0); + return (_jit->pc.w); +} +dbopi(gt) + +static jit_word_t +_sse_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t jp_code; + jit_word_t jz_code; + ucomisdr(r0, r1); + jps(0); + jp_code = _jit->pc.w; + jzs(0); + jz_code = _jit->pc.w; + patch_rel_char(jp_code, _jit->pc.w); + jmpi(i0); + patch_rel_char(jz_code, _jit->pc.w); + return (_jit->pc.w); +} +dbopi(ne) + +static jit_word_t +_sse_bunltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomisdr(r0, r1); + jnae(i0); + return (_jit->pc.w); +} +dbopi(unlt) + +static jit_word_t +_sse_bunler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) + jmpi(i0); + else { + ucomisdr(r0, r1); + jna(i0); + } + return (_jit->pc.w); +} +dbopi(unle) + +static jit_word_t +_sse_buneqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) + jmpi(i0); + else { + ucomisdr(r0, r1); + je(i0); + } + return (_jit->pc.w); +} +dbopi(uneq) + +static jit_word_t +_sse_bunger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) + jmpi(i0); + else { + ucomisdr(r1, r0); + jna(i0); + } + return (_jit->pc.w); +} +dbopi(unge) + +static jit_word_t +_sse_bungtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomisdr(r1, r0); + jnae(i0); + return (_jit->pc.w); +} +dbopi(ungt) + +static jit_word_t +_sse_bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomisdr(r0, r1); + jne(i0); + return (_jit->pc.w); +} +dbopi(ltgt) + +static jit_word_t +_sse_bordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomisdr(r0, r1); + jnp(i0); + return (_jit->pc.w); +} +dbopi(ord) + +static jit_word_t +_sse_bunordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + ucomisdr(r0, r1); + jp(i0); + return (_jit->pc.w); +} +dbopi(unord) +# undef fopi +# undef fbopi +# undef bopi +# undef dbopi +# undef fpr_bopi +# undef fpr_opi +#endif diff --git a/deps/lightning/lib/jit_x86-sz.c b/deps/lightning/lib/jit_x86-sz.c new file mode 100644 index 0000000..663b840 --- /dev/null +++ b/deps/lightning/lib/jit_x86-sz.c @@ -0,0 +1,1610 @@ + +#if __X32 +#define JIT_INSTR_MAX 42 + 0, /* data */ + 0, /* live */ + 3, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 3, /* label */ + 34, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 3, /* va_start */ + 5, /* va_arg */ + 7, /* va_arg_d */ + 0, /* va_end */ + 3, /* addr */ + 6, /* addi */ + 4, /* addcr */ + 6, /* addci */ + 4, /* addxr */ + 5, /* addxi */ + 4, /* subr */ + 6, /* subi */ + 6, /* subcr */ + 6, /* subci */ + 6, /* subxr */ + 5, /* subxi */ + 8, /* rsbi */ + 5, /* mulr */ + 7, /* muli */ + 20, /* qmulr */ + 25, /* qmuli */ + 20, /* qmulr_u */ + 25, /* qmuli_u */ + 21, /* divr */ + 24, /* divi */ + 22, /* divr_u */ + 25, /* divi_u */ + 23, /* qdivr */ + 26, /* qdivi */ + 24, /* qdivr_u */ + 27, /* qdivi_u */ + 21, /* remr */ + 24, /* remi */ + 22, /* remr_u */ + 25, /* remi_u */ + 4, /* andr */ + 7, /* andi */ + 4, /* orr */ + 8, /* ori */ + 4, /* xorr */ + 8, /* xori */ + 16, /* lshr */ + 7, /* lshi */ + 16, /* rshr */ + 5, /* rshi */ + 16, /* rshr_u */ + 5, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 15, /* ltr */ + 16, /* lti */ + 15, /* ltr_u */ + 16, /* lti_u */ + 15, /* ler */ + 16, /* lei */ + 15, /* ler_u */ + 16, /* lei_u */ + 15, /* eqr */ + 16, /* eqi */ + 15, /* ger */ + 16, /* gei */ + 15, /* ger_u */ + 16, /* gei_u */ + 15, /* gtr */ + 16, /* gti */ + 15, /* gtr_u */ + 16, /* gti_u */ + 15, /* ner */ + 16, /* nei */ + 2, /* movr */ + 5, /* movi */ + 11, /* extr_c */ + 11, /* extr_uc */ + 3, /* extr_s */ + 3, /* extr_us */ + 0, /* extr_i */ + 0, /* extr_ui */ + 7, /* htonr_us */ + 4, /* htonr_ui */ + 0, /* htonr_ul */ + 3, /* ldr_c */ + 7, /* ldi_c */ + 3, /* ldr_uc */ + 7, /* ldi_uc */ + 3, /* ldr_s */ + 7, /* ldi_s */ + 3, /* ldr_us */ + 7, /* ldi_us */ + 2, /* ldr_i */ + 6, /* ldi_i */ + 0, /* ldr_ui */ + 0, /* ldi_ui */ + 0, /* ldr_l */ + 0, /* ldi_l */ + 4, /* ldxr_c */ + 7, /* ldxi_c */ + 4, /* ldxr_uc */ + 7, /* ldxi_uc */ + 4, /* ldxr_s */ + 7, /* ldxi_s */ + 4, /* ldxr_us */ + 7, /* ldxi_us */ + 3, /* ldxr_i */ + 6, /* ldxi_i */ + 0, /* ldxr_ui */ + 0, /* ldxi_ui */ + 0, /* ldxr_l */ + 0, /* ldxi_l */ + 10, /* str_c */ + 14, /* sti_c */ + 3, /* str_s */ + 7, /* sti_s */ + 2, /* str_i */ + 6, /* sti_i */ + 0, /* str_l */ + 0, /* sti_l */ + 11, /* stxr_c */ + 11, /* stxi_c */ + 4, /* stxr_s */ + 7, /* stxi_s */ + 3, /* stxr_i */ + 6, /* stxi_i */ + 0, /* stxr_l */ + 0, /* stxi_l */ + 8, /* bltr */ + 9, /* blti */ + 8, /* bltr_u */ + 9, /* blti_u */ + 8, /* bler */ + 12, /* blei */ + 8, /* bler_u */ + 9, /* blei_u */ + 8, /* beqr */ + 12, /* beqi */ + 8, /* bger */ + 9, /* bgei */ + 8, /* bger_u */ + 9, /* bgei_u */ + 8, /* bgtr */ + 9, /* bgti */ + 8, /* bgtr_u */ + 9, /* bgti_u */ + 8, /* bner */ + 12, /* bnei */ + 8, /* bmsr */ + 12, /* bmsi */ + 8, /* bmcr */ + 12, /* bmci */ + 8, /* boaddr */ + 9, /* boaddi */ + 8, /* boaddr_u */ + 9, /* boaddi_u */ + 8, /* bxaddr */ + 9, /* bxaddi */ + 8, /* bxaddr_u */ + 9, /* bxaddi_u */ + 8, /* bosubr */ + 9, /* bosubi */ + 8, /* bosubr_u */ + 9, /* bosubi_u */ + 8, /* bxsubr */ + 9, /* bxsubi */ + 8, /* bxsubr_u */ + 9, /* bxsubi_u */ + 2, /* jmpr */ + 5, /* jmpi */ + 2, /* callr */ + 5, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 24, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 8, /* addr_f */ + 19, /* addi_f */ + 12, /* subr_f */ + 19, /* subi_f */ + 21, /* rsbi_f */ + 8, /* mulr_f */ + 19, /* muli_f */ + 12, /* divr_f */ + 19, /* divi_f */ + 12, /* negr_f */ + 12, /* absr_f */ + 6, /* sqrtr_f */ + 13, /* ltr_f */ + 27, /* lti_f */ + 13, /* ler_f */ + 27, /* lei_f */ + 15, /* eqr_f */ + 29, /* eqi_f */ + 13, /* ger_f */ + 27, /* gei_f */ + 13, /* gtr_f */ + 27, /* gti_f */ + 18, /* ner_f */ + 32, /* nei_f */ + 13, /* unltr_f */ + 27, /* unlti_f */ + 13, /* unler_f */ + 27, /* unlei_f */ + 13, /* uneqr_f */ + 27, /* uneqi_f */ + 13, /* unger_f */ + 27, /* ungei_f */ + 13, /* ungtr_f */ + 27, /* ungti_f */ + 13, /* ltgtr_f */ + 27, /* ltgti_f */ + 13, /* ordr_f */ + 27, /* ordi_f */ + 13, /* unordr_f */ + 27, /* unordi_f */ + 8, /* truncr_f_i */ + 0, /* truncr_f_l */ + 8, /* extr_f */ + 4, /* extr_d_f */ + 10, /* movr_f */ + 19, /* movi_f */ + 4, /* ldr_f */ + 8, /* ldi_f */ + 5, /* ldxr_f */ + 8, /* ldxi_f */ + 6, /* str_f */ + 10, /* sti_f */ + 7, /* stxr_f */ + 8, /* stxi_f */ + 10, /* bltr_f */ + 23, /* blti_f */ + 10, /* bler_f */ + 23, /* blei_f */ + 12, /* beqr_f */ + 25, /* beqi_f */ + 10, /* bger_f */ + 23, /* bgei_f */ + 10, /* bgtr_f */ + 23, /* bgti_f */ + 13, /* bner_f */ + 26, /* bnei_f */ + 10, /* bunltr_f */ + 23, /* bunlti_f */ + 10, /* bunler_f */ + 23, /* bunlei_f */ + 10, /* buneqr_f */ + 23, /* buneqi_f */ + 10, /* bunger_f */ + 23, /* bungei_f */ + 10, /* bungtr_f */ + 23, /* bungti_f */ + 10, /* bltgtr_f */ + 23, /* bltgti_f */ + 10, /* bordr_f */ + 23, /* bordi_f */ + 10, /* bunordr_f */ + 23, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 10, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 8, /* addr_d */ + 26, /* addi_d */ + 12, /* subr_d */ + 26, /* subi_d */ + 30, /* rsbi_d */ + 8, /* mulr_d */ + 26, /* muli_d */ + 12, /* divr_d */ + 26, /* divi_d */ + 18, /* negr_d */ + 13, /* absr_d */ + 6, /* sqrtr_d */ + 13, /* ltr_d */ + 37, /* lti_d */ + 13, /* ler_d */ + 37, /* lei_d */ + 15, /* eqr_d */ + 39, /* eqi_d */ + 13, /* ger_d */ + 37, /* gei_d */ + 13, /* gtr_d */ + 37, /* gti_d */ + 18, /* ner_d */ + 42, /* nei_d */ + 13, /* unltr_d */ + 37, /* unlti_d */ + 13, /* unler_d */ + 37, /* unlei_d */ + 13, /* uneqr_d */ + 37, /* uneqi_d */ + 13, /* unger_d */ + 37, /* ungei_d */ + 13, /* ungtr_d */ + 37, /* ungti_d */ + 13, /* ltgtr_d */ + 37, /* ltgti_d */ + 13, /* ordr_d */ + 37, /* ordi_d */ + 13, /* unordr_d */ + 37, /* unordi_d */ + 8, /* truncr_d_i */ + 0, /* truncr_d_l */ + 8, /* extr_d */ + 4, /* extr_f_d */ + 10, /* movr_d */ + 24, /* movi_d */ + 4, /* ldr_d */ + 8, /* ldi_d */ + 5, /* ldxr_d */ + 8, /* ldxi_d */ + 6, /* str_d */ + 10, /* sti_d */ + 7, /* stxr_d */ + 8, /* stxi_d */ + 10, /* bltr_d */ + 28, /* blti_d */ + 10, /* bler_d */ + 28, /* blei_d */ + 12, /* beqr_d */ + 30, /* beqi_d */ + 10, /* bger_d */ + 28, /* bgei_d */ + 10, /* bgtr_d */ + 28, /* bgti_d */ + 13, /* bner_d */ + 31, /* bnei_d */ + 10, /* bunltr_d */ + 28, /* bunlti_d */ + 10, /* bunler_d */ + 28, /* bunlei_d */ + 10, /* buneqr_d */ + 28, /* buneqi_d */ + 10, /* bunger_d */ + 28, /* bungei_d */ + 10, /* bungtr_d */ + 28, /* bungti_d */ + 10, /* bltgtr_d */ + 28, /* bltgti_d */ + 10, /* bordr_d */ + 28, /* bordi_d */ + 10, /* bunordr_d */ + 28, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 10, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif + +#if __X64 +#if __CYGWIN__ || _WIN32 +#define JIT_INSTR_MAX 130 + 0, /* data */ + 0, /* live */ + 6, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 7, /* label */ + 130, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 7, /* va_start */ + 7, /* va_arg */ + 9, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 13, /* addi */ + 6, /* addcr */ + 13, /* addci */ + 6, /* addxr */ + 7, /* addxi */ + 6, /* subr */ + 13, /* subi */ + 9, /* subcr */ + 13, /* subci */ + 9, /* subxr */ + 7, /* subxi */ + 16, /* rsbi */ + 7, /* mulr */ + 14, /* muli */ + 20, /* qmulr */ + 30, /* qmuli */ + 20, /* qmulr_u */ + 30, /* qmuli_u */ + 22, /* divr */ + 29, /* divi */ + 23, /* divr_u */ + 30, /* divi_u */ + 25, /* qdivr */ + 32, /* qdivi */ + 26, /* qdivr_u */ + 33, /* qdivi_u */ + 22, /* remr */ + 29, /* remi */ + 23, /* remr_u */ + 30, /* remi_u */ + 6, /* andr */ + 13, /* andi */ + 6, /* orr */ + 13, /* ori */ + 6, /* xorr */ + 13, /* xori */ + 9, /* lshr */ + 8, /* lshi */ + 9, /* rshr */ + 7, /* rshi */ + 9, /* rshr_u */ + 7, /* rshi_u */ + 6, /* negr */ + 6, /* comr */ + 13, /* ltr */ + 14, /* lti */ + 13, /* ltr_u */ + 14, /* lti_u */ + 13, /* ler */ + 14, /* lei */ + 13, /* ler_u */ + 14, /* lei_u */ + 13, /* eqr */ + 14, /* eqi */ + 13, /* ger */ + 14, /* gei */ + 13, /* ger_u */ + 14, /* gei_u */ + 13, /* gtr */ + 14, /* gti */ + 13, /* gtr_u */ + 14, /* gti_u */ + 13, /* ner */ + 14, /* nei */ + 3, /* movr */ + 10, /* movi */ + 7, /* extr_c */ + 7, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 3, /* extr_i */ + 3, /* extr_ui */ + 9, /* htonr_us */ + 6, /* htonr_ui */ + 6, /* htonr_ul */ + 4, /* ldr_c */ + 15, /* ldi_c */ + 4, /* ldr_uc */ + 15, /* ldi_uc */ + 4, /* ldr_s */ + 15, /* ldi_s */ + 4, /* ldr_us */ + 15, /* ldi_us */ + 3, /* ldr_i */ + 14, /* ldi_i */ + 3, /* ldr_ui */ + 14, /* ldi_ui */ + 3, /* ldr_l */ + 14, /* ldi_l */ + 5, /* ldxr_c */ + 8, /* ldxi_c */ + 5, /* ldxr_uc */ + 8, /* ldxi_uc */ + 5, /* ldxr_s */ + 8, /* ldxi_s */ + 5, /* ldxr_us */ + 8, /* ldxi_us */ + 4, /* ldxr_i */ + 7, /* ldxi_i */ + 4, /* ldxr_ui */ + 6, /* ldxi_ui */ + 4, /* ldxr_l */ + 7, /* ldxi_l */ + 6, /* str_c */ + 17, /* sti_c */ + 4, /* str_s */ + 15, /* sti_s */ + 3, /* str_i */ + 14, /* sti_i */ + 3, /* str_l */ + 14, /* sti_l */ + 7, /* stxr_c */ + 7, /* stxi_c */ + 5, /* stxr_s */ + 7, /* stxi_s */ + 4, /* stxr_i */ + 6, /* stxi_i */ + 4, /* stxr_l */ + 8, /* stxi_l */ + 9, /* bltr */ + 10, /* blti */ + 9, /* bltr_u */ + 10, /* blti_u */ + 9, /* bler */ + 13, /* blei */ + 9, /* bler_u */ + 10, /* blei_u */ + 9, /* beqr */ + 19, /* beqi */ + 9, /* bger */ + 10, /* bgei */ + 9, /* bger_u */ + 10, /* bgei_u */ + 9, /* bgtr */ + 10, /* bgti */ + 9, /* bgtr_u */ + 10, /* bgti_u */ + 9, /* bner */ + 19, /* bnei */ + 9, /* bmsr */ + 13, /* bmsi */ + 9, /* bmcr */ + 13, /* bmci */ + 9, /* boaddr */ + 10, /* boaddi */ + 9, /* boaddr_u */ + 10, /* boaddi_u */ + 9, /* bxaddr */ + 10, /* bxaddi */ + 9, /* bxaddr_u */ + 10, /* bxaddi_u */ + 9, /* bosubr */ + 10, /* bosubi */ + 9, /* bosubr_u */ + 10, /* bosubi_u */ + 9, /* bxsubr */ + 10, /* bxsubi */ + 9, /* bxsubr_u */ + 10, /* bxsubi_u */ + 3, /* jmpr */ + 5, /* jmpi */ + 3, /* callr */ + 13, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 124, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 10, /* addr_f */ + 21, /* addi_f */ + 15, /* subr_f */ + 21, /* subi_f */ + 27, /* rsbi_f */ + 10, /* mulr_f */ + 21, /* muli_f */ + 15, /* divr_f */ + 21, /* divi_f */ + 15, /* negr_f */ + 15, /* absr_f */ + 5, /* sqrtr_f */ + 16, /* ltr_f */ + 31, /* lti_f */ + 16, /* ler_f */ + 31, /* lei_f */ + 18, /* eqr_f */ + 33, /* eqi_f */ + 16, /* ger_f */ + 31, /* gei_f */ + 16, /* gtr_f */ + 31, /* gti_f */ + 20, /* ner_f */ + 35, /* nei_f */ + 16, /* unltr_f */ + 31, /* unlti_f */ + 16, /* unler_f */ + 31, /* unlei_f */ + 16, /* uneqr_f */ + 31, /* uneqi_f */ + 16, /* unger_f */ + 31, /* ungei_f */ + 16, /* ungtr_f */ + 31, /* ungti_f */ + 16, /* ltgtr_f */ + 31, /* ltgti_f */ + 16, /* ordr_f */ + 31, /* ordi_f */ + 16, /* unordr_f */ + 31, /* unordi_f */ + 5, /* truncr_f_i */ + 5, /* truncr_f_l */ + 5, /* extr_f */ + 5, /* extr_d_f */ + 5, /* movr_f */ + 15, /* movi_f */ + 5, /* ldr_f */ + 16, /* ldi_f */ + 6, /* ldxr_f */ + 8, /* ldxi_f */ + 5, /* str_f */ + 16, /* sti_f */ + 6, /* stxr_f */ + 9, /* stxi_f */ + 10, /* bltr_f */ + 21, /* blti_f */ + 10, /* bler_f */ + 24, /* blei_f */ + 12, /* beqr_f */ + 27, /* beqi_f */ + 10, /* bger_f */ + 25, /* bgei_f */ + 10, /* bgtr_f */ + 25, /* bgti_f */ + 13, /* bner_f */ + 28, /* bnei_f */ + 10, /* bunltr_f */ + 25, /* bunlti_f */ + 10, /* bunler_f */ + 25, /* bunlei_f */ + 10, /* buneqr_f */ + 25, /* buneqi_f */ + 10, /* bunger_f */ + 25, /* bungei_f */ + 10, /* bungtr_f */ + 25, /* bungti_f */ + 10, /* bltgtr_f */ + 25, /* bltgti_f */ + 10, /* bordr_f */ + 25, /* bordi_f */ + 10, /* bunordr_f */ + 25, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 10, /* addr_d */ + 25, /* addi_d */ + 15, /* subr_d */ + 25, /* subi_d */ + 27, /* rsbi_d */ + 10, /* mulr_d */ + 25, /* muli_d */ + 15, /* divr_d */ + 25, /* divi_d */ + 22, /* negr_d */ + 16, /* absr_d */ + 5, /* sqrtr_d */ + 17, /* ltr_d */ + 32, /* lti_d */ + 17, /* ler_d */ + 32, /* lei_d */ + 19, /* eqr_d */ + 34, /* eqi_d */ + 17, /* ger_d */ + 32, /* gei_d */ + 17, /* gtr_d */ + 32, /* gti_d */ + 21, /* ner_d */ + 36, /* nei_d */ + 17, /* unltr_d */ + 32, /* unlti_d */ + 17, /* unler_d */ + 32, /* unlei_d */ + 17, /* uneqr_d */ + 32, /* uneqi_d */ + 17, /* unger_d */ + 32, /* ungei_d */ + 17, /* ungtr_d */ + 32, /* ungti_d */ + 17, /* ltgtr_d */ + 32, /* ltgti_d */ + 17, /* ordr_d */ + 32, /* ordi_d */ + 17, /* unordr_d */ + 32, /* unordi_d */ + 5, /* truncr_d_i */ + 5, /* truncr_d_l */ + 5, /* extr_d */ + 5, /* extr_f_d */ + 5, /* movr_d */ + 15, /* movi_d */ + 5, /* ldr_d */ + 16, /* ldi_d */ + 6, /* ldxr_d */ + 8, /* ldxi_d */ + 5, /* str_d */ + 16, /* sti_d */ + 6, /* stxr_d */ + 9, /* stxi_d */ + 11, /* bltr_d */ + 26, /* blti_d */ + 11, /* bler_d */ + 26, /* blei_d */ + 13, /* beqr_d */ + 28, /* beqi_d */ + 11, /* bger_d */ + 26, /* bgei_d */ + 11, /* bgtr_d */ + 26, /* bgti_d */ + 14, /* bner_d */ + 29, /* bnei_d */ + 11, /* bunltr_d */ + 26, /* bunlti_d */ + 11, /* bunler_d */ + 26, /* bunlei_d */ + 11, /* buneqr_d */ + 26, /* buneqi_d */ + 11, /* bunger_d */ + 26, /* bungei_d */ + 11, /* bungtr_d */ + 26, /* bungti_d */ + 11, /* bltgtr_d */ + 26, /* bltgti_d */ + 11, /* bordr_d */ + 26, /* bordi_d */ + 11, /* bunordr_d */ + 26, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#else + +# if __X64_32 +#define JIT_INSTR_MAX 108 + 0, /* data */ + 0, /* live */ + 3, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 3, /* label */ + 108, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 41, /* va_start */ + 45, /* va_arg */ + 54, /* va_arg_d */ + 0, /* va_end */ + 5, /* addr */ + 7, /* addi */ + 6, /* addcr */ + 7, /* addci */ + 6, /* addxr */ + 7, /* addxi */ + 6, /* subr */ + 7, /* subi */ + 9, /* subcr */ + 7, /* subci */ + 9, /* subxr */ + 7, /* subxi */ + 10, /* rsbi */ + 7, /* mulr */ + 8, /* muli */ + 18, /* qmulr */ + 24, /* qmuli */ + 18, /* qmulr_u */ + 24, /* qmuli_u */ + 19, /* divr */ + 22, /* divi */ + 20, /* divr_u */ + 23, /* divi_u */ + 22, /* qdivr */ + 25, /* qdivi */ + 23, /* qdivr_u */ + 26, /* qdivi_u */ + 19, /* remr */ + 22, /* remi */ + 20, /* remr_u */ + 23, /* remi_u */ + 6, /* andr */ + 9, /* andi */ + 6, /* orr */ + 10, /* ori */ + 6, /* xorr */ + 10, /* xori */ + 9, /* lshr */ + 8, /* lshi */ + 9, /* rshr */ + 7, /* rshi */ + 9, /* rshr_u */ + 7, /* rshi_u */ + 6, /* negr */ + 6, /* comr */ + 13, /* ltr */ + 14, /* lti */ + 13, /* ltr_u */ + 14, /* lti_u */ + 13, /* ler */ + 14, /* lei */ + 13, /* ler_u */ + 14, /* lei_u */ + 13, /* eqr */ + 14, /* eqi */ + 13, /* ger */ + 14, /* gei */ + 13, /* ger_u */ + 14, /* gei_u */ + 13, /* gtr */ + 14, /* gti */ + 13, /* gtr_u */ + 14, /* gti_u */ + 13, /* ner */ + 14, /* nei */ + 3, /* movr */ + 6, /* movi */ + 7, /* extr_c */ + 7, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 0, /* extr_i */ + 0, /* extr_ui */ + 9, /* htonr_us */ + 6, /* htonr_ui */ + 0, /* htonr_ul */ + 5, /* ldr_c */ + 9, /* ldi_c */ + 5, /* ldr_uc */ + 9, /* ldi_uc */ + 5, /* ldr_s */ + 9, /* ldi_s */ + 5, /* ldr_us */ + 9, /* ldi_us */ + 4, /* ldr_i */ + 8, /* ldi_i */ + 0, /* ldr_ui */ + 0, /* ldi_ui */ + 0, /* ldr_l */ + 0, /* ldi_l */ + 9, /* ldxr_c */ + 7, /* ldxi_c */ + 9, /* ldxr_uc */ + 7, /* ldxi_uc */ + 9, /* ldxr_s */ + 7, /* ldxi_s */ + 9, /* ldxr_us */ + 7, /* ldxi_us */ + 8, /* ldxr_i */ + 7, /* ldxi_i */ + 0, /* ldxr_ui */ + 0, /* ldxi_ui */ + 0, /* ldxr_l */ + 0, /* ldxi_l */ + 7, /* str_c */ + 11, /* sti_c */ + 5, /* str_s */ + 9, /* sti_s */ + 4, /* str_i */ + 8, /* sti_i */ + 0, /* str_l */ + 0, /* sti_l */ + 12, /* stxr_c */ + 7, /* stxi_c */ + 10, /* stxr_s */ + 7, /* stxi_s */ + 9, /* stxr_i */ + 6, /* stxi_i */ + 0, /* stxr_l */ + 0, /* stxi_l */ + 9, /* bltr */ + 10, /* blti */ + 9, /* bltr_u */ + 10, /* blti_u */ + 9, /* bler */ + 12, /* blei */ + 9, /* bler_u */ + 10, /* blei_u */ + 9, /* beqr */ + 13, /* beqi */ + 9, /* bger */ + 10, /* bgei */ + 9, /* bger_u */ + 10, /* bgei_u */ + 9, /* bgtr */ + 10, /* bgti */ + 9, /* bgtr_u */ + 10, /* bgti_u */ + 9, /* bner */ + 13, /* bnei */ + 9, /* bmsr */ + 13, /* bmsi */ + 9, /* bmcr */ + 13, /* bmci */ + 9, /* boaddr */ + 10, /* boaddi */ + 9, /* boaddr_u */ + 10, /* boaddi_u */ + 9, /* bxaddr */ + 10, /* bxaddi */ + 9, /* bxaddr_u */ + 10, /* bxaddi_u */ + 9, /* bosubr */ + 10, /* bosubi */ + 9, /* bosubr_u */ + 10, /* bosubi_u */ + 9, /* bxsubr */ + 10, /* bxsubi */ + 9, /* bxsubr_u */ + 10, /* bxsubi_u */ + 2, /* jmpr */ + 5, /* jmpi */ + 3, /* callr */ + 9, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 34, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 10, /* addr_f */ + 21, /* addi_f */ + 15, /* subr_f */ + 21, /* subi_f */ + 26, /* rsbi_f */ + 10, /* mulr_f */ + 21, /* muli_f */ + 15, /* divr_f */ + 21, /* divi_f */ + 15, /* negr_f */ + 15, /* absr_f */ + 5, /* sqrtr_f */ + 15, /* ltr_f */ + 26, /* lti_f */ + 15, /* ler_f */ + 26, /* lei_f */ + 17, /* eqr_f */ + 28, /* eqi_f */ + 15, /* ger_f */ + 26, /* gei_f */ + 15, /* gtr_f */ + 26, /* gti_f */ + 20, /* ner_f */ + 31, /* nei_f */ + 15, /* unltr_f */ + 26, /* unlti_f */ + 15, /* unler_f */ + 26, /* unlei_f */ + 15, /* uneqr_f */ + 26, /* uneqi_f */ + 15, /* unger_f */ + 26, /* ungei_f */ + 15, /* ungtr_f */ + 26, /* ungti_f */ + 15, /* ltgtr_f */ + 26, /* ltgti_f */ + 15, /* ordr_f */ + 26, /* ordi_f */ + 15, /* unordr_f */ + 26, /* unordi_f */ + 5, /* truncr_f_i */ + 0, /* truncr_f_l */ + 5, /* extr_f */ + 5, /* extr_d_f */ + 5, /* movr_f */ + 11, /* movi_f */ + 6, /* ldr_f */ + 10, /* ldi_f */ + 11, /* ldxr_f */ + 9, /* ldxi_f */ + 6, /* str_f */ + 10, /* sti_f */ + 11, /* stxr_f */ + 9, /* stxi_f */ + 10, /* bltr_f */ + 21, /* blti_f */ + 10, /* bler_f */ + 21, /* blei_f */ + 12, /* beqr_f */ + 23, /* beqi_f */ + 10, /* bger_f */ + 21, /* bgei_f */ + 10, /* bgtr_f */ + 21, /* bgti_f */ + 13, /* bner_f */ + 24, /* bnei_f */ + 10, /* bunltr_f */ + 21, /* bunlti_f */ + 10, /* bunler_f */ + 21, /* bunlei_f */ + 10, /* buneqr_f */ + 21, /* buneqi_f */ + 10, /* bunger_f */ + 21, /* bungei_f */ + 10, /* bungtr_f */ + 21, /* bungti_f */ + 10, /* bltgtr_f */ + 21, /* bltgti_f */ + 10, /* bordr_f */ + 21, /* bordi_f */ + 10, /* bunordr_f */ + 21, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 10, /* addr_d */ + 33, /* addi_d */ + 15, /* subr_d */ + 33, /* subi_d */ + 38, /* rsbi_d */ + 10, /* mulr_d */ + 33, /* muli_d */ + 15, /* divr_d */ + 33, /* divi_d */ + 22, /* negr_d */ + 16, /* absr_d */ + 5, /* sqrtr_d */ + 16, /* ltr_d */ + 39, /* lti_d */ + 16, /* ler_d */ + 39, /* lei_d */ + 18, /* eqr_d */ + 41, /* eqi_d */ + 16, /* ger_d */ + 39, /* gei_d */ + 16, /* gtr_d */ + 39, /* gti_d */ + 21, /* ner_d */ + 44, /* nei_d */ + 16, /* unltr_d */ + 39, /* unlti_d */ + 16, /* unler_d */ + 39, /* unlei_d */ + 16, /* uneqr_d */ + 39, /* uneqi_d */ + 16, /* unger_d */ + 39, /* ungei_d */ + 16, /* ungtr_d */ + 39, /* ungti_d */ + 16, /* ltgtr_d */ + 39, /* ltgti_d */ + 16, /* ordr_d */ + 39, /* ordi_d */ + 16, /* unordr_d */ + 39, /* unordi_d */ + 5, /* truncr_d_i */ + 0, /* truncr_d_l */ + 5, /* extr_d */ + 5, /* extr_f_d */ + 5, /* movr_d */ + 23, /* movi_d */ + 6, /* ldr_d */ + 10, /* ldi_d */ + 11, /* ldxr_d */ + 9, /* ldxi_d */ + 6, /* str_d */ + 10, /* sti_d */ + 11, /* stxr_d */ + 9, /* stxi_d */ + 11, /* bltr_d */ + 34, /* blti_d */ + 11, /* bler_d */ + 34, /* blei_d */ + 13, /* beqr_d */ + 36, /* beqi_d */ + 11, /* bger_d */ + 34, /* bgei_d */ + 11, /* bgtr_d */ + 34, /* bgti_d */ + 14, /* bner_d */ + 37, /* bnei_d */ + 11, /* bunltr_d */ + 34, /* bunlti_d */ + 11, /* bunler_d */ + 34, /* bunlei_d */ + 11, /* buneqr_d */ + 34, /* buneqi_d */ + 11, /* bunger_d */ + 34, /* bungei_d */ + 11, /* bungtr_d */ + 34, /* bungti_d */ + 11, /* bltgtr_d */ + 34, /* bltgti_d */ + 11, /* bordr_d */ + 34, /* bordi_d */ + 11, /* bunordr_d */ + 34, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ + +# else +#define JIT_INSTR_MAX 115 + 0, /* data */ + 0, /* live */ + 6, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 7, /* label */ + 115, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 42, /* va_start */ + 41, /* va_arg */ + 50, /* va_arg_d */ + 0, /* va_end */ + 5, /* addr */ + 13, /* addi */ + 6, /* addcr */ + 13, /* addci */ + 6, /* addxr */ + 7, /* addxi */ + 6, /* subr */ + 13, /* subi */ + 9, /* subcr */ + 13, /* subci */ + 9, /* subxr */ + 7, /* subxi */ + 16, /* rsbi */ + 7, /* mulr */ + 14, /* muli */ + 20, /* qmulr */ + 30, /* qmuli */ + 20, /* qmulr_u */ + 30, /* qmuli_u */ + 22, /* divr */ + 29, /* divi */ + 23, /* divr_u */ + 30, /* divi_u */ + 25, /* qdivr */ + 32, /* qdivi */ + 26, /* qdivr_u */ + 33, /* qdivi_u */ + 22, /* remr */ + 29, /* remi */ + 23, /* remr_u */ + 30, /* remi_u */ + 6, /* andr */ + 13, /* andi */ + 6, /* orr */ + 13, /* ori */ + 6, /* xorr */ + 13, /* xori */ + 9, /* lshr */ + 8, /* lshi */ + 9, /* rshr */ + 7, /* rshi */ + 9, /* rshr_u */ + 7, /* rshi_u */ + 6, /* negr */ + 6, /* comr */ + 13, /* ltr */ + 14, /* lti */ + 13, /* ltr_u */ + 14, /* lti_u */ + 13, /* ler */ + 14, /* lei */ + 13, /* ler_u */ + 14, /* lei_u */ + 13, /* eqr */ + 14, /* eqi */ + 13, /* ger */ + 14, /* gei */ + 13, /* ger_u */ + 14, /* gei_u */ + 13, /* gtr */ + 14, /* gti */ + 13, /* gtr_u */ + 14, /* gti_u */ + 13, /* ner */ + 14, /* nei */ + 3, /* movr */ + 10, /* movi */ + 4, /* extr_c */ + 4, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 3, /* extr_i */ + 3, /* extr_ui */ + 9, /* htonr_us */ + 6, /* htonr_ui */ + 6, /* htonr_ul */ + 5, /* ldr_c */ + 9, /* ldi_c */ + 5, /* ldr_uc */ + 9, /* ldi_uc */ + 5, /* ldr_s */ + 9, /* ldi_s */ + 5, /* ldr_us */ + 9, /* ldi_us */ + 4, /* ldr_i */ + 8, /* ldi_i */ + 4, /* ldr_ui */ + 8, /* ldi_ui */ + 4, /* ldr_l */ + 8, /* ldi_l */ + 6, /* ldxr_c */ + 8, /* ldxi_c */ + 6, /* ldxr_uc */ + 8, /* ldxi_uc */ + 6, /* ldxr_s */ + 8, /* ldxi_s */ + 6, /* ldxr_us */ + 8, /* ldxi_us */ + 5, /* ldxr_i */ + 7, /* ldxi_i */ + 5, /* ldxr_ui */ + 6, /* ldxi_ui */ + 5, /* ldxr_l */ + 7, /* ldxi_l */ + 4, /* str_c */ + 8, /* sti_c */ + 5, /* str_s */ + 9, /* sti_s */ + 4, /* str_i */ + 8, /* sti_i */ + 4, /* str_l */ + 8, /* sti_l */ + 5, /* stxr_c */ + 6, /* stxi_c */ + 6, /* stxr_s */ + 7, /* stxi_s */ + 5, /* stxr_i */ + 6, /* stxi_i */ + 5, /* stxr_l */ + 7, /* stxi_l */ + 9, /* bltr */ + 10, /* blti */ + 9, /* bltr_u */ + 10, /* blti_u */ + 9, /* bler */ + 13, /* blei */ + 9, /* bler_u */ + 10, /* blei_u */ + 9, /* beqr */ + 19, /* beqi */ + 9, /* bger */ + 10, /* bgei */ + 9, /* bger_u */ + 10, /* bgei_u */ + 9, /* bgtr */ + 10, /* bgti */ + 9, /* bgtr_u */ + 10, /* bgti_u */ + 9, /* bner */ + 19, /* bnei */ + 9, /* bmsr */ + 13, /* bmsi */ + 9, /* bmcr */ + 13, /* bmci */ + 9, /* boaddr */ + 10, /* boaddi */ + 9, /* boaddr_u */ + 10, /* boaddi_u */ + 9, /* bxaddr */ + 10, /* bxaddi */ + 9, /* bxaddr_u */ + 10, /* bxaddi_u */ + 9, /* bosubr */ + 10, /* bosubi */ + 9, /* bosubr_u */ + 10, /* bosubi_u */ + 9, /* bxsubr */ + 10, /* bxsubi */ + 9, /* bxsubr_u */ + 10, /* bxsubi_u */ + 3, /* jmpr */ + 5, /* jmpi */ + 3, /* callr */ + 13, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 37, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 10, /* addr_f */ + 21, /* addi_f */ + 15, /* subr_f */ + 21, /* subi_f */ + 30, /* rsbi_f */ + 10, /* mulr_f */ + 21, /* muli_f */ + 15, /* divr_f */ + 21, /* divi_f */ + 15, /* negr_f */ + 15, /* absr_f */ + 5, /* sqrtr_f */ + 11, /* ltr_f */ + 26, /* lti_f */ + 11, /* ler_f */ + 26, /* lei_f */ + 13, /* eqr_f */ + 28, /* eqi_f */ + 11, /* ger_f */ + 26, /* gei_f */ + 11, /* gtr_f */ + 26, /* gti_f */ + 16, /* ner_f */ + 31, /* nei_f */ + 11, /* unltr_f */ + 26, /* unlti_f */ + 11, /* unler_f */ + 26, /* unlei_f */ + 11, /* uneqr_f */ + 26, /* uneqi_f */ + 11, /* unger_f */ + 26, /* ungei_f */ + 11, /* ungtr_f */ + 26, /* ungti_f */ + 11, /* ltgtr_f */ + 26, /* ltgti_f */ + 11, /* ordr_f */ + 26, /* ordi_f */ + 11, /* unordr_f */ + 26, /* unordi_f */ + 5, /* truncr_f_i */ + 5, /* truncr_f_l */ + 5, /* extr_f */ + 5, /* extr_d_f */ + 5, /* movr_f */ + 15, /* movi_f */ + 6, /* ldr_f */ + 10, /* ldi_f */ + 7, /* ldxr_f */ + 9, /* ldxi_f */ + 6, /* str_f */ + 10, /* sti_f */ + 7, /* stxr_f */ + 9, /* stxi_f */ + 10, /* bltr_f */ + 21, /* blti_f */ + 10, /* bler_f */ + 25, /* blei_f */ + 12, /* beqr_f */ + 27, /* beqi_f */ + 10, /* bger_f */ + 25, /* bgei_f */ + 10, /* bgtr_f */ + 25, /* bgti_f */ + 13, /* bner_f */ + 28, /* bnei_f */ + 10, /* bunltr_f */ + 25, /* bunlti_f */ + 10, /* bunler_f */ + 25, /* bunlei_f */ + 10, /* buneqr_f */ + 25, /* buneqi_f */ + 10, /* bunger_f */ + 25, /* bungei_f */ + 10, /* bungtr_f */ + 25, /* bungti_f */ + 10, /* bltgtr_f */ + 25, /* bltgti_f */ + 10, /* bordr_f */ + 25, /* bordi_f */ + 10, /* bunordr_f */ + 25, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 10, /* addr_d */ + 25, /* addi_d */ + 15, /* subr_d */ + 25, /* subi_d */ + 30, /* rsbi_d */ + 10, /* mulr_d */ + 25, /* muli_d */ + 15, /* divr_d */ + 25, /* divi_d */ + 22, /* negr_d */ + 16, /* absr_d */ + 5, /* sqrtr_d */ + 12, /* ltr_d */ + 27, /* lti_d */ + 12, /* ler_d */ + 27, /* lei_d */ + 14, /* eqr_d */ + 29, /* eqi_d */ + 12, /* ger_d */ + 27, /* gei_d */ + 12, /* gtr_d */ + 27, /* gti_d */ + 17, /* ner_d */ + 32, /* nei_d */ + 12, /* unltr_d */ + 27, /* unlti_d */ + 12, /* unler_d */ + 27, /* unlei_d */ + 12, /* uneqr_d */ + 27, /* uneqi_d */ + 12, /* unger_d */ + 27, /* ungei_d */ + 12, /* ungtr_d */ + 27, /* ungti_d */ + 12, /* ltgtr_d */ + 27, /* ltgti_d */ + 12, /* ordr_d */ + 27, /* ordi_d */ + 12, /* unordr_d */ + 27, /* unordi_d */ + 5, /* truncr_d_i */ + 5, /* truncr_d_l */ + 5, /* extr_d */ + 5, /* extr_f_d */ + 5, /* movr_d */ + 15, /* movi_d */ + 6, /* ldr_d */ + 10, /* ldi_d */ + 7, /* ldxr_d */ + 9, /* ldxi_d */ + 6, /* str_d */ + 10, /* sti_d */ + 7, /* stxr_d */ + 9, /* stxi_d */ + 11, /* bltr_d */ + 26, /* blti_d */ + 11, /* bler_d */ + 26, /* blei_d */ + 13, /* beqr_d */ + 28, /* beqi_d */ + 11, /* bger_d */ + 26, /* bgei_d */ + 11, /* bgtr_d */ + 26, /* bgti_d */ + 14, /* bner_d */ + 29, /* bnei_d */ + 11, /* bunltr_d */ + 26, /* bunlti_d */ + 11, /* bunler_d */ + 26, /* bunlei_d */ + 11, /* buneqr_d */ + 26, /* buneqi_d */ + 11, /* bunger_d */ + 26, /* bungei_d */ + 11, /* bungtr_d */ + 26, /* bungti_d */ + 11, /* bltgtr_d */ + 26, /* bltgti_d */ + 11, /* bordr_d */ + 26, /* bordi_d */ + 11, /* bunordr_d */ + 26, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 0, /* movr_w_f */ + 0, /* movr_ww_d */ + 0, /* movr_w_d */ + 0, /* movr_f_w */ + 0, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 0, /* movr_d_w */ + 0, /* movi_d_w */ +#endif /* __CYGWIN__ || _WIN32 */ +# endif /* __X64_32 */ +#endif /* __X64 */ diff --git a/deps/lightning/lib/jit_x86-x87.c b/deps/lightning/lib/jit_x86-x87.c new file mode 100644 index 0000000..4453bf3 --- /dev/null +++ b/deps/lightning/lib/jit_x86-x87.c @@ -0,0 +1,1344 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# if __X32 +# define x87_address_p(i0) 1 +# else +# if __X64_32 +# define x87_address_p(i0) ((jit_word_t)(i0) >= 0) +# else +# define x87_address_p(i0) can_sign_extend_int_p(i0) +# endif +# endif +# define _ST0_REGNO 0 +# define _ST1_REGNO 1 +# define _ST2_REGNO 2 +# define _ST3_REGNO 3 +# define _ST4_REGNO 4 +# define _ST5_REGNO 5 +# define _ST6_REGNO 6 +# define x87rx(code, md, rb, ri, ms) _x87rx(_jit, code, md, rb, ri, ms) +# define fldcwm(md, rb, ri, ms) x87rx(015, md, rb, ri, ms) +# define fstcwm(md, rb, ri, ms) _fstcwm(_jit, md, rb, ri, ms) +static void +_fstcwm(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t); +# define fldsm(md, rb, ri, ms) x87rx(010, md, rb, ri, ms) +# define fstsm(md, rb, ri, ms) x87rx(012, md, rb, ri, ms) +# define fldlm(md, rb, ri, ms) x87rx(050, md, rb, ri, ms) +# define fstlm(md, rb, ri, ms) x87rx(052, md, rb, ri, ms) +# define fisttplm(md, rb, ri, ms) x87rx(031, md, rb, ri, ms) +# define fistlm(md, rb, ri, ms) x87rx(032, md, rb, ri, ms) +# define fisttpqm(md, rb, ri, ms) x87rx(071, md, rb, ri, ms) +# define fildlm(md, rb, ri, ms) x87rx(030, md, rb,ri, ms) +# define fildqm(md, rb, ri, ms) x87rx(075, md, rb,ri, ms) +static void +_x87rx(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t, jit_int32_t, jit_int32_t); +# define x87ri(cc,r0) _x87ri(_jit,cc,r0) +# define fchs_() x87ri(014, 0) +# define fabs_() x87ri(014, 1) +# define fld1() x87ri(015, 0) +# define fldl2t() x87ri(015, 1) +# define fldl2e() x87ri(015, 2) +# define fldpi() x87ri(015, 3) +# define fldlg2() x87ri(015, 4) +# define fldln2() x87ri(015, 5) +# define fldz() x87ri(015, 6) +# define fsqrt_() x87ri(017, 2) +# define fldr(r0) x87ri(010, r0) +# define fxchr(r0) x87ri(011, r0) +# define fstr(r0) x87ri(052, r0) +# define fstpr(r0) x87ri(053, r0) +# define fucomir(r0) x87ri(035, r0) +# define fucomipr(r0) x87ri(075, r0) +static void _x87ri(jit_state_t*, jit_int32_t, jit_int32_t); +# define faddr(r0, r1) x87rri(000, r0, r1) +# define fmulr(r0, r1) x87rri(001, r0, r1) +# define fsubr(r0, r1) x87rri(004, r0, r1) +# define fsubrr(r0, r1) x87rri(005, r0, r1) +# define fdivr(r0, r1) x87rri(006, r0, r1) +# define fdivrr(r0, r1) x87rri(007, r0, r1) +# define x87rri(cc, r0, r1) _x87rri(_jit, cc, r0, r1) +static void _x87rri(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define x87_addr_f(r0, r1, r2) _x87_addr_d(_jit, r0, r1, r2) +# define x87_addi_f(r0, r1, i0) _x87_addi_f(_jit, r0, r1, i0) +static void _x87_addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_addr_d(r0, r1, r2) _x87_addr_d(_jit, r0, r1, r2) +static void _x87_addr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define x87_addi_d(r0, r1, i0) _x87_addi_d(_jit, r0, r1, i0) +static void _x87_addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_subr_f(r0, r1, r2) _x87_subr_d(_jit, r0, r1, r2) +# define x87_subi_f(r0, r1, i0) _x87_subi_f(_jit, r0, r1, i0) +static void _x87_subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_subr_d(r0, r1, r2) _x87_subr_d(_jit, r0, r1, r2) +static void _x87_subr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define x87_subi_d(r0, r1, i0) _x87_subi_d(_jit, r0, r1, i0) +static void _x87_subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_rsbr_f(r0, r1, r2) x87_subr_f(r0, r2, r1) +# define x87_rsbi_f(r0, r1, i0) _x87_rsbi_f(_jit, r0, r1, i0) +static void _x87_rsbi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_rsbr_d(r0, r1, r2) x87_subr_d(r0, r2, r1) +# define x87_rsbi_d(r0, r1, i0) _x87_rsbi_d(_jit, r0, r1, i0) +static void _x87_rsbi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_mulr_f(r0, r1, r2) _x87_mulr_d(_jit, r0, r1, r2) +# define x87_muli_f(r0, r1, i0) _x87_muli_f(_jit, r0, r1, i0) +static void _x87_muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_mulr_d(r0, r1, r2) _x87_mulr_d(_jit, r0, r1, r2) +static void _x87_mulr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define x87_muli_d(r0, r1, i0) _x87_muli_d(_jit, r0, r1, i0) +static void _x87_muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_divr_f(r0, r1, r2) _x87_divr_d(_jit, r0, r1, r2) +# define x87_divi_f(r0, r1, i0) _x87_divi_f(_jit, r0, r1, i0) +static void _x87_divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_divr_d(r0, r1, r2) _x87_divr_d(_jit, r0, r1, r2) +static void _x87_divr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define x87_divi_d(r0, r1, i0) _x87_divi_d(_jit, r0, r1, i0) +static void _x87_divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_absr_f(r0, r1) _x87_absr_d(_jit, r0, r1) +# define x87_absr_d(r0, r1) _x87_absr_d(_jit, r0, r1) +static void _x87_absr_d(jit_state_t*, jit_int32_t, jit_int32_t); +# define x87_negr_f(r0, r1) _x87_negr_d(_jit, r0, r1) +# define x87_negr_d(r0, r1) _x87_negr_d(_jit, r0, r1) +static void _x87_negr_d(jit_state_t*, jit_int32_t, jit_int32_t); +# define x87_sqrtr_f(r0, r1) _x87_sqrtr_d(_jit, r0, r1) +# define x87_sqrtr_d(r0, r1) _x87_sqrtr_d(_jit, r0, r1) +static void _x87_sqrtr_d(jit_state_t*, jit_int32_t, jit_int32_t); +# define x87_truncr_f_i(r0, r1) _x87_truncr_d_i(_jit, r0, r1) +# define x87_truncr_d_i(r0, r1) _x87_truncr_d_i(_jit, r0, r1) +static void _x87_truncr_d_i(jit_state_t*, jit_int32_t, jit_int32_t); +# if __X64 +# define x87_truncr_f_l(r0, r1) _x87_truncr_d_l(_jit, r0, r1) +# define x87_truncr_d_l(r0, r1) _x87_truncr_d_l(_jit, r0, r1) +static void _x87_truncr_d_l(jit_state_t*, jit_int32_t, jit_int32_t); +# endif +# define x87_extr_f(r0, r1) _x87_extr_d(_jit, r0, r1) +# define x87_extr_d(r0, r1) _x87_extr_d(_jit, r0, r1) +# define x87_extr_f_d(r0, r1) x87_movr_d(r0, r1) +# define x87_extr_d_f(r0, r1) x87_movr_d(r0, r1) +static void _x87_extr_d(jit_state_t*, jit_int32_t, jit_int32_t); +# define x87cmp(code, r0, r1, r2) _x87cmp(_jit, code, r0, r1, r2) +static void +_x87cmp(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t); +# define x87cmp2(code, r0, r1, r2) _x87cmp2(_jit, code, r0, r1, r2) +static void +_x87cmp2(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t); +# define x87jcc(code, i0, r0, r1) _x87jcc(_jit, code, i0, r0, r1) +static jit_word_t +_x87jcc(jit_state_t*, jit_int32_t, jit_word_t, jit_int32_t, jit_int32_t); +# define x87jcc2(code, i0, r0, r1) _x87jcc2(_jit, code, i0, r0, r1) +static jit_word_t +_x87jcc2(jit_state_t*, jit_int32_t, jit_word_t, jit_int32_t, jit_int32_t); +#define x87_movi_f(r0,i0) _x87_movi_f(_jit,r0,i0) +static void _x87_movi_f(jit_state_t*, jit_int32_t, jit_float32_t*); +# define x87_ldr_f(r0, r1) _x87_ldr_f(_jit, r0, r1) +static void _x87_ldr_f(jit_state_t*, jit_int32_t, jit_int32_t); +# define x87_ldi_f(r0, i0) _x87_ldi_f(_jit, r0, i0) +static void _x87_ldi_f(jit_state_t*, jit_int32_t, jit_word_t); +# define x87_ldxr_f(r0, r1, r2) _x87_ldxr_f(_jit, r0, r1, r2) +static void _x87_ldxr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define x87_ldxi_f(r0, r1, i0) _x87_ldxi_f(_jit, r0, r1, i0) +static void _x87_ldxi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define x87_str_f(r0, r1) _x87_str_f(_jit, r0, r1) +static void _x87_str_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define x87_sti_f(i0, r0) _x87_sti_f(_jit, i0, r0) +static void _x87_sti_f(jit_state_t*,jit_word_t, jit_int32_t); +# define x87_stxr_f(r0, r1, r2) _x87_stxr_f(_jit, r0, r1, r2) +static void _x87_stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define x87_stxi_f(i0, r0, r1) _x87_stxi_f(_jit, i0, r0, r1) +static void _x87_stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define x87_ltr_f(r0, r1, r2) x87cmp(X86_CC_A, r0, r2, r1) +# define x87_lti_f(r0, r1, i0) _x87_lti_f(_jit, r0, r1, i0) +static void _x87_lti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_ler_f(r0, r1, r2) x87cmp(X86_CC_AE, r0, r2, r1) +# define x87_lei_f(r0, r1, i0) _x87_lei_f(_jit, r0, r1, i0) +static void _x87_lei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_eqr_f(r0, r1, r2) x87_eqr_d(r0, r2, r1) +# define x87_eqi_f(r0, r1, i0) _x87_eqi_f(_jit, r0, r1, i0) +static void _x87_eqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_ger_f(r0, r1, r2) x87cmp(X86_CC_AE, r0, r1, r2) +# define x87_gei_f(r0, r1, i0) _x87_gei_f(_jit, r0, r1, i0) +static void _x87_gei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_gtr_f(r0, r1, r2) x87cmp(X86_CC_A, r0, r1, r2) +# define x87_gti_f(r0, r1, i0) _x87_gti_f(_jit, r0, r1, i0) +static void _x87_gti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_ner_f(r0, r1, r2) x87_ner_d(r0, r2, r1) +# define x87_nei_f(r0, r1, i0) _x87_nei_f(_jit, r0, r1, i0) +static void _x87_nei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_unltr_f(r0, r1, r2) x87cmp(X86_CC_NAE, r0, r1, r2) +# define x87_unlti_f(r0, r1, i0) _x87_unlti_f(_jit, r0, r1, i0) +static void _x87_unlti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_unler_f(r0, r1, r2) x87cmp(X86_CC_NA, r0, r1, r2) +# define x87_unlei_f(r0, r1, i0) _x87_unlei_f(_jit, r0, r1, i0) +static void _x87_unlei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_uneqr_f(r0, r1, r2) x87cmp2(X86_CC_E, r0, r1, r2) +# define x87_uneqi_f(r0, r1, i0) _x87_uneqi_f(_jit, r0, r1, i0) +static void _x87_uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_unger_f(r0, r1, r2) x87cmp(X86_CC_NA, r0, r2, r1) +# define x87_ungei_f(r0, r1, i0) _x87_ungei_f(_jit, r0, r1, i0) +static void _x87_ungei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_ungtr_f(r0, r1, r2) x87cmp(X86_CC_NAE, r0, r2, r1) +# define x87_ungti_f(r0, r1, i0) _x87_ungti_f(_jit, r0, r1, i0) +static void _x87_ungti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_ltgtr_f(r0, r1, r2) x87_ltgtr_d(r0, r1, r2) +# define x87_ltgti_f(r0, r1, i0) _x87_ltgti_f(_jit, r0, r1, i0) +static void _x87_ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_ordr_f(r0, r1, r2) x87cmp2(X86_CC_NP, r0, r2, r1) +# define x87_ordi_f(r0, r1, i0) _x87_ordi_f(_jit, r0, r1, i0) +static void _x87_ordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_unordr_f(r0, r1, r2) x87cmp2(X86_CC_P, r0, r2, r1) +# define x87_unordi_f(r0, r1, i0) _x87_unordi_f(_jit, r0, r1, i0) +static void _x87_unordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define x87_ltr_d(r0, r1, r2) x87cmp(X86_CC_A, r0, r2, r1) +# define x87_lti_d(r0, r1, i0) _x87_lti_d(_jit, r0, r1, i0) +static void _x87_lti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_ler_d(r0, r1, r2) x87cmp(X86_CC_AE, r0, r2, r1) +# define x87_lei_d(r0, r1, i0) _x87_lei_d(_jit, r0, r1, i0) +static void _x87_lei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_eqr_d(r0, r1, r2) _x87_eqr_d(_jit, r0, r2, r1) +static void _x87_eqr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define x87_eqi_d(r0, r1, i0) _x87_eqi_d(_jit, r0, r1, i0) +static void _x87_eqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_ger_d(r0, r1, r2) x87cmp(X86_CC_AE, r0, r1, r2) +# define x87_gei_d(r0, r1, i0) _x87_gei_d(_jit, r0, r1, i0) +static void _x87_gei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_gtr_d(r0, r1, r2) x87cmp(X86_CC_A, r0, r1, r2) +# define x87_gti_d(r0, r1, i0) _x87_gti_d(_jit, r0, r1, i0) +static void _x87_gti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_ner_d(r0, r1, r2) _x87_ner_d(_jit, r0, r2, r1) +static void _x87_ner_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define x87_nei_d(r0, r1, i0) _x87_nei_d(_jit, r0, r1, i0) +static void _x87_nei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_unltr_d(r0, r1, r2) x87cmp(X86_CC_NAE, r0, r1, r2) +# define x87_unlti_d(r0, r1, i0) _x87_unlti_d(_jit, r0, r1, i0) +static void _x87_unlti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_unler_d(r0, r1, r2) x87cmp(X86_CC_NA, r0, r1, r2) +# define x87_unlei_d(r0, r1, i0) _x87_unlei_d(_jit, r0, r1, i0) +static void _x87_unlei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_uneqr_d(r0, r1, r2) x87cmp2(X86_CC_E, r0, r1, r2) +# define x87_uneqi_d(r0, r1, i0) _x87_uneqi_d(_jit, r0, r1, i0) +static void _x87_uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_unger_d(r0, r1, r2) x87cmp(X86_CC_NA, r0, r2, r1) +# define x87_ungei_d(r0, r1, i0) _x87_ungei_d(_jit, r0, r1, i0) +static void _x87_ungei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_ungtr_d(r0, r1, r2) x87cmp(X86_CC_NAE, r0, r2, r1) +# define x87_ungti_d(r0, r1, i0) _x87_ungti_d(_jit, r0, r1, i0) +static void _x87_ungti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_ltgtr_d(r0, r1, r2) _x87_ltgtr_d(_jit, r0, r1, r2) +static void _x87_ltgtr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define x87_ltgti_d(r0, r1, i0) _x87_ltgti_d(_jit, r0, r1, i0) +static void _x87_ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_ordr_d(r0, r1, r2) x87cmp2(X86_CC_NP, r0, r2, r1) +# define x87_ordi_d(r0, r1, i0) _x87_ordi_d(_jit, r0, r1, i0) +static void _x87_ordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define x87_unordr_d(r0, r1, r2) x87cmp2(X86_CC_P, r0, r2, r1) +# define x87_unordi_d(r0, r1, i0) _x87_unordi_d(_jit, r0, r1, i0) +static void _x87_unordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +#define x87_movr_f(r0,r1) _x87_movr_d(_jit,r0,r1) +#define x87_movr_d(r0,r1) _x87_movr_d(_jit,r0,r1) +static void _x87_movr_d(jit_state_t*, jit_int32_t, jit_int32_t); +#define x87_movi_d(r0,i0) _x87_movi_d(_jit,r0,i0) +static void _x87_movi_d(jit_state_t*, jit_int32_t, jit_float64_t*); +# define x87_ldr_d(r0, r1) _x87_ldr_d(_jit, r0, r1) +static void _x87_ldr_d(jit_state_t*, jit_int32_t, jit_int32_t); +# define x87_ldi_d(r0, i0) _x87_ldi_d(_jit, r0, i0) +static void _x87_ldi_d(jit_state_t*, jit_int32_t, jit_word_t); +# define x87_ldxr_d(r0, r1, r2) _x87_ldxr_d(_jit, r0, r1, r2) +static void _x87_ldxr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define x87_ldxi_d(r0, r1, i0) _x87_ldxi_d(_jit, r0, r1, i0) +static void _x87_ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define x87_str_d(r0, r1) _x87_str_d(_jit, r0, r1) +static void _x87_str_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define x87_sti_d(i0, r0) _x87_sti_d(_jit, i0, r0) +static void _x87_sti_d(jit_state_t*,jit_word_t,jit_int32_t); +# define x87_stxr_d(r0, r1, r2) _x87_stxr_d(_jit, r0, r1, r2) +static void _x87_stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define x87_stxi_d(i0, r0, r1) _x87_stxi_d(_jit, i0, r0, r1) +static void _x87_stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define x87_bltr_f(i0, r0, r1) x87jcc(X86_CC_A, i0, r1, r0) +# define x87_blti_f(i0, r0, i1) _x87_blti_f(_jit, i0, r0, i1) +static jit_word_t +_x87_blti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_bler_f(i0, r0, r1) x87jcc(X86_CC_AE, i0, r1, r0) +# define x87_blei_f(i0, r0, i1) _x87_blei_f(_jit, i0, r0, i1) +static jit_word_t +_x87_blei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_beqr_f(i0, r0, r1) _x87_beqr_d(_jit, i0, r0, r1) +# define x87_beqi_f(i0, r0, i1) _x87_beqi_f(_jit, i0, r0, i1) +static jit_word_t +_x87_beqi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_bger_f(i0, r0, r1) x87jcc(X86_CC_AE, i0, r0, r1) +# define x87_bgei_f(i0, r0, i1) _x87_bgei_f(_jit, i0, r0, i1) +static jit_word_t +_x87_bgei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_bgtr_f(i0, r0, r1) x87jcc(X86_CC_A, i0, r0, r1) +# define x87_bgti_f(i0, r0, i1) _x87_bgti_f(_jit, i0, r0, i1) +static jit_word_t +_x87_bgti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_bner_f(i0, r0, r1) _x87_bner_d(_jit, i0, r0, r1) +# define x87_bnei_f(i0, r0, i1) _x87_bnei_f(_jit, i0, r0, i1) +static jit_word_t +_x87_bnei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_bunltr_f(i0, r0, r1) x87jcc(X86_CC_NAE, i0, r0, r1) +# define x87_bunlti_f(i0, r0, i1) _x87_bunlti_f(_jit, i0, r0, i1) +static jit_word_t +_x87_bunlti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_bunler_f(i0, r0, r1) x87jcc(X86_CC_NA, i0, r0, r1) +# define x87_bunlei_f(i0, r0, i1) _x87_bunlei_f(_jit, i0, r0, i1) +static jit_word_t +_x87_bunlei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_buneqr_f(i0, r0, r1) x87jcc2(X86_CC_E, i0, r0, r1) +# define x87_buneqi_f(i0, r0, i1) _x87_buneqi_f(_jit, i0, r0, i1) +static jit_word_t +_x87_buneqi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_bunger_f(i0, r0, r1) x87jcc(X86_CC_NA, i0, r1, r0) +# define x87_bungei_f(i0, r0, i1) _x87_bungei_f(_jit, i0, r0, i1) +static jit_word_t +_x87_bungei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_bungtr_f(i0, r0, r1) x87jcc(X86_CC_NAE, i0, r1, r0) +# define x87_bungti_f(i0, r0, i1) _x87_bungti_f(_jit, i0, r0, i1) +static jit_word_t +_x87_bungti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_bltgtr_f(i0, r0, r1) x87jcc2(X86_CC_NE, i0, r0, r1) +# define x87_bltgti_f(i0, r0, i1) _x87_bltgti_f(_jit, i0, r0, i1) +static jit_word_t +_x87_bltgti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_bordr_f(i0, r0, r1) x87jcc2(X86_CC_NP, i0, r0, r1) +# define x87_bordi_f(i0, r0, i1) _x87_bordi_f(_jit, i0, r0, i1) +static jit_word_t +_x87_bordi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_bunordr_f(i0, r0, r1) x87jcc2(X86_CC_P, i0, r0, r1) +# define x87_bunordi_f(i0, r0, i1) _x87_bunordi_f(_jit, i0, r0, i1) +static jit_word_t +_x87_bunordi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*); +# define x87_bltr_d(i0, r0, r1) x87jcc(X86_CC_A, i0, r1, r0) +# define x87_blti_d(i0, r0, i1) _x87_blti_d(_jit, i0, r0, i1) +static jit_word_t +_x87_blti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define x87_bler_d(i0, r0, r1) x87jcc(X86_CC_AE, i0, r1, r0) +# define x87_blei_d(i0, r0, i1) _x87_blei_d(_jit, i0, r0, i1) +static jit_word_t +_x87_blei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define x87_beqr_d(i0, r0, r1) _x87_beqr_d(_jit, i0, r0, r1) +static jit_word_t +_x87_beqr_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define x87_beqi_d(i0, r0, i1) _x87_beqi_d(_jit, i0, r0, i1) +static jit_word_t +_x87_beqi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define x87_bger_d(i0, r0, r1) x87jcc(X86_CC_AE, i0, r0, r1) +# define x87_bgei_d(i0, r0, i1) _x87_bgei_d(_jit, i0, r0, i1) +static jit_word_t +_x87_bgei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define x87_bgtr_d(i0, r0, r1) x87jcc(X86_CC_A, i0, r0, r1) +# define x87_bgti_d(i0, r0, i1) _x87_bgti_d(_jit, i0, r0, i1) +static jit_word_t +_x87_bgti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define x87_bner_d(i0, r0, r1) _x87_bner_d(_jit, i0, r0, r1) +static jit_word_t +_x87_bner_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define x87_bnei_d(i0, r0, i1) _x87_bnei_d(_jit, i0, r0, i1) +static jit_word_t +_x87_bnei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define x87_bunltr_d(i0, r0, r1) x87jcc(X86_CC_NAE, i0, r0, r1) +# define x87_bunlti_d(i0, r0, i1) _x87_bunlti_d(_jit, i0, r0, i1) +static jit_word_t +_x87_bunlti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define x87_bunler_d(i0, r0, r1) x87jcc(X86_CC_NA, i0, r0, r1) +# define x87_bunlei_d(i0, r0, i1) _x87_bunlei_d(_jit, i0, r0, i1) +static jit_word_t +_x87_bunlei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define x87_buneqr_d(i0, r0, r1) x87jcc2(X86_CC_E, i0, r0, r1) +# define x87_buneqi_d(i0, r0, i1) _x87_buneqi_d(_jit, i0, r0, i1) +static jit_word_t +_x87_buneqi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define x87_bunger_d(i0, r0, r1) x87jcc(X86_CC_NA, i0, r1, r0) +# define x87_bungei_d(i0, r0, i1) _x87_bungei_d(_jit, i0, r0, i1) +static jit_word_t +_x87_bungei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define x87_bungtr_d(i0, r0, r1) x87jcc(X86_CC_NAE, i0, r1, r0) +# define x87_bungti_d(i0, r0, i1) _x87_bungti_d(_jit, i0, r0, i1) +static jit_word_t +_x87_bungti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define x87_bltgtr_d(i0, r0, r1) x87jcc2(X86_CC_NE, i0, r0, r1) +# define x87_bltgti_d(i0, r0, i1) _x87_bltgti_d(_jit, i0, r0, i1) +static jit_word_t +_x87_bltgti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define x87_bordr_d(i0, r0, r1) x87jcc2(X86_CC_NP, i0, r0, r1) +# define x87_bordi_d(i0, r0, i1) _x87_bordi_d(_jit, i0, r0, i1) +static jit_word_t +_x87_bordi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +# define x87_bunordr_d(i0, r0, r1) x87jcc2(X86_CC_P, i0, r0, r1) +# define x87_bunordi_d(i0, r0, i1) _x87_bunordi_d(_jit, i0, r0, i1) +static jit_word_t +_x87_bunordi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*); +#endif + +#if CODE +# define fpr_opi(name, type, size) \ +static void \ +_x87_##name##i_##type(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, \ + jit_float##size##_t *i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr); \ + assert(jit_x87_reg_p(reg)); \ + x87_movi_##type(rn(reg), i0); \ + x87_##name##r_##type(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +# define fpr_bopi(name, type, size) \ +static jit_word_t \ +_x87_b##name##i_##type(jit_state_t *_jit, \ + jit_word_t i0, jit_int32_t r0, \ + jit_float##size##_t *i1) \ +{ \ + jit_word_t word; \ + jit_int32_t reg = jit_get_reg(jit_class_fpr| \ + jit_class_nospill); \ + assert(jit_x87_reg_p(reg)); \ + x87_movi_##type(rn(reg), i1); \ + word = x87_b##name##r_##type(i0, r0, rn(reg)); \ + jit_unget_reg(reg); \ + return (word); \ +} +# define fopi(name) fpr_opi(name, f, 32) +# define fbopi(name) fpr_bopi(name, f, 32) +# define dopi(name) fpr_opi(name, d, 64) +# define dbopi(name) fpr_bopi(name, d, 64) + +static void +_fstcwm(jit_state_t *_jit, jit_int32_t md, + jit_int32_t rb, jit_int32_t ri, jit_int32_t ms) +{ + ic(0x9b); + rex(0, 1, rb, ri, _NOREG); + x87rx(017, md, rb, ri, ms); +} + +static void +_x87rx(jit_state_t *_jit, jit_int32_t code, jit_int32_t md, + jit_int32_t rb, jit_int32_t ri, jit_int32_t ms) +{ + rex(0, 1, rb, ri, _NOREG); + ic(0xd8 | (code >> 3)); + rx((code & 7), md, rb, ri, ms); +} + +static void +_x87ri(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0) +{ + ic(0xd8 | (code >> 3)); + mrm(0x03, (code & 7), r0); +} + +static void +_x87rri(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0, jit_int32_t r1) +{ + if (r1 == _ST0_REGNO) + x87ri(code | 040, r0); + else { + assert(r0 == _ST0_REGNO); + x87ri(code, r1); + } +} + +fopi(add) +fopi(sub) +fopi(rsb) +fopi(mul) +fopi(div) + +static void +_x87_addr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r1) { + if (r2 == _ST0_REGNO) + faddr(r0, _ST0_REGNO); + else if (r0 == _ST0_REGNO) + faddr(_ST0_REGNO, r2); + else { + fxchr(r0); + faddr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2); + fxchr(r0); + } + } + else if (r0 == r2) { + if (r1 == _ST0_REGNO) + faddr(r0, _ST0_REGNO); + else if (r0 == _ST0_REGNO) + faddr(_ST0_REGNO, r1); + else { + fxchr(r0); + faddr(_ST0_REGNO, r1); + fxchr(r0); + } + } + else { + fldr(r1); + faddr(_ST0_REGNO, r2 + 1); + fstpr(r0 + 1); + } +} + +dopi(add) + +static void +_x87_subr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r1) { + if (r2 == _ST0_REGNO) + fsubrr(r0, _ST0_REGNO); + else if (r0 == _ST0_REGNO) + fsubr(_ST0_REGNO, r2); + else { + fxchr(r0); + fsubr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2); + fxchr(r0); + } + } + else if (r0 == r2) { + if (r1 == _ST0_REGNO) + fsubr(r0, _ST0_REGNO); + else if (r0 == _ST0_REGNO) + fsubrr(_ST0_REGNO, r1); + else { + fxchr(r0); + fsubrr(_ST0_REGNO, r1); + fxchr(r0); + } + } + else { + fldr(r1); + fsubr(_ST0_REGNO, r2 + 1); + fstpr(r0 + 1); + } +} + +dopi(sub) + +dopi(rsb) + +static void +_x87_mulr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r1) { + if (r2 == _ST0_REGNO) + fmulr(r0, _ST0_REGNO); + else if (r0 == _ST0_REGNO) + fmulr(_ST0_REGNO, r2); + else { + fxchr(r0); + fmulr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2); + fxchr(r0); + } + } + else if (r0 == r2) { + if (r1 == _ST0_REGNO) + fmulr(r0, _ST0_REGNO); + else if (r0 == _ST0_REGNO) + fmulr(_ST0_REGNO, r1); + else { + fxchr(r0); + fmulr(_ST0_REGNO, r1); + fxchr(r0); + } + } + else { + fldr(r1); + fmulr(_ST0_REGNO, r2 + 1); + fstpr(r0 + 1); + } +} + +dopi(mul) + +static void +_x87_divr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r1) { + if (r2 == _ST0_REGNO) + fdivrr(r0, _ST0_REGNO); + else if (r0 == _ST0_REGNO) + fdivr(_ST0_REGNO, r2); + else { + fxchr(r0); + fdivr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2); + fxchr(r0); + } + } + else if (r0 == r2) { + if (r1 == _ST0_REGNO) + fdivr(r0, _ST0_REGNO); + else if (r0 == _ST0_REGNO) + fsubrr(_ST0_REGNO, r1); + else { + fxchr(r0); + fdivrr(_ST0_REGNO, r1); + fxchr(r0); + } + } + else { + fldr(r1); + fdivr(_ST0_REGNO, r2 + 1); + fstpr(r0 + 1); + } +} + +dopi(div) + +static void +_x87_absr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) { + if (r1 == _ST0_REGNO) + fabs_(); + else { + fxchr(r0); + fabs_(); + fxchr(r0); + } + } + else { + fldr(r1); + fabs_(); + fstpr(r0 + 1); + } +} + +static void +_x87_negr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) { + if (r1 == _ST0_REGNO) + fchs_(); + else { + fxchr(r0); + fchs_(); + fxchr(r0); + } + } + else { + fldr(r1); + fchs_(); + fstpr(r0 + 1); + } +} + +static void +_x87_sqrtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == r1) { + if (r1 == _ST0_REGNO) + fsqrt_(); + else { + fxchr(r0); + fsqrt_(); + fxchr(r0); + } + } + else { + fldr(r1); + fsqrt_(); + fstpr(r0 + 1); + } +} + +static void +_x87_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ +#if defined(sun) + /* for the sake of passing test cases in x87 mode, otherwise only sse + * is supported */ + fstcwm(-4, _RBP_REGNO, _NOREG, _SCL1); + ldxi_s(r0, _RBP_REGNO, -4); + extr_uc(r0, r0); +# define FPCW_CHOP 0xc00 + ori(r0, r0, FPCW_CHOP); + stxi_s(-8, _RBP_REGNO, r0); + fldcwm(-8, _RBP_REGNO, _NOREG, _SCL1); + if (r1 == _ST0_REGNO) + fistlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1); + else { + fxchr(r1); + fistlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1); + fxchr(r1); + } + fldcwm(-4, _RBP_REGNO, _NOREG, _SCL1); + ldxi(r0, _RBP_REGNO, CVT_OFFSET); +#else + fldr(r1); + fisttplm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1); + ldxi_i(r0, _RBP_REGNO, CVT_OFFSET); +#endif +} + +# if __X64 +static void +_x87_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + fldr(r1); + fisttpqm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1); + ldxi(r0, _RBP_REGNO, CVT_OFFSET); +} +# endif + +static void +_x87_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + stxi(CVT_OFFSET, _RBP_REGNO, r1); +# if __X32 + fildlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1); +# else + fildqm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1); +# endif + fstpr(r0 + 1); +} + +static void +_x87cmp(jit_state_t *_jit, jit_int32_t code, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_bool_t rc; + jit_int32_t reg; + if ((rc = reg8_p(r0))) + reg = r0; + else { + reg = _RAX_REGNO; + movr(r0, reg); + } + ixorr(reg, reg); + if (r1 == _ST0_REGNO) + fucomir(r2); + else { + fldr(r1); + fucomipr(r2 + 1); + } + cc(code, reg); + if (!rc) + xchgr(r0, reg); +} + +static void +_x87cmp2(jit_state_t *_jit, jit_int32_t code, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_bool_t rc; + jit_int32_t reg; + jit_int32_t f1, f2; + if (r2 == _ST0_REGNO) f1 = r2, f2 = r1; + else f1 = r1, f2 = r2; + if ((rc = reg8_p(r0))) + reg = r0; + else { + reg = _RAX_REGNO; + movr(r0, reg); + } + ixorr(reg, reg); + if (f1 == _ST0_REGNO) + fucomir(f2); + else { + fldr(f1); + fucomipr(f2 + 1); + } + cc(code, reg); + if (!rc) + xchgr(r0, reg); +} + +static jit_word_t +_x87jcc(jit_state_t *_jit, jit_int32_t code, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 == _ST0_REGNO) + fucomir(r1); + else { + fldr(r0); + fucomipr(r1 + 1); + } + jcc(code, i0); + return (_jit->pc.w); +} + +static jit_word_t +_x87jcc2(jit_state_t *_jit, jit_int32_t code, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t f0, f1; + if (r1 == _ST0_REGNO) f0 = r1, f1 = r0; + else f0 = r0, f1 = r1; + if (f0 == _ST0_REGNO) + fucomir(f1); + else { + fldr(f0); + fucomipr(f1 + 1); + } + jcc(code, i0); + return (_jit->pc.w); +} + +fopi(lt) +fopi(le) +fopi(eq) +fopi(ge) +fopi(gt) +fopi(ne) +fopi(unlt) +fopi(unle) +fopi(uneq) +fopi(unge) +fopi(ungt) +fopi(ltgt) +fopi(ord) +fopi(unord) +fbopi(lt) +fbopi(le) +fbopi(eq) +fbopi(ge) +fbopi(gt) +fbopi(ne) +fbopi(unlt) +fbopi(unle) +fbopi(uneq) +fbopi(unge) +fbopi(ungt) +fbopi(ltgt) +fbopi(ord) +fbopi(unord) + +static void +_x87_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_int32_t reg; + + data.f = *i0; + if (data.f == 0.0 && !(data.i & 0x80000000)) + fldz(); + else if (data.f == 1.0) + fld1(); + else if (data.f == 3.3219280948873623478703195458468f) + fldl2t(); + else if (data.f == 1.4426950408889634073599246886656f) + fldl2e(); + else if (data.f == 3.1415926535897932384626421096161f) + fldpi(); + else if (data.f == 0.3010299956639811952137387498515f) + fldlg2(); + else if (data.f == 0.6931471805599453094172323683399f) + fldln2(); + else { + if (_jitc->no_data) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.i); + stxi_i(CVT_OFFSET, _RBP_REGNO, rn(reg)); + jit_unget_reg(reg); + x87_ldxi_f(r0, _RBP_REGNO, CVT_OFFSET); + } + else + x87_ldi_f(r0, (jit_word_t)i0); + return; + } + fstpr(r0 + 1); +} + +static void +_x87_ldr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + fldsm(0, r1, _NOREG, _SCL1); + fstpr(r0 + 1); +} + +static void +_x87_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (x87_address_p(i0)) { + fldsm(i0, _NOREG, _NOREG, _SCL1); + fstpr(r0 + 1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + x87_ldr_f(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_x87_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + x87_ldr_f(r0, rn(reg)); + jit_unget_reg(reg); +#else + fldsm(0, r1, r2, _SCL1); + fstpr(r0 + 1); +#endif +} + +static void +_x87_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + fldsm(i0, r1, _NOREG, _SCL1); + fstpr(r0 + 1); + } + else { + reg = jit_get_reg(jit_class_gpr); +#if __X64_32 + addi(rn(reg), r1, i0); + x87_ldr_f(r0, rn(reg)); +#else + movi(rn(reg), i0); + x87_ldxr_f(r0, r1, rn(reg)); +#endif + jit_unget_reg(reg); + } +} + +static void +_x87_str_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r1 == _ST0_REGNO) + fstsm(0, r0, _NOREG, _SCL1); + else { + fxchr(r1); + fstsm(0, r0, _NOREG, _SCL1); + fxchr(r1); + } +} + +static void +_x87_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (!x87_address_p(i0)) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + x87_str_f(rn(reg), r0); + jit_unget_reg(reg); + } + else if (r0 == _ST0_REGNO) + fstsm(i0, _NOREG, _NOREG, _SCL1); + else { + fxchr(r0); + fstsm(i0, _NOREG, _NOREG, _SCL1); + fxchr(r0); + } +} + +static void +_x87_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + x87_str_f(rn(reg), r2); + jit_unget_reg(reg); +#else + if (r2 == _ST0_REGNO) + fstsm(0, r0, r1, _SCL1); + else { + fxchr(r2); + fstsm(0, r0, r1, _SCL1); + fxchr(r2); + } +#endif +} + +static void +_x87_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (!can_sign_extend_int_p(i0)) { + reg = jit_get_reg(jit_class_gpr); +#if __X64_32 + addi(rn(reg), r0, i0); + x87_str_f(rn(reg), r1); +#else + movi(rn(reg), i0); + x87_stxr_f(rn(reg), r0, r1); +#endif + jit_unget_reg(reg); + } + else if (r1 == _ST0_REGNO) + fstsm(i0, r0, _NOREG, _SCL1); + else { + fxchr(r1); + fstsm(i0, r0, _NOREG, _SCL1); + fxchr(r1); + } +} + +static void +_x87_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) { + if (r1 == _ST0) + fstr(r0); + else if (r0 == _ST0) { + fxchr(r1); + fstr(r1); + } + else { + fldr(r1); + fstpr(r0 + 1); + } + } +} + +static void +_x87_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + union { + jit_int32_t ii[2]; + jit_word_t w; + jit_float64_t d; + } data; + jit_int32_t reg; + + data.d = *i0; + if (data.d == 0.0 && !(data.ii[1] & 0x80000000)) + fldz(); + else if (data.d == 1.0) + fld1(); + else if (data.d == 3.3219280948873623478703195458468) + fldl2t(); + else if (data.d == 1.4426950408889634073599246886656) + fldl2e(); + else if (data.d == 3.1415926535897932384626421096161) + fldpi(); + else if (data.d == 0.3010299956639811952137387498515) + fldlg2(); + else if (data.d == 0.6931471805599453094172323683399) + fldln2(); + else { + if (_jitc->no_data) { + reg = jit_get_reg(jit_class_gpr); +#if __X32 || __X64_32 + movi(rn(reg), data.ii[0]); + stxi_i(CVT_OFFSET, _RBP_REGNO, rn(reg)); + movi(rn(reg), data.ii[1]); + stxi_i(CVT_OFFSET + 4, _RBP_REGNO, rn(reg)); +#else + movi(rn(reg), data.w); + stxi_l(CVT_OFFSET, _RBP_REGNO, rn(reg)); +#endif + jit_unget_reg(reg); + x87_ldxi_d(r0, _RBP_REGNO, CVT_OFFSET); + } + else + x87_ldi_d(r0, (jit_word_t)i0); + return; + } + fstpr(r0 + 1); +} + +dopi(lt) +dopi(le) + +static void +_x87_eqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_bool_t rc; + jit_word_t jp_code; + jit_int32_t reg, f1, f2; + if (r2 == _ST0_REGNO) f1 = r2, f2 = r1; + else f1 = r1, f2 = r2; + if ((rc = reg8_p(r0))) + reg = r0; + else { + reg = _RAX_REGNO; + movr(r0, reg); + } + ixorr(reg, reg); + if (f1 == _ST0_REGNO) + fucomir(f2); + else { + fldr(f1); + fucomipr(f2 + 1); + } + jpes(0); + jp_code = _jit->pc.w; + cc(X86_CC_E, reg); + patch_rel_char(jp_code, _jit->pc.w); + if (!rc) + xchgr(r0, reg); +} + +dopi(eq) +dopi(ge) +dopi(gt) + +static void +_x87_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_bool_t rc; + jit_word_t jp_code; + jit_int32_t reg, f1, f2; + if (r2 == _ST0_REGNO) f1 = r2, f2 = r1; + else f1 = r1, f2 = r2; + if ((rc = reg8_p(r0))) + reg = r0; + else { + reg = _RAX_REGNO; + movr(r0, reg); + } + imovi(reg, 1); + if (f1 == _ST0_REGNO) + fucomir(f2); + else { + fldr(f1); + fucomipr(f2 + 1); + } + jpes(0); + jp_code = _jit->pc.w; + cc(X86_CC_NE, reg); + patch_rel_char(jp_code, _jit->pc.w); + if (!rc) + xchgr(r0, reg); +} + +dopi(ne) +dopi(unlt) +dopi(unle) +dopi(uneq) +dopi(unge) +dopi(ungt) + +static void +_x87_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r1 == r2) + movi(r0, 1); + else + x87cmp2(X86_CC_NE, r0, r1, r2); +} + +dopi(ltgt) +dopi(ord) +dopi(unord) + +static void +_x87_ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + fldlm(0, r1, _NOREG, _SCL1); + fstpr(r0 + 1); +} + +static void +_x87_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (x87_address_p(i0)) { + fldlm(i0, _NOREG, _NOREG, _SCL1); + fstpr(r0 + 1); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + x87_ldr_d(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_x87_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + x87_ldr_d(r0, rn(reg)); + jit_unget_reg(reg); +#else + fldlm(0, r1, r2, _SCL1); + fstpr(r0 + 1); +#endif +} + +static void +_x87_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_int_p(i0)) { + fldlm(i0, r1, _NOREG, _SCL1); + fstpr(r0 + 1); + } + else { + reg = jit_get_reg(jit_class_gpr); +#if __X64_32 + addi(rn(reg), r1, i0); + x87_ldr_d(r0, rn(reg)); +#else + movi(rn(reg), i0); + x87_ldxr_d(r0, r1, rn(reg)); +#endif + jit_unget_reg(reg); + } +} + +static void +_x87_str_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r1 == _ST0_REGNO) + fstlm(0, r0, _NOREG, _SCL1); + else { + fxchr(r1); + fstlm(0, r0, _NOREG, _SCL1); + fxchr(r1); + } +} + +static void +_x87_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (!x87_address_p(i0)) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + x87_str_d(rn(reg), r0); + jit_unget_reg(reg); + } + else if (r0 == _ST0_REGNO) + fstlm(i0, _NOREG, _NOREG, _SCL1); + else { + fxchr(r0); + fstlm(i0, _NOREG, _NOREG, _SCL1); + fxchr(r0); + } +} + +static void +_x87_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ +#if __X64_32 + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + x87_str_d(rn(reg), r2); + jit_unget_reg(reg); +#else + if (r2 == _ST0_REGNO) + fstlm(0, r0, r1, _SCL1); + else { + fxchr(r2); + fstlm(0, r0, r1, _SCL1); + fxchr(r2); + } +#endif +} + +static void +_x87_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (!can_sign_extend_int_p(i0)) { + reg = jit_get_reg(jit_class_gpr); +#if __X64_32 + addi(rn(reg), r0, i0); + x87_str_d(rn(reg), r1); +#else + movi(rn(reg), i0); + x87_stxr_d(rn(reg), r0, r1); +#endif + jit_unget_reg(reg); + } + else if (r1 == _ST0_REGNO) + fstlm(i0, r0, _NOREG, _SCL1); + else { + fxchr(r1); + fstlm(i0, r0, _NOREG, _SCL1); + fxchr(r1); + } +} + +dbopi(lt) +dbopi(le) + +static jit_word_t +_x87_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t f0, f1; + jit_word_t jp_code; + if (r1 == _ST0_REGNO) f0 = r1, f1 = r0; + else f0 = r0, f1 = r1; + if (f0 == _ST0_REGNO) + fucomir(f1); + else { + fldr(f0); + fucomipr(f1 + 1); + } + jpes(0); + jp_code = _jit->pc.w; + jcc(X86_CC_E, i0); + patch_rel_char(jp_code, _jit->pc.w); + return (_jit->pc.w); +} +dbopi(eq) +dbopi(ge) +dbopi(gt) + +static jit_word_t +_x87_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t f0, f1; + jit_word_t jp_code; + jit_word_t jz_code; + if (r1 == _ST0_REGNO) f0 = r1, f1 = r0; + else f0 = r0, f1 = r1; + if (f0 == _ST0_REGNO) + fucomir(f1); + else { + fldr(f0); + fucomipr(f1 + 1); + } + jpes(0); + jp_code = _jit->pc.w; + jzs(0); + jz_code = _jit->pc.w; + patch_rel_char(jp_code, _jit->pc.w); + jmpi(i0); + patch_rel_char(jz_code, _jit->pc.w); + return (_jit->pc.w); +} +dbopi(ne) +dbopi(unlt) +dbopi(unle) +dbopi(uneq) +dbopi(unge) +dbopi(ungt) +dbopi(ltgt) +dbopi(ord) +dbopi(unord) +# undef fopi +# undef fbopi +# undef dopi +# undef dbopi +# undef fpr_bopi +# undef fpr_opi +#endif diff --git a/deps/lightning/lib/jit_x86.c b/deps/lightning/lib/jit_x86.c new file mode 100644 index 0000000..c34a117 --- /dev/null +++ b/deps/lightning/lib/jit_x86.c @@ -0,0 +1,2264 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include <lightning.h> +#include <lightning/jit_private.h> + +#if __X32 +# define jit_arg_reg_p(i) 0 +# define jit_arg_f_reg_p(i) 0 +# define stack_framesize 20 +# define stack_adjust 12 +# define CVT_OFFSET -12 +# define REAL_WORDSIZE 4 +# define va_gp_increment 4 +# define va_fp_increment 8 +#else +# if __CYGWIN__ || _WIN32 +# define jit_arg_reg_p(i) ((i) >= 0 && (i) < 4) +# define jit_arg_f_reg_p(i) jit_arg_reg_p(i) +# define stack_framesize 152 +# define va_fp_increment 8 +# else +# define jit_arg_reg_p(i) ((i) >= 0 && (i) < 6) +# define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 8) +# define stack_framesize 56 +# define first_gp_argument rdi +# define first_gp_offset offsetof(jit_va_list_t, rdi) +# define first_gp_from_offset(gp) ((gp) / 8) +# define last_gp_argument r9 +# define va_gp_max_offset \ + (offsetof(jit_va_list_t, r9) - offsetof(jit_va_list_t, rdi) + 8) +# define first_fp_argument xmm0 +# define first_fp_offset offsetof(jit_va_list_t, xmm0) +# define last_fp_argument xmm7 +# define va_fp_max_offset \ + (offsetof(jit_va_list_t, xmm7) - offsetof(jit_va_list_t, rdi) + 16) +# define va_fp_increment 16 +# define first_fp_from_offset(fp) (((fp) - va_gp_max_offset) / 16) +# endif +# define va_gp_increment 8 +# define stack_adjust 8 +# define CVT_OFFSET -8 +# define REAL_WORDSIZE 8 +#endif + +/* + * Types + */ +#if __X32 || __CYGWIN__ || _WIN32 +typedef jit_pointer_t jit_va_list_t; +#else +typedef struct jit_va_list { + jit_int32_t gpoff; + jit_int32_t fpoff; + jit_pointer_t over; + jit_pointer_t save; + /* Declared explicitly as int64 for the x32 abi */ + jit_int64_t rdi; + jit_int64_t rsi; + jit_int64_t rdx; + jit_int64_t rcx; + jit_int64_t r8; + jit_int64_t r9; + jit_float64_t xmm0; + jit_float64_t _up0; + jit_float64_t xmm1; + jit_float64_t _up1; + jit_float64_t xmm2; + jit_float64_t _up2; + jit_float64_t xmm3; + jit_float64_t _up3; + jit_float64_t xmm4; + jit_float64_t _up4; + jit_float64_t xmm5; + jit_float64_t _up5; + jit_float64_t xmm6; + jit_float64_t _up6; + jit_float64_t xmm7; + jit_float64_t _up7; +} jit_va_list_t; +#endif + +/* + * Prototypes + */ +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); +#define sse_from_x87_f(r0, r1) _sse_from_x87_f(_jit, r0, r1) +static void _sse_from_x87_f(jit_state_t*,jit_int32_t,jit_int32_t); +#define sse_from_x87_d(r0, r1) _sse_from_x87_d(_jit, r0, r1) +static void _sse_from_x87_d(jit_state_t*,jit_int32_t,jit_int32_t); +#define x87_from_sse_f(r0, r1) _x87_from_sse_f(_jit, r0, r1) +static void _x87_from_sse_f(jit_state_t*,jit_int32_t,jit_int32_t); +#define x87_from_sse_d(r0, r1) _x87_from_sse_d(_jit, r0, r1) +static void _x87_from_sse_d(jit_state_t*,jit_int32_t,jit_int32_t); + +#define PROTO 1 +# include "jit_x86-cpu.c" +# include "jit_x86-sse.c" +# include "jit_x86-x87.c" +#undef PROTO + +/* + * Initialization + */ +jit_cpu_t jit_cpu; +jit_register_t _rvs[] = { +#if __X32 + { rc(gpr) | rc(rg8) | 0, "%eax" }, + { rc(gpr) | rc(rg8) | 1, "%ecx" }, + { rc(gpr) | rc(rg8) | 2, "%edx" }, + { rc(sav) | rc(rg8) | rc(gpr) | 3, "%ebx" }, + { rc(sav) | rc(gpr) | 6, "%esi" }, + { rc(sav) | rc(gpr) | 7, "%edi" }, + { rc(sav) | 4, "%esp" }, + { rc(sav) | 5, "%ebp" }, + { rc(xpr) | rc(fpr) | 0, "%xmm0" }, + { rc(xpr) | rc(fpr) | 1, "%xmm1" }, + { rc(xpr) | rc(fpr) | 2, "%xmm2" }, + { rc(xpr) | rc(fpr) | 3, "%xmm3" }, + { rc(xpr) | rc(fpr) | 4, "%xmm4" }, + { rc(xpr) | rc(fpr) | 5, "%xmm5" }, + { rc(xpr) | rc(fpr) | 6, "%xmm6" }, + { rc(xpr) | rc(fpr) | 7, "%xmm7" }, + { rc(fpr) | 0, "st(0)" }, + { rc(fpr) | 1, "st(1)" }, + { rc(fpr) | 2, "st(2)" }, + { rc(fpr) | 3, "st(3)" }, + { rc(fpr) | 4, "st(4)" }, + { rc(fpr) | 5, "st(5)" }, + { rc(fpr) | 6, "st(6)" }, + { rc(fpr) | 7, "st(7)" }, +#else +# if __CYGWIN__ || _WIN32 + { rc(gpr) | rc(rg8) | 0, "%rax" }, + { rc(gpr) | rc(rg8) | rc(rg8) | 10, "%r10" }, + { rc(gpr) | rc(rg8) | rc(rg8) | 11, "%r11" }, + { rc(sav) | rc(rg8) | rc(gpr) | 3, "%rbx" }, + { rc(sav) | rc(gpr) | 7, "%rdi" }, + { rc(sav) | rc(gpr) | 6, "%rsi" }, + { rc(sav) | rc(gpr) | 12, "%r12" }, + { rc(sav) | rc(gpr) | 13, "%r13" }, + { rc(sav) | rc(gpr) | 14, "%r14" }, + { rc(sav) | rc(gpr) | 15, "%r15" }, + { rc(arg) | rc(rg8) | rc(gpr) | 9, "%r9" }, + { rc(arg) | rc(rg8) | rc(gpr) | 8, "%r8" }, + { rc(arg) | rc(rg8) | rc(gpr) | 2, "%rdx" }, + { rc(arg) | rc(rg8) | rc(gpr) | 1, "%rcx" }, + { rc(sav) | 4, "%rsp" }, + { rc(sav) | 5, "%rbp" }, + { rc(xpr) | rc(fpr) | 4, "%xmm4" }, + { rc(xpr) | rc(fpr) | 5, "%xmm5" }, + { rc(sav) | rc(xpr) | rc(fpr) | 6, "%xmm6" }, + { rc(sav) | rc(xpr) | rc(fpr) | 7, "%xmm7" }, + { rc(sav) | rc(xpr) | rc(fpr) | 8, "%xmm8" }, + { rc(sav) | rc(xpr) | rc(fpr) | 9, "%xmm9" }, + { rc(sav) | rc(xpr) | rc(fpr) | 10, "%xmm10" }, + { rc(sav) | rc(xpr) | rc(fpr) | 11, "%xmm11" }, + { rc(sav) | rc(xpr) | rc(fpr) | 12, "%xmm12" }, + { rc(sav) | rc(xpr) | rc(fpr) | 13, "%xmm13" }, + { rc(sav) | rc(xpr) | rc(fpr) | 14, "%xmm14" }, + { rc(sav) | rc(xpr) | rc(fpr) | 15, "%xmm15" }, + { rc(xpr) | rc(arg) | rc(fpr) | 3, "%xmm3" }, + { rc(xpr) | rc(arg) | rc(fpr) | 2, "%xmm2" }, + { rc(xpr) | rc(arg) | rc(fpr) | 1, "%xmm1" }, + { rc(xpr) | rc(arg) | rc(fpr) | 0, "%xmm0" }, +#else + /* %rax is a pseudo flag argument for varargs functions */ + { rc(arg) | rc(gpr) | rc(rg8) | 0, "%rax" }, + { rc(gpr) | rc(rg8) | 10, "%r10" }, + { rc(gpr) | rc(rg8) | 11, "%r11" }, + { rc(sav) | rc(rg8) | rc(gpr) | 3, "%rbx" }, + { rc(sav) | rc(rg8) | rc(gpr) | 13, "%r13" }, + { rc(sav) | rc(rg8) | rc(gpr) | 14, "%r14" }, + { rc(sav) | rc(rg8) | rc(gpr) | 15, "%r15" }, + { rc(sav) | rc(gpr) | rc(rg8) | 12, "%r12" }, + { rc(arg) | rc(rg8) | rc(gpr) | 9, "%r9" }, + { rc(arg) | rc(rg8) | rc(gpr) | 8, "%r8" }, + { rc(arg) | rc(rg8) | rc(gpr) | 1, "%rcx" }, + { rc(arg) | rc(rg8) | rc(gpr) | 2, "%rdx" }, + { rc(arg) | rc(rg8) | rc(gpr) | 6, "%rsi" }, + { rc(arg) | rc(rg8) | rc(gpr) | 7, "%rdi" }, + { rc(sav) | 4, "%rsp" }, + { rc(sav) | 5, "%rbp" }, + { rc(xpr) | rc(fpr) | 8, "%xmm8" }, + { rc(xpr) | rc(fpr) | 9, "%xmm9" }, + { rc(xpr) | rc(fpr) | 10, "%xmm10" }, + { rc(xpr) | rc(fpr) | 11, "%xmm11" }, + { rc(xpr) | rc(fpr) | 12, "%xmm12" }, + { rc(xpr) | rc(fpr) | 13, "%xmm13" }, + { rc(xpr) | rc(fpr) | 14, "%xmm14" }, + { rc(xpr) | rc(fpr) | 15, "%xmm15" }, + { rc(xpr) | rc(arg) | rc(fpr) | 7, "%xmm7" }, + { rc(xpr) | rc(arg) | rc(fpr) | 6, "%xmm6" }, + { rc(xpr) | rc(arg) | rc(fpr) | 5, "%xmm5" }, + { rc(xpr) | rc(arg) | rc(fpr) | 4, "%xmm4" }, + { rc(xpr) | rc(arg) | rc(fpr) | 3, "%xmm3" }, + { rc(xpr) | rc(arg) | rc(fpr) | 2, "%xmm2" }, + { rc(xpr) | rc(arg) | rc(fpr) | 1, "%xmm1" }, + { rc(xpr) | rc(arg) | rc(fpr) | 0, "%xmm0" }, +# endif + { rc(fpr) | 0, "st(0)" }, + { rc(fpr) | 1, "st(1)" }, + { rc(fpr) | 2, "st(2)" }, + { rc(fpr) | 3, "st(3)" }, + { rc(fpr) | 4, "st(4)" }, + { rc(fpr) | 5, "st(5)" }, + { rc(fpr) | 6, "st(6)" }, + { rc(fpr) | 7, "st(7)" }, +#endif + { _NOREG, "<none>" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ + union { + struct { + jit_uint32_t sse3 : 1; + jit_uint32_t pclmulqdq : 1; + jit_uint32_t dtes64 : 1; /* amd reserved */ + jit_uint32_t monitor : 1; + jit_uint32_t ds_cpl : 1; /* amd reserved */ + jit_uint32_t vmx : 1; /* amd reserved */ + jit_uint32_t smx : 1; /* amd reserved */ + jit_uint32_t est : 1; /* amd reserved */ + jit_uint32_t tm2 : 1; /* amd reserved */ + jit_uint32_t ssse3 : 1; + jit_uint32_t cntx_id : 1; /* amd reserved */ + jit_uint32_t __reserved0 : 1; + jit_uint32_t fma : 1; + jit_uint32_t cmpxchg16b : 1; + jit_uint32_t xtpr : 1; /* amd reserved */ + jit_uint32_t pdcm : 1; /* amd reserved */ + jit_uint32_t __reserved1 : 1; + jit_uint32_t pcid : 1; /* amd reserved */ + jit_uint32_t dca : 1; /* amd reserved */ + jit_uint32_t sse4_1 : 1; + jit_uint32_t sse4_2 : 1; + jit_uint32_t x2apic : 1; /* amd reserved */ + jit_uint32_t movbe : 1; /* amd reserved */ + jit_uint32_t popcnt : 1; + jit_uint32_t tsc : 1; /* amd reserved */ + jit_uint32_t aes : 1; + jit_uint32_t xsave : 1; + jit_uint32_t osxsave : 1; + jit_uint32_t avx : 1; + jit_uint32_t __reserved2 : 1; /* amd F16C */ + jit_uint32_t __reserved3 : 1; + jit_uint32_t __alwayszero : 1; /* amd RAZ */ + } bits; + jit_uword_t cpuid; + } ecx; + union { + struct { + jit_uint32_t fpu : 1; + jit_uint32_t vme : 1; + jit_uint32_t de : 1; + jit_uint32_t pse : 1; + jit_uint32_t tsc : 1; + jit_uint32_t msr : 1; + jit_uint32_t pae : 1; + jit_uint32_t mce : 1; + jit_uint32_t cmpxchg8b : 1; + jit_uint32_t apic : 1; + jit_uint32_t __reserved0 : 1; + jit_uint32_t sep : 1; + jit_uint32_t mtrr : 1; + jit_uint32_t pge : 1; + jit_uint32_t mca : 1; + jit_uint32_t cmov : 1; + jit_uint32_t pat : 1; + jit_uint32_t pse36 : 1; + jit_uint32_t psn : 1; /* amd reserved */ + jit_uint32_t clfsh : 1; + jit_uint32_t __reserved1 : 1; + jit_uint32_t ds : 1; /* amd reserved */ + jit_uint32_t acpi : 1; /* amd reserved */ + jit_uint32_t mmx : 1; + jit_uint32_t fxsr : 1; + jit_uint32_t sse : 1; + jit_uint32_t sse2 : 1; + jit_uint32_t ss : 1; /* amd reserved */ + jit_uint32_t htt : 1; + jit_uint32_t tm : 1; /* amd reserved */ + jit_uint32_t __reserved2 : 1; + jit_uint32_t pbe : 1; /* amd reserved */ + } bits; + jit_uword_t cpuid; + } edx; +#if __X32 + int ac, flags; +#endif + jit_uword_t eax, ebx; + +#if __X32 + /* adapted from glibc __sysconf */ + __asm__ volatile ("pushfl;\n\t" + "popl %0;\n\t" + "movl $0x240000, %1;\n\t" + "xorl %0, %1;\n\t" + "pushl %1;\n\t" + "popfl;\n\t" + "pushfl;\n\t" + "popl %1;\n\t" + "xorl %0, %1;\n\t" + "pushl %0;\n\t" + "popfl" + : "=r" (flags), "=r" (ac)); + + /* i386 or i486 without cpuid */ + if ((ac & (1 << 21)) == 0) + /* probably without x87 as well */ + return; +#endif + + /* query %eax = 1 function */ +#if __X32 || __X64_32 + __asm__ volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" +#else + __asm__ volatile ("xchgq %%rbx, %1; cpuid; xchgq %%rbx, %1" +#endif + : "=a" (eax), "=r" (ebx), + "=c" (ecx.cpuid), "=d" (edx.cpuid) + : "0" (1)); + + jit_cpu.fpu = edx.bits.fpu; + jit_cpu.cmpxchg8b = edx.bits.cmpxchg8b; + jit_cpu.cmov = edx.bits.cmov; + jit_cpu.mmx = edx.bits.mmx; + jit_cpu.sse = edx.bits.sse; + jit_cpu.sse2 = edx.bits.sse2; + jit_cpu.sse3 = ecx.bits.sse3; + jit_cpu.pclmulqdq = ecx.bits.pclmulqdq; + jit_cpu.ssse3 = ecx.bits.ssse3; + jit_cpu.fma = ecx.bits.fma; + jit_cpu.cmpxchg16b = ecx.bits.cmpxchg16b; + jit_cpu.sse4_1 = ecx.bits.sse4_1; + jit_cpu.sse4_2 = ecx.bits.sse4_2; + jit_cpu.movbe = ecx.bits.movbe; + jit_cpu.popcnt = ecx.bits.popcnt; + jit_cpu.aes = ecx.bits.aes; + jit_cpu.avx = ecx.bits.avx; + + /* query %eax = 0x80000001 function */ +#if __X64 +# if __X64_32 + __asm__ volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" +# else + __asm__ volatile ("xchgq %%rbx, %1; cpuid; xchgq %%rbx, %1" +# endif + : "=a" (eax), "=r" (ebx), + "=c" (ecx.cpuid), "=d" (edx.cpuid) + : "0" (0x80000001)); + jit_cpu.lahf = ecx.cpuid & 1; +#endif +} + +void +_jit_init(jit_state_t *_jit) +{ +#if __X32 + jit_int32_t regno; + static jit_bool_t first = 1; +#endif + + _jitc->reglen = jit_size(_rvs) - 1; +#if __X32 + if (first) { + if (!jit_cpu.sse2) { + for (regno = _jitc->reglen; regno >= 0; regno--) { + if (_rvs[regno].spec & jit_class_xpr) + _rvs[regno].spec = 0; + } + } + first = 0; + } +#endif +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + _jitc->function->self.size = stack_framesize; + _jitc->function->self.argi = _jitc->function->self.argf = + _jitc->function->self.aoff = _jitc->function->self.alen = 0; + /* sse/x87 conversion */ + _jitc->function->self.aoff = CVT_OFFSET; + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + assert(_jitc->function); + switch (length) { + case 0: case 1: break; + case 2: _jitc->function->self.aoff &= -2; break; + case 3: case 4: _jitc->function->self.aoff &= -4; break; + default: _jitc->function->self.aoff &= -8; break; + } + _jitc->function->self.aoff -= length; + + /* jit_allocai() may be called from jit_x86-cpu.c, and force a function + * generation restart on some conditions: div/rem and qmul/qdiv, due + * to registers constraints. + * The check is to prevent an assertion of a jit_xyz() being called + * during code generation, and attempting to add a node to the tail + * of the current IR generation. */ + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } + + return (_jitc->function->self.aoff); +} + +void +_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) +{ + jit_int32_t reg; + assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); + if (!_jitc->function->allocar) { + _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); + _jitc->function->allocar = 1; + } + reg = jit_get_reg(jit_class_gpr); + jit_negr(reg, v); + jit_andi(reg, reg, -16); + jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); + jit_addr(u, u, reg); + jit_addr(JIT_SP, JIT_SP, reg); + jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); + jit_unget_reg(reg); + jit_dec_synth(); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + assert(_jitc->function); + jit_inc_synth(ret); + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr, u); + /* movr(%ret, %ret) would be optimized out */ + if (JIT_RET != u) + jit_movr(JIT_RET, u); + /* explicitly tell it is live */ + jit_live(JIT_RET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti(jit_state_t *_jit, jit_word_t u) +{ + jit_inc_synth_w(reti, u); + jit_movi(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_f, u); + if (JIT_FRET != u) + jit_movr_f(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_inc_synth_f(reti_f, u); + jit_movi_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_d, u); + if (JIT_FRET != u) + jit_movr_d(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_inc_synth_d(reti_d, u); + jit_movi_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_epilog(jit_state_t *_jit) +{ + assert(_jitc->function); + assert(_jitc->function->epilog->next == NULL); + jit_link(_jitc->function->epilog); + _jitc->function = NULL; +} + +jit_bool_t +_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) +{ + if (u->code == jit_code_arg) + return (jit_arg_reg_p(u->u.w)); + assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d); + return (jit_arg_f_reg_p(u->u.w)); +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + jit_inc_synth(ellipsis); + if (_jitc->prepare) { + jit_link_prepare(); + /* Remember that a varargs function call is being constructed. */ + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; + } + else { + jit_link_prolog(); + /* Remember the current function is varargs. */ + assert(!(_jitc->function->self.call & jit_call_varargs)); + _jitc->function->self.call |= jit_call_varargs; + +#if __X64 && !(__CYGWIN__ || _WIN32) + /* Allocate va_list like object in the stack. + * If applicable, with enough space to save all argument + * registers, and use fixed offsets for them. */ + _jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t)); + + /* Initialize gp offset in save area. */ + if (jit_arg_reg_p(_jitc->function->self.argi)) + _jitc->function->vagp = _jitc->function->self.argi * 8; + else + _jitc->function->vagp = va_gp_max_offset; + + /* Initialize fp offset in save area. */ + if (jit_arg_f_reg_p(_jitc->function->self.argf)) + _jitc->function->vafp = _jitc->function->self.argf * 16 + + va_gp_max_offset; + else + _jitc->function->vafp = va_fp_max_offset; +#endif + } + jit_dec_synth(); +} + +void +_jit_va_push(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(va_push, u); + jit_pushargr(u); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + assert(!(_jitc->function->self.call & jit_call_varargs)); +#if __X64 + if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi++; +# if __CYGWIN__ || _WIN32 + _jitc->function->self.size += sizeof(jit_word_t); +# endif + } + else +#endif + { + offset = _jitc->function->self.size; + _jitc->function->self.size += REAL_WORDSIZE; + } + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + assert(!(_jitc->function->self.call & jit_call_varargs)); +#if __X64 +# if __CYGWIN__ || _WIN32 + if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi++; + _jitc->function->self.size += sizeof(jit_word_t); + } +# else + if (jit_arg_f_reg_p(_jitc->function->self.argf)) + offset = _jitc->function->self.argf++; +# endif + else +#endif + { + offset = _jitc->function->self.size; + _jitc->function->self.size += REAL_WORDSIZE; + } + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + assert(!(_jitc->function->self.call & jit_call_varargs)); +#if __X64 +# if __CYGWIN__ || _WIN32 + if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi++; + _jitc->function->self.size += sizeof(jit_word_t); + } +# else + if (jit_arg_f_reg_p(_jitc->function->self.argf)) + offset = _jitc->function->self.argf++; +# endif + else +#endif + { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_float64_t); + } + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +void +_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); +#if __X64 + if (jit_arg_reg_p(v->u.w)) + jit_extr_c(u, JIT_RA0 - v->u.w); + else +#endif + jit_ldxi_c(u, _RBP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); +#if __X64 + if (jit_arg_reg_p(v->u.w)) + jit_extr_uc(u, JIT_RA0 - v->u.w); + else +#endif + jit_ldxi_uc(u, _RBP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); +#if __X64 + if (jit_arg_reg_p(v->u.w)) + jit_extr_s(u, JIT_RA0 - v->u.w); + else +#endif + jit_ldxi_s(u, _RBP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); +#if __X64 + if (jit_arg_reg_p(v->u.w)) + jit_extr_us(u, JIT_RA0 - v->u.w); + else +#endif + jit_ldxi_us(u, _RBP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); +#if __X64 + if (jit_arg_reg_p(v->u.w)) { +# if __X64_32 + jit_movr(u, JIT_RA0 - v->u.w); +# else + jit_extr_i(u, JIT_RA0 - v->u.w); +# endif + } + else +#endif + jit_ldxi_i(u, _RBP, v->u.w); + jit_dec_synth(); +} + +#if __X64 && !__X64_32 +void +_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_ui(u, JIT_RA0 - v->u.w); + else + jit_ldxi_ui(u, _RBP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(u, JIT_RA0 - v->u.w); + else + jit_ldxi_l(u, _RBP, v->u.w); + jit_dec_synth(); +} +#endif + +void +_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); +#if __X64 + if (jit_arg_reg_p(v->u.w)) + jit_movr(JIT_RA0 - v->u.w, u); + else +#endif + jit_stxi(v->u.w, _RBP, u); + jit_dec_synth(); +} + +void +_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); +#if __X64 + if (jit_arg_reg_p(v->u.w)) + jit_movi(JIT_RA0 - v->u.w, u); + else +#endif + { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(v->u.w, _RBP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); +#if __X64 + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_f(u, _XMM0 - v->u.w); + else +#endif + jit_ldxi_f(u, _RBP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); +#if __X64 + if (jit_arg_reg_p(v->u.w)) + jit_movr_f(_XMM0 - v->u.w, u); + else +#endif + jit_stxi_f(v->u.w, _RBP, u); + jit_dec_synth(); +} + +void +_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); +#if __X64 + if (jit_arg_reg_p(v->u.w)) + jit_movi_f(_XMM0 - v->u.w, u); + else +#endif + { + regno = jit_get_reg(jit_class_gpr); + jit_movi_f(regno, u); + jit_stxi_f(v->u.w, _RBP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); +#if __X64 + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(u, _XMM0 - v->u.w); + else +#endif + jit_ldxi_d(u, _RBP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); +#if __X64 + if (jit_arg_reg_p(v->u.w)) + jit_movr_d(_XMM0 - v->u.w, u); + else +#endif + jit_stxi_d(v->u.w, _RBP, u); + jit_dec_synth(); +} + +void +_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); +#if __X64 + if (jit_arg_reg_p(v->u.w)) + jit_movi_d(_XMM0 - v->u.w, u); + else +#endif + { + regno = jit_get_reg(jit_class_gpr); + jit_movi_d(regno, u); + jit_stxi_d(v->u.w, _RBP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); +#if __X64 + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr(JIT_RA0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; +# if __CYGWIN__ || _WIN32 + if (_jitc->function->call.call & jit_call_varargs) + jit_stxi(_jitc->function->call.size, _RSP, u); + _jitc->function->call.size += sizeof(jit_word_t); +# endif + } + else +#endif + { + jit_stxi(_jitc->function->call.size, _RSP, u); + _jitc->function->call.size += REAL_WORDSIZE; + } + jit_dec_synth(); +} + +void +_jit_pushargi(jit_state_t *_jit, jit_word_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); +#if __X64 + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi(JIT_RA0 - _jitc->function->call.argi, u); +# if __CYGWIN__ || _WIN32 + if (_jitc->function->call.call & jit_call_varargs) + jit_stxi(_jitc->function->call.size, _RSP, + JIT_RA0 - _jitc->function->call.argi); + _jitc->function->call.size += sizeof(jit_word_t); +# endif + ++_jitc->function->call.argi; + } + else +#endif + { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size, _RSP, regno); + _jitc->function->call.size += REAL_WORDSIZE; + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); +#if __X64 +# if __CYGWIN__ || _WIN32 + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr_f(_XMM0 - _jitc->function->call.argi, u); + if (_jitc->function->call.call & jit_call_varargs) { + jit_stxi_f(_jitc->function->call.size, _RSP, + _XMM0 - _jitc->function->call.argi); + jit_ldxi_i(JIT_RA0 - _jitc->function->call.argi, _RSP, + _jitc->function->call.size); + } + ++_jitc->function->call.argi; + _jitc->function->call.size += sizeof(jit_word_t); + } +# else + if (jit_arg_f_reg_p(_jitc->function->self.argf)) { + jit_movr_f(_XMM0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } +# endif + else +#endif + { + jit_stxi_f(_jitc->function->call.size, _RSP, u); + _jitc->function->call.size += REAL_WORDSIZE; + } + jit_dec_synth(); +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); +#if __X64 +# if __CYGWIN__ || _WIN32 + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi_f(_XMM0 - _jitc->function->call.argi, u); + if (_jitc->function->call.call & jit_call_varargs) { + jit_stxi_f(_jitc->function->call.size, _RSP, + _XMM0 - _jitc->function->call.argi); + jit_ldxi_i(JIT_RA0 - _jitc->function->call.argi, _RSP, + _jitc->function->call.size); + } + ++_jitc->function->call.argi; + _jitc->function->call.size += sizeof(jit_word_t); + } +# else + if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_movi_f(_XMM0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } +# endif + else +#endif + { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(_jitc->function->call.size, _RSP, regno); + _jitc->function->call.size += REAL_WORDSIZE; + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); +#if __X64 +# if __CYGWIN__ || _WIN32 + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr_d(_XMM0 - _jitc->function->call.argi, u); + if (_jitc->function->call.call & jit_call_varargs) { + jit_stxi_d(_jitc->function->call.size, _RSP, + _XMM0 - _jitc->function->call.argi); + jit_ldxi_l(JIT_RA0 - _jitc->function->call.argi, _RSP, + _jitc->function->call.size); + } + ++_jitc->function->call.argi; + _jitc->function->call.size += sizeof(jit_word_t); + } +# else + if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_movr_d(_XMM0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } +# endif + else +#endif + { + jit_stxi_d(_jitc->function->call.size, _RSP, u); + _jitc->function->call.size += sizeof(jit_float64_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); +#if __X64 +# if __CYGWIN__ || _WIN32 + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi_d(_XMM0 - _jitc->function->call.argi, u); + if (_jitc->function->call.call & jit_call_varargs) { + jit_stxi_d(_jitc->function->call.size, _RSP, + _XMM0 - _jitc->function->call.argi); + jit_ldxi_l(JIT_RA0 - _jitc->function->call.argi, _RSP, + _jitc->function->call.size); + } + ++_jitc->function->call.argi; + _jitc->function->call.size += sizeof(jit_word_t); + } +# else + if (jit_arg_f_reg_p(_jitc->function->call.argf)) { + jit_movi_d(_XMM0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } +# endif + else +#endif + { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(_jitc->function->call.size, _RSP, regno); + _jitc->function->call.size += sizeof(jit_float64_t); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ +#if __X64 + jit_int32_t spec; + + spec = jit_class(_rvs[regno].spec); + if (spec & jit_class_arg) { + if (spec & jit_class_gpr) { + regno = JIT_RA0 - regno; + if (regno >= 0 && regno < node->v.w) + return (1); + } + else if (spec & jit_class_fpr) { + regno = _XMM0 - regno; + if (regno >= 0 && regno < node->w.w) + return (1); + } + } +#endif + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_int32_t reg; + jit_node_t *call; + assert(_jitc->function); + reg = r0; + jit_inc_synth_w(finishr, r0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; +#if __X64 +# if !(__CYGWIN__ || _WIN32) + if (_jitc->function->call.call & jit_call_varargs) { + if (jit_regno(reg) == _RAX) { + reg = jit_get_reg(jit_class_gpr); + jit_movr(reg, _RAX); + } + if (_jitc->function->call.argf) + jit_movi(_RAX, _jitc->function->call.argf); + else + jit_movi(_RAX, 0); + if (reg != r0) + jit_unget_reg(reg); + } +# endif +#endif + call = jit_callr(reg); + call->v.w = _jitc->function->call.argi; + call->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ +#if __X64 + jit_int32_t reg; +#endif + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; +#if __X64 + /* FIXME preventing %rax allocation is good enough, but for consistency + * it should automatically detect %rax is dead, in case it has run out + * registers, and not save/restore it, what would be wrong if using the + * the return value, otherwise, just a needless noop */ + /* >> prevent %rax from being allocated as the function pointer */ + jit_regset_setbit(&_jitc->regarg, _RAX); + reg = jit_get_reg(jit_class_gpr); + node = jit_movi(reg, (jit_word_t)i0); + jit_finishr(reg); + jit_unget_reg(reg); + /* << prevent %rax from being allocated as the function pointer */ + jit_regset_clrbit(&_jitc->regarg, _RAX); +#else + node = jit_calli(i0); + node->v.w = _jitc->function->call.argi; + node->w.w = _jitc->function->call.argf; +#endif + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); + return (node); +} + +void +_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_c, r0); + jit_extr_c(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_uc, r0); + jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_s, r0); + jit_extr_s(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_us, r0); + jit_extr_us(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_i, r0); +#if __X32 || __X64_32 + if (r0 != JIT_RET) + jit_movr(r0, JIT_RET); +#else + jit_extr_i(r0, JIT_RET); +#endif + jit_dec_synth(); +} + +#if __X64 && !__X64_32 +void +_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_ui, r0); + jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_l, r0); + if (r0 != JIT_RET) + jit_movr(r0, JIT_RET); + jit_dec_synth(); +} +#endif + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_f, r0); +#if __X64 + if (r0 != JIT_FRET) + jit_movr_f(r0, JIT_FRET); +#endif + jit_dec_synth(); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_d, r0); +#if __X64 + if (r0 != JIT_FRET) + jit_movr_d(r0, JIT_FRET); +#endif + jit_dec_synth(); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_int32_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + jit_int32_t patch_offset; + } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + + _jitc->function = NULL; + + jit_reglive_setup(); + + undo.word = 0; + undo.node = NULL; + undo.patch_offset = 0; +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_rf(name, type) \ + case jit_code_##name##r##type: \ + if (jit_x87_reg_p(node->v.w)) \ + x87_##name##r##type(rn(node->u.w), rn(node->v.w)); \ + else \ + sse_##name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_fr(name, type) \ + case jit_code_##name##r##type: \ + if (jit_x87_reg_p(node->u.w)) \ + x87_##name##r##type(rn(node->u.w), rn(node->v.w)); \ + else \ + sse_##name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_fw(name, type) \ + case jit_code_##name##i##type: \ + if (jit_x87_reg_p(node->u.w)) \ + x87_##name##i##type(rn(node->u.w), node->v.w); \ + else \ + sse_##name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_wf(name, type) \ + case jit_code_##name##i##type: \ + if (jit_x87_reg_p(node->v.w)) \ + x87_##name##i##type(node->u.w, rn(node->v.w)); \ + else \ + sse_##name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_ff(name, type) \ + case jit_code_##name##r##type: \ + if (jit_x87_reg_p(node->u.w) && \ + jit_x87_reg_p(node->v.w)) \ + x87_##name##r##type(rn(node->u.w), rn(node->v.w)); \ + else \ + sse_##name##r##type(rn(node->u.w), rn(node->v.w)); \ + break; +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_frr(name, type) \ + case jit_code_##name##r##type: \ + if (jit_x87_reg_p(node->u.w)) \ + x87_##name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + else \ + sse_##name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrf(name, type) \ + case jit_code_##name##r##type: \ + if (jit_x87_reg_p(node->w.w)) \ + x87_##name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + else \ + sse_##name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_frw(name, type) \ + case jit_code_##name##i##type: \ + if (jit_x87_reg_p(node->u.w)) \ + x87_##name##i##type(rn(node->u.w), \ + rn(node->v.w), node->w.w); \ + else \ + sse_##name##i##type(rn(node->u.w), \ + rn(node->v.w), node->w.w); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \ + break +#define case_wrf(name, type) \ + case jit_code_##name##i##type: \ + if (jit_x87_reg_p(node->w.w)) \ + x87_##name##i##type(node->u.w, \ + rn(node->v.w), rn(node->w.w)); \ + else \ + sse_##name##i##type(node->u.w, \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type(_jit->pc.w, \ + rn(node->v.w), rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break +#define case_rff(name, type) \ + case jit_code_##name##r##type: \ + if (jit_x87_reg_p(node->v.w) && \ + jit_x87_reg_p(node->w.w)) \ + x87_##name##r##type(rn(node->u.w), rn(node->v.w), \ + rn(node->w.w)); \ + else \ + sse_##name##r##type(rn(node->u.w), rn(node->v.w), \ + rn(node->w.w)); \ + break; +#define case_rfw(name, type, size) \ + case jit_code_##name##i##type: \ + assert(node->flag & jit_flag_data); \ + if (jit_x87_reg_p(node->v.w)) \ + x87_##name##i##type(rn(node->u.w), rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + else \ + sse_##name##i##type(rn(node->u.w), rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + break +#define case_fff(name, type) \ + case jit_code_##name##r##type: \ + if (jit_x87_reg_p(node->u.w) && \ + jit_x87_reg_p(node->v.w) && \ + jit_x87_reg_p(node->w.w)) \ + x87_##name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + else \ + sse_##name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_ffw(name, type, size) \ + case jit_code_##name##i##type: \ + assert(node->flag & jit_flag_data); \ + if (jit_x87_reg_p(node->u.w) && \ + jit_x87_reg_p(node->v.w)) \ + x87_##name##i##type(rn(node->u.w), rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + else \ + sse_##name##i##type(rn(node->u.w), rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + break +#define case_bff(name, type) \ + case jit_code_b##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) { \ + if (jit_x87_reg_p(node->v.w) && \ + jit_x87_reg_p(node->w.w)) \ + x87_b##name##r##type(temp->u.w, \ + rn(node->v.w), rn(node->w.w)); \ + else \ + sse_b##name##r##type(temp->u.w, \ + rn(node->v.w), rn(node->w.w)); \ + } \ + else { \ + if (jit_x87_reg_p(node->v.w) && \ + jit_x87_reg_p(node->w.w)) \ + word = x87_b##name##r##type(_jit->pc.w, \ + rn(node->v.w), rn(node->w.w)); \ + else \ + word = sse_b##name##r##type(_jit->pc.w, \ + rn(node->v.w), rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_bfw(name, type, size) \ + case jit_code_b##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) { \ + if (jit_x87_reg_p(node->v.w)) \ + x87_b##name##i##type(temp->u.w, \ + rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + else \ + sse_b##name##i##type(temp->u.w, \ + rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + } \ + else { \ + if (jit_x87_reg_p(node->v.w)) \ + word = x87_b##name##i##type(_jit->pc.w, \ + rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + else \ + word = sse_b##name##i##type(_jit->pc.w, \ + rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + patch(word, node); \ + } \ + break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end) + return (NULL); + +#if DEVEL_DISASSEMBLER + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; +#endif + value = jit_classify(node->code); + jit_regarg_set(node, value); + switch (node->code) { + case jit_code_align: + assert(!(node->u.w & (node->u.w - 1)) && + node->u.w <= sizeof(jit_word_t)); + if ((word = _jit->pc.w & (node->u.w - 1))) + nop(node->u.w - word); + break; + case jit_code_note: case jit_code_name: + node->u.w = _jit->pc.w; + break; + case jit_code_label: + if ((node->link || (node->flag & jit_flag_use)) && + (word = _jit->pc.w & (sizeof(jit_word_t) - 1))) + nop(sizeof(jit_word_t) - word); + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + break; + case_rrr(add,); + case_rrw(add,); + case_rrr(addx,); + case_rrw(addx,); + case_rrr(addc,); + case_rrw(addc,); + case_rrr(sub,); + case_rrw(sub,); + case_rrr(subx,); + case_rrw(subx,); + case_rrr(subc,); + case_rrw(subc,); + case_rrw(rsb,); + case_rrr(mul,); + case_rrw(mul,); + case_rrrr(qmul,); + case_rrrw(qmul,); + case_rrrr(qmul, _u); + case_rrrw(qmul, _u); + case_rrr(div,); + case_rrw(div,); + case_rrr(div, _u); + case_rrw(div, _u); + case_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rr(neg,); + case_rr(com,); + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), node->v.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rr(hton, _us); + case_rr(hton, _ui); +#if __X64 && !__X64_32 + case_rr(hton, _ul); +#endif + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); +#if __X64 && !__X64_32 + case_rr(ext, _i); + case_rr(ext, _ui); +#endif + case_rf(trunc, _f_i); + case_rf(trunc, _d_i); +#if __X64 + case_rf(trunc, _f_l); + case_rf(trunc, _d_l); +#endif + case_rr(ld, _c); + case_rw(ld, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rr(ld, _i); + case_rw(ld, _i); +#if __X64 && !__X64_32 + case_rr(ld, _ui); + case_rw(ld, _ui); + case_rr(ld, _l); + case_rw(ld, _l); +#endif + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rrr(ldx, _i); + case_rrw(ldx, _i); +#if __X64 && !__X64_32 + case_rrr(ldx, _ui); + case_rrw(ldx, _ui); + case_rrr(ldx, _l); + case_rrw(ldx, _l); +#endif + case_rr(st, _c); + case_wr(st, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rr(st, _i); + case_wr(st, _i); +#if __X64 && !__X64_32 + case_rr(st, _l); + case_wr(st, _l); +#endif + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rrr(stx, _i); + case_wrr(stx, _i); +#if __X64 && !__X64_32 + case_rrr(stx, _l); + case_wrr(stx, _l); +#endif + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_fff(add, _f); + case_ffw(add, _f, 32); + case_fff(sub, _f); + case_ffw(sub, _f, 32); + case_ffw(rsb, _f, 32); + case_fff(mul, _f); + case_ffw(mul, _f, 32); + case_fff(div, _f); + case_ffw(div, _f, 32); + case_ff(abs, _f); + case_ff(neg, _f); + case_ff(sqrt, _f); + case_fr(ext, _f); + case_fr(ext, _d_f); + case_rff(lt, _f); + case_rfw(lt, _f, 32); + case_rff(le, _f); + case_rfw(le, _f, 32); + case_rff(eq, _f); + case_rfw(eq, _f, 32); + case_rff(ge, _f); + case_rfw(ge, _f, 32); + case_rff(gt, _f); + case_rfw(gt, _f, 32); + case_rff(ne, _f); + case_rfw(ne, _f, 32); + case_rff(unlt, _f); + case_rfw(unlt, _f, 32); + case_rff(unle, _f); + case_rfw(unle, _f, 32); + case_rff(uneq, _f); + case_rfw(uneq, _f, 32); + case_rff(unge, _f); + case_rfw(unge, _f, 32); + case_rff(ungt, _f); + case_rfw(ungt, _f, 32); + case_rff(ltgt, _f); + case_rfw(ltgt, _f, 32); + case_rff(ord, _f); + case_rfw(ord, _f, 32); + case_rff(unord, _f); + case_rfw(unord, _f, 32); + case jit_code_movr_f: + if (jit_x87_reg_p(node->u.w)) { + if (jit_x87_reg_p(node->v.w)) + x87_movr_f(rn(node->u.w), rn(node->v.w)); + else + x87_from_sse_f(rn(node->u.w), rn(node->v.w)); + } + else { + if (jit_sse_reg_p(node->v.w)) + sse_movr_f(rn(node->u.w), rn(node->v.w)); + else + sse_from_x87_f(rn(node->u.w), rn(node->v.w)); + } + break; + case jit_code_movi_f: + assert(node->flag & jit_flag_data); + if (jit_x87_reg_p(node->u.w)) + x87_movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); + else + sse_movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); + break; + case_fr(ld, _f); + case_fw(ld, _f); + case_frr(ldx, _f); + case_frw(ldx, _f); + case_rf(st, _f); + case_wf(st, _f); + case_rrf(stx, _f); + case_wrf(stx, _f); + case_bff(lt, _f); + case_bfw(lt, _f, 32); + case_bff(le, _f); + case_bfw(le, _f, 32); + case_bff(eq, _f); + case_bfw(eq, _f, 32); + case_bff(ge, _f); + case_bfw(ge, _f, 32); + case_bff(gt, _f); + case_bfw(gt, _f, 32); + case_bff(ne, _f); + case_bfw(ne, _f, 32); + case_bff(unlt, _f); + case_bfw(unlt, _f, 32); + case_bff(unle, _f); + case_bfw(unle, _f, 32); + case_bff(uneq, _f); + case_bfw(uneq, _f, 32); + case_bff(unge, _f); + case_bfw(unge, _f, 32); + case_bff(ungt, _f); + case_bfw(ungt, _f, 32); + case_bff(ltgt, _f); + case_bfw(ltgt, _f, 32); + case_bff(ord, _f); + case_bfw(ord, _f, 32); + case_bff(unord, _f); + case_bfw(unord, _f, 32); + case_fff(add, _d); + case_ffw(add, _d, 64); + case_fff(sub, _d); + case_ffw(sub, _d, 64); + case_ffw(rsb, _d, 64); + case_fff(mul, _d); + case_ffw(mul, _d, 64); + case_fff(div, _d); + case_ffw(div, _d, 64); + case_ff(abs, _d); + case_ff(neg, _d); + case_ff(sqrt, _d); + case_fr(ext, _d); + case_fr(ext, _f_d); + case_rff(lt, _d); + case_rfw(lt, _d, 64); + case_rff(le, _d); + case_rfw(le, _d, 64); + case_rff(eq, _d); + case_rfw(eq, _d, 64); + case_rff(ge, _d); + case_rfw(ge, _d, 64); + case_rff(gt, _d); + case_rfw(gt, _d, 64); + case_rff(ne, _d); + case_rfw(ne, _d, 64); + case_rff(unlt, _d); + case_rfw(unlt, _d, 64); + case_rff(unle, _d); + case_rfw(unle, _d, 64); + case_rff(uneq, _d); + case_rfw(uneq, _d, 64); + case_rff(unge, _d); + case_rfw(unge, _d, 64); + case_rff(ungt, _d); + case_rfw(ungt, _d, 64); + case_rff(ltgt, _d); + case_rfw(ltgt, _d, 64); + case_rff(ord, _d); + case_rfw(ord, _d, 64); + case_rff(unord, _d); + case_rfw(unord, _d, 64); + case jit_code_movr_d: + if (jit_x87_reg_p(node->u.w)) { + if (jit_x87_reg_p(node->v.w)) + x87_movr_d(rn(node->u.w), rn(node->v.w)); + else + x87_from_sse_d(rn(node->u.w), rn(node->v.w)); + } + else { + if (jit_sse_reg_p(node->v.w)) + sse_movr_d(rn(node->u.w), rn(node->v.w)); + else + sse_from_x87_d(rn(node->u.w), rn(node->v.w)); + } + break; + case jit_code_movi_d: + assert(node->flag & jit_flag_data); + if (jit_x87_reg_p(node->u.w)) + x87_movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w); + else + sse_movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w); + break; + case_fr(ld, _d); + case_fw(ld, _d); + case_frr(ldx, _d); + case_frw(ldx, _d); + case_rf(st, _d); + case_wf(st, _d); + case_rrf(stx, _d); + case_wrf(stx, _d); + case_bff(lt, _d); + case_bfw(lt, _d, 64); + case_bff(le, _d); + case_bfw(le, _d, 64); + case_bff(eq, _d); + case_bfw(eq, _d, 64); + case_bff(ge, _d); + case_bfw(ge, _d, 64); + case_bff(gt, _d); + case_bfw(gt, _d, 64); + case_bff(ne, _d); + case_bfw(ne, _d, 64); + case_bff(unlt, _d); + case_bfw(unlt, _d, 64); + case_bff(unle, _d); + case_bfw(unle, _d, 64); + case_bff(uneq, _d); + case_bfw(uneq, _d, 64); + case_bff(unge, _d); + case_bfw(unge, _d, 64); + case_bff(ungt, _d); + case_bfw(ungt, _d, 64); + case_bff(ltgt, _d); + case_bfw(ltgt, _d, 64); + case_bff(ord, _d); + case_bfw(ord, _d, 64); + case_bff(unord, _d); + case_bfw(unord, _d, 64); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + break; + case jit_code_jmpi: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi(_jit->pc.w); + patch(word, node); + } + } + else + jmpi(node->u.w); + break; + case jit_code_callr: + callr(rn(node->u.w)); + break; + case jit_code_calli: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = calli(temp->u.w); + if (!(temp->flag & jit_flag_patch)) + patch(word, node); + } + else + calli(node->u.w); + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif + undo.patch_offset = _jitc->patches.offset; + restart_function: + _jitc->again = 0; + prolog(node); + break; + case jit_code_epilog: + assert(_jitc->function == _jitc->functions.ptr + node->w.w); + if (_jitc->again) { + for (temp = undo.node->next; + temp != node; temp = temp->next) { + if (temp->code == jit_code_label || + temp->code == jit_code_epilog) + temp->flag &= ~jit_flag_patch; + } + temp->flag &= ~jit_flag_patch; + node = undo.node; + _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif + _jitc->patches.offset = undo.patch_offset; + goto restart_function; + } + if (node->link && + (word = _jit->pc.w & (sizeof(jit_word_t) - 1))) + nop(sizeof(jit_word_t) - word); + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + epilog(node); + _jitc->function = NULL; + break; + case jit_code_va_start: + vastart(rn(node->u.w)); + break; + case jit_code_va_arg: + vaarg(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_va_arg_d: + vaarg_d(rn(node->u.w), rn(node->v.w), jit_x87_reg_p(node->u.w)); + break; + case jit_code_live: case jit_code_ellipsis: + case jit_code_va_push: + case jit_code_allocai: case jit_code_allocar: + case jit_code_arg: + case jit_code_arg_f: case jit_code_arg_d: + case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: +#if __X64 && !__X64_32 + case jit_code_getarg_ui: case jit_code_getarg_l: +#endif + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: +#if __X64 && !__X32 + case jit_code_retval_ui: case jit_code_retval_l: +#endif + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: + break; + case jit_code_retval_f: +#if __X32 + if (jit_sse_reg_p(node->u.w)) { + fstpr(_ST1_REGNO); + sse_from_x87_f(rn(node->u.w), _ST0_REGNO); + } + else + fstpr(rn(node->u.w) + 1); +#endif + break; + case jit_code_retval_d: +#if __X32 + if (jit_sse_reg_p(node->u.w)) { + fstpr(_ST1_REGNO); + sse_from_x87_d(rn(node->u.w), _ST0_REGNO); + } + else + fstpr(rn(node->u.w) + 1); +#endif + break; + default: + abort(); + } + jit_regarg_clr(node, value); + assert(_jitc->regarg == 0 && _jitc->synth == 0); + /* update register live state */ + jit_reglive(node); + } +#undef case_bfw +#undef case_bff +#undef case_ffw +#undef case_rfw +#undef case_rff +#undef case_brw +#undef case_brr +#undef case_wrf +#undef case_wrr +#undef case_frw +#undef case_rrf +#undef case_rrw +#undef case_frr +#undef case_rrr +#undef case_wf +#undef case_fw +#undef case_fr +#undef case_rr + + for (offset = 0; offset < _jitc->patches.offset; offset++) { + node = _jitc->patches.ptr[offset].node; + word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(node, _jitc->patches.ptr[offset].inst, word); + } + + jit_flush(_jit->code.ptr, _jit->pc.uc); + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_x86-cpu.c" +# include "jit_x86-sse.c" +# include "jit_x86-x87.c" +#undef CODE + +void +jit_flush(void *fptr, void *tptr) +{ +} + +void +_emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0) +{ + ldxi(rn(r0), rn(r1), i0); +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1) +{ + stxi(i0, rn(r0), rn(r1)); +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0) +{ + if (jit_x87_reg_p(r0)) + x87_ldxi_d(rn(r0), rn(r1), i0); + else + sse_ldxi_d(rn(r0), rn(r1), i0); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1) +{ + if (jit_x87_reg_p(r1)) + x87_stxi_d(i0, rn(r0), rn(r1)); + else + sse_stxi_d(i0, rn(r0), rn(r1)); +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) + flag = node->v.n->flag; + else + flag = node->u.n->flag; + assert(!(flag & jit_flag_patch)); + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} + +static void +_sse_from_x87_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + x87_stxi_f(CVT_OFFSET, _RBP_REGNO, r1); + sse_ldxi_f(r0, _RBP_REGNO, CVT_OFFSET); +} + +static void +_sse_from_x87_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + x87_stxi_d(CVT_OFFSET, _RBP_REGNO, r1); + sse_ldxi_d(r0, _RBP_REGNO, CVT_OFFSET); +} + +static void +_x87_from_sse_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + sse_stxi_f(CVT_OFFSET, _RBP_REGNO, r1); + x87_ldxi_f(r0, _RBP_REGNO, CVT_OFFSET); +} + +static void +_x87_from_sse_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + sse_stxi_d(CVT_OFFSET, _RBP_REGNO, r1); + x87_ldxi_d(r0, _RBP_REGNO, CVT_OFFSET); +} diff --git a/deps/lightning/lib/lightning.c b/deps/lightning/lib/lightning.c new file mode 100644 index 0000000..3f2ab40 --- /dev/null +++ b/deps/lightning/lib/lightning.c @@ -0,0 +1,3513 @@ +/* + * Copyright (C) 2012-2019 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include <lightning.h> +#include <lightning/jit_private.h> +#include <mman.h> +#if defined(__sgi) +# include <fcntl.h> +#endif + +#ifndef MAP_ANON +# define MAP_ANON MAP_ANONYMOUS +# ifndef MAP_ANONYMOUS +# define MAP_ANONYMOUS 0 +# endif +#endif + +#define jit_regload_reload 0 /* convert to reload */ +#define jit_regload_delete 1 /* just remove node */ +#define jit_regload_isdead 2 /* delete and unset live bit */ + +/* + * Prototypes + */ +static jit_word_t hash_data(const void*, jit_word_t); + +#define new_pool() _new_pool(_jit) +static void _new_pool(jit_state_t*); + +#define new_node(u) _new_node(_jit, u) +static jit_node_t *_new_node(jit_state_t*, jit_code_t); + +#define link_node(u) _link_node(_jit, u) +static inline jit_node_t *_link_node(jit_state_t*, jit_node_t*); + +#define del_node(u, v) _del_node(_jit, u, v) +static inline void _del_node(jit_state_t*, jit_node_t*, jit_node_t*); + +#define free_node(u) _free_node(_jit, u) +static inline void _free_node(jit_state_t*, jit_node_t*); + +#define del_label(u, v) _del_label(_jit, u, v) +static void _del_label(jit_state_t*, jit_node_t*, jit_node_t*); + +#define jit_dataset() _jit_dataset(_jit) +static void +_jit_dataset(jit_state_t *_jit); + +#define jit_setup(block) _jit_setup(_jit, block) +static void +_jit_setup(jit_state_t *_jit, jit_block_t *block); + +#define jit_follow(block, todo) _jit_follow(_jit, block, todo) +static void +_jit_follow(jit_state_t *_jit, jit_block_t *block, jit_bool_t *todo); + +#define jit_update(node, live, mask) _jit_update(_jit, node, live, mask) +static void +_jit_update(jit_state_t *_jit, jit_node_t *node, + jit_regset_t *live, jit_regset_t *mask); + +#define thread_jumps() _thread_jumps(_jit) +static void +_thread_jumps(jit_state_t *_jit); + +#define sequential_labels() _sequential_labels(_jit) +static void +_sequential_labels(jit_state_t *_jit); + +#define split_branches() _split_branches(_jit) +static void +_split_branches(jit_state_t *_jit); + +#define shortcut_jump(prev, node) _shortcut_jump(_jit, prev, node) +static jit_bool_t +_shortcut_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node); + +#define redundant_jump(prev, node) _redundant_jump(_jit, prev, node) +static jit_bool_t +_redundant_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node); + +static jit_code_t +reverse_jump_code(jit_code_t code); + +#define reverse_jump(prev, node) _reverse_jump(_jit, prev, node) +static jit_bool_t +_reverse_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node); + +#define redundant_store(node, jump) _redundant_store(_jit, node, jump) +static void +_redundant_store(jit_state_t *_jit, jit_node_t *node, jit_bool_t jump); + +#define simplify_movr(p, n, k, s) _simplify_movr(_jit, p, n, k, s) +static jit_bool_t +_simplify_movr(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node, + jit_int32_t kind, jit_int32_t size); + +#define simplify_movi(p, n, k, s) _simplify_movi(_jit, p, n, k, s) +static jit_bool_t +_simplify_movi(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node, + jit_int32_t kind, jit_int32_t size); + +#define simplify_ldxi(prev, node) _simplify_ldxi(_jit, prev, node) +static jit_bool_t +_simplify_ldxi(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node); + +#define simplify_stxi(prev, node) _simplify_stxi(_jit, prev, node) +static jit_bool_t +_simplify_stxi(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node); + +#define simplify_spill(node, regno) _simplify_spill(_jit, node, regno) +static void +_simplify_spill(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno); + +#define simplify() _simplify(_jit) +static void +_simplify(jit_state_t *_jit); + +#define jit_reg_undef -1 +#define jit_reg_static 0 +#define jit_reg_change 1 +#define register_change_p(n, l, r) _register_change_p(_jit, n, l, r) +static jit_int32_t +_register_change_p(jit_state_t *_jit, jit_node_t *node, jit_node_t *link, + jit_int32_t regno); + +#define spill_reglive_p(node, regno) _spill_reglive_p(_jit, node, regno) +static jit_bool_t +_spill_reglive_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno); + +#define patch_registers() _patch_registers(_jit) +static void +_patch_registers(jit_state_t *_jit); + +#define patch_register(n,l,r,p) _patch_register(_jit,n,l,r,p) +static void +_patch_register(jit_state_t *jit, jit_node_t *node, jit_node_t *link, + jit_int32_t regno, jit_int32_t patch); + +/* + * Initialization + */ +#if !defined(__sgi) +#define mmap_fd -1 +#endif + +/* + * Implementation + */ +void +init_jit(const char *progname) +{ + jit_get_cpu(); + jit_init_debug(progname); + jit_init_size(); +} + +void +finish_jit(void) +{ + jit_finish_debug(); + jit_finish_size(); +} + +jit_int32_t +_jit_get_reg(jit_state_t *_jit, jit_int32_t regspec) +{ + jit_int32_t spec; + jit_int32_t regno; + + spec = regspec & ~(jit_class_chk|jit_class_nospill); + if (spec & jit_class_named) { + regno = jit_regno(spec); + if (jit_regset_tstbit(&_jitc->regsav, regno)) + /* fail if register is spilled */ + goto fail; + if (jit_regset_tstbit(&_jitc->regarg, regno)) + /* fail if register is an argument to current instruction */ + goto fail; + if (jit_regset_tstbit(&_jitc->reglive, regno)) { + if (regspec & jit_class_nospill) + /* fail if register is live and should not spill/reload */ + goto fail; + goto spill; + } + jit_regset_setbit(&_jitc->regarg, regno); + return (regno); + } + else + assert(jit_class(spec) != 0); + + if (_jitc->emit) { + /* search for a free register matching spec */ + for (regno = 0; regno < _jitc->reglen; regno++) { + if ((jit_class(_rvs[regno].spec) & spec) == spec && + !jit_regset_tstbit(&_jitc->regarg, regno) && + !jit_regset_tstbit(&_jitc->reglive, regno)) + goto regarg; + } + + /* search for a register matching spec that is not an argument + * for the current instruction */ + for (regno = 0; regno < _jitc->reglen; regno++) { + if ((jit_class(_rvs[regno].spec) & spec) == spec && + !jit_regset_tstbit(&_jitc->regsav, regno) && + !jit_regset_tstbit(&_jitc->regarg, regno) && + !(regspec & jit_class_nospill)) { + spill: + assert(_jitc->function != NULL); + if (spec & jit_class_gpr) { + if (!_jitc->function->regoff[regno]) { + _jitc->function->regoff[regno] = + jit_allocai(sizeof(jit_word_t)); + _jitc->again = 1; + } +#if DEBUG + /* emit_stxi must not need temporary registers */ + assert(!_jitc->getreg); + _jitc->getreg = 1; +#endif + emit_stxi(_jitc->function->regoff[regno], JIT_FP, regno); +#if DEBUG + _jitc->getreg = 0; +#endif + } + else { + if (!_jitc->function->regoff[regno]) { + _jitc->function->regoff[regno] = + jit_allocai(sizeof(jit_float64_t)); + _jitc->again = 1; + } +#if DEBUG + /* emit_stxi must not need temporary registers */ + assert(!_jitc->getreg); + _jitc->getreg = 1; +#endif + emit_stxi_d(_jitc->function->regoff[regno], JIT_FP, regno); +#if DEBUG + _jitc->getreg = 0; +#endif + } + jit_regset_setbit(&_jitc->regsav, regno); + regarg: + jit_regset_setbit(&_jitc->regarg, regno); + if (jit_class(_rvs[regno].spec) & jit_class_sav) { + /* if will modify callee save registers without a + * function prolog, better patch this assertion */ + assert(_jitc->function != NULL); + if (!jit_regset_tstbit(&_jitc->function->regset, regno)) { + jit_regset_setbit(&_jitc->function->regset, regno); + _jitc->again = 1; + } + } + return (regno); + } + } + } + else { + /* nospill hint only valid during emit" */ + assert(!(regspec & jit_class_nospill)); + for (regno = 0; regno < _jitc->reglen; regno++) { + if ((jit_class(_rvs[regno].spec) & spec) == spec && + !jit_regset_tstbit(&_jitc->regsav, regno) && + !jit_regset_tstbit(&_jitc->regarg, regno)) { + jit_regset_setbit(&_jitc->regarg, regno); + jit_regset_setbit(&_jitc->regsav, regno); + jit_save(regno); + return (jit_regno_patch|regno); + } + } + } + + /* Out of hardware registers */ +fail: + assert(regspec & jit_class_chk); + return (JIT_NOREG); +} + +void +_jit_unget_reg(jit_state_t *_jit, jit_int32_t regno) +{ + regno = jit_regno(regno); + if (jit_regset_tstbit(&_jitc->regsav, regno)) { + if (_jitc->emit) { +#if DEBUG + /* emit_ldxi must not need a temporary register */ + assert(!_jitc->getreg); + _jitc->getreg = 1; +#endif + if (jit_class(_rvs[regno].spec) & jit_class_gpr) + emit_ldxi(regno, JIT_FP, _jitc->function->regoff[regno]); + else + emit_ldxi_d(regno, JIT_FP, _jitc->function->regoff[regno]); +#if DEBUG + /* emit_ldxi must not need a temporary register */ + _jitc->getreg = 0; +#endif + } + else + jit_load(regno); + jit_regset_clrbit(&_jitc->regsav, regno); + } +#if defined(jit_carry) + assert((regno == jit_carry /*&& _NOREG != jit_carry*/) || + jit_regset_tstbit(&_jitc->regarg, regno) != 0); +#else + assert(jit_regset_tstbit(&_jitc->regarg, regno) != 0); +#endif + jit_regset_clrbit(&_jitc->regarg, regno); +} + +jit_bool_t +_jit_callee_save_p(jit_state_t *_jit, jit_int32_t regno) +{ + assert(regno >= 0 && regno < JIT_NOREG); + return (!!(_rvs[regno].spec & jit_class_sav)); +} + +extern jit_bool_t +_jit_pointer_p(jit_state_t *_jit, jit_pointer_t address) +{ + return ((jit_uint8_t *)address >= _jit->code.ptr && + (jit_word_t)address < _jit->pc.w); +} + +#if __ia64__ +void +jit_regset_com(jit_regset_t *u, jit_regset_t *v) +{ + u->rl = ~v->rl; u->rh = ~v->rh; + u->fl = ~v->fl; u->fh = ~v->fh; +} + +void +jit_regset_and(jit_regset_t *u, jit_regset_t *v, jit_regset_t *w) +{ + u->rl = v->rl & w->rl; u->rh = v->rh & w->rh; + u->fl = v->fl & w->fl; u->fh = v->fh & w->fh; +} + +void +jit_regset_ior(jit_regset_t *u, jit_regset_t *v, jit_regset_t *w) +{ + u->rl = v->rl | w->rl; u->rh = v->rh | w->rh; + u->fl = v->fl | w->fl; u->fh = v->fh | w->fh; +} + +void +jit_regset_xor(jit_regset_t *u, jit_regset_t *v, jit_regset_t *w) +{ + u->rl = v->rl ^ w->rl; u->rh = v->rh ^ w->rh; + u->fl = v->fl ^ w->fl; u->fh = v->fh ^ w->fh; +} + +void +jit_regset_set(jit_regset_t *u, jit_regset_t *v) +{ + u->rl = v->rl; u->rh = v->rh; + u->fl = v->fl; u->fh = v->fh; +} + +void +jit_regset_set_mask(jit_regset_t *u, jit_int32_t v) +{ + jit_bool_t w = !!(v & (v - 1)); + + assert(v >= 0 && v <= 256); + if (v == 0) + u->rl = u->rh = u->fl = u->fh = -1LL; + else if (v <= 64) { + u->rl = w ? (1LL << v) - 1 : -1LL; + u->rh = u->fl = u->fh = 0; + } + else if (v <= 128) { + u->rl = -1LL; + u->rh = w ? (1LL << (v - 64)) - 1 : -1LL; + u->fl = u->fh = 0; + } + else if (v <= 192) { + u->rl = u->rh = -1LL; + u->fl = w ? (1LL << (v - 128)) - 1 : -1LL; + u->fh = 0; + } + else { + u->rl = u->rh = u->fl = -1LL; + u->fh = w ? (1LL << (v - 128)) - 1 : -1LL; + } +} + +jit_bool_t +jit_regset_cmp_ui(jit_regset_t *u, jit_word_t v) +{ + return !((u->rl == v && u->rh == 0 && u->fl == 0 && u->fh == 0)); +} + +void +jit_regset_set_ui(jit_regset_t *u, jit_word_t v) +{ + u->rl = v; + u->rh = u->fl = u->fh = 0; +} + +jit_bool_t +jit_regset_set_p(jit_regset_t *u) +{ + return (u->rl || u->rh || u->fl || u->fh); +} + +void +jit_regset_clrbit(jit_regset_t *set, jit_int32_t bit) +{ + assert(bit >= 0 && bit <= 255); + if (bit < 64) + set->rl &= ~(1LL << bit); + else if (bit < 128) + set->rh &= ~(1LL << (bit - 64)); + else if (bit < 192) + set->fl &= ~(1LL << (bit - 128)); + else + set->fh &= ~(1LL << (bit - 192)); +} + +void +jit_regset_setbit(jit_regset_t *set, jit_int32_t bit) +{ + assert(bit >= 0 && bit <= 255); + if (bit < 64) + set->rl |= 1LL << bit; + else if (bit < 128) + set->rh |= 1LL << (bit - 64); + else if (bit < 192) + set->fl |= 1LL << (bit - 128); + else + set->fh |= 1LL << (bit - 192); +} + +jit_bool_t +jit_regset_tstbit(jit_regset_t *set, jit_int32_t bit) +{ + assert(bit >= 0 && bit <= 255); + if (bit < 64) + return (!!(set->rl & (1LL << bit))); + else if (bit < 128) + return (!!(set->rh & (1LL << (bit - 64)))); + else if (bit < 192) + return (!!(set->fl & (1LL << (bit - 128)))); + return (!!(set->fh & (1LL << (bit - 192)))); +} + +unsigned long +jit_regset_scan1(jit_regset_t *set, jit_int32_t offset) +{ + assert(offset >= 0 && offset <= 255); + for (; offset < 64; offset++) { + if (set->rl & (1LL << offset)) + return (offset); + } + for (; offset < 128; offset++) { + if (set->rh & (1LL << (offset - 64))) + return (offset); + } + for (; offset < 192; offset++) { + if (set->fl & (1LL << (offset - 128))) + return (offset); + } + for (; offset < 256; offset++) { + if (set->fh & (1LL << (offset - 192))) + return (offset); + } + return (ULONG_MAX); +} + +#elif __sparc__ && __WORDSIZE == 64 +void +jit_regset_com(jit_regset_t *u, jit_regset_t *v) +{ + u->rl = ~v->rl; u->rh = ~v->rh; +} + +void +jit_regset_and(jit_regset_t *u, jit_regset_t *v, jit_regset_t *w) +{ + u->rl = v->rl & w->rl; u->rh = v->rh & w->rh; +} + +void +jit_regset_ior(jit_regset_t *u, jit_regset_t *v, jit_regset_t *w) +{ + u->rl = v->rl | w->rl; u->rh = v->rh | w->rh; +} + +void +jit_regset_xor(jit_regset_t *u, jit_regset_t *v, jit_regset_t *w) +{ + u->rl = v->rl ^ w->rl; u->rh = v->rh ^ w->rh; +} + +void +jit_regset_set(jit_regset_t *u, jit_regset_t *v) +{ + u->rl = v->rl; u->rh = v->rh; +} + +void +jit_regset_set_mask(jit_regset_t *u, jit_int32_t v) +{ + jit_bool_t w = !!(v & (v - 1)); + + assert(v >= 0 && v <= 128); + if (v == 0) + u->rl = u->rh = -1LL; + else if (v <= 64) { + u->rl = w ? (1LL << v) - 1 : -1LL; + u->rh = 0; + } + else { + u->rl = -1LL; + u->rh = w ? (1LL << (v - 64)) - 1 : -1LL; + } +} + +jit_bool_t +jit_regset_cmp_ui(jit_regset_t *u, jit_word_t v) +{ + return !((u->rl == v && u->rh == 0)); +} + +void +jit_regset_set_ui(jit_regset_t *u, jit_word_t v) +{ + u->rl = v; + u->rh = 0; +} + +jit_bool_t +jit_regset_set_p(jit_regset_t *u) +{ + return (u->rl || u->rh); +} + +void +jit_regset_clrbit(jit_regset_t *set, jit_int32_t bit) +{ + assert(bit >= 0 && bit <= 128); + if (bit < 64) + set->rl &= ~(1LL << bit); + else + set->rh &= ~(1LL << (bit - 64)); +} + +void +jit_regset_setbit(jit_regset_t *set, jit_int32_t bit) +{ + assert(bit >= 0 && bit <= 127); + if (bit < 64) + set->rl |= 1LL << bit; + else + set->rh |= 1LL << (bit - 64); +} + +jit_bool_t +jit_regset_tstbit(jit_regset_t *set, jit_int32_t bit) +{ + assert(bit >= 0 && bit <= 127); + if (bit < 64) + return (!!(set->rl & (1LL << bit))); + else + return (!!(set->rh & (1LL << (bit - 64)))); +} + +unsigned long +jit_regset_scan1(jit_regset_t *set, jit_int32_t offset) +{ + assert(offset >= 0 && offset <= 127); + for (; offset < 64; offset++) { + if (set->rl & (1LL << offset)) + return (offset); + } + for (; offset < 128; offset++) { + if (set->rh & (1LL << (offset - 64))) + return (offset); + } + return (ULONG_MAX); +} + +#else +unsigned long +jit_regset_scan1(jit_regset_t *set, jit_int32_t offset) +{ + jit_regset_t mask; + assert(offset >= 0 && offset <= 63); + if ((mask = *set >> offset)) { + for (;;) { + if (mask & 1) + return (offset); + mask >>= 1; + ++offset; + } + } + return (ULONG_MAX); +} +#endif + +void +_jit_save(jit_state_t *_jit, jit_int32_t reg) +{ + reg = jit_regno(reg); + assert(!_jitc->realize); + _jitc->spill[reg] = jit_new_node_w(jit_code_save, reg); +} + +void +_jit_load(jit_state_t *_jit, jit_int32_t reg) +{ + jit_node_t *node; + + reg = jit_regno(reg); + assert(!_jitc->realize); + assert(_jitc->spill[reg] != NULL); + node = jit_new_node_w(jit_code_load, reg); + /* create a path to flag the save/load is not required */ + node->link = _jitc->spill[reg]; + node->link->link = node; + _jitc->spill[reg] = NULL; +} + +static jit_word_t +hash_data(const void *data, jit_word_t length) +{ + const jit_uint8_t *ptr; + jit_word_t i, key; + for (i = key = 0, ptr = data; i < length; i++) + key = (key << (key & 1)) ^ ptr[i]; + return (key); +} + +jit_pointer_t +_jit_address(jit_state_t *_jit, jit_node_t *node) +{ + assert(_jitc->done); + assert(node != NULL && + /* If a node type that is documented to be a fixed marker */ + (node->code == jit_code_note || node->code == jit_code_name || + /* If another special fixed marker, returned by jit_indirect() */ + (node->code == jit_code_label && (node->flag & jit_flag_use) != 0))); + return ((jit_pointer_t)node->u.w); +} + +jit_node_t * +_jit_data(jit_state_t *_jit, const void *data, + jit_word_t length, jit_int32_t align) +{ + jit_word_t key; + jit_node_t *node; + + assert(!_jitc->realize); + + /* Ensure there is space even if asking for a duplicate */ + if (((_jitc->data.offset + 7) & -8) + length > _jit->data.length) { + jit_word_t size; + + size = (_jit->data.length + length + 4096) & - 4095; + assert(size >= _jit->data.length); + if (_jitc->data.ptr == NULL) + jit_alloc((jit_pointer_t *)&_jitc->data.ptr, size); + else + jit_realloc((jit_pointer_t *)&_jitc->data.ptr, + _jit->data.length, size); + _jit->data.length = size; + } + if (_jitc->data.table == NULL) + jit_alloc((jit_pointer_t *)&_jitc->data.table, + (_jitc->data.size = 16) * sizeof(jit_node_t*)); + + key = hash_data(data, length) & (_jitc->data.size - 1); + node = _jitc->data.table[key]; + for (; node; node = node->next) { + if (node->v.w == length && + memcmp(_jitc->data.ptr + node->u.w, data, length) == 0) + break; + } + + if (!node) { + node = jit_new_node_no_link(jit_code_data); + if (!align) + align = length; + switch (align) { + case 0: case 1: + break; + case 2: + _jitc->data.offset = (_jitc->data.offset + 1) & -2; + break; + case 3: case 4: + _jitc->data.offset = (_jitc->data.offset + 3) & -4; + break; + default: + _jitc->data.offset = (_jitc->data.offset + 7) & -8; + break; + } + node->u.w = _jitc->data.offset; + node->v.w = length; + jit_memcpy(_jitc->data.ptr + _jitc->data.offset, data, length); + _jitc->data.offset += length; + + node->next = _jitc->data.table[key]; + _jitc->data.table[key] = node; + ++_jitc->data.count; + + /* Rehash if more than 75% used table */ + if (_jitc->data.count > + (_jitc->data.size >> 1) + (_jitc->data.size >> 2) && + (_jitc->data.size << 1) > _jitc->data.size) { + jit_word_t i; + jit_node_t **hash; + jit_node_t *next; + jit_node_t *temp; + + jit_alloc((jit_pointer_t *)&hash, + (_jitc->data.size << 1) * sizeof(jit_node_t*)); + for (i = 0; i < _jitc->data.size; i++) { + temp = _jitc->data.table[i]; + for (; temp; temp = next) { + next = temp->next; + key = hash_data(_jitc->data.ptr + temp->u.w, temp->v.w) & + ((_jitc->data.size << 1) - 1); + temp->next = hash[key]; + hash[key] = temp; + } + } + jit_free((jit_pointer_t *)&_jitc->data.table); + _jitc->data.table = hash; + _jitc->data.size <<= 1; + } + } + + return (node); +} + +static void +_new_pool(jit_state_t *_jit) +{ + jit_node_t *list; + jit_int32_t offset; + + if (_jitc->pool.offset >= _jitc->pool.length) { + jit_int32_t length; + + length = _jitc->pool.length + 16; + jit_realloc((jit_pointer_t *)&_jitc->pool.ptr, + _jitc->pool.length * sizeof(jit_node_t *), + length * sizeof(jit_node_t *)); + _jitc->pool.length = length; + } + jit_alloc((jit_pointer_t *)(_jitc->pool.ptr + _jitc->pool.offset), + sizeof(jit_node_t) * 1024); + list = _jitc->pool.ptr[_jitc->pool.offset]; + for (offset = 1; offset < 1024; offset++, list++) + list->next = list + 1; + list->next = _jitc->list; + _jitc->list = _jitc->pool.ptr[_jitc->pool.offset]; + ++_jitc->pool.offset; +} + +static jit_node_t * +_new_node(jit_state_t *_jit, jit_code_t code) +{ + jit_node_t *node; + + if (_jitc->list == NULL) + new_pool(); + node = _jitc->list; + _jitc->list = node->next; + if (_jitc->synth) + node->flag |= jit_flag_synth; + node->next = NULL; + node->code = code; + + return (node); +} + +static inline jit_node_t * +_link_node(jit_state_t *_jit, jit_node_t *node) +{ + if (_jitc->tail) + _jitc->tail->next = node; + else + _jitc->head = node; + return (_jitc->tail = node); +} + +static inline void +_del_node(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node) +{ + if (prev == node) { + assert(prev == _jitc->head); + _jitc->head = node->next; + } + else + prev->next = node->next; + memset(node, 0, sizeof(jit_node_t)); + node->next = _jitc->list; + _jitc->list = node; +} + +static inline void +_free_node(jit_state_t *_jit, jit_node_t *node) +{ + memset(node, 0, sizeof(jit_node_t)); + node->next = _jitc->list; + _jitc->list = node; +} + +static void +_del_label(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node) +{ + jit_block_t *block; + + /* only allow call to del_label on linked labels */ + block = _jitc->blocks.ptr + node->v.w; + assert(block->label == node); + + /* del_label() should only be called when optimizing. + * This will leave an empty block index */ + jit_regset_del(&block->reglive); + jit_regset_del(&block->regmask); + block->label = NULL; + + /* redundant, should be already true */ + assert(node->link == NULL); + del_node(prev, node); +} + +jit_state_t * +jit_new_state(void) +{ + jit_state_t *_jit; + + jit_alloc((jit_pointer_t *)&_jit, sizeof(jit_state_t)); + jit_alloc((jit_pointer_t *)&_jitc, sizeof(jit_compiler_t)); + jit_regset_new(&_jitc->regarg); + jit_regset_new(&_jitc->regsav); + jit_regset_new(&_jitc->reglive); + jit_regset_new(&_jitc->regmask); + + jit_init(); + + jit_alloc((jit_pointer_t *)&_jitc->spill, + _jitc->reglen * sizeof(jit_node_t*)); + jit_alloc((jit_pointer_t *)&_jitc->gen, + _jitc->reglen * sizeof(jit_int32_t)); + jit_alloc((jit_pointer_t *)&_jitc->values, + _jitc->reglen * sizeof(jit_value_t)); + + jit_alloc((jit_pointer_t *)&_jitc->patches.ptr, + (_jitc->patches.length = 1024) * sizeof(jit_patch_t)); + jit_alloc((jit_pointer_t *)&_jitc->functions.ptr, + (_jitc->functions.length = 16) * sizeof(jit_function_t)); + jit_alloc((jit_pointer_t *)&_jitc->pool.ptr, + (_jitc->pool.length = 16) * sizeof(jit_node_t*)); + jit_alloc((jit_pointer_t *)&_jitc->blocks.ptr, + (_jitc->blocks.length = 16) * sizeof(jit_block_t)); +#if __arm__ && DISASSEMBLER + jit_alloc((jit_pointer_t *)&_jitc->data_info.ptr, + (_jitc->data_info.length = 1024) * sizeof(jit_data_info_t)); +#endif + + /* allocate at most one extra note in case jit_name() is + * never called, or called after adding at least one note */ + _jit->note.length = 1; + _jitc->note.size = sizeof(jit_note_t); + + return (_jit); +} + +void +_jit_clear_state(jit_state_t *_jit) +{ +#if DEVEL_DISASSEMBLER +# define jit_really_clear_state() _jit_really_clear_state(_jit) +} + +void _jit_really_clear_state(jit_state_t *_jit) +{ +#endif + jit_word_t offset; + jit_function_t *function; + + /* release memory not required at jit execution time and set + * pointers to NULL to explicitly know they are released */ + _jitc->head = _jitc->tail = NULL; + + jit_free((jit_pointer_t *)&_jitc->data.table); + _jitc->data.size = _jitc->data.count = 0; + + jit_free((jit_pointer_t *)&_jitc->spill); + jit_free((jit_pointer_t *)&_jitc->gen); + jit_free((jit_pointer_t *)&_jitc->values); + + jit_free((jit_pointer_t *)&_jitc->blocks.ptr); + + jit_free((jit_pointer_t *)&_jitc->patches.ptr); + _jitc->patches.offset = _jitc->patches.length = 0; + + for (offset = 0; offset < _jitc->functions.offset; offset++) { + function = _jitc->functions.ptr + offset; + jit_free((jit_pointer_t *)&function->regoff); + } + jit_free((jit_pointer_t *)&_jitc->functions.ptr); + _jitc->functions.offset = _jitc->functions.length = 0; + _jitc->function = NULL; + + for (offset = 0; offset < _jitc->pool.offset; offset++) + jit_free((jit_pointer_t *)(_jitc->pool.ptr + offset)); + jit_free((jit_pointer_t *)&_jitc->pool.ptr); + _jitc->pool.offset = _jitc->pool.length = 0; + _jitc->list = NULL; + + _jitc->note.head = _jitc->note.tail = + _jitc->note.name = _jitc->note.note = NULL; + _jitc->note.base = NULL; + +#if __arm__ && DISASSEMBLER + jit_free((jit_pointer_t *)&_jitc->data_info.ptr); +#endif + +#if (__powerpc__ && _CALL_AIXDESC) || __ia64__ + jit_free((jit_pointer_t *)&_jitc->prolog.ptr); +#endif + +#if __ia64__ + jit_regset_del(&_jitc->regs); +#endif + + jit_free((jit_pointer_t *)&_jitc); +} + +void +_jit_destroy_state(jit_state_t *_jit) +{ +#if DEVEL_DISASSEMBLER + jit_really_clear_state(); +#endif + if (!_jit->user_code) + munmap(_jit->code.ptr, _jit->code.length); + if (!_jit->user_data) + munmap(_jit->data.ptr, _jit->data.length); + jit_free((jit_pointer_t *)&_jit); +} + +void +_jit_synth_inc(jit_state_t *_jit) +{ + assert(_jitc->synth < 8); + ++_jitc->synth; +} + +jit_node_t * +_jit_new_node(jit_state_t *_jit, jit_code_t code) +{ + assert(!_jitc->realize); + return (link_node(new_node(code))); +} + +jit_node_t * +_jit_new_node_no_link(jit_state_t *_jit, jit_code_t code) +{ + assert(!_jitc->realize); + return (new_node(code)); +} + +void +_jit_link_node(jit_state_t *_jit, jit_node_t *node) +{ + assert(!_jitc->realize); + link_node(node); +} + +void +_jit_synth_dec(jit_state_t *_jit) +{ + assert(_jitc->synth > 0); + --_jitc->synth; +} + +jit_node_t * +_jit_new_node_w(jit_state_t *_jit, jit_code_t code, + jit_word_t u) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.w = u; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_f(jit_state_t *_jit, jit_code_t code, + jit_float32_t u) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.f = u; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_d(jit_state_t *_jit, jit_code_t code, + jit_float64_t u) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.d = u; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_p(jit_state_t *_jit, jit_code_t code, + jit_pointer_t u) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.p = u; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_ww(jit_state_t *_jit, jit_code_t code, + jit_word_t u, jit_word_t v) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.w = u; + node->v.w = v; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_wp(jit_state_t *_jit, jit_code_t code, + jit_word_t u, jit_pointer_t v) +{ + return (jit_new_node_ww(code, u, (jit_word_t)v)); +} + +jit_node_t * +_jit_new_node_fp(jit_state_t *_jit, jit_code_t code, + jit_float32_t u, jit_pointer_t v) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.f = u; + node->v.w = (jit_word_t)v; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_dp(jit_state_t *_jit, jit_code_t code, + jit_float64_t u, jit_pointer_t v) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.d = u; + node->v.w = (jit_word_t)v; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_pw(jit_state_t *_jit, jit_code_t code, + jit_pointer_t u, jit_word_t v) +{ + return (jit_new_node_ww(code, (jit_word_t)u, v)); +} + +jit_node_t * +_jit_new_node_wf(jit_state_t *_jit, jit_code_t code, + jit_word_t u, jit_float32_t v) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.w = u; + node->v.f = v; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_wd(jit_state_t *_jit, jit_code_t code, + jit_word_t u, jit_float64_t v) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.w = u; + node->v.d = v; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_www(jit_state_t *_jit, jit_code_t code, + jit_word_t u, jit_word_t v, jit_word_t w) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.w = u; + node->v.w = v; + node->w.w = w; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_qww(jit_state_t *_jit, jit_code_t code, + jit_int32_t l, jit_int32_t h, + jit_word_t v, jit_word_t w) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + assert(l != h); + node->u.q.l = l; + node->u.q.h = h; + node->v.w = v; + node->w.w = w; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_wwf(jit_state_t *_jit, jit_code_t code, + jit_word_t u, jit_word_t v, jit_float32_t w) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.w = u; + node->v.w = v; + node->w.f = w; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_wwd(jit_state_t *_jit, jit_code_t code, + jit_word_t u, jit_word_t v, jit_float64_t w) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.w = u; + node->v.w = v; + node->w.d = w; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_pww(jit_state_t *_jit, jit_code_t code, + jit_pointer_t u, jit_word_t v, jit_word_t w) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.p = u; + node->v.w = v; + node->w.w = w; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_pwf(jit_state_t *_jit, jit_code_t code, + jit_pointer_t u, jit_word_t v, jit_float32_t w) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.p = u; + node->v.w = v; + node->w.f = w; + return (link_node(node)); +} + +jit_node_t * +_jit_new_node_pwd(jit_state_t *_jit, jit_code_t code, + jit_pointer_t u, jit_word_t v, jit_float64_t w) +{ + jit_node_t *node = new_node(code); + assert(!_jitc->realize); + node->u.p = u; + node->v.w = v; + node->w.d = w; + return (link_node(node)); +} + +jit_node_t * +_jit_label(jit_state_t *_jit) +{ + jit_node_t *node; + + if (!(node = _jitc->tail) || node->code != jit_code_label) { + node = jit_forward(); + jit_link(node); + } + + return (node); +} + +jit_node_t * +_jit_forward(jit_state_t *_jit) +{ + return (jit_new_node_no_link(jit_code_label)); +} + +jit_node_t * +_jit_indirect(jit_state_t *_jit) +{ + jit_node_t *node; + + node = jit_label(); + node->flag |= jit_flag_use; + + return (node); +} + +void +_jit_link(jit_state_t *_jit, jit_node_t *node) +{ + jit_block_t *block; + + assert((node->code == jit_code_label || + node->code == jit_code_prolog || + node->code == jit_code_epilog) && !node->next); + jit_link_node(node); + if (_jitc->blocks.offset >= _jitc->blocks.length) { + jit_word_t length; + + length = _jitc->blocks.length + 16; + jit_realloc((jit_pointer_t *)&_jitc->blocks.ptr, + _jitc->blocks.length * sizeof(jit_block_t), + length * sizeof(jit_block_t)); + _jitc->blocks.length = length; + } + block = _jitc->blocks.ptr + _jitc->blocks.offset; + block->label = node; + node->v.w = _jitc->blocks.offset; + jit_regset_new(&block->reglive); + jit_regset_new(&block->regmask); + ++_jitc->blocks.offset; +} + +jit_bool_t +_jit_forward_p(jit_state_t *_jit, jit_node_t *node) +{ + return (node->code == jit_code_label && !node->next && node != _jitc->tail); +} + +jit_bool_t +_jit_indirect_p(jit_state_t *_jit, jit_node_t *node) +{ + return (node->code == jit_code_label && !!(node->flag & jit_flag_use)); +} + +jit_bool_t +_jit_target_p(jit_state_t *_jit, jit_node_t *node) +{ + return (node->code == jit_code_label && !!node->link); +} + +void +_jit_prepare(jit_state_t *_jit) +{ + assert(_jitc->function != NULL); + _jitc->function->call.call = jit_call_default; + _jitc->function->call.argi = + _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = jit_new_node(jit_code_prepare); +} + +void +_jit_patch(jit_state_t* _jit, jit_node_t *instr) +{ + jit_node_t *label; + + if (!(label = _jitc->tail) || label->code != jit_code_label) + label = jit_label(); + jit_patch_at(instr, label); +} + +jit_int32_t +_jit_classify(jit_state_t *_jit, jit_code_t code) +{ + jit_int32_t mask; + + switch (code) { + case jit_code_data: case jit_code_save: case jit_code_load: + case jit_code_name: case jit_code_label: case jit_code_note: + case jit_code_prolog: case jit_code_ellipsis: case jit_code_va_push: + case jit_code_epilog: case jit_code_ret: case jit_code_prepare: + mask = 0; + break; + case jit_code_live: case jit_code_va_end: + case jit_code_retr: case jit_code_retr_f: case jit_code_retr_d: + case jit_code_pushargr: case jit_code_pushargr_f: + case jit_code_pushargr_d: + case jit_code_finishr: /* synthesized will set jit_cc_a0_jmp */ + mask = jit_cc_a0_reg; + break; + case jit_code_align: case jit_code_reti: case jit_code_pushargi: + case jit_code_finishi: /* synthesized will set jit_cc_a0_jmp */ + mask = jit_cc_a0_int; + break; + case jit_code_reti_f: case jit_code_pushargi_f: + mask = jit_cc_a0_flt; + break; + case jit_code_reti_d: case jit_code_pushargi_d: + mask = jit_cc_a0_dbl; + break; + case jit_code_allocai: + mask = jit_cc_a0_int|jit_cc_a1_int; + break; + case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d: + mask = jit_cc_a0_int|jit_cc_a0_arg; + break; + case jit_code_calli: case jit_code_jmpi: + mask = jit_cc_a0_jmp; + break; + case jit_code_callr: case jit_code_jmpr: + mask = jit_cc_a0_reg|jit_cc_a0_jmp; + break; + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: case jit_code_retval_ui: + case jit_code_retval_l: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_va_start: + mask = jit_cc_a0_reg|jit_cc_a0_chg; + break; + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: case jit_code_getarg_ui: + case jit_code_getarg_l: + case jit_code_getarg_f: case jit_code_getarg_d: + mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_arg; + break; + case jit_code_putargr: case jit_code_putargr_f: + case jit_code_putargr_d: + mask = jit_cc_a0_reg|jit_cc_a1_arg; + break; + case jit_code_putargi: + mask = jit_cc_a0_int|jit_cc_a1_arg; + break; + case jit_code_putargi_f: + mask = jit_cc_a0_flt|jit_cc_a1_arg; + break; + case jit_code_putargi_d: + mask = jit_cc_a0_dbl|jit_cc_a1_arg; + break; + case jit_code_movi: case jit_code_ldi_c: case jit_code_ldi_uc: + case jit_code_ldi_s: case jit_code_ldi_us: case jit_code_ldi_i: + case jit_code_ldi_ui: case jit_code_ldi_l: case jit_code_ldi_f: + case jit_code_ldi_d: + mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_int; + break; + case jit_code_movi_f: case jit_code_movi_f_w: + mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_flt; + break; + case jit_code_movi_d: case jit_code_movi_d_w: + mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_dbl; + break; + case jit_code_movi_d_ww: + mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg|jit_cc_a1_chg| + jit_cc_a2_dbl; + break; + case jit_code_negr: case jit_code_comr: case jit_code_movr: + case jit_code_extr_c: case jit_code_extr_uc: case jit_code_extr_s: + case jit_code_extr_us: case jit_code_extr_i: case jit_code_extr_ui: + case jit_code_truncr_f_i: case jit_code_truncr_f_l: + case jit_code_truncr_d_i: case jit_code_truncr_d_l: + case jit_code_htonr_us: case jit_code_htonr_ui: case jit_code_htonr_ul: + case jit_code_ldr_c: case jit_code_ldr_uc: + case jit_code_ldr_s: case jit_code_ldr_us: case jit_code_ldr_i: + case jit_code_ldr_ui: case jit_code_ldr_l: case jit_code_negr_f: + case jit_code_absr_f: case jit_code_sqrtr_f: case jit_code_movr_f: + case jit_code_extr_f: case jit_code_extr_d_f: case jit_code_ldr_f: + case jit_code_negr_d: case jit_code_absr_d: case jit_code_sqrtr_d: + case jit_code_movr_d: case jit_code_extr_d: case jit_code_extr_f_d: + case jit_code_ldr_d: + case jit_code_movr_w_f: case jit_code_movr_f_w: + case jit_code_movr_w_d: case jit_code_movr_d_w: + case jit_code_va_arg: case jit_code_va_arg_d: + mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg; + break; + case jit_code_movr_d_ww: + mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg|jit_cc_a1_chg| + jit_cc_a2_reg; + break; + case jit_code_addi: case jit_code_addxi: case jit_code_addci: + case jit_code_subi: case jit_code_subxi: case jit_code_subci: + case jit_code_rsbi: + case jit_code_muli: case jit_code_divi: case jit_code_divi_u: + case jit_code_remi: case jit_code_remi_u: case jit_code_andi: + case jit_code_ori: case jit_code_xori: case jit_code_lshi: + case jit_code_rshi: case jit_code_rshi_u: case jit_code_lti: + case jit_code_lti_u: case jit_code_lei: case jit_code_lei_u: + case jit_code_eqi: case jit_code_gei: case jit_code_gei_u: + case jit_code_gti: case jit_code_gti_u: case jit_code_nei: + case jit_code_ldxi_c: case jit_code_ldxi_uc: case jit_code_ldxi_s: + case jit_code_ldxi_us: case jit_code_ldxi_i: case jit_code_ldxi_ui: + case jit_code_ldxi_l: case jit_code_ldxi_f: case jit_code_ldxi_d: + mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg|jit_cc_a2_int; + break; + case jit_code_qmuli: case jit_code_qmuli_u: + case jit_code_qdivi: case jit_code_qdivi_u: + mask = jit_cc_a0_reg|jit_cc_a0_rlh|jit_cc_a0_chg| + jit_cc_a1_reg|jit_cc_a2_int; + break; + case jit_code_addi_f: case jit_code_subi_f: case jit_code_rsbi_f: + case jit_code_muli_f: case jit_code_divi_f: case jit_code_lti_f: + case jit_code_lei_f: case jit_code_eqi_f: case jit_code_gei_f: + case jit_code_gti_f: case jit_code_nei_f: case jit_code_unlti_f: + case jit_code_unlei_f: case jit_code_uneqi_f: case jit_code_ungei_f: + case jit_code_ungti_f: case jit_code_ltgti_f: case jit_code_ordi_f: + case jit_code_unordi_f: + mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg|jit_cc_a2_flt; + break; + case jit_code_addi_d: case jit_code_subi_d: case jit_code_rsbi_d: + case jit_code_muli_d: case jit_code_divi_d: case jit_code_lti_d: + case jit_code_lei_d: case jit_code_eqi_d: case jit_code_gei_d: + case jit_code_gti_d: case jit_code_nei_d: case jit_code_unlti_d: + case jit_code_unlei_d: case jit_code_uneqi_d: case jit_code_ungei_d: + case jit_code_ungti_d: case jit_code_ltgti_d: case jit_code_ordi_d: + case jit_code_unordi_d: + mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg|jit_cc_a2_dbl; + break; + case jit_code_addr: case jit_code_addxr: case jit_code_addcr: + case jit_code_subr: case jit_code_subxr: case jit_code_subcr: + case jit_code_mulr: case jit_code_divr: case jit_code_divr_u: + case jit_code_remr: case jit_code_remr_u: case jit_code_andr: + case jit_code_orr: case jit_code_xorr: case jit_code_lshr: + case jit_code_rshr: case jit_code_rshr_u: case jit_code_ltr: + case jit_code_ltr_u: case jit_code_ler: case jit_code_ler_u: + case jit_code_eqr: case jit_code_ger: case jit_code_ger_u: + case jit_code_gtr: case jit_code_gtr_u: case jit_code_ner: + case jit_code_ldxr_c: case jit_code_ldxr_uc: case jit_code_ldxr_s: + case jit_code_ldxr_us: case jit_code_ldxr_i: case jit_code_ldxr_ui: + case jit_code_ldxr_l: case jit_code_addr_f: case jit_code_subr_f: + case jit_code_mulr_f: case jit_code_divr_f: case jit_code_ltr_f: + case jit_code_ler_f: case jit_code_eqr_f: case jit_code_ger_f: + case jit_code_gtr_f: case jit_code_ner_f: case jit_code_unltr_f: + case jit_code_unler_f: case jit_code_uneqr_f: case jit_code_unger_f: + case jit_code_ungtr_f: case jit_code_ltgtr_f: case jit_code_ordr_f: + case jit_code_unordr_f: case jit_code_ldxr_f: case jit_code_addr_d: + case jit_code_subr_d: case jit_code_mulr_d: case jit_code_divr_d: + case jit_code_ltr_d: case jit_code_ler_d: case jit_code_eqr_d: + case jit_code_ger_d: case jit_code_gtr_d: case jit_code_ner_d: + case jit_code_unltr_d: case jit_code_unler_d: case jit_code_uneqr_d: + case jit_code_unger_d: case jit_code_ungtr_d: case jit_code_ltgtr_d: + case jit_code_ordr_d: case jit_code_unordr_d: case jit_code_ldxr_d: + case jit_code_movr_ww_d: + mask = jit_cc_a0_reg|jit_cc_a0_chg|jit_cc_a1_reg|jit_cc_a2_reg; + break; + case jit_code_qmulr: case jit_code_qmulr_u: + case jit_code_qdivr: case jit_code_qdivr_u: + mask = jit_cc_a0_reg|jit_cc_a0_rlh|jit_cc_a0_chg| + jit_cc_a1_reg|jit_cc_a2_reg; + break; + case jit_code_sti_c: case jit_code_sti_s: case jit_code_sti_i: + case jit_code_sti_l: case jit_code_sti_f: case jit_code_sti_d: + mask = jit_cc_a0_int|jit_cc_a1_reg; + break; + case jit_code_blti: case jit_code_blti_u: case jit_code_blei: + case jit_code_blei_u: case jit_code_beqi: case jit_code_bgei: + case jit_code_bgei_u: case jit_code_bgti: case jit_code_bgti_u: + case jit_code_bnei: case jit_code_bmsi: case jit_code_bmci: + mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_int; + break; + case jit_code_blti_f: case jit_code_blei_f: case jit_code_beqi_f: + case jit_code_bgei_f: case jit_code_bgti_f: case jit_code_bnei_f: + case jit_code_bunlti_f: case jit_code_bunlei_f: case jit_code_buneqi_f: + case jit_code_bungei_f: case jit_code_bungti_f: case jit_code_bltgti_f: + case jit_code_bordi_f: case jit_code_bunordi_f: + mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_flt; + break; + case jit_code_blti_d: case jit_code_blei_d: case jit_code_beqi_d: + case jit_code_bgei_d: case jit_code_bgti_d: case jit_code_bnei_d: + case jit_code_bunlti_d: case jit_code_bunlei_d: case jit_code_buneqi_d: + case jit_code_bungei_d: case jit_code_bungti_d: case jit_code_bltgti_d: + case jit_code_bordi_d: case jit_code_bunordi_d: + mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_dbl; + break; + case jit_code_allocar: /* synthesized instructions make it + * equivalent to jit_cc_a0_chg */ + case jit_code_str_c: case jit_code_str_s: case jit_code_str_i: + case jit_code_str_l: case jit_code_str_f: case jit_code_str_d: + mask = jit_cc_a0_reg|jit_cc_a1_reg; + break; + case jit_code_stxi_c: case jit_code_stxi_s: case jit_code_stxi_i: + case jit_code_stxi_l: case jit_code_stxi_f: case jit_code_stxi_d: + mask = jit_cc_a0_int|jit_cc_a1_reg|jit_cc_a2_reg; + break; + case jit_code_bltr: case jit_code_bltr_u: case jit_code_bler: + case jit_code_bler_u: case jit_code_beqr: case jit_code_bger: + case jit_code_bger_u: case jit_code_bgtr: case jit_code_bgtr_u: + case jit_code_bner: case jit_code_bmsr: case jit_code_bmcr: + case jit_code_bltr_f: case jit_code_bler_f: case jit_code_beqr_f: + case jit_code_bger_f: case jit_code_bgtr_f: case jit_code_bner_f: + case jit_code_bunltr_f: case jit_code_bunler_f: case jit_code_buneqr_f: + case jit_code_bunger_f: case jit_code_bungtr_f: case jit_code_bltgtr_f: + case jit_code_bordr_f: case jit_code_bunordr_f:case jit_code_bltr_d: + case jit_code_bler_d: case jit_code_beqr_d: case jit_code_bger_d: + case jit_code_bgtr_d: case jit_code_bner_d: case jit_code_bunltr_d: + case jit_code_bunler_d: case jit_code_buneqr_d: case jit_code_bunger_d: + case jit_code_bungtr_d: case jit_code_bltgtr_d: case jit_code_bordr_d: + case jit_code_bunordr_d: + mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_reg; + break; + case jit_code_boaddi: case jit_code_boaddi_u: case jit_code_bxaddi: + case jit_code_bxaddi_u: case jit_code_bosubi: case jit_code_bosubi_u: + case jit_code_bxsubi: case jit_code_bxsubi_u: + mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a1_chg|jit_cc_a2_int; + break; + case jit_code_stxr_c: case jit_code_stxr_s: case jit_code_stxr_i: + case jit_code_stxr_l: case jit_code_stxr_f: case jit_code_stxr_d: + mask = jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_reg; + break; + case jit_code_boaddr: case jit_code_boaddr_u: case jit_code_bxaddr: + case jit_code_bxaddr_u: case jit_code_bosubr: case jit_code_bosubr_u: + case jit_code_bxsubr: case jit_code_bxsubr_u: + mask = jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a1_chg|jit_cc_a2_reg; + break; + default: + abort(); + } + + return (mask); +} + +void +_jit_patch_abs(jit_state_t *_jit, jit_node_t *instr, jit_pointer_t address) +{ + jit_int32_t mask; + + switch (instr->code) { + case jit_code_movi: case jit_code_ldi_c: case jit_code_ldi_uc: + case jit_code_ldi_s: case jit_code_ldi_us: case jit_code_ldi_i: + case jit_code_ldi_ui: case jit_code_ldi_l: case jit_code_ldi_f: + case jit_code_ldi_d: + instr->v.p = address; + break; + case jit_code_sti_c: case jit_code_sti_s: case jit_code_sti_i: + case jit_code_sti_l: case jit_code_sti_f: case jit_code_sti_d: + instr->u.p = address; + break; + default: + mask = jit_classify(instr->code); + assert((mask & (jit_cc_a0_reg|jit_cc_a0_jmp)) == jit_cc_a0_jmp); + instr->u.p = address; + } +} + +void +_jit_patch_at(jit_state_t *_jit, jit_node_t *instr, jit_node_t *label) +{ + jit_int32_t mask; + + assert(!(instr->flag & jit_flag_node)); + instr->flag |= jit_flag_node; + switch (instr->code) { + case jit_code_movi: + assert(label->code == jit_code_label || + label->code == jit_code_data); + instr->v.n = label; + if (label->code == jit_code_data) + instr->flag |= jit_flag_data; + break; + case jit_code_jmpi: + assert(label->code == jit_code_label || + label->code == jit_code_epilog); + instr->u.n = label; + break; + default: + mask = jit_classify(instr->code); + assert((mask & (jit_cc_a0_reg|jit_cc_a0_jmp)) == jit_cc_a0_jmp); + assert(label->code == jit_code_label); + instr->u.n = label; + break; + } + /* link field is used as list of nodes associated with a given label */ + instr->link = label->link; + label->link = instr; +} + +void +_jit_optimize(jit_state_t *_jit) +{ + jit_bool_t jump; + jit_bool_t todo; + jit_int32_t mask; + jit_node_t *node; + jit_block_t *block; + jit_word_t offset; + + _jitc->function = NULL; + + thread_jumps(); + sequential_labels(); + split_branches(); + + /* create initial mapping of live register values + * at the start of a basic block */ + for (offset = 0; offset < _jitc->blocks.offset; offset++) { + block = _jitc->blocks.ptr + offset; + if (!block->label) + continue; + if (block->label->code != jit_code_epilog) + jit_setup(block); + } + + /* set live state of registers not referenced in a block, but + * referenced in a jump target or normal flow */ + do { + todo = 0; + for (offset = 0; offset < _jitc->blocks.offset; offset++) { + block = _jitc->blocks.ptr + offset; + if (!block->label) + continue; + if (block->label->code != jit_code_epilog) + jit_follow(block, &todo); + } + } while (todo); + + patch_registers(); + simplify(); + + /* figure out labels that are only reached with a jump + * and is required to do a simple redundant_store removal + * on jit_beqi below */ + jump = 1; + for (node = _jitc->head; node; node = node->next) { + switch (node->code) { + case jit_code_label: + if (!jump) + node->flag |= jit_flag_head; + break; + case jit_code_jmpi: case jit_code_jmpr: + case jit_code_epilog: + jump = 1; + break; + case jit_code_data: case jit_code_note: + break; + default: + jump = 0; + break; + } + } + + for (node = _jitc->head; node; node = node->next) { + mask = jit_classify(node->code); + if (mask & jit_cc_a0_reg) + node->u.w &= ~jit_regno_patch; + if (mask & jit_cc_a1_reg) + node->v.w &= ~jit_regno_patch; + if (mask & jit_cc_a2_reg) + node->w.w &= ~jit_regno_patch; + switch (node->code) { + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + break; + case jit_code_epilog: + _jitc->function = NULL; + break; + case jit_code_beqi: + redundant_store(node, 1); + break; + case jit_code_bnei: + redundant_store(node, 0); + break; + default: +#if JIT_HASH_CONSTS + if (mask & jit_cc_a0_flt) { + node->u.p = jit_data(&node->u.f, sizeof(jit_float32_t), 4); + node->flag |= jit_flag_node | jit_flag_data; + } + else if (mask & jit_cc_a0_dbl) { + node->u.p = jit_data(&node->u.d, sizeof(jit_float64_t), 8); + node->flag |= jit_flag_node | jit_flag_data; + } + else if (mask & jit_cc_a1_flt) { + node->v.p = jit_data(&node->v.f, sizeof(jit_float32_t), 4); + node->flag |= jit_flag_node | jit_flag_data; + } + else if (mask & jit_cc_a1_dbl) { + node->v.p = jit_data(&node->v.d, sizeof(jit_float64_t), 8); + node->flag |= jit_flag_node | jit_flag_data; + } + else if (mask & jit_cc_a2_flt) { + node->w.p = jit_data(&node->w.f, sizeof(jit_float32_t), 4); + node->flag |= jit_flag_node | jit_flag_data; + } + else if (mask & jit_cc_a2_dbl) { + node->w.p = jit_data(&node->w.d, sizeof(jit_float64_t), 8); + node->flag |= jit_flag_node | jit_flag_data; + } +#endif + if (_jitc->function) { + if ((mask & (jit_cc_a0_reg|jit_cc_a0_chg)) == + (jit_cc_a0_reg|jit_cc_a0_chg)) { + if (mask & jit_cc_a0_rlh) { + jit_regset_setbit(&_jitc->function->regset, + jit_regno(node->u.q.l)); + jit_regset_setbit(&_jitc->function->regset, + jit_regno(node->u.q.h)); + } + else + jit_regset_setbit(&_jitc->function->regset, + jit_regno(node->u.w)); + } + if ((mask & (jit_cc_a1_reg|jit_cc_a1_chg)) == + (jit_cc_a1_reg|jit_cc_a1_chg)) + jit_regset_setbit(&_jitc->function->regset, + jit_regno(node->v.w)); + if ((mask & (jit_cc_a2_reg|jit_cc_a2_chg)) == + (jit_cc_a2_reg|jit_cc_a2_chg)) + jit_regset_setbit(&_jitc->function->regset, + jit_regno(node->w.w)); + } + break; + } + } +} + +void +_jit_reglive(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t spec; + jit_int32_t value; + jit_block_t *block; + + switch (node->code) { + case jit_code_label: case jit_code_prolog: case jit_code_epilog: + block = _jitc->blocks.ptr + node->v.w; + jit_regset_set(&_jitc->reglive, &block->reglive); + break; + case jit_code_callr: + value = jit_regno(node->u.w); + if (!(node->u.w & jit_regno_patch)) { + jit_regset_setbit(&_jitc->reglive, value); + } + case jit_code_calli: + for (value = 0; value < _jitc->reglen; value++) { + spec = jit_class(_rvs[value].spec); + if ((spec & jit_class_arg) && jit_regarg_p(node, value)) + jit_regset_setbit(&_jitc->reglive, value); + else if (!(spec & jit_class_sav)) + jit_regset_clrbit(&_jitc->reglive, value); + } + break; + default: + value = jit_classify(node->code); + if (value & jit_cc_a0_reg) { + if (value & jit_cc_a0_rlh) { + if (!(node->u.q.l & jit_regno_patch)) { + if (value & jit_cc_a0_chg) { + jit_regset_clrbit(&_jitc->reglive, node->u.q.l); + jit_regset_setbit(&_jitc->regmask, node->u.q.l); + } + else + jit_regset_setbit(&_jitc->reglive, node->u.q.l); + } + if (!(node->u.q.h & jit_regno_patch)) { + if (value & jit_cc_a0_chg) { + jit_regset_clrbit(&_jitc->reglive, node->u.q.h); + jit_regset_setbit(&_jitc->regmask, node->u.q.h); + } + else + jit_regset_setbit(&_jitc->reglive, node->u.q.h); + } + } + else { + if (!(node->u.w & jit_regno_patch)) { + if (value & jit_cc_a0_chg) { + jit_regset_clrbit(&_jitc->reglive, node->u.w); + jit_regset_setbit(&_jitc->regmask, node->u.w); + } + else + jit_regset_setbit(&_jitc->reglive, node->u.w); + } + } + } + if ((value & jit_cc_a1_reg) && !(node->v.w & jit_regno_patch)) { + if (value & jit_cc_a1_chg) { + jit_regset_clrbit(&_jitc->reglive, node->v.w); + jit_regset_setbit(&_jitc->regmask, node->v.w); + } + else + jit_regset_setbit(&_jitc->reglive, node->v.w); + } + if ((value & jit_cc_a2_reg) && !(node->w.w & jit_regno_patch)) { + if (value & jit_cc_a2_chg) { + jit_regset_clrbit(&_jitc->reglive, node->w.w); + jit_regset_setbit(&_jitc->regmask, node->w.w); + } + else + jit_regset_setbit(&_jitc->reglive, node->w.w); + } + if (jit_regset_set_p(&_jitc->regmask)) { + jit_update(node->next, &_jitc->reglive, &_jitc->regmask); + if (jit_regset_set_p(&_jitc->regmask)) { + /* any unresolved live state is considered as live */ + jit_regset_ior(&_jitc->reglive, + &_jitc->reglive, &_jitc->regmask); + jit_regset_set_ui(&_jitc->regmask, 0); + } + } + break; + } +} + +void +_jit_regarg_set(jit_state_t *_jit, jit_node_t *node, jit_int32_t value) +{ +#if GET_JIT_SIZE + jit_size_prepare(); +#endif + if (value & jit_cc_a0_reg) { + if (value & jit_cc_a0_rlh) { + jit_regset_setbit(&_jitc->regarg, jit_regno(node->u.q.l)); + jit_regset_setbit(&_jitc->regarg, jit_regno(node->u.q.h)); + } + else + jit_regset_setbit(&_jitc->regarg, jit_regno(node->u.w)); + } + if (value & jit_cc_a1_reg) + jit_regset_setbit(&_jitc->regarg, jit_regno(node->v.w)); + if (value & jit_cc_a2_reg) + jit_regset_setbit(&_jitc->regarg, jit_regno(node->w.w)); +} + +void +_jit_regarg_clr(jit_state_t *_jit, jit_node_t *node, jit_int32_t value) +{ +#if GET_JIT_SIZE + jit_size_collect(node); +#endif + if (value & jit_cc_a0_reg) { + if (value & jit_cc_a0_rlh) { + jit_regset_clrbit(&_jitc->regarg, jit_regno(node->u.q.l)); + jit_regset_clrbit(&_jitc->regarg, jit_regno(node->u.q.h)); + } + else + jit_regset_clrbit(&_jitc->regarg, jit_regno(node->u.w)); + } + if (value & jit_cc_a1_reg) + jit_regset_clrbit(&_jitc->regarg, jit_regno(node->v.w)); + if (value & jit_cc_a2_reg) + jit_regset_clrbit(&_jitc->regarg, jit_regno(node->w.w)); +} + +void +_jit_realize(jit_state_t *_jit) +{ + assert(!_jitc->realize); + if (_jitc->function) + jit_epilog(); + jit_optimize(); + _jitc->realize = 1; + + /* ensure it is aligned */ + _jitc->data.offset = (_jitc->data.offset + 7) & -8; + +#if GET_JIT_SIZE + /* Heuristic to guess code buffer size */ + _jitc->mult = 4; + _jit->code.length = _jitc->pool.length * 1024 * _jitc->mult; +#else + _jit->code.length = jit_get_size(); +#endif +} + +void +_jit_dataset(jit_state_t *_jit) +{ + jit_uint8_t *ptr; + jit_node_t *node; + jit_word_t offset; +#if defined(__sgi) + int mmap_fd; +#endif + + assert(!_jitc->dataset); + if (!_jit->user_data) { + + /* create read only data buffer */ + _jit->data.length = (_jitc->data.offset + + /* reserve space for annotations */ + _jitc->note.size + 4095) & -4096; +#if defined(__sgi) + mmap_fd = open("/dev/zero", O_RDWR); +#endif + _jit->data.ptr = mmap(NULL, _jit->data.length, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, mmap_fd, 0); + assert(_jit->data.ptr != MAP_FAILED); +#if defined(__sgi) + close(mmap_fd); +#endif + } + + if (!_jitc->no_data) + jit_memcpy(_jit->data.ptr, _jitc->data.ptr, _jitc->data.offset); + + if (_jitc->no_note) { + /* Space for one note is always allocated, so revert it here + * if after jit_new_state was called, it is also requested to + * not generate annotation information */ + _jit->note.length = 0; + _jitc->note.size = 0; + } + else { + _jitc->note.base = _jit->data.ptr; + if (!_jitc->no_data) + _jitc->note.base += _jitc->data.offset; + memset(_jitc->note.base, 0, _jitc->note.size); + } + + if (_jit->user_data) + /* Need the temporary hashed data until jit_emit is finished */ + ptr = _jitc->no_data ? _jitc->data.ptr : _jit->data.ptr; + else { + ptr = _jit->data.ptr; + /* Temporary hashed data no longer required */ + jit_free((jit_pointer_t *)&_jitc->data.ptr); + } + + for (offset = 0; offset < _jitc->data.size; offset++) { + for (node = _jitc->data.table[offset]; node; node = node->next) { + node->flag |= jit_flag_patch; + node->u.w = (jit_word_t)(ptr + node->u.w); + } + } + + _jitc->dataset = 1; +} + +jit_pointer_t +_jit_get_code(jit_state_t *_jit, jit_word_t *length) +{ + assert(_jitc->realize); + if (length) { + if (_jitc->done) + /* If code already generated, return exact size of code */ + *length = _jit->pc.uc - _jit->code.ptr; + else + /* Else return current size of the code buffer */ + *length = _jit->code.length; + } + + return (_jit->code.ptr); +} + +void +_jit_set_code(jit_state_t *_jit, jit_pointer_t ptr, jit_word_t length) +{ + assert(_jitc->realize); + _jit->code.ptr = ptr; + _jit->code.length = length; + _jit->user_code = 1; +} + +jit_pointer_t +_jit_get_data(jit_state_t *_jit, jit_word_t *data_size, jit_word_t *note_size) +{ + assert(_jitc->realize); + if (data_size) + *data_size = _jitc->data.offset; + if (note_size) + *note_size = _jitc->note.size; + return (_jit->data.ptr); +} + +void +_jit_set_data(jit_state_t *_jit, jit_pointer_t ptr, + jit_word_t length, jit_word_t flags) +{ + assert(_jitc->realize); + if (flags & JIT_DISABLE_DATA) + _jitc->no_data = 1; + else + assert(length >= _jitc->data.offset); + if (flags & JIT_DISABLE_NOTE) + _jitc->no_note = 1; + else { + if (flags & JIT_DISABLE_DATA) + assert(length >= _jitc->note.size); + else + assert(length >= _jitc->data.offset + _jitc->note.size); + } + _jit->data.ptr = ptr; + _jit->data.length = length; + _jit->user_data = 1; +} + +jit_pointer_t +_jit_emit(jit_state_t *_jit) +{ + jit_pointer_t code; + jit_node_t *node; + size_t length; + int result; +#if defined(__sgi) + int mmap_fd; +#endif + + if (!_jitc->realize) + jit_realize(); + + if (!_jitc->dataset) + jit_dataset(); + + _jitc->emit = 1; + + if (!_jit->user_code) { +#if defined(__sgi) + mmap_fd = open("/dev/zero", O_RDWR); +#endif + _jit->code.ptr = mmap(NULL, _jit->code.length, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, mmap_fd, 0); + assert(_jit->code.ptr != MAP_FAILED); + } + _jitc->code.end = _jit->code.ptr + _jit->code.length - + jit_get_max_instr(); + _jit->pc.uc = _jit->code.ptr; + + for (;;) { + if ((code = emit_code()) == NULL) { + _jitc->patches.offset = 0; + for (node = _jitc->head; node; node = node->next) { + if (node->link && + (node->code == jit_code_label || + node->code == jit_code_epilog)) + node->flag &= ~jit_flag_patch; + } + if (_jit->user_code) + goto fail; +#if GET_JIT_SIZE + ++_jitc->mult; + length = _jitc->pool.length * 1024 * _jitc->mult; +#else + /* Should only happen on very special cases */ + length = _jit->code.length + 4096; +#endif + +#if !HAVE_MREMAP + munmap(_jit->code.ptr, _jit->code.length); +#endif + +#if HAVE_MREMAP +# if __NetBSD__ + _jit->code.ptr = mremap(_jit->code.ptr, _jit->code.length, + _jit->code.ptr, length, 0); +# else + _jit->code.ptr = mremap(_jit->code.ptr, _jit->code.length, + length, MREMAP_MAYMOVE, NULL); +# endif +#else + _jit->code.ptr = mmap(NULL, length, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, mmap_fd, 0); +#endif + + assert(_jit->code.ptr != MAP_FAILED); + _jit->code.length = length; + _jitc->code.end = _jit->code.ptr + _jit->code.length - + jit_get_max_instr(); + _jit->pc.uc = _jit->code.ptr; + } + else + break; + } + +#if defined(__sgi) + if (!_jit->user_code) + close(mmap_fd); +#endif + + _jitc->done = 1; + if (!_jitc->no_note) + jit_annotate(); + + if (_jit->user_data) + jit_free((jit_pointer_t *)&_jitc->data.ptr); + else { + result = mprotect(_jit->data.ptr, _jit->data.length, PROT_READ); + assert(result == 0); + } + if (!_jit->user_code) { + result = mprotect(_jit->code.ptr, _jit->code.length, + PROT_READ | PROT_EXEC); + assert(result == 0); + } + + return (_jit->code.ptr); +fail: + return (NULL); +} + +void +_jit_frame(jit_state_t *_jit, jit_int32_t frame) +{ + jit_trampoline(frame, 1); +} + +void +_jit_tramp(jit_state_t *_jit, jit_int32_t frame) +{ + jit_trampoline(frame, 0); +} + +void +_jit_trampoline(jit_state_t *_jit, jit_int32_t frame, jit_bool_t prolog) +{ + jit_int32_t regno; + + /* Must be called after prolog, actually, just to simplify + * tests and know there is a current function and that + * _jitc->function->self.aoff is at the before any alloca value */ + assert(_jitc->tail && _jitc->tail->code == jit_code_prolog); + + /* + 24 for 3 possible spilled temporaries (that could be a double) */ + frame += 24; +#if defined(__hppa__) + frame += _jitc->function->self.aoff; +#else + frame -= _jitc->function->self.aoff; +#endif + _jitc->function->frame = frame; + if (prolog) + _jitc->function->define_frame = 1; + else + _jitc->function->assume_frame = 1; + for (regno = 0; regno < _jitc->reglen; regno++) + if (jit_class(_rvs[regno].spec) & jit_class_sav) + jit_regset_setbit(&_jitc->function->regset, regno); +} + +/* Compute initial reglive and regmask set values of a basic block. + * reglive is the set of known live registers + * regmask is the set of registers not referenced in the block + * Registers in regmask might be live. + */ +static void +_jit_setup(jit_state_t *_jit, jit_block_t *block) +{ + jit_node_t *node; + jit_bool_t live; + unsigned long value; + + jit_regset_set_mask(&block->regmask, _jitc->reglen); + for (value = 0; value < _jitc->reglen; ++value) + if (!(jit_class(_rvs[value].spec) & (jit_class_gpr|jit_class_fpr))) + jit_regset_clrbit(&block->regmask, value); + + for (node = block->label->next; node; node = node->next) { + switch (node->code) { + case jit_code_label: case jit_code_prolog: + case jit_code_epilog: + return; + default: + /* Check argument registers in reverse order to properly + * handle registers that are both, argument and result */ + value = jit_classify(node->code); + if ((value & jit_cc_a2_reg) && + !(node->w.w & jit_regno_patch) && + jit_regset_tstbit(&block->regmask, node->w.w)) { + live = !(value & jit_cc_a2_chg); + jit_regset_clrbit(&block->regmask, node->w.w); + if (live) + jit_regset_setbit(&block->reglive, node->w.w); + } + if ((value & jit_cc_a1_reg) && + !(node->v.w & jit_regno_patch) && + jit_regset_tstbit(&block->regmask, node->v.w)) { + live = !(value & jit_cc_a1_chg); + jit_regset_clrbit(&block->regmask, node->v.w); + if (live) + jit_regset_setbit(&block->reglive, node->v.w); + } + if (value & jit_cc_a0_reg) { + live = !(value & jit_cc_a0_chg); + if (value & jit_cc_a0_rlh) { + if (!(node->u.q.l & jit_regno_patch) && + jit_regset_tstbit(&block->regmask, node->u.q.l)) { + jit_regset_clrbit(&block->regmask, node->u.q.l); + if (live) + jit_regset_setbit(&block->reglive, node->u.q.l); + } + if (!(node->u.q.h & jit_regno_patch) && + jit_regset_tstbit(&block->regmask, node->u.q.h)) { + jit_regset_clrbit(&block->regmask, node->u.q.h); + if (live) + jit_regset_setbit(&block->reglive, node->u.q.h); + } + } + else { + if (!(node->u.w & jit_regno_patch) && + jit_regset_tstbit(&block->regmask, node->u.w)) { + jit_regset_clrbit(&block->regmask, node->u.w); + if (live) + jit_regset_setbit(&block->reglive, node->u.w); + } + } + } + break; + } + } +} + +/* Update regmask and reglive of blocks at entry point of branch targets + * or normal flow that have a live register not used in this block. + */ +static void +_jit_follow(jit_state_t *_jit, jit_block_t *block, jit_bool_t *todo) +{ + jit_node_t *node; + jit_block_t *next; + jit_int32_t spec; + jit_int32_t regno; + unsigned long value; + jit_node_t *label; + jit_regset_t reglive; + jit_regset_t regmask; + jit_regset_t regtemp; + + jit_regset_set(®live, &block->reglive); + jit_regset_set(®mask, &block->regmask); + for (node = block->label->next; node; node = node->next) { + switch (node->code) { + case jit_code_label: + /* Do not consider jmpi and jmpr cannot jump to the + * next instruction. */ + next = _jitc->blocks.ptr + node->v.w; + /* Set of live registers in next block that are at unknown + * state in this block. */ + jit_regset_and(®temp, ®mask, &next->reglive); + if (jit_regset_set_p(®temp)) { + /* Add live state of next block to current block. */ + jit_regset_ior(&block->reglive, &block->reglive, ®temp); + /* Remove from unknown state bitmask. */ + jit_regset_com(®temp, ®temp); + jit_regset_and(&block->regmask, &block->regmask, ®temp); + *todo = 1; + } + case jit_code_prolog: + case jit_code_epilog: + return; + case jit_code_callr: + value = jit_regno(node->u.w); + if (!(node->u.w & jit_regno_patch)) { + if (jit_regset_tstbit(®mask, value)) { + jit_regset_clrbit(®mask, value); + jit_regset_setbit(®live, value); + } + } + case jit_code_calli: + for (value = 0; value < _jitc->reglen; ++value) { + value = jit_regset_scan1(®mask, value); + if (value >= _jitc->reglen) + break; + spec = jit_class(_rvs[value].spec); + if (!(spec & jit_class_sav)) + jit_regset_clrbit(®mask, value); + if ((spec & jit_class_arg) && jit_regarg_p(node, value)) + jit_regset_setbit(®live, value); + } + break; + default: + value = jit_classify(node->code); + if (value & jit_cc_a2_reg) { + if (!(node->w.w & jit_regno_patch)) { + if (jit_regset_tstbit(®mask, node->w.w)) { + jit_regset_clrbit(®mask, node->w.w); + if (!(value & jit_cc_a2_chg)) + jit_regset_setbit(®live, node->w.w); + } + } + } + if (value & jit_cc_a1_reg) { + if (!(node->v.w & jit_regno_patch)) { + if (jit_regset_tstbit(®mask, node->v.w)) { + jit_regset_clrbit(®mask, node->v.w); + if (!(value & jit_cc_a1_chg)) + jit_regset_setbit(®live, node->v.w); + } + } + } + if (value & jit_cc_a0_reg) { + if (value & jit_cc_a0_rlh) { + if (!(node->u.q.l & jit_regno_patch)) { + if (jit_regset_tstbit(®mask, node->u.q.l)) { + jit_regset_clrbit(®mask, node->u.q.l); + if (!(value & jit_cc_a0_chg)) + jit_regset_setbit(®live, node->u.q.l); + } + } + if (!(node->u.q.h & jit_regno_patch)) { + if (jit_regset_tstbit(®mask, node->u.q.h)) { + jit_regset_clrbit(®mask, node->u.q.h); + if (!(value & jit_cc_a0_chg)) + jit_regset_setbit(®live, node->u.q.h); + } + } + } + else { + if (!(node->u.w & jit_regno_patch)) { + if (jit_regset_tstbit(®mask, node->u.w)) { + jit_regset_clrbit(®mask, node->u.w); + if (!(value & jit_cc_a0_chg)) + jit_regset_setbit(®live, node->u.w); + } + } + } + } + if (value & jit_cc_a0_jmp) { + if (node->flag & jit_flag_node) { + label = node->u.n; + /* Do not consider jmpi and jmpr cannot jump to the + * next instruction. */ + next = _jitc->blocks.ptr + label->v.w; + jit_regset_and(®temp, ®mask, &next->reglive); + if (jit_regset_set_p(®temp)) { + /* Add live state. */ + jit_regset_ior(&block->reglive, + &block->reglive, ®temp); + /* Remove from unknown state bitmask. */ + jit_regset_com(®temp, ®temp); + jit_regset_and(&block->regmask, + &block->regmask, ®temp); + *todo = 1; + } + } + else { + /* Jump to unknown location. + * This is a pitfall of the implementation. + * Only jmpi to not a jit code should reach here, + * or a jmpr of a computed address. + * Because the implementation needs jit_class_nospill + * registers, must treat jmpr as a function call. This + * means that only JIT_Vn registers can be trusted on + * arrival of jmpr. + */ + for (regno = 0; regno < _jitc->reglen; regno++) { + spec = jit_class(_rvs[regno].spec); + if (jit_regset_tstbit(®mask, regno) && + (spec & (jit_class_gpr|jit_class_fpr)) && + !(spec & jit_class_sav)) + jit_regset_clrbit(®mask, regno); + } + /* Assume non callee save registers are live due + * to jump to unknown location. */ + /* Treat all callee save as live. */ + jit_regset_ior(®live, ®live, ®mask); + /* Treat anything else as dead. */ + jit_regset_set_ui(®mask, 0); + } + } + break; + } + } +} + +/* Follow code generation up to finding a label or end of code. + * When finding a label, update the set of live registers. + * On branches, update based on taken branch or normal flow. + */ +static void +_jit_update(jit_state_t *_jit, jit_node_t *node, + jit_regset_t *live, jit_regset_t *mask) +{ + jit_int32_t spec; + jit_int32_t regno; + unsigned long value; + jit_block_t *block; + jit_node_t *label; + jit_regset_t regtemp; + + for (; node; node = node->next) { + if (jit_regset_set_p(mask) == 0) + break; + switch (node->code) { + case jit_code_label: + block = _jitc->blocks.ptr + node->v.w; + jit_regset_and(®temp, mask, &block->reglive); + if (jit_regset_set_p(®temp)) { + /* Add live state. */ + jit_regset_ior(live, live, ®temp); + /* Remove from unknown state bitmask. */ + jit_regset_com(®temp, ®temp); + jit_regset_and(mask, mask, ®temp); + } + return; + case jit_code_prolog: + jit_regset_set_ui(mask, 0); + return; + case jit_code_epilog: + jit_regset_set_ui(mask, 0); + return; + case jit_code_callr: + value = jit_regno(node->u.w); + if (!(node->u.w & jit_regno_patch)) { + if (jit_regset_tstbit(mask, value)) { + jit_regset_clrbit(mask, value); + jit_regset_setbit(live, value); + } + } + case jit_code_calli: + for (value = 0; value < _jitc->reglen; ++value) { + value = jit_regset_scan1(mask, value); + if (value >= _jitc->reglen) + break; + spec = jit_class(_rvs[value].spec); + if (!(spec & jit_class_sav)) + jit_regset_clrbit(mask, value); + if ((spec & jit_class_arg) && jit_regarg_p(node, value)) + jit_regset_setbit(live, value); + } + break; + default: + value = jit_classify(node->code); + if (value & jit_cc_a2_reg) { + if (!(node->w.w & jit_regno_patch)) { + if (jit_regset_tstbit(mask, node->w.w)) { + jit_regset_clrbit(mask, node->w.w); + if (!(value & jit_cc_a2_chg)) + jit_regset_setbit(live, node->w.w); + } + } + } + if (value & jit_cc_a1_reg) { + if (!(node->v.w & jit_regno_patch)) { + if (jit_regset_tstbit(mask, node->v.w)) { + jit_regset_clrbit(mask, node->v.w); + if (!(value & jit_cc_a1_chg)) + jit_regset_setbit(live, node->v.w); + } + } + } + if (value & jit_cc_a0_reg) { + if (value & jit_cc_a0_rlh) { + if (!(node->u.q.l & jit_regno_patch)) { + if (jit_regset_tstbit(mask, node->u.q.l)) { + jit_regset_clrbit(mask, node->u.q.l); + if (!(value & jit_cc_a0_chg)) + jit_regset_setbit(live, node->u.q.l); + } + } + if (!(node->u.q.h & jit_regno_patch)) { + if (jit_regset_tstbit(mask, node->u.q.h)) { + jit_regset_clrbit(mask, node->u.q.h); + if (!(value & jit_cc_a0_chg)) + jit_regset_setbit(live, node->u.q.h); + } + } + } + else { + if (!(node->u.w & jit_regno_patch)) { + if (jit_regset_tstbit(mask, node->u.w)) { + jit_regset_clrbit(mask, node->u.w); + if (!(value & jit_cc_a0_chg)) + jit_regset_setbit(live, node->u.w); + } + } + } + } + if (value & jit_cc_a0_jmp) { + if (node->flag & jit_flag_node) { + label = node->u.n; + /* Do not consider jmpi and jmpr cannot jump to the + * next instruction. */ + block = _jitc->blocks.ptr + label->v.w; + jit_regset_and(®temp, mask, &block->reglive); + if (jit_regset_set_p(®temp)) { + /* Add live state. */ + jit_regset_ior(live, live, ®temp); + /* Remove from unknown state bitmask. */ + jit_regset_com(®temp, ®temp); + jit_regset_and(mask, mask, ®temp); + } + } + else { + /* Jump to unknown location. + * This is a pitfall of the implementation. + * Only jmpi to not a jit code should reach here, + * or a jmpr of a computed address. + * Because the implementation needs jit_class_nospill + * registers, must treat jmpr as a function call. This + * means that only JIT_Vn registers can be trusted on + * arrival of jmpr. + */ + for (regno = 0; regno < _jitc->reglen; regno++) { + spec = jit_class(_rvs[regno].spec); + if (jit_regset_tstbit(mask, regno) && + (spec & (jit_class_gpr|jit_class_fpr)) && + !(spec & jit_class_sav)) + jit_regset_clrbit(mask, regno); + } + /* Assume non callee save registers are live due + * to jump to unknown location. */ + /* Treat all callee save as live. */ + jit_regset_ior(live, live, mask); + /* Treat anything else as dead. */ + jit_regset_set_ui(mask, 0); + } + } + break; + } + } +} + +static void +_thread_jumps(jit_state_t *_jit) +{ + jit_node_t *prev; + jit_node_t *node; + jit_node_t *next; + jit_int32_t mask; + + for (prev = node = _jitc->head; node;) { + next = node->next; + switch (node->code) { + case jit_code_jmpi: + if (redundant_jump(prev, node)) { + node = prev; + continue; + } + if (shortcut_jump(prev, node)) + continue; + break; + case jit_code_jmpr: + case jit_code_callr: case jit_code_calli: + /* non optimizable jump like code */ + break; + default: + mask = jit_classify(node->code); + if (mask & jit_cc_a0_jmp) { + if (reverse_jump(prev, node) || + shortcut_jump(prev, node)) + continue; + } + break; + } + prev = node; + node = next; + } +} + +static void +_sequential_labels(jit_state_t *_jit) +{ + jit_node_t *jump; + jit_node_t *link; + jit_node_t *prev; + jit_node_t *next; + jit_node_t *node; + + for (prev = node = _jitc->head; node; node = next) { + next = node->next; + if (node->code == jit_code_label) { + if (!node->flag) { + if (!node->link) { + del_label(prev, node); + continue; + } + if (prev != node && prev->code == jit_code_label) { + if ((jump = node->link)) { + for (; jump; jump = link) { + link = jump->link; + jump->u.n = prev; + jump->link = prev->link; + prev->link = jump; + } + node->link = NULL; + } + del_label(prev, node); + continue; + } + } + if (next && next->code == jit_code_label && !next->flag) { + if ((jump = next->link)) { + for (; jump; jump = link) { + link = jump->link; + jump->u.n = node; + jump->link = node->link; + node->link = jump; + } + next->link = NULL; + } + del_label(node, next); + next = node->next; + continue; + } + } + prev = node; + } +} + +static void +_split_branches(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *next; + jit_node_t *label; + jit_block_t *block; + + for (node = _jitc->head; node; node = next) { + if ((next = node->next)) { + if (next->code == jit_code_label || + next->code == jit_code_prolog || + next->code == jit_code_epilog) + continue; + /* split block on branches */ + if (jit_classify(node->code) & jit_cc_a0_jmp) { + label = new_node(jit_code_label); + label->next = next; + node->next = label; + if (_jitc->blocks.offset >= _jitc->blocks.length) { + jit_word_t length; + + length = _jitc->blocks.length + 16; + jit_realloc((jit_pointer_t *)&_jitc->blocks.ptr, + _jitc->blocks.length * sizeof(jit_block_t), + length * sizeof(jit_block_t)); + _jitc->blocks.length = length; + } + block = _jitc->blocks.ptr + _jitc->blocks.offset; + block->label = label; + label->v.w = _jitc->blocks.offset; + jit_regset_new(&block->reglive); + jit_regset_new(&block->regmask); + ++_jitc->blocks.offset; + } + } + } +} + +static jit_bool_t +_shortcut_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node) +{ + jit_bool_t cond; + jit_node_t *jump; + jit_node_t *next; + jit_node_t *temp; + + if (!(node->flag & jit_flag_node)) + return (0); + assert(node->code != jit_code_jmpr); + cond = node->code != jit_code_jmpi; + jump = node->u.n; + for (next = jump->next; next; next = next->next) { + switch (next->code) { + case jit_code_jmpi: + if (!(next->flag & jit_flag_node)) + return (0); + if (jump->link == node) + jump->link = node->link; + else { + for (temp = jump->link; + temp->link != node; + temp = temp->link) + assert(temp != NULL); + temp->link = node->link; + } + jump = next->u.n; + node->u.n = jump; + node->link = jump->link; + jump->link = node; + return (1); + case jit_code_jmpr: + if (cond) + return (0); + node->code = jit_code_jmpr; + node->u.w = next->u.w; + node->link = NULL; + node->flag &= ~jit_flag_node; + return (1); + case jit_code_note: case jit_code_label: + break; + default: + return (0); + } + } + return (0); +} + +static jit_bool_t +_redundant_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node) +{ + jit_node_t *local_prev; + jit_node_t *local_next; + + if (!(node->flag & jit_flag_node)) + return (0); + for (local_prev = node, local_next = node->next; + local_next; + local_prev = local_next, local_next = local_next->next) { + + switch (local_next->code) { + case jit_code_label: case jit_code_epilog: + if (node->u.n == local_next) { + if (local_next->link == node) + local_next->link = node->link; + else { + for (local_prev = local_next->link; + local_prev->link != node; + local_prev = local_prev->link) + assert(local_prev != NULL); + local_prev->link = node->link; + } + del_node(prev, node); + return (1); + } + break; + case jit_code_name: case jit_code_note: + case jit_code_align: + break; + default: + return (0); + } + } + return (0); +} + +static jit_code_t +reverse_jump_code(jit_code_t code) +{ + switch (code) { + case jit_code_bltr: return (jit_code_bger); + case jit_code_blti: return (jit_code_bgei); + case jit_code_bltr_u: return (jit_code_bger_u); + case jit_code_blti_u: return (jit_code_bgei_u); + case jit_code_bler: return (jit_code_bgtr); + case jit_code_blei: return (jit_code_bgti); + case jit_code_bler_u: return (jit_code_bgtr_u); + case jit_code_blei_u: return (jit_code_bgti_u); + case jit_code_beqr: return (jit_code_bner); + case jit_code_beqi: return (jit_code_bnei); + case jit_code_bger: return (jit_code_bltr); + case jit_code_bgei: return (jit_code_blti); + case jit_code_bger_u: return (jit_code_bltr_u); + case jit_code_bgei_u: return (jit_code_blti_u); + case jit_code_bgtr: return (jit_code_bler); + case jit_code_bgti: return (jit_code_blei); + case jit_code_bgtr_u: return (jit_code_bler_u); + case jit_code_bgti_u: return (jit_code_blei_u); + case jit_code_bner: return (jit_code_beqr); + case jit_code_bnei: return (jit_code_beqi); + case jit_code_bmsr: return (jit_code_bmcr); + case jit_code_bmsi: return (jit_code_bmci); + case jit_code_bmcr: return (jit_code_bmsr); + case jit_code_bmci: return (jit_code_bmsi); + case jit_code_bltr_f: return (jit_code_bunger_f); + case jit_code_blti_f: return (jit_code_bungei_f); + case jit_code_bler_f: return (jit_code_bungtr_f); + case jit_code_blei_f: return (jit_code_bungti_f); + + case jit_code_beqr_f: return (jit_code_bner_f); + case jit_code_beqi_f: return (jit_code_bnei_f); + + case jit_code_bger_f: return (jit_code_bunltr_f); + case jit_code_bgei_f: return (jit_code_bunlti_f); + case jit_code_bgtr_f: return (jit_code_bunler_f); + case jit_code_bgti_f: return (jit_code_bunlei_f); + + case jit_code_bner_f: return (jit_code_beqr_f); + case jit_code_bnei_f: return (jit_code_beqr_f); + + case jit_code_bunltr_f: return (jit_code_bger_f); + case jit_code_bunlti_f: return (jit_code_bgei_f); + case jit_code_bunler_f: return (jit_code_bgtr_f); + case jit_code_bunlei_f: return (jit_code_bgti_f); + + case jit_code_buneqr_f: return (jit_code_bltgtr_f); + case jit_code_buneqi_f: return (jit_code_bltgti_f); + + case jit_code_bunger_f: return (jit_code_bltr_f); + case jit_code_bungei_f: return (jit_code_blti_f); + case jit_code_bungtr_f: return (jit_code_bler_f); + case jit_code_bungti_f: return (jit_code_blei_f); + + case jit_code_bltgtr_f: return (jit_code_buneqr_f); + case jit_code_bltgti_f: return (jit_code_buneqi_f); + + case jit_code_bordr_f: return (jit_code_bunordr_f); + case jit_code_bordi_f: return (jit_code_bunordi_f); + case jit_code_bunordr_f:return (jit_code_bordr_f); + case jit_code_bunordi_f:return (jit_code_bordi_f); + case jit_code_bltr_d: return (jit_code_bunger_d); + case jit_code_blti_d: return (jit_code_bungei_d); + case jit_code_bler_d: return (jit_code_bungtr_d); + case jit_code_blei_d: return (jit_code_bungti_d); + + case jit_code_beqr_d: return (jit_code_bner_d); + case jit_code_beqi_d: return (jit_code_bnei_d); + + case jit_code_bger_d: return (jit_code_bunltr_d); + case jit_code_bgei_d: return (jit_code_bunlti_d); + case jit_code_bgtr_d: return (jit_code_bunler_d); + case jit_code_bgti_d: return (jit_code_bunlei_d); + + case jit_code_bner_d: return (jit_code_beqr_d); + case jit_code_bnei_d: return (jit_code_beqi_d); + + case jit_code_bunltr_d: return (jit_code_bger_d); + case jit_code_bunlti_d: return (jit_code_bgei_d); + case jit_code_bunler_d: return (jit_code_bgtr_d); + case jit_code_bunlei_d: return (jit_code_bgti_d); + + case jit_code_buneqr_d: return (jit_code_bltgtr_d); + case jit_code_buneqi_d: return (jit_code_bltgti_d); + + case jit_code_bunger_d: return (jit_code_bltr_d); + case jit_code_bungei_d: return (jit_code_blti_d); + case jit_code_bungtr_d: return (jit_code_bler_d); + case jit_code_bungti_d: return (jit_code_blei_d); + + case jit_code_bltgtr_d: return (jit_code_buneqr_d); + case jit_code_bltgti_d: return (jit_code_buneqi_d); + + case jit_code_bordr_d: return (jit_code_bunordr_d); + case jit_code_bordi_d: return (jit_code_bunordi_d); + case jit_code_bunordr_d:return (jit_code_bordr_d); + case jit_code_bunordi_d:return (jit_code_bordi_d); + case jit_code_boaddr: return (jit_code_bxaddr); + case jit_code_boaddi: return (jit_code_bxaddi); + case jit_code_boaddr_u: return (jit_code_bxaddr_u); + case jit_code_boaddi_u: return (jit_code_bxaddi_u); + case jit_code_bxaddr: return (jit_code_boaddr); + case jit_code_bxaddi: return (jit_code_boaddi); + case jit_code_bxaddr_u: return (jit_code_boaddr_u); + case jit_code_bxaddi_u: return (jit_code_boaddi_u); + case jit_code_bosubr: return (jit_code_bxsubr); + case jit_code_bosubi: return (jit_code_bxsubi); + case jit_code_bosubr_u: return (jit_code_bxsubr_u); + case jit_code_bosubi_u: return (jit_code_bxsubi_u); + case jit_code_bxsubr: return (jit_code_bosubr); + case jit_code_bxsubi: return (jit_code_bosubi); + case jit_code_bxsubr_u: return (jit_code_bosubr_u); + case jit_code_bxsubi_u: return (jit_code_bosubi_u); + default: abort(); /* invalid jump code */ + } +} + +/* + * change common pattern: + * <cond_jump L0> <jump L1> <label L0> + * into + * <reverse_cond_jump L1> + */ +static jit_bool_t +_reverse_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node) +{ + jit_node_t *local_prev; + jit_node_t *local_next; + jit_node_t *local_jump; + + if (!(node->flag & jit_flag_node)) + return (0); + /* =><cond_jump L0> <jump L1> <label L0> */ + local_next = node->next; + if (local_next->code != jit_code_jmpi || + !(local_next->flag & jit_flag_node)) + return (0); + /* <cond_jump L0> =><jump L1> <label L0> */ + + local_jump = local_next->u.n; + for (local_prev = local_next, local_next = local_next->next; + local_next; + local_prev = local_next, local_next = local_next->next) { + switch (local_next->code) { + case jit_code_label: case jit_code_epilog: + if (node->u.n == local_next) { + if (local_next->link == node) + local_next->link = node->link; + else { + for (local_prev = local_next->link; + local_prev->link != node; + local_prev = local_prev->link) + assert(local_prev != NULL); + local_prev->link = node->link; + } + del_node(node, node->next); + node->code = reverse_jump_code(node->code); + node->u.n = local_jump; + node->link = local_jump->link; + local_jump->link = node; + return (1); + } + break; + case jit_code_note: + break; + default: + return (0); + } + } + return (0); +} + +static void +_redundant_store(jit_state_t *_jit, jit_node_t *node, jit_bool_t jump) +{ + jit_node_t *iter; + jit_node_t *prev; + jit_word_t word; + jit_int32_t spec; + jit_int32_t regno; + + if (jump) { + prev = node->u.n; + if (prev->code == jit_code_epilog) + return; + assert(prev->code == jit_code_label); + if ((prev->flag & jit_flag_head) || node->link || prev->link != node) + /* multiple sources */ + return; + /* if there are sequential labels it will return below */ + } + else + prev = node; + word = node->w.w; + regno = jit_regno(node->v.w); + for (iter = prev->next; iter; prev = iter, iter = iter->next) { + switch (iter->code) { + case jit_code_label: case jit_code_prolog: + case jit_code_epilog: + return; + case jit_code_movi: + if (regno == jit_regno(iter->u.w)) { + if (iter->flag || iter->v.w != word) + return; + del_node(prev, iter); + iter = prev; + } + break; + default: + spec = jit_classify(iter->code); + if (spec & jit_cc_a0_jmp) + return; + if ((spec & (jit_cc_a0_reg|jit_cc_a0_chg)) == + (jit_cc_a0_reg|jit_cc_a0_chg)) { + if (spec & jit_cc_a0_rlh) { + if (regno == jit_regno(iter->u.q.l) || + regno == jit_regno(iter->u.q.h)) + return; + } + else { + if (regno == jit_regno(iter->u.w)) + return; + } + } + if ((spec & (jit_cc_a1_reg|jit_cc_a1_chg)) == + (jit_cc_a1_reg|jit_cc_a1_chg)) { + if (regno == jit_regno(iter->v.w)) + return; + } + if ((spec & (jit_cc_a2_reg|jit_cc_a2_chg)) == + (jit_cc_a2_reg|jit_cc_a2_chg)) { + if (regno == jit_regno(iter->w.w)) + return; + } + break; + } + } +} + +static jit_bool_t +_simplify_movr(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node, + jit_int32_t kind, jit_int32_t size) +{ + jit_int32_t regno; + jit_int32_t right; + jit_value_t *value; + + regno = jit_regno(node->u.w); + right = jit_regno(node->v.w); + value = _jitc->values + regno; + if ((value->kind == jit_kind_register && + jit_regno(value->base.q.l) == right && + value->base.q.h == _jitc->gen[right]) || + (value->kind == kind && _jitc->values[right].kind == kind && + memcmp(&value->base.w, &_jitc->values[right].base.w, size) == 0)) { + del_node(prev, node); + return (1); + } + if (_jitc->values[right].kind == jit_kind_word) + jit_memcpy(value, _jitc->values + right, sizeof(jit_value_t)); + else { + value->kind = jit_kind_register; + value->base.q.l = right; + value->base.q.h = _jitc->gen[right]; + } + ++_jitc->gen[regno]; + + return (0); +} + +static jit_bool_t +_simplify_movi(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node, + jit_int32_t kind, jit_int32_t size) +{ + jit_value_t *value; + jit_int32_t spec; + jit_int32_t regno; + jit_int32_t offset; + + regno = jit_regno(node->u.w); + value = _jitc->values + regno; + if (node->flag & jit_flag_node) { + /* set to undefined if value will be patched */ + value->kind = 0; + ++_jitc->gen[regno]; + return (0); + } + if (value->kind == kind) { + if (memcmp(&node->v.w, &value->base.w, size) == 0) { + del_node(prev, node); + return (1); + } + spec = jit_class(_rvs[regno].spec); + if (kind == jit_kind_word) + spec &= jit_class_gpr; + else + spec &= (jit_class_xpr | jit_class_fpr); + for (offset = 0; offset < _jitc->reglen; offset++) { + if (_jitc->values[offset].kind == kind && + memcmp(&node->v.w, &_jitc->values[offset].base.w, size) == 0 && + (jit_class(_rvs[offset].spec) & spec) == spec) { + if (kind == jit_kind_word) + node->code = jit_code_movr; + else if (kind == jit_kind_float32) + node->code = jit_code_movr_f; + else + node->code = jit_code_movr_d; + node->v.w = offset; + jit_memcpy(value, _jitc->values + offset, sizeof(jit_value_t)); + ++_jitc->gen[regno]; + return (0); + } + } + } + value->kind = kind; + jit_memcpy(&value->base.w, &node->v.w, size); + ++_jitc->gen[regno]; + + return (0); +} + +/* simple/safe redundandy test not checking if another register + * holds the same value + */ +static jit_bool_t +_simplify_ldxi(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node) +{ + jit_value_t *value; + jit_int32_t regno; + jit_int32_t right; + + regno = jit_regno(node->u.w); + right = jit_regno(node->v.w); + value = _jitc->values + regno; + if (regno != right && + value->kind == jit_kind_code && value->code == node->code && + value->base.q.l == right && value->base.q.h == _jitc->gen[right] && + node->w.w == value->disp.w) { + del_node(prev, node); + return (1); + } + value->kind = jit_kind_code; + value->code = node->code; + value->base.q.l = right; + value->base.q.h = _jitc->gen[right]; + value->disp.w = node->w.w; + ++_jitc->gen[regno]; + + return (0); +} + +static jit_bool_t +_simplify_stxi(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node) +{ + jit_value_t *value; + jit_int32_t regno; + jit_int32_t right; + jit_int32_t offset; + + regno = jit_regno(node->w.w); + right = jit_regno(node->v.w); + value = _jitc->values + regno; + + /* check for redundant store after load */ + if (regno != right && + value->kind == jit_kind_code && value->code == node->code && + value->base.q.l == right && value->base.q.h == _jitc->gen[right] && + node->u.w == value->disp.w) { + del_node(prev, node); + return (1); + } + + /* assume anything can alias, and invalidate tracked values */ + for (offset = 0; offset < _jitc->reglen; offset++) { + if (_jitc->values[offset].kind == jit_kind_code) { + _jitc->values[offset].kind = 0; + ++_jitc->gen[offset]; + } + } + + /* no multiple information, so, if set to a constant, + * prefer to keep that information */ + if (value->kind == 0) { + value->kind = jit_kind_code; + switch (node->code) { + /* no information about signed/unsigned either */ + case jit_code_stxi_c: value->code = jit_code_ldxi_c; break; + case jit_code_stxi_s: value->code = jit_code_ldxi_s; break; + case jit_code_stxi_i: value->code = jit_code_ldxi_i; break; + case jit_code_stxi_l: value->code = jit_code_ldxi_l; break; + case jit_code_stxi_f: value->code = jit_code_ldxi_f; break; + case jit_code_stxi_d: value->code = jit_code_ldxi_d; break; + default: abort(); + } + value->kind = jit_kind_code; + value->base.q.l = right; + value->base.q.h = _jitc->gen[right]; + value->disp.w = node->u.w; + } + + return (0); +} + +/* usually there should be only one store in the + * jit_get_reg/jit_unget_reg, but properly handle + * multiple ones by moving the save node */ +static void +_simplify_spill(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + jit_node_t *save; + jit_node_t *temp; + + if ((temp = _jitc->spill[regno]) && (save = temp->next) != node) { + temp->next = save->next; + save->next = node->next; + node->next = save; + _jitc->spill[regno] = node; + } +} + +/* checks for simple cases where a register is set more than + * once to the same value, and is a common pattern of calls + * to jit_pushargi and jit_pushargr + */ +static void +_simplify(jit_state_t *_jit) +{ + jit_node_t *prev; + jit_node_t *node; + jit_node_t *next; + jit_int32_t info; + jit_int32_t regno; + + for (prev = NULL, node = _jitc->head; node; prev = node, node = next) { + next = node->next; + switch (node->code) { + case jit_code_label: case jit_code_prolog: + case jit_code_callr: case jit_code_calli: + reset: + memset(_jitc->gen, 0, sizeof(jit_int32_t) * _jitc->reglen); + memset(_jitc->values, 0, sizeof(jit_value_t) * _jitc->reglen); + break; + case jit_code_save: + _jitc->spill[jit_regno(node->u.w)] = prev; + break; + case jit_code_load: + regno = jit_regno(node->u.w); + if (register_change_p(node->link->next, node, regno) != + jit_reg_change) { + /* spill not required due to optimizing common + * redundancy case of calling jit_get_reg/jit_unget_reg + * and then setting the register to the value it is + * already holding */ + patch_register(node->link->next, node, + jit_regno_patch|regno, regno); + del_node(_jitc->spill[regno], node->link); + del_node(prev, node); + node = prev; + } + _jitc->spill[regno] = NULL; + break; + case jit_code_movr: + regno = jit_regno(node->u.w); + if (simplify_movr(prev, node, + jit_kind_word, sizeof(jit_word_t))) + simplify_spill(node = prev, regno); + break; + case jit_code_movi: + regno = jit_regno(node->u.w); + if (simplify_movi(prev, node, + jit_kind_word, sizeof(jit_word_t))) + simplify_spill(node = prev, regno); + break; + case jit_code_movr_f: + regno = jit_regno(node->u.w); + if (simplify_movr(prev, node, + jit_kind_float32, sizeof(jit_float32_t))) + simplify_spill(node = prev, regno); + break; + case jit_code_movi_f: + regno = jit_regno(node->u.w); + if (simplify_movi(prev, node, + jit_kind_float32, sizeof(jit_float32_t))) + simplify_spill(node = prev, regno); + break; + case jit_code_movr_d: + regno = jit_regno(node->u.w); + if (simplify_movr(prev, node, + jit_kind_float64, sizeof(jit_float64_t))) + simplify_spill(node = prev, regno); + break; + case jit_code_movi_d: + regno = jit_regno(node->u.w); + if (simplify_movi(prev, node, + jit_kind_float64, sizeof(jit_float64_t))) + simplify_spill(node = prev, regno); + break; + case jit_code_ldxi_c: case jit_code_ldxi_uc: + case jit_code_ldxi_s: case jit_code_ldxi_us: + case jit_code_ldxi_i: case jit_code_ldxi_ui: + case jit_code_ldxi_l: + case jit_code_ldxi_f: case jit_code_ldxi_d: + regno = jit_regno(node->u.w); + if (simplify_ldxi(prev, node)) + simplify_spill(node = prev, regno); + break; + case jit_code_stxi_c: case jit_code_stxi_s: + case jit_code_stxi_i: case jit_code_stxi_l: + case jit_code_stxi_f: case jit_code_stxi_d: + regno = jit_regno(node->u.w); + if (simplify_stxi(prev, node)) + simplify_spill(node = prev, regno); + break; + default: + info = jit_classify(node->code); + if (info & jit_cc_a0_jmp) + /* labels are not implicitly added when not taking + * a conditional branch */ + goto reset; + if (info & jit_cc_a0_chg) { + if (info & jit_cc_a0_rlh) { + regno = jit_regno(node->u.q.l); + _jitc->values[regno].kind = 0; + ++_jitc->gen[regno]; + regno = jit_regno(node->u.q.h); + _jitc->values[regno].kind = 0; + ++_jitc->gen[regno]; + } + else { + regno = jit_regno(node->u.w); + _jitc->values[regno].kind = 0; + ++_jitc->gen[regno]; + } + } + if (info & jit_cc_a1_chg) { + regno = jit_regno(node->v.w); + _jitc->values[regno].kind = 0; + ++_jitc->gen[regno]; + } + if (info & jit_cc_a2_chg) { + regno = jit_regno(node->w.w); + _jitc->values[regno].kind = 0; + ++_jitc->gen[regno]; + } + break; + } + } +} + +static jit_int32_t +_register_change_p(jit_state_t *_jit, jit_node_t *node, jit_node_t *link, + jit_int32_t regno) +{ + jit_int32_t value; + + for (; node != link; node = node->next) { + switch (node->code) { + case jit_code_label: case jit_code_prolog: + /* lack of extra information so cannot say it is undefined */ + return (jit_reg_change); + case jit_code_callr: case jit_code_calli: + if (!(jit_class(_rvs[regno].spec) & jit_class_sav)) + return (jit_reg_undef); + break; + default: + value = jit_classify(node->code); + /* lack of extra information */ + if (value & jit_cc_a0_jmp) + return (jit_reg_change); + else if ((value & (jit_cc_a0_reg|jit_cc_a0_chg)) == + (jit_cc_a0_reg|jit_cc_a0_chg) && + (((value & jit_cc_a0_rlh) && + (node->u.q.l == regno || node->u.q.h == regno)) || + (!(value & jit_cc_a0_rlh) && + node->u.w == regno))) + return (jit_reg_change); + else if ((value & jit_cc_a1_reg) && node->v.w == regno && + (value & jit_cc_a1_chg)) + return (jit_reg_change); + else if ((value & jit_cc_a2_reg) && node->w.w == regno && + (value & jit_cc_a2_chg)) + return (jit_reg_change); + } + } + + return (jit_reg_static); +} + +/* most of this could be done at the same time as generating jit, but + * avoid complications on different cpu backends and patch spill/loads + * here, by simulating jit generation */ +static jit_bool_t +_spill_reglive_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + if (!jit_regset_tstbit(&_jitc->reglive, regno)) { + jit_regset_setbit(&_jitc->regmask, regno); + jit_update(node->next, &_jitc->reglive, &_jitc->regmask); + if (!jit_regset_tstbit(&_jitc->reglive, regno) && + register_change_p(node->next, node->link, regno) != jit_reg_change) + return (0); + } + + return (1); +} + +static void +_patch_registers(jit_state_t *_jit) +{ + jit_node_t *prev; + jit_node_t *node; + jit_node_t *next; + jit_int32_t info; + jit_int32_t spec; + jit_int32_t regno; + jit_int32_t value; + + _jitc->function = NULL; + + jit_reglive_setup(); + for (prev = NULL, node = _jitc->head; node; node = next) { + next = node->next; + + info = jit_classify(node->code); + jit_regarg_set(node, info); + + switch (node->code) { + case jit_code_save: + regno = jit_regno(node->u.w); + if (!spill_reglive_p(node, regno)) { + /* register is not live, just remove spill/reload */ + jit_regarg_clr(node, info); + node->link->v.w = jit_regload_delete; + del_node(prev, node); + continue; + } + else { + /* try to find a free register of the same class */ + spec = jit_class(_rvs[regno].spec) & ~jit_class_arg; + for (value = 0; value < _jitc->reglen; value++) { + if (value != regno && + ((jit_class(_rvs[value].spec) & spec) & + ~jit_class_arg) == spec && + !jit_regset_tstbit(&_jitc->regarg, value) && + !spill_reglive_p(node, value)) + break; + } + if (value < _jitc->reglen) { + jit_regarg_clr(node, info); + patch_register(node->next, node->link, + jit_regno_patch|node->u.w, + jit_regno_patch|value); + /* mark as live just in case there are nested + * register patches, so that next patch will + * not want to use the same register */ + jit_regset_setbit(&_jitc->reglive, value); + /* register is not live, just remove spill/reload */ + node->link->v.w = jit_regload_isdead; + del_node(prev, node); + continue; + } + else { + /* failed to find a free register */ + if (spec & jit_class_gpr) { + if (!_jitc->function->regoff[regno]) + _jitc->function->regoff[regno] = + jit_allocai(sizeof(jit_word_t)); +#if __WORDSIZE == 32 + node->code = jit_code_stxi_i; +#else + node->code = jit_code_stxi_l; +#endif + } + else { + node->code = jit_code_stxi_d; + if (!_jitc->function->regoff[regno]) + _jitc->function->regoff[regno] = + jit_allocai(sizeof(jit_float64_t)); + } + node->u.w = _jitc->function->regoff[regno]; + node->v.w = JIT_FP; + node->w.w = regno; + node->link = NULL; + } + } + break; + case jit_code_load: + regno = jit_regno(node->u.w); + if (node->v.w) { + if (node->v.w == jit_regload_isdead) + jit_regset_clrbit(&_jitc->reglive, regno); + del_node(prev, node); + continue; + } + spec = jit_class(_rvs[regno].spec); + if (spec & jit_class_gpr) { +#if __WORDSIZE == 32 + node->code = jit_code_ldxi_i; +#else + node->code = jit_code_ldxi_l; +#endif + } + else + node->code = jit_code_ldxi_d; + node->v.w = regno; + node->v.w = JIT_FP; + node->w.w = _jitc->function->regoff[regno]; + node->link = NULL; + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + break; + case jit_code_epilog: + _jitc->function = NULL; + break; + default: + break; + } + + jit_regarg_clr(node, info); + /* update register live state */ + jit_reglive(node); + prev = node; + } +} + +static void +_patch_register(jit_state_t *_jit, jit_node_t *node, jit_node_t *link, + jit_int32_t regno, jit_int32_t patch) +{ + jit_int32_t value; + + for (; node != link; node = node->next) { + value = jit_classify(node->code); + if (value & jit_cc_a0_reg) { + if (value & jit_cc_a0_rlh) { + if (node->u.q.l == regno) + node->u.q.l = patch; + if (node->u.q.h == regno) + node->u.q.h = patch; + } + else { + if (node->u.w == regno) + node->u.w = patch; + } + } + if ((value & jit_cc_a1_reg) && node->v.w == regno) + node->v.w = patch; + if ((value & jit_cc_a2_reg) && node->w.w == regno) + node->w.w = patch; + } +} + +#if defined(__i386__) || defined(__x86_64__) +# include "jit_x86.c" +#elif defined(__mips__) +# include "jit_mips.c" +#elif defined(__arm__) +# include "jit_arm.c" +#elif defined(__powerpc__) +# include "jit_ppc.c" +#elif defined(__sparc__) +# include "jit_sparc.c" +#elif defined(__ia64__) +# include "jit_ia64.c" +#elif defined(__hppa__) +# include "jit_hppa.c" +#elif defined(__aarch64__) +# include "jit_aarch64.c" +#elif defined(__s390__) || defined(__s390x__) +# include "jit_s390.c" +#elif defined(__alpha__) +# include "jit_alpha.c" +#elif defined(__riscv) +# include "jit_riscv.c" +#endif |