--- /dev/null
+/*
+ * Copyright (C) 2022 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 ii(i) *_jit->pc.ui++ = (i)
+# define can_sign_extend_si12_p(s12) ((s12) <= 2047 && (s12) >= -2048)
+# define can_zero_extend_u12_p(u12) ((u12) <= 4095 && (u12) >= 0)
+# define can_sign_extend_si16_p(s16) ((s16) <= 32767 && (s16) >= -32768)
+# define can_sign_extend_si21_p(s21) ((s21) <= 1048575 && (s21) >= -1048576)
+# define can_sign_extend_si26_p(s26) \
+ ((s26) <= 33554431 && (s26) >= -33554432)
+# define can_sign_extend_si32_p(s32) \
+ ((s32) <= 2147483647LL && (s32) >= -2147483648LL)
+# define _ZERO_REGNO 0
+# define _RA_REGNO 1
+# define _SP_REGNO 3
+# define _FP_REGNO 22
+# define stack_framesize 160
+# 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)
+# define orrr(op, rk, rj, rd) _orrr(_jit, op, rk, rj, rd)
+# define ou5rr(op, i5, rj, rd) _orrr(_jit, op, i5, rj, rd)
+# define orru5(op, rk, rj, i5) _orrr(_jit, op, rk, rj, i5)
+static void _orrr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define ou2rrr(op, i2, rk, rj, rd) _ou2rrr(_jit, op, i2, rk, rj, rd)
+static void _ou2rrr(jit_state_t*,jit_int32_t,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define ou3rrr(op, u3, rk, rj, rd) _ou3rrr(_jit, op, u3, rk, rj, rd)
+static void _ou3rrr(jit_state_t*,jit_int32_t,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define ou6rr(op, u6, rj, rd) _ou6rr(_jit, op, u6, rj, rd)
+static void _ou6rr(jit_state_t*,jit_int32_t,
+ jit_int32_t,jit_int32_t,jit_int32_t);
+# define ou5u1u5rr(op,m5,u1,l5,rj,rd) _ou5u1u5rr(_jit,op,m5,u1,l5,rj,rd)
+static void _ou5u1u5rr(jit_state_t*,jit_int32_t,jit_int32_t,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define ou6u6rr(op, m6, l6, rj, rd) _ou6u6rr(_jit, op, m6, l6, rj, rd)
+static void _ou6u6rr(jit_state_t*,jit_int32_t,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define o5r23(op, i5, rj, i2, rd) _o5r23(_jit, op, i5, rj, i2, rd)
+static void _o5r23(jit_state_t*,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define o523r(op, i5, i2, rj, i3) _o523r(_jit, op, i5, i2, rj, i3)
+static void _o523r(jit_state_t*,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define os12rr(op, i12, rj, rd) _os12rr(_jit, op, i12, rj, rd)
+# define os12ru5(op, i12, rj, u5) _os12rr(_jit, op, i12, rj, u5)
+static void _os12rr(jit_state_t*,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define ou12rr(op, u12, rj, rd) _ou12rr(_jit, op, u12, rj, rd)
+static void _ou12rr(jit_state_t*,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define ou14u5r(op, u14, u5, rd) _ou14u5r(_jit, op, u14, u5, rd)
+static void _osu14u5r(jit_state_t*,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define os14rr(op, s14, rj, rd) _os14rr(_jit, op, s14, rj, rd)
+static void _os14rr(jit_state_t*,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define ou8rr(op, u8, rd, rj) _ou8rr(_jit, op, u8, rd, rj)
+# define ou8u5r(op, u8, u5, rj) _ou8rr(_jit, op, u8, u5, rj)
+static void _ou8rr(jit_state_t*,jit_int32_t,
+ jit_int32_t,jit_int32_t,jit_int32_t);
+# define ou15(op, u15) _ou15(_jit, op, u15)
+static void _ou15(jit_state_t*, jit_int32_t,jit_int32_t);
+# define orrrr(op, ra, rk, rj, rd) _orrrr(_jit, op, ra, rk, rj, rd)
+static void _orrrr(jit_state_t*,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define ou5rru2u3(op,u5,rj,rk,u2,u3) _ou5rru2u3(_jit, op, u5, rj, rk, u2, u3)
+static void _ou5rru2u3(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,
+ jit_int32_t,jit_int32_t,jit_int32_t);
+# define os16rr(op, s16, rj, rd) _os16rr(_jit, op, s16, rj, rd)
+static void _os16rr(jit_state_t*,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define os20r(op, s20, rd) _os20r(_jit, op, s20, rd)
+static void _os20r(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
+# define orj21(op, rj, j21) _orj21(_jit, op, rj, j21)
+static void _orj21(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
+# define ou2u3j21(op, u2, u3, j21) _ou2u3j21(_jit, op, u2, u3, j21)
+static void _o2cj21(jit_state_t*,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define oj16rr(op, j16, rj, rd) _oj16rr(_jit, op, j16, rj, rd)
+static void _oj16rr(jit_state_t*,
+ jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
+# define oj26(op, j26) _oj26(_jit, op, j26)
+static void _oj26(jit_state_t*, jit_int32_t,jit_int32_t);
+# define CLO_W(rd, rj) ou5rr(0x000, 0x04, rj, rd)
+# define CLZ_W(rd, rj) ou5rr(0x000, 0x05, rj, rd)
+# define CTO_W(rd, rj) ou5rr(0x000, 0x06, rj, rd)
+# define CTZ_W(rd, rj) ou5rr(0x000, 0x07, rj, rd)
+# define CLO_D(rd, rj) ou5rr(0x000, 0x08, rj, rd)
+# define CLZ_D(rd, rj) ou5rr(0x000, 0x09, rj, rd)
+# define CTO_D(rd, rj) ou5rr(0x000, 0x0a, rj, rd)
+# define CTZ_D(rd, rj) ou5rr(0x000, 0x0b, rj, rd)
+# define REVB_2H(rd, rj) ou5rr(0x000, 0x0c, rj, rd)
+# define REVB_4H(rd, rj) ou5rr(0x000, 0x0d, rj, rd)
+# define REVB_2W(rd, rj) ou5rr(0x000, 0x0e, rj, rd)
+# define REVB_D(rd, rj) ou5rr(0x000, 0x0f, rj, rd)
+# define REVH_2W(rd, rj) ou5rr(0x000, 0x10, rj, rd)
+# define REVH_D(rd, rj) ou5rr(0x000, 0x11, rj, rd)
+# define BITREV_4B(rd, rj) ou5rr(0x000, 0x12, rj, rd)
+# define BITREV_8B(rd, rj) ou5rr(0x000, 0x13, rj, rd)
+# define BITREV_W(rd, rj) ou5rr(0x000, 0x14, rj, rd)
+# define BITREV_D(rd, rj) ou5rr(0x000, 0x15, rj, rd)
+# define EXT_W_H(rd, rj) ou5rr(0x000, 0x16, rj, rd)
+# define EXT_W_B(rd, rj) ou5rr(0x000, 0x17, rj, rd)
+# define RDTIMEL_W(rd, rj) ou5rr(0x000, 0x18, rj, rd)
+# define RDTIMEH_W(rd, rj) ou5rr(0x000, 0x19, rj, rd)
+# define RDTIME_D(rd, rj) ou5rr(0x000, 0x20, rj, rd)
+# define CPUCFG(rd, rj) ou5rr(0x000, 0x21, rj, rd)
+# define ASRTLE_D( rj, rk) orru5(0x002, rk, rj, 0x00)
+# define ASRTGT_D( rj, rk) orru5(0x003, rk, rj, 0x00)
+# define ALSL_W(rd, rj, rk, sa2) ou2rrr(0x002, sa2, rk, rj, rd)
+# define ALSL_WU(rd, rj, rk, sa2) ou2rrr(0x003, sa2, rk, rj, rd)
+# define BYTEPICK_W(rd, rj, rk, sa2) ou2rrr(0x004, sa2, rk, rj, rd)
+# define BYTEPICK_D(rd, rj, rk, sa3) ou3rrr(0x003, sa3, rk, rj, rd)
+# define ADD_W(rd, rj, rk) orrr(0x020, rk, rj, rd)
+# define ADD_D(rd, rj, rk) orrr(0x021, rk, rj, rd)
+# define SUB_W(rd, rj, rk) orrr(0x022, rk, rj, rd)
+# define SUB_D(rd, rj, rk) orrr(0x023, rk, rj, rd)
+# define SLT(rd, rj, rk) orrr(0x024, rk, rj, rd)
+# define SLTU(rd, rj, rk) orrr(0x025, rk, rj, rd)
+# define MASKEQZ(rd, rj, rk) orrr(0x026, rk, rj, rd)
+# define MASKNEZ(rd, rj, rk) orrr(0x027, rk, rj, rd)
+# define NOR(rd, rj, rk) orrr(0x028, rk, rj, rd)
+# define AND(rd, rj, rk) orrr(0x029, rk, rj, rd)
+# define OR(rd, rj, rk) orrr(0x02a, rk, rj, rd)
+# define XOR(rd, rj, rk) orrr(0x02b, rk, rj, rd)
+# define ORN(rd, rj, rk) orrr(0x02c, rk, rj, rd)
+# define ANDN(rd, rj, rk) orrr(0x02d, rk, rj, rd)
+# define SLL_W(rd, rj, rk) orrr(0x02e, rk, rj, rd)
+# define SRL_W(rd, rj, rk) orrr(0x02f, rk, rj, rd)
+# define SRA_W(rd, rj, rk) orrr(0x030, rk, rj, rd)
+# define SLL_D(rd, rj, rk) orrr(0x031, rk, rj, rd)
+# define SRL_D(rd, rj, rk) orrr(0x032, rk, rj, rd)
+# define SRA_D(rd, rj, rk) orrr(0x033, rk, rj, rd)
+# define ROTR_W(rd, rj, rk) orrr(0x036, rk, rj, rd)
+# define ROTR_D(rd, rj, rk) orrr(0x037, rk, rj, rd)
+# define MUL_W(rd, rj, rk) orrr(0x038, rk, rj, rd)
+# define MULH_W(rd, rj, rk) orrr(0x039, rk, rj, rd)
+# define MULH_WU(rd, rj, rk) orrr(0x03a, rk, rj, rd)
+# define MUL_D(rd, rj, rk) orrr(0x03b, rk, rj, rd)
+# define MULH_D(rd, rj, rk) orrr(0x03c, rk, rj, rd)
+# define MULH_DU(rd, rj, rk) orrr(0x03d, rk, rj, rd)
+# define MULW_D_W(rd, rj, rk) orrr(0x03e, rk, rj, rd)
+# define MULW_D_WU(rd, rj, rk) orrr(0x03f, rk, rj, rd)
+# define DIV_W(rd, rj, rk) orrr(0x040, rk, rj, rd)
+# define MOD_W(rd, rj, rk) orrr(0x041, rk, rj, rd)
+# define DIV_WU(rd, rj, rk) orrr(0x042, rk, rj, rd)
+# define MOD_WU(rd, rj, rk) orrr(0x043, rk, rj, rd)
+# define DIV_D(rd, rj, rk) orrr(0x044, rk, rj, rd)
+# define MOD_D(rd, rj, rk) orrr(0x045, rk, rj, rd)
+# define DIV_DU(rd, rj, rk) orrr(0x046, rk, rj, rd)
+# define MOD_DU(rd, rj, rk) orrr(0x047, rk, rj, rd)
+# define CRC_W_B_W(rd, rj, rk) orrr(0x048, rk, rj, rd)
+# define CRC_W_H_W(rd, rj, rk) orrr(0x049, rk, rj, rd)
+# define CRC_W_W_W(rd, rj, rk) orrr(0x04a, rk, rj, rd)
+# define CRC_W_D_W(rd, rj, rk) orrr(0x04b, rk, rj, rd)
+# define CRCC_W_B_W(rd, rj, rk) orrr(0x04c, rk, rj, rd)
+# define CRCC_W_H_W(rd, rj, rk) orrr(0x04d, rk, rj, rd)
+# define CCRC_W_W_W(rd, rj, rk) orrr(0x04e, rk, rj, rd)
+# define CCRC_W_D_W(rd, rj, rk) orrr(0x04f, rk, rj, rd)
+# define BREAK(code) ou15(0x054, code)
+# define DBCL(code) ou15(0x055, code)
+# define SYSCALL(code) ou15(0x056, code)
+# define ALSL_D(rd, rj, rk, sa2) ou2rrr(0x016, sa2, rk, rj, rd)
+# define SLLI_W(rd, rj, ui5) ou5rr(0x081, ui5, rj, rd)
+# define SLLI_D(rd, rj, ui6) ou6rr(0x041, ui6, rj, rd)
+# define SRLI_W(rd, rj, ui5) ou5rr(0x089, ui5, rj, rd)
+# define SRLI_D(rd, rj, ui6) ou6rr(0x045, ui6, rj, rd)
+# define SRAI_W(rd, rj, ui5) ou5rr(0x091, ui5, rj, rd)
+# define SRAI_D(rd, rj, ui6) ou6rr(0x049, ui6, rj, rd)
+# define ROTRI_W(rd, rj, ui5) ou5rr(0x099, ui5, rj, rd)
+# define ROTRI_D(rd, rj, ui6) ou6rr(0x04d, ui6, rj, rd)
+# define BSTRINS_W(rd, rj, m5, l5) ou5u1u5rr(0x003, m5, 0x0, l5, rj, rd)
+# define BSTRPICK_W(rd, rj, m5, l5) ou5u1u5rr(0x003, m5, 0x1, l5, rj, rd)
+# define BSTRINS_D(rd, rj, m6, l6) ou6u6rr(0x002, m6, l6, rj, rd)
+# define BSTRPICK_D(rd, rj, m6, l6) ou6u6rr(0x003, m6, l6, rj, rd)
+# define SLTI(rd, rj, i12) os12rr(0x008, i12, rj, rd)
+# define SLTUI(rd, rj, i12) os12rr(0x009, i12, rj, rd)
+# define ADDI_W(rd, rj, si12) os12rr(0x00a, si12, rj, rd)
+# define ADDI_D(rd, rj, si12) os12rr(0x00b, si12, rj, rd)
+# define LU52I_D(rd, rj, i12) os12rr(0x00c, i12, rj, rd)
+# define ANDI(rd, rj, i12) ou12rr(0x00d, i12, rj, rd)
+# define ORI(rd, rj, i12) ou12rr(0x00e, i12, rj, rd)
+# define XORI(rd, rj, i12) ou12rr(0x00f, i12, rj, rd)
+# define CSRRD(rd, csr) ou14u5r(0x004, csr, 0x00, rd)
+# define CSRWR(rd, csr) ou14u5r(0x004, csr, 0x01, rd)
+# define CSRXCHG(rd, rj, csr) ou14u5r(0x004, csr, rj, rd)
+# define CACOP(i5, rj, si12) os12ru5(0x018, si12, rj, i5)
+# define LDDIR(rd, rj, level) ou8rr(0x190, level, rj, rd)
+# define LDPTE( rj, level) ou8u5r(0x191, level, rj, 0x00)
+# define IOCSRRD_B(rd, rj) ou5rr(0xc90, 0x00, rj, rd)
+# define IOCSRRD_H(rd, rj) ou5rr(0xc90, 0x01, rj, rd)
+# define IOCSRRD_W(rd, rj) ou5rr(0xc90, 0x02, rj, rd)
+# define IOCSRRD_D(rd, rj) ou5rr(0xc90, 0x03, rj, rd)
+# define IOCSRWR_B(rd, rj) ou5rr(0xc90, 0x04, rj, rd)
+# define IOCSRWR_H(rd, rj) ou5rr(0xc90, 0x05, rj, rd)
+# define IOCSRWR_W(rd, rj) ou5rr(0xc90, 0x06, rj, rd)
+# define IOCSRWR_D(rd, rj) ou5rr(0xc90, 0x07, rj, rd)
+# define TLBCLR() ii( 0x6482000)
+# define TLBFLUSH() ii( 0x6482400)
+# define TLBSRCH() ii( 0x6482800)
+# define TLBRD() ii( 0x6482c00)
+# define TLBWR() ii( 0x6483000)
+# define TLBFILL() ii( 0x6483400)
+# define ERTN() ii( 0x6483800)
+# define IDLE(level) ou15(0xc91, level)
+# define INVTLB(op, rj, rk) orru5(0xc93, rk, rj, op)
+# define ADDU16I_D(rd, rj, si16) os16rr(0x004, si16, rj, rd)
+# define LU12I_W(rd, si20) os20r(0x00a, si20, rd)
+# define LU32I_D(rd, si20) os20r(0x00b, si20, rd)
+# define PCADDI(rd, si20) os20r(0x00c, si20, rd)
+# define PCALAU12I(rd, si20) os20r(0x00d, si20, rd)
+# define PCADDU12I(rd, si20) os20r(0x00e, si20, rd)
+# define PCADDU18I(rd, si20) os20r(0x00f, si20, rd)
+# define LL_W(rd, rj, si14) os14rr(0x020, si14, rj, rd)
+# define SC_W(rd, rj, si14) os14rr(0x021, si14, rj, rd)
+# define LL_D(rd, rj, si14) os14rr(0x022, si14, rj, rd)
+# define SC_D(rd, rj, si14) os14rr(0x023, si14, rj, rd)
+# define LDPTR_W(rd, rj, si14) os14rr(0x024, si14, rj, rd)
+# define SDPTR_W(rd, rj, si14) os14rr(0x025, si14, rj, rd)
+# define LDPTR_D(rd, rj, si14) os14rr(0x026, si14, rj, rd)
+# define SDPTR_D(rd, rj, si14) os14rr(0x027, si14, rj, rd)
+# define LD_B(rd, rj, si12) os12rr(0x0a0, si12, rj, rd)
+# define LD_H(rd, rj, si12) os12rr(0x0a1, si12, rj, rd)
+# define LD_W(rd, rj, si12) os12rr(0x0a2, si12, rj, rd)
+# define LD_D(rd, rj, si12) os12rr(0x0a3, si12, rj, rd)
+# define ST_B(rd, rj, si12) os12rr(0x0a4, si12, rj, rd)
+# define ST_H(rd, rj, si12) os12rr(0x0a5, si12, rj, rd)
+# define ST_W(rd, rj, si12) os12rr(0x0a6, si12, rj, rd)
+# define ST_D(rd, rj, si12) os12rr(0x0a7, si12, rj, rd)
+# define LD_BU(rd, rj, si12) os12rr(0x0a8, si12, rj, rd)
+# define LD_HU(rd, rj, si12) os12rr(0x0a9, si12, rj, rd)
+# define LD_WU(rd, rj, si12) os12rr(0x0aa, si12, rj, rd)
+# define PRELD(hint, rj, si12) os12ru5(0x0ab, si12, rj , hint)
+# define LDX_B(rd, rj, rk) orrr(0x7000, rk, rj, rd)
+# define LDX_H(rd, rj, rk) orrr(0x7008, rk, rj, rd)
+# define LDX_W(rd, rj, rk) orrr(0x7010, rk, rj, rd)
+# define LDX_D(rd, rj, rk) orrr(0x7018, rk, rj, rd)
+# define STX_B(rd, rj, rk) orrr(0x7020, rk, rj, rd)
+# define STX_H(rd, rj, rk) orrr(0x7028, rk, rj, rd)
+# define STX_W(rd, rj, rk) orrr(0x7030, rk, rj, rd)
+# define STX_D(rd, rj, rk) orrr(0x7038, rk, rj, rd)
+# define LDX_BU(rd, rj, rk) orrr(0x7040, rk, rj, rd)
+# define LDX_HU(rd, rj, rk) orrr(0x7048, rk, rj, rd)
+# define LDX_WU(rd, rj, rk) orrr(0x7050, rk, rj, rd)
+# define PRELDX(hint, rj, rk) orru5(0x7058, rk, rj, hint)
+# define AMSWAP_W(rd, rj, rk) orrr(0x70c0, rk, rj, rd)
+# define AMSWAP_D(rd, rj, rk) orrr(0x70c1, rk, rj, rd)
+# define AMADD_W(rd, rj, rk) orrr(0x70c2, rk, rj, rd)
+# define AMADD_D(rd, rj, rk) orrr(0x70c3, rk, rj, rd)
+# define AMAND_W(rd, rj, rk) orrr(0x70c4, rk, rj, rd)
+# define AMAND_D(rd, rj, rk) orrr(0x70c5, rk, rj, rd)
+# define AMOR_W(rd, rj, rk) orrr(0x70c6, rk, rj, rd)
+# define AMOR_D(rd, rj, rk) orrr(0x70c7, rk, rj, rd)
+# define AMXOR_W(rd, rj, rk) orrr(0x70c8, rk, rj, rd)
+# define AMXOR_D(rd, rj, rk) orrr(0x70c9, rk, rj, rd)
+# define AMMAX_W(rd, rj, rk) orrr(0x70ca, rk, rj, rd)
+# define AMMAX_D(rd, rj, rk) orrr(0x70cb, rk, rj, rd)
+# define AMMIN_W(rd, rj, rk) orrr(0x70cc, rk, rj, rd)
+# define AMMIN_D(rd, rj, rk) orrr(0x70cd, rk, rj, rd)
+# define AMMAX_WU(rd, rj, rk) orrr(0x70ce, rk, rj, rd)
+# define AMMAX_DU(rd, rj, rk) orrr(0x70cf, rk, rj, rd)
+# define AMMIN_WU(rd, rj, rk) orrr(0x70d0, rk, rj, rd)
+# define AMMIN_DU(rd, rj, rk) orrr(0x70d1, rk, rj, rd)
+# define AMSWAP_DB_W(rd, rj, rk) orrr(0x70d2, rk, rj, rd)
+# define AMSWAP_DB_D(rd, rj, rk) orrr(0x70d3, rk, rj, rd)
+# define AMADD_DB_W(rd, rj, rk) orrr(0x70d4, rk, rj, rd)
+# define AMADD_DB_D(rd, rj, rk) orrr(0x70d5, rk, rj, rd)
+# define AMAND_DB_W(rd, rj, rk) orrr(0x70d6, rk, rj, rd)
+# define AMAND_DB_D(rd, rj, rk) orrr(0x70d7, rk, rj, rd)
+# define AMOR_DB_W(rd, rj, rk) orrr(0x70d8, rk, rj, rd)
+# define AMOR_DB_D(rd, rj, rk) orrr(0x70d9, rk, rj, rd)
+# define AMXOR_DB_W(rd, rj, rk) orrr(0x70da, rk, rj, rd)
+# define AMXOR_DB_D(rd, rj, rk) orrr(0x70db, rk, rj, rd)
+# define AMMAX_DB_W(rd, rj, rk) orrr(0x70dc, rk, rj, rd)
+# define AMMAX_DB_D(rd, rj, rk) orrr(0x70dd, rk, rj, rd)
+# define AMMIN_DB_W(rd, rj, rk) orrr(0x70de, rk, rj, rd)
+# define AMMIN_DB_D(rd, rj, rk) orrr(0x70df, rk, rj, rd)
+# define AMMAX_DB_WU(rd, rj, rk) orrr(0x70e0, rk, rj, rd)
+# define AMMAX_DB_DU(rd, rj, rk) orrr(0x70e1, rk, rj, rd)
+# define AMMIN_DB_WU(rd, rj, rk) orrr(0x70e2, rk, rj, rd)
+# define AMMIN_DB_DU(rd, rj, rk) orrr(0x70e3, rk, rj, rd)
+# define DBAR(hint) ou15(0x70e4, hint)
+# define IBAR(hint) ou15(0x70e5, hint)
+# define LDGT_B(rd, rj, rk) orrr(0x70f0, rk, rj, rd)
+# define LDGT_H(rd, rj, rk) orrr(0x70f1, rk, rj, rd)
+# define LDGT_W(rd, rj, rk) orrr(0x70f2, rk, rj, rd)
+# define LDGT_D(rd, rj, rk) orrr(0x70f3, rk, rj, rd)
+# define LDLE_B(rd, rj, rk) orrr(0x70f4, rk, rj, rd)
+# define LDLE_H(rd, rj, rk) orrr(0x70f5, rk, rj, rd)
+# define LDLE_W(rd, rj, rk) orrr(0x70f6, rk, rj, rd)
+# define LDLE_D(rd, rj, rk) orrr(0x70f7, rk, rj, rd)
+# define STGT_B(rd, rj, rk) orrr(0x70f8, rk, rj, rd)
+# define STGT_H(rd, rj, rk) orrr(0x70f9, rk, rj, rd)
+# define STGT_W(rd, rj, rk) orrr(0x70fa, rk, rj, rd)
+# define STGT_D(rd, rj, rk) orrr(0x70fb, rk, rj, rd)
+# define STLE_B(rd, rj, rk) orrr(0x70fc, rk, rj, rd)
+# define STLE_H(rd, rj, rk) orrr(0x70rd, rk, rj, rd)
+# define STLE_W(rd, rj, rk) orrr(0x70fe, rk, rj, rd)
+# define STLE_D(rd, rj, rk) orrr(0x70ff, rk, rj, rd)
+# define BEQZ( rj, offs) orj21(0x010, rj, offs)
+# define BNEZ( rj, offs) orj21(0x011, rj, offs)
+# define BCEQZ( cj, offs) ou2u3j21(0x012, 0x0, cj, offs)
+# define BCNEZ( cj, offs) ou2u3j21(0x012, 0x1, cj, offs)
+# define JIRL(rd, rj, offs) oj16rr(0x013, offs, rj, rd)
+# define B(offs) oj26(0x014, offs)
+# define BL(offs) oj26(0x015, offs)
+# define BEQ(rj, rd, offs) oj16rr(0x016, offs, rj, rd)
+# define BNE(rj, rd, offs) oj16rr(0x017, offs, rj, rd)
+# define BLT(rj, rd, offs) oj16rr(0x018, offs, rj, rd)
+# define BGE(rj, rd, offs) oj16rr(0x019, offs, rj, rd)
+# define BLTU(rj, rd, offs) oj16rr(0x01a, offs, rj, rd)
+# define BGEU(rj, rd, offs) oj16rr(0x01b, offs, rj, rd)
+# define NOP() ANDI(_ZERO_REGNO, _ZERO_REGNO, 0)
+# define nop(i0) _nop(_jit, i0)
+# define comr(r0, r1) NOR(r0, r1, r1)
+# define negr(r0, r1) subr(r0, _ZERO_REGNO, r1)
+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 movnr(r0, r1, r2) _movnr(_jit, r0, r1, r2)
+static void _movnr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+# define movzr(r0, r1, r2) _movzr(_jit, r0, r1, r2)
+static void _movzr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+# define casx(r0, r1, r2, r3, i0) _casx(_jit, r0, r1, r2, r3, i0)
+static void _casx(jit_state_t *_jit,jit_int32_t,jit_int32_t,
+ jit_int32_t,jit_int32_t,jit_word_t);
+#define casr(r0, r1, r2, r3) casx(r0, r1, r2, r3, 0)
+#define casi(r0, i0, r1, r2) casx(r0, _NOREG, r1, r2, i0)
+# define addr(r0, r1, r2) ADD_D(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_D(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) MUL_D(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) 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 divr(r0, r1, r2) DIV_D(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) DIV_DU(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(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 remr(r0, r1, r2) MOD_D(r0, r1, r2)
+# 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) MOD_DU(r0, r1, r2)
+# 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) SLL_D(r0, r1, r2)
+# define lshi(r0, r1, i0) SLLI_D(r0, r1, i0)
+# define rshr(r0, r1, r2) SRA_D(r0, r1, r2)
+# define rshi(r0, r1, i0) SRAI_D(r0, r1, i0)
+# define rshr_u(r0, r1, r2) SRL_D(r0, r1, r2)
+# define rshi_u(r0, r1, i0) SRLI_D(r0, r1, i0)
+# 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 ldr_c(r0, r1) LD_B(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) LD_BU(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) LD_H(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) LD_HU(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) LD_W(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) LD_WU(r0, r1, 0)
+# 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_D(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) LDX_B(r0, r1, r2)
+# 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) LDX_BU(r0, r1, r2)
+# 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) LDX_H(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) LDX_HU(r0, r1, r2)
+# 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) LDX_W(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) LDX_WU(r0, r1, r2)
+# 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) LDX_D(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) ST_B(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) ST_H(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) ST_W(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) ST_D(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) STX_B(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) STX_H(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) STX_W(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) STX_D(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);
+# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1)
+static void _bswapr_us(jit_state_t*, jit_int32_t, jit_int32_t);
+# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1)
+static void _bswapr_ui(jit_state_t*, jit_int32_t, jit_int32_t);
+# define bswapr_ul(r0, r1) REVB_D(r0, r1)
+# define extr_c(r0, r1) EXT_W_B(r0, r1)
+# define extr_uc(r0, r1) BSTRPICK_D(r0, r1, 7, 0)
+# define extr_s(r0, r1) EXT_W_H(r0, r1)
+# define extr_us(r0, r1) BSTRPICK_D(r0, r1, 15, 0)
+# define extr_i(r0, r1) SLLI_W(r0, r1, 0)
+# define extr_ui(r0, r1) BSTRPICK_D(r0, r1, 31, 0)
+# 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, 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) 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 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 jmpr(r0) JIRL(_ZERO_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 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(br, r0, r1) _bmsr(_jit, br, r0, r1)
+static jit_word_t _bmsr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+# define bmsi(br, r0, i0) _bmsi(_jit, br, r0, i0)
+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)
+static jit_word_t _bmcr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+# define bmci(br, r0, i0) _bmci(_jit, br, r0, i0)
+static jit_word_t _bmci(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
+# define callr(r0) JIRL(_RA_REGNO, r0, 0)
+# 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 void
+_orrr(jit_state_t *_jit,
+ jit_int32_t op, jit_int32_t rk, jit_int32_t rj, jit_int32_t rd)
+{
+ assert(!(op & ~0xffff));
+ assert(!(rk & ~0x1f));
+ assert(!(rj & ~0x1f));
+ assert(!(rd & ~0x1f));
+ ii((op << 15) | (rk << 10) | (rj << 5) | rd);
+}
+
+static void
+_ou2rrr(jit_state_t *_jit, jit_int32_t op,
+ jit_int32_t u2, jit_int32_t rk, jit_int32_t rj, jit_int32_t rd)
+{
+ assert(!(op & ~0x7ff));
+ assert(!(u2 & ~3));
+ assert(!(rk & ~0x1f));
+ assert(!(rj & ~0x1f));
+ assert(!(rd & ~0x1f));
+ ii((op << 17) | (u2 << 15) | (rk << 10) | (rj << 5) | rd);
+}
+
+static void
+_ou3rrr(jit_state_t *_jit, jit_int32_t op,
+ jit_int32_t u3, jit_int32_t rk, jit_int32_t rj, jit_int32_t rd)
+{
+ assert(!(op & ~0x3ff));
+ assert(!(u3 & ~7));
+ assert(!(rk & ~0x1f));
+ assert(!(rj & ~0x1f));
+ assert(!(rd & ~0x1f));
+ ii((op << 18) | (u3 << 15) | (rk << 10) | (rj << 5) | rd);
+}
+
+static void
+_ou6rr(jit_state_t *_jit, jit_int32_t op,
+ jit_int32_t u6, jit_int32_t rj, jit_int32_t rd)
+{
+ assert(!(op & ~0x3ff));
+ assert(!(u6 & ~0x3f));
+ assert(!(rj & ~0x1f));
+ assert(!(rd & ~0x1f));
+ ii((op << 16) | (u6 << 10) | (rj << 5) | rd);
+}
+
+static void
+_ou5u1u5rr(jit_state_t *_jit, jit_int32_t op, jit_int32_t m5,
+ jit_int32_t u1, jit_int32_t l5, jit_int32_t rj, jit_int32_t rd)
+{
+ assert(!(op & ~0x7ff));
+ assert(!(m5 & ~0x1f));
+ assert(!(u1 & ~1));
+ assert(!(l5 & ~0x1f));
+ assert(!(rj & ~0x1f));
+ assert(!(rd & ~0x1f));
+ ii((op << 21) | (m5 << 16) | (u1 << 15) | (l5 << 10) | (rj << 5) | rd);
+}
+
+static void
+_ou6u6rr(jit_state_t *_jit, jit_int32_t op,
+ jit_int32_t m6, jit_int32_t l6, jit_int32_t rj, jit_int32_t rd)
+{
+ assert(!(op & ~0x3ff));
+ assert(!(m6 & ~0x3f));
+ assert(!(l6 & ~0x3f));
+ assert(!(rj & ~0x1f));
+ assert(!(rd & ~0x1f));
+ ii((op << 22) | (m6 << 16) | (l6 << 10) | (rj << 5) | rd);
+}
+
+static void
+_o5r23(jit_state_t *_jit, jit_int32_t op,
+ jit_int32_t i5, jit_int32_t rj, jit_int32_t i2, jit_int32_t i3)
+{
+ assert(!(op & ~0xffff));
+ assert(!(i5 & ~0x3f));
+ assert(!(rj & ~0x3f));
+ assert(!(i2 & ~0x3));
+ assert(!(i3 & ~0x1f));
+ ii((op << 15) | (i5 << 10) | (rj << 5) | (i2 << 3) | i3);
+}
+
+static void
+_o523r(jit_state_t *_jit, jit_int32_t op,
+ jit_int32_t i5, jit_int32_t i2, jit_int32_t i3, jit_int32_t rd)
+{
+ assert(!(op & ~0xffff));
+ assert(!(i5 & ~0x3f));
+ assert(!(i2 & ~0x3));
+ assert(!(i3 & ~0x7));
+ assert(!(rd & ~0x3f));
+ ii((op << 15) | (i5 << 10) | (i2 << 8) | (i3 << 5) | rd);
+}
+
+static void
+_os12rr(jit_state_t *_jit,
+ jit_int32_t op, jit_int32_t s12, jit_int32_t rj, jit_int32_t rd)
+{
+ assert(!(op & ~0x3ff));
+ assert(s12 <= 2047 && s12 >= -2048); s12 &= 0xfff;
+ assert(!(rj & ~0x1f));
+ assert(!(rd & ~0x1f));
+ ii((op << 22) | (s12 << 10) | (rj << 5) | rd);
+}
+
+static void
+_ou12rr(jit_state_t *_jit,
+ jit_int32_t op, jit_int32_t u12, jit_int32_t rj, jit_int32_t rd)
+{
+ assert(!(op & ~0x3ff));
+ assert(!(u12 & ~0xfff));
+ assert(!(rj & ~0x1f));
+ assert(!(rd & ~0x1f));
+ ii((op << 22) | (u12 << 10) | (rj << 5) | rd);
+}
+
+static void
+_ou14u5r(jit_state_t *_jit,
+ jit_int32_t op, jit_int32_t u14, jit_int32_t u5, jit_int32_t rd)
+{
+ assert(!(op & ~0xff));
+ assert(!(u14 & ~0x3fff));
+ assert(!(u5 & ~0x1f));
+ assert(!(rd & ~0x1f));
+ ii((op << 24) | (u14 << 10) | (u5 << 5) | rd);
+}
+
+static void
+_os14rr(jit_state_t *_jit,
+ jit_int32_t op, jit_int32_t s14, jit_int32_t rj, jit_int32_t rd)
+{
+ assert(!(op & ~0xff));
+ assert(s14 <= 8191 && s14 >= -8192); s14 &= 0x3fff;
+ assert(!(rj & ~0x1f));
+ assert(!(rd & ~0x1f));
+ ii((op << 24) | (s14 << 10) | (rj << 5) | rd);
+}
+
+static void
+_ou8rr(jit_state_t *_jit, jit_int32_t op,
+ jit_int32_t u8, jit_int32_t rj, jit_int32_t rd)
+{
+ assert(!(op & ~0x3fff));
+ assert(!(u8 & ~0xff));
+ assert(!(rj & ~0x1f));
+ assert(!(rd & ~0x1f));
+ ii((op << 18) | (u8 << 10) | (rj << 5) | rd);
+}
+
+static void
+_ou15(jit_state_t *_jit, jit_int32_t op, jit_int32_t u15)
+{
+ assert(!(op & ~0x1ffff));
+ assert(!(u15 & ~0x7fff));
+ ii((op << 15) | u15);
+}
+
+static void
+_orrrr(jit_state_t *_jit, jit_int32_t op,
+ jit_int32_t ra, jit_int32_t rk, jit_int32_t rj, jit_int32_t rd)
+{
+ assert(!(op & ~0xfff));
+ assert(!(ra & ~0x1f));
+ assert(!(rk & ~0x1f));
+ assert(!(rj & ~0x1f));
+ assert(!(rd & ~0x1f));
+ ii((op << 20) | (ra << 15) | (rk << 10) | (rj << 5) | rd);
+}
+
+static void
+_ou5rru2u3(jit_state_t *_jit,jit_int32_t op, jit_int32_t u5,
+ jit_int32_t rk, jit_int32_t rj, jit_int32_t u2, jit_int32_t u3)
+{
+ assert(!(op & ~0xfff));
+ assert(!(u5 & ~0x1f));
+ assert(!(rk & ~0x1f));
+ assert(!(rj & ~0x1f));
+ assert(!(u2 & ~3));
+ assert(!(u3 & ~7));
+ ii((op << 20) | (u5 << 15) | (rk << 10) | (rj << 5) | (u2 << 3) | u3);
+}
+
+static void
+_os16rr(jit_state_t *_jit,
+ jit_int32_t op, jit_int32_t s16, jit_int32_t rj, jit_int32_t rd)
+{
+ assert(!(op & ~0x3f));
+ assert(s16 <= 32767 && s16 >= -32768); s16 &= 0xffff;
+ assert(!(rj & ~0x1f));
+ assert(!(rd & ~0x1f));
+ ii((op << 26) | (s16 << 10) | (rj << 5) | rd);
+}
+
+static void
+_os20r(jit_state_t *_jit, jit_int32_t op, jit_int32_t s20, jit_int32_t rd)
+{
+ assert(!(op & ~0x7f));
+ assert(s20 <= 524287 && s20 >= -524288); s20 &= 0xfffff;
+ assert(!(rd & ~0x1f));
+ ii((op << 25) | (s20 << 5) | rd);
+}
+
+static void
+_orj21(jit_state_t *_jit, jit_int32_t op, jit_int32_t rj ,jit_int32_t j21)
+{
+ assert(!(op & ~0x7f));
+ assert(j21 <= 1048575 && j21 >= -1048576); j21 &= 0x1fffff;
+ assert(!(rj & ~0x1f));
+ ii((op << 26) | ((j21 & 0xffff) << 10) | (rj << 5) | (j21 >> 16));
+}
+
+static void
+_ou2u3j21(jit_state_t *_jit,
+ jit_int32_t op, jit_int32_t u2, jit_int32_t u3, jit_int32_t j21)
+{
+ assert(!(op & ~0x7f));
+ assert(j21 <= 1048575 && j21 >= -1048576); j21 &= 0x1fffff;
+ assert(!(u2 & ~3));
+ assert(!(u3 & ~7));
+ ii((op << 26) | ((j21 & 0xffff) << 10) | (u2 << 8) | (u3 << 5) | (j21 >> 16));
+}
+
+static void
+_oj16rr(jit_state_t *_jit,
+ jit_int32_t op, jit_int32_t j16, jit_int32_t rj, jit_int32_t rd)
+{
+ assert(!(op & ~0x7f));
+ assert(j16 <= 32767 && j16 >= -32768); j16 &= 0xffff;
+ assert(!(rd & ~0x1f));
+ assert(!(rj & ~0x1f));
+ ii((op << 26) | (j16 << 10) | (rj << 5) | rd);
+}
+
+static void
+_oj26(jit_state_t *_jit, jit_int32_t op, jit_int32_t j26)
+{
+ assert(!(op & ~0x7f));
+ assert(j26 <= 33554431 && j26 >= -33554432); j26 &= 0x3ffffff;
+ ii((op << 26) | ((j26 & 0x1ffffff) << 10) | (j26 >> 16));
+}
+
+static void
+_nop(jit_state_t *_jit, jit_int32_t i0)
+{
+ for (; i0 > 0; i0 -= 4)
+ NOP();
+ assert(i0 == 0);
+}
+
+static void
+_movnr(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);
+ MASKEQZ(rn(reg), r1, r2);
+ MASKNEZ(r0, r0, r2);
+ OR(r0, r0, rn(reg));
+ jit_unget_reg(reg);
+}
+
+static void
+_movzr(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);
+ MASKNEZ(rn(reg), r1, r2);
+ MASKEQZ(r0, r0, r2);
+ OR(r0, r0, rn(reg));
+ jit_unget_reg(reg);
+}
+
+static void
+_casx(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
+ jit_int32_t r2, jit_int32_t r3, jit_word_t i0)
+{
+ jit_int32_t t0, r1_reg, iscasi;
+ jit_word_t retry, done, jump0, jump1;
+ if ((iscasi = (r1 == _NOREG))) {
+ r1_reg = jit_get_reg(jit_class_gpr);
+ r1 = rn(r1_reg);
+ movi(r1, i0);
+ }
+ t0 = jit_get_reg(jit_class_gpr);
+ movi(r0, 0); /* Assume will fail */
+ DBAR(0); /* Barrier */
+ retry = _jit->pc.w;
+ LL_D(rn(t0), r1, 0); /* Load current value */
+ jump0 = _jit->pc.w;
+ BNE(rn(t0), r2, 0); /* If not equal, already done and r0 is zero */
+ movr(r0, r3); /* Make r0 an inout argument */
+ SC_D(r0, r1, 0); /* r0 is 0 if failed, 1 if succeed */
+ jump1 = _jit->pc.w;
+ BEQ(r0, _ZERO_REGNO, 0);
+ /* FIXME Not certain what 0x700 hint means. Copied from C generated code */
+ DBAR(0x700);
+ done = _jit->pc.w;
+ patch_at(jump0, done);
+ patch_at(jump1, retry);
+ jit_unget_reg(t0);
+ if (iscasi)
+ jit_unget_reg(r1_reg);
+}
+
+static void
+_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+ if (r0 != r1)
+ OR(r0, r1, _ZERO_REGNO);
+}
+
+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_si12_p(i0))
+ ADDI_D(r0, _ZERO_REGNO, i0);
+ else if (!(i0 & 0xffff) && can_sign_extend_si16_p(i0 >> 16))
+ ADDU16I_D(r0, _ZERO_REGNO, i0 >> 16);
+ else {
+ jit_word_t w = i0 - _jit->pc.w;
+ /* If loading some constant reachable address */
+ if (can_sign_extend_si32_p(w)) {
+ jit_int32_t lo = (jit_int32_t)w << 20 >> 20;
+ jit_int32_t hi = w - lo;
+ PCADDU12I(r0, hi >> 12);
+ if (lo)
+ ADDI_D(r0, r0, lo);
+ }
+ else {
+ jit_int32_t _00_11, _12_31, _32_51, _52_63;
+ _00_11 = i0 & 0xfff;
+ _12_31 = (i0 >> 12) & 0xfffff;
+ _32_51 = (i0 >> 32) & 0xfffff;
+ _52_63 = (i0 >> 52) & 0xfff;
+ if (_12_31) {
+ LU12I_W(r0, _12_31 << 12 >> 12);
+ if (_00_11)
+ ORI(r0, r0, _00_11);
+ }
+ else
+ ORI(r0, _ZERO_REGNO, _00_11);
+ if (_32_51 || (_12_31 & 0x80000))
+ LU32I_D(r0, _32_51 << 12 >> 12);
+ if (_52_63 || (_12_31 & 0x80000) || (_32_51 & 0x80000))
+ LU52I_D(r0, r0, _52_63 << 20 >> 20);
+ }
+ }
+}
+
+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 _00_11, _12_31, _32_51, _52_63;
+ _00_11 = i0 & 0xfff;
+ _12_31 = (i0 >> 12) & 0xfffff;
+ _32_51 = (i0 >> 32) & 0xfffff;
+ _52_63 = (i0 >> 52) & 0xfff;
+ w = _jit->pc.w;
+ LU12I_W(r0, _12_31 << 12 >> 12);
+ ORI(r0, r0, _00_11);
+ LU32I_D(r0, _32_51 << 12 >> 12);
+ LU52I_D(r0, r0, _52_63 << 20 >> 20);
+ 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 == 0)
+ movr(r0, r1);
+ else if (can_sign_extend_si12_p(i0))
+ ADDI_D(r0, r1, i0);
+ else if (!(i0 & 0xffff) && can_sign_extend_si16_p(i0 >> 16))
+ ADDU16I_D(r0, r1, i0 >> 16);
+ 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_si12_p(i0))
+ ADDI_D(rn(t0), r1, i0);
+ else if (!(i0 & 0xffff) && can_sign_extend_si16_p(i0 >> 16))
+ ADDU16I_D(rn(t0), r1, i0 >> 16);
+ 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_si12_p(i0))
+ ADDI_D(r0, r1, i0);
+ else if (!(i0 & 0xffff) && can_sign_extend_si16_p(i0 >> 16))
+ ADDU16I_D(r0, r1, i0 >> 16);
+ 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_si12_p(-i0))
+ ADDI_D(r0, r1, -i0);
+ else if (!(-i0 & 0xffff) && can_sign_extend_si16_p(-i0 >> 16))
+ ADDU16I_D(r0, r1, -i0 >> 16);
+ 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_si12_p(-i0))
+ ADDI_D(rn(t0), r1, -i0);
+ else if (!(-i0 & 0xffff) && can_sign_extend_si16_p(-i0 >> 16))
+ ADDU16I_D(rn(t0), r1, -i0 >> 16);
+ 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_si12_p(-i0))
+ ADDI_D(r0, r1, -i0);
+ else if (!(-i0 & 0xffff) && can_sign_extend_si16_p(-i0 >> 16))
+ ADDU16I_D(r0, r1, -i0 >> 16);
+ 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
+_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 t0;
+ if (r0 == r2 || r0 == r3) {
+ t0 = jit_get_reg(jit_class_gpr);
+ mulr(rn(t0), r2, r3);
+ }
+ else
+ mulr(r0, r2, r3);
+ if (sign)
+ MULH_D(r1, r2, r3);
+ else
+ MULH_DU(r1, r2, r3);
+ if (r0 == r2 || r0 == r3) {
+ movr(r0, rn(t0));
+ jit_unget_reg(t0);
+ }
+}
+
+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 t0;
+ if (r0 == r2 || r0 == r3)
+ t0 = jit_get_reg(jit_class_gpr);
+ else
+ t0 = _NOREG;
+ if (sign) {
+ if (t0 == _NOREG)
+ DIV_D(r0, r2, r3);
+ else
+ DIV_D(rn(t0), r2, r3);
+ MOD_D(r1, r2, r3);
+ }
+ else {
+ if (t0 == _NOREG)
+ DIV_DU(r0, r2, r3);
+ else
+ DIV_DU(rn(t0), r2, r3);
+ MOD_DU(r1, r2, r3);
+ }
+ if (t0 != _NOREG) {
+ movr(r0, rn(t0));
+ jit_unget_reg(t0);
+ }
+}
+
+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
+_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
+_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_u12_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_u12_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_u12_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
+_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ jit_int32_t reg;
+ if (can_sign_extend_si12_p(i0))
+ LD_B(r0, _ZERO_REGNO, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LD_B(r0, rn(reg), 0);
+ 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_si12_p(i0))
+ LD_BU(r0, _ZERO_REGNO, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LD_BU(r0, rn(reg), 0);
+ 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_si12_p(i0))
+ LD_H(r0, _ZERO_REGNO, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LD_H(r0, rn(reg), 0);
+ 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_si12_p(i0))
+ LD_HU(r0, _ZERO_REGNO, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LD_HU(r0, rn(reg), 0);
+ 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_si12_p(i0))
+ LD_W(r0, _ZERO_REGNO, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LD_W(r0, rn(reg), 0);
+ 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 (can_sign_extend_si12_p(i0))
+ LD_WU(r0, _ZERO_REGNO, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LD_WU(r0, rn(reg), 0);
+ 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_si12_p(i0))
+ LD_D(r0, _ZERO_REGNO, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LD_D(r0, rn(reg), 0);
+ 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_si12_p(i0))
+ LD_B(r0, r1, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LDX_B(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 (can_sign_extend_si12_p(i0))
+ LD_BU(r0, r1, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LDX_BU(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 (can_sign_extend_si12_p(i0))
+ LD_H(r0, r1, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LDX_H(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 (can_sign_extend_si12_p(i0))
+ LD_HU(r0, r1, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LDX_HU(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 (can_sign_extend_si12_p(i0))
+ LD_W(r0, r1, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LDX_W(r0, r1, 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_si12_p(i0))
+ LD_WU(r0, r1, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LDX_WU(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 (can_sign_extend_si12_p(i0))
+ LD_D(r0, r1, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ LDX_D(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 (can_sign_extend_si12_p(i0))
+ ST_B(r0, _ZERO_REGNO, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ ST_B(r0, rn(reg), 0);
+ 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_si12_p(i0))
+ ST_H(r0, _ZERO_REGNO, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ ST_H(r0, rn(reg), 0);
+ 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_si12_p(i0))
+ ST_W(r0, _ZERO_REGNO, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ ST_W(r0, rn(reg), 0);
+ 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 (can_sign_extend_si12_p(i0))
+ ST_D(r0, _ZERO_REGNO, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ ST_D(r0, rn(reg), 0);
+ 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_si12_p(i0))
+ ST_B(r1, r0, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ STX_B(r1, r0, rn(reg));
+ 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_si12_p(i0))
+ ST_H(r1, r0, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ STX_H(r1, r0, rn(reg));
+ 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_si12_p(i0))
+ ST_W(r1, r0, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ STX_W(r1, r0, rn(reg));
+ 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_si12_p(i0))
+ ST_D(r1, r0, i0);
+ else {
+ reg = jit_get_reg(jit_class_gpr);
+ movi(rn(reg), i0);
+ STX_D(r1, r0, rn(reg));
+ jit_unget_reg(reg);
+ }
+}
+
+static void
+_bswapr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+ REVB_2H(r0, r1);
+ extr_us(r0, r0);
+}
+
+static void
+_bswapr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+ REVB_2W(r0, r1);
+ extr_ui(r0, r0);
+}
+
+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_si12_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_si12_p(i0))
+ SLTUI(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 (can_sign_extend_si12_p(i0 + 1))
+ SLTI(r0, r1, i0 + 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 (can_sign_extend_si12_p(i0 + 1))
+ SLTUI(r0, r1, i0 + 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;
+ if (can_sign_extend_si12_p(i0)) {
+ SLTI(r0, r1, i0);
+ XORI(r0, r0, 1);
+ } else {
+ 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;
+ if (can_sign_extend_si12_p(i0)) {
+ SLTUI(r0, r1, i0);
+ XORI(r0, r0, 1);
+ } else {
+ 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;
+ w = _jit->pc.w;
+ BLT(r0, r1, (i0 - w) >> 2);
+ 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, _ZERO_REGNO, (i0 - w) >> 2);
+ }
+ if (i1) {
+ reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
+ movi(rn(reg), i1);
+ w = _jit->pc.w;
+ BLT(r0, rn(reg), (i0 - w) >> 2);
+ 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;
+ w = _jit->pc.w;
+ BLTU(r0, r1, (i0 - w) >> 2);
+ 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 == 0)
+ w = bltr_u(i0, r0, _ZERO_REGNO);
+ else {
+ reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
+ movi(rn(reg), i1);
+ w = _jit->pc.w;
+ BLTU(r0, rn(reg), (i0 - w) >> 2);
+ 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;
+ BEQZ(rn(reg), (i0 - w) >> 2);
+ 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;
+ 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;
+ jit_int32_t reg;
+ reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
+ SLTU(rn(reg), r1, r0);
+ w = _jit->pc.w;
+ BEQZ(rn(reg), (i0 - w) >> 2);
+ 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 = bler_u(i0, r0, _ZERO_REGNO);
+ 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);
+ 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;
+ BEQZ(r0, (i0 - w) >> 2);
+ }
+ 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;
+ w = _jit->pc.w;
+ BGE(r0, r1, (i0 - w) >> 2);
+ 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 = bger(i0, r0, _ZERO_REGNO);
+ else {
+ reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
+ movi(rn(reg), i1);
+ w = bger(i0, r0, rn(reg));
+ 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;
+ w = _jit->pc.w;
+ BGEU(r0, r1, (i0 - w) >> 2);
+ 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 == 0) {
+ w = _jit->pc.w;
+ B((i0 - w) >> 2);
+ }
+ else {
+ reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
+ 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;
+ BNEZ(rn(reg), (i0 - w) >> 2);
+ 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;
+ 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;
+ jit_int32_t reg;
+ reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
+ SLTU(rn(reg), r1, r0);
+ w = _jit->pc.w;
+ BNEZ(rn(reg), (i0 - w) >> 2);
+ 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);
+ 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);
+ 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;
+ BNEZ(r0, (i0 - w) >> 2);
+ }
+ 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
+_jmpi(jit_state_t *_jit, jit_word_t i0)
+{
+ jit_word_t w;
+ w = (i0 - _jit->pc.w) >> 2;
+ if (can_sign_extend_si26_p(i0))
+ B(w);
+ 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 jit_word_t
+_boaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
+{
+ jit_word_t w, b;
+ 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;
+ BNEZ(rn(t0), 0);
+ /* r1 >= 0 */
+ SLT(rn(t1), r0, rn(t1));
+ b = _jit->pc.w;
+ B(0);
+ /* r1 < 0 */
+ patch_at(w, _jit->pc.w);
+ SLT(rn(t1), rn(t1), r0);
+ /**/
+ patch_at(b, _jit->pc.w);
+ w = _jit->pc.w;
+ BNEZ(rn(t1), (i0 - w) >> 2);
+ 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;
+ t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+ 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, 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;
+ BNEZ(rn(t1), (i0 - w) >> 2);
+ 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;
+ 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, b;
+ 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;
+ BNEZ(rn(t0), 0);
+ /* r1 >= 0 */
+ SLT(rn(t1), r0, rn(t1));
+ b = _jit->pc.w;
+ B(0);
+ /* r1 < 0 */
+ patch_at(w, _jit->pc.w);
+ SLT(rn(t1), rn(t1), r0);
+ /**/
+ patch_at(b, _jit->pc.w);
+ w = _jit->pc.w;
+ BEQZ(rn(t1), (i0 - w) >> 2);
+ 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;
+ 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, 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;
+ BEQZ(rn(t1), (i0 - w) >> 2);
+ 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;
+ 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, b;
+ 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));
+ b = _jit->pc.w;
+ B(0);
+ /* r1 < 0 */
+ patch_at(w, _jit->pc.w);
+ SLT(rn(t1), rn(t1), r0);
+ /**/
+ patch_at(b, _jit->pc.w);
+ w = _jit->pc.w;
+ BNEZ(rn(t1), (i0 - w) >> 2);
+ 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;
+ 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, 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;
+ BNEZ(rn(t1), (i0 - w) >> 2);
+ 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 i0, jit_int32_t r0, jit_int32_t r1)
+{
+ jit_word_t w, b;
+ 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;
+ BNEZ(rn(t0), 0);
+ /* r1 >= 0 */
+ SLT(rn(t1), r0, rn(t1));
+ b = _jit->pc.w;
+ B(0);
+ /* r1 < 0 */
+ patch_at(w, _jit->pc.w);
+ SLT(rn(t1), rn(t1), r0);
+ /**/
+ patch_at(b, _jit->pc.w);
+ w = _jit->pc.w;
+ BEQZ(rn(t1), (i0 - w) >> 2);
+ 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;
+ 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, 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;
+ BEQZ(rn(t1), (i0 - w) >> 2);
+ 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;
+ 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;
+ BNEZ(rn(t0), (i0 - w) >> 2);
+ 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);
+ andi(rn(t0), r0, i1);
+ w = _jit->pc.w;
+ BNEZ(rn(t0), (i0 - w) >> 2);
+ 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;
+ BEQZ(rn(t0), (i0 - w) >> 2);
+ 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);
+ andi(rn(t0), r0, i1);
+ w = _jit->pc.w;
+ BEQZ(rn(t0), (i0 - w) >> 2);
+ jit_unget_reg(t0);
+ return (w);
+}
+
+static void
+_calli(jit_state_t *_jit, jit_word_t i0)
+{
+ jit_word_t w;
+ w = (i0 - _jit->pc.w) >> 2;
+ if (can_sign_extend_si26_p(i0))
+ BL(w);
+ else
+ (void)calli_p(i0);
+}
+
+static jit_word_t
+_calli_p(jit_state_t *_jit, jit_word_t i0)
+{
+ jit_word_t w;
+ jit_word_t reg;
+ reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
+ 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;
+ 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, _S0))
+ stxi(16, _SP_REGNO, rn(_S0));
+ if (jit_regset_tstbit(&_jitc->function->regset, _S1))
+ stxi(24, _SP_REGNO, rn(_S1));
+ if (jit_regset_tstbit(&_jitc->function->regset, _S2))
+ stxi(32, _SP_REGNO, rn(_S2));
+ if (jit_regset_tstbit(&_jitc->function->regset, _S3))
+ stxi(40, _SP_REGNO, rn(_S3));
+ if (jit_regset_tstbit(&_jitc->function->regset, _S4))
+ stxi(48, _SP_REGNO, rn(_S4));
+ if (jit_regset_tstbit(&_jitc->function->regset, _S5))
+ stxi(56, _SP_REGNO, rn(_S5));
+ if (jit_regset_tstbit(&_jitc->function->regset, _S6))
+ stxi(64, _SP_REGNO, rn(_S6));
+ if (jit_regset_tstbit(&_jitc->function->regset, _S7))
+ stxi(72, _SP_REGNO, rn(_S7));
+ if (jit_regset_tstbit(&_jitc->function->regset, _S8))
+ stxi(80, _SP_REGNO, rn(_S8));
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS0))
+ stxi_d(88, _SP_REGNO, rn(_FS0));
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS1))
+ stxi_d(96, _SP_REGNO, rn(_FS1));
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS2))
+ stxi_d(104, _SP_REGNO, rn(_FS2));
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS3))
+ stxi_d(112, _SP_REGNO, rn(_FS3));
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS4))
+ stxi_d(120, _SP_REGNO, rn(_FS4));
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS5))
+ stxi_d(128, _SP_REGNO, rn(_FS5));
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS6))
+ stxi_d(136, _SP_REGNO, rn(_FS6));
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS7))
+ stxi_d(144, _SP_REGNO, rn(_FS7));
+ 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, _S0))
+ ldxi(rn(_S0), _SP_REGNO, 16);
+ if (jit_regset_tstbit(&_jitc->function->regset, _S1))
+ ldxi(rn(_S1), _SP_REGNO, 24);
+ if (jit_regset_tstbit(&_jitc->function->regset, _S2))
+ ldxi(rn(_S2), _SP_REGNO, 32);
+ if (jit_regset_tstbit(&_jitc->function->regset, _S3))
+ ldxi(rn(_S3), _SP_REGNO, 40);
+ if (jit_regset_tstbit(&_jitc->function->regset, _S4))
+ ldxi(rn(_S4), _SP_REGNO, 48);
+ if (jit_regset_tstbit(&_jitc->function->regset, _S5))
+ ldxi(rn(_S5), _SP_REGNO, 56);
+ if (jit_regset_tstbit(&_jitc->function->regset, _S6))
+ ldxi(rn(_S6), _SP_REGNO, 64);
+ if (jit_regset_tstbit(&_jitc->function->regset, _S7))
+ ldxi(rn(_S7), _SP_REGNO, 72);
+ if (jit_regset_tstbit(&_jitc->function->regset, _S8))
+ ldxi(rn(_S8), _SP_REGNO, 80);
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS0))
+ ldxi_d(rn(_FS0), _SP_REGNO, 88);
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS1))
+ ldxi_d(rn(_FS1), _SP_REGNO, 96);
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS2))
+ ldxi_d(rn(_FS2), _SP_REGNO, 104);
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS3))
+ ldxi_d(rn(_FS3), _SP_REGNO, 112);
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS4))
+ ldxi_d(rn(_FS4), _SP_REGNO, 120);
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS5))
+ ldxi_d(rn(_FS5), _SP_REGNO, 128);
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS6))
+ ldxi_d(rn(_FS6), _SP_REGNO, 136);
+ if (jit_regset_tstbit(&_jitc->function->regset, _FS7))
+ ldxi_d(rn(_FS7), _SP_REGNO, 144);
+ addi(_SP_REGNO, _SP_REGNO, stack_framesize);
+ JIRL(_ZERO_REGNO, _RA_REGNO, 0);
+}
+
+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)
+{
+ jit_uint32_t c;
+ union {
+ jit_uint32_t *i;
+ jit_word_t w;
+ } u;
+ u.w = instr;
+ c = u.i[0];
+ /* movi_p? */
+ if ((c >> 25) == 10) { /* LU12I_W */
+ jit_int32_t _00_11, _12_31, _32_51, _52_63;
+ _00_11 = label & 0xfff;
+ _12_31 = (label >> 12) & 0xfffff;
+ _32_51 = (label >> 32) & 0xfffff;
+ _52_63 = (label >> 52) & 0xfff;
+ u.i[0] &= ~(0xfffff << 5);
+ u.i[0] |= _12_31 << 5;
+ assert((u.i[1] >> 22) == 14); /* ORI */
+ u.i[1] &= ~(0xfff << 10);
+ u.i[1] |= _00_11 << 10;
+ assert((u.i[2] >> 25) == 11); /* LU32I_D */
+ u.i[2] &= ~(0xfffff << 5);
+ u.i[2] |= _32_51 << 5;
+ assert((u.i[3] >> 22) == 12); /* LU52I_D */
+ u.i[3] &= ~(0xfff << 10);
+ u.i[3] |= _52_63 << 0;
+ }
+ else if ((c >> 26) >= 22 && (c >> 26) <= 27) {
+ /* B{EQ,NE,LT,GE,LTU,GEU} */
+ jit_word_t disp = (label - instr) >> 2;
+ assert(can_sign_extend_si16_p(disp));
+ u.i[0] &= ~(0xffff << 10);
+ u.i[0] |= (disp & 0xffff) << 10;
+ }
+ else if ((c >> 26) == 20 || (c >> 26) == 21) { /* B or BL */
+ jit_word_t disp = (label - instr) >> 2;
+ assert(can_sign_extend_si26_p(disp));
+ disp &= 0x3ffffff;
+ u.i[0] &= ~0x3ffffff;
+ u.i[0] |= ((disp & 0xffff) << 10) | (disp >> 16);
+ }
+ else if ((c >> 26) >= 16 && (c >> 26) <= 18) { /* B{,C}{EQ,NE}Z */
+ jit_word_t disp = (label - instr) >> 2;
+ assert(can_sign_extend_si21_p(disp));
+ disp &= 0x1fffff;
+ u.i[0] &= ~((0xffff << 10) | 0x1f);
+ u.i[0] |= ((disp & 0xffff) << 10) | (disp >> 16);
+ }
+ else
+ abort();
+}
+#endif
--- /dev/null
+/*
+ * Copyright (C) 2022 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 FADD_S(fd, fj, fk) orrr(0x201, fk, fj, fd)
+# define FADD_D(fd, fj, fk) orrr(0x202, fk, fj, fd)
+# define FSUB_S(fd, fj, fk) orrr(0x205, fk, fj, fd)
+# define FSUB_D(fd, fj, fk) orrr(0x206, fk, fj, fd)
+# define FMUL_S(fd, fj, fk) orrr(0x209, fk, fj, fd)
+# define FMUL_D(fd, fj, fk) orrr(0x20a, fk, fj, fd)
+# define FDIV_S(fd, fj, fk) orrr(0x20d, fk, fj, fd)
+# define FDIV_D(fd, fj, fk) orrr(0x20e, fk, fj, fd)
+# define FMAX_S(fd, fj, fk) orrr(0x211, fk, fj, fd)
+# define FMAX_D(fd, fj, fk) orrr(0x212, fk, fj, fd)
+# define FMIN_S(fd, fj, fk) orrr(0x215, fk, fj, fd)
+# define FMIN_D(fd, fj, fk) orrr(0x216, fk, fj, fd)
+# define FMAXA_S(fd, fj, fk) orrr(0x219, fk, fj, fd)
+# define FMAXA_D(fd, fj, fk) orrr(0x21a, fk, fj, fd)
+# define FMINA_S(fd, fj, fk) orrr(0x21d, fk, fj, fd)
+# define FMINA_D(fd, fj, fk) orrr(0x21e, fk, fj, fd)
+# define FSCALEB_S(fd, fj, fk) orrr(0x221, fk, fj, fd)
+# define FSCALEB_D(fd, fj, fk) orrr(0x222, fk, fj, fd)
+# define FCOPYSIGN_S(fd, fj, fk) orrr(0x225, fk, fj, fd)
+# define FCOPYSIGN_D(fd, fj, fk) orrr(0x226, fk, fj, fd)
+# define FABS_S(fd, fj) ou5rr(0x228, 0x01, fj, fd)
+# define FABS_D(fd, fj) ou5rr(0x228, 0x02, fj, fd)
+# define FNEG_S(fd, fj) ou5rr(0x228, 0x05, fj, fd)
+# define FNEG_D(fd, fj) ou5rr(0x228, 0x06, fj, fd)
+# define FGLOB_S(fd, fj) ou5rr(0x228, 0x09, fj, fd)
+# define FGLOB_D(fd, fj) ou5rr(0x228, 0x0a, fj, fd)
+# define FCLASS_S(fd, fj) ou5rr(0x228, 0x0d, fj, fd)
+# define FCLASS_D(fd, fj) ou5rr(0x228, 0x0e, fj, fd)
+# define FSQRT_S(fd, fj) ou5rr(0x228, 0x11, fj, fd)
+# define FSQRT_D(fd, fj) ou5rr(0x228, 0x12, fj, fd)
+# define FRECIP_S(fd, fj) ou5rr(0x228, 0x15, fj, fd)
+# define FRECIP_D(fd, fj) ou5rr(0x228, 0x16, fj, fd)
+# define FRSQRT_S(fd, fj) ou5rr(0x228, 0x19, fj, fd)
+# define FRSQRT_D(fd, fj) ou5rr(0x228, 0x1a, fj, fd)
+# define FMOV_S(fd, fj) ou5rr(0x229, 0x05, fj, fd)
+# define FMOV_D(fd, fj) ou5rr(0x229, 0x06, fj, fd)
+# define MOVGR2FR_W(fd, rj) ou5rr(0x229, 0x09, rj, fd)
+# define MOVGR2FR_D(fd, rj) ou5rr(0x229, 0x0a, rj, fd)
+# define MOVGR2FRH_W(fd, rj) ou5rr(0x229, 0x0b, rj, fd)
+# define MOVFR2GR_S(rd, fj) ou5rr(0x229, 0x0d, fj, rd)
+# define MOVFR2GR_D(rd, fj) ou5rr(0x229, 0x0e, fj, rd)
+# define MOVFRH2GR_S(rd, fj) ou5rr(0x229, 0x0f, fj, rd)
+# define MOVGR2FCSR(fc, rj) ou5rr(0x229, 0x10, rj, fc)
+# define MOVFCSR2GR(rd, fc) ou5rr(0x229, 0x12, fc, rd)
+# define MOVFR2CF(cd, fj) o5r23(0x229, 0x14, fj, 0, cd)
+# define MOVCF2FR(fd, cj) o523r(0x229, 0x15, 0, cj, fd)
+# define MOVGR2CF(cd, fj) o5r23(0x229, 0x16, fj, 0, cd)
+# define MOVCF2GR(fd, cj) o523r(0x229, 0x17, 0, cj, fd)
+# define FCVT_S_D(fd, fj) ou5rr(0x232, 0x06, fj, fd)
+# define FCVT_D_S(fd, fj) ou5rr(0x232, 0x09, fj, fd)
+# define FTINTRM_W_S(fd, fj) ou5rr(0x234, 0x01, fj, fd)
+# define FTINTRM_W_D(fd, fj) ou5rr(0x234, 0x02, fj, fd)
+# define FTINTRM_L_S(fd, fj) ou5rr(0x234, 0x09, fj, fd)
+# define FTINTRM_L_D(fd, fj) ou5rr(0x234, 0x0a, fj, fd)
+# define FTINTRP_W_S(fd, fj) ou5rr(0x234, 0x11, fj, fd)
+# define FTINTRP_W_D(fd, fj) ou5rr(0x234, 0x12, fj, fd)
+# define FTINTRP_L_S(fd, fj) ou5rr(0x234, 0x19, fj, fd)
+# define FTINTRP_L_D(fd, fj) ou5rr(0x234, 0x1a, fj, fd)
+# define FTINTRZ_W_S(fd, fj) ou5rr(0x235, 0x01, fj, fd)
+# define FTINTRZ_W_D(fd, fj) ou5rr(0x235, 0x02, fj, fd)
+# define FTINTRZ_L_S(fd, fj) ou5rr(0x235, 0x09, fj, fd)
+# define FTINTRZ_L_D(fd, fj) ou5rr(0x235, 0x0a, fj, fd)
+# define FTINTRNE_W_S(fd, fj) ou5rr(0x235, 0x11, fj, fd)
+# define FTINTRNE_W_D(fd, fj) ou5rr(0x235, 0x12, fj, fd)
+# define FTINTRNE_L_S(fd, fj) ou5rr(0x235, 0x19, fj, fd)
+# define FTINTRNE_L_D(fd, fj) ou5rr(0x235, 0x1a, fj, fd)
+# define FTINT_W_S(fd, fj) ou5rr(0x236, 0x01, fj, fd)
+# define FTINT_W_D(fd, fj) ou5rr(0x236, 0x02, fj, fd)
+# define FTINT_L_S(fd, fj) ou5rr(0x236, 0x09, fj, fd)
+# define FTINT_L_D(fd, fj) ou5rr(0x236, 0x0a, fj, fd)
+# define FFINT_S_W(fd, fj) ou5rr(0x23a, 0x04, fj, fd)
+# define FFINT_S_L(fd, fj) ou5rr(0x23a, 0x06, fj, fd)
+# define FFINT_D_W(fd, fj) ou5rr(0x23a, 0x08, fj, fd)
+# define FFINT_D_L(fd, fj) ou5rr(0x23a, 0x0a, fj, fd)
+# define FRINT_S(fd, fj) ou5rr(0x23c, 0x11, fj, fd)
+# define FRINT_D(fd, fj) ou5rr(0x23c, 0x12, fj, fd)
+# define FMADD_S(fd, fj, fk, fa) orrrr(0x081, fa, fk, fj, fd)
+# define FMADD_D(fd, fj, fk, fa) orrrr(0x082, fa, fk, fj, fd)
+# define FMSUB_S(fd, fj, fk, fa) orrrr(0x085, fa, fk, fj, fd)
+# define FMSUB_D(fd, fj, fk, fa) orrrr(0x086, fa, fk, fj, fd)
+# define FNMADD_S(fd, fj, fk, fa) orrrr(0x089, fa, fk, fj, fd)
+# define FNMADD_D(fd, fj, fk, fa) orrrr(0x08a, fa, fk, fj, fd)
+# define FNMSUB_S(fd, fj, fk, fa) orrrr(0x08d, fa, fk, fj, fd)
+# define FNMSUB_D(fd, fj, fk, fa) orrrr(0x08e, fa, fk, fj, fd)
+/* No QNaN exception */
+# define _CAF 0x00
+# define _CUN 0x08
+# define _CEQ 0x04
+# define _CUEQ 0x0c
+# define _CLT 0x02
+# define _CULT 0x0a
+# define _CLE 0x06
+# define _CULE 0x0e
+# define _CNE 0x10
+# define _COR 0x14
+# define _CUNE 0x18
+/* QNaN exception */
+# define _SAF 0x01
+# define _SUN 0x09
+# define _SEQ 0x05
+# define _SUEQ 0x0D
+# define _SLT 0x03
+# define _SULT 0x0B
+# define _SLE 0x07
+# define _SULE 0x0F
+# define _SNE 0x11
+# define _SOR 0x15
+# define _SUNE 0x19
+# define FCMP_cond_S(cc, cd, fj, fk) ou5rru2u3(0x0c1, cc, fk, fj, 0, cd)
+# define FCMP_CAF_S(cd, fj, fk) FCMP_cond_S( _CAF, cd, fj, fk)
+# define FCMP_CUN_S(cd, fj, fk) FCMP_cond_S( _CUN, cd, fj, fk)
+# define FCMP_CEQ_S(cd, fj, fk) FCMP_cond_S( _CEQ, cd, fj, fk)
+# define FCMP_CUEQ_S(cd, fj, fk) FCMP_cond_S(_CUEQ, cd, fj, fk)
+# define FCMP_CLT_S(cd, fj, fk) FCMP_cond_S( _CLT, cd, fj, fk)
+# define FCMP_CULT_S(cd, fj, fk) FCMP_cond_S(_CULT, cd, fj, fk)
+# define FCMP_CLE_S(cd, fj, fk) FCMP_cond_S( _CLE, cd, fj, fk)
+# define FCMP_CULE_S(cd, fj, fk) FCMP_cond_S(_CULE, cd, fj, fk)
+# define FCMP_CNE_S(cd, fj, fk) FCMP_cond_S( _CNE, cd, fj, fk)
+# define FCMP_COR_S(cd, fj, fk) FCMP_cond_S( _COR, cd, fj, fk)
+# define FCMP_CUNE_S(cd, fj, fk) FCMP_cond_S(_CUNE, cd, fj, fk)
+# define FCMP_SAF_S(cd, fj, fk) FCMP_cond_S( _CAF, cd, fj, fk)
+# define FCMP_SUN_S(cd, fj, fk) FCMP_cond_S( _CUN, cd, fj, fk)
+# define FCMP_SEQ_S(cd, fj, fk) FCMP_cond_S( _CEQ, cd, fj, fk)
+# define FCMP_SUEQ_S(cd, fj, fk) FCMP_cond_S(_CUEQ, cd, fj, fk)
+# define FCMP_SLT_S(cd, fj, fk) FCMP_cond_S( _CLT, cd, fj, fk)
+# define FCMP_SULT_S(cd, fj, fk) FCMP_cond_S(_CULT, cd, fj, fk)
+# define FCMP_SLE_S(cd, fj, fk) FCMP_cond_S( _CLE, cd, fj, fk)
+# define FCMP_SULE_S(cd, fj, fk) FCMP_cond_S(_CULE, cd, fj, fk)
+# define FCMP_SNE_S(cd, fj, fk) FCMP_cond_S( _CNE, cd, fj, fk)
+# define FCMP_SOR_S(cd, fj, fk) FCMP_cond_S( _COR, cd, fj, fk)
+# define FCMP_SUNE_S(cd, fj, fk) FCMP_cond_S(_CUNE, cd, fj, fk)
+# define FCMP_cond_D(cc, cd, fj, fk) ou5rru2u3(0x0c2, cc, fk, fj, 0, cd)
+# define FCMP_CAF_D(cd, fj, fk) FCMP_cond_D( _CAF, cd, fj, fk)
+# define FCMP_CUN_D(cd, fj, fk) FCMP_cond_D( _CUN, cd, fj, fk)
+# define FCMP_CEQ_D(cd, fj, fk) FCMP_cond_D( _CEQ, cd, fj, fk)
+# define FCMP_CUEQ_D(cd, fj, fk) FCMP_cond_D(_CUEQ, cd, fj, fk)
+# define FCMP_CLT_D(cd, fj, fk) FCMP_cond_D( _CLT, cd, fj, fk)
+# define FCMP_CULT_D(cd, fj, fk) FCMP_cond_D(_CULT, cd, fj, fk)
+# define FCMP_CLE_D(cd, fj, fk) FCMP_cond_D( _CLE, cd, fj, fk)
+# define FCMP_CULE_D(cd, fj, fk) FCMP_cond_D(_CULE, cd, fj, fk)
+# define FCMP_CNE_D(cd, fj, fk) FCMP_cond_D( _CNE, cd, fj, fk)
+# define FCMP_COR_D(cd, fj, fk) FCMP_cond_D( _COR, cd, fj, fk)
+# define FCMP_CUNE_D(cd, fj, fk) FCMP_cond_D(_CUNE, cd, fj, fk)
+# define FCMP_SAF_D(cd, fj, fk) FCMP_cond_D( _CAF, cd, fj, fk)
+# define FCMP_SUN_D(cd, fj, fk) FCMP_cond_D( _CUN, cd, fj, fk)
+# define FCMP_SEQ_D(cd, fj, fk) FCMP_cond_D( _CEQ, cd, fj, fk)
+# define FCMP_SUEQ_D(cd, fj, fk) FCMP_cond_D(_CUEQ, cd, fj, fk)
+# define FCMP_SLT_D(cd, fj, fk) FCMP_cond_D( _CLT, cd, fj, fk)
+# define FCMP_SULT_D(cd, fj, fk) FCMP_cond_D(_CULT, cd, fj, fk)
+# define FCMP_SLE_D(cd, fj, fk) FCMP_cond_D( _CLE, cd, fj, fk)
+# define FCMP_SULE_D(cd, fj, fk) FCMP_cond_D(_CULE, cd, fj, fk)
+# define FCMP_SNE_D(cd, fj, fk) FCMP_cond_D( _CNE, cd, fj, fk)
+# define FCMP_SOR_D(cd, fj, fk) FCMP_cond_D( _COR, cd, fj, fk)
+# define FCMP_SUNE_D(cd, fj, fk) FCMP_cond_D(_CUNE, cd, fj, fk)
+# define FSEL(fd, fj, fk, u3) ou3rrr(0x340, u3, fk, fj, fd)
+# define FLD_S(fd, rj, si12) os12rr(0x0ac, si12, rj, fd)
+# define FST_S(fd, rj, si12) os12rr(0x0ad, si12, rj, fd)
+# define FLD_D(fd, rj, si12) os12rr(0x0ae, si12, rj, fd)
+# define FST_D(fd, rj, si12) os12rr(0x0af, si12, rj, fd)
+# define FLDX_S(fd, rj, rk) orrr(0x7060, rk, rj, fd)
+# define FLDX_D(fd, rj, rk) orrr(0x7068, rk, rj, fd)
+# define FSTX_S(fd, rj, rk) orrr(0x7070, rk, rj, fd)
+# define FSTX_D(fd, rj, rk) orrr(0x7078, rk, rj, fd)
+# define FLDGT_S(fd, rj, rk) orrr(0x70e8, rk, rj, fd)
+# define FLDGT_D(fd, rj, rk) orrr(0x70e9, rk, rj, fd)
+# define FLDLE_S(fd, rj, rk) orrr(0x70ea, rk, rj, fd)
+# define FLDLE_D(fd, rj, rk) orrr(0x70eb, rk, rj, fd)
+# define FSTGT_S(fd, rj, rk) orrr(0x70ec, rk, rj, fd)
+# define FSTGT_D(fd, rj, rk) orrr(0x70ed, rk, rj, fd)
+# define FSTLE_S(fd, rj, rk) orrr(0x70ee, rk, rj, fd)
+# define FSTLE_D(fd, rj, rk) orrr(0x70ef, rk, rj, fd)
+# 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_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_f_l(r0, r1) _truncr_f_l(_jit, r0, r1)
+static void _truncr_f_l(jit_state_t*, jit_int32_t, jit_int32_t);
+# 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 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 rsbr_f(r0, r1, r2) FSUB_S(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) FMUL_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 divr_f(r0, r1, r2) FDIV_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 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) _extr_f(_jit, r0, r1)
+static void _extr_f(jit_state_t*, jit_int32_t, jit_int32_t);
+# define ldr_f(r0, r1) FLD_S(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 ldxr_f(r0, r1, r2) FLDX_S(r0, r1, r2)
+# 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) FST_S(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 stxr_f(r0, r1, r2) FSTX_S(r2, r1, r0)
+# 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) FMOV_S(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 movr_f_w(r0, r1) MOVFR2GR_S(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) MOVGR2FR_W(r0, r1)
+# define extr_d_f(r0, r1) FCVT_S_D(r0, r1)
+# 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, i0) _lti_f(_jit, r0, r1, i0)
+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, i0) _lei_f(_jit, r0, r1, i0)
+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, i0) _eqi_f(_jit, r0, r1, i0)
+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, i0) _gei_f(_jit, r0, r1, i0)
+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, i0) _gti_f(_jit, r0, r1, i0)
+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, i0) _nei_f(_jit, r0, r1, i0)
+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, i0) _unlti_f(_jit, r0, r1, i0)
+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, i1) _unlei_f(_jit, r0, r1, i1)
+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, 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) _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, i0) _ungei_f(_jit, r0, r1, i0)
+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, i0) _ungti_f(_jit, r0, r1, i0)
+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, 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) _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, i0) _ordi_f(_jit, r0, r1, i0)
+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, i0) _unordi_f(_jit, r0, r1, i0)
+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 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_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_d(r0, r1, r2) FSUB_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) FMUL_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_d(r0, r1, r2) FDIV_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_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) _extr_d(_jit, r0, r1)
+static void _extr_d(jit_state_t*, jit_int32_t, jit_int32_t);
+# define ldr_d(r0, r1) FLD_D(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_d(r0, r1, r2) FLDX_D(r0, r1, r2)
+# 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) FST_D(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_d(r0, r1, r2) FSTX_D(r2, r1, r0)
+# 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) FMOV_D(r0, r1)
+# 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_d_w(r0, r1) MOVFR2GR_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) MOVGR2FR_D(r0, r1)
+# define extr_f_d(r0, r1) FCVT_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, 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_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, 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_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, 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_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, 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_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, 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_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, 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_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, 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_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, 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_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) _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, 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_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, 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_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) _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, 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_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, 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_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 /* PROTO */
+
+#if CODE
+static void
+_truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+ jit_int32_t reg = jit_get_reg(jit_class_fpr);
+ FTINTRZ_W_S(rn(reg), r1);
+ MOVFR2GR_S(r0, rn(reg));
+ 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 = jit_get_reg(jit_class_fpr);
+ FTINTRZ_W_D(rn(reg), r1);
+ MOVFR2GR_S(r0, rn(reg));
+ jit_unget_reg(reg);
+}
+
+static void
+_truncr_f_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+ jit_int32_t reg = jit_get_reg(jit_class_fpr);
+ FTINTRZ_L_S(rn(reg), r1);
+ MOVFR2GR_D(r0, rn(reg));
+ 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 = jit_get_reg(jit_class_fpr);
+ FTINTRZ_L_D(rn(reg), r1);
+ MOVFR2GR_D(r0, rn(reg));
+ jit_unget_reg(reg);
+}
+
+# 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)
+
+# 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)
+
+fopi(add)
+fopi(sub)
+fopi(rsb)
+fopi(mul)
+fopi(div)
+
+static void
+_extr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+ MOVGR2FR_D(r0, r1);
+ FFINT_S_L(r0, r0);
+}
+
+static void
+_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ jit_int32_t t0;
+ if (can_sign_extend_si12_p(i0))
+ FLD_S(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
+_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
+{
+ jit_int32_t t0;
+ if (can_sign_extend_si12_p(i0))
+ FLD_S(r0, r1, i0);
+ else {
+ t0 = jit_get_reg(jit_class_gpr);
+ movi(rn(t0), i0);
+ ldxr_f(r0, r1, 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 (can_sign_extend_si12_p(i0))
+ FST_S(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
+_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
+{
+ jit_int32_t t0;
+ if (can_sign_extend_si12_p(i0))
+ FST_S(r1, r0, i0);
+ else {
+ t0 = jit_get_reg(jit_class_gpr);
+ movi(rn(t0), i0);
+ stxr_f(rn(t0), r0, 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);
+}
+
+static void
+_ltr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_SLT_S(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+fopi(lt)
+
+static void
+_ler_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_SLE_S(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+fopi(le)
+
+static void
+_eqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CEQ_S(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+fopi(eq)
+
+static void
+_ger_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_SLE_S(0, r2, r1);
+ MOVCF2GR(r0, 0);
+}
+fopi(ge)
+
+static void
+_gtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_SLT_S(0, r2, r1);
+ MOVCF2GR(r0, 0);
+}
+fopi(gt)
+
+static void
+_ner_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CUNE_S(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+fopi(ne)
+
+static void
+_unltr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CULT_S(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+fopi(unlt)
+
+static void
+_unler_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CULE_S(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+fopi(unle)
+
+static void
+_uneqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CUEQ_S(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+fopi(uneq)
+
+static void
+_unger_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CULE_S(0, r2, r1);
+ MOVCF2GR(r0, 0);
+}
+fopi(unge)
+
+static void
+_ungtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CULT_S(0, r2, r1);
+ MOVCF2GR(r0, 0);
+}
+fopi(ungt)
+
+static void
+_ltgtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CNE_S(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+fopi(ltgt)
+
+static void
+_ordr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_COR_S(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+fopi(ord)
+
+static void
+_unordr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_COR_S(0, r1, r2);
+ MOVCF2GR(r0, 0);
+ XORI(r0, r0, 1);
+}
+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;
+ FCMP_SLT_S(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_SLE_S(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CEQ_S(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_SLE_S(0, r2, r1);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_SLT_S(0, r2, r1);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CUNE_S(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CULT_S(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CULE_S(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CUEQ_S(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CULE_S(0, r2, r1);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CULT_S(0, r2, r1);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CNE_S(0, r2, r1);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_COR_S(0, r2, r1);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_COR_S(0, r2, r1);
+ w = _jit->pc.w;
+ BCEQZ(0, (i0 - w) >> 2);
+ return (w);
+}
+fbopi(unord)
+
+dopi(add)
+dopi(sub)
+dopi(rsb)
+dopi(mul)
+dopi(div)
+
+static void
+_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+ MOVGR2FR_D(r0, r1);
+ FFINT_D_L(r0, r0);
+}
+
+static void
+_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+ jit_int32_t t0;
+ if (can_sign_extend_si12_p(i0))
+ FLD_D(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
+_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
+{
+ jit_int32_t t0;
+ if (can_sign_extend_si12_p(i0))
+ FLD_D(r0, r1, i0);
+ else {
+ t0 = jit_get_reg(jit_class_gpr);
+ movi(rn(t0), i0);
+ ldxr_d(r0, r1, 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 (can_sign_extend_si12_p(i0))
+ FST_D(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
+_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
+{
+ jit_int32_t t0;
+ if (can_sign_extend_si12_p(i0))
+ FST_D(r1, r0, i0);
+ else {
+ t0 = jit_get_reg(jit_class_gpr);
+ movi(rn(t0), i0);
+ stxr_d(rn(t0), r0, 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);
+}
+
+static void
+_ltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_SLT_D(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+dopi(lt)
+
+static void
+_ler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_SLE_D(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+dopi(le)
+
+static void
+_eqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CEQ_D(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+dopi(eq)
+
+static void
+_ger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_SLE_D(0, r2, r1);
+ MOVCF2GR(r0, 0);
+}
+dopi(ge)
+
+static void
+_gtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_SLT_D(0, r2, r1);
+ MOVCF2GR(r0, 0);
+}
+dopi(gt)
+
+static void
+_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CUNE_D(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+dopi(ne)
+
+static void
+_unltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CULT_D(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+dopi(unlt)
+
+static void
+_unler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CULE_D(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+dopi(unle)
+
+static void
+_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CUEQ_D(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+dopi(uneq)
+
+static void
+_unger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CULE_D(0, r2, r1);
+ MOVCF2GR(r0, 0);
+}
+dopi(unge)
+
+static void
+_ungtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CULT_D(0, r2, r1);
+ MOVCF2GR(r0, 0);
+}
+dopi(ungt)
+
+static void
+_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_CNE_D(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+dopi(ltgt)
+
+static void
+_ordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_COR_D(0, r1, r2);
+ MOVCF2GR(r0, 0);
+}
+dopi(ord)
+
+static void
+_unordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ FCMP_COR_D(0, r1, r2);
+ MOVCF2GR(r0, 0);
+ XORI(r0, r0, 1);
+}
+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;
+ FCMP_SLT_D(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_SLE_D(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CEQ_D(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_SLE_D(0, r2, r1);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_SLT_D(0, r2, r1);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CUNE_D(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CULT_D(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CULE_D(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CUEQ_D(0, r1, r2);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CULE_D(0, r2, r1);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CULT_D(0, r2, r1);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_CNE_D(0, r2, r1);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_COR_D(0, r2, r1);
+ w = _jit->pc.w;
+ BCNEZ(0, (i0 - w) >> 2);
+ 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;
+ FCMP_COR_D(0, r2, r1);
+ w = _jit->pc.w;
+ BCEQZ(0, (i0 - w) >> 2);
+ 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 */
--- /dev/null
+/*
+ * Copyright (C) 2022 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 struct 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_loongarch-cpu.c"
+# include "jit_loongarch-fpu.c"
+#undef PROTO
+
+/*
+ * Initialization
+ */
+jit_register_t _rvs[] = {
+ { rc(gpr) | 0x14, "$t8" },
+ { rc(gpr) | 0x13, "$t7" },
+ { rc(gpr) | 0x12, "$t6" },
+ { rc(gpr) | 0x11, "$t5" },
+ { rc(gpr) | 0x10, "$t4" },
+ { rc(gpr) | 0x0f, "$t3" },
+ { rc(gpr) | 0x0e, "$t2" },
+ { rc(gpr) | 0x0d, "$t1" },
+ { rc(gpr) | 0x0c, "$t0" },
+ { rc(sav) | rc(gpr) | 0x1f, "$s8" },
+ { rc(sav) | rc(gpr) | 0x1e, "$s7" },
+ { rc(sav) | rc(gpr) | 0x1d, "$s6" },
+ { rc(sav) | rc(gpr) | 0x1c, "$s5" },
+ { rc(sav) | rc(gpr) | 0x1b, "$s4" },
+ { rc(sav) | rc(gpr) | 0x1a, "$s3" },
+ { rc(sav) | rc(gpr) | 0x19, "$s2" },
+ { rc(sav) | rc(gpr) | 0x18, "$s1" },
+ { rc(sav) | rc(gpr) | 0x17, "$s0" },
+ { rc(arg) | rc(gpr) | 0x0b, "$a7" },
+ { rc(arg) | rc(gpr) | 0x0a, "$a6" },
+ { rc(arg) | rc(gpr) | 0x09, "$a5" },
+ { rc(arg) | rc(gpr) | 0x08, "$a4" },
+ { rc(arg) | rc(gpr) | 0x07, "$a3" },
+ { rc(arg) | rc(gpr) | 0x06, "$a2" },
+ { rc(arg) | rc(gpr) | 0x05, "$a1" },
+ { rc(arg) | rc(gpr) | 0x04, "$a0" },
+ { 0x16, "$fp" },
+ { 0x15, "<reserved>" },
+ { 0x00, "$zero" },
+ { 0x01, "$ra" },
+ { 0x02, "$tp" },
+ { 0x03, "$sp" },
+ { rc(fpr) | 0x08, "$ft0" },
+ { rc(fpr) | 0x09, "$ft1" },
+ { rc(fpr) | 0x0a, "$ft2" },
+ { rc(fpr) | 0x0b, "$ft3" },
+ { rc(fpr) | 0x0c, "$ft4" },
+ { rc(fpr) | 0x0d, "$ft5" },
+ { rc(fpr) | 0x0e, "$ft6" },
+ { rc(fpr) | 0x0f, "$ft7" },
+ { rc(fpr) | 0x10, "$ft8" },
+ { rc(fpr) | 0x11, "$ft9" },
+ { rc(fpr) | 0x12, "$ft10" },
+ { rc(fpr) | 0x13, "$ft11" },
+ { rc(fpr) | 0x14, "$ft12" },
+ { rc(fpr) | 0x15, "$ft13" },
+ { rc(fpr) | 0x16, "$ft14" },
+ { rc(fpr) | 0x17, "$ft15" },
+ { rc(arg) | rc(fpr) | 0x07, "$fa7" },
+ { rc(arg) | rc(fpr) | 0x06, "$fa6" },
+ { rc(arg) | rc(fpr) | 0x05, "$fa5" },
+ { rc(arg) | rc(fpr) | 0x04, "$fa4" },
+ { rc(arg) | rc(fpr) | 0x03, "$fa3" },
+ { rc(arg) | rc(fpr) | 0x02, "$fa2" },
+ { rc(arg) | rc(fpr) | 0x01, "$fa1" },
+ { rc(arg) | rc(fpr) | 0x00, "$fa0" },
+ { rc(sav) | rc(fpr) | 0x1f, "$fs7" },
+ { rc(sav) | rc(fpr) | 0x1e, "$fs6" },
+ { rc(sav) | rc(fpr) | 0x1d, "$fs5" },
+ { rc(sav) | rc(fpr) | 0x1c, "$fs4" },
+ { rc(sav) | rc(fpr) | 0x1b, "$fs3" },
+ { rc(sav) | rc(fpr) | 0x1a, "$fs2" },
+ { rc(sav) | rc(fpr) | 0x19, "$fs1" },
+ { rc(sav) | rc(fpr) | 0x18, "$fs0" },
+ { _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.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);
+ 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);
+ 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, _A0 - 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, _A0 - 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, _A0 - 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, _A0 - 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, _A0 - 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, _A0 - 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, _A0 - 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(_A0 - 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(_A0 - 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, _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(_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(_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, _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_f_reg_p(v->u.w))
+ jit_movr_d(_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_f_reg_p(v->u.w))
+ jit_movi_d(_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(_A0 - _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(_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);
+ 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(_FA0 - _jitc->function->call.argf, u);
+ ++_jitc->function->call.argf;
+ }
+ else if (jit_arg_reg_p(_jitc->function->call.argi)) {
+ 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 += 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(_FA0 - _jitc->function->call.argf, u);
+ ++_jitc->function->call.argf;
+ }
+ else if (jit_arg_reg_p(_jitc->function->call.argi)) {
+ 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);
+ 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(_FA0 - _jitc->function->call.argf, u);
+ ++_jitc->function->call.argf;
+ }
+ else if (jit_arg_reg_p(_jitc->function->call.argi)) {
+ 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 += 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(_FA0 - _jitc->function->call.argf, u);
+ ++_jitc->function->call.argf;
+ }
+ else if (jit_arg_reg_p(_jitc->function->call.argi)) {
+ 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);
+ 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 = _A0 - regno;
+ if (regno >= 0 && regno < node->v.w)
+ return (1);
+ if (spec & jit_class_fpr) {
+ regno = _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->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();
+}
+
+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_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), 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:
+ /* Must align to a power of two */
+ assert(!(node->u.w & (node->u.w - 1)));
+ 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:
+ /* 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);
+ 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(bswap, _us);
+ case_rr(bswap, _ui);
+ case_rr(bswap, _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 jit_code_casr:
+ casr(rn(node->u.w), rn(node->v.w),
+ rn(node->w.q.l), rn(node->w.q.h));
+ break;
+ case jit_code_casi:
+ casi(rn(node->u.w), node->v.w,
+ rn(node->w.q.l), rn(node->w.q.h));
+ break;
+ case_rrr(movn,);
+ case_rrr(movz,);
+ 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;
+ }
+ 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_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 = 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_loongarch-cpu.c"
+# include "jit_loongarch-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;
+}