unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* riscv files for lightening
@ 2021-01-29 19:13 Matt Wette
  2021-01-30 15:14 ` Matt Wette
  0 siblings, 1 reply; 2+ messages in thread
From: Matt Wette @ 2021-01-29 19:13 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: text/plain, Size: 499 bytes --]

Andy,

I took a stab at porting RISC-V from lightning to lightening.
I have no riscv toolset or computer yet so these are untested.

I copied files from sv/lightning for riscv to wingo/lightening. Patch 
attached.
The changes are:
1) copy lightning/jit_riscv{.c,-cpu.c-fpu.c,-sz.c,.h} to lightening
2) s/include "jit_riscv/include "riscv/
3) s/git_int/int/ and s/git_uint/uint/
4) copied the JIT_RA0, etc defines from jit_private.h to riscv.c
5) updated lightening.am
6) updated lightening.h

Matt


[-- Attachment #2: 0001-merge-riscv-files-from-lightning.patch --]
[-- Type: text/x-patch, Size: 173550 bytes --]

From d5ee171e902a3a38dd667518ff215aa3fe825185 Mon Sep 17 00:00:00 2001
From: Matt Wette <mwette@alumni.caltech.edu>
Date: Fri, 29 Jan 2021 11:07:17 -0800
Subject: [PATCH] merge riscv files from lightning

---
 lightening.am          |    4 +
 lightening.h           |    2 +
 lightening/riscv-cpu.c | 2378 ++++++++++++++++++++++++++++++++++++++++
 lightening/riscv-fpu.c | 1271 +++++++++++++++++++++
 lightening/riscv-sz.c  |  401 +++++++
 lightening/riscv.c     | 1621 +++++++++++++++++++++++++++
 lightening/riscv.h     |  147 +++
 7 files changed, 5824 insertions(+)
 create mode 100644 lightening/riscv-cpu.c
 create mode 100644 lightening/riscv-fpu.c
 create mode 100644 lightening/riscv-sz.c
 create mode 100644 lightening/riscv.c
 create mode 100644 lightening/riscv.h

diff --git a/lightening.am b/lightening.am
index 2c9089e..be22c31 100644
--- a/lightening.am
+++ b/lightening.am
@@ -53,6 +53,10 @@ lightening_extra_files =				\
 	$(lightening)/lightening/ppc.c			\
 	$(lightening)/lightening/ppc-cpu.c		\
 	$(lightening)/lightening/ppc-fpu.c		\
+	$(lightening)/lightening/riscv.c		\
+	$(lightening)/lightening/riscv-cpu.c		\
+	$(lightening)/lightening/riscv-fpu.c		\
+	$(lightening)/lightening/riscv-sz.c		\
 	$(lightening)/lightening/x86.c			\
 	$(lightening)/lightening/x86-cpu.c		\
 	$(lightening)/lightening/x86-sse.c
diff --git a/lightening.h b/lightening.h
index efa5dfd..5c02fa9 100644
--- a/lightening.h
+++ b/lightening.h
@@ -77,6 +77,8 @@ jit_same_fprs (jit_fpr_t a, jit_fpr_t b)
 #  include "lightening/aarch64.h"
 #elif defined(__s390__) || defined(__s390x__)
 #  include "lightening/s390.h"
+#elif defined(__riscv__)
+#  include "lightening/riscv.h"
 #endif
 
 enum jit_reloc_kind
diff --git a/lightening/riscv-cpu.c b/lightening/riscv-cpu.c
new file mode 100644
index 0000000..dbe1249
--- /dev/null
+++ b/lightening/riscv-cpu.c
@@ -0,0 +1,2378 @@
+/*
+ * Copyright (C) 2019,2021  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU lightning.
+ *
+ * GNU lightning is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU lightning is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ *
+ * Authors:
+ *	Paulo Cesar Pereira de Andrade
+ */
+
+#if PROTO
+#define _ZERO_REGNO		0
+#define _RA_REGNO		1
+#define _SP_REGNO		2
+#define _FP_REGNO		8
+typedef union {
+#  define ui			uint32_t
+    struct  {
+	ui opcode	: 7;
+	ui rd		: 5;
+	ui funct3	: 3;
+	ui rs1		: 5;
+	ui rs2		: 5;
+	ui funct7	: 7;
+    } R;
+    struct  {
+	ui opcode	: 7;
+	ui rd		: 5;
+	ui funct3	: 3;
+	ui rs1		: 5;
+	ui rs2		: 5;
+	ui funct2	: 2;
+	ui rs3		: 5;
+    } R4;
+    struct  {
+	ui opcode	: 7;
+	ui rd		: 5;
+	ui funct3	: 3;
+	ui rs1		: 5;
+	ui imm11_0	: 12;
+    } I;
+#  if __WORDSIZE == 64
+    struct  {
+	ui opcode	: 7;
+	ui rd		: 5;
+	ui funct3	: 3;
+	ui rs1		: 5;
+	ui shamt	: 6;
+	ui imm6_0	: 6;
+    } IS;
+#  endif
+    struct  {
+	ui opcode	: 7;
+	ui imm4_0	: 5;
+	ui funct3	: 3;
+	ui rs1		: 5;
+	ui rs2		: 5;
+	ui imm11_5	: 7;
+    } S;
+    struct  {
+	ui opcode	: 7;
+	ui imm11	: 1;
+	ui imm4_1	: 4;
+	ui funct3	: 3;
+	ui rs1		: 5;
+	ui rs2		: 5;
+	ui imm10_5	: 6;
+	ui imm12	: 1;
+    } B;
+    struct  {
+	ui opcode	: 7;
+	ui rd		: 5;
+	ui imm12_31	: 20;
+    } U;
+    struct  {
+	ui opcode	: 7;
+	ui rd		: 5;
+	ui imm19_12	: 8;
+	ui imm11	: 1;
+	ui imm10_1	: 10;
+	ui imm20	: 1;
+    } J;
+    int32_t		w;
+#  undef ui
+} instr_t;
+#  define ii(i)				*_jit->pc.ui++ = i
+/* FIXME could jit_rewind_prolog() to only use extra 64 bytes
+ * if a variadic jit function that have variadic arguments in
+ * registers */
+#  define stack_framesize		(200 + 64)
+#  define ldr(r0, r1)			ldr_l(r0, r1)
+#  define ldi(r0, im)			ldi_l(r0, im)
+#  define ldxr(r0, r1, r2)		ldxr_l(r0, r1, r2)
+#  define ldxi(r0, r1, im)		ldxi_l(r0, r1, im)
+#  define str(r0, r1)			str_l(r0, r1)
+#  define sti(im, r0)			sti_l(im, r0)
+#  define stxr(r0, r1, r2)		stxr_l(r0, r1, r2)
+#  define stxi(im, r0, r1)		stxi_l(im, r0, r1)
+#  define simm6_p(im)			((im) <= 31 && (im) >= -32)
+#  define simm12_p(im)			((im) <= 2047 && (im) >= -2048)
+#  define simm20_p(im)			((im) <= 524287 && (im) >= -524288)
+#  define simm32_p(im)			((im) <= 2147483647LL && (im) >= -2147483648LL)
+
+/*
+ * RV32I Base Instruction Set
+ */
+#  define LUI(rd, imm)			Utype(55, rd, imm)
+#  define AUIPC(rd, imm)		Utype(23, rd, imm)
+#  define JAL(rd, imm)			Jtype(111, rd, imm)
+#  define JALR(rd, rs1, imm)		Itype(103, rd, 0, rs1, imm)
+#  define BEQ(rs1, rs2, imm)		Btype(99, 0, rs1, rs2, imm)
+#  define BNE(rs1, rs2, imm)		Btype(99, 1, rs1, rs2, imm)
+#  define BLT(rs1, rs2, imm)		Btype(99, 4, rs1, rs2, imm)
+#  define BGE(rs1, rs2, imm)		Btype(99, 5, rs1, rs2, imm)
+#  define BLTU(rs1, rs2, imm)		Btype(99, 6, rs1, rs2, imm)
+#  define BGEU(rs1, rs2, imm)		Btype(99, 7, rs1, rs2, imm)
+#  define LB(rd, rs1, imm)		Itype(3, rd, 0, rs1, imm)
+#  define LH(rd, rs1, imm)		Itype(3, rd, 1, rs1, imm)
+#  define LW(rd, rs1, imm)		Itype(3, rd, 2, rs1, imm)
+#  define LBU(rd, rs1, imm)		Itype(3, rd, 4, rs1, imm)
+#  define LHU(rd, rs1, imm)		Itype(3, rd, 5, rs1, imm)
+#  define SB(rs1, rs2, imm)		Stype(35, 0, rs1, rs2, imm)
+#  define SH(rs1, rs2, imm)		Stype(35, 1, rs1, rs2, imm)
+#  define SW(rs1, rs2, imm)		Stype(35, 2, rs1, rs2, imm)
+#  define ADDI(rd, rs1, imm)		Itype(19, rd, 0, rs1, imm)
+#  define SLTI(rd, rs1, imm)		Itype(19, rd, 2, rs1, imm)
+#  define SLTIU(rd, rs1, imm)		Itype(19, rd, 3, rs1, imm)
+#  define XORI(rd, rs1, imm)		Itype(19, rd, 4, rs1, imm)
+#  define ORI(rd, rs1, imm)		Itype(19, rd, 6, rs1, imm)
+#  define ANDI(rd, rs1, imm)		Itype(19, rd, 7, rs1, imm)
+#  if __WORDSIZE == 32
+#    define SLLI(rd, rs1, imm)		Rtype(19, rd, 1, rs1, imm, 0)
+#    define SRLI(rd, rs1, imm)		Rtype(19, rd, 5, rs1, imm, 0)
+#    define SRAI(rd, rs1, imm)		Rtype(19, rd, 5, rs1, imm, 32)
+#  endif
+#  define ADD(rd, rs1, rs2)		Rtype(51, rd, 0, rs1, rs2, 0)
+#  define SUB(rd, rs1, rs2)		Rtype(51, rd, 0, rs1, rs2, 32)
+#  define SLL(rd, rs1, rs2)		Rtype(51, rd, 1, rs1, rs2, 0)
+#  define SLT(rd, rs1, rs2)		Rtype(51, rd, 2, rs1, rs2, 0)
+#  define SLTU(rd, rs1, rs2)		Rtype(51, rd, 3, rs1, rs2, 0)
+#  define XOR(rd, rs1, rs2)		Rtype(51, rd, 4, rs1, rs2, 0)
+#  define SRL(rd, rs1, rs2)		Rtype(51, rd, 5, rs1, rs2, 0)
+#  define SRA(rd, rs1, rs2)		Rtype(51, rd, 5, rs1, rs2, 32)
+#  define OR(rd, rs1, rs2)		Rtype(51, rd, 6, rs1, rs2, 0)
+#  define AND(rd, rs1, rs2)		Rtype(51, rd, 7, rs1, rs2, 0)
+#  define FENCE(imm)			Itype(15, 0, 0, 0, im)
+#  define FENCE_I(imm)			Itype(15, 0, 1, 0, im)
+#  define ECALL()			Itype(115, 0, 0, 0, 0)
+#  define EBREAK()			Itype(115, 0, 0, 0, 1)
+#  define CSRRW(rd, rs1, csr)		Itype(115, rd, 1, rs1, csr)
+#  define CSRRS(rd, rs1, csr)		Itype(115, rd, 2, rs1, csr)
+#  define CSRRC(rd, rs1, csr)		Itype(115, rd, 3, rs1, csr)
+#  define CSRRWI(rd, zimm, csr)		Itype(115, rd, 5, zimm, csr)
+#  define CSRRSI(rd, zimm, csr)		Itype(115, rd, 6, zimm, csr)
+#  define CSRRCI(rd, zimm, csr)		Itype(115, rd, 7, zimm, csr)
+/*
+ * RV64I Base Instruction Set (in addition to RV32I)
+ */
+#  define LWU(rd, rs1, imm)		Itype(3, rd, 6, rs1, imm)
+#  define LD(rd, rs1, imm)		Itype(3, rd, 3, rs1, imm)
+#  define SD(rs1, rs2, imm)		Stype(35, 3, rs1, rs2, imm)
+#  if __WORDSIZE == 64
+#    define SLLI(rd, rs1, sh)		IStype(19, rd, 1, rs1, sh, 0)
+#    define SRLI(rd, rs1, sh)		IStype(19, rd, 5, rs1, sh, 0)
+#    define SRAI(rd, rs1, sh)		IStype(19, rd, 5, rs1, sh, 16)
+#  endif
+#  define ADDIW(rd, rs1, imm)		Itype(27, rd, 0, rs1, imm)
+#  define SLLIW(rd, rs1, imm)		Rtype(27, rd, 1, rs1, imm, 0)
+#  define SRLIW(rd, rs1, imm)		Rtype(27, rd, 3, rs1, imm, 0)
+#  define SRAIW(rd, rs1, imm)		Rtype(27, rd, 3, rs1, imm, 32)
+#  define ADDW(rd, rs1, imm)		Rtype(59, rd, 0, rs1, imm, 0)
+#  define SUBW(rd, rs1, imm)		Rtype(59, rd, 0, rs1, imm, 32)
+#  define SLLW(rd, rs1, imm)		Rtype(59, rd, 1, rs1, imm, 0)
+#  define SRLW(rd, rs1, imm)		Rtype(59, rd, 5, rs1, imm, 0)
+#  define SRAW(rd, rs1, imm)		Rtype(59, rd, 5, rs1, imm, 32)
+/*
+ * RV32M Standard Extension
+ */
+#  define MUL(rd, rs1, rs2)		Rtype(51, rd, 0, rs1, rs2, 1)
+#  define MULH(rd, rs1, rs2)		Rtype(51, rd, 1, rs1, rs2, 1)
+#  define MULHSU(rd, rs1, rs2)		Rtype(51, rd, 2, rs1, rs2, 1)
+#  define MULHU(rd, rs1, rs2)		Rtype(51, rd, 3, rs1, rs2, 1)
+#  define DIV(rd, rs1, rs2)		Rtype(51, rd, 4, rs1, rs2, 1)
+#  define DIVU(rd, rs1, rs2)		Rtype(51, rd, 5, rs1, rs2, 1)
+#  define REM(rd, rs1, rs2)		Rtype(51, rd, 6, rs1, rs2, 1)
+#  define REMU(rd, rs1, rs2)		Rtype(51, rd, 7, rs1, rs2, 1)
+/*
+ * RV64M Standard Extension (in addition to RV32M)
+ */
+#  define MULW(rd, rs1, rs2)		Rtype(59, rd, 0, rs1, rs2, 1)
+#  define DIVW(rd, rs1, rs2)		Rtype(59, rd, 4, rs1, rs2, 1)
+#  define DIVUW(rd, rs1, rs2)		Rtype(59, rd, 5, rs1, rs2, 1)
+#  define REMW(rd, rs1, rs2)		Rtype(59, rd, 6, rs1, rs2, 1)
+#  define REMUW(rd, rs1, rs2)		Rtype(59, rd, 7, rs1, rs2, 1)
+/*
+ * RV32A Standard Extension
+ */
+#  define LR_W(rd, rs1)			R4type(47, rd, 2, rs1, 0, 0, 2)
+#  define SC_W(rd, rs1, rs2)		R4type(47, rd, 2, rs1, rs2, 0, 3)
+#  define AMOSWAP_W(rd, rs1, rs2)	R4type(47, rd, 2, rs1, rs2, 0, 1)
+#  define AMOADD_W(rd, rs1, rs2)	R4type(47, rd, 2, rs1, rs2, 0, 0)
+#  define AMOXOR_W(rd, rs1, rs2)	R4type(47, rd, 2, rs1, rs2, 0, 4)
+#  define AMOAND_W(rd, rs1, rs2)	R4type(47, rd, 2, rs1, rs2, 0, 12)
+#  define AMOOR_W(rd, rs1, rs2)		R4type(47, rd, 2, rs1, rs2, 0, 8)
+#  define AMOMIN_W(rd, rs1, rs2)	R4type(47, rd, 2, rs1, rs2, 0, 16)
+#  define AMOMAX_W(rd, rs1, rs2)	R4type(47, rd, 2, rs1, rs2, 0, 20)
+#  define AMOMINU_W(rd, rs1, rs2)	R4type(47, rd, 2, rs1, rs2, 0, 24)
+#  define AMOMAXU_W(rd, rs1, rs2)	R4type(47, rd, 2, rs1, rs2, 0, 28)
+/*
+ * RV64A Standard Extension (in addition to RV32A)
+ */
+#  define LR_D(rd, rs1)			R4type(47, rd, 3, rs1, 0, 0, 2)
+#  define SC_D(rd, rs1, rs2)		R4type(47, rd, 3, rs1, rs2, 0, 3)
+#  define AMOSWAP_D(rd, rs1, rs2)	R4type(47, rd, 3, rs1, rs2, 0, 1)
+#  define AMOADD_D(rd, rs1, rs2)	R4type(47, rd, 3, rs1, rs2, 0, 0)
+#  define AMOXOR_D(rd, rs1, rs2)	R4type(47, rd, 3, rs1, rs2, 0, 4)
+#  define AMOAND_D(rd, rs1, rs2)	R4type(47, rd, 3, rs1, rs2, 0, 12)
+#  define AMOOR_D(rd, rs1, rs2)		R4type(47, rd, 3, rs1, rs2, 0, 8)
+#  define AMOMIN_D(rd, rs1, rs2)	R4type(47, rd, 3, rs1, rs2, 0, 16)
+#  define AMOMAX_D(rd, rs1, rs2)	R4type(47, rd, 3, rs1, rs2, 0, 20)
+#  define AMOMINU_D(rd, rs1, rs2)	R4type(47, rd, 3, rs1, rs2, 0, 24)
+#  define AMOMAXU_D(rd, rs1, rs2)	R4type(47, rd, 3, rs1, rs2, 0, 28)
+/*
+ * Pseudo Instructions
+ */
+#  define NOP()				ADDI(_ZERO_REGNO, _ZERO_REGNO, 0)
+#  define MV(r0, r1)			ADDI(r0, r1, 0)
+#  define NOT(r0, r1)			XORI(r0, r1, -1)
+#  define NEG(r0, r1)			SUB(r0, _ZERO_REGNO, r1)
+#  define NEGW(r0, r1)			SUBW(r0, _ZERO_REGNO, r1)
+#  define SEXT_W(r0, r1)		ADDIW(r0, r1, 0)
+#  define RET()				JALR(0, 1, 0)
+
+/*
+ * Enconding functions
+ */
+#  define Rtype(op, rd, fct, rs1, rs2, fct2)			\
+	_Rtype(_jit, op, rd, fct, rs1, rs2, fct2)
+static void _Rtype(jit_state_t*, int32_t, int32_t,
+		   int32_t, int32_t, int32_t, int32_t);
+#  define R4type(op, rd, fct, rs1,rs2,fct2,rs3)			\
+	_R4type(_jit, op, rd, fct, rs1, rs2, fct2, rs3)
+static void _R4type(jit_state_t*, int32_t, int32_t, int32_t,
+		    int32_t, int32_t, int32_t, int32_t);
+#  define Itype(op, rd, fct, rs1, imm)				\
+	_Itype(_jit, op, rd, fct, rs1, imm)
+static void _Itype(jit_state_t*, int32_t, int32_t,
+		   int32_t, int32_t, int32_t);
+#  if __WORDSIZE == 64
+#  define IStype(op, rd, fct, rs1, sh, imm)			\
+	_IStype(_jit, op, rd, fct, rs1, sh, imm)
+static void _IStype(jit_state_t*, int32_t, int32_t,
+		   int32_t, int32_t, int32_t,int32_t);
+#  endif
+#  define Stype(op, fct, rs1, rs2, imm)				\
+	_Stype(_jit, op, fct, rs1, rs2, imm)
+static void _Stype(jit_state_t*, int32_t, int32_t,
+		   int32_t, int32_t, int32_t);
+#  define Btype(op, fct, rs1, rs2, imm)				\
+	_Btype(_jit, op, fct, rs1, rs2, imm)
+static void _Btype(jit_state_t*, int32_t, int32_t,
+		   int32_t, int32_t, int32_t);
+#  define Utype(op, rd, imm)		_Utype(_jit, op, rd, imm)
+static void _Utype(jit_state_t*, int32_t, int32_t, int32_t);
+#  define Jtype(op, rd, imm)		_Jtype(_jit, op, rd, imm)
+static void _Jtype(jit_state_t*, int32_t, int32_t, int32_t);
+/*
+ * Lightning instructions
+ */
+#  define nop(im)			_nop(_jit, im)
+static void _nop(jit_state_t*, int32_t);
+#  define addr(r0, r1, r2)		ADD(r0, r1, r2)
+#  define addi(r0, r1, im)		_addi(_jit, r0, r1, im)
+static void _addi(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define addcr(r0, r1, r2)		_addcr(_jit, r0, r1, r2)
+static void _addcr(jit_state_t*,int32_t,int32_t,int32_t);
+#  define addci(r0, r1, im)		_addci(_jit, r0, r1, im)
+static void _addci(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define addxr(r0, r1, r2)		_addxr(_jit, r0, r1, r2)
+static void _addxr(jit_state_t*,int32_t,int32_t,int32_t);
+#  define addxi(r0, r1, im)		_addxi(_jit, r0, r1, im)
+static void _addxi(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define subr(r0, r1, r2)		SUB(r0, r1, r2)
+#  define subi(r0, r1, im)		_subi(_jit, r0, r1, im)
+static void _subi(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define subcr(r0, r1, r2)		_subcr(_jit, r0, r1, r2)
+static void _subcr(jit_state_t*,int32_t,int32_t,int32_t);
+#  define subci(r0, r1, im)		_subci(_jit, r0, r1, im)
+static void _subci(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define subxr(r0, r1, r2)		_subxr(_jit, r0, r1, r2)
+static void _subxr(jit_state_t*,int32_t,int32_t,int32_t);
+#  define subxi(r0, r1, im)		_subxi(_jit, r0, r1, im)
+static void _subxi(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define rsbi(r0, r1, im)		_rsbi(_jit, r0, r1, im)
+static void _rsbi(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define mulr(r0, r1, r2)		MUL(r0, r1, r2)
+#  define muli(r0, r1, im)		_muli(_jit, r0, r1, im)
+static void _muli(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define divr(r0, r1, r2)		DIV(r0, r1, r2)
+#  define divi(r0, r1, im)		_divi(_jit, r0, r1, im)
+static void _divi(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define divr_u(r0, r1, r2)		DIVU(r0, r1, r2)
+#  define divi_u(r0, r1, im)		_divi_u(_jit, r0, r1, im)
+static void _divi_u(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define remr(r0, r1, r2)		REM(r0, r1, r2)
+#  define remi(r0, r1, im)		_remi(_jit, r0, r1, im)
+static void _remi(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define remr_u(r0, r1, r2)		REMU(r0, r1, r2)
+#  define remi_u(r0, r1, im)		_remi_u(_jit, r0, r1, im)
+static void _remi_u(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define qmulr(r0, r1, r2, r3)		_qmulr(_jit,r0,r1,r2,r3)
+static void _qmulr(jit_state_t*,int32_t,int32_t,int32_t,int32_t);
+#  define qmuli(r0, r1, r2, i0)		_qmuli(_jit,r0,r1,r2,i0)
+static void _qmuli(jit_state_t*,int32_t,int32_t,int32_t,jit_word_t);
+#  define qmulr_u(r0, r1, r2, r3)	_qmulr_u(_jit,r0,r1,r2,r3)
+static void _qmulr_u(jit_state_t*,int32_t,int32_t,int32_t,int32_t);
+#  define qmuli_u(r0, r1, r2, i0)	_qmuli_u(_jit,r0,r1,r2,i0)
+static void _qmuli_u(jit_state_t*,int32_t,int32_t,int32_t,jit_word_t);
+static void _iqdivr(jit_state_t*,jit_bool_t,
+		    int32_t,int32_t,int32_t,int32_t);
+#  define qdivr(r0,r1,r2,r3)		_iqdivr(_jit,1,r0,r1,r2,r3)
+#  define qdivr_u(r0,r1,r2,r3)		_iqdivr(_jit,0,r0,r1,r2,r3)
+static void _iqdivr(jit_state_t*,jit_bool_t,
+		    int32_t,int32_t,int32_t,int32_t);
+#  define qdivi(r0,r1,r2,i0)		_qdivi(_jit,r0,r1,r2,i0)
+static void _qdivi(jit_state_t*,int32_t,
+		   int32_t,int32_t,jit_word_t);
+#  define qdivi_u(r0,r1,r2,i0)		_qdivi_u(_jit,r0,r1,r2,i0)
+static void _qdivi_u(jit_state_t*,int32_t,
+		     int32_t,int32_t,jit_word_t);
+#  define lshr(r0, r1, r2)		SLL(r0, r1, r2)
+#  define lshi(r0, r1, im)		_lshi(_jit, r0, r1, im)
+static void _lshi(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define rshr(r0, r1, r2)		SRA(r0, r1, r2)
+#  define rshi(r0, r1, im)		_rshi(_jit, r0, r1, im)
+static void _rshi(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define rshr_u(r0, r1, r2)		SRL(r0, r1, r2)
+#  define rshi_u(r0, r1, im)		_rshi_u(_jit, r0, r1, im)
+static void _rshi_u(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define negr(r0, r1)			NEG(r0, r1)
+#  define comr(r0, r1)			NOT(r0, r1)
+#  define andr(r0, r1, r2)		AND(r0, r1, r2)
+#  define andi(r0, r1, im)		_andi(_jit, r0, r1, im)
+static void _andi(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define orr(r0, r1, r2)		OR(r0, r1, r2)
+#  define ori(r0, r1, im)		_ori(_jit, r0, r1, im)
+static void _ori(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define xorr(r0, r1, r2)		XOR(r0, r1, r2)
+#  define xori(r0, r1, im)		_xori(_jit, r0, r1, im)
+static void _xori(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define ldr_c(r0, r1)			LB(r0, r1, 0)
+#  define ldi_c(r0, im)			_ldi_c(_jit, r0, im)
+static void _ldi_c(jit_state_t*,int32_t,jit_word_t);
+#  define ldr_uc(r0, r1)		LBU(r0, r1, 0)
+#  define ldi_uc(r0, im)		_ldi_uc(_jit, r0, im)
+static void _ldi_uc(jit_state_t*,int32_t,jit_word_t);
+#  define ldr_s(r0, r1)			LH(r0, r1, 0)
+#  define ldi_s(r0, im)			_ldi_s(_jit, r0, im)
+static void _ldi_s(jit_state_t*,int32_t,jit_word_t);
+#  define ldr_us(r0, r1)		LHU(r0, r1, 0)
+#  define ldi_us(r0, im)		_ldi_us(_jit, r0, im)
+static void _ldi_us(jit_state_t*,int32_t,jit_word_t);
+#  define ldr_i(r0, r1)			LW(r0, r1, 0)
+#  define ldi_i(r0, im)			_ldi_i(_jit, r0, im)
+static void _ldi_i(jit_state_t*,int32_t,jit_word_t);
+#  define ldr_ui(r0, r1)		LWU(r0, r1, 0)
+#  define ldi_ui(r0, im)		_ldi_ui(_jit, r0, im)
+static void _ldi_ui(jit_state_t*,int32_t,jit_word_t);
+#  define ldr_l(r0, r1)			LD(r0, r1, 0)
+#  define ldi_l(r0, im)			_ldi_l(_jit, r0, im)
+static void _ldi_l(jit_state_t*,int32_t,jit_word_t);
+#  define ldxr_c(r0, r1, r2)		_ldxr_c(_jit, r0, r1, r2)
+static void _ldxr_c(jit_state_t*,int32_t,int32_t,int32_t);
+#  define ldxi_c(r0, r1, im)		_ldxi_c(_jit, r0, r1, im)
+static void _ldxi_c(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define ldxr_uc(r0, r1, r2)		_ldxr_uc(_jit, r0, r1, r2)
+static void _ldxr_uc(jit_state_t*,int32_t,int32_t,int32_t);
+#  define ldxi_uc(r0, r1, im)		_ldxi_uc(_jit, r0, r1, im)
+static void _ldxi_uc(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define ldxr_s(r0, r1, r2)		_ldxr_s(_jit, r0, r1, r2)
+static void _ldxr_s(jit_state_t*,int32_t,int32_t,int32_t);
+#  define ldxi_s(r0, r1, im)		_ldxi_s(_jit, r0, r1, im)
+static void _ldxi_s(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define ldxr_us(r0, r1, r2)		_ldxr_us(_jit, r0, r1, r2)
+static void _ldxr_us(jit_state_t*,int32_t,int32_t,int32_t);
+#  define ldxi_us(r0, r1, im)		_ldxi_us(_jit, r0, r1, im)
+static void _ldxi_us(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define ldxr_i(r0, r1, r2)		_ldxr_i(_jit, r0, r1, r2)
+static void _ldxr_i(jit_state_t*,int32_t,int32_t,int32_t);
+#  define ldxi_i(r0, r1, im)		_ldxi_i(_jit, r0, r1, im)
+static void _ldxi_i(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define ldxr_ui(r0, r1, r2)		_ldxr_ui(_jit, r0, r1, r2)
+static void _ldxr_ui(jit_state_t*,int32_t,int32_t,int32_t);
+#  define ldxi_ui(r0, r1, im)		_ldxi_ui(_jit, r0, r1, im)
+static void _ldxi_ui(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define ldxr_l(r0, r1, r2)		_ldxr_l(_jit, r0, r1, r2)
+static void _ldxr_l(jit_state_t*,int32_t,int32_t,int32_t);
+#  define ldxi_l(r0, r1, im)		_ldxi_l(_jit, r0, r1, im)
+static void _ldxi_l(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define str_c(r0, r1)			SB(r0, r1, 0)
+#  define sti_c(im, r0)			_sti_c(_jit, im, r0)
+static void _sti_c(jit_state_t*,jit_word_t,int32_t);
+#  define str_s(r0, r1)			SH(r0, r1, 0)
+#  define sti_s(im, r0)			_sti_s(_jit, im, r0)
+static void _sti_s(jit_state_t*,jit_word_t,int32_t);
+#  define str_i(r0, r1)			SW(r0, r1, 0)
+#  define sti_i(im, r0)			_sti_i(_jit, im, r0)
+static void _sti_i(jit_state_t*,jit_word_t,int32_t);
+#  define str_l(r0, r1)			SD(r0, r1, 0)
+#  define sti_l(im, r0)			_sti_l(_jit, im, r0)
+static void _sti_l(jit_state_t*,jit_word_t,int32_t);
+#  define stxr_c(r0, r1, r2)		_stxr_c(_jit, r0, r1, r2)
+static void _stxr_c(jit_state_t*,int32_t,int32_t,int32_t);
+#  define stxi_c(i0, r0, r1)		_stxi_c(_jit, i0, r0, r1)
+static void _stxi_c(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define stxr_s(r0, r1, r2)		_stxr_s(_jit, r0, r1, r2)
+static void _stxr_s(jit_state_t*,int32_t,int32_t,int32_t);
+#  define stxi_s(i0, r0, r1)		_stxi_s(_jit, i0, r0, r1)
+static void _stxi_s(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define stxr_i(r0, r1, r2)		_stxr_i(_jit, r0, r1, r2)
+static void _stxr_i(jit_state_t*,int32_t,int32_t,int32_t);
+#  define stxi_i(i0, r0, r1)		_stxi_i(_jit, i0, r0, r1)
+static void _stxi_i(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define stxr_l(r0, r1, r2)		_stxr_l(_jit, r0, r1, r2)
+static void _stxr_l(jit_state_t*,int32_t,int32_t,int32_t);
+#  define stxi_l(i0, r0, r1)		_stxi_l(_jit, i0, r0, r1)
+static void _stxi_l(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define htonr_us(r0, r1)		_htonr_us(_jit, r0, r1)
+static void _htonr_us(jit_state_t*,int32_t,int32_t);
+#  define htonr_ui(r0, r1)		_htonr_ui(_jit, r0, r1)
+static void _htonr_ui(jit_state_t*,int32_t,int32_t);
+#  define htonr_ul(r0, r1)		_htonr_ul(_jit, r0, r1)
+static void _htonr_ul(jit_state_t*,int32_t,int32_t);
+#  define extr_c(r0, r1)		_extr_c(_jit, r0, r1)
+static void _extr_c(jit_state_t*,int32_t,int32_t);
+#  define extr_uc(r0, r1)		andi(r0, r1, 0xff)
+#  define extr_s(r0, r1)		_extr_s(_jit, r0, r1)
+static void _extr_s(jit_state_t*,int32_t,int32_t);
+#  define extr_us(r0, r1)		_extr_us(_jit, r0, r1)
+static void _extr_us(jit_state_t*,int32_t,int32_t);
+#  define extr_i(r0, r1)		SEXT_W(r0, r1)
+#  define extr_ui(r0, r1)		_extr_ui(_jit, r0, r1)
+static void _extr_ui(jit_state_t*,int32_t,int32_t);
+#  define movr(r0, r1)			MV(r0, r1)
+#  define movi(r0, im)			_movi(_jit, r0, im)
+static void _movi(jit_state_t*,int32_t,jit_word_t);
+#  define movi_p(r0, im)		_movi_p(_jit, r0, im)
+static jit_word_t _movi_p(jit_state_t*,int32_t,jit_word_t);
+#  define ltr(r0, r1, r2)		SLT(r0, r1, r2)
+#  define lti(r0, r1, im)		_lti(_jit, r0, r1, im)
+static void _lti(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define ltr_u(r0, r1, r2)		SLTU(r0, r1, r2)
+#  define lti_u(r0, r1, im)		_lti_u(_jit, r0, r1, im)
+static void _lti_u(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define ler(r0, r1, r2)		_ler(_jit, r0, r1, r2)
+static void _ler(jit_state_t*,int32_t,int32_t,int32_t);
+#  define lei(r0, r1, im)		_lei(_jit, r0, r1, im)
+static void _lei(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define ler_u(r0, r1, r2)		_ler_u(_jit, r0, r1, r2)
+static void _ler_u(jit_state_t*,int32_t,int32_t,int32_t);
+#  define lei_u(r0, r1, im)		_lei_u(_jit, r0, r1, im)
+static void _lei_u(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define eqr(r0, r1, r2)		_eqr(_jit, r0, r1, r2)
+static void _eqr(jit_state_t*,int32_t,int32_t,int32_t);
+#  define eqi(r0, r1, im)		_eqi(_jit, r0, r1, im)
+static void _eqi(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define ger(r0, r1, r2)		_ger(_jit, r0, r1, r2)
+static void _ger(jit_state_t*,int32_t,int32_t,int32_t);
+#  define gei(r0, r1, r2)		_gei(_jit, r0, r1, r2)
+static void _gei(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define ger_u(r0, r1, r2)		_ger_u(_jit, r0, r1, r2)
+static void _ger_u(jit_state_t*,int32_t,int32_t,int32_t);
+#  define gei_u(r0, r1, im)		_gei_u(_jit, r0, r1, im)
+static void _gei_u(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define gtr(r0, r1, r2)		SLT(r0, r2, r1)
+#  define gti(r0, r1, im)		_gti(_jit, r0, r1, im)
+static void _gti(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define gtr_u(r0, r1, r2)		SLTU(r0, r2, r1)
+#  define gti_u(r0, r1, im)		_gti_u(_jit, r0, r1, im)
+static void _gti_u(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define ner(r0, r1, r2)		_ner(_jit, r0, r1, r2)
+static void _ner(jit_state_t*,int32_t,int32_t,int32_t);
+#  define nei(r0, r1, im)		_nei(_jit, r0, r1, im)
+static void _nei(jit_state_t*,int32_t,int32_t,jit_word_t);
+#  define bltr(br, r0, r1)		_bltr(_jit, br, r0, r1)
+static jit_word_t _bltr(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define blti(br, r0, im)		_blti(_jit, br, r0, im)
+static jit_word_t _blti(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bltr_u(br, r0, r1)		_bltr_u(_jit, br, r0, r1)
+static jit_word_t _bltr_u(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define blti_u(br, r0, im)		_blti_u(_jit, br, r0, im)
+static jit_word_t _blti_u(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bler(br, r0, r1)		_bler(_jit, br, r0, r1)
+static jit_word_t _bler(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define blei(br, r0, im)		_blei(_jit, br, r0, im)
+static jit_word_t _blei(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bler_u(br, r0, r1)		_bler_u(_jit, br, r0, r1)
+static jit_word_t _bler_u(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define blei_u(br, r0, im)		_blei_u(_jit, br, r0, im)
+static jit_word_t _blei_u(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define beqr(br, r0, r1)		_beqr(_jit, br, r0, r1)
+static jit_word_t _beqr(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define beqi(br, r0, im)		_beqi(_jit, br, r0, im)
+static jit_word_t _beqi(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bger(br, r0, r1)		_bger(_jit, br, r0, r1)
+static jit_word_t _bger(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define bgei(br, r0, im)		_bgei(_jit, br, r0, im)
+static jit_word_t _bgei(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bger_u(br, r0, r1)		_bger_u(_jit, br, r0, r1)
+static jit_word_t _bger_u(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define bgei_u(br, r0, im)		_bgei_u(_jit, br, r0, im)
+static jit_word_t _bgei_u(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bgtr(br, r0, r1)		_bgtr(_jit, br, r0, r1)
+static jit_word_t _bgtr(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define bgti(br, r0, im)		_bgti(_jit, br, r0, im)
+static jit_word_t _bgti(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bgtr_u(br, r0, r1)		_bgtr_u(_jit, br, r0, r1)
+static jit_word_t _bgtr_u(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define bgti_u(br, r0, im)		_bgti_u(_jit, br, r0, im)
+static jit_word_t _bgti_u(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bner(br, r0, r1)		_bner(_jit, br, r0, r1)
+static jit_word_t _bner(jit_state_t*,jit_word_t,int32_t,int32_t);
+#  define bnei(br, r0, im)		_bnei(_jit, br, r0, im)
+static jit_word_t _bnei(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define boaddr(br, r0, r1)		_boaddr(_jit, br, r0, r1)
+#  define boaddi(br, r0, im)		_boaddi(_jit, br, r0, im)
+static jit_word_t _boaddr(jit_state_t*,jit_word_t,int32_t,int32_t);
+static jit_word_t _boaddi(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define boaddr_u(br, r0, r1)		_boaddr_u(_jit, br, r0, r1)
+#  define boaddi_u(br, r0, im)		_boaddi_u(_jit, br, r0, im)
+static jit_word_t _boaddr_u(jit_state_t*,jit_word_t,int32_t,int32_t);
+static jit_word_t _boaddi_u(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bxaddr(br, r0, r1)		_bxaddr(_jit, br, r0, r1)
+#  define bxaddi(br, r0, im)		_bxaddi(_jit, br, r0, im)
+static jit_word_t _bxaddr(jit_state_t*,jit_word_t,int32_t,int32_t);
+static jit_word_t _bxaddi(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bxaddr_u(br, r0, r1)		_bxaddr_u(_jit, br, r0, r1)
+#  define bxaddi_u(br, r0, im)		_bxaddi_u(_jit, br, r0, im)
+static jit_word_t _bxaddr_u(jit_state_t*,jit_word_t,int32_t,int32_t);
+static jit_word_t _bxaddi_u(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bosubr(br, r0, r1)		_bosubr(_jit, br, r0, r1)
+#  define bosubi(br, r0, im)		_bosubi(_jit, br, r0, im)
+static jit_word_t _bosubr(jit_state_t*,jit_word_t,int32_t,int32_t);
+static jit_word_t _bosubi(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bosubr_u(br, r0, r1)		_bosubr_u(_jit, br, r0, r1)
+#  define bosubi_u(br, r0, im)		_bosubi_u(_jit, br, r0, im)
+static jit_word_t _bosubr_u(jit_state_t*,jit_word_t,int32_t,int32_t);
+static jit_word_t _bosubi_u(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bxsubr(br, r0, r1)		_bxsubr(_jit, br, r0, r1)
+#  define bxsubi(br, r0, im)		_bxsubi(_jit, br, r0, im)
+static jit_word_t _bxsubr(jit_state_t*,jit_word_t,int32_t,int32_t);
+static jit_word_t _bxsubi(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bxsubr_u(br, r0, r1)		_bxsubr_u(_jit, br, r0, r1)
+#  define bxsubi_u(br, r0, im)		_bxsubi_u(_jit, br, r0, im)
+static jit_word_t _bxsubr_u(jit_state_t*,jit_word_t,int32_t,int32_t);
+static jit_word_t _bxsubi_u(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bmsr(br, r0, r1)		_bmsr(_jit, br, r0, r1)
+#  define bmsi(br, r0, im)		_bmsi(_jit, br, r0, im)
+static jit_word_t _bmsr(jit_state_t*,jit_word_t,int32_t,int32_t);
+static jit_word_t _bmsi(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define bmcr(br, r0, r1)		_bmcr(_jit, br, r0, r1)
+#  define bmci(br, r0, im)		_bmci(_jit, br, r0, im)
+static jit_word_t _bmcr(jit_state_t*,jit_word_t,int32_t,int32_t);
+static jit_word_t _bmci(jit_state_t*,jit_word_t,int32_t,jit_word_t);
+#  define jmpr(r0)			JALR(_ZERO_REGNO, r0, 0)
+#  define jmpi(im)			_jmpi(_jit, im)
+static void _jmpi(jit_state_t*,jit_word_t);
+#  define jmpi_p(im)			_jmpi_p(_jit, im)
+static jit_word_t _jmpi_p(jit_state_t*,jit_word_t);
+#  define callr(r0)			JALR(_RA_REGNO, r0, 0)
+#  define calli(im)			_calli(_jit, im)
+static void _calli(jit_state_t*,jit_word_t);
+#  define calli_p(im)		_calli_p(_jit, im)
+static jit_word_t _calli_p(jit_state_t*,jit_word_t);
+#  define prolog(i0)			_prolog(_jit,i0)
+static void _prolog(jit_state_t*,jit_node_t*);
+#  define epilog(i0)			_epilog(_jit,i0)
+static void _epilog(jit_state_t*,jit_node_t*);
+#  define vastart(r0)			_vastart(_jit, r0)
+static void _vastart(jit_state_t*, int32_t);
+#  define vaarg(r0, r1)			_vaarg(_jit, r0, r1)
+static void _vaarg(jit_state_t*, int32_t, int32_t);
+#define patch_abs(instr,label)		_patch_at(_jit,instr,label)
+#define patch_at(instr,label)		_patch_at(_jit,instr,label)
+static void _patch_at(jit_state_t*,jit_word_t,jit_word_t);
+#endif		/* PROTO */
+
+#if CODE
+static void
+_Rtype(jit_state_t *_jit, int32_t op, int32_t rd,
+       int32_t fct, int32_t rs1, int32_t rs2, int32_t fct2)
+{
+    instr_t	i;
+    assert(!(op   & ~0x7f));
+    assert(!(rd   & ~0x1f));
+    assert(!(fct  & ~0x07));
+    assert(!(rs1  & ~0x1f));
+    assert(!(rs2  & ~0x1f));
+    assert(!(fct2 & ~0x7f));
+    i.R.opcode	= op;
+    i.R.rd	= rd;
+    i.R.funct3	= fct;
+    i.R.rs1	= rs1;
+    i.R.rs2	= rs2;
+    i.R.funct7	= fct2;
+    ii(i.w);
+}
+
+static void
+_R4type(jit_state_t *_jit, int32_t op, int32_t rd, int32_t fct,
+	int32_t rs1, int32_t rs2, int32_t fct2, int32_t rs3)
+{
+    instr_t	i;
+    assert(!(op   & ~0x7f));
+    assert(!(rd   & ~0x1f));
+    assert(!(fct  & ~0x07));
+    assert(!(rs1  & ~0x1f));
+    assert(!(rs2  & ~0x1f));
+    assert(!(fct2 & ~0x03));
+    assert(!(rs3  & ~0x1f));
+    i.R4.opcode	= op;
+    i.R4.rd	= rd;
+    i.R4.funct3	= fct;
+    i.R4.rs1	= rs1;
+    i.R4.rs2	= rs2;
+    i.R4.funct2	= fct2;
+    i.R4.rs3	= rs3;
+    ii(i.w);
+}
+
+static void
+_Itype(jit_state_t *_jit, int32_t op, int32_t rd,
+       int32_t fct, int32_t rs1, int32_t imm)
+{
+    instr_t	i;
+    assert(!(op  &  ~0x7f));
+    assert(!(rd  &  ~0x1f));
+    assert(!(fct &  ~0x07));
+    assert(!(rs1 &  ~0x1f));
+    assert(simm12_p(imm));
+    i.I.opcode	= op;
+    i.I.rd	= rd;
+    i.I.funct3	= fct;
+    i.I.rs1	= rs1;
+    i.I.imm11_0	= imm;
+    ii(i.w);
+}
+
+#  if __WORDSIZE == 64
+static void
+_IStype(jit_state_t *_jit, int32_t op, int32_t rd,
+       int32_t fct, int32_t rs1, int32_t sh, int32_t imm)
+{
+    instr_t	i;
+    assert(!(op  &  ~0x7f));
+    assert(!(rd  &  ~0x1f));
+    assert(!(fct &  ~0x07));
+    assert(!(rs1 &  ~0x1f));
+    assert(!(sh  &  ~0x3f));
+    assert(simm6_p(imm));
+    i.IS.opcode	= op;
+    i.IS.rd	= rd;
+    i.IS.funct3	= fct;
+    i.IS.rs1	= rs1;
+    i.IS.shamt	= sh;
+    i.IS.imm6_0 = imm;
+    ii(i.w);
+}
+#  endif
+
+static void
+_Stype(jit_state_t *_jit, int32_t op, int32_t fct,
+       int32_t rs1, int32_t rs2, int32_t imm)
+{
+    instr_t	i;
+    assert(!(op  &  ~0x7f));
+    assert(!(fct &  ~0x07));
+    assert(!(rs1 &  ~0x1f));
+    assert(!(rs2 &  ~0x1f));
+    assert(simm12_p(imm));
+    i.S.opcode	= op;
+    i.S.imm4_0	= imm & 0x1f;
+    i.S.funct3	= fct;
+    i.S.rs1	= rs1;
+    i.S.rs2	= rs2;
+    i.S.imm11_5	= (imm >> 5) & 0x7f;
+    ii(i.w);
+}
+
+static void
+_Btype(jit_state_t *_jit, int32_t op, int32_t fct,
+       int32_t rs1, int32_t rs2, int32_t imm)
+{
+    instr_t	i;
+    assert(!(op  & ~0x7f));
+    assert(!(fct & ~0x07));
+    assert(!(rs1 & ~0x1f));
+    assert(!(rs2 & ~0x1f));
+    assert(!(imm & 1) && simm12_p(imm));
+    i.B.opcode	= op;
+    i.B.imm11	= (imm >> 11) & 0x1;
+    i.B.imm4_1	= (imm >>  1) & 0xf;
+    i.B.funct3	= fct;
+    i.B.rs1	= rs1;
+    i.B.rs2	= rs2;
+    i.B.imm10_5	= (imm >>  5) & 0x3f;
+    i.B.imm12	= (imm >> 12) & 0x1;
+    ii(i.w);
+}
+
+static void
+_Utype(jit_state_t *_jit, int32_t op, int32_t rd, int32_t imm)
+{
+    instr_t	i;
+    assert(!(op	& ~0x7f));
+    assert(!(rd	& ~0x1f));
+    assert(simm20_p(imm));
+    i.U.opcode	= op;
+    i.U.rd	= rd;
+    i.U.imm12_31= imm;
+    ii(i.w);
+}
+
+static void
+_Jtype(jit_state_t *_jit, int32_t op, int32_t rd, int32_t imm)
+{
+    instr_t	i;
+    assert(!(op & ~0x7f));
+    assert(!(rd & ~0x1f));
+    assert(!(imm & 1) && imm <= 1048575 && imm >= -1048576);
+    i.J.opcode	= op;
+    i.J.rd	= rd;
+    i.J.imm19_12= (imm >> 12) &  0xff;
+    i.J.imm11	= (imm >> 11) &   0x1;
+    i.J.imm10_1	= (imm >>  1) & 0x3ff;
+    i.J.imm20	= (imm >> 20) &   0x1;
+    ii(i.w);
+}
+
+static void
+_nop(jit_state_t *_jit, int32_t im)
+{
+    for (; im > 0; im -= 4)
+	NOP();
+    assert(im == 0);
+}
+
+static void
+_addi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    if (simm12_p(i0))
+	ADDI(r0, r1, i0);
+    else {
+	int32_t	t0;
+	t0 = jit_get_reg(jit_class_gpr);
+	movi(rn(t0), i0);
+	addr(r0, r1, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_addcr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
+{
+    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, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    int32_t		t0;
+    if (jit_carry == _NOREG)
+	jit_carry = jit_get_reg(jit_class_gpr);
+    if (r0 == r1) {
+	t0 = jit_get_reg(jit_class_gpr);
+	addi(rn(t0), r1, i0);
+	SLTU(rn(jit_carry), rn(t0), r1);
+	movr(r0, rn(t0));
+	jit_unget_reg(t0);
+    }
+    else {
+	addi(r0, r1, i0);
+	SLTU(rn(jit_carry), r0, r1);
+    }
+}
+
+static void
+_addxr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
+{
+    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, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    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, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    if (simm12_p(-i0))
+	ADDI(r0, r1, -i0);
+    else {
+	int32_t	t0;
+	t0 = jit_get_reg(jit_class_gpr);
+	movi(rn(t0), i0);
+	subr(r0, r1, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_subcr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
+{
+    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, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    int32_t		t0;
+    if (jit_carry == _NOREG)
+	jit_carry = jit_get_reg(jit_class_gpr);
+    if (r0 == r1) {
+	t0 = jit_get_reg(jit_class_gpr);
+	subi(rn(t0), r1, i0);
+	SLTU(rn(jit_carry), r1, rn(t0));
+	movr(r0, rn(t0));
+	jit_unget_reg(t0);
+    }
+    else {
+	subi(r0, r1, i0);
+	SLTU(rn(jit_carry), r1, r0);
+    }
+}
+
+static void
+_subxr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
+{
+    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, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    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, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    subi(r0, r1, i0);
+    negr(r0, r0);
+}
+
+static void
+_muli(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    movi(rn(t0), i0);
+    mulr(r0, r1, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_divi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    movi(rn(t0), i0);
+    divr(r0, r1, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_divi_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    movi(rn(t0), i0);
+    divr_u(r0, r1, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_remi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    movi(rn(t0), i0);
+    remr(r0, r1, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_remi_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    movi(rn(t0), i0);
+    remr_u(r0, r1, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_qmulr(jit_state_t *_jit, int32_t r0,
+       int32_t r1, int32_t r2, int32_t r3)
+{
+    int32_t		t0;
+    if (r0 == r2 || r0 == r3) {
+	t0 = jit_get_reg(jit_class_gpr);
+	mulr(rn(t0), r2, r3);
+    }
+    else
+	mulr(r0, r2, r3);
+    MULH(r1, r2, r3);
+    if (r0 == r2 || r0 == r3) {
+	movr(r0, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_qmuli(jit_state_t *_jit, int32_t r0,
+       int32_t r1, int32_t r2, jit_word_t i0)
+{
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    movi(rn(t0), i0);
+    qmulr(r0, r1, r2, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_qmulr_u(jit_state_t *_jit, int32_t r0,
+	 int32_t r1, int32_t r2, int32_t r3)
+{
+    int32_t		t0;
+    if (r0 == r2 || r0 == r3) {
+	t0 = jit_get_reg(jit_class_gpr);
+	mulr(rn(t0), r2, r3);
+    }
+    else
+	mulr(r0, r2, r3);
+    MULHU(r1, r2, r3);
+    if (r0 == r2 || r0 == r3) {
+	movr(r0, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_qmuli_u(jit_state_t *_jit, int32_t r0,
+	 int32_t r1, int32_t r2, jit_word_t i0)
+{
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    movi(rn(t0), i0);
+    qmulr_u(r0, r1, r2, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_iqdivr(jit_state_t *_jit, jit_bool_t sign,
+	int32_t r0, int32_t r1, int32_t r2, int32_t r3)
+{
+    int32_t		sv0, rg0;
+    int32_t		sv1, rg1;
+    if (r0 == r2 || r0 == r3) {
+	sv0 = jit_get_reg(jit_class_gpr);
+	rg0 = rn(sv0);
+    }
+    else
+	rg0 = r0;
+    if (r1 == r2 || r1 == r3) {
+	sv1 = jit_get_reg(jit_class_gpr);
+	rg1 = rn(sv1);
+    }
+    else
+	rg1 = r1;
+    if (sign)
+	divr(rg0, r2, r3);
+    else
+	divr_u(rg0, r2, r3);
+    mulr(rg1, r3, rg0);
+    subr(rg1, r2, rg1);
+    if (rg0 != r0) {
+	movr(r0, rg0);
+	jit_unget_reg(sv0);
+    }
+    if (rg1 != r1) {
+	movr(r1, rg1);
+	jit_unget_reg(sv1);
+    }
+}
+
+static void
+_qdivi(jit_state_t *_jit, int32_t r0,
+       int32_t r1, int32_t r2, jit_word_t i0)
+{
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    movi(rn(t0), i0);
+    qdivr(r0, r1, r2, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_qdivi_u(jit_state_t *_jit, int32_t r0,
+	 int32_t r1, int32_t r2, jit_word_t i0)
+{
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    movi(rn(t0), i0);
+    qdivr_u(r0, r1, r2, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_lshi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    if (i0 == 0)
+	movr(r0, r1);
+    else {
+	assert(i0 > 0 && i0 < 64);
+	SLLI(r0, r1, i0);
+    }
+}
+
+static void
+_rshi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    if (i0 == 0)
+	movr(r0, r1);
+    else {
+	assert(i0 > 0 && i0 < 64);
+	SRAI(r0, r1, i0);
+    }
+}
+
+static void
+_rshi_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    if (i0 == 0)
+	movr(r0, r1);
+    else {
+	assert(i0 > 0 && i0 < 64);
+	SRLI(r0, r1, i0);
+    }
+}
+
+static void
+_andi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    if (simm12_p(i0))
+	ANDI(r0, r1, i0);
+    else {
+	int32_t	t0;
+	t0 = jit_get_reg(jit_class_gpr);
+	movi(rn(t0), i0);
+	andr(r0, r1, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_ori(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    if (simm12_p(i0))
+	ORI(r0, r1, i0);
+    else {
+	int32_t	t0;
+	t0 = jit_get_reg(jit_class_gpr);
+	movi(rn(t0), i0);
+	orr(r0, r1, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_xori(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    if (simm12_p(i0))
+	XORI(r0, r1, i0);
+    else {
+	int32_t	t0;
+	t0 = jit_get_reg(jit_class_gpr);
+	movi(rn(t0), i0);
+	xorr(r0, r1, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+#  define DEFLD(T,O)							\
+static void								\
+_ldi_##T(jit_state_t *_jit, int32_t r0, jit_word_t i0)		\
+{									\
+    if (simm12_p(i0))							\
+	L##O(r0, _ZERO_REGNO, i0);					\
+    else {								\
+	int32_t	t0;						\
+	t0 = jit_get_reg(jit_class_gpr);				\
+	movi(rn(t0), i0);						\
+	ldr_##T(r0, rn(t0));						\
+	jit_unget_reg(t0);						\
+    }									\
+}									\
+									\
+static void								\
+_ldxr_##T(jit_state_t *_jit,int32_t r0,int32_t r1,int32_t r2)\
+{									\
+    int32_t	t0;							\
+    t0 = jit_get_reg(jit_class_gpr);					\
+    addr(rn(t0), r1, r2);						\
+    ldr_##T(r0, rn(t0));						\
+    jit_unget_reg(t0);							\
+}									\
+									\
+static void								\
+_ldxi_##T(jit_state_t *_jit,int32_t r0,int32_t r1,jit_word_t i0)\
+{									\
+    if (simm12_p(i0))							\
+	L##O(r0, r1, i0);						\
+    else {								\
+	int32_t	t0;						\
+	t0 = jit_get_reg(jit_class_gpr);				\
+	addi(rn(t0), r1, i0);						\
+	ldr_##T(r0, rn(t0));						\
+	jit_unget_reg(t0);						\
+    }									\
+}
+
+DEFLD(c,B)
+DEFLD(uc,BU)
+DEFLD(s,H)
+DEFLD(us,HU)
+DEFLD(i,W)
+DEFLD(ui,WU)
+DEFLD(l,D)
+
+#  define DEFST(T, O)							\
+static void								\
+_sti_##T(jit_state_t *_jit, jit_word_t i0, int32_t r0)		\
+{									\
+    if (simm12_p(i0))							\
+	S##O(_ZERO_REGNO, r0, i0);					\
+    else {								\
+	int32_t	t0;						\
+	t0 = jit_get_reg(jit_class_gpr);				\
+	movi(rn(t0), i0);						\
+	str_##T(rn(t0), r0);						\
+	jit_unget_reg(t0);						\
+    }									\
+}									\
+									\
+static void								\
+_stxr_##T(jit_state_t *_jit,int32_t r0,int32_t r1,int32_t r2)\
+{									\
+    int32_t	t0;							\
+    t0 = jit_get_reg(jit_class_gpr);					\
+    addr(rn(t0), r0, r1);						\
+    str_##T(rn(t0), r2);						\
+    jit_unget_reg(t0);							\
+}									\
+									\
+static void								\
+_stxi_##T(jit_state_t *_jit,jit_word_t i0,int32_t r0,int32_t r1)\
+{									\
+    if (simm12_p(i0))							\
+	S##O(r0, r1, i0);						\
+    else {								\
+	int32_t	t0;						\
+	t0 = jit_get_reg(jit_class_gpr);				\
+	addi(rn(t0), r0, i0);						\
+	str_##T(rn(t0), r1);						\
+	jit_unget_reg(t0);						\
+    }									\
+}
+
+DEFST(c, B)
+DEFST(s, H)
+DEFST(i, W)
+DEFST(l, D)
+
+static void
+_htonr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
+{
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    rshi(rn(t0), r1, 8);
+    andi(r0, r1, 0xff);
+    andi(rn(t0), rn(t0), 0xff);
+    lshi(r0, r0, 8);
+    orr(r0, r0, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_htonr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
+{
+    int32_t		t0;
+    int32_t		t1;
+    int32_t		t2;
+    t0 = jit_get_reg(jit_class_gpr);
+    t1 = jit_get_reg(jit_class_gpr);
+    t2 = jit_get_reg(jit_class_gpr);
+    rshi(rn(t0), r1, 24);
+    rshi(rn(t1), r1, 16);
+    rshi(rn(t2), r1,  8);
+    andi(rn(t0), rn(t0), 0xff);
+    andi(rn(t1), rn(t1), 0xff);
+    andi(rn(t2), rn(t2), 0xff);
+    andi(r0, r1, 0xff);
+    lshi(r0, r0, 24);
+    lshi(rn(t1), rn(t1), 8);
+    orr(r0, r0, rn(t0));
+    lshi(rn(t2), rn(t2), 16);
+    orr(r0, r0, rn(t1));
+    orr(r0, r0, rn(t2));
+    jit_unget_reg(t2);
+    jit_unget_reg(t1);
+    jit_unget_reg(t0);
+}
+
+static void
+_htonr_ul(jit_state_t *_jit, int32_t r0, int32_t r1)
+{
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    rshi_u(rn(t0), r1, 32);
+    htonr_ui(r0, r1);
+    htonr_ui(rn(t0), rn(t0));
+    lshi(r0, r0, 32);
+    orr(r0, r0, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_extr_c(jit_state_t *_jit, int32_t r0, int32_t r1)
+{
+    lshi(r0, r1, 56);
+    rshi(r0, r0, 56);
+}
+
+static void
+_extr_s(jit_state_t *_jit, int32_t r0, int32_t r1)
+{
+    lshi(r0, r1, 48);
+    rshi(r0, r0, 48);
+}
+
+static void
+_extr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
+{
+    lshi(r0, r1, 48);
+    rshi_u(r0, r0, 48);
+}
+
+static void
+_extr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
+{
+    lshi(r0, r1, 32);
+    rshi_u(r0, r0, 32);
+}
+
+static void
+_movi(jit_state_t *_jit, int32_t r0, jit_word_t i0)
+{
+    if (simm32_p(i0)) {
+	int32_t	lo = (int32_t)i0 << 20 >> 20;
+	int32_t	hi = i0 - lo;
+	if (hi) {
+	    LUI(r0, hi >> 12);
+	    if (lo)
+		ADDIW(r0, r0, lo);
+	}
+	else
+	    ADDIW(r0, _ZERO_REGNO, lo);
+    }
+    else {
+	int32_t	lo = i0 << 32 >> 32;
+	jit_word_t	hi = i0 - lo;
+	int32_t	t0 = jit_get_reg(jit_class_gpr);
+	movi(rn(t0), (int32_t)(hi >> 32));
+	movi(r0, lo);
+	lshi(rn(t0), rn(t0), 32);
+	addr(r0, r0, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static jit_word_t
+_movi_p(jit_state_t *_jit, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    int32_t		ww = i0 << 32 >> 32;
+    int32_t		lo = ww << 20 >> 20;
+    int32_t		hi = ww - lo;
+    w = _jit->pc.w;
+    t0 = jit_get_reg(jit_class_gpr);
+    LUI(r0, hi >> 12);
+    ADDIW(r0, r0, lo);
+    ww = i0 >> 32;
+    lo = ww << 20 >> 20;
+    hi = ww - lo;
+    LUI(rn(t0), hi >> 12);
+    ADDIW(rn(t0), rn(t0), lo);
+    SLLI(rn(t0), rn(t0), 32);
+    ADD(r0, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static void
+_lti(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    if (simm12_p(i0))
+	SLTI(r0, r1, i0);
+    else {
+	int32_t	t0;
+	t0 = jit_get_reg(jit_class_gpr);
+	movi(r0, i0);
+	ltr(r0, r1, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_lti_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    if (simm12_p(i0))
+	SLTIU(r0, r1, i0);
+    else {
+	int32_t	t0;
+	t0 = jit_get_reg(jit_class_gpr);
+	movi(r0, i0);
+	ltr_u(r0, r1, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_ler(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
+{
+    SLT(r0, r2, r1);
+    XORI(r0, r0, 1);
+}
+
+static void
+_lei(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    int32_t		t0;
+    if (i0 == 0) {
+	SLT(r0, _ZERO_REGNO, r1);
+	XORI(r0, r0, 1);
+    }
+    else {
+	t0 = jit_get_reg(jit_class_gpr);
+	movi(rn(t0), i0);
+	ler(r0, r1, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_ler_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
+{
+    SLTU(r0, r2, r1);
+    XORI(r0, r0, 1);
+}
+
+static void
+_lei_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    int32_t		t0;
+    if (i0 == 0) {
+	SLTU(r0, _ZERO_REGNO, r1);
+	XORI(r0, r0, 1);
+    }
+    else {
+	t0 = jit_get_reg(jit_class_gpr);
+	movi(rn(t0), i0);
+	ler_u(r0, r1, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_eqr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
+{
+    subr(r0, r1, r2);
+    SLTU(r0, _ZERO_REGNO, r0);
+    XORI(r0, r0, 1);
+}
+
+static void
+_eqi(jit_state_t *_jit, int32_t r0, 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, int32_t r0, int32_t r1, int32_t r2)
+{
+    SLT(r0, r1, r2);
+    XORI(r0, r0, 1);
+}
+
+static void
+_gei(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    movi(rn(t0), i0);
+    ger(r0, r1, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_ger_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
+{
+    SLTU(r0, r1, r2);
+    XORI(r0, r0, 1);
+}
+
+static void
+_gei_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    movi(rn(t0), i0);
+    ger_u(r0, r1, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_gti(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    int32_t	t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    movi(r0, i0);
+    ltr(r0, rn(t0), r1);
+    jit_unget_reg(t0);
+}
+
+static void
+_gti_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    int32_t	t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    movi(r0, i0);
+    ltr_u(r0, rn(t0), r1);
+    jit_unget_reg(t0);
+}
+
+static void
+_ner(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
+{
+    subr(r0, r1, r2);
+    SLTU(r0, _ZERO_REGNO, r0);
+}
+
+static void
+_nei(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    if (i0) {
+	subi(r0, r1, i0);
+	SLTU(r0, _ZERO_REGNO, r0);
+    }
+    else
+	SLTU(r0, _ZERO_REGNO, r1);
+}
+
+static jit_word_t
+_bltr(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    w = _jit->pc.w;
+    BLT(r0, r1, br - w);
+    return (w);
+}
+
+static jit_word_t
+_blti(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    jit_reg_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bltr(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bltr_u(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    w = _jit->pc.w;
+    BLTU(r0, r1, br - w);
+    return (w);
+}
+
+static jit_word_t
+_blti_u(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    jit_reg_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bltr_u(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bler(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    w = _jit->pc.w;
+    BGE(r1, r0, br - w);
+    return (w);
+}
+
+static jit_word_t
+_blei(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    jit_reg_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bler(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bler_u(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    w = _jit->pc.w;
+    BGEU(r1, r0, br - w);
+    return (w);
+}
+
+static jit_word_t
+_blei_u(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    jit_reg_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bler_u(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_beqr(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    w = _jit->pc.w;
+    BEQ(r1, r0, br - w);
+    return (w);
+}
+
+static jit_word_t
+_beqi(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    jit_reg_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = beqr(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bger(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    w = _jit->pc.w;
+    BGE(r0, r1, br - w);
+    return (w);
+}
+
+static jit_word_t
+_bgei(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    jit_reg_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bger(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bger_u(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    w = _jit->pc.w;
+    BGEU(r0, r1, br - w);
+    return (w);
+}
+
+static jit_word_t
+_bgei_u(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    jit_reg_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bger_u(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bgtr(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    w = _jit->pc.w;
+    BLT(r1, r0, br - w);
+    return (w);
+}
+
+static jit_word_t
+_bgti(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    jit_reg_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bgtr(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bgtr_u(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    w = _jit->pc.w;
+    BLTU(r1, r0, br - w);
+    return (w);
+}
+
+static jit_word_t
+_bgti_u(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    jit_reg_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bgtr_u(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bner(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    w = _jit->pc.w;
+    BNE(r1, r0, br - w);
+    return (w);
+}
+
+static jit_word_t
+_bnei(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    jit_reg_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bner(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_boaddr(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w, jal;
+    int32_t		t0, t1;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    /* t0 = r1 < 0; */
+    SLT(rn(t0), r1, _ZERO_REGNO);
+    /* t1 = r0 */
+    movr(rn(t1), r0);
+    /* r0 = r0 + r1 */
+    addr(r0, r0, r1);
+    /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */
+    w = _jit->pc.w;
+    BNE(rn(t0), _ZERO_REGNO, 0);
+    /* r1 >= 0 */
+    SLT(rn(t1), r0, rn(t1));
+    jal = _jit->pc.w;
+    JAL(_ZERO_REGNO, 0);
+    /* r1 < 0 */
+    patch_at(w, _jit->pc.w);
+    SLT(rn(t1), rn(t1), r0);
+    /**/
+    patch_at(jal, _jit->pc.w);
+    w = _jit->pc.w;
+    BNE(rn(t1), _ZERO_REGNO, br - w);
+    jit_unget_reg(t1);
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_boaddi(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = boaddr(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_boaddr_u(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    int32_t		t0, t1;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    addr(rn(t0), r0, r1);
+    SLTU(rn(t1), rn(t0), r0);
+    movr(r0, rn(t0));
+    w = _jit->pc.w;
+    BNE(_ZERO_REGNO, rn(t1), br - w);
+    jit_unget_reg(t1);
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_boaddi_u(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = boaddr_u(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bxaddr(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w, jal;
+    int32_t		t0, t1;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    /* t0 = r1 < 0; */
+    SLT(rn(t0), r1, _ZERO_REGNO);
+    /* t1 = r0 */
+    movr(rn(t1), r0);
+    /* r0 = r0 + r1 */
+    addr(r0, r0, r1);
+    /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */
+    w = _jit->pc.w;
+    BNE(rn(t0), _ZERO_REGNO, 0);
+    /* r1 >= 0 */
+    SLT(rn(t1), r0, rn(t1));
+    jal = _jit->pc.w;
+    JAL(_ZERO_REGNO, 0);
+    /* r1 < 0 */
+    patch_at(w, _jit->pc.w);
+    SLT(rn(t1), rn(t1), r0);
+    /**/
+    patch_at(jal, _jit->pc.w);
+    w = _jit->pc.w;
+    BEQ(rn(t1), _ZERO_REGNO, br - w);
+    jit_unget_reg(t1);
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bxaddi(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bxaddr(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bxaddr_u(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    int32_t		t0, t1;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    addr(rn(t0), r0, r1);
+    SLTU(rn(t1), rn(t0), r0);
+    movr(r0, rn(t0));
+    w = _jit->pc.w;
+    BEQ(_ZERO_REGNO, rn(t1), br - w);
+    jit_unget_reg(t1);
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bxaddi_u(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bxaddr_u(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bosubr(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w, jal;
+    int32_t		t0, t1;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    /* t0 = 0 < r1; */
+    SLT(rn(t0), _ZERO_REGNO, r1);
+    /* t1 = r0 */
+    movr(rn(t1), r0);
+    /* r0 = r0 - r1 */
+    subr(r0, r0, r1);
+    /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */
+    w = _jit->pc.w;
+    BNE(rn(t0), _ZERO_REGNO, 0);
+    /* r1 >= 0 */
+    SLT(rn(t1), r0, rn(t1));
+    jal = _jit->pc.w;
+    JAL(_ZERO_REGNO, 0);
+    /* r1 < 0 */
+    patch_at(w, _jit->pc.w);
+    SLT(rn(t1), rn(t1), r0);
+    /**/
+    patch_at(jal, _jit->pc.w);
+    w = _jit->pc.w;
+    BNE(rn(t1), _ZERO_REGNO, br - w);
+    jit_unget_reg(t1);
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bosubi(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bosubr(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bosubr_u(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    int32_t		t0, t1;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    subr(rn(t0), r0, r1);
+    SLTU(rn(t1), r0, rn(t0));
+    movr(r0, rn(t0));
+    w = _jit->pc.w;
+    BNE(_ZERO_REGNO, rn(t1), br - w);
+    jit_unget_reg(t1);
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bosubi_u(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bosubr_u(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bxsubr(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w, jal;
+    int32_t		t0, t1;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    /* t0 = r1 < 0; */
+    SLT(rn(t0), _ZERO_REGNO, r1);
+    /* t1 = r0 */
+    movr(rn(t1), r0);
+    /* r0 = r0 - r1 */
+    subr(r0, r0, r1);
+    /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */
+    w = _jit->pc.w;
+    BNE(rn(t0), _ZERO_REGNO, 0);
+    /* r1 >= 0 */
+    SLT(rn(t1), r0, rn(t1));
+    jal = _jit->pc.w;
+    JAL(_ZERO_REGNO, 0);
+    /* r1 < 0 */
+    patch_at(w, _jit->pc.w);
+    SLT(rn(t1), rn(t1), r0);
+    /**/
+    patch_at(jal, _jit->pc.w);
+    w = _jit->pc.w;
+    BEQ(rn(t1), _ZERO_REGNO, br - w);
+    jit_unget_reg(t1);
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bxsubi(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bxsubr(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bxsubr_u(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    int32_t		t0, t1;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    subr(rn(t0), r0, r1);
+    SLTU(rn(t1), r0, rn(t0));
+    movr(r0, rn(t0));
+    w = _jit->pc.w;
+    BEQ(_ZERO_REGNO, rn(t1), br - w);
+    jit_unget_reg(t1);
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bxsubi_u(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bxsubr_u(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bmsr(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    AND(rn(t0), r0, r1);
+    w = _jit->pc.w;
+    BNE(_ZERO_REGNO, rn(t0), br - w);
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bmsi(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bmsr(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bmcr(jit_state_t *_jit, jit_word_t br, int32_t r0, int32_t r1)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    AND(rn(t0), r0, r1);
+    w = _jit->pc.w;
+    BEQ(_ZERO_REGNO, rn(t0), br - w);
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static jit_word_t
+_bmci(jit_state_t *_jit, jit_word_t br, int32_t r0, jit_word_t i0)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    movi(rn(t0), i0);
+    w = bmcr(br, r0, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static void
+_jmpi(jit_state_t *_jit, jit_word_t i0)
+{
+    int32_t		t0;
+    jit_word_t		dsp;
+    dsp = i0 - _jit->pc.w;
+    if (simm20_p(dsp))
+	JAL(_ZERO_REGNO, dsp);
+    else {
+	t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+	movi(rn(t0), i0);
+	jmpr(rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static jit_word_t
+_jmpi_p(jit_state_t *_jit, jit_word_t i0)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    w = movi_p(rn(t0), i0);
+    jmpr(rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static void
+_calli(jit_state_t *_jit, jit_word_t i0)
+{
+    int32_t		t0;
+    jit_word_t		dsp;
+    dsp = i0 - _jit->pc.w;
+    if (simm20_p(dsp))
+	JAL(_RA_REGNO, dsp);
+    else {
+	t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+	movi(rn(t0), i0);
+	callr(rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static jit_word_t
+_calli_p(jit_state_t *_jit, jit_word_t i0)
+{
+    jit_word_t		w;
+    int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    w = movi_p(rn(t0), i0);
+    callr(rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+
+static void
+_prolog(jit_state_t *_jit, jit_node_t *node)
+{
+    int32_t		reg;
+    if (_jitc->function->define_frame || _jitc->function->assume_frame) {
+	int32_t	frame = -_jitc->function->frame;
+	assert(_jitc->function->self.aoff >= frame);
+	if (_jitc->function->assume_frame)
+	    return;
+	_jitc->function->self.aoff = frame;
+    }
+    if (_jitc->function->allocar)
+	_jitc->function->self.aoff &= -16;
+    _jitc->function->stack = ((_jitc->function->self.alen -
+			      /* align stack at 16 bytes */
+			      _jitc->function->self.aoff) + 15) & -16;
+    subi(_SP_REGNO, _SP_REGNO, stack_framesize);
+    stxi(0, _SP_REGNO, _RA_REGNO);
+    stxi(8, _SP_REGNO, _FP_REGNO);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S1))
+	stxi(16, _SP_REGNO, 9);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S2))
+	stxi(24, _SP_REGNO, 18);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S3))
+	stxi(32, _SP_REGNO, 19);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S4))
+	stxi(40, _SP_REGNO, 20);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S5))
+	stxi(48, _SP_REGNO, 21);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S6))
+	stxi(56, _SP_REGNO, 22);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S7))
+	stxi(64, _SP_REGNO, 23);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S8))
+	stxi(72, _SP_REGNO, 24);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S9))
+	stxi(80, _SP_REGNO, 25);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S10))
+	stxi(88, _SP_REGNO, 26);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S11))
+	stxi(96, _SP_REGNO, 27);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS0))
+	stxi_d(104, _SP_REGNO, 8);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS1))
+	stxi_d(112, _SP_REGNO, 9);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS2))
+	stxi_d(120, _SP_REGNO, 18);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS3))
+	stxi_d(128, _SP_REGNO, 19);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS4))
+	stxi_d(136, _SP_REGNO, 20);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS5))
+	stxi_d(144, _SP_REGNO, 21);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS6))
+	stxi_d(152, _SP_REGNO, 22);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS7))
+	stxi_d(160, _SP_REGNO, 23);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS8))
+	stxi_d(168, _SP_REGNO, 24);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS9))
+	stxi_d(176, _SP_REGNO, 25);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS10))
+	stxi_d(184, _SP_REGNO, 26);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS11))
+	stxi_d(192, _SP_REGNO, 27);
+    movr(_FP_REGNO, _SP_REGNO);
+    if (_jitc->function->stack)
+	subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack);
+    if (_jitc->function->allocar) {
+	reg = jit_get_reg(jit_class_gpr);
+	movi(rn(reg), _jitc->function->self.aoff);
+	stxi_i(_jitc->function->aoffoff, _FP_REGNO, rn(reg));
+	jit_unget_reg(reg);
+    }
+    if (_jitc->function->self.call & jit_call_varargs) {
+	for (reg = _jitc->function->vagp; jit_arg_reg_p(reg); ++reg)
+	    stxi(stack_framesize - ((8 - reg) * 8),
+		 _FP_REGNO, rn(JIT_RA0 - reg));
+    }
+}
+
+static void
+_epilog(jit_state_t *_jit, jit_node_t *node)
+{
+    if (_jitc->function->assume_frame)
+	return;
+    movr(_SP_REGNO, _FP_REGNO);
+    ldxi(_RA_REGNO, _SP_REGNO, 0);
+    ldxi(_FP_REGNO, _SP_REGNO, 8);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S1))
+	ldxi(9, _SP_REGNO, 16);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S2))
+	ldxi(18, _SP_REGNO, 24);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S3))
+	ldxi(19, _SP_REGNO, 32);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S4))
+	ldxi(20, _SP_REGNO, 40);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S5))
+	ldxi(21, _SP_REGNO, 48);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S6))
+	ldxi(22, _SP_REGNO, 56);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S7))
+	ldxi(23, _SP_REGNO, 64);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S8))
+	ldxi(24, _SP_REGNO, 72);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S9))
+	ldxi(25, _SP_REGNO, 80);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S10))
+	ldxi(26, _SP_REGNO, 88);
+    if (jit_regset_tstbit(&_jitc->function->regset, _S11))
+	ldxi(27, _SP_REGNO, 96);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS0))
+	ldxi_d(8, _SP_REGNO, 104);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS1))
+	ldxi_d(9, _SP_REGNO, 112);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS2))
+	ldxi_d(18, _SP_REGNO, 120);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS3))
+	ldxi_d(19, _SP_REGNO, 128);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS4))
+	ldxi_d(20, _SP_REGNO, 136);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS5))
+	ldxi_d(21, _SP_REGNO, 144);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS6))
+	ldxi_d(22, _SP_REGNO, 152);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS7))
+	ldxi_d(23, _SP_REGNO, 160);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS8))
+	ldxi_d(24, _SP_REGNO, 168);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS9))
+	ldxi_d(25, _SP_REGNO, 176);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS10))
+	ldxi_d(26, _SP_REGNO, 184);
+    if (jit_regset_tstbit(&_jitc->function->regset, _FS11))
+	ldxi_d(27, _SP_REGNO, 192);
+    addi(_SP_REGNO, _SP_REGNO, stack_framesize);
+    RET();
+}
+
+static void
+_vastart(jit_state_t *_jit, 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, int32_t r0, int32_t r1)
+{
+    assert(_jitc->function->self.call & jit_call_varargs);
+    /* Load argument. */
+    ldr(r0, r1);
+    /* Update va_list. */
+    addi(r1, r1, sizeof(jit_word_t));
+}
+
+static void
+_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
+{
+    instr_t		 i;
+    union {
+	int32_t	*i;
+	jit_word_t	 w;
+    } u;
+    u.w = instr;
+    i.w = u.i[0];
+    /* movi_p? */
+    if (i.U.opcode == 55) {					/* LUI */
+	int32_t	ww = label << 32 >> 32;
+	int32_t	lo = ww << 20 >> 20;
+	int32_t	hi = ww - lo;
+	i.U.imm12_31 = hi >> 12;
+	u.i[0] = i.w;
+	i.w = u.i[1];
+	if (i.I.opcode == 27 && i.I.funct3 == 0) {		/* ADDIW */
+	    i.I.imm11_0 = lo & 0xfff;
+	    u.i[1] = i.w;
+	    i.w = u.i[2];
+	    if (i.U.opcode == 55) {				/* LUI */
+		ww = label >> 32;
+		lo = ww << 20 >> 20;
+		hi = ww - lo;
+		i.U.imm12_31 = hi >> 12;
+		u.i[2] = i.w;
+		i.w = u.i[3];
+		if (i.I.opcode == 27 && i.I.funct3 == 0) {	/* ADDIW */
+		    i.I.imm11_0 = lo & 0xfff;
+		    u.i[3] = i.w;
+		    i.w = u.i[4];
+		    assert(i.IS.opcode == 19);			/* SLLI */
+		    assert(i.IS.shamt == 32);
+		    i.w = u.i[5];
+		    assert(i.R.opcode == 51);			/* ADD */
+		}
+		else
+		    abort();
+	    }
+	    else
+		abort();
+	}
+	else
+	    abort();
+    }
+    /* b{lt,le,eq,ge,gt,ne}{,_u}? */
+    else if (i.B.opcode == 99) {		/* B{EQ,NE,LT,GE,LTU,GEU} */
+	jit_word_t jmp = label - instr;
+	assert(simm12_p(jmp));
+	i.B.imm11	= (jmp >> 11) & 0x1;
+	i.B.imm4_1	= (jmp >> 1) & 0xf;
+	i.B.imm10_5	= (jmp >> 5) & 0x3f;
+	i.B.imm12	= (jmp >> 12) & 0x1;
+	u.i[0] = i.w;
+    }
+    else if (i.J.opcode == 111) {		/* JAL */
+	jit_word_t jmp = label - instr;
+	i.J.imm19_12	= (jmp >> 12) &  0xff;
+	i.J.imm11	= (jmp >> 11) &   0x1;
+	i.J.imm10_1	= (jmp >>  1) & 0x3ff;
+	i.J.imm20	= (jmp >> 20) &   0x1;
+	u.i[0] = i.w;
+    }
+    else
+	abort();
+}
+#endif		/* CODE */
diff --git a/lightening/riscv-fpu.c b/lightening/riscv-fpu.c
new file mode 100644
index 0000000..367975e
--- /dev/null
+++ b/lightening/riscv-fpu.c
@@ -0,0 +1,1271 @@
+/*
+ * Copyright (C) 2019  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU lightning.
+ *
+ * GNU lightning is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU lightning is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ *
+ * Authors:
+ *	Paulo Cesar Pereira de Andrade
+ */
+
+#if PROTO
+/*
+ * RV32F Standard Extension
+ */
+#  define FLW(rd, rs1, im)		Itype(7, rd, 2, rs1, im)
+#  define FSW(rs1, rs2, imm)		Stype(39, 2, rs1, rs2, imm)
+#  define FMADD_S(rd, rs1, rs2, rs3)	R4type(67, rd, 0, rs1, rs2, 0, rs3)
+#  define FMSUB_S(rd, rs1, rs2, rs3)	R4type(71, rd, 0, rs1, rs2, 0, rs3)
+#  define FNMSUB_S(rd, rs1, rs2, rs3)	R4type(75, rd, 0, rs1, rs2, 0, rs3)
+#  define FNMADD_S(rd, rs1, rs2, rs3)	R4type(79, rd, 0, rs1, rs2, 0, rs3)
+#  define FADD_S(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 0)
+#  define FSUB_S(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 4)
+#  define FMUL_S(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 8)
+#  define FDIV_S(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 12)
+#  define FSQRT_S(rd, rs1)		Rtype(83, rd, 0, rs1, 0, 44)
+#  define FSGNJ_S(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 16)
+#  define FSGNJN_S(rd, rs1, rs2)	Rtype(83, rd, 1, rs1, rs2, 16)
+#  define FSGNJX_S(rd, rs1, rs2)	Rtype(83, rd, 2, rs1, rs2, 16)
+#  define FMIN_S(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 20)
+#  define FMAX_S(rd, rs1, rs2)		Rtype(83, rd, 1, rs1, rs2, 20)
+#  define FCVT_W_S(rd, rs1)		Rtype(83, rd, 0, rs1, 0, 96)
+#  define FCVT_WU_S(rd, rs1)		Rtype(83, rd, 1, rs1, 1, 96)
+#  define FMV_X_W(rd, rs1)		Rtype(83, rd, 0, rs1, 0, 112)
+#  define FEQ_S(rd, rs1, rs2)		Rtype(83, rd, 2, rs1, rs2, 80)
+#  define FLT_S(rd, rs1, rs2)		Rtype(83, rd, 1, rs1, rs2, 80)
+#  define FLE_S(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 80)
+#  define FCLASS_S(rd, rs1)		Rtype(83, rd, 1, rs1, 0, 112)
+#  define FCVT_S_W(rd, rs1)		Rtype(83, rd, 0, rs1, 0, 104)
+#  define FCVT_S_WU(rd, rs1)		Rtype(83, rd, 0, rs1, 1, 104)
+#  define FMV_W_X(rd, rs1)		Rtype(83, rd, 0, rs1, 0, 120)
+/*
+ * RV64F Standard Extension (in addition to RV32F)
+ */
+#  define FCVT_L_S(rd, rs1)		Rtype(83, rd, 0, rs1, 2, 96)
+#  define FCVT_LU_S(rd, rs1)		Rtype(83, rd, 0, rs1, 3, 96)
+#  define FCVT_S_L(rd, rs1)		Rtype(83, rd, 0, rs1, 2, 104)
+#  define FCVT_S_LU(rd, rs1)		Rtype(83, rd, 0, rs1, 3, 104)
+/*
+ * RV32D Standard Extension
+ */
+#  define FLD(rd, rs1, im)		Itype(7, rd, 3, rs1, im)
+#  define FSD(rs1, rs2, imm)		Stype(39, 3, rs1, rs2, imm)
+#  define FMADD_D(rd, rs1, rs2, rs3)	R4type(67, rd, 0, rs1, rs2, 1, rs3)
+#  define FMSUB_D(rd, rs1, rs2, rs3)	R4type(71, rd, 0, rs1, rs2, 1, rs3)
+#  define FNMSUB_D(rd, rs1, rs2, rs3)	R4type(75, rd, 0, rs1, rs2, 1, rs3)
+#  define FNMADD_D(rd, rs1, rs2, rs3)	R4type(79, rd, 0, rs1, rs2, 1, rs3)
+#  define FADD_D(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 1)
+#  define FSUB_D(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 5)
+#  define FMUL_D(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 9)
+#  define FDIV_D(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 13)
+#  define FSQRT_D(rd, rs1)		Rtype(83, rd, 0, rs1, 0, 45)
+#  define FSGNJ_D(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 17)
+#  define FSGNJN_D(rd, rs1, rs2)	Rtype(83, rd, 1, rs1, rs2, 17)
+#  define FSGNJX_D(rd, rs1, rs2)	Rtype(83, rd, 2, rs1, rs2, 17)
+#  define FMIN_D(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 21)
+#  define FMAX_D(rd, rs1, rs2)		Rtype(83, rd, 1, rs1, rs2, 21)
+#  define FCVT_S_D(rd, rs1)		Rtype(83, rd, 0, rs1, 1, 32)
+#  define FCVT_D_S(rd, rs1)		Rtype(83, rd, 0, rs1, 0, 33)
+#  define FEQ_D(rd, rs1, rs2)		Rtype(83, rd, 2, rs1, rs2, 81)
+#  define FLT_D(rd, rs1, rs2)		Rtype(83, rd, 1, rs1, rs2, 81)
+#  define FLE_D(rd, rs1, rs2)		Rtype(83, rd, 0, rs1, rs2, 81)
+#  define FCLASS_D(rd, rs1)		Rtype(83, rd, 1, rs1, 0, 113)
+#  define FCVT_W_D(rd, rs1)		Rtype(83, rd, 0, rs1, 0, 97)
+#  define FCVT_WU_D(rd, rs1)		Rtype(83, rd, 0, rs1, 1, 97)
+#  define FCVT_D_W(rd, rs1)		Rtype(83, rd, 0, rs1, 0, 105)
+#  define FCVT_D_WU(rd, rs1)		Rtype(83, rd, 0, rs1, 1, 105)
+/*
+ * RV64D Standard Extension (in addition to RV32D)
+ */
+#  define FCVT_L_D(rd, rs1)		Rtype(83, rd, 0, rs1, 2, 97)
+#  define FCVT_LU_D(rd, rs1)		Rtype(83, rd, 0, rs1, 3, 97)
+#  define FMV_X_D(rd, rs1)		Rtype(83, rd, 0, rs1, 0, 113)
+#  define FCVT_D_L(rd, rs1)		Rtype(83, rd, 0, rs1, 2, 105)
+#  define FCVT_D_LU(rd, rs1)		Rtype(83, rd, 0, rs1, 3, 105)
+#  define FMV_D_X(rd, rs1)		Rtype(83, rd, 0, rs1, 0, 121)
+/*
+ * Pseudo instructions
+ */
+#  define FMV_S(r0, r1)			FSGNJ_S(r0, r1, r1)
+#  define FABS_S(r0, r1)		FSGNJX_S(r0, r1, r1)
+#  define FNEG_S(r0, r1)		FSGNJN_S(r0, r1, r1)
+#  define FMV_D(r0, r1)			FSGNJ_D(r0, r1, r1)
+#  define FABS_D(r0, r1)		FSGNJX_D(r0, r1, r1)
+#  define FNEG_D(r0, r1)		FSGNJN_D(r0, r1, r1)
+
+/*
+ * Lightning instructions
+ */
+#  define truncr_f_i(r0, r1)		FCVT_W_S(r0, r1)
+#  define truncr_d_i(r0, r1)		FCVT_W_D(r0, r1)
+#  define truncr_f_l(r0, r1)		FCVT_L_S(r0, r1)
+#  define truncr_d_l(r0, r1)		FCVT_L_D(r0, r1)
+#  define addr_f(r0, r1, r2)		FADD_S(r0, r1, r2)
+#  define addi_f(r0, r1, im)		_addi_f(_jit, r0, r1, im)
+static void _addi_f(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float32_t);
+#  define subr_f(r0, r1, r2)		FSUB_S(r0, r1, r2)
+#  define subi_f(r0, r1, im)		_subi_f(_jit, r0, r1, im)
+static void _subi_f(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float32_t);
+#  define rsbr_f(r0, r1, r2)		FSUB_S(r0, r2, r1)
+#  define rsbi_f(r0, r1, im)		_rsbi_f(_jit, r0, r1, im)
+static void _rsbi_f(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float32_t);
+#  define mulr_f(r0, r1, r2)		FMUL_S(r0, r1, r2)
+#  define muli_f(r0, r1, im)		_muli_f(_jit, r0, r1, im)
+static void _muli_f(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float32_t);
+#  define divr_f(r0, r1, r2)		FDIV_S(r0, r1, r2)
+#  define divi_f(r0, r1, im)		_divi_f(_jit, r0, r1, im)
+static void _divi_f(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float32_t);
+#  define absr_f(r0, r1)		FABS_S(r0, r1)
+#  define negr_f(r0, r1)		FNEG_S(r0, r1)
+#  define sqrtr_f(r0, r1)		FSQRT_S(r0, r1)
+#  define extr_f(r0, r1)		FCVT_S_L(r0, r1)
+#  define ldr_f(r0, r1)			FLW(r0, r1, 0)
+#  define ldi_f(r0, im)			_ldi_f(_jit, r0, im)
+static void _ldi_f(jit_state_t*, jit_int32_t, jit_word_t);
+#  define ldxr_f(r0, r1, r2)		_ldxr_f(_jit, r0, r1, r2)
+static void _ldxr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define ldxi_f(r0, r1, i0)		_ldxi_f(_jit, r0, r1, i0)
+static void _ldxi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
+#  define str_f(r0, r1)			FSW(r0, r1, 0)
+#  define sti_f(im, r0)			_sti_f(_jit, im, r0)
+static void _sti_f(jit_state_t*, jit_word_t, jit_int32_t);
+#  define stxr_f(r0, r1, r2)		_stxr_f(_jit, r0, r1, r2)
+static void _stxr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define stxi_f(im, r0, r1)		_stxi_f(_jit, im, r0, r1)
+static void _stxi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
+#  define movr_f(r0, r1)		FMV_S(r0, r1)
+#  define movi_f(r0, im)		_movi_f(_jit, r0, im)
+static void _movi_f(jit_state_t*, jit_int32_t, jit_float32_t);
+#  define movr_f_w(r0, r1)		FMV_X_W(r0, r1)
+#  define movi_f_w(r0, im)		_movi_f_w(_jit, r0, im)
+static void _movi_f_w(jit_state_t*, jit_int32_t, jit_float32_t);
+#  define movr_w_f(r0, r1)		FMV_W_X(r0, r1)
+#  define extr_d_f(r0, r1)		FCVT_S_D(r0, r1)
+#  define ltr_f(r0, r1, r2)		FLT_S(r0, r1, r2)
+#  define lti_f(r0, r1, im)		_lti_f(_jit, r0, r1, im)
+static void _lti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define ler_f(r0, r1, r2)		FLE_S(r0, r1, r2)
+#  define lei_f(r0, r1, im)		_lei_f(_jit, r0, r1, im)
+static void _lei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define eqr_f(r0, r1, r2)		FEQ_S(r0, r1, r2)
+#  define eqi_f(r0, r1, im)		_eqi_f(_jit, r0, r1, im)
+static void _eqi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define ger_f(r0, r1, r2)		FLE_S(r0, r2, r1)
+#  define gei_f(r0, r1, im)		_gei_f(_jit, r0, r1, im)
+static void _gei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define gtr_f(r0, r1, r2)		FLT_S(r0, r2, r1)
+#  define gti_f(r0, r1, im)		_gti_f(_jit, r0, r1, im)
+static void _gti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define ner_f(r0, r1, r2)		_ner_f(_jit, r0, r1, r2)
+static void _ner_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define nei_f(r0, r1, im)		_nei_f(_jit, r0, r1, im)
+static void _nei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define unltr_f(r0, r1, r2)		_unltr_f(_jit, r0, r1, r2)
+static void _unltr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define unlti_f(r0, r1, im)		_unlti_f(_jit, r0, r1, im)
+static void _unlti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define unler_f(r0, r1, r2)		_unler_f(_jit, r0, r1, r2)
+static void _unler_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define unlei_f(r0, r1, im)		_unlei_f(_jit, r0, r1, im)
+static void _unlei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define uneqr_f(r0, r1, r2)		_uneqr_f(_jit, r0, r1, r2)
+static void _uneqr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define uneqi_f(r0, r1, im)		_uneqi_f(_jit, r0, r1, im)
+static void _uneqi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define unger_f(r0, r1, r2)		_unger_f(_jit, r0, r1, r2)
+static void _unger_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define ungei_f(r0, r1, im)		_ungei_f(_jit, r0, r1, im)
+static void _ungei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define ungtr_f(r0, r1, r2)		_ungtr_f(_jit, r0, r1, r2)
+static void _ungtr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define ungti_f(r0, r1, im)		_ungti_f(_jit, r0, r1, im)
+static void _ungti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define ltgtr_f(r0, r1, r2)		_ltgtr_f(_jit, r0, r1, r2)
+static void _ltgtr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define ltgti_f(r0, r1, im)		_ltgti_f(_jit, r0, r1, im)
+static void _ltgti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define ordr_f(r0, r1, r2)		_ordr_f(_jit, r0, r1, r2)
+static void _ordr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define ordi_f(r0, r1, im)		_ordi_f(_jit, r0, r1, im)
+static void _ordi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define unordr_f(r0, r1, r2)		_unordr_f(_jit, r0, r1, r2)
+static void _unordr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define unordi_f(r0, r1, im)		_unordi_f(_jit, r0, r1, im)
+static void _unordi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t);
+#  define bltr_f(br, r0, r1)		_bltr_f(_jit,br,r0,r1)
+static jit_word_t _bltr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define blti_f(br, r0, im)		_blti_f(_jit,br,r0,im)
+static jit_word_t _blti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define bler_f(br, r0, r1)		_bler_f(_jit,br,r0,r1)
+static jit_word_t _bler_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define blei_f(br, r0, im)		_blei_f(_jit,br,r0,im)
+static jit_word_t _blei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define beqr_f(br, r0, r1)		_beqr_f(_jit,br,r0,r1)
+static jit_word_t _beqr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define beqi_f(br, r0, im)		_beqi_f(_jit,br,r0,im)
+static jit_word_t _beqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define bger_f(br, r0, r1)		_bger_f(_jit,br,r0,r1)
+static jit_word_t _bger_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bgei_f(br, r0, im)		_bgei_f(_jit,br,r0,im)
+static jit_word_t _bgei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define bgtr_f(br, r0, r1)		_bgtr_f(_jit,br,r0,r1)
+static jit_word_t _bgtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bgti_f(br, r0, im)		_bgti_f(_jit,br,r0,im)
+static jit_word_t _bgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define bner_f(br, r0, r1)		_bner_f(_jit,br,r0,r1)
+static jit_word_t _bner_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bnei_f(br, r0, im)		_bnei_f(_jit,br,r0,im)
+static jit_word_t _bnei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define bunltr_f(br, r0, r1)		_bunltr_f(_jit,br,r0,r1)
+static jit_word_t _bunltr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bunlti_f(br, r0, im)		_bunlti_f(_jit,br,r0,im)
+static jit_word_t _bunlti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define bunler_f(br, r0, r1)		_bunler_f(_jit,br,r0,r1)
+static jit_word_t _bunler_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bunlei_f(br, r0, im)		_bunlei_f(_jit,br,r0,im)
+static jit_word_t _bunlei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define buneqr_f(br, r0, r1)		_buneqr_f(_jit,br,r0,r1)
+static jit_word_t _buneqr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define buneqi_f(br, r0, im)		_buneqi_f(_jit,br,r0,im)
+static jit_word_t _buneqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define bunger_f(br, r0, r1)		_bunger_f(_jit,br,r0,r1)
+static jit_word_t _bunger_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bungei_f(br, r0, im)		_bungei_f(_jit,br,r0,im)
+static jit_word_t _bungei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define bungtr_f(br, r0, r1)		_bungtr_f(_jit,br,r0,r1)
+static jit_word_t _bungtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bungti_f(br, r0, im)		_bungti_f(_jit,br,r0,im)
+static jit_word_t _bungti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define bltgtr_f(br, r0, r1)		_bltgtr_f(_jit,br,r0,r1)
+static jit_word_t _bltgtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bltgti_f(br, r0, im)		_bltgti_f(_jit,br,r0,im)
+static jit_word_t _bltgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define bordr_f(br, r0, r1)		_bordr_f(_jit,br,r0,r1)
+static jit_word_t _bordr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bordi_f(br, r0, im)		_bordi_f(_jit,br,r0,im)
+static jit_word_t _bordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define bunordr_f(br, r0, r1)		_bunordr_f(_jit,br,r0,r1)
+static jit_word_t _bunordr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bunordi_f(br, r0, im)		_bunordi_f(_jit,br,r0,im)
+static jit_word_t _bunordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
+#  define addr_d(r0, r1, r2)		FADD_D(r0, r1, r2)
+#  define addi_d(r0, r1, im)		_addi_d(_jit, r0, r1, im)
+static void _addi_d(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float64_t);
+#  define subr_d(r0, r1, r2)		FSUB_D(r0, r1, r2)
+#  define subi_d(r0, r1, im)		_subi_d(_jit, r0, r1, im)
+static void _subi_d(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float64_t);
+#  define rsbr_d(r0, r1, r2)		FSUB_D(r0, r2, r1)
+#  define rsbi_d(r0, r1, im)		_rsbi_d(_jit, r0, r1, im)
+static void _rsbi_d(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float64_t);
+#  define mulr_d(r0, r1, r2)		FMUL_D(r0, r1, r2)
+#  define muli_d(r0, r1, im)		_muli_d(_jit, r0, r1, im)
+static void _muli_d(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float64_t);
+#  define divr_d(r0, r1, r2)		FDIV_D(r0, r1, r2)
+#  define divi_d(r0, r1, im)		_divi_d(_jit, r0, r1, im)
+static void _divi_d(jit_state_t *_jit,jit_int32_t,jit_int32_t,jit_float64_t);
+#  define absr_d(r0, r1)		FABS_D(r0, r1)
+#  define negr_d(r0, r1)		FNEG_D(r0, r1)
+#  define sqrtr_d(r0, r1)		FSQRT_D(r0, r1)
+#  define extr_d(r0, r1)		FCVT_D_L(r0, r1)
+#  define ldr_d(r0, r1)			FLD(r0, r1, 0)
+#  define ldi_d(r0, im)			_ldi_d(_jit, r0, im)
+static void _ldi_d(jit_state_t*, jit_int32_t, jit_word_t);
+#  define ldxr_d(r0, r1, r2)		_ldxr_d(_jit, r0, r1, r2)
+static void _ldxr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define ldxi_d(r0, r1, i0)		_ldxi_d(_jit, r0, r1, i0)
+static void _ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
+#  define str_d(r0, r1)			FSD(r0, r1, 0)
+#  define sti_d(im, r0)			_sti_d(_jit, im, r0)
+static void _sti_d(jit_state_t*, jit_word_t, jit_int32_t);
+#  define stxr_d(r0, r1, r2)		_stxr_d(_jit, r0, r1, r2)
+static void _stxr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define stxi_d(im, r0, r1)		_stxi_d(_jit, im, r0, r1)
+static void _stxi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
+#  define movr_d(r0, r1)		FMV_D(r0, r1)
+#  define movi_d(r0, im)		_movi_d(_jit, r0, im)
+static void _movi_d(jit_state_t*, jit_int32_t, jit_float64_t);
+#  define movr_d_w(r0, r1)		FMV_X_D(r0, r1)
+#  define movi_d_w(r0, im)		_movi_d_w(_jit, r0, im)
+static void _movi_d_w(jit_state_t*, jit_int32_t, jit_float64_t);
+#  define movr_w_d(r0, r1)		FMV_D_X(r0, r1)
+#  define extr_f_d(r0, r1)		FCVT_D_S(r0, r1)
+#  define ltr_d(r0, r1, r2)		FLT_D(r0, r1, r2)
+#  define lti_d(r0, r1, r2)		_lti_d(_jit, r0, r1, r2)
+static void _lti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define ler_d(r0, r1, r2)		FLE_D(r0, r1, r2)
+#  define lei_d(r0, r1, r2)		_lei_d(_jit, r0, r1, r2)
+static void _lei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define eqr_d(r0, r1, r2)		FEQ_D(r0, r1, r2)
+#  define eqi_d(r0, r1, r2)		_eqi_d(_jit, r0, r1, r2)
+static void _eqi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define ger_d(r0, r1, r2)		FLE_D(r0, r2, r1)
+#  define gei_d(r0, r1, r2)		_gei_d(_jit, r0, r1, r2)
+static void _gei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define gtr_d(r0, r1, r2)		FLT_D(r0, r2, r1)
+#  define gti_d(r0, r1, r2)		_gti_d(_jit, r0, r1, r2)
+static void _gti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define ner_d(r0, r1, r2)		_ner_d(_jit, r0, r1, r2)
+static void _ner_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define nei_d(r0, r1, r2)		_nei_d(_jit, r0, r1, r2)
+static void _nei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define unltr_d(r0, r1, r2)		_unltr_d(_jit, r0, r1, r2)
+static void _unltr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define unlti_d(r0, r1, im)		_unlti_d(_jit, r0, r1, im)
+static void _unlti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define unler_d(r0, r1, r2)		_unler_d(_jit, r0, r1, r2)
+static void _unler_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define unlei_d(r0, r1, im)		_unlei_d(_jit, r0, r1, im)
+static void _unlei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define uneqr_d(r0, r1, r2)		_uneqr_d(_jit, r0, r1, r2)
+static void _uneqr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define uneqi_d(r0, r1, im)		_uneqi_d(_jit, r0, r1, im)
+static void _uneqi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define unger_d(r0, r1, r2)		_unger_d(_jit, r0, r1, r2)
+static void _unger_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define ungei_d(r0, r1, im)		_ungei_d(_jit, r0, r1, im)
+static void _ungei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define ungtr_d(r0, r1, r2)		_ungtr_d(_jit, r0, r1, r2)
+static void _ungtr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define ungti_d(r0, r1, im)		_ungti_d(_jit, r0, r1, im)
+static void _ungti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define ltgtr_d(r0, r1, r2)		_ltgtr_d(_jit, r0, r1, r2)
+static void _ltgtr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define ltgti_d(r0, r1, im)		_ltgti_d(_jit, r0, r1, im)
+static void _ltgti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define ordr_d(r0, r1, r2)		_ordr_d(_jit, r0, r1, r2)
+static void _ordr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define ordi_d(r0, r1, im)		_ordi_d(_jit, r0, r1, im)
+static void _ordi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define unordr_d(r0, r1, r2)		_unordr_d(_jit, r0, r1, r2)
+static void _unordr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
+#  define unordi_d(r0, r1, im)		_unordi_d(_jit, r0, r1, im)
+static void _unordi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t);
+#  define bltr_d(br, r0, r1)		_bltr_d(_jit,br,r0,r1)
+static jit_word_t _bltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define blti_d(br, r0, im)		_blti_d(_jit,br,r0,im)
+static jit_word_t _blti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define bler_d(br, r0, r1)		_bler_d(_jit,br,r0,r1)
+static jit_word_t _bler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define blei_d(br, r0, im)		_blei_d(_jit,br,r0,im)
+static jit_word_t _blei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define beqr_d(br, r0, r1)		_beqr_d(_jit,br,r0,r1)
+static jit_word_t _beqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define beqi_d(br, r0, im)		_beqi_d(_jit,br,r0,im)
+static jit_word_t _beqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define bger_d(br, r0, r1)		_bger_d(_jit,br,r0,r1)
+static jit_word_t _bger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bgei_d(br, r0, im)		_bgei_d(_jit,br,r0,im)
+static jit_word_t _bgei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define bgtr_d(br, r0, r1)		_bgtr_d(_jit,br,r0,r1)
+static jit_word_t _bgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bgti_d(br, r0, im)		_bgti_d(_jit,br,r0,im)
+static jit_word_t _bgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define bner_d(br, r0, r1)		_bner_d(_jit,br,r0,r1)
+static jit_word_t _bner_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bnei_d(br, r0, im)		_bnei_d(_jit,br,r0,im)
+static jit_word_t _bnei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define bunltr_d(br, r0, r1)		_bunltr_d(_jit,br,r0,r1)
+static jit_word_t _bunltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bunlti_d(br, r0, im)		_bunlti_d(_jit,br,r0,im)
+static jit_word_t _bunlti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define bunler_d(br, r0, r1)		_bunler_d(_jit,br,r0,r1)
+static jit_word_t _bunler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bunlei_d(br, r0, im)		_bunlei_d(_jit,br,r0,im)
+static jit_word_t _bunlei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define buneqr_d(br, r0, r1)		_buneqr_d(_jit,br,r0,r1)
+static jit_word_t _buneqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define buneqi_d(br, r0, im)		_buneqi_d(_jit,br,r0,im)
+static jit_word_t _buneqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define bunger_d(br, r0, r1)		_bunger_d(_jit,br,r0,r1)
+static jit_word_t _bunger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bungei_d(br, r0, im)		_bungei_d(_jit,br,r0,im)
+static jit_word_t _bungei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define bungtr_d(br, r0, r1)		_bungtr_d(_jit,br,r0,r1)
+static jit_word_t _bungtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bungti_d(br, r0, im)		_bungti_d(_jit,br,r0,im)
+static jit_word_t _bungti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define bltgtr_d(br, r0, r1)		_bltgtr_d(_jit,br,r0,r1)
+static jit_word_t _bltgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bltgti_d(br, r0, im)		_bltgti_d(_jit,br,r0,im)
+static jit_word_t _bltgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define bordr_d(br, r0, r1)		_bordr_d(_jit,br,r0,r1)
+static jit_word_t _bordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bordi_d(br, r0, im)		_bordi_d(_jit,br,r0,im)
+static jit_word_t _bordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define bunordr_d(br, r0, r1)		_bunordr_d(_jit,br,r0,r1)
+static jit_word_t _bunordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
+#  define bunordi_d(br, r0, im)		_bunordi_d(_jit,br,r0,im)
+static jit_word_t _bunordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
+#  define vaarg_d(r0, r1)		_vaarg_d(_jit, r0, r1)
+static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t);
+#endif /* PROTO */
+
+#if CODE
+#  define fpr_opi(name, type, size)					\
+static void								\
+_##name##i_##type(jit_state_t *_jit,					\
+		  jit_int32_t r0, jit_int32_t r1,			\
+		  jit_float##size##_t i0)				\
+{									\
+    jit_int32_t		reg = jit_get_reg(jit_class_fpr);		\
+    movi_##type(rn(reg), i0);						\
+    name##r_##type(r0, r1, rn(reg));					\
+    jit_unget_reg(reg);							\
+}
+#  define fopi(name)			fpr_opi(name, f, 32)
+#  define dopi(name)			fpr_opi(name, d, 64)
+
+fopi(add)
+fopi(sub)
+fopi(rsb)
+fopi(mul)
+fopi(div)
+
+static void
+_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+    jit_int32_t		t0;
+    if (simm12_p(i0))
+	FLW(r0, _ZERO_REGNO, i0);
+    else {
+	t0 = jit_get_reg(jit_class_gpr);
+	movi(rn(t0), i0);
+	ldr_f(r0, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    addr(rn(t0), r1, r2);
+    ldr_f(r0, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
+{
+    jit_int32_t		t0;
+    if (simm12_p(i0))
+	FLW(r0, r1, i0);
+    else {
+	t0 = jit_get_reg(jit_class_gpr);
+	addi(rn(t0), r1, i0);
+	ldr_f(r0, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
+{
+    jit_int32_t		t0;
+    if (simm12_p(i0))
+	FSW(r0, _ZERO_REGNO, i0);
+    else {
+	t0 = jit_get_reg(jit_class_gpr);
+	movi(rn(t0), i0);
+	str_f(rn(t0), r0);
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    addr(rn(t0), r0, r1);
+    str_f(rn(t0), r2);
+    jit_unget_reg(t0);
+}
+
+static void
+_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
+{
+    jit_int32_t		t0;
+    if (simm12_p(i0))
+	FSW(r0, r1, i0);
+    else {
+	t0 = jit_get_reg(jit_class_gpr);
+	addi(rn(t0), r0, i0);
+	str_f(rn(t0), r1);
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0)
+{
+    union {
+	jit_int32_t	 i;
+	jit_float32_t	 f;
+    } data;
+    jit_int32_t		 reg;
+    data.f = i0;
+    if (data.i == 0)
+	movr_w_f(r0, _ZERO_REGNO);
+    else {
+	reg = jit_get_reg(jit_class_gpr);
+	movi(rn(reg), data.i);
+	movr_w_f(r0, rn(reg));
+	jit_unget_reg(reg);
+    }
+}
+
+static void
+_movi_f_w(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0)
+{
+    union {
+	jit_int32_t	i;
+	jit_float32_t	f;
+    } data;
+    data.f = i0;
+    movi(r0, data.i);
+}
+
+fopi(lt)
+fopi(le)
+fopi(eq)
+fopi(ge)
+fopi(gt)
+
+static void
+_ner_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    eqr_f(r0, r1, r2);
+    xori(r0, r0, 1);
+}
+fopi(ne)
+
+#  define fpr_bopi(name, type, size)					\
+static jit_word_t							\
+_b##name##i_##type(jit_state_t *_jit,					\
+		  jit_word_t i0, jit_int32_t r0,			\
+		  jit_float##size##_t i1)				\
+{									\
+    jit_word_t		word;						\
+    jit_int32_t		reg = jit_get_reg(jit_class_fpr|		\
+					  jit_class_nospill);		\
+    movi_##type(rn(reg), i1);						\
+    word = b##name##r_##type(i0, r0, rn(reg));				\
+    jit_unget_reg(reg);							\
+    return (word);							\
+}
+#  define fbopi(name)			fpr_bopi(name, f, 32)
+#  define dbopi(name)			fpr_bopi(name, d, 64)
+
+#  define unop(CLASS, OP)						\
+    jit_word_t		w;						\
+    jit_int32_t		t0, t1;						\
+    t0 = jit_get_reg(jit_class_gpr);					\
+    FCLASS_##CLASS(rn(t0), r1);						\
+    t1 = jit_get_reg(jit_class_gpr);					\
+    FCLASS_##CLASS(rn(t1), r2);						\
+    orr(rn(t0), rn(t0), rn(t1));					\
+    jit_unget_reg(t1);							\
+    rshi(rn(t0), rn(t0), 8);						\
+    ltr(r0, _ZERO_REGNO, rn(t0));					\
+    jit_unget_reg(t0);							\
+    w = _jit->pc.w;							\
+    BLT(_ZERO_REGNO, r0, 0);						\
+    OP(r0, r1, r2);							\
+    patch_at(w, _jit->pc.w)
+
+static void
+_unltr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    unop(S, ltr_f);
+}
+fopi(unlt)
+
+static void
+_unler_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    unop(S, ler_f);
+}
+fopi(unle)
+
+static void
+_uneqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    unop(S, eqr_f);
+}
+fopi(uneq)
+
+static void
+_unger_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    unop(S, ger_f);
+}
+fopi(unge)
+
+static void
+_ungtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    unop(S, gtr_f);
+}
+fopi(ungt)
+
+static void
+_ltgtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w0, w1;
+    jit_int32_t		t0, t1;
+    t0 = jit_get_reg(jit_class_gpr);
+    FCLASS_S(rn(t0), r1);
+    t1 = jit_get_reg(jit_class_gpr);
+    FCLASS_S(rn(t1), r2);
+    orr(rn(t0), rn(t0), rn(t1));
+    jit_unget_reg(t1);
+    rshi(rn(t0), rn(t0), 8);
+    ltr(r0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    w0 = _jit->pc.w;
+    BEQ(_ZERO_REGNO, r0, 0);
+    movr(r0, _ZERO_REGNO);
+    w1 = _jit->pc.w;
+    JAL(_ZERO_REGNO, 0);
+    patch_at(w0, _jit->pc.w);
+    ner_f(r0, r1, r2);
+    patch_at(w1, _jit->pc.w);
+}
+fopi(ltgt)
+
+static void
+_ordr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_int32_t		t0, t1;	
+    t0 = jit_get_reg(jit_class_gpr);
+    FCLASS_S(rn(t0), r1);
+    t1 = jit_get_reg(jit_class_gpr);
+    FCLASS_S(rn(t1), r2);
+    orr(rn(t0), rn(t0), rn(t1));
+    jit_unget_reg(t1);
+    rshi(rn(t0), rn(t0), 8);
+    eqr(r0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+}
+fopi(ord)
+
+static void
+_unordr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_int32_t		t0, t1;	
+    t0 = jit_get_reg(jit_class_gpr);
+    FCLASS_S(rn(t0), r1);
+    t1 = jit_get_reg(jit_class_gpr);
+    FCLASS_S(rn(t1), r2);
+    orr(rn(t0), rn(t0), rn(t1));
+    jit_unget_reg(t1);
+    rshi(rn(t0), rn(t0), 8);
+    ltr(r0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+}
+fopi(unord)
+
+static jit_word_t
+_bltr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    ltr_f(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(lt)
+
+static jit_word_t
+_bler_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    ler_f(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(le)
+
+static jit_word_t
+_beqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    eqr_f(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(eq)
+
+static jit_word_t
+_bger_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    ger_f(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(ge)
+
+static jit_word_t
+_bgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    gtr_f(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(gt)
+
+static jit_word_t
+_bner_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    eqr_f(rn(t0), r1, r2);
+    w = beqr(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(ne)
+
+static jit_word_t
+_bunltr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    unltr_f(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(unlt)
+
+static jit_word_t
+_bunler_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    unler_f(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(unle)
+
+static jit_word_t
+_buneqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    uneqr_f(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(uneq)
+
+static jit_word_t
+_bunger_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    unger_f(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(unge)
+
+static jit_word_t
+_bungtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    ungtr_f(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(ungt)
+
+static jit_word_t
+_bltgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    ltgtr_f(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(ltgt)
+
+static jit_word_t
+_bordr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    ordr_f(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(ord)
+
+static jit_word_t
+_bunordr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    unordr_f(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+fbopi(unord)
+
+dopi(add)
+dopi(sub)
+dopi(rsb)
+dopi(mul)
+dopi(div)
+
+static void
+_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
+{
+    jit_int32_t		t0;
+    if (simm12_p(i0))
+	FLD(r0, _ZERO_REGNO, i0);
+    else {
+	t0 = jit_get_reg(jit_class_gpr);
+	movi(rn(t0), i0);
+	ldr_d(r0, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    addr(rn(t0), r1, r2);
+    ldr_d(r0, rn(t0));
+    jit_unget_reg(t0);
+}
+
+static void
+_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
+{
+    jit_int32_t		t0;
+    if (simm12_p(i0))
+	FLD(r0, r1, i0);
+    else {
+	t0 = jit_get_reg(jit_class_gpr);
+	addi(rn(t0), r1, i0);
+	ldr_d(r0, rn(t0));
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
+{
+    jit_int32_t		t0;
+    if (simm12_p(i0))
+	FSD(r0, _ZERO_REGNO, i0);
+    else {
+	t0 = jit_get_reg(jit_class_gpr);
+	movi(rn(t0), i0);
+	str_d(rn(t0), r0);
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr);
+    addr(rn(t0), r0, r1);
+    str_d(rn(t0), r2);
+    jit_unget_reg(t0);
+}
+
+static void
+_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
+{
+    jit_int32_t		t0;
+    if (simm12_p(i0))
+	FSD(r0, r1, i0);
+    else {
+	t0 = jit_get_reg(jit_class_gpr);
+	addi(rn(t0), r0, i0);
+	str_d(rn(t0), r1);
+	jit_unget_reg(t0);
+    }
+}
+
+static void
+_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0)
+{
+    union {
+	jit_word_t	 w;
+	jit_float64_t	 d;
+    } data;
+    jit_int32_t		 reg;
+    data.d = i0;
+    if (data.w == 0)
+	movr_w_d(r0, _ZERO_REGNO);
+    else {
+	reg = jit_get_reg(jit_class_gpr);
+	movi(rn(reg), data.w);
+	movr_w_d(r0, rn(reg));
+	jit_unget_reg(reg);
+    }
+}
+
+static void
+_movi_d_w(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0)
+{
+    union {
+	jit_int64_t	l;
+	jit_float64_t	d;
+    } data;
+    data.d = i0;
+    movi(r0, data.l);
+}
+
+dopi(lt)
+dopi(le)
+dopi(eq)
+dopi(ge)
+dopi(gt)
+
+static void
+_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    eqr_d(r0, r1, r2);
+    xori(r0, r0, 1);
+}
+dopi(ne)
+
+static void
+_unltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    unop(D, ltr_d);
+}
+dopi(unlt)
+
+static void
+_unler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    unop(D, ler_d);
+}
+dopi(unle)
+
+static void
+_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    unop(D, eqr_d);
+}
+dopi(uneq)
+
+static void
+_unger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    unop(D, ger_d);
+}
+dopi(unge)
+
+static void
+_ungtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    unop(D, gtr_d);
+}
+dopi(ungt)
+
+static void
+_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w0, w1;
+    jit_int32_t		t0, t1;
+    t0 = jit_get_reg(jit_class_gpr);
+    FCLASS_D(rn(t0), r1);
+    t1 = jit_get_reg(jit_class_gpr);
+    FCLASS_D(rn(t1), r2);
+    orr(rn(t0), rn(t0), rn(t1));
+    jit_unget_reg(t1);
+    rshi(rn(t0), rn(t0), 8);
+    ltr(r0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    w0 = _jit->pc.w;
+    BEQ(_ZERO_REGNO, r0, 0);
+    movr(r0, _ZERO_REGNO);
+    w1 = _jit->pc.w;
+    JAL(_ZERO_REGNO, 0);
+    patch_at(w0, _jit->pc.w);
+    ner_d(r0, r1, r2);
+    patch_at(w1, _jit->pc.w);
+}
+dopi(ltgt)
+
+static void
+_ordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_int32_t		t0, t1;	
+    t0 = jit_get_reg(jit_class_gpr);
+    FCLASS_D(rn(t0), r1);
+    t1 = jit_get_reg(jit_class_gpr);
+    FCLASS_D(rn(t1), r2);
+    orr(rn(t0), rn(t0), rn(t1));
+    jit_unget_reg(t1);
+    rshi(rn(t0), rn(t0), 8);
+    eqr(r0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+}
+dopi(ord)
+
+static void
+_unordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_int32_t		t0, t1;	
+    t0 = jit_get_reg(jit_class_gpr);
+    FCLASS_D(rn(t0), r1);
+    t1 = jit_get_reg(jit_class_gpr);
+    FCLASS_D(rn(t1), r2);
+    orr(rn(t0), rn(t0), rn(t1));
+    jit_unget_reg(t1);
+    rshi(rn(t0), rn(t0), 8);
+    ltr(r0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+}
+dopi(unord)
+
+static jit_word_t
+_bltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    ltr_d(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(lt)
+
+static jit_word_t
+_bler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    ler_d(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(le)
+
+static jit_word_t
+_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    eqr_d(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(eq)
+
+static jit_word_t
+_bger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    ger_d(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(ge)
+
+static jit_word_t
+_bgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    gtr_d(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(gt)
+
+static jit_word_t
+_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    eqr_d(rn(t0), r1, r2);
+    w = beqr(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(ne)
+
+static jit_word_t
+_bunltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    unltr_d(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(unlt)
+
+static jit_word_t
+_bunler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    unler_d(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(unle)
+
+static jit_word_t
+_buneqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    uneqr_d(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(uneq)
+
+static jit_word_t
+_bunger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    unger_d(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(unge)
+
+static jit_word_t
+_bungtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    ungtr_d(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(ungt)
+
+static jit_word_t
+_bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    ltgtr_d(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(ltgt)
+
+static jit_word_t
+_bordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    ordr_d(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(ord)
+
+static jit_word_t
+_bunordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t		w;
+    jit_int32_t		t0;
+    t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
+    unordr_d(rn(t0), r1, r2);
+    w = bner(i0, _ZERO_REGNO, rn(t0));
+    jit_unget_reg(t0);
+    return (w);
+}
+dbopi(unord)
+
+static void
+_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+    assert(_jitc->function->self.call & jit_call_varargs);
+    /* Load argument. */
+    ldr_d(r0, r1);
+    /* Update va_list. */
+    addi(r1, r1, sizeof(jit_float64_t));
+}
+
+#endif /* CODE */
diff --git a/lightening/riscv-sz.c b/lightening/riscv-sz.c
new file mode 100644
index 0000000..2f1d725
--- /dev/null
+++ b/lightening/riscv-sz.c
@@ -0,0 +1,401 @@
+#if __WORDSIZE == 64
+#define JIT_INSTR_MAX 116
+    0,	/* data */
+    0,	/* live */
+    4,	/* align */
+    0,	/* save */
+    0,	/* load */
+    0,	/* #name */
+    0,	/* #note */
+    0,	/* label */
+    112,	/* prolog */
+    0,	/* ellipsis */
+    0,	/* va_push */
+    0,	/* allocai */
+    0,	/* allocar */
+    0,	/* arg */
+    0,	/* getarg_c */
+    0,	/* getarg_uc */
+    0,	/* getarg_s */
+    0,	/* getarg_us */
+    0,	/* getarg_i */
+    0,	/* getarg_ui */
+    0,	/* getarg_l */
+    0,	/* putargr */
+    0,	/* putargi */
+    4,	/* va_start */
+    8,	/* va_arg */
+    8,	/* va_arg_d */
+    0,	/* va_end */
+    4,	/* addr */
+    20,	/* addi */
+    12,	/* addcr */
+    28,	/* addci */
+    28,	/* addxr */
+    28,	/* addxi */
+    4,	/* subr */
+    20,	/* subi */
+    12,	/* subcr */
+    28,	/* subci */
+    28,	/* subxr */
+    28,	/* subxi */
+    28,	/* rsbi */
+    4,	/* mulr */
+    20,	/* muli */
+    12,	/* qmulr */
+    24,	/* qmuli */
+    12,	/* qmulr_u */
+    24,	/* qmuli_u */
+    4,	/* divr */
+    20,	/* divi */
+    4,	/* divr_u */
+    20,	/* divi_u */
+    20,	/* qdivr */
+    16,	/* qdivi */
+    20,	/* qdivr_u */
+    16,	/* qdivi_u */
+    4,	/* remr */
+    20,	/* remi */
+    4,	/* remr_u */
+    20,	/* remi_u */
+    4,	/* andr */
+    20,	/* andi */
+    4,	/* orr */
+    20,	/* ori */
+    4,	/* xorr */
+    20,	/* xori */
+    4,	/* lshr */
+    4,	/* lshi */
+    4,	/* rshr */
+    4,	/* rshi */
+    4,	/* rshr_u */
+    4,	/* rshi_u */
+    4,	/* negr */
+    4,	/* comr */
+    4,	/* ltr */
+    4,	/* lti */
+    4,	/* ltr_u */
+    4,	/* lti_u */
+    8,	/* ler */
+    12,	/* lei */
+    8,	/* ler_u */
+    12,	/* lei_u */
+    12,	/* eqr */
+    12,	/* eqi */
+    8,	/* ger */
+    12,	/* gei */
+    8,	/* ger_u */
+    12,	/* gei_u */
+    4,	/* gtr */
+    8,	/* gti */
+    4,	/* gtr_u */
+    8,	/* gti_u */
+    8,	/* ner */
+    8,	/* nei */
+    4,	/* movr */
+    24,	/* movi */
+    8,	/* extr_c */
+    4,	/* extr_uc */
+    8,	/* extr_s */
+    8,	/* extr_us */
+    4,	/* extr_i */
+    8,	/* extr_ui */
+    20,	/* htonr_us */
+    52,	/* htonr_ui */
+    116,	/* htonr_ul */
+    4,	/* ldr_c */
+    12,	/* ldi_c */
+    4,	/* ldr_uc */
+    12,	/* ldi_uc */
+    4,	/* ldr_s */
+    12,	/* ldi_s */
+    4,	/* ldr_us */
+    12,	/* ldi_us */
+    4,	/* ldr_i */
+    12,	/* ldi_i */
+    4,	/* ldr_ui */
+    12,	/* ldi_ui */
+    4,	/* ldr_l */
+    12,	/* ldi_l */
+    8,	/* ldxr_c */
+    16,	/* ldxi_c */
+    8,	/* ldxr_uc */
+    16,	/* ldxi_uc */
+    8,	/* ldxr_s */
+    16,	/* ldxi_s */
+    8,	/* ldxr_us */
+    16,	/* ldxi_us */
+    8,	/* ldxr_i */
+    16,	/* ldxi_i */
+    8,	/* ldxr_ui */
+    16,	/* ldxi_ui */
+    8,	/* ldxr_l */
+    16,	/* ldxi_l */
+    4,	/* str_c */
+    12,	/* sti_c */
+    4,	/* str_s */
+    12,	/* sti_s */
+    4,	/* str_i */
+    12,	/* sti_i */
+    4,	/* str_l */
+    12,	/* sti_l */
+    8,	/* stxr_c */
+    16,	/* stxi_c */
+    8,	/* stxr_s */
+    16,	/* stxi_s */
+    8,	/* stxr_i */
+    16,	/* stxi_i */
+    8,	/* stxr_l */
+    16,	/* stxi_l */
+    4,	/* bltr */
+    8,	/* blti */
+    4,	/* bltr_u */
+    8,	/* blti_u */
+    4,	/* bler */
+    8,	/* blei */
+    4,	/* bler_u */
+    8,	/* blei_u */
+    4,	/* beqr */
+    28,	/* beqi */
+    4,	/* bger */
+    8,	/* bgei */
+    4,	/* bger_u */
+    8,	/* bgei_u */
+    4,	/* bgtr */
+    8,	/* bgti */
+    4,	/* bgtr_u */
+    8,	/* bgti_u */
+    4,	/* bner */
+    20,	/* bnei */
+    8,	/* bmsr */
+    12,	/* bmsi */
+    8,	/* bmcr */
+    12,	/* bmci */
+    32,	/* boaddr */
+    36,	/* boaddi */
+    16,	/* boaddr_u */
+    20,	/* boaddi_u */
+    32,	/* bxaddr */
+    36,	/* bxaddi */
+    16,	/* bxaddr_u */
+    20,	/* bxaddi_u */
+    32,	/* bosubr */
+    36,	/* bosubi */
+    16,	/* bosubr_u */
+    20,	/* bosubi_u */
+    32,	/* bxsubr */
+    36,	/* bxsubi */
+    16,	/* bxsubr_u */
+    20,	/* bxsubi_u */
+    4,	/* jmpr */
+    28,	/* jmpi */
+    4,	/* callr */
+    28,	/* calli */
+    0,	/* prepare */
+    0,	/* pushargr */
+    0,	/* pushargi */
+    0,	/* finishr */
+    0,	/* finishi */
+    0,	/* ret */
+    0,	/* retr */
+    0,	/* reti */
+    0,	/* retval_c */
+    0,	/* retval_uc */
+    0,	/* retval_s */
+    0,	/* retval_us */
+    0,	/* retval_i */
+    0,	/* retval_ui */
+    0,	/* retval_l */
+    112,	/* epilog */
+    0,	/* arg_f */
+    0,	/* getarg_f */
+    0,	/* putargr_f */
+    0,	/* putargi_f */
+    4,	/* addr_f */
+    12,	/* addi_f */
+    4,	/* subr_f */
+    12,	/* subi_f */
+    12,	/* rsbi_f */
+    4,	/* mulr_f */
+    12,	/* muli_f */
+    4,	/* divr_f */
+    12,	/* divi_f */
+    4,	/* negr_f */
+    4,	/* absr_f */
+    4,	/* sqrtr_f */
+    4,	/* ltr_f */
+    12,	/* lti_f */
+    4,	/* ler_f */
+    12,	/* lei_f */
+    4,	/* eqr_f */
+    12,	/* eqi_f */
+    4,	/* ger_f */
+    12,	/* gei_f */
+    4,	/* gtr_f */
+    12,	/* gti_f */
+    8,	/* ner_f */
+    16,	/* nei_f */
+    28,	/* unltr_f */
+    36,	/* unlti_f */
+    28,	/* unler_f */
+    36,	/* unlei_f */
+    28,	/* uneqr_f */
+    36,	/* uneqi_f */
+    28,	/* unger_f */
+    36,	/* ungei_f */
+    28,	/* ungtr_f */
+    36,	/* ungti_f */
+    40,	/* ltgtr_f */
+    48,	/* ltgti_f */
+    28,	/* ordr_f */
+    36,	/* ordi_f */
+    20,	/* unordr_f */
+    28,	/* unordi_f */
+    4,	/* truncr_f_i */
+    4,	/* truncr_f_l */
+    4,	/* extr_f */
+    4,	/* extr_d_f */
+    4,	/* movr_f */
+    8,	/* movi_f */
+    4,	/* ldr_f */
+    12,	/* ldi_f */
+    8,	/* ldxr_f */
+    16,	/* ldxi_f */
+    4,	/* str_f */
+    12,	/* sti_f */
+    8,	/* stxr_f */
+    16,	/* stxi_f */
+    8,	/* bltr_f */
+    16,	/* blti_f */
+    8,	/* bler_f */
+    16,	/* blei_f */
+    8,	/* beqr_f */
+    16,	/* beqi_f */
+    8,	/* bger_f */
+    16,	/* bgei_f */
+    8,	/* bgtr_f */
+    16,	/* bgti_f */
+    8,	/* bner_f */
+    16,	/* bnei_f */
+    32,	/* bunltr_f */
+    40,	/* bunlti_f */
+    32,	/* bunler_f */
+    40,	/* bunlei_f */
+    32,	/* buneqr_f */
+    40,	/* buneqi_f */
+    32,	/* bunger_f */
+    40,	/* bungei_f */
+    32,	/* bungtr_f */
+    40,	/* bungti_f */
+    44,	/* bltgtr_f */
+    52,	/* bltgti_f */
+    32,	/* bordr_f */
+    40,	/* bordi_f */
+    24,	/* bunordr_f */
+    32,	/* bunordi_f */
+    0,	/* pushargr_f */
+    0,	/* pushargi_f */
+    0,	/* retr_f */
+    0,	/* reti_f */
+    0,	/* retval_f */
+    0,	/* arg_d */
+    0,	/* getarg_d */
+    0,	/* putargr_d */
+    0,	/* putargi_d */
+    4,	/* addr_d */
+    24,	/* addi_d */
+    4,	/* subr_d */
+    24,	/* subi_d */
+    24,	/* rsbi_d */
+    4,	/* mulr_d */
+    24,	/* muli_d */
+    4,	/* divr_d */
+    24,	/* divi_d */
+    4,	/* negr_d */
+    4,	/* absr_d */
+    4,	/* sqrtr_d */
+    4,	/* ltr_d */
+    24,	/* lti_d */
+    4,	/* ler_d */
+    24,	/* lei_d */
+    4,	/* eqr_d */
+    24,	/* eqi_d */
+    4,	/* ger_d */
+    24,	/* gei_d */
+    4,	/* gtr_d */
+    24,	/* gti_d */
+    8,	/* ner_d */
+    28,	/* nei_d */
+    28,	/* unltr_d */
+    48,	/* unlti_d */
+    28,	/* unler_d */
+    48,	/* unlei_d */
+    28,	/* uneqr_d */
+    48,	/* uneqi_d */
+    28,	/* unger_d */
+    48,	/* ungei_d */
+    28,	/* ungtr_d */
+    48,	/* ungti_d */
+    40,	/* ltgtr_d */
+    60,	/* ltgti_d */
+    28,	/* ordr_d */
+    48,	/* ordi_d */
+    20,	/* unordr_d */
+    40,	/* unordi_d */
+    4,	/* truncr_d_i */
+    4,	/* truncr_d_l */
+    4,	/* extr_d */
+    4,	/* extr_f_d */
+    4,	/* movr_d */
+    20,	/* movi_d */
+    4,	/* ldr_d */
+    12,	/* ldi_d */
+    8,	/* ldxr_d */
+    16,	/* ldxi_d */
+    4,	/* str_d */
+    12,	/* sti_d */
+    8,	/* stxr_d */
+    16,	/* stxi_d */
+    8,	/* bltr_d */
+    28,	/* blti_d */
+    8,	/* bler_d */
+    28,	/* blei_d */
+    8,	/* beqr_d */
+    28,	/* beqi_d */
+    8,	/* bger_d */
+    28,	/* bgei_d */
+    8,	/* bgtr_d */
+    28,	/* bgti_d */
+    8,	/* bner_d */
+    28,	/* bnei_d */
+    32,	/* bunltr_d */
+    52,	/* bunlti_d */
+    32,	/* bunler_d */
+    52,	/* bunlei_d */
+    32,	/* buneqr_d */
+    52,	/* buneqi_d */
+    32,	/* bunger_d */
+    52,	/* bungei_d */
+    32,	/* bungtr_d */
+    52,	/* bungti_d */
+    44,	/* bltgtr_d */
+    64,	/* bltgti_d */
+    32,	/* bordr_d */
+    52,	/* bordi_d */
+    24,	/* bunordr_d */
+    44,	/* bunordi_d */
+    0,	/* pushargr_d */
+    0,	/* pushargi_d */
+    0,	/* retr_d */
+    0,	/* reti_d */
+    0,	/* retval_d */
+    4,	/* movr_w_f */
+    0,	/* movr_ww_d */
+    4,	/* movr_w_d */
+    0,	/* movr_f_w */
+    4,	/* movi_f_w */
+    0,	/* movr_d_ww */
+    0,	/* movi_d_ww */
+    4,	/* movr_d_w */
+    16,	/* movi_d_w */
+#endif /* __WORDSIZE */
diff --git a/lightening/riscv.c b/lightening/riscv.c
new file mode 100644
index 0000000..0efca1e
--- /dev/null
+++ b/lightening/riscv.c
@@ -0,0 +1,1621 @@
+/*
+ * Copyright (C) 2019,2021  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_RA0		_A0
+#define JIT_FA0		_FA0
+#define JIT_SP		_SP
+#define JIT_RET		_A0
+#define JIT_FRET	_FA0
+
+#define jit_arg_reg_p(i)		((i) >= 0 && (i) < 8)
+#define jit_arg_f_reg_p(i)		((i) >= 0 && (i) < 8)
+
+/*
+ * Types
+ */
+typedef jit_pointer_t jit_va_list_t;
+
+/*
+ * Prototypes
+ */
+#define patch(instr, node)		_patch(_jit, instr, node)
+static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
+
+#define PROTO				1
+#  include "riscv-cpu.c"
+#  include "riscv-fpu.c"
+#undef PROTO
+
+/*
+ * Initialization
+ */
+static const jit_register_t		_rvs[] = {
+    { 0x00,				"zero" },
+    { 0x01,				"ra" },
+    { 0x02,				"sp" },
+    { 0x03,				"gp" },
+#if 0		/* Pretend it does not exist, so _NOREG can be used in
+		 * a 64 bit bitmask */
+    { 0x04,				"tp" },
+#endif
+    { rc(gpr) | 0x05,			"t0" },
+    { rc(gpr) | 0x06,			"t1" },
+    { rc(gpr) | 0x07,			"t2" },
+    { rc(gpr) | 0x1c,			"t3" },
+    { rc(gpr) | 0x1d,			"t4" },
+    { rc(gpr) | 0x1e,			"t5" },
+    { rc(gpr) | 0x1f,			"t6" },
+    { 0x08,				"fp" },
+    { rc(sav) | rc(gpr) | 0x09,		"s1" },
+    { rc(sav) | rc(gpr) | 0x12,		"s2" },
+    { rc(sav) | rc(gpr) | 0x13,		"s3" },
+    { rc(sav) | rc(gpr) | 0x14,		"s4" },
+    { rc(sav) | rc(gpr) | 0x15,		"s5" },
+    { rc(sav) | rc(gpr) | 0x16,		"s6" },
+    { rc(sav) | rc(gpr) | 0x17,		"s7" },
+    { rc(sav) | rc(gpr) | 0x18,		"s8" },
+    { rc(sav) | rc(gpr) | 0x19,		"s9" },
+    { rc(sav) | rc(gpr) | 0x1a,		"s10" },
+    { rc(sav) | rc(gpr) | 0x1b,		"s11" },
+    { rc(arg) | rc(gpr) | 0x11,		"a7" },
+    { rc(arg) | rc(gpr) | 0x10,		"a6" },
+    { rc(arg) | rc(gpr) | 0x0f,		"a5" },
+    { rc(arg) | rc(gpr) | 0x0e,		"a4" },
+    { rc(arg) | rc(gpr) | 0x0d,		"a3" },
+    { rc(arg) | rc(gpr) | 0x0c,		"a2" },
+    { rc(arg) | rc(gpr) | 0x0b,		"a1" },
+    { rc(arg) | rc(gpr) | 0x0a,		"a0" },
+    { rc(fpr) | 0x00,			"ft0" },
+    { rc(fpr) | 0x01,			"ft1" },
+    { rc(fpr) | 0x02,			"ft2" },
+    { rc(fpr) | 0x03,			"ft3" },
+    { rc(fpr) | 0x04,			"ft4" },
+    { rc(fpr) | 0x05,			"ft5" },
+    { rc(fpr) | 0x06,			"ft6" },
+    { rc(fpr) | 0x07,			"ft7" },
+    { rc(fpr) | 0x1c,			"ft8" },
+    { rc(fpr) | 0x1d,			"ft9" },
+    { rc(fpr) | 0x1e,			"ft10" },
+    { rc(fpr) | 0x1f,			"ft11" },
+    { rc(sav) | rc(fpr) | 0x08,		"fs0" },
+    { rc(sav) | rc(fpr) | 0x09,		"fs1" },
+    { rc(sav) | rc(fpr) | 0x12,		"fs2" },
+    { rc(sav) | rc(fpr) | 0x13,		"fs3" },
+    { rc(sav) | rc(fpr) | 0x14,		"fs4" },
+    { rc(sav) | rc(fpr) | 0x15,		"fs5" },
+    { rc(sav) | rc(fpr) | 0x16,		"fs6" },
+    { rc(sav) | rc(fpr) | 0x17,		"fs7" },
+    { rc(sav) | rc(fpr) | 0x18,		"fs8" },
+    { rc(sav) | rc(fpr) | 0x19,		"fs9" },
+    { rc(sav) | rc(fpr) | 0x1a,		"fs10" },
+    { rc(sav) | rc(fpr) | 0x1b,		"fs11" },
+    { rc(arg) | rc(fpr) | 0x11,		"fa7" },
+    { rc(arg) | rc(fpr) | 0x10,		"fa6" },
+    { rc(arg) | rc(fpr) | 0x0f,		"fa5" },
+    { rc(arg) | rc(fpr) | 0x0e,		"fa4" },
+    { rc(arg) | rc(fpr) | 0x0d,		"fa3" },
+    { rc(arg) | rc(fpr) | 0x0c,		"fa2" },
+    { rc(arg) | rc(fpr) | 0x0b,		"fa1" },
+    { rc(arg) | rc(fpr) | 0x0a,		"fa0" },
+    { _NOREG,				"<none>" },
+};
+
+/*
+ * Implementation
+ */
+void
+jit_get_cpu(void)
+{
+}
+
+void
+_jit_init(jit_state_t *_jit)
+{
+    _jitc->reglen = jit_size(_rvs) - 1;
+    jit_carry = _NOREG;
+}
+
+void
+_jit_prolog(jit_state_t *_jit)
+{
+    int32_t		 offset;
+
+    if (_jitc->function)
+	jit_epilog();
+    assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
+    jit_regset_set_ui(&_jitc->regsav, 0);
+    offset = _jitc->functions.offset;
+    if (offset >= _jitc->functions.length) {
+	jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
+		    _jitc->functions.length * sizeof(jit_function_t),
+		    (_jitc->functions.length + 16) * sizeof(jit_function_t));
+	_jitc->functions.length += 16;
+    }
+    _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
+    _jitc->function->self.size = stack_framesize;
+    _jitc->function->self.argi = _jitc->function->self.argf =
+	_jitc->function->self.alen = 0;
+    _jitc->function->self.aoff = 0;
+    _jitc->function->self.call = jit_call_default;
+    jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
+	      _jitc->reglen * sizeof(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);
+}
+
+int32_t
+_jit_allocai(jit_state_t *_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, int32_t u, int32_t v)
+{
+    int32_t		 r0;
+    assert(_jitc->function);
+    jit_inc_synth_ww(allocar, u, v);
+    if (!_jitc->function->allocar) {
+	_jitc->function->aoffoff = jit_allocai(sizeof(int32_t));
+	_jitc->function->allocar = 1;
+    }
+    r0 = jit_get_reg(jit_class_gpr);
+    jit_negr(r0, v);
+    jit_andi(r0, r0, -16);
+    jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff);
+    jit_addr(u, u, r0);
+    jit_addr(JIT_SP, JIT_SP, r0);
+    jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u);
+    jit_unget_reg(r0);
+    jit_dec_synth();
+}
+
+void
+_jit_ret(jit_state_t *_jit)
+{
+    jit_node_t		*instr;
+    assert(_jitc->function);
+    jit_inc_synth(ret);
+    /* jump to epilog */
+    instr = jit_jmpi();
+    jit_patch_at(instr, _jitc->function->epilog);
+    jit_dec_synth();
+}
+
+void
+_jit_retr(jit_state_t *_jit, 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, int32_t u)
+{
+    jit_inc_synth_w(retr_f, u);
+    if (u != JIT_FRET)
+	jit_movr_f(JIT_FRET, u);
+    else
+	jit_live(JIT_FRET);
+    jit_ret();
+    jit_dec_synth();
+}
+
+void
+_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
+{
+    jit_inc_synth_f(reti_f, u);
+    jit_movi_f(JIT_FRET, u);
+    jit_ret();
+    jit_dec_synth();
+}
+
+void
+_jit_retr_d(jit_state_t *_jit, int32_t u)
+{
+    jit_inc_synth_w(retr_d, u);
+    if (u != JIT_FRET)
+	jit_movr_d(JIT_FRET, u);
+    else
+	jit_live(JIT_FRET);
+    jit_ret();
+    jit_dec_synth();
+}
+
+void
+_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
+{
+    jit_inc_synth_d(reti_d, u);
+    jit_movi_d(JIT_FRET, u);
+    jit_ret();
+    jit_dec_synth();
+}
+
+void
+_jit_epilog(jit_state_t *_jit)
+{
+    assert(_jitc->function);
+    assert(_jitc->function->epilog->next == NULL);
+    jit_link(_jitc->function->epilog);
+    _jitc->function = NULL;
+}
+
+jit_bool_t
+_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
+{
+    if (u->code == jit_code_arg)
+	return (jit_arg_reg_p(u->u.w));
+    assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d);
+    return (jit_arg_f_reg_p(u->u.w));
+}
+
+void
+_jit_ellipsis(jit_state_t *_jit)
+{
+    jit_inc_synth(ellipsis);
+    if (_jitc->prepare) {
+	jit_link_prepare();
+	assert(!(_jitc->function->call.call & jit_call_varargs));
+	_jitc->function->call.call |= jit_call_varargs;
+    }
+    else {
+	jit_link_prolog();
+	assert(!(_jitc->function->self.call & jit_call_varargs));
+	_jitc->function->self.call |= jit_call_varargs;
+	_jitc->function->vagp = _jitc->function->self.argi;
+    }
+    jit_dec_synth();
+}
+
+void
+_jit_va_push(jit_state_t *_jit, 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;
+    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;
+    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;
+    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, int32_t u, jit_node_t *v)
+{
+    assert(v->code == jit_code_arg);
+    jit_inc_synth_wp(getarg_c, u, v);
+    if (jit_arg_reg_p(v->u.w))
+	jit_extr_c(u, JIT_RA0 - v->u.w);
+    else
+	jit_ldxi_c(u, JIT_FP, v->u.w);
+    jit_dec_synth();
+}
+
+void
+_jit_getarg_uc(jit_state_t *_jit, int32_t u, jit_node_t *v)
+{
+    assert(v->code == jit_code_arg);
+    jit_inc_synth_wp(getarg_uc, u, v);
+    if (jit_arg_reg_p(v->u.w))
+	jit_extr_uc(u, JIT_RA0 - v->u.w);
+    else
+	jit_ldxi_uc(u, JIT_FP, v->u.w);
+    jit_dec_synth();
+}
+
+void
+_jit_getarg_s(jit_state_t *_jit, int32_t u, jit_node_t *v)
+{
+    assert(v->code == jit_code_arg);
+    jit_inc_synth_wp(getarg_s, u, v);
+    if (jit_arg_reg_p(v->u.w))
+	jit_extr_s(u, JIT_RA0 - v->u.w);
+    else
+	jit_ldxi_s(u, JIT_FP, v->u.w);
+    jit_dec_synth();
+}
+
+void
+_jit_getarg_us(jit_state_t *_jit, int32_t u, jit_node_t *v)
+{
+    assert(v->code == jit_code_arg);
+    jit_inc_synth_wp(getarg_us, u, v);
+    if (jit_arg_reg_p(v->u.w))
+	jit_extr_us(u, JIT_RA0 - v->u.w);
+    else
+	jit_ldxi_us(u, JIT_FP, v->u.w);
+    jit_dec_synth();
+}
+
+void
+_jit_getarg_i(jit_state_t *_jit, int32_t u, jit_node_t *v)
+{
+    assert(v->code == jit_code_arg);
+    jit_inc_synth_wp(getarg_i, u, v);
+    if (jit_arg_reg_p(v->u.w))
+	jit_extr_i(u, JIT_RA0 - v->u.w);
+    else
+	jit_ldxi_i(u, JIT_FP, v->u.w);
+    jit_dec_synth();
+}
+
+void
+_jit_getarg_ui(jit_state_t *_jit, int32_t u, jit_node_t *v)
+{
+    assert(v->code == jit_code_arg);
+    jit_inc_synth_wp(getarg_ui, u, v);
+    if (jit_arg_reg_p(v->u.w))
+	jit_extr_ui(u, JIT_RA0 - v->u.w);
+    else
+	jit_ldxi_ui(u, JIT_FP, v->u.w);
+    jit_dec_synth();
+}
+
+void
+_jit_getarg_l(jit_state_t *_jit, int32_t u, jit_node_t *v)
+{
+    assert(v->code == jit_code_arg);
+    jit_inc_synth_wp(getarg_l, u, v);
+    if (jit_arg_reg_p(v->u.w))
+	jit_movr(u, JIT_RA0 - v->u.w);
+    else
+	jit_ldxi_l(u, JIT_FP, v->u.w);
+    jit_dec_synth();
+}
+
+void
+_jit_putargr(jit_state_t *_jit, int32_t u, jit_node_t *v)
+{
+    assert(v->code == jit_code_arg);
+    jit_inc_synth_wp(putargr, u, v);
+    if (jit_arg_reg_p(v->u.w))
+	jit_movr(JIT_RA0 - v->u.w, u);
+    else
+	jit_stxi(v->u.w, JIT_FP, u);
+    jit_dec_synth();
+}
+
+void
+_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
+{
+    int32_t		regno;
+    assert(v->code == jit_code_arg);
+    jit_inc_synth_wp(putargi, u, v);
+    if (jit_arg_reg_p(v->u.w))
+	jit_movi(JIT_RA0 - v->u.w, u);
+    else {
+	regno = jit_get_reg(jit_class_gpr);
+	jit_movi(regno, u);
+	jit_stxi(v->u.w, JIT_FP, regno);
+	jit_unget_reg(regno);
+    }
+    jit_dec_synth();
+}
+
+void
+_jit_getarg_f(jit_state_t *_jit, int32_t u, jit_node_t *v)
+{
+    assert(v->code == jit_code_arg_f);
+    jit_inc_synth_wp(getarg_f, u, v);
+    if (jit_arg_f_reg_p(v->u.w))
+	jit_movr_f(u, JIT_FA0 - v->u.w);
+    else if (jit_arg_reg_p(v->u.w - 8))
+	jit_movr_w_f(u, JIT_RA0 - (v->u.w - 8));
+    else
+	jit_ldxi_f(u, JIT_FP, v->u.w);
+    jit_dec_synth();
+}
+
+void
+_jit_putargr_f(jit_state_t *_jit, int32_t u, jit_node_t *v)
+{
+    assert(v->code == jit_code_arg_f);
+    jit_inc_synth_wp(putargr_f, u, v);
+    if (jit_arg_f_reg_p(v->u.w))
+	jit_movr_f(JIT_FA0 - v->u.w, u);
+    else if (jit_arg_reg_p(v->u.w - 8))
+	jit_movr_f_w(JIT_RA0 - (v->u.w - 8), u);
+    else
+	jit_stxi_f(v->u.w, JIT_FP, u);
+    jit_dec_synth();
+}
+
+void
+_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
+{
+    int32_t		regno;
+    assert(v->code == jit_code_arg_f);
+    jit_inc_synth_fp(putargi_f, u, v);
+    if (jit_arg_f_reg_p(v->u.w))
+	jit_movi_f(JIT_FA0 - v->u.w, u);
+    else if (jit_arg_reg_p(v->u.w - 8)) {
+	union {
+	    jit_float32_t	f;
+	    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, int32_t u, jit_node_t *v)
+{
+    assert(v->code == jit_code_arg_d);
+    jit_inc_synth_wp(getarg_d, u, v);
+    if (jit_arg_f_reg_p(v->u.w))
+	jit_movr_d(u, JIT_FA0 - v->u.w);
+    else if (jit_arg_reg_p(v->u.w - 8))
+	jit_movr_w_d(u, JIT_RA0 - (v->u.w - 8));
+    else
+	jit_ldxi_d(u, JIT_FP, v->u.w);
+    jit_dec_synth();
+}
+
+void
+_jit_putargr_d(jit_state_t *_jit, int32_t u, jit_node_t *v)
+{
+    assert(v->code == jit_code_arg_d);
+    jit_inc_synth_wp(putargr_d, u, v);
+    if (jit_arg_reg_p(v->u.w))
+	jit_movr_d(JIT_FA0 - v->u.w, u);
+    else if (jit_arg_reg_p(v->u.w - 8))
+	jit_movr_d_w(JIT_RA0 - (v->u.w - 8), u);
+    else
+	jit_stxi_d(v->u.w, JIT_FP, u);
+    jit_dec_synth();
+}
+
+void
+_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
+{
+    int32_t		regno;
+    assert(v->code == jit_code_arg_d);
+    jit_inc_synth_dp(putargi_d, u, v);
+    if (jit_arg_reg_p(v->u.w))
+	jit_movi_d(JIT_FA0 - v->u.w, u);
+    else if (jit_arg_reg_p(v->u.w - 8)) {
+	union {
+	    jit_float64_t	d;
+	    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, int32_t u)
+{
+    assert(_jitc->function);
+    jit_inc_synth_w(pushargr, u);
+    jit_link_prepare();
+    if (jit_arg_reg_p(_jitc->function->call.argi)) {
+	jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
+	++_jitc->function->call.argi;
+    }
+    else {
+	jit_stxi(_jitc->function->call.size, JIT_SP, u);
+	_jitc->function->call.size += sizeof(jit_word_t);
+    }
+    jit_dec_synth();
+}
+
+void
+_jit_pushargi(jit_state_t *_jit, jit_word_t u)
+{
+    int32_t		 regno;
+    assert(_jitc->function);
+    jit_inc_synth_w(pushargi, u);
+    jit_link_prepare();
+    if (jit_arg_reg_p(_jitc->function->call.argi)) {
+	jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
+	++_jitc->function->call.argi;
+    }
+    else {
+	regno = jit_get_reg(jit_class_gpr);
+	jit_movi(regno, u);
+	jit_stxi(_jitc->function->call.size, JIT_SP, regno);
+	jit_unget_reg(regno);
+	_jitc->function->call.size += sizeof(jit_word_t);
+    }
+    jit_dec_synth();
+}
+
+void
+_jit_pushargr_f(jit_state_t *_jit, int32_t u)
+{
+    assert(_jitc->function);
+    jit_inc_synth_w(pushargr_f, u);
+    jit_link_prepare();
+    if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
+	!(_jitc->function->call.call & jit_call_varargs)) {
+	jit_movr_f(JIT_FA0 - _jitc->function->call.argf, u);
+	++_jitc->function->call.argf;
+    }
+    else if (jit_arg_reg_p(_jitc->function->call.argi)) {
+	jit_movr_f_w(JIT_RA0 - _jitc->function->call.argi, u);
+	++_jitc->function->call.argi;
+    }
+    else {
+	jit_stxi_f(_jitc->function->call.size, JIT_SP, u);
+	_jitc->function->call.size += sizeof(jit_word_t);
+    }
+    jit_dec_synth();
+}
+
+void
+_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
+{
+    int32_t		regno;
+    assert(_jitc->function);
+    jit_inc_synth_f(pushargi_f, u);
+    jit_link_prepare();
+    if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
+	!(_jitc->function->call.call & jit_call_varargs)) {
+	jit_movi_f(JIT_FA0 - _jitc->function->call.argf, u);
+	++_jitc->function->call.argf;
+    }
+    else if (jit_arg_reg_p(_jitc->function->call.argi)) {
+	jit_movi_f_w(JIT_RA0 - _jitc->function->call.argi, u);
+	++_jitc->function->call.argi;
+    }
+    else {
+	regno = jit_get_reg(jit_class_fpr);
+	jit_movi_f(regno, u);
+ 	jit_stxi_f(_jitc->function->call.size, JIT_SP, regno);
+	jit_unget_reg(regno);
+	_jitc->function->call.size += sizeof(jit_word_t);
+    }
+    jit_dec_synth();
+}
+
+void
+_jit_pushargr_d(jit_state_t *_jit, int32_t u)
+{
+    assert(_jitc->function);
+    jit_inc_synth_w(pushargr_d, u);
+    jit_link_prepare();
+    if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
+	!(_jitc->function->call.call & jit_call_varargs)) {
+	jit_movr_d(JIT_FA0 - _jitc->function->call.argf, u);
+	++_jitc->function->call.argf;
+    }
+    else if (jit_arg_reg_p(_jitc->function->call.argi)) {
+	jit_movr_d_w(JIT_RA0 - _jitc->function->call.argi, u);
+	++_jitc->function->call.argi;
+    }
+    else {
+	jit_stxi_d(_jitc->function->call.size, JIT_SP, u);
+	_jitc->function->call.size += sizeof(jit_word_t);
+    }
+    jit_dec_synth();
+}
+
+void
+_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
+{
+    int32_t		regno;
+    assert(_jitc->function);
+    jit_inc_synth_d(pushargi_d, u);
+    jit_link_prepare();
+    if (jit_arg_f_reg_p(_jitc->function->call.argf) &&
+	!(_jitc->function->call.call & jit_call_varargs)) {
+	jit_movi_d(JIT_FA0 - _jitc->function->call.argf, u);
+	++_jitc->function->call.argf;
+    }
+    else if (jit_arg_reg_p(_jitc->function->call.argi)) {
+	jit_movi_d_w(JIT_RA0 - _jitc->function->call.argi, u);
+	++_jitc->function->call.argi;
+    }
+    else {
+	regno = jit_get_reg(jit_class_fpr);
+	jit_movi_d(regno, u);
+ 	jit_stxi_d(_jitc->function->call.size, JIT_SP, regno);
+	jit_unget_reg(regno);
+	_jitc->function->call.size += sizeof(jit_word_t);
+    }
+    jit_dec_synth();
+}
+
+jit_bool_t
+_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, int32_t regno)
+{
+    int32_t		spec;
+    spec = jit_class(_rvs[regno].spec);
+    if (spec & jit_class_arg) {
+	regno = JIT_RA0 - regno;
+	if (regno >= 0 && regno < node->v.w)
+	    return (1);
+	if (spec & jit_class_fpr) {
+	    regno = JIT_FA0 - regno;
+	    if (regno >= 0 && regno < node->w.w)
+		return (1);
+	}
+    }
+
+    return (0);
+}
+
+void
+_jit_finishr(jit_state_t *_jit, int32_t r0)
+{
+    jit_node_t		*node;
+    assert(_jitc->function);
+    jit_inc_synth_w(finishr, r0);
+    if (_jitc->function->self.alen < _jitc->function->call.size)
+	_jitc->function->self.alen = _jitc->function->call.size;
+    node = jit_callr(r0);
+    node->v.w = _jitc->function->self.argi;
+    node->w.w = _jitc->function->call.argf;
+    _jitc->function->call.argi = _jitc->function->call.argf =
+	_jitc->function->call.size = 0;
+    _jitc->prepare = 0;
+    jit_dec_synth();
+}
+
+jit_node_t *
+_jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
+{
+    jit_node_t		*node;
+    assert(_jitc->function);
+    jit_inc_synth_w(finishi, (jit_word_t)i0);
+    if (_jitc->function->self.alen < _jitc->function->call.size)
+	_jitc->function->self.alen = _jitc->function->call.size;
+    node = jit_calli(i0);
+    node->v.w = _jitc->function->call.argi;
+    node->w.w = _jitc->function->call.argf;
+    _jitc->function->call.argi = _jitc->function->call.argf =
+	_jitc->function->call.size = 0;
+    _jitc->prepare = 0;
+    jit_dec_synth();
+    return (node);
+}
+
+void
+_jit_retval_c(jit_state_t *_jit, 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, 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, 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, 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, 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, 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, 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, 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, int32_t r0)
+{
+    jit_inc_synth_w(retval_d, r0);
+    if (r0 != JIT_FRET)
+	jit_movr_d(r0, JIT_FRET);
+    jit_dec_synth();
+}
+
+jit_pointer_t
+_emit_code(jit_state_t *_jit)
+{
+    jit_node_t		*node;
+    jit_node_t		*temp;
+    jit_word_t		 word;
+    jit_word_t		 value;
+    int32_t		 offset;
+    struct {
+	jit_node_t	*node;
+	uint8_t		*data;
+	jit_word_t	 word;
+#if DEVEL_DISASSEMBLER
+	jit_word_t	 prevw;
+#endif
+	int32_t	 const_offset;
+	int32_t	 patch_offset;
+    } undo;
+#if DEVEL_DISASSEMBLER
+    jit_word_t		 prevw;
+#endif
+
+    _jitc->function = NULL;
+
+    jit_reglive_setup();
+
+    undo.word = 0;
+    undo.node = NULL;
+    undo.const_offset = undo.patch_offset = 0;
+#  define assert_data(node)		/**/
+#define case_rr(name, type)						\
+	    case jit_code_##name##r##type:				\
+		name##r##type(rn(node->u.w), rn(node->v.w));		\
+		break
+#define case_rw(name, type)						\
+	    case jit_code_##name##i##type:				\
+		name##i##type(rn(node->u.w), node->v.w);		\
+		break
+#define case_wr(name, type)						\
+	    case jit_code_##name##i##type:				\
+		name##i##type(node->u.w, rn(node->v.w));		\
+		break
+#define case_rrr(name, type)						\
+	    case jit_code_##name##r##type:				\
+		name##r##type(rn(node->u.w),				\
+			      rn(node->v.w), rn(node->w.w));		\
+		break
+#define case_rrrr(name, type)						\
+	    case jit_code_##name##r##type:				\
+		name##r##type(rn(node->u.q.l), rn(node->u.q.h),		\
+			      rn(node->v.w), rn(node->w.w));		\
+		break
+#define case_rrw(name, type)						\
+	    case jit_code_##name##i##type:				\
+		name##i##type(rn(node->u.w), rn(node->v.w), node->w.w);	\
+		break
+#define case_rrrw(name, type)						\
+	    case jit_code_##name##i##type:				\
+		name##i##type(rn(node->u.q.l), rn(node->u.q.h),		\
+			      rn(node->v.w), node->w.w);		\
+		break
+#define case_rrf(name)							\
+	    case jit_code_##name##i_f:					\
+		assert_data(node);					\
+		name##i_f(rn(node->u.w), rn(node->v.w), node->w.f);	\
+		break
+#define case_rrd(name)							\
+	    case jit_code_##name##i_d:					\
+		assert_data(node);					\
+		name##i_d(rn(node->u.w), rn(node->v.w), node->w.d);	\
+		break
+#define case_wrr(name, type)						\
+	    case jit_code_##name##i##type:				\
+		name##i##type(node->u.w, rn(node->v.w), rn(node->w.w));	\
+		break
+#define case_brr(name, type)						\
+	    case jit_code_##name##r##type:				\
+		temp = node->u.n;					\
+		assert(temp->code == jit_code_label ||			\
+		       temp->code == jit_code_epilog);			\
+		if (temp->flag & jit_flag_patch)			\
+		    name##r##type(temp->u.w, rn(node->v.w),		\
+				  rn(node->w.w));			\
+		else {							\
+		    word = name##r##type(_jit->pc.w,			\
+					 rn(node->v.w), rn(node->w.w));	\
+		    patch(word, node);					\
+		}							\
+		break
+#define case_brw(name, type)						\
+	    case jit_code_##name##i##type:				\
+		temp = node->u.n;					\
+		assert(temp->code == jit_code_label ||			\
+		       temp->code == jit_code_epilog);			\
+		if (temp->flag & jit_flag_patch)			\
+		    name##i##type(temp->u.w,				\
+				  rn(node->v.w), node->w.w);		\
+		else {							\
+		    word = name##i##type(_jit->pc.w,			\
+					 rn(node->v.w), node->w.w);	\
+		    patch(word, node);					\
+		}							\
+		break;
+#define case_brf(name)							\
+	    case jit_code_##name##i_f:					\
+		temp = node->u.n;					\
+		assert(temp->code == jit_code_label ||			\
+		       temp->code == jit_code_epilog);			\
+		if (temp->flag & jit_flag_patch)			\
+		    name##i_f(temp->u.w, rn(node->v.w), node->w.f);	\
+		else {							\
+		    word = name##i_f(_jit->pc.w, rn(node->v.w),		\
+				node->w.f);				\
+		    patch(word, node);					\
+		}							\
+		break
+#define case_brd(name)							\
+	    case jit_code_##name##i_d:					\
+		temp = node->u.n;					\
+		assert(temp->code == jit_code_label ||			\
+		       temp->code == jit_code_epilog);			\
+		if (temp->flag & jit_flag_patch)			\
+		    name##i_d(temp->u.w, rn(node->v.w), node->w.d);	\
+		else {							\
+		    word = name##i_d(_jit->pc.w, rn(node->v.w),		\
+				node->w.d);				\
+		    patch(word, node);					\
+		}							\
+		break
+#if DEVEL_DISASSEMBLER
+    prevw = _jit->pc.w;
+#endif
+    for (node = _jitc->head; node; node = node->next) {
+	if (_jit->pc.uc >= _jitc->code.end)
+	    return (NULL);
+
+#if DEVEL_DISASSEMBLER
+	node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw;
+	prevw = _jit->pc.w;
+#endif
+	value = jit_classify(node->code);
+	jit_regarg_set(node, value);
+	switch (node->code) {
+	    case jit_code_align:
+		assert(!(node->u.w & (node->u.w - 1)) &&
+		       node->u.w <= sizeof(jit_word_t));
+		if (node->u.w == sizeof(jit_word_t) &&
+		    (word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
+		    nop(sizeof(jit_word_t) - word);
+		break;
+	    case jit_code_note:		case jit_code_name:
+		node->u.w = _jit->pc.w;
+		break;
+	    case jit_code_label:
+		/* remember label is defined */
+		node->flag |= jit_flag_patch;
+		node->u.w = _jit->pc.w;
+		break;
+		case_rrr(add,);
+		case_rrw(add,);
+		case_rrr(addc,);
+		case_rrw(addc,);
+		case_rrr(addx,);
+		case_rrw(addx,);
+		case_rrr(sub,);
+		case_rrw(sub,);
+		case_rrr(subc,);
+		case_rrw(subc,);
+		case_rrr(subx,);
+		case_rrw(subx,);
+		case_rrw(rsb,);
+		case_rrr(mul,);
+		case_rrw(mul,);
+		case_rrrr(qmul,);
+		case_rrrw(qmul,);
+		case_rrrr(qmul, _u);
+		case_rrrw(qmul, _u);
+		case_rrr(div,);
+		case_rrw(div,);
+		case_rrr(div, _u);
+		case_rrw(div, _u);
+		case_rrrr(qdiv,);
+		case_rrrw(qdiv,);
+		case_rrrr(qdiv, _u);
+		case_rrrw(qdiv, _u);
+		case_rrr(rem,);
+		case_rrw(rem,);
+		case_rrr(rem, _u);
+		case_rrw(rem, _u);
+		case_rrr(lsh,);
+		case_rrw(lsh,);
+		case_rrr(rsh,);
+		case_rrw(rsh,);
+		case_rrr(rsh, _u);
+		case_rrw(rsh, _u);
+		case_rr(neg,);
+		case_rr(com,);
+		case_rrr(and,);
+		case_rrw(and,);
+		case_rrr(or,);
+		case_rrw(or,);
+		case_rrr(xor,);
+		case_rrw(xor,);
+		case_rr(trunc, _f_i);
+		case_rr(trunc, _d_i);
+		case_rr(trunc, _f_l);
+		case_rr(trunc, _d_l);
+		case_rr(ld, _c);
+		case_rw(ld, _c);
+		case_rr(ld, _uc);
+		case_rw(ld, _uc);
+		case_rr(ld, _s);
+		case_rw(ld, _s);
+		case_rr(ld, _us);
+		case_rw(ld, _us);
+		case_rr(ld, _i);
+		case_rw(ld, _i);
+		case_rr(ld, _ui);
+		case_rw(ld, _ui);
+		case_rr(ld, _l);
+		case_rw(ld, _l);
+		case_rrr(ldx, _c);
+		case_rrw(ldx, _c);
+		case_rrr(ldx, _uc);
+		case_rrw(ldx, _uc);
+		case_rrr(ldx, _s);
+		case_rrw(ldx, _s);
+		case_rrr(ldx, _us);
+		case_rrw(ldx, _us);
+		case_rrr(ldx, _i);
+		case_rrw(ldx, _i);
+		case_rrr(ldx, _ui);
+		case_rrw(ldx, _ui);
+		case_rrr(ldx, _l);
+		case_rrw(ldx, _l);
+		case_rr(st, _c);
+		case_wr(st, _c);
+		case_rr(st, _s);
+		case_wr(st, _s);
+		case_rr(st, _i);
+		case_wr(st, _i);
+		case_rr(st, _l);
+		case_wr(st, _l);
+		case_rrr(stx, _c);
+		case_wrr(stx, _c);
+		case_rrr(stx, _s);
+		case_wrr(stx, _s);
+		case_rrr(stx, _i);
+		case_wrr(stx, _i);
+		case_rrr(stx, _l);
+		case_wrr(stx, _l);
+		case_rr(hton, _us);
+		case_rr(hton, _ui);
+		case_rr(hton, _ul);
+		case_rr(ext, _c);
+		case_rr(ext, _uc);
+		case_rr(ext, _s);
+		case_rr(ext, _us);
+		case_rr(ext, _i);
+		case_rr(ext, _ui);
+		case_rr(mov,);
+	    case jit_code_movi:
+		if (node->flag & jit_flag_node) {
+		    temp = node->v.n;
+		    if (temp->code == jit_code_data ||
+			(temp->code == jit_code_label &&
+			 (temp->flag & jit_flag_patch)))
+			movi(rn(node->u.w), temp->u.w);
+		    else {
+			assert(temp->code == jit_code_label ||
+			       temp->code == jit_code_epilog);
+			word = movi_p(rn(node->u.w), temp->u.w);
+			patch(word, node);
+		    }
+		}
+		else
+		    movi(rn(node->u.w), node->v.w);
+		break;
+		case_rrr(lt,);
+		case_rrw(lt,);
+		case_rrr(lt, _u);
+		case_rrw(lt, _u);
+		case_rrr(le,);
+		case_rrw(le,);
+		case_rrr(le, _u);
+		case_rrw(le, _u);
+		case_rrr(eq,);
+		case_rrw(eq,);
+		case_rrr(ge,);
+		case_rrw(ge,);
+		case_rrr(ge, _u);
+		case_rrw(ge, _u);
+		case_rrr(gt,);
+		case_rrw(gt,);
+		case_rrr(gt, _u);
+		case_rrw(gt, _u);
+		case_rrr(ne,);
+		case_rrw(ne,);
+		case_brr(blt,);
+		case_brw(blt,);
+		case_brr(blt, _u);
+		case_brw(blt, _u);
+		case_brr(ble,);
+		case_brw(ble,);
+		case_brr(ble, _u);
+		case_brw(ble, _u);
+		case_brr(beq,);
+		case_brw(beq,);
+		case_brr(bge,);
+		case_brw(bge,);
+		case_brr(bge, _u);
+		case_brw(bge, _u);
+		case_brr(bgt,);
+		case_brw(bgt,);
+		case_brr(bgt, _u);
+		case_brw(bgt, _u);
+		case_brr(bne,);
+		case_brw(bne,);
+		case_brr(boadd,);
+		case_brw(boadd,);
+		case_brr(boadd, _u);
+		case_brw(boadd, _u);
+		case_brr(bxadd,);
+		case_brw(bxadd,);
+		case_brr(bxadd, _u);
+		case_brw(bxadd, _u);
+		case_brr(bosub,);
+		case_brw(bosub,);
+		case_brr(bosub, _u);
+		case_brw(bosub, _u);
+		case_brr(bxsub,);
+		case_brw(bxsub,);
+		case_brr(bxsub, _u);
+		case_brw(bxsub, _u);
+		case_brr(bms,);
+		case_brw(bms,);
+		case_brr(bmc,);
+		case_brw(bmc,);
+		case_rrr(add, _f);
+		case_rrf(add);
+		case_rrr(sub, _f);
+		case_rrf(sub);
+		case_rrf(rsb);
+		case_rrr(mul, _f);
+		case_rrf(mul);
+		case_rrr(div, _f);
+		case_rrf(div);
+		case_rr(abs, _f);
+		case_rr(neg, _f);
+		case_rr(sqrt, _f);
+		case_rr(ext, _f);
+		case_rr(ld, _f);
+		case_rw(ld, _f);
+		case_rrr(ldx, _f);
+		case_rrw(ldx, _f);
+		case_rr(st, _f);
+		case_wr(st, _f);
+		case_rrr(stx, _f);
+		case_wrr(stx, _f);
+		case_rr(mov, _f);
+	    case jit_code_movi_f:
+		assert_data(node);
+		movi_f(rn(node->u.w), node->v.f);
+		break;
+		case_rr(ext, _d_f);
+		case_rrr(lt, _f);
+		case_rrf(lt);
+		case_rrr(le, _f);
+		case_rrf(le);
+		case_rrr(eq, _f);
+		case_rrf(eq);
+		case_rrr(ge, _f);
+		case_rrf(ge);
+		case_rrr(gt, _f);
+		case_rrf(gt);
+		case_rrr(ne, _f);
+		case_rrf(ne);
+		case_rrr(unlt, _f);
+		case_rrf(unlt);
+		case_rrr(unle, _f);
+		case_rrf(unle);
+		case_rrr(uneq, _f);
+		case_rrf(uneq);
+		case_rrr(unge, _f);
+		case_rrf(unge);
+		case_rrr(ungt, _f);
+		case_rrf(ungt);
+		case_rrr(ltgt, _f);
+		case_rrf(ltgt);
+		case_rrr(ord, _f);
+		case_rrf(ord);
+		case_rrr(unord, _f);
+		case_rrf(unord);
+		case_brr(blt, _f);
+		case_brf(blt);
+		case_brr(ble, _f);
+		case_brf(ble);
+		case_brr(beq, _f);
+		case_brf(beq);
+		case_brr(bge, _f);
+		case_brf(bge);
+		case_brr(bgt, _f);
+		case_brf(bgt);
+		case_brr(bne, _f);
+		case_brf(bne);
+		case_brr(bunlt, _f);
+		case_brf(bunlt);
+		case_brr(bunle, _f);
+		case_brf(bunle);
+		case_brr(buneq, _f);
+		case_brf(buneq);
+		case_brr(bunge, _f);
+		case_brf(bunge);
+		case_brr(bungt, _f);
+		case_brf(bungt);
+		case_brr(bltgt, _f);
+		case_brf(bltgt);
+		case_brr(bord, _f);
+		case_brf(bord);
+		case_brr(bunord, _f);
+		case_brf(bunord);
+		case_rrr(add, _d);
+		case_rrd(add);
+		case_rrr(sub, _d);
+		case_rrd(sub);
+		case_rrd(rsb);
+		case_rrr(mul, _d);
+		case_rrd(mul);
+		case_rrr(div, _d);
+		case_rrd(div);
+		case_rr(abs, _d);
+		case_rr(neg, _d);
+		case_rr(sqrt, _d);
+		case_rr(ext, _d);
+		case_rr(ld, _d);
+		case_rw(ld, _d);
+		case_rrr(ldx, _d);
+		case_rrw(ldx, _d);
+		case_rr(st, _d);
+		case_wr(st, _d);
+		case_rrr(stx, _d);
+		case_wrr(stx, _d);
+		case_rr(mov, _d);
+	    case jit_code_movi_d:
+		assert_data(node);
+		movi_d(rn(node->u.w), node->v.d);
+		break;
+		case_rr(ext, _f_d);
+		case_rrr(lt, _d);
+		case_rrd(lt);
+		case_rrr(le, _d);
+		case_rrd(le);
+		case_rrr(eq, _d);
+		case_rrd(eq);
+		case_rrr(ge, _d);
+		case_rrd(ge);
+		case_rrr(gt, _d);
+		case_rrd(gt);
+		case_rrr(ne, _d);
+		case_rrd(ne);
+		case_rrr(unlt, _d);
+		case_rrd(unlt);
+		case_rrr(unle, _d);
+		case_rrd(unle);
+		case_rrr(uneq, _d);
+		case_rrd(uneq);
+		case_rrr(unge, _d);
+		case_rrd(unge);
+		case_rrr(ungt, _d);
+		case_rrd(ungt);
+		case_rrr(ltgt, _d);
+		case_rrd(ltgt);
+		case_rrr(ord, _d);
+		case_rrd(ord);
+		case_rrr(unord, _d);
+		case_rrd(unord);
+		case_brr(blt, _d);
+		case_brd(blt);
+		case_brr(ble, _d);
+		case_brd(ble);
+		case_brr(beq, _d);
+		case_brd(beq);
+		case_brr(bge, _d);
+		case_brd(bge);
+		case_brr(bgt, _d);
+		case_brd(bgt);
+		case_brr(bne, _d);
+		case_brd(bne);
+		case_brr(bunlt, _d);
+		case_brd(bunlt);
+		case_brr(bunle, _d);
+		case_brd(bunle);
+		case_brr(buneq, _d);
+		case_brd(buneq);
+		case_brr(bunge, _d);
+		case_brd(bunge);
+		case_brr(bungt, _d);
+		case_brd(bungt);
+		case_brr(bltgt, _d);
+		case_brd(bltgt);
+		case_brr(bord, _d);
+		case_brd(bord);
+		case_brr(bunord, _d);
+		case_brd(bunord);
+	    case jit_code_jmpr:
+		jmpr(rn(node->u.w));
+		break;
+	    case jit_code_jmpi:
+		if (node->flag & jit_flag_node) {
+		    temp = node->u.n;
+		    assert(temp->code == jit_code_label ||
+			   temp->code == jit_code_epilog);
+		    if (temp->flag & jit_flag_patch)
+			jmpi(temp->u.w);
+		    else {
+			word = jmpi_p(_jit->pc.w);
+			patch(word, node);
+		    }
+		}
+		else
+		    jmpi(node->u.w);
+		break;
+	    case jit_code_callr:
+		callr(rn(node->u.w));
+		break;
+	    case jit_code_calli:
+		if (node->flag & jit_flag_node) {
+		    temp = node->u.n;
+		    assert(temp->code == jit_code_label ||
+			   temp->code == jit_code_epilog);
+		    if (temp->flag & jit_flag_patch)
+			calli(temp->u.w);
+		    else {
+			word = calli_p(_jit->pc.w);
+			patch(word, node);
+		    }
+		}
+		else
+		    calli(node->u.w);
+		break;
+	    case jit_code_prolog:
+		_jitc->function = _jitc->functions.ptr + node->w.w;
+		undo.node = node;
+		undo.word = _jit->pc.w;
+#if DEVEL_DISASSEMBLER
+		undo.prevw = prevw;
+#endif
+		undo.patch_offset = _jitc->patches.offset;
+	    restart_function:
+		_jitc->again = 0;
+		prolog(node);
+		break;
+	    case jit_code_epilog:
+		assert(_jitc->function == _jitc->functions.ptr + node->w.w);
+		if (_jitc->again) {
+		    for (temp = undo.node->next;
+			 temp != node; temp = temp->next) {
+			if (temp->code == jit_code_label ||
+			    temp->code == jit_code_epilog)
+			    temp->flag &= ~jit_flag_patch;
+		    }
+		    temp->flag &= ~jit_flag_patch;
+		    node = undo.node;
+		    _jit->pc.w = undo.word;
+#if DEVEL_DISASSEMBLER
+		    prevw = undo.prevw;
+#endif
+		    _jitc->patches.offset = undo.patch_offset;
+		    goto restart_function;
+		}
+		/* remember label is defined */
+		node->flag |= jit_flag_patch;
+		node->u.w = _jit->pc.w;
+		epilog(node);
+		_jitc->function = NULL;
+		break;
+	    case jit_code_movr_w_f:
+		movr_w_f(rn(node->u.w), rn(node->v.w));
+		break;
+	    case jit_code_movr_f_w:
+		movr_f_w(rn(node->u.w), rn(node->v.w));
+		break;
+	    case jit_code_movi_f_w:
+		assert_data(node);
+		movi_f_w(rn(node->u.w), node->v.f);
+		break;
+	    case jit_code_movr_w_d:
+		movr_w_d(rn(node->u.w), rn(node->v.w));
+		break;
+	    case jit_code_movr_d_w:
+		movr_d_w(rn(node->u.w), rn(node->v.w));
+		break;
+	    case jit_code_movi_d_w:
+		assert_data(node);
+		movi_d_w(rn(node->u.w), node->v.d);
+		break;
+	    case jit_code_va_start:
+		vastart(rn(node->u.w));
+		break;
+	    case jit_code_va_arg:
+		vaarg(rn(node->u.w), rn(node->v.w));
+		break;
+	    case jit_code_va_arg_d:
+		vaarg_d(rn(node->u.w), rn(node->v.w));
+		break;
+	    case jit_code_live:			case jit_code_ellipsis:
+	    case jit_code_va_push:
+	    case jit_code_allocai:		case jit_code_allocar:
+	    case jit_code_arg:
+	    case jit_code_arg_f:		case jit_code_arg_d:
+	    case jit_code_va_end:
+	    case jit_code_ret:
+	    case jit_code_retr:			case jit_code_reti:
+	    case jit_code_retr_f:		case jit_code_reti_f:
+	    case jit_code_retr_d:		case jit_code_reti_d:
+	    case jit_code_getarg_c:		case jit_code_getarg_uc:
+	    case jit_code_getarg_s:		case jit_code_getarg_us:
+	    case jit_code_getarg_i:		case jit_code_getarg_ui:
+	    case jit_code_getarg_l:
+	    case jit_code_getarg_f:		case jit_code_getarg_d:
+	    case jit_code_putargr:		case jit_code_putargi:
+	    case jit_code_putargr_f:		case jit_code_putargi_f:
+	    case jit_code_putargr_d:		case jit_code_putargi_d:
+	    case jit_code_pushargr:		case jit_code_pushargi:
+	    case jit_code_pushargr_f:		case jit_code_pushargi_f:
+	    case jit_code_pushargr_d:		case jit_code_pushargi_d:
+	    case jit_code_retval_c:		case jit_code_retval_uc:
+	    case jit_code_retval_s:		case jit_code_retval_us:
+	    case jit_code_retval_i:
+	    case jit_code_retval_ui:		case jit_code_retval_l:
+	    case jit_code_retval_f:		case jit_code_retval_d:
+	    case jit_code_prepare:
+	    case jit_code_finishr:		case jit_code_finishi:
+		break;
+	    default:
+		abort();
+	}
+	if (jit_carry != _NOREG) {
+	    switch (node->code) {
+		case jit_code_note:
+		case jit_code_addcr:		case jit_code_addci:
+		case jit_code_addxr:		case jit_code_addxi:
+		case jit_code_subcr:		case jit_code_subci:
+		case jit_code_subxr:		case jit_code_subxi:
+		    break;
+		default:
+		    jit_unget_reg(jit_carry);
+		    jit_carry = _NOREG;
+		    break;
+	    }
+	}
+	jit_regarg_clr(node, value);
+	assert(_jitc->regarg == 0 ||
+	       (jit_carry != _NOREG && _jitc->regarg == (1 << jit_carry)));
+	assert(_jitc->synth == 0);
+	/* update register live state */
+	jit_reglive(node);
+    }
+#undef case_brw
+#undef case_brr
+#undef case_wrr
+#undef case_rrw
+#undef case_rrr
+#undef case_wr
+#undef case_rw
+#undef case_rr
+
+    for (offset = 0; offset < _jitc->patches.offset; offset++) {
+	node = _jitc->patches.ptr[offset].node;
+	word = _jitc->patches.ptr[offset].inst;
+	value = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
+	patch_at(word, value);
+    }
+
+    jit_flush(_jit->code.ptr, _jit->pc.uc);
+
+    return (_jit->code.ptr);
+}
+
+#define CODE				1
+#  include "riscv-cpu.c"
+#  include "riscv-fpu.c"
+#undef CODE
+
+void
+jit_flush(void *fptr, void *tptr)
+{
+#if defined(__GNUC__)
+    jit_word_t		f, t, s;
+
+    s = sysconf(_SC_PAGE_SIZE);
+    f = (jit_word_t)fptr & -s;
+    t = (((jit_word_t)tptr) + s - 1) & -s;
+    __clear_cache((void *)f, (void *)t);
+#endif
+}
+
+void
+_emit_ldxi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
+{
+    ldxi(rn(r0), rn(r1), i0);
+}
+
+void
+_emit_stxi(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
+{
+    stxi(i0, rn(r0), rn(r1));
+}
+
+void
+_emit_ldxi_d(jit_state_t *_jit, int32_t r0, 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, int32_t r0, 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)
+{
+    int32_t		 flag;
+
+    assert(node->flag & jit_flag_node);
+    if (node->code == jit_code_movi)
+	flag = node->v.n->flag;
+    else
+	flag = node->u.n->flag;
+    assert(!(flag & jit_flag_patch));
+    if (_jitc->patches.offset >= _jitc->patches.length) {
+	jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
+		    _jitc->patches.length * sizeof(jit_patch_t),
+		    (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
+	_jitc->patches.length += 1024;
+    }
+    _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
+    _jitc->patches.ptr[_jitc->patches.offset].node = node;
+    ++_jitc->patches.offset;
+}
diff --git a/lightening/riscv.h b/lightening/riscv.h
new file mode 100644
index 0000000..1b4f93d
--- /dev/null
+++ b/lightening/riscv.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2019  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU lightning.
+ *
+ * GNU lightning is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU lightning is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ *
+ * Authors:
+ *	Paulo Cesar Pereira de Andrade
+ */
+
+#ifndef _jit_riscv_h
+#define _jit_riscv_h
+
+#define JIT_HASH_CONSTS		0
+#define JIT_NUM_OPERANDS	3
+
+/*
+ * Types
+ */
+#define JIT_FP			_FP
+typedef enum {
+#define jit_r(i)		(JIT_R0 + (i))
+#define jit_r_num()		7
+#define jit_v(i)		(JIT_V0 + (i))
+#define jit_v_num()		11
+#define jit_f(i)		(JIT_F0 + (i))
+#define jit_f_num()		12
+    _ZERO,	/*  x0 - Hard-wired zero	---		*/
+    _RA,	/*  x1 - Return address		(CalleR save)	*/
+    _SP,	/*  x2 - Stack pointer		(CalleE save)	*/
+    _GP,	/*  x3 - Global pointer		---		*/
+
+#if 0		/* Pretend it does not exist, so _NOREG can be used in
+		 * a 64 bit bitmask */
+    _TP,	/*  x4 - Thread pointer		---		*/
+#endif
+    
+#define JIT_R0		_T0
+#define JIT_R1		_T1
+#define JIT_R2		_T2
+#define JIT_R3		_T3
+#define JIT_R4		_T4
+#define JIT_R5		_T5
+#define JIT_R6		_T6
+    _T0,	/*  x5 - Temporary/alternate
+			 link register		(CalleR save)	*/
+    _T1,	/*  x6 - Temporary		(CalleR save)	*/
+    _T2,	/*  x7 - Temporary		(CalleR save)	*/
+    _T3,	/* x28 - Temporary		(CalleR save)	*/
+    _T4,	/* x28 - Temporary		(CalleR save)	*/
+    _T5,	/* x30 - Temporary		(CalleR save)	*/
+    _T6,	/* x31 - Temporary		(CalleR save)	*/
+    _FP,	/*  x8 - Saved register/frame
+			 pointer		(CalleE save)	*/
+    _S0 = _FP,
+#define JIT_V0		_S1
+#define JIT_V1		_S2
+#define JIT_V2		_S3
+#define JIT_V3		_S4
+#define JIT_V4		_S5
+#define JIT_V5		_S6
+#define JIT_V6		_S7
+#define JIT_V7		_S8
+#define JIT_V8		_S9
+#define JIT_V9		_S10
+#define JIT_V10		_S11
+    _S1,	/*  x9 - Saved register		(CalleE save)	*/
+    _S2,	/* x18 - Saved register		(CalleE save)	*/
+    _S3,	/* x19 - Saved register		(CalleE save)	*/
+    _S4,	/* x20 - Saved register		(CalleE save)	*/
+    _S5,	/* x21 - Saved register		(CalleE save)	*/
+    _S6,	/* x22 - Saved register		(CalleE save)	*/
+    _S7,	/* x23 - Saved register		(CalleE save)	*/
+    _S8,	/* x24 - Saved register		(CalleE save)	*/
+    _S9,	/* x25 - Saved register		(CalleE save)	*/
+    _S10,	/* x26 - Saved register		(CalleE save)	*/
+    _S11,	/* x27 - Saved register		(CalleE save)	*/
+    _A7,	/* x17 - Function argument	(CalleR save)	*/
+    _A6,	/* x16 - Function argument	(CalleR save)	*/
+    _A5,	/* x15 - Function argument	(CalleR save)	*/
+    _A4,	/* x14 - Function argument	(CalleR save)	*/
+    _A3,	/* x13 - Function argument	(CalleR save)	*/
+    _A2,	/* x12 - Function argument	(CalleR save)	*/
+    _A1,	/* x11 - Function argument/
+			 return value		(CalleR save)	*/
+    _A0,	/* x10 - Function argument/
+			 return value		(CalleR save)	*/
+    _FT0,	/*  f0 - FP temporary		(CalleR save)	*/
+    _FT1,	/*  f1 - FP temporary		(CalleR save)	*/
+    _FT2,	/*  f2 - FP temporary		(CalleR save)	*/
+    _FT3,	/*  f3 - FP temporary		(CalleR save)	*/
+    _FT4,	/*  f4 - FP temporary		(CalleR save)	*/
+    _FT5,	/*  f5 - FP temporary		(CalleR save)	*/
+    _FT6,	/*  f6 - FP temporary		(CalleR save)	*/
+    _FT7,	/*  f7 - FP temporary		(CalleR save)	*/
+    _FT8,	/* f28 - FP temporary		(CalleR save)	*/
+    _FT9,	/* f29 - FP temporary		(CalleR save)	*/
+    _FT10,	/* f30 - FP temporary		(CalleR save)	*/
+    _FT11,	/* f31 - FP temporary		(CalleR save)	*/
+#define JIT_F0		_FS0
+#define JIT_F1		_FS1
+#define JIT_F2		_FS2
+#define JIT_F3		_FS3
+#define JIT_F4		_FS4
+#define JIT_F5		_FS5
+#define JIT_F6		_FS6
+#define JIT_F7		_FS7
+#define JIT_F8		_FS8
+#define JIT_F9		_FS9
+#define JIT_F10		_FS10
+#define JIT_F11		_FS11
+    _FS0,	/*  f8 - FP saved register	(CalleE save)	*/
+    _FS1,	/*  f9 - FP saved register	(CalleE save)	*/
+    _FS2,	/* f18 - FP saved register	(CalleE save)	*/
+    _FS3,	/* f19 - FP saved register	(CalleE save)	*/
+    _FS4,	/* f20 - FP saved register	(CalleE save)	*/
+    _FS5,	/* f21 - FP saved register	(CalleE save)	*/
+    _FS6,	/* f22 - FP saved register	(CalleE save)	*/
+    _FS7,	/* f23 - FP saved register	(CalleE save)	*/
+    _FS8,	/* f24 - FP saved register	(CalleE save)	*/
+    _FS9,	/* f25 - FP saved register	(CalleE save)	*/
+    _FS10,	/* f26 - FP saved register	(CalleE save)	*/
+    _FS11,	/* f27 - FP saved register	(CalleE save)	*/
+    _FA7,	/* f17 - FP Function argument	(CalleR save)	*/
+    _FA6,	/* f16 - FP Function argument	(CalleR save)	*/
+    _FA5,	/* f15 - FP Function argument	(CalleR save)	*/
+    _FA4,	/* f14 - FP Function argument	(CalleR save)	*/
+    _FA3,	/* f13 - FP Function argument	(CalleR save)	*/
+    _FA2,	/* f12 - FP Function argument	(CalleR save)	*/
+    _FA1,	/* f11 - FP function argument/
+			 return value		(CalleR save)	*/
+    _FA0,	/* f10 - FP function argument/
+			 return value		(CalleR save)	*/
+    _NOREG,
+#define JIT_NOREG		_NOREG
+} jit_reg_t;
+
+#endif /* _jit_riscv_h */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: riscv files for lightening
  2021-01-29 19:13 riscv files for lightening Matt Wette
@ 2021-01-30 15:14 ` Matt Wette
  0 siblings, 0 replies; 2+ messages in thread
From: Matt Wette @ 2021-01-30 15:14 UTC (permalink / raw)
  To: guile-devel



On 1/29/21 11:13 AM, Matt Wette wrote:
> Andy,
>
> I took a stab at porting RISC-V from lightning to lightening.
> I have no riscv toolset or computer yet so these are untested.
>
> I copied files from sv/lightning for riscv to wingo/lightening. Patch 
> attached.
> The changes are:
> 1) copy lightning/jit_riscv{.c,-cpu.c-fpu.c,-sz.c,.h} to lightening
> 2) s/include "jit_riscv/include "riscv/
> 3) s/git_int/int/ and s/git_uint/uint/
> 4) copied the JIT_RA0, etc defines from jit_private.h to riscv.c
> 5) updated lightening.am
> 6) updated lightening.h
>
> Matt
>
I did find github.com/riscv/riscv/riscv-gnu-toolchain.
I'm going to see where that goes wrt testing.

Matt




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-01-30 15:14 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-29 19:13 riscv files for lightening Matt Wette
2021-01-30 15:14 ` Matt Wette

unofficial mirror of guile-devel@gnu.org 

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://yhetil.org/guile-devel/0 guile-devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 guile-devel guile-devel/ https://yhetil.org/guile-devel \
		guile-devel@gnu.org
	public-inbox-index guile-devel

Example config snippet for mirrors.
Newsgroups are available over NNTP:
	nntp://news.yhetil.org/yhetil.lisp.guile.devel
	nntp://news.gmane.io/gmane.lisp.guile.devel


AGPL code for this site: git clone http://ou63pmih66umazou.onion/public-inbox.git