/*
 * Copyright (C) 2013-2017  Free Software Foundation, Inc.
 *
 * This file is part of GNU lightning.
 *
 * GNU lightning is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 3, or (at your option)
 * any later version.
 *
 * GNU lightning is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 * License for more details.
 *
 * Authors:
 *	Paulo Cesar Pereira de Andrade
 */

#if PROTO
#  if __WORDSIZE == 32
#    define ldr(r0,r1)			ldr_i(r0,r1)
#    define ldxr(r0,r1,r2)		ldxr_i(r0,r1,r2)
#    define ldxi(r0,r1,i0)		ldxi_i(r0,r1,i0)
#    define stxi(i0,r0,r1)		stxi_i(i0,r0,r1)
#  else
#    define ldr(r0,r1)			ldr_l(r0,r1)
#    define ldxr(r0,r1,r2)		ldxr_l(r0,r1,r2)
#    define ldxi(r0,r1,i0)		ldxi_l(r0,r1,i0)
#    define stxi(i0,r0,r1)		stxi_l(i0,r0,r1)
#  endif
#  define is(i)				*_jit->pc.us++ = i
#  if __WORDSIZE == 32
#    define stack_framesize		96
#  else
#    define stack_framesize		160
#  endif
#  define _R0_REGNO			0
#  define _R1_REGNO			1
#  define _R7_REGNO			7
#  define _R13_REGNO			13
#  define _FP_REGNO			_R13_REGNO
#  define _R14_REGNO			14
#  define _R15_REGNO			15
#  define u12_p(i0)			((i0) >= 0 && (i0) <= 4095)
#  define s16_p(i0)			((i0) >= -32768 && (i0) <= 32767)
#  define x16(i0)			((i0) & 0xffff)
#  define s20_p(i0)			((i0) >= -524288 && (i0) <= 524287)
#  define x20(i0)			((i0) & 0xfffff)
#  if __WORDSIZE == 32
#    define s32_p(i0)			1
#  else
#    define s32_p(i0)							\
    ((i0) >= -2147483648L && (i0) < 2147483647L)
#  endif

/*
	Condition Code		Instruction	(Mask) Bit Mask Value
	0			8		8
	1			9		4
	2			10		2
	3			11		1

AGR:
	0	Zero
	1	< zero
	2	> zero
	3	Overflow
--
1	->	overflow		CC_O
14	->	no overflow		CC_NO

ALGR:
 	0	Zero, no carry
 	1	Not zero, no carry
 	2	Zero, carry
 	3	Not zero, carry
--
2|1	->	carry			CC_NLE
8|4	->	no carry		CC_LE

SGR:
	0	Zero
	1	< zero
	2	> zero
	3	Overflow
--
1	->	overflow		CC_O
14	->	no overflow		CC_NO

SLGR:
	0	--
	1	Not zero, borrow
	2	Zero, no borrow
	3	Not zero, no borrow
--
4	->	borrow			CC_L
11	->	no borrow		CC_NL
  */

#  define CC_NV				0x0
#  define CC_O				0x1
#  define CC_H				0x2
#  define CC_NLE			0x3
#  define CC_L				0x4
#  define CC_NHE			0x5
#  define CC_LH				0x6
#  define CC_NE				0x7
#  define CC_E				0x8
#  define CC_NLH			0x9
#  define CC_HE				0xA
#  define CC_NL				0xB
#  define CC_LE				0xC
#  define CC_NH				0xD
#  define CC_NO				0xE
#  define CC_AL				0xF
#  define _us				uint16_t
#  define _ui				uint32_t
#  define E_(Op)			_E(_jit,Op)
static void _E(jit_state_t*,_ui);
#  define I_(Op,I)			_I(_jit,Op,I)
static void _I(jit_state_t*,_ui,_ui);
#  define RR_(Op,R1,R2)			_RR(_jit,Op,R1,R2)
static void _RR(jit_state_t*,_ui,_ui,_ui);
#  define RRE_(Op,R1,R2)		_RRE(_jit,Op,R1,R2)
static void _RRE(jit_state_t*,_ui,_ui,_ui);
#  define RRF_(Op,R3,M4,R1,R2)		_RRF(_jit,Op,R3,M4,R1,R2)
static void _RRF(jit_state_t*,_ui,_ui,_ui,_ui,_ui);
#  define RX_(Op,R1,X2,B2,D2)		_RX(_jit,Op,R1,X2,B2,D2)
static void _RX(jit_state_t*,_ui,_ui,_ui,_ui,_ui);
#  define RXE_(Op,R1,X2,B2,D2,Op2)	_RXE(_jit,Op,R1,X2,B2,D2,Op2)
static void _RXE(jit_state_t*,_ui,_ui,_ui,_ui,_ui,_ui);
#  define RXF_(Op,R3,X2,B2,D2,R1,Op2)	_RXF(_jit,Op,R3,X2,B2,D2,R1,Op2)
static void _RXF(jit_state_t*,_ui,_ui,_ui,_ui,_ui,_ui,_ui);
#  define RXY_(Op,R1,X2,B2,D2,Op2)	_RXY(_jit,Op,R1,X2,B2,D2,Op2)
static void _RXY(jit_state_t*,_ui,_ui,_ui,_ui,_ui,_ui);
#  define RS_(Op,R1,R3,B2,D2)		_RS(_jit,Op,R1,R3,B2,D2)
static void _RS(jit_state_t*,_ui,_ui,_ui,_ui,_ui);
#  define RSY_(Op,R1,R3,B2,D2,Op2)	RXY_(Op,R1,R3,B2,D2,Op2)
#  define RSL_(Op,L1,B1,D1,Op2)		_RSL(_jit,Op,L1,B1,D1,Op2)
static void _RSL(jit_state_t*,_ui,_ui,_ui,_ui,_ui);
#  define RSI_(Op,R1,R3,I2)		_RSI(_jit,Op,R1,R3,I2)
static void _RSI(jit_state_t*,_ui,_ui,_ui,_ui);
#  define RI_(Op,R1,Op2,I2)		RSI_(Op,R1,Op2,I2)
#  define RIE_(Op,R1,R3,I2,Op2)		_RIE(_jit,Op,R1,R3,I2,Op2)
static void _RIE(jit_state_t*,_ui,_ui,_ui,_ui,_ui);
#  define RIL_(Op,R1,Op2,I2)		_RIL(_jit,Op,R1,Op2,I2)
static void _RIL(jit_state_t*,_ui,_ui,_ui,_ui);
#  define SI_(Op,I2,B1,D1)		_SI(_jit,Op,I2,B1,D1)
static void _SI(jit_state_t*,_ui,_ui,_ui,_ui);
#  define SIY_(Op,I2,B1,D1,Op2)		_SIY(_jit,Op,I2,B1,D1,Op2)
static void _SIY(jit_state_t*,_ui,_ui,_ui,_ui,_ui);
#  define S_(Op,B2,D2)			_S(_jit,Op,B2,D2)
static void _S(jit_state_t*,_ui,_ui,_ui);
#  define SSL_(Op,L,B1,D1,B2,D2)	SS_(Op,(L)>>4,(L)&0xF,B1,D1,B2,D2)
#  define SS_(Op,LL,LH,B1,D1,B2,D2)	_SS(_jit,Op,LL,LH,B1,D1,B2,D2)
static void _SS(jit_state_t*,_ui,_ui,_ui,_ui,_ui,_ui,_ui);
#  define SSE_(Op,B1,D1,B2,D2)		_SSE(_jit,Op,B1,D1,B2,D2)
static void _SSE(jit_state_t*,_ui,_ui,_ui,_ui,_ui);
#  undef _us
#  undef _ui
#  define nop(c)			_nop(_jit,c)
static void _nop(jit_state_t*,int32_t);
#  if __WORDSIZE == 32
#    define ADD_(r0,r1)			AR(r0,r1)
#    define ADDI_(r0,i0)		AHI(r0,i0)
#    define ADDC_(r0,r1)		ALR(r0,r1)
#    define ADDX_(r0,r1)		ALCR(r0,r1)
#    define AND_(r0,r1)			NR(r0,r1)
#    define CMP_(r0,r1)			CR(r0,r1)
#    define CMPU_(r0,r1)		CLR(r0,r1)
#    define DIVREM_(r0,r1)		DR(r0,r1)
#    define DIVREMU_(r0,r1)		DLR(r0,r1)
#    define OR_(r0,r1)			OR(r0,r1)
#    define MUL_(r0,r1)			MSR(r0,r1)
#    define MULI_(r0,i0)		MHI(r0,i0)
#    define MULU_(r0,r1)		MLR(r0,r1)
#    define SUB_(r0,r1)			SR(r0,r1)
#    define SUBC_(r0,r1)		SLR(r0,r1)
#    define SUBX_(r0,r1)		SLBR(r0,r1)
#    define TEST_(r0,r1)		LTR(r0,r1)
#    define XOR_(r0,r1)			XR(r0,r1)
#  else
#    define ADD_(r0,r1)			AGR(r0,r1)
#    define ADDI_(r0,i0)		AGHI(r0,i0)
#    define ADDC_(r0,r1)		ALGR(r0,r1)
#    define ADDX_(r0,r1)		ALCGR(r0,r1)
#    define AND_(r0,r1)			NGR(r0,r1)
#    define CMP_(r0,r1)			CGR(r0,r1)
#    define CMPU_(r0,r1)		CLGR(r0,r1)
#    define DIVREM_(r0,r1)		DSGR(r0,r1)
#    define DIVREMU_(r0,r1)		DLGR(r0,r1)
#    define MUL_(r0,r1)			MSGR(r0,r1)
#    define MULI_(r0,i0)		MGHI(r0,i0)
#    define MULU_(r0,r1)		MLGR(r0,r1)
#    define OR_(r0,r1)			OGR(r0,r1)
#    define SUB_(r0,r1)			SGR(r0,r1)
#    define SUBC_(r0,r1)		SLGR(r0,r1)
#    define SUBX_(r0,r1)		SLBGR(r0,r1)
#    define TEST_(r0,r1)		LTGR(r0,r1)
#    define XOR_(r0,r1)			XGR(r0,r1)
#  endif
/****************************************************************
 * General Instructions						*
 ****************************************************************/
/* ADD */
#  define AR(R1,R2)			RR_(0x1A,R1,R2)
#  define AGR(R1,R2)			RRE_(0xB908,R1,R2)
#  define AGFR(R1,R2)			RRE_(0xB918,R1,R2)
#  define A(R1,D2,X2,B2)		RX_(0x5A,R1,X2,B2,D2)
#  define AY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x5A)
#  define AG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x08)
#  define AGF(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x18)
/* ADD HALFWORD */
#  define AH(R1,D2,X2,B2)		RX_(0x4A,R1,X2,B2,D2)
#  define AHY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x7A)
/* ADD HALFWORD IMMEDIATE */
#  define AHI(R1,I2)			RI_(0xA7,R1,0xA,I2)
#  define AGHI(R1,I2)			RI_(0xA7,R1,0xB,I2)
/* ADD LOGICAL */
#  define ALR(R1,R2)			RR_(0x1E,R1,R2)
#  define ALGR(R1,R2)			RRE_(0xB90A,R1,R2)
#  define ALGFR(R1,R2)			RRE_(0xB91A,R1,R2)
#  define AL(R1,D2,X2,B2)		RX_(0x5E,R1,X2,B2,D2)
#  define ALY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x5E)
#  define ALG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x0A)
#  define ALGF(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x1A)
/* ADD LOGICAL WITH CARRY */
#  define ALCR(R1,R2)			RRE_(0xB998,R1,R2)
#  define ALCGR(R1,R2)			RRE_(0xB988,R1,R2)
#  define ALC(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x98)
#  define ALCG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x88)
/* AND */
#  define NR(R1,R2)			RR_(0x14,R1,R2)
#  define NGR(R1,R2)			RRE_(0xB980,R1,R2)
#  define N(R1,D2,X2,B2)		RX_(0x54,R1,X2,B2,D2)
#  define NY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x54)
#  define NG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x80)
#  define NI(D1,B1,I2)			SI_(0x94,I2,B1,D1)
#  define NIY(D1,B1,I2)			SIY_(0xEB,I2,B1,D1,0x54)
#  define NC(D1,L,B1,D2,B2)		SSL_(0xD4,L,B1,D1,B2,D2)
/* AND IMMEDIATE */
#  define NIHH(R1,I2)			RI_(0xA5,R1,0x4,I2)
#  define NIHL(R1,I2)			RI_(0xA5,R1,0x5,I2)
#  define NILH(R1,I2)			RI_(0xA5,R1,0x6,I2)
#  define NILL(R1,I2)			RI_(0xA5,R1,0x7,I2)
/* BRANCH AND LINK */
#  define BALR(R1,R2)			RR_(0x05,R1,R2)
#  define BAL(R1,D2,X2,B2)		RX_(0x45,R1,X2,B2,D2)
/* BRANCH AND SAVE */
#  define BASR(R1,R2)			RR_(0x0D,R1,R2)
#  define BAS(R1,D2,X2,B2)		RX_(0x4D,R1,X2,B2,D2)
/* BRANCH AND SAVE AND SET MODE */
#  define BASSM(R1,R2)			RR_(0x0C,R1,R2)
/* BRANCH AND SET MODE */
#  define BSM(R1,R2)			RR_(0x0B,R1,R2)
/* BRANCH ON CONDITION */
#  define BCR(M1,R2)			RR_(0x07,M1,R2)
#  define BR(R2)			BCR(CC_AL,R2)
#  define NOPR(R2)			BCR(CC_NV,R2)
#  define BC(M1,D2,X2,B2)		RX_(0x47,M1,X2,B2,D2)
/* BRANCH ON COUNT */
#  define BCTR(R1,R2)			RR_(0x06,R1,R2)
#  define BCTGR(R1,R2)			RRE_(0xB946,R1,R2)
#  define BCT(R1,D2,X2,B2)		RX_(0x46,R1,X2,B2,D2)
#  define BCTG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x46)
/* BRANCH ON INDEX HIGH */
#  define BXH(R1,R3,D2,B2)		RS_(0x86,R1,R3,B2,D2)
#  define BXHG(R1,R3,B2,D2)		RSY_(0xEB,R1,R3,B2,D2,0x44)
/* BRANCH ON INDEX LOW OR EQUAL */
#  define BXLE(R1,R3,D2,B2)		RS_(0x87,R1,R3,B2,D2)
#  define BXLEG(R1,R3,B2,D2)		RSY_(0xEB,R1,R3,B2,D2,0x45)
/* BRANCH RELATIVE AND SAVE */
#  define BRAS(R1,I2)			RI_(0xA7,R1,0x5,I2)
/* BRANCH RELATIVE AND SAVE LONG */
#  define BRASL(R1,I2)			RIL_(0xC0,R1,0x5,I2)
/* BRANCH RELATIVE ON CONDITION */
#  define BRC(M1,I2)			RI_(0xA7,M1,0x4,I2)
#  define J(I2)				BRC(CC_AL,I2)
/* BRANCH RELATIVE ON CONDITION LONG */
#  define BRCL(M1,I2)			RIL_(0xC0,M1,0x4,I2)
#  define BRL(I2)			BRCL(CC_AL,I2)
/* BRANCH RELATIVE ON COUNT */
#  define BRCT(M1,I2)			RI_(0xA7,M1,0x6,I2)
#  define BRCTG(M1,I2)			RI_(0xA7,M1,0x7,I2)
/* BRANCH RELATIVE ON INDEX HIGH */
#  define BRXH(R1,R3,I2)		RSI_(0x84,R1,R3,I2)
#  define BRXHG(R1,R3,I2)		RIE_(0xEC,R1,R3,I2,0x44)
/* BRANCH RELATIVE ON INDEX LOW OR EQUAL */
#  define BRXLE(R1,R3,I2)		RSI_(0x85,R1,R3,I2)
#  define BRXLEG(R1,R3,I2)		RIE_(0xEC,R1,R3,I2,0x45)
/* CHECKSUM */
#  define CKSUM(R1,R2)			RRE_(0xB241,R1,R2)
/* CIPHER MESAGE (KM) */
#  define KM(R1,R2)			RRE_(0xB92E,R1,R2)
/* CIPHER MESAGE WITH CHAINING (KMC) */
#  define KMC(R1,R2)			RRE_(0xB92F,R1,R2)
/* COMPARE */
#  define CR(R1,R2)			RR_(0x19,R1,R2)
#  define CGR(R1,R2)			RRE_(0xB920,R1,R2)
#  define CGFR(R1,R2)			RRE_(0xB930,R1,R2)
#  define C(R1,D2,X2,B2)		RX_(0x59,R1,X2,B2,D2)
#  define CY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x59)
#  define CG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x20)
#  define CGF(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x30)
/* COMPARE AND FORM CODEWORD */
#  define CFC(D2,B2)			S_(0xB21A,B2,D2)
/* COMPARE AND SWAP */
#  define CS(R1,R3,D2,B2)		RS_(0xBA,R1,R3,B2,D2)
#  define CSY(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x14)
#  define CSG(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x30)
/* COMPARE DOUBLE AND SWAP */
#  define CDS(R1,R3,D2,B2)		RS_(0xBB,R1,R3,B2,D2)
#  define CSDY(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x31)
#  define CSDG(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x3E)
/* COMPARE HALFWORD */
#  define CH(R1,D2,X2,B2)		RX_(0x49,R1,X2,B2,D2)
#  define CHY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x79)
/* COMPARE HALFWORD IMMEDIATE */
#  define CHI(R1,I2)			RI_(0xA7,R1,0xE,I2)
#  define CGHI(R1,I2)			RI_(0xA7,R1,0xF,I2)
/* COMPARE LOGICAL */
#  define CLR(R1,R2)			RR_(0x15,R1,R2)
#  define CLGR(R1,R2)			RRE_(0xB921,R1,R2)
#  define CLGFR(R1,R2)			RRE_(0xB931,R1,R2)
#  define CL(R1,D2,X2,B2)		RX_(0x55,R1,X2,B2,D2)
#  define CLY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x55)
#  define CLG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x21)
#  define CLGF(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x31)
#  define CLI(D1,B1,I2)			SI_(0x95,I2,B1,D1)
#  define CLIY(D1,B1,I2)		SIY_(0xEB,I2,B1,D1,0x55)
#  define CLC(D1,L,B1,D2,B2)		SSL_(0xD5,L,B1,D1,B2,D2)
/* COMPARE LOGICAL CHARACTERS UNDER MASK */
#  define CLM(R1,M3,D2,B2)		RS_(0xBD,R1,M3,B2,D2)
#  define CLMY(R1,M3,D2,B2)		RSY_(0xEB,R1,M3,B2,D2,0x21)
#  define CLMH(R1,M3,D2,B2)		RSY_(0xEB,R1,M3,B2,D2,0x20)
/* COMPARE LOGICAL LONG */
#  define CLCL(R1,R2)			RR_(0x0F,R1,R2)
/* COMPARE LOGICAL LONG EXTENDED */
#  define CLCLE(R1,R3,D2,B2)		RS_(0xA9,R1,R3,B2,D2)
/* COMPARE LOGICAL LONG UNICODE */
#  define CLCLU(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x8F)
/* COMPARE LOGICAL STRING */
#  define CLST(R1,R2)			RRE_(0xB25D,R1,R2)
/* COMPARE UNTIL SUBSTRING EQUAL */
#  define CUSE(R1,R2)			RRE_(0xB257,R1,R2)
/* COMPRESSION CALL */
#  define CMPSC(R1,R2)			RRE_(0xB263,R1,R2)
/* COMPUTE INTERMEDIATE MESSAGE DIGEST (KIMD) */
#  define KIMD(R1,R2)			RRE_(0xB93E,R1,R2)
/* COMPUTE LAST MESSAGE DIGEST (KIMD) */
#  define KLMD(R1,R2)			RRE_(0xB93F,R1,R2)
/* COMPUTE MESSAGE AUTHENTICATION CODE (KMAC) */
#  define KMAC(R1,R2)			RRE_(0xB91E,R1,R2)
/* CONVERT TO BINARY */
#  define CVB(R1,D2,X2,B2)		RX_(0x4F,R1,X2,B2,D2)
#  define CVBY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x06)
#  define CVBG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x0e)
/* CONVERT TO DECIMAL */
#  define CVD(R1,D2,X2,B2)		RX_(0x4E,R1,X2,B2,D2)
#  define CVDY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x26)
#  define CVDG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x2E)
/* CONVERT UNICODE TO UTF-8 */
#  define CUUTF(R1,R2)			RRE_(0xB2A6,R1,R2)
/* CONVERT UTF-8 TO UNICODE */
#  define CUTFU(R1,R2)			RRE_(0xB2A7,R1,R2)
/* COPY ACCESS */
#  define CPYA(R1,R2)			RRE_(0xB24D,R1,R2)
/* DIVIDE */
#  define DR(R1,R2)			RR_(0x1D,R1,R2)
#  define D(R1,D2,X2,B2)		RX_(0x5D,R1,X2,B2,D2)
/* DIVIDE LOGICAL */
#  define DLR(R1,R2)			RRE_(0xB997,R1,R2)
#  define DLGR(R1,R2)			RRE_(0xB987,R1,R2)
#  define DL(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x97)
#  define DLG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x87)
/* DIVIDE SINGLE */
#  define DSGR(R1,R2)			RRE_(0xB90D,R1,R2)
#  define DSGFR(R1,R2)			RRE_(0xB91D,R1,R2)
#  define DSG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x0D)
#  define DSGF(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x1D)
/* EXCLUSIVE OR */
#  define XR(R1,R2)			RR_(0x17,R1,R2)
#  define XGR(R1,R2)			RRE_(0xB982,R1,R2)
#  define X(R1,D2,X2,B2)		RX_(0x57,R1,X2,B2,D2)
#  define XY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x57)
#  define XG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x82)
#  define XI(D1,B1,I2)			SI_(0x97,I2,B1,D1)
#  define XIY(D1,B1,I2)			SIY_(0xEB,I2,B1,D1,0x57)
#  define XC(D1,L,B1,D2,B2)		SSL_(0xD7,L,B1,D1,B2,D2)
/* EXECUTE */
#  define EX(R1,D2,X2,B2)		RX_(0x44,R1,X2,B2,D2)
/* EXTRACT ACCESS */
#  define EAR(R1,R2)			RRE_(0xB24F,R1,R2)
/* EXTRACT PSW */
#  define EPSW(R1,R2)			RRE_(0xB98D,R1,R2)
/* INSERT CHARACTER */
#  define IC(R1,D2,X2,B2)		RX_(0x43,R1,X2,B2,D2)
#  define ICY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x73)
/* INSERT CHARACTERS UNDER MASK */
#  define ICM(R1,M3,D2,B2)		RS_(0xBF,R1,M3,B2,D2)
#  define ICMY(R1,M3,D2,B2)		RSY_(0xEB,R1,M3,B2,D2,0x81)
#  define ICMH(R1,M3,D2,B2)		RSY_(0xEB,R1,M3,B2,D2,0x80)
/* INSERT IMMEDIATE */
#  define IIHH(R1,I2)			RI_(0xA5,R1,0x0,I2)
#  define IIHL(R1,I2)			RI_(0xA5,R1,0x1,I2)
#  define IILH(R1,I2)			RI_(0xA5,R1,0x2,I2)
#  define IILL(R1,I2)			RI_(0xA5,R1,0x3,I2)
/* INSERT PROGRAM MASK */
#  define IPM(R1)			RRE_(0xB222,R1,0)
/* LOAD */
#  define LR(R1,R2)			RR_(0x18,R1,R2)
#  define LGR(R1,R2)			RRE_(0xB904,R1,R2)
#  define LGFR(R1,R2)			RRE_(0xB914,R1,R2)
#  define L(R1,D2,X2,B2)		RX_(0x58,R1,X2,B2,D2)
#  define LY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x58)
#  define LG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x04)
#  define LGF(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x14)
/* LOAD ACCESS MULTIPLE */
#  define LAM(R1,R3,D2,B2)		RS_(0x9A,R1,R3,B2,D2)
#  define LAMY(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x9A)
/* LOAD ADDRESS */
#  define LA(R1,D2,X2,B2)		RX_(0x41,R1,X2,B2,D2)
#  define LAY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x71)
/* LOAD ADDRESS EXTENDED */
#  define LAE(R1,D2,X2,B2)		RX_(0x51,R1,X2,B2,D2)
/* LOAD ADDRESS RELATIVE LONG */
#  define LARL(R1,I2)			RIL_(0xC0,R1,0x0,I2)
/* LOAD AND TEST */
#  define LTR(R1,R2)			RR_(0x12,R1,R2)
#  define LTGR(R1,R2)			RRE_(0xB902,R1,R2)
#  define LTGFR(R1,R2)			RRE_(0xB912,R1,R2)
/* LOAD BYTE */
#  define LGBR(R1,R2)			RRE_(0xB906,R1,R2)	/* disasm */
#  define LB(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x76)
#  define LGB(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x77)
/* LOAD COMPLEMENT */
#  define LCR(R1,R2)			RR_(0x13,R1,R2)
#  define LCGR(R1,R2)			RRE_(0xB903,R1,R2)
#  define LCGFR(R1,R2)			RRE_(0xB913,R1,R2)
/* LOAD HALFWORD */
#  define LH(R1,D2,X2,B2)		RX_(0x48,R1,X2,B2,D2)
#  define LHY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x78)
#  define LGHR(R1,R2)			RRE_(0xB907,R1,R2)	/* disasm */
#  define LGH(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x15)
/* LOAD HALFWORD IMMEDIATE */
#  define LHI(R1,I2)			RI_(0xA7,R1,0x8,I2)
#  define LGHI(R1,I2)			RI_(0xA7,R1,0x9,I2)
/* LOAD LOGICAL */
#  define LLGFR(R1,R2)			RRE_(0xB916,R1,R2)
#  define LLGF(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x16)
/* LOAD LOGICAL CHARACTER */
#  define LLGCR(R1,R2)			RRE_(0xB984,R1,R2)	/* disasm */
#  define LLGC(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x90)
/* LOAD LOGICAL HALFWORD */
#  define LLGHR(R1,R2)			RRE_(0xB985,R1,R2)	/* disasm */
#  define LLGH(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x91)
/* LOAD LOGICAL IMMEDIATE */
#  define LLIHH(R1,I2)			RI_(0xA5,R1,0xC,I2)
#  define LLIHL(R1,I2)			RI_(0xA5,R1,0xD,I2)
#  define LLILH(R1,I2)			RI_(0xA5,R1,0xE,I2)
#  define LLILL(R1,I2)			RI_(0xA5,R1,0xF,I2)
/* LOAD LOGICAL THIRTY ONE BITS */
#  define LLGTR(R1,R2)			RRE_(0xB917,R1,R2)
#  define LLGT(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x17)
/* LOAD MULTIPLE */
#  define LM(R1,R3,D2,B2)		RS_(0x98,R1,R3,B2,D2)
#  define LMY(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x98)
#  define LMG(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x04)
/* LOAD MULTIPLE DISJOINT */
#  define LMD(R1,R3,D2,B2,D4,B4)	SS_(0xEF,R1,R3,B2,D2,B4,D4)
/* LOAD MULTIPLE HIGH */
#  define LMH(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x96)
/* LOAD NEGATIVE */
#  define LNR(R1,R2)			RR_(0x11,R1,R2)
#  define LNGR(R1,R2)			RRE_(0xB901,R1,R2)
#  define LNGFR(R1,R2)			RRE_(0xB911,R1,R2)
/* LOAD PAIR FROM QUADWORD */
#  define LPQ(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x8F)
/* LOAD POSITIVE */
#  define LPR(R1,R2)			RR_(0x10,R1,R2)
#  define LPGR(R1,R2)			RRE_(0xB900,R1,R2)
#  define LPGFR(R1,R2)			RRE_(0xB910,R1,R2)
/* LOAD REVERSED */
#  define LRVR(R1,R2)			RRE_(0xB91F,R1,R2)
#  define LRVGR(R1,R2)			RRE_(0xB90F,R1,R2)
#  define LRVH(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x1F)
#  define LRV(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x1E)
#  define LRVG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x0F)
/* MONITOR CALL */
#  define MC(D1,B1,I2)			SI_(0xAF,I2,B1,D1)
/* MOVE */
#  define MVI(D1,B1,I2)			SI_(0x92,I2,B1,D1)
#  define MVIY(D1,B1,I2)		SIY_(0xEB,I2,B1,D1,0x52)
#  define MVC(D1,L,B1,D2,B2)		SSL_(0xD2,L,B1,D1,B2,D2)
/* MOVE INVERSE */
#  define MVCIN(D1,L,B1,D2,B2)		SSL_(0xE8,L,B1,D1,B2,D2)
/* MOVE LONG */
#  define MVCL(R1,R2)			RR_(0x0E,R1,R2)
/* MOVE LONG EXTENDED */
#  define MVCLE(R1,R3,D2,B2)		RS_(0xA8,R1,R3,B2,D2)
/* MOVE LONG UNICODE */
#  define MVCLU(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x8E)
/* MOVE NUMERICS */
#  define MVN(D1,L,B1,D2,B2)		SSL_(0xD1,L,B1,D1,B2,D2)
/* MOVE STRING */
#  define MVST(R1,R2)			RRE_(0xB255,R1,R2)
/* MOVE WITH OFFSET */
#  define MVO(D1,L1,B1,D2,L2,B2)	SS_(0xF1,L1,L2,B1,D1,B2,D2)
/* MOVE ZONES */
#  define MVZ(D1,L,B1,D2,B2)		SSL_(0xD3,L,B1,D1,B2,D2)
/* MULTIPLY */
#  define MR(R1,R2)			RR_(0x1C,R1,R2)
#  define M(R1,D2,X2,B2)		RX_(0x5C,R1,X2,B2,D2)
/* MULTIPLY HALFWORD */
#  define MH(R1,D2,X2,B2)		RX_(0x4C,R1,X2,B2,D2)
/* MULTIPLY HALFWORD IMMEDIATE */
#  define MHI(R1,I2)			RI_(0xA7,R1,0xC,I2)
#  define MGHI(R1,I2)			RI_(0xA7,R1,0xD,I2)
/* MULTIPLY LOGICAL */
#  define MLR(R1,R2)			RRE_(0xB996,R1,R2)
#  define MLGR(R1,R2)			RRE_(0xB986,R1,R2)
#  define ML(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x96)
#  define MLG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x86)
/* MULTIPLY SINGLE */
#  define MSR(R1,R2)			RRE_(0xB252,R1,R2)
#  define MSGR(R1,R2)			RRE_(0xB90C,R1,R2)
#  define MSGFR(R1,R2)			RRE_(0xB91C,R1,R2)
#  define MS(R1,D2,X2,B2)		RX_(0x71,R1,X2,B2,D2)
#  define MSY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x51)
#  define MSG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x0C)
#  define MSGF(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x1C)
/* OR */
#  define OR(R1,R2)			RR_(0x16,R1,R2)
#  define OGR(R1,R2)			RRE_(0xB981,R1,R2)
#  define O(R1,D2,X2,B2)		RX_(0x56,R1,X2,B2,D2)
#  define OY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x56)
#  define OG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x81)
#  define OI(D1,B1,I2)			SI_(0x96,I2,B1,D1)
#  define OIY(D1,B1,I2)			SIY_(0xEB,I2,B1,D1,0x56)
#  define OC(D1,L,B1,D2,B2)		SSL_(0xD6,L,B1,D1,B2,D2)
/* OR IMMEDIATE */
#  define OIHH(R1,I2)			RI_(0xA5,R1,0x8,I2)
#  define OIHL(R1,I2)			RI_(0xA5,R1,0x9,I2)
#  define OILH(R1,I2)			RI_(0xA5,R1,0xA,I2)
#  define OILL(R1,I2)			RI_(0xA5,R1,0xB,I2)
/* PACK */
#  define PACK(D1,L1,B1,D2,L2,B2)	SS_(0xF2,L1,L2,B1,D1,B2,D2)
/* PACK ASCII */
#  define PKA(D1,B1,D2,L2,B2)		SSL_(0xE9,L2,B1,D1,B2,D2)
/* PACK UNICODE */
#  define PKU(D1,B1,D2,L2,B2)		SSL_(0xE1,L2,B1,D1,B2,D2)
/* PERFORM LOCKED OPERATION */
#  define PLO(R1,D2,B2,R3,D4,B4)	SS_(0xEE,R1,R3,B2,D2,B4,D4)
/* ROTATE LEFT SINGLE LOGICAL */
#  define RLL(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x1D)
#  define RLLG(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x1C)
/* SEARCH STRING */
#  define SRST(R1,R2)			RRE_(0xB25E,R1,R2)
/* SET ACCESS */
#  define SAR(R1,R2)			RRE_(0xB24E,R1,R2)
/* SET ADDRESSING MODE */
#  define SAM24()			E_(0x10C)
#  define SAM31()			E_(0x10D)
#  define SAM64()			E_(0x10E)
/* SET PROGRAM MASK */
#  define SPM(R1)			RR_(0x04,R1,0)
/* SHIFT LEFT DOUBLE */
#  define SLDA(R1,D2,B2)		RS_(0x8F,R1,0,B2,D2)
/* SHIFT LEFT DOUBLE LOGICAL */
#  define SLDL(R1,D2,B2)		RS_(0x8D,R1,0,B2,D2)
/* SHIFT LEFT SINGLE */
#  define SLA(R1,D2,B2)			RS_(0x8B,R1,0,B2,D2)
#  define SLAG(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x0B)
/* SHIFT LEFT SINGLE LOGICAL */
#  define SLL(R1,D2,B2)			RS_(0x89,R1,0,B2,D2)
#  define SLLG(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x0D)
/* SHIFT RIGHT DOUBLE */
#  define SRDA(R1,D2,B2)		RS_(0x8E,R1,0,B2,D2)
/* SHIFT RIGHT DOUBLE LOGICAL */
#  define SRDL(R1,D2,B2)		RS_(0x8C,R1,0,B2,D2)
/* SHIFT RIGHT SINGLE */
#  define SRA(R1,D2,B2)			RS_(0x8A,R1,0,B2,D2)
#  define SRAG(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x0A)
/* SHIFT RIGHT SINGLE LOGICAL */
#  define SRL(R1,D2,B2)			RS_(0x88,R1,0,B2,D2)
#  define SRLG(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x0C)
/* STORE */
#  define ST(R1,D2,X2,B2)		RX_(0x50,R1,X2,B2,D2)
#  define STY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x50)
#  define STG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x24)
/* STORE ACCESS MULTIPLE */
#  define STAM(R1,R3,D2,B2)		RS_(0x9B,R1,R3,B2,D2)
#  define STAMY(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x9B)
/* STORE CHARACTER */
#  define STC(R1,D2,X2,B2)		RX_(0x42,R1,X2,B2,D2)
#  define STCY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x72)
/* STORE CHARACTERS UNDER MASK */
#  define STCM(R1,M3,D2,B2)		RS_(0xBE,R1,M3,B2,D2)
#  define STCMY(R1,M3,D2,B2)		RSY_(0xEB,R1,M3,B2,D2,0x2D)
#  define STCMH(R1,M3,D2,B2)		RSY_(0xEB,R1,M3,B2,D2,0x2C)
/* STORE CLOCK */
#  define STCK(D2,B2)			S_(0xB205,B2,D2)
/* STORE CLOCK EXTENDED */
#  define STCKE(D2,B2)			S_(0xB278,B2,D2)
/* STORE HALFWORD */
#  define STH(R1,D2,X2,B2)		RX_(0x40,R1,X2,B2,D2)
#  define STHY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x70)
/* STORE MULTIPLE */
#  define STM(R1,R3,D2,B2)		RS_(0x90,R1,R3,B2,D2)
#  define STMY(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x90)
#  define STMG(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x24)
/* STORE MULTIPLE HIGH */
#  define STMH(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x26)
/* STORE PAIR TO QUADWORD */
#  define STPQ(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x8E)
/* STORE REVERSED */
#  define STRVH(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x3F)
#  define STRV(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x3E)
#  define STRVG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x2F)
/* SUBTRACT */
#  define SR(R1,R2)			RR_(0x1B,R1,R2)
#  define SGR(R1,R2)			RRE_(0xB909,R1,R2)
#  define SGFR(R1,R2)			RRE_(0xB919,R1,R2)
#  define S(R1,D2,X2,B2)		RX_(0x5B,R1,X2,B2,D2)
#  define SY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x5B)
#  define SG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x09)
#  define SGF(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x19)
/* SUBTRACT HALFWORD */
#  define SH(R1,D2,X2,B2)		RX_(0x4B,R1,X2,B2,D2)
#  define SHY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x7B)
/* SUBTRACT LOGICAL */
#  define SLR(R1,R2)			RR_(0x1F,R1,R2)
#  define SLGR(R1,R2)			RRE_(0xB90B,R1,R2)
#  define SLGFR(R1,R2)			RRE_(0xB91B,R1,R2)
#  define SL(R1,D2,X2,B2)		RX_(0x5F,R1,X2,B2,D2)
#  define SLY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x5F)
#  define SLG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x0B)
#  define SLGF(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x1B)
/* SUBTRACT LOGICAL WITH BORROW */
#  define SLBR(R1,R2)			RRE_(0xB999,R1,R2)
#  define SLBGR(R1,R2)			RRE_(0xB989,R1,R2)
#  define SLB(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x99)
#  define SLBG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x89)
/* SUPERVISOR CALL */
#  define SVC(I)			I_(0xA,I)
/* TEST ADDRESSING MODE */
#  define TAM()				E_(0x10B)
/* TEST AND SET */
#  define TS(D2,B2)			RS_(0x93,0,0,B2,D2)
/* TEST UNDER MASK (TEST UNDER MASK HIGH, TEST UNDER MASK LOW) */
#  define TM(D1,B1,I2)			SI_(0x91,I2,B1,D1)
#  define TMY(D1,B1,I2)			SIY_(0xEB,I2,B1,D1,0x51)
#  define TMHH(R1,I2)			RI_(0xA7,R1,0x2,I2)
#  define TMHL(R1,I2)			RI_(0xA7,R1,0x3,I2)
#  define TMLH(R1,I2)			RI_(0xA7,R1,0x0,I2)
#  define TMH(R1,I2)			TMLH(R1,I2)
#  define TMLL(R1,I2)			RI_(0xA7,R1,0x1,I2)
#  define TML(R1,I2)			TMLL(R1,I2)
/* TRANSLATE */
#  define TR(D1,L,B1,D2,B2)		SSL_(0xDC,L,B1,D1,B2,D2)
/* TRANSLATE AND TEST */
#  define TRT(D1,L,B1,D2,B2)		SSL_(0xDD,L,B1,D1,B2,D2)
/* TRANSLATE EXTENDED */
#  define TRE(R1,R2)			RRE_(0xB2A5,R1,R2)
/* TRANSLATE ONE TO ONE */
#  define TROO(R1,R2)			RRE_(0xB993,R1,R2)
/* TRANSLATE ONE TO TWO */
#  define TROT(R1,R2)			RRE_(0xB992,R1,R2)
/* TRANSLATE TWO TO ONE */
#  define TRTO(R1,R2)			RRE_(0xB991,R1,R2)
/* TRANSLATE TWO TO TWO */
#  define TRTT(R1,R2)			RRE_(0xB990,R1,R2)
/* UNPACK */
#  define UNPK(D1,L1,B1,D2,L2,B2)	SS_(0xF3,L1,L2,B1,D1,B2,D2)
/* UNPACK ASCII */
#  define UNPKA(D1,L1,B1,D2,L2,B2)	SS_(0xEA,L1,L2,B1,D1,B2,D2)
/* UNPACK UNICODE */
#  define UNPKU(D1,L1,B1,D2,L2,B2)	SS_(0xE2,L1,L2,B1,D1,B2,D2)
/* UPDATE TREE */
#  define UPT()				E_(0x0102)
/****************************************************************
 * Decimal Instructions						*
 ****************************************************************/
/* ADD DECIMAL */
#  define AP(D1,L1,B1,D2,L2,B2)		SS_(0xFA,L1,L2,B1,D1,B2,D2)
/* COMPARE DECIMAL */
#  define CP(D1,L1,B1,D2,L2,B2)		SS_(0xF9,L1,L2,B1,D1,B2,D2)
/* DIVIDE DECIMAL */
#  define DP(D1,L1,B1,D2,L2,B2)		SS_(0xFD,L1,L2,B1,D1,B2,D2)
/* EDIT */
#  define ED(D1,L,B1,D2,B2)		SSL_(0xDE,L,B1,D1,B2,D2)
/* EDIT AND MARK */
#  define EDMK(D1,L,B1,D2,B2)		SSL_(0xDE,L,B1,D1,B2,D2)
/* MULTIPLY DECIMAL */
#  define MP(D1,L1,B1,D2,L2,B2)		SS_(0xFC,L1,L2,B1,D1,B2,D2)
/* SHIFT AND ROUND DECIMAL */
#  define SRP(D1,L1,B1,D2,L2,B2)	SS_(0xF0,L1,L2,B1,D1,B2,D2)
/* SUBTRACE DECIMAL */
#  define SP(D1,L1,B1,D2,L2,B2)		SS_(0xFB,L1,L2,B1,D1,B2,D2)
/* TEST DECIMAL */
#  define TP(D1,L1,B1)			RSL_(0xEB,L1,B1,D1,0xC0)
/* ZERO AND ADD */
#  define ZAP(D1,L1,B1,D2,L2,B2)	SS_(0xF8,L1,L2,B1,D1,B2,D2)
/****************************************************************
 * Control Instructions						*
 ****************************************************************/
/* BRANCH AND SET AUTHORITY */
#  define BSA(R1,R2)			RRE_(0xB25A,R1,R2)
/* BRANCH AND STACK */
#  define BAKR(R1,R2)			RRE_(0xB240,R1,R2)
/* BRANCH IN SUBSPACE GROUP */
#  define BSG(R1,R2)			RRE_(0xB258,R1,R2)
/* COMPARE AND SWAP AND PURGE */
#  define CSP(R1,R2)			RRE_(0xB250,R1,R2)
#  define CSPG(R1,R2)			RRE_(0xB98A,R1,R2)
/* DIAGNOSE */
#  define DIAG()			SI_(0x83,0,0,0)
/* EXTRACT AND SET EXTENDED AUTHORITY */
#  define ESEA(R1)			RRE_(0xB99D,R1,0)
/* EXTRACT PRIMARY ASN */
#  define EPAR(R1)			RRE_(0xB226,R1,0)
/* EXTRACT SECONDARY ASN */
#  define ESAR(R1)			RRE_(0xB227,R1,0)
/* EXTRACT STACKED REGISTERS */
#  define EREG(R1,R2)			RRE_(0xB249,R1,R2)
#  define EREGG(R1,R2)			RRE_(0xB90E,R1,R2)
/* EXTRACT STACKED STATE */
#  define ESTA(R1,R2)			RRE_(0xB24A,R1,R2)
/* INSERT ADDRESS SPACE CONTROL */
#  define IAC(R1)			RRE_(0xB224,R1,0)
/* INSERT PSW KEY */
#  define IPK()				S_(0xB20B,0,0)
/* INSERT STORAGE KEY EXTENDED */
#  define ISKE(R1,R2)			RRE_(0xB229,R1,R2)
/* INSERT VIRTUAL STORAGE KEY */
#  define IVSK(R1,R2)			RRE_(0xB223,R1,R2)
/* INVALIDATE DAT TABLE ENTRY */
#  define IDTE(R1,R2,R3)		RRF_(0xB98E,R3,0,R1,R2)
/* INVALIDATE PAGE TABLE ENTRY */
#  define IPTE(R1,R2)			RRE_(0xB221,R1,R2)
/* LOAD ADDRESS SPACE PARAMETER */
#  define LASP(D1,B1,D2,B2)		SSE_(0xE500,B1,D1,B2,D2)
/* LOAD CONTROL */
#  define LCTL(R1,R3,D2,B2)		RS_(0xB7,R1,R3,B2,D2)
#  define LCTLG(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x2F)
/* LOAD PSW */
#  define LPSW(D2,B2)			SI_(0x82,0,B2,D2)
/* LOAD PSW EXTENDED */
#  define LPSWE(D2,B2)			S_(0xB2B2,B2,D2)
/* LOAD REAL ADDRESS */
#  define LRA(R1,D2,X2,B2)		RX_(0xB1,R1,X2,B2,D2)
#  define LRAY(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x13)
#  define LRAG(R1,D2,X2,B2)		RXY_(0xE3,R1,X2,B2,D2,0x03)
/* LOAD USING REAL ADDRESS */
#  define LURA(R1,R2)			RRE_(0xB24B,R1,R2)
#  define LURAG(R1,R2)			RRE_(0xB905,R1,R2)
/* MODIFY STACKED STATE */
#  define MSTA(R1)			RRE_(0xB247,R1,0)
/* MOVE PAGE */
#  define MVPG(R1,R2)			RRE_(0xB254,R1,R2)
/* MOVE TO PRIMARY */
#  define MVCP(D1,R1,B1,D2,B2,R3)	SS_(0xDA,R1,R3,B1,D1,B2,D2)
/* MOVE TO SECONDARY */
#  define MVCS(D1,R1,B1,D2,B2,R3)	SS_(0xDB,R1,R3,B1,D1,B2,D2)
/* MOVE WITH DESTINATION KEY */
#  define MVCDK(D1,B1,D2,B2)		SSE_(0xE50F,B1,D1,B2,D2)
/* MOVE WITH KEY */
#  define MVCK(D1,R1,B1,D2,B2,R3)	SS_(0xD9,R1,R3,B1,D1,B2,D2)
/* MOVE WITH SOURCE KEY */
#  define MVCSK(D1,B1,D2,B2)		SSE_(0xE50E,B1,D1,B2,D2)
/* PAGE IN */
#  define PGIN(R1,R2)			RRE_(0xB22E,R1,R2)
/* PAGE OUT */
#  define PGOUT(R1,R2)			RRE_(0xB22F,R1,R2)
/* PROGRAM CALL */
#  define PC(D2,B2)			S_(0xB218,B2,D2)
/* PROGRAM RETURN */
#  define PR()				E_(0x0101)
/* PROGRAM TRANSFER */
#  define PT(R1,R2)			RRE_(0xB228,R1,R2)
/* PURGE ALB */
#  define PALB()			RRE_(0xB248,0,0)
/* PURGE TLB */
#  define PTLB()			S_(0xB20D,0,0)
/* RESET REFERENCE BIT EXTENDED */
#  define RRBE(R1,R2)			RRE_(0xB22A,R1,R2)
/* RESUME PROGRAM */
#  define RP(D2,B2)			S_(0xB277,B2,D2)
/* SET ADDRESS SPACE CONTROL */
#  define SAC(D2,B2)			S_(0xB219,B2,D2)
/* SET ADDRESS SPACE CONTROL FAST */
#  define SACF(D2,B2)			S_(0xB279,B2,D2)
/* SET CLOCK */
#  define SCK(D2,B2)			S_(0xB204,B2,D2)
/* SET CLOCK COMPARATOR */
#  define SCKC(D2,B2)			S_(0xB206,B2,D2)
/* SET CLOCK PROGRAMMABLE FIELD */
#  define SCKPF()			E_(0x0107)
/* SET CPU TIMER */
#  define SPT(D2,B2)			S_(0xB208,B2,D2)
/* SET PREFIX */
#  define SPX(D2,B2)			S_(0xB210,B2,D2)
/* SET PSW FROM ADDRESS */
#  define SPKA(D2,B2)			S_(0xB20A,B2,D2)
/* SET SECONDARY ASN */
#  define SSAR(R1)			RRE_(0xB225,R1,0)
/* SET STORAGE KEY EXTENDED */
#  define SSKE(R1,R2)			RRE_(0xB22B,R1,R2)
/* SET SYSTEM MASK */
#  define SSM(D2,B2)			SI_(0x80,0,B2,D2)
/* SIGNAL PROCESSOR */
#  define SIGP(R1,R3,D2,B2)		RS_(0xAE,R1,R3,B2,D2)
/* STORE CLOCK COMPARATOR */
#  define STCKC(D2,B2)			S_(0xB207,B2,D2)
/* STORE CONTROL */
#  define STCTL(R1,R3,D2,B2)		RS_(0xB6,R1,R3,B2,D2)
#  define STCTG(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x25)
/* STORE CPU ADDRESS */
#  define STAP(D2,B2)			S_(0xB212,B2,D2)
/* STORE CPU ID */
#  define STIDP(D2,B2)			S_(0xB202,B2,D2)
/* STORE CPU TIMER */
#  define STPT(D2,B2)			S_(0xB209,B2,D2)
/* STORE FACILITY LIST */
#  define STFL(D2,B2)			S_(0xB2B1,B2,D2)
/* STORE PREFIX */
#  define STPX(D2,B2)			S_(0xB211,B2,D2)
/* STORE REAL ADDRES */
#  define STRAG(D1,B1,D2,B2)		SSE_(0xE502,B1,D1,B2,D2)
/* STORE SYSTEM INFORMATION */
#  define STSI(D2,B2)			S_(0xB27D,B2,D2)
/* STORE THEN AND SYSTEM MASK */
#  define STNSM(D1,B1,I2)		SI_(0xAC,I2,B1,D1)
/* STORE THEN OR SYSTEM MASK */
#  define STOSM(D1,B1,I2)		SI_(0xAD,I2,B1,D1)
/* STORE USING REAL ADDRESS */
#  define STURA(R1,R2)			RRE_(0xB246,R1,R2)
#  define STURG(R1,R2)			RRE_(0xB925,R1,R2)
/* TEST ACCESS */
#  define TAR(R1,R2)			RRE_(0xB24C,R1,R2)
/* TEST BLOCK */
#  define TB(R1,R2)			RRE_(0xB22C,R1,R2)
/* TEST PROTECTION */
#  define TPROT(D1,B1,D2,B2)		SSE_(0xE501,B1,D1,B2,D2)
/* TRACE */
#  define TRACE(R1,R3,D2,B2)		RS_(0x99,R1,R3,B2,D2)
#  define TRACG(R1,R3,D2,B2)		RSY_(0xEB,R1,R3,B2,D2,0x0F)
/* TRAP */
#  define TRAP2()			E_(0x01FF)
#  define TRAP4(D2,B2)			S_(0xB2FF,B2,D2)
/****************************************************************
 * I/O Instructions						*
 ****************************************************************/
/* CANCEL SUBCHANNEL */
#  define XSCH()			S_(0xB276,0,0)
/* CLEAR SUBCHANNEL */
#  define CSCH()			S_(0xB230,0,0)
/* HALT SUBCHANNEL */
#  define HSCH()			S_(0xB231,0,0)
/* MODIFY SUBCHANNEL */
#  define MSCH(D2,B2)			S_(0xB232,B2,D2)
/* RESET CHANNEL PATH */
#  define RCHP()			S_(0xB23B,0,0)
/* RESUME SUBCHANNEL */
#  define RSCH()			S_(0xB238,0,0)
/* SET ADDRESS LIMIT */
#  define SAL()				S_(0xB237,0,0)
/* SET CHANNEL MONITOR */
#  define SCHM()			S_(0xB23C,0,0)
/* START SUBCHANNEL */
#  define SSCH(D2,B2)			S_(0xB233,B2,D2)
/* STORE CHANNEL PATH STATUS */
#  define STCPS(D2,B2)			S_(0xB23A,B2,D2)
/* STORE CHANNEL REPORT WORD */
#  define STCRW(D2,B2)			S_(0xB239,B2,D2)
/* STORE SUBCHANNEL */
#  define STSCH(D2,B2)			S_(0xB234,B2,D2)
/* TEST PENDING INTERRUPTION */
#  define TPI(D2,B2)			S_(0xB236,B2,D2)
/* TEST SUBCHANNEL */
#  define TSCH(D2,B2)			S_(0xB235,B2,D2)
#  define xdivr(r0,r1)			_xdivr(_jit,r0,r1)
static int32_t _xdivr(jit_state_t*,int32_t,int32_t);
#  define xdivr_u(r0,r1)		_xdivr_u(_jit,r0,r1)
static int32_t _xdivr_u(jit_state_t*,int32_t,int32_t);
#  define xdivi(r0,i0)			_xdivi(_jit,r0,i0)
static int32_t _xdivi(jit_state_t*,int32_t,jit_word_t);
#  define xdivi_u(r0,i0)		_xdivi_u(_jit,r0,i0)
static int32_t _xdivi_u(jit_state_t*,int32_t,jit_word_t);
#  define crr(cc,r0,r1,r2)		_crr(_jit,cc,r0,r1,r2)
static void _crr(jit_state_t*,
		 int32_t,int32_t,int32_t,int32_t);
#  define cri(cc,r0,r1,i0)		_cri(_jit,cc,r0,r1,i0)
static void _cri(jit_state_t*,
		 int32_t,int32_t,int32_t,jit_word_t);
#  define crr_u(cc,r0,r1,r2)		_crr_u(_jit,cc,r0,r1,r2)
static void _crr_u(jit_state_t*,
		   int32_t,int32_t,int32_t,int32_t);
#  define cri_u(cc,r0,r1,i0)		_cri_u(_jit,cc,r0,r1,i0)
static void _cri_u(jit_state_t*,
		   int32_t,int32_t,int32_t,jit_word_t);
#  define brr(cc,i0,r0,r1)		_brr(_jit,cc,i0,r0,r1)
static void _brr(jit_state_t*,int32_t,
		 jit_word_t,int32_t,int32_t);
#  define brr_p(cc,i0,r0,r1)		_brr_p(_jit,cc,i0,r0,r1)
static jit_word_t _brr_p(jit_state_t*,int32_t,
			 jit_word_t,int32_t,int32_t);
#  define bri(cc,i0,r0,i1)		_bri(_jit,cc,i0,r0,i1)
static void _bri(jit_state_t*,int32_t,
		 jit_word_t,int32_t,jit_word_t);
#  define bri_p(cc,i0,r0,i1)		_bri_p(_jit,cc,i0,r0,i1)
static jit_word_t _bri_p(jit_state_t*,int32_t,
			 jit_word_t,int32_t,jit_word_t);
#  define brr_u(cc,i0,r0,r1)		_brr_u(_jit,cc,i0,r0,r1)
static void _brr_u(jit_state_t*,int32_t,
		   jit_word_t,int32_t,int32_t);
#  define brr_u_p(cc,i0,r0,r1)		_brr_u_p(_jit,cc,i0,r0,r1)
static jit_word_t _brr_u_p(jit_state_t*,int32_t,
			   jit_word_t,int32_t,int32_t);
#  define bri_u(cc,i0,r0,i1)		_bri_u(_jit,cc,i0,r0,i1)
static void _bri_u(jit_state_t*,int32_t,
		   jit_word_t,int32_t,jit_word_t);
#  define bri_u_p(cc,i0,r0,i1)		_bri_u_p(_jit,cc,i0,r0,i1)
static jit_word_t _bri_u_p(jit_state_t*,int32_t,
			   jit_word_t,int32_t,jit_word_t);
#  define baddr(c,s,i0,r0,r1)		_baddr(_jit,c,s,i0,r0,r1)
static void _baddr(jit_state_t*,int32_t,jit_bool_t,
		   jit_word_t,int32_t,int32_t);
#  define baddr_p(c,s,i0,r0,r1)		_baddr_p(_jit,c,s,i0,r0,r1)
static jit_word_t _baddr_p(jit_state_t*,int32_t,jit_bool_t,
			   jit_word_t,int32_t,int32_t);
#  define baddi(c,s,i0,r0,i1)		_baddi(_jit,c,s,i0,r0,i1)
static void _baddi(jit_state_t*,int32_t,jit_bool_t,
		   jit_word_t,int32_t,jit_word_t);
#  define baddi_p(c,s,i0,r0,i1)		_baddi_p(_jit,c,s,i0,r0,i1)
static jit_word_t _baddi_p(jit_state_t*,int32_t,jit_bool_t,
			   jit_word_t,int32_t,jit_word_t);
#  define bsubr(c,s,i0,r0,r1)		_bsubr(_jit,c,s,i0,r0,r1)
static void _bsubr(jit_state_t*,int32_t,jit_bool_t,
		   jit_word_t,int32_t,int32_t);
#  define bsubr_p(c,s,i0,r0,r1)		_bsubr_p(_jit,c,s,i0,r0,r1)
static jit_word_t _bsubr_p(jit_state_t*,int32_t,jit_bool_t,
			   jit_word_t,int32_t,int32_t);
#  define bsubi(c,s,i0,r0,i1)		_bsubi(_jit,c,s,i0,r0,i1)
static void _bsubi(jit_state_t*,int32_t,jit_bool_t,
		   jit_word_t,int32_t,jit_word_t);
#  define bsubi_p(c,s,i0,r0,i1)		_bsubi_p(_jit,c,s,i0,r0,i1)
static jit_word_t _bsubi_p(jit_state_t*,int32_t,jit_bool_t,
			   jit_word_t,int32_t,jit_word_t);
#  define bmxr(cc,i0,r0,r1)		_bmxr(_jit,cc,i0,r0,r1)
static void _bmxr(jit_state_t*,int32_t,
		  jit_word_t,int32_t,int32_t);
#  define bmxr_p(cc,i0,r0,r1)		_bmxr_p(_jit,cc,i0,r0,r1)
static jit_word_t _bmxr_p(jit_state_t*,int32_t,
			  jit_word_t,int32_t,int32_t);
#  define bmxi(cc,i0,r0,i1)		_bmxi(_jit,cc,i0,r0,i1)
static void _bmxi(jit_state_t*,int32_t,
		  jit_word_t,int32_t,jit_word_t);
#  define bmxi_p(cc,i0,r0,i1)		_bmxi_p(_jit,cc,i0,r0,i1)
static jit_word_t _bmxi_p(jit_state_t*,int32_t,
			  jit_word_t,int32_t,jit_word_t);
#  define movr(r0,r1)			_movr(_jit,r0,r1)
static void _movr(jit_state_t*,int32_t,int32_t);
#  define movi(r0,i0)			_movi(_jit,r0,i0)
static void _movi(jit_state_t*,int32_t,jit_word_t);
#  define movi_p(r0,i0)			_movi_p(_jit,r0,i0)
static jit_word_t _movi_p(jit_state_t*,int32_t,jit_word_t);
#  define addr(r0,r1,r2)		_addr(_jit,r0,r1,r2)
static void _addr(jit_state_t*,int32_t,int32_t,int32_t);
#  define addi(r0,r1,i0)		_addi(_jit,r0,r1,i0)
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,i0)		_addci(_jit,r0,r1,i0)
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,i0)		_addxi(_jit,r0,r1,i0)
static void _addxi(jit_state_t*,int32_t,int32_t,jit_word_t);
#  define subr(r0,r1,r2)		_subr(_jit,r0,r1,r2)
static void _subr(jit_state_t*,int32_t,int32_t,int32_t);
#  define subi(r0,r1,i0)		_subi(_jit,r0,r1,i0)
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,i0)		_subci(_jit,r0,r1,i0)
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,i0)		_subxi(_jit,r0,r1,i0)
static void _subxi(jit_state_t*,int32_t,int32_t,jit_word_t);
#  define rsbi(r0, r1, i0)		_rsbi(_jit, r0, r1, i0)
static void _rsbi(jit_state_t*,int32_t,int32_t,jit_word_t);
#  define mulr(r0,r1,r2)		_mulr(_jit,r0,r1,r2)
static void _mulr(jit_state_t*,int32_t,int32_t,int32_t);
#  define muli(r0,r1,i0)		_muli(_jit,r0,r1,i0)
static void _muli(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);
#  define divr(r0,r1,r2)		_divr(_jit,r0,r1,r2)
static void _divr(jit_state_t*,int32_t,int32_t,int32_t);
#  define divi(r0,r1,i0)		_divi(_jit,r0,r1,i0)
static void _divi(jit_state_t*,int32_t,int32_t,jit_word_t);
#  define divr_u(r0,r1,r2)		_divr_u(_jit,r0,r1,r2)
static void _divr_u(jit_state_t*,int32_t,int32_t,int32_t);
#  define divi_u(r0,r1,i0)		_divi_u(_jit,r0,r1,i0)
static void _divi_u(jit_state_t*,int32_t,int32_t,jit_word_t);
#  define remr(r0,r1,r2)		_remr(_jit,r0,r1,r2)
static void _remr(jit_state_t*,int32_t,int32_t,int32_t);
#  define remi(r0,r1,i0)		_remi(_jit,r0,r1,i0)
static void _remi(jit_state_t*,int32_t,int32_t,jit_word_t);
#  define remr_u(r0,r1,r2)		_remr_u(_jit,r0,r1,r2)
static void _remr_u(jit_state_t*,int32_t,int32_t,int32_t);
#  define remi_u(r0,r1,i0)		_remi_u(_jit,r0,r1,i0)
static void _remi_u(jit_state_t*,int32_t,int32_t,jit_word_t);
#  define qdivr(r0,r1,r2,r3)		_qdivr(_jit,r0,r1,r2,r3)
static void _qdivr(jit_state_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 qdivr_u(r0,r1,r2,r3)		_qdivr_u(_jit,r0,r1,r2,r3)
static void _qdivr_u(jit_state_t*,int32_t,
		     int32_t,int32_t,int32_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);
#  if __WORDSIZE == 32
#    define lshr(r0,r1,r2)		_lshr(_jit,r0,r1,r2)
static void _lshr(jit_state_t*,int32_t,int32_t,int32_t);
#  else
#    define lshr(r0,r1,r2)		SLLG(r0,r1,0,r2)
#  endif
#  define lshi(r0,r1,i0)		_lshi(_jit,r0,r1,i0)
static void _lshi(jit_state_t*,int32_t,int32_t,jit_word_t);
#  if __WORDSIZE == 32
#    define rshr(r0,r1,r2)		_rshr(_jit,r0,r1,r2)
static void _rshr(jit_state_t*,int32_t,int32_t,int32_t);
#  else
#    define rshr(r0,r1,r2)		SRAG(r0,r1,0,r2)
#  endif
#  define rshi(r0,r1,i0)		_rshi(_jit,r0,r1,i0)
static void _rshi(jit_state_t*,int32_t,int32_t,jit_word_t);
#  if __WORDSIZE == 32
#    define rshr_u(r0,r1,r2)		_rshr_u(_jit,r0,r1,r2)
static void _rshr_u(jit_state_t*,int32_t,int32_t,int32_t);
#  else
#    define rshr_u(r0,r1,r2)		SRLG(r0,r1,0,r2)
#  endif
#  define rshi_u(r0,r1,i0)		_rshi_u(_jit,r0,r1,i0)
static void _rshi_u(jit_state_t*,int32_t,int32_t,jit_word_t);
#  if __WORDSIZE == 32
#    define negr(r0,r1)			LCR(r0,r1)
#  else
#    define negr(r0,r1)			LCGR(r0,r1)
#  endif
#  define comr(r0,r1)			_comr(_jit,r0,r1)
static void _comr(jit_state_t*,int32_t,int32_t);
#  define andr(r0,r1,r2)		_andr(_jit,r0,r1,r2)
static void _andr(jit_state_t*,int32_t,int32_t,int32_t);
#  define andi(r0,r1,i0)		_andi(_jit,r0,r1,i0)
static void _andi(jit_state_t*,int32_t,int32_t,jit_word_t);
#  define orr(r0,r1,r2)			_orr(_jit,r0,r1,r2)
static void _orr(jit_state_t*,int32_t,int32_t,int32_t);
#  define ori(r0,r1,i0)			_ori(_jit,r0,r1,i0)
static void _ori(jit_state_t*,int32_t,int32_t,jit_word_t);
#  define xorr(r0,r1,r2)		_xorr(_jit,r0,r1,r2)
static void _xorr(jit_state_t*,int32_t,int32_t,int32_t);
#  define xori(r0,r1,i0)		_xori(_jit,r0,r1,i0)
static void _xori(jit_state_t*,int32_t,int32_t,jit_word_t);
#  define bswapr_us(r0,r1)		extr_us(r0,r1)
#  if __WORDSIZE == 32
#    define bswapr_ui(r0,r1)		movr(r0,r1)
#  else
#    define bswapr_ui(r0,r1)		extr_ui(r0,r1)
#    define bswapr, 2019_ul(r0,r1)		movr(r0,r1)
#  endif
#  define extr_c(r0,r1)			LGBR(r0,r1)
#  define extr_uc(r0,r1)		LLGCR(r0,r1)
#  define extr_s(r0,r1)			LGHR(r0,r1)
#  define extr_us(r0,r1)		LLGHR(r0,r1)
#  if __WORDSIZE == 64
#    define extr_i(r0,r1)		LGFR(r0,r1)
#    define extr_ui(r0,r1)		LLGFR(r0,r1)
#  endif
#  define ldr_c(r0,r1)			LGB(r0,0,0,r1)
#  define ldi_c(r0,i0)			_ldi_c(_jit,r0,i0)
static void _ldi_c(jit_state_t*,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,i0)		_ldxi_c(_jit,r0,r1,i0)
static void _ldxi_c(jit_state_t*,int32_t,int32_t,jit_word_t);
#  define ldr_uc(r0,r1)			LLGC(r0,0,0,r1)
#  define ldi_uc(r0,i0)			_ldi_uc(_jit,r0,i0)
static void _ldi_uc(jit_state_t*,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,i0)		_ldxi_uc(_jit,r0,r1,i0)
static void _ldxi_uc(jit_state_t*,int32_t,int32_t,jit_word_t);
#  if __WORDSIZE == 32
#    define ldr_s(r0,r1)		LH(r0,0,0,r1)
#  else
#    define ldr_s(r0,r1)		LGH(r0,0,0,r1)
#  endif
#  define ldi_s(r0,i0)			_ldi_s(_jit,r0,i0)
static void _ldi_s(jit_state_t*,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,i0)		_ldxi_s(_jit,r0,r1,i0)
static void _ldxi_s(jit_state_t*,int32_t,int32_t,jit_word_t);
#  define ldr_us(r0,r1)			LLGH(r0,0,0,r1)
#  define ldi_us(r0,i0)			_ldi_us(_jit,r0,i0)
static void _ldi_us(jit_state_t*,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,i0)		_ldxi_us(_jit,r0,r1,i0)
static void _ldxi_us(jit_state_t*,int32_t,int32_t,jit_word_t);
#  if __WORDSIZE == 32
#    define ldr_i(r0,r1)		LLGF(r0,0,0,r1)
#  else
#    define ldr_i(r0,r1)		LGF(r0,0,0,r1)
#  endif
#  define ldi_i(r0,i0)			_ldi_i(_jit,r0,i0)
static void _ldi_i(jit_state_t*,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,i0)		_ldxi_i(_jit,r0,r1,i0)
static void _ldxi_i(jit_state_t*,int32_t,int32_t,jit_word_t);
#  if __WORDSIZE == 64
#    define ldr_ui(r0,r1)		LLGF(r0,0,0,r1)
#    define ldi_ui(r0,i0)		_ldi_ui(_jit,r0,i0)
static void _ldi_ui(jit_state_t*,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,i0)		_ldxi_ui(_jit,r0,r1,i0)
static void _ldxi_ui(jit_state_t*,int32_t,int32_t,jit_word_t);
#    define ldr_l(r0,r1)		LG(r0,0,0,r1)
#    define ldi_l(r0,i0)		_ldi_l(_jit,r0,i0)
static void _ldi_l(jit_state_t*,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,i0)		_ldxi_l(_jit,r0,r1,i0)
static void _ldxi_l(jit_state_t*,int32_t,int32_t,jit_word_t);
#  endif
#  define str_c(r0,r1)			STC(r1,0,0,r0)
#  define sti_c(i0,r0)			_sti_c(_jit,i0,r0)
static void _sti_c(jit_state_t*,jit_word_t,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 str_s(r0,r1)			STH(r1,0,0,r0)
#  define sti_s(i0,r0)			_sti_s(_jit,i0,r0)
static void _sti_s(jit_state_t*,jit_word_t,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 str_i(r0,r1)			ST(r1,0,0,r0)
#  define sti_i(i0,r0)			_sti_i(_jit,i0,r0)
static void _sti_i(jit_state_t*,jit_word_t,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);
#  if __WORDSIZE == 64
#    define str_l(r0,r1)		STG(r1,0,0,r0)
#    define sti_l(i0,r0)		_sti_l(_jit,i0,r0)
static void _sti_l(jit_state_t*,jit_word_t,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);
#  endif
#  define ltr(r0,r1,r2)			crr(CC_L,r0,r1,r2)
#  define lti(r0,r1,i0)			cri(CC_L,r0,r1,i0)
#  define ltr_u(r0,r1,r2)		crr_u(CC_L,r0,r1,r2)
#  define lti_u(r0,r1,i0)		cri_u(CC_L,r0,r1,i0)
#  define ler(r0,r1,r2)			crr(CC_LE,r0,r1,r2)
#  define lei(r0,r1,i0)			cri(CC_LE,r0,r1,i0)
#  define ler_u(r0,r1,r2)		crr_u(CC_LE,r0,r1,r2)
#  define lei_u(r0,r1,i0)		cri_u(CC_LE,r0,r1,i0)
#  define eqr(r0,r1,r2)			crr(CC_E,r0,r1,r2)
#  define eqi(r0,r1,i0)			cri(CC_E,r0,r1,i0)
#  define ger(r0,r1,r2)			crr(CC_HE,r0,r1,r2)
#  define gei(r0,r1,i0)			cri(CC_HE,r0,r1,i0)
#  define ger_u(r0,r1,r2)		crr_u(CC_HE,r0,r1,r2)
#  define gei_u(r0,r1,i0)		cri_u(CC_HE,r0,r1,i0)
#  define gtr(r0,r1,r2)			crr(CC_H,r0,r1,r2)
#  define gti(r0,r1,i0)			cri(CC_H,r0,r1,i0)
#  define gtr_u(r0,r1,r2)		crr_u(CC_H,r0,r1,r2)
#  define gti_u(r0,r1,i0)		cri_u(CC_H,r0,r1,i0)
#  define ner(r0,r1,r2)			crr(CC_NE,r0,r1,r2)
#  define nei(r0,r1,i0)			cri(CC_NE,r0,r1,i0)
#  define bltr(i0,r0,r1)		brr(CC_L,i0,r0,r1)
#  define bltr_p(i0,r0,r1)		brr_p(CC_L,i0,r0,r1)
#  define blti(i0,r0,i1)		bri(CC_L,i0,r0,i1)
#  define blti_p(i0,r0,i1)		bri_p(CC_L,i0,r0,i1)
#  define bltr_u(i0,r0,r1)		brr_u(CC_L,i0,r0,r1)
#  define bltr_u_p(i0,r0,r1)		brr_u_p(CC_L,i0,r0,r1)
#  define blti_u(i0,r0,i1)		bri_u(CC_L,i0,r0,i1)
#  define blti_u_p(i0,r0,i1)		bri_u_p(CC_L,i0,r0,i1)
#  define bler(i0,r0,r1)		brr(CC_LE,i0,r0,r1)
#  define bler_p(i0,r0,r1)		brr_p(CC_LE,i0,r0,r1)
#  define blei(i0,r0,i1)		bri(CC_LE,i0,r0,i1)
#  define blei_p(i0,r0,i1)		bri_p(CC_LE,i0,r0,i1)
#  define bler_u(i0,r0,r1)		brr_u(CC_LE,i0,r0,r1)
#  define bler_u_p(i0,r0,r1)		brr_u_p(CC_LE,i0,r0,r1)
#  define blei_u(i0,r0,i1)		bri_u(CC_LE,i0,r0,i1)
#  define blei_u_p(i0,r0,i1)		bri_u_p(CC_LE,i0,r0,i1)
#  define beqr(i0,r0,r1)		brr(CC_E,i0,r0,r1)
#  define beqr_p(i0,r0,r1)		brr_p(CC_E,i0,r0,r1)
#  define beqi(i0,r0,i1)		bri(CC_E,i0,r0,i1)
#  define beqi_p(i0,r0,i1)		bri_p(CC_E,i0,r0,i1)
#  define bger(i0,r0,r1)		brr(CC_HE,i0,r0,r1)
#  define bger_p(i0,r0,r1)		brr_p(CC_HE,i0,r0,r1)
#  define bgei(i0,r0,i1)		bri(CC_HE,i0,r0,i1)
#  define bgei_p(i0,r0,i1)		bri_p(CC_HE,i0,r0,i1)
#  define bger_u(i0,r0,r1)		brr_u(CC_HE,i0,r0,r1)
#  define bger_u_p(i0,r0,r1)		brr_u_p(CC_HE,i0,r0,r1)
#  define bgei_u(i0,r0,i1)		bri_u(CC_HE,i0,r0,i1)
#  define bgei_u_p(i0,r0,i1)		bri_u_p(CC_HE,i0,r0,i1)
#  define bgtr(i0,r0,r1)		brr(CC_H,i0,r0,r1)
#  define bgtr_p(i0,r0,r1)		brr_p(CC_H,i0,r0,r1)
#  define bgti(i0,r0,i1)		bri(CC_H,i0,r0,i1)
#  define bgti_p(i0,r0,i1)		bri_p(CC_H,i0,r0,i1)
#  define bgtr_u(i0,r0,r1)		brr_u(CC_H,i0,r0,r1)
#  define bgtr_u_p(i0,r0,r1)		brr_u_p(CC_H,i0,r0,r1)
#  define bgti_u(i0,r0,i1)		bri_u(CC_H,i0,r0,i1)
#  define bgti_u_p(i0,r0,i1)		bri_u_p(CC_H,i0,r0,i1)
#  define bner(i0,r0,r1)		brr(CC_NE,i0,r0,r1)
#  define bner_p(i0,r0,r1)		brr_p(CC_NE,i0,r0,r1)
#  define bnei(i0,r0,i1)		bri(CC_NE,i0,r0,i1)
#  define bnei_p(i0,r0,i1)		bri_p(CC_NE,i0,r0,i1)
#  define boaddr(i0,r0,r1)		baddr(CC_O,1,i0,r0,r1)
#  define boaddr_p(i0,r0,r1)		baddr_p(CC_O,1,i0,r0,r1)
#  define boaddi(i0,r0,i1)		baddi(CC_O,1,i0,r0,i1)
#  define boaddi_p(i0,r0,i1)		baddi_p(CC_O,1,i0,r0,i1)
#  define boaddr_u(i0,r0,r1)		baddr(CC_NLE,0,i0,r0,r1)
#  define boaddr_u_p(i0,r0,r1)		baddr_p(CC_NLE,0,i0,r0,r1)
#  define boaddi_u(i0,r0,i1)		baddi(CC_NLE,0,i0,r0,i1)
#  define boaddi_u_p(i0,r0,i1)		baddi_p(CC_NLE,0,i0,r0,i1)
#  define bxaddr(i0,r0,r1)		baddr(CC_NO,1,i0,r0,r1)
#  define bxaddr_p(i0,r0,r1)		baddr_p(CC_NO,1,i0,r0,r1)
#  define bxaddi(i0,r0,i1)		baddi(CC_NO,1,i0,r0,i1)
#  define bxaddi_p(i0,r0,i1)		baddi_p(CC_NO,1,i0,r0,i1)
#  define bxaddr_u(i0,r0,r1)		baddr(CC_LE,0,i0,r0,r1)
#  define bxaddr_u_p(i0,r0,r1)		baddr_p(CC_LE,0,i0,r0,r1)
#  define bxaddi_u(i0,r0,i1)		baddi(CC_LE,0,i0,r0,i1)
#  define bxaddi_u_p(i0,r0,i1)		baddi_p(CC_LE,0,i0,r0,i1)
#  define bosubr(i0,r0,r1)		bsubr(CC_O,1,i0,r0,r1)
#  define bosubr_p(i0,r0,r1)		bsubr_p(CC_O,1,i0,r0,r1)
#  define bosubi(i0,r0,i1)		bsubi(CC_O,1,i0,r0,i1)
#  define bosubi_p(i0,r0,i1)		bsubi_p(CC_O,1,i0,r0,i1)
#  define bosubr_u(i0,r0,r1)		bsubr(CC_L,0,i0,r0,r1)
#  define bosubr_u_p(i0,r0,r1)		bsubr_p(CC_L,0,i0,r0,r1)
#  define bosubi_u(i0,r0,i1)		bsubi(CC_L,0,i0,r0,i1)
#  define bosubi_u_p(i0,r0,i1)		bsubi_p(CC_L,0,i0,r0,i1)
#  define bxsubr(i0,r0,r1)		bsubr(CC_NO,1,i0,r0,r1)
#  define bxsubr_p(i0,r0,r1)		bsubr_p(CC_NO,1,i0,r0,r1)
#  define bxsubi(i0,r0,i1)		bsubi(CC_NO,1,i0,r0,i1)
#  define bxsubi_p(i0,r0,i1)		bsubi_p(CC_NO,1,i0,r0,i1)
#  define bxsubr_u(i0,r0,r1)		bsubr(CC_NL,0,i0,r0,r1)
#  define bxsubr_u_p(i0,r0,r1)		bsubr_p(CC_NL,0,i0,r0,r1)
#  define bxsubi_u(i0,r0,i1)		bsubi(CC_NL,0,i0,r0,i1)
#  define bxsubi_u_p(i0,r0,i1)		bsubi_p(CC_NL,0,i0,r0,i1)
#  define bmsr(i0,r0,r1)		bmxr(CC_NE,i0,r0,r1)
#  define bmsr_p(i0,r0,r1)		bmxr_p(CC_NE,i0,r0,r1)
#  define bmsi(i0,r0,i1)		bmxi(CC_NE,i0,r0,i1)
#  define bmsi_p(i0,r0,i1)		bmxi_p(CC_NE,i0,r0,i1)
#  define bmcr(i0,r0,r1)		bmxr(CC_E,i0,r0,r1)
#  define bmcr_p(i0,r0,r1)		bmxr_p(CC_E,i0,r0,r1)
#  define bmci(i0,r0,i1)		bmxi(CC_E,i0,r0,i1)
#  define bmci_p(i0,r0,i1)		bmxi_p(CC_E,i0,r0,i1)
#  define jmpr(r0)			BR(r0)
#  define jmpi(i0)			_jmpi(_jit,i0)
static void _jmpi(jit_state_t*,jit_word_t);
#  define jmpi_p(i0)			_jmpi_p(_jit,i0)
static jit_word_t _jmpi_p(jit_state_t*,jit_word_t);
#  define callr(r0)			BALR(_R14_REGNO,r0)
#  define calli(i0)			_calli(_jit,i0)
static void _calli(jit_state_t*,jit_word_t);
#  define calli_p(i0)			_calli_p(_jit,i0)
static jit_word_t _calli_p(jit_state_t*,jit_word_t);
#  define prolog(i0)			_prolog(_jit,i0)
static void _prolog(jit_state_t*,jit_node_t*);
#  define epilog(i0)			_epilog(_jit,i0)
static void _epilog(jit_state_t*,jit_node_t*);
#  define vastart(r0)			_vastart(_jit, r0)
static void _vastart(jit_state_t*, int32_t);
#  define vaarg(r0, r1)			_vaarg(_jit, r0, r1)
static void _vaarg(jit_state_t*, int32_t, int32_t);
#  define patch_at(instr,label)		_patch_at(_jit,instr,label)
static void _patch_at(jit_state_t*,jit_word_t,jit_word_t);
#endif

#if CODE
#  define _us				uint16_t
#  define _ui				uint32_t
static void
_E(jit_state_t *_jit, _ui Op)
{
    union {
	struct {
	    _us	op;
	} b;
	_us	s;
    } i0;
    i0.b.op = Op;
    assert(i0.b.op == Op);
    is(i0.s);
}

static void
_I(jit_state_t *_jit, _ui Op, _ui I)
{
    union {
	struct {
	    _us	op : 8;
	    _us	i  : 8;
	} b;
	_us	s;
    } i0;
    i0.b.op = Op;
    i0.b.i  = I;
    assert(i0.b.op == Op);
    assert(i0.b.i  == I);
    is(i0.s);
}

static void
_RR(jit_state_t *_jit, _ui Op, _ui R1, _ui R2)
{
    union {
	struct {
	    _us	op : 8;
	    _us	r1 : 4;
	    _us	r2 : 4;
	} b;
	_us	s;
    } i0;
    i0.b.op = Op;
    i0.b.r1 = R1;
    i0.b.r2 = R2;
    assert(i0.b.op == Op);
    assert(i0.b.r1 == R1);
    assert(i0.b.r2 == R2);
    is(i0.s);
}

static void
_RRE(jit_state_t *_jit, _ui Op, _ui R1, _ui R2)
{
    union {
	struct {
	    _us	op;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	_  : 8;
	    _us	r1 : 4;
	    _us	r2 : 4;
	} b;
	_us	s;
    } i1;
    i0.b.op = Op;
    i1.b._ = 0;
    i1.b.r1 = R1;
    i1.b.r2 = R2;
    assert(i0.b.op == Op);
    assert(i1.b.r1 == R1);
    assert(i1.b.r2 == R2);
    is(i0.s);
    is(i1.s);
}

static void
_RRF(jit_state_t *_jit, _ui Op, _ui R3, _ui M4, _ui R1, _ui R2)
{
    union {
	struct {
	    _us	op;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	r3 : 4;
	    _us	m4 : 4;
	    _us	r1 : 4;
	    _us	r2 : 4;
	} b;
	_us	s;
    } i1;
    i0.b.op = Op;
    i1.b.r3 = R3;
    i1.b.m4 = M4;
    i1.b.r1 = R1;
    i1.b.r2 = R2;
    assert(i0.b.op == Op);
    assert(i1.b.r3 == R3);
    assert(i1.b.m4 == M4);
    assert(i1.b.r1 == R1);
    assert(i1.b.r2 == R2);
    is(i0.s);
    is(i1.s);
}

static void
_RX(jit_state_t *_jit, _ui Op, _ui R1, _ui X2, _ui B2, _ui D2)
{
    union {
	struct {
	    _us	op :  8;
	    _us	r1 :  4;
	    _us	x2 :  4;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	b2 :  4;
	    _us	d2 : 12;
	} b;
	_us	s;
    } i1;
    i0.b.op = Op;
    i0.b.r1 = R1;
    i0.b.x2 = X2;
    i1.b.b2 = B2;
    i1.b.d2 = D2;
    assert(i0.b.op == Op);
    assert(i0.b.r1 == R1);
    assert(i0.b.x2 == X2);
    assert(i1.b.b2 == B2);
    assert(i1.b.d2 == D2);
    is(i0.s);
    is(i1.s);
}

static void
_RXE(jit_state_t *_jit, _ui Op, _ui R1, _ui X2, _ui B2, _ui D2, _ui Op2)
{
    union {
	struct {
	    _us	op :  8;
	    _us	r1 :  4;
	    _us	x2 :  4;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	b2 :  4;
	    _us	d2 : 12;
	} b;
	_ui	s;
    } i1;
    union {
	struct {
	    _us	_  :  8;
	    _us	op :  8;
	} b;
	_us	s;
    } i2;
    i2.b._ = 0;
    i0.b.op = Op;
    i0.b.r1 = R1;
    i0.b.x2 = X2;
    i1.b.b2 = B2;
    i1.b.d2 = D2;
    i2.b.op = Op2;
    assert(i0.b.op == Op);
    assert(i0.b.r1 == R1);
    assert(i0.b.x2 == X2);
    assert(i1.b.b2 == B2);
    assert(i1.b.d2 == D2);
    assert(i2.b.op == Op2);
    is(i0.s);
    is(i1.s);
    is(i2.s);
}

static void
_RXF(jit_state_t *_jit, _ui Op, _ui R3, _ui X2, _ui B2, _ui D2, _ui R1, _ui Op2)
{
    union {
	struct {
	    _us	op :  8;
	    _us	r3 :  4;
	    _us	x2 :  4;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	b2 :  4;
	    _us	d2 : 12;
	} b;
	_us	s;
    } i1;
    union {
	struct {
	    _us	r1 :  4;
	    _us	_  :  4;
	    _us	op :  8;
	} b;
	_us	s;
    } i2;
    i2.b._ = 0;
    i0.b.op = Op;
    i0.b.r3 = R3;
    i0.b.x2 = X2;
    i1.b.b2 = B2;
    i1.b.d2 = D2;
    i2.b.r1 = R1;
    i2.b.op = Op2;
    assert(i0.b.op == Op);
    assert(i0.b.r3 == R3);
    assert(i0.b.x2 == X2);
    assert(i1.b.b2 == B2);
    assert(i1.b.d2 == D2);
    assert(i2.b.r1 == R1);
    assert(i2.b.op == Op2);
    is(i0.s);
    is(i1.s);
    is(i2.s);
}

static void
_RXY(jit_state_t *_jit, _ui Op, _ui R1, _ui X2, _ui B2, _ui D2, _ui Op2)
{
    union {
	struct {
	    _us	op :  8;
	    _us	r1 :  4;
	    _us	x2 :  4;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	b2 :  4;
	    _us	dl : 12;
	} b;
	_us	s;
    } i1;
    union {
	struct {
	    _us	dh :  8;
	    _us	op :  8;
	} b;
	_us	s;
    } i2;
    i0.s = i1.s = i2.s = 0;
    i0.b.op = Op;
    i0.b.r1 = R1;
    i0.b.x2 = X2;
    i1.b.b2 = B2;
    i1.b.dl = D2 & 0xfff;
    i2.b.dh = D2 >> 12;
    i2.b.op = Op2;
    assert(i0.b.op == Op);
    assert(i0.b.r1 == R1);
    assert(i0.b.x2 == X2);
    assert(i1.b.b2 == B2);
    assert(i2.b.dh == D2 >> 12);
    assert(i2.b.op == Op2);
    is(i0.s);
    is(i1.s);
    is(i2.s);
}

static void
_RS(jit_state_t *_jit, _ui Op, _ui R1, _ui R3, _ui B2, _ui D2)
{
    union {
	struct {
	    _us	op :  8;
	    _us	r1 :  4;
	    _us	r3 :  4;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	b2 :  4;
	    _us	d2 : 12;
	} b;
	_us	s;
    } i1;
    i0.s = i1.s = 0;
    i0.b.op = Op;
    i0.b.r1 = R1;
    i0.b.r3 = R3;
    i1.b.b2 = B2;
    i1.b.d2 = D2;
    assert(i0.b.op == Op);
    assert(i0.b.r1 == R1);
    assert(i0.b.r3 == R3);
    assert(i1.b.b2 == B2);
    assert(i1.b.d2 == D2);
    is(i0.s);
    is(i1.s);
}

static void
_RSL(jit_state_t *_jit, _ui Op, _ui L1, _ui B1, _ui D1, _ui Op2)
{
    union {
	struct {
	    _us	op :  8;
	    _us	l1 :  4;
	    _us _  :  4;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	b1 :  4;
	    _us	d1 : 12;
	} b;
	_us	s;
    } i1;
    union {
	struct {
	    _us	_  :  8;
	    _us	op :  8;
	} b;
	_us	s;
    } i2;
    i0.b._ = 0;
    i2.b._ = 0;
    i0.b.op = Op;
    i0.b.l1 = L1;
    i1.b.b1 = B1;
    i1.b.d1 = D1;
    i2.b.op = Op2;
    assert(i0.b.op == Op);
    assert(i0.b.l1 == L1);
    assert(i1.b.b1 == B1);
    assert(i1.b.d1 == D1);
    assert(i2.b.op == Op2);
    is(i0.s);
    is(i1.s);
    is(i2.s);
}

static void
_RSI(jit_state_t *_jit, _ui Op, _ui R1, _ui R3, _ui I2)
{
    union {
	struct {
	    _us	op :  8;
	    _us	r1 :  4;
	    _us	r3 :  4;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	i2;
	} b;
	_us	s;
    } i1;
    i0.b.op = Op;
    i0.b.r1 = R1;
    i0.b.r3 = R3;
    i1.b.i2 = I2;
    assert(i0.b.op == Op);
    assert(i0.b.r1 == R1);
    assert(i0.b.r3 == R3);
    assert(i1.b.i2 == I2);
    is(i0.s);
    is(i1.s);
}

static void
_RIE(jit_state_t *_jit, _ui Op, _ui R1, _ui R3, _ui I2, _ui Op2)
{
    union {
	struct {
	    _us	op :  8;
	    _us	r1 :  4;
	    _us	r3 :  4;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	i2;
	} b;
	_us	s;
    } i1;
    union {
	struct {
	    _us	_  :  8;
	    _us	op :  8;
	} b;
	_us	s;
    } i2;
    i2.b._ = 0;
    i0.b.op = Op;
    i0.b.r1 = R1;
    i0.b.r3 = R3;
    i1.b.i2 = I2;
    i2.b.op = Op2;
    assert(i0.b.op == Op);
    assert(i0.b.r1 == R1);
    assert(i0.b.r3 == R3);
    assert(i1.b.i2 == I2);
    assert(i2.b.op == Op2);
    is(i0.s);
    is(i1.s);
    is(i2.s);
}

static void
_RIL(jit_state_t *_jit, _ui Op, _ui R1, _ui Op2, _ui I2)
{
    union {
	struct {
	    _us	o1 :  8;
	    _us	r1 :  4;
	    _us	o2 :  4;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _ui	ih : 16;
	    _ui	il : 16;
	} b;
	_ui	i;
    } i12;
    i0.b.o1 = Op;
    i0.b.r1 = R1;
    i0.b.o2 = Op2;
    i12.i   = I2;
    assert(i0.b.o1 == Op);
    assert(i0.b.r1 == R1);
    assert(i0.b.o2 == Op2);
    is(i0.s);
    is(i12.b.ih);
    is(i12.b.il);
}

static void
_SI(jit_state_t *_jit, _ui Op, _ui I2, _ui B1, _ui D1)
{
    union {
	struct {
	    _us	op :  8;
	    _us	i2 :  8;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	b1 :  4;
	    _us	d1 : 12;
	} b;
	_us	s;
    } i1;
    i0.b.op = Op;
    i0.b.i2 = I2;
    i1.b.b1 = B1;
    i1.b.d1 = D1;
    assert(i0.b.op == Op);
    assert(i0.b.i2 == I2);
    assert(i1.b.b1 == B1);
    assert(i1.b.d1 == D1);
    is(i0.s);
    is(i1.s);
}

static void
_SIY(jit_state_t *_jit, _ui Op, _ui I2, _ui B1, _ui D1, _ui Op2)
{
    union {
	struct {
	    _us	op :  8;
	    _us	i2 :  8;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	b1 :  4;
	    _us	dl : 12;
	} b;
	_us	s;
    } i1;
    union {
	struct {
	    _us	dh :  8;
	    _us	op :  8;
	} b;
	_us	s;
    } i2;
    i0.b.op = Op;
    i0.b.i2 = I2;
    i1.b.b1 = B1;
    i1.b.dl = D1 & 0xfff;
    i2.b.dh = D1 >> 8;
    i2.b.op = Op2;
    assert(i0.b.op == Op);
    assert(i0.b.i2 == I2);
    assert(i1.b.b1 == B1);
    assert(i2.b.dh == D1 >> 8);
    assert(i2.b.op == Op2);
    is(i0.s);
    is(i1.s);
    is(i2.s);
}

static void
_S(jit_state_t *_jit, _ui Op, _ui B2, _ui D2)
{
    union {
	struct {
	    _us	op;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	b2 :  4;
	    _us	d2 : 12;
	} b;
	_us	s;
    } i1;
    i0.b.op = Op;
    i1.b.b2 = B2;
    i1.b.d2 = D2;
    assert(i0.b.op == Op);
    assert(i1.b.b2 == B2);
    assert(i1.b.d2 == D2);
    is(i0.s);
    is(i1.s);
}

static void
_SS(jit_state_t *_jit, _ui Op, _ui LL, _ui LH, _ui B1, _ui D1, _ui B2, _ui D2)
{
    union {
	struct {
	    _us	op :  8;
	    _us	ll :  4;
	    _us	lh :  4;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	b1 :  4;
	    _us	d1 : 12;
	} b;
	_us	s;
    } i1;
    union {
	struct {
	    _us	b2 :  4;
	    _us	d2 : 12;
	} b;
	_us	s;
    } i2;
    i0.b.op = Op;
    i0.b.ll = LL;
    i0.b.lh = LH;
    i1.b.b1 = B1;
    i1.b.d1 = D1;
    i2.b.b2 = B2;
    i2.b.d2 = D2;
    assert(i0.b.op == Op);
    assert(i0.b.ll == LL);
    assert(i0.b.lh == LH);
    assert(i1.b.b1 == B1);
    assert(i1.b.d1 == D1);
    assert(i2.b.b2 == B2);
    assert(i2.b.d2 == D2);
    is(i0.s);
    is(i1.s);
    is(i2.s);
}

static void
_SSE(jit_state_t *_jit, _ui Op, _ui B1, _ui D1, _ui B2, _ui D2)
{
    union {
	struct {
	    _us	op;
	} b;
	_us	s;
    } i0;
    union {
	struct {
	    _us	b1 :  4;
	    _us	d1 : 12;
	} b;
	_us	s;
    } i1;
    union {
	struct {
	    _us	b2 :  4;
	    _us	d2 : 12;
	} b;
	_us	s;
    } i2;
    i0.b.op = Op;
    i1.b.b1 = B1;
    i1.b.d1 = D1;
    i2.b.b2 = B2;
    i2.b.d2 = D2;
    assert(i0.b.op == Op);
    assert(i1.b.b1 == B1);
    assert(i1.b.d1 == D1);
    assert(i2.b.b2 == B2);
    assert(i2.b.d2 == D2);
    is(i0.s);
    is(i1.s);
    is(i2.s);
}
#  undef _us
#  undef _ui

static void
_nop(jit_state_t *_jit, int32_t c)
{
    assert(c >= 0 && !(c & 1));
    while (c) {
	NOPR(_R7_REGNO);
	c -= 2;
    }
}

static int32_t
_xdivr(jit_state_t *_jit, int32_t r0, int32_t r1)
{
    int32_t		regno;
    regno = jit_get_reg_pair();
#if __WORDSIZE == 32
    movr(rn(regno), r0);
    SRDA(rn(regno), 32, 0);
#else
    movr(rn(regno) + 1, r0);
#endif
    DIVREM_(rn(regno), r1);
    jit_unget_reg_pair(regno);
    return (regno);
}

static int32_t
_xdivr_u(jit_state_t *_jit, int32_t r0, int32_t r1)
{
    int32_t		regno;
    regno = jit_get_reg_pair();
#if __WORDSIZE == 32
    movr(rn(regno), r0);
    SRDL(rn(regno), 32, 0);
#else
    movr(rn(regno) + 1, r0);
#endif
    movi(rn(regno), 0);
    DIVREMU_(rn(regno), r1);
    jit_unget_reg_pair(regno);
    return (regno);
}

static int32_t
_xdivi(jit_state_t *_jit, int32_t r0, jit_word_t i0)
{
    int32_t		imm, regno;
    regno = jit_get_reg_pair();
    imm = jit_get_reg(jit_class_gpr);
#if __WORDSIZE == 32
    movr(rn(regno), r0);
    SRDA(rn(regno), 32, 0);
#else
    movr(rn(regno) + 1, r0);
#endif
    movi(rn(imm), i0);
    DIVREM_(rn(regno), rn(imm));
    jit_unget_reg(imm);
    jit_unget_reg_pair(regno);
    return (regno);
}

static int32_t
_xdivi_u(jit_state_t *_jit, int32_t r0, jit_word_t i0)
{
    /* cannot overlap because operand is 128-bit */
    int32_t		imm, regno;
    regno = jit_get_reg_pair();
    imm = jit_get_reg(jit_class_gpr);
#if __WORDSIZE == 32
    movr(rn(regno), r0);
    SRDL(rn(regno), 32, 0);
#else
    movr(rn(regno) + 1, r0);
#endif
    movi(rn(regno), 0);
    movi(rn(imm), i0);
    DIVREMU_(rn(regno), rn(imm));
    jit_unget_reg(imm);
    jit_unget_reg_pair(regno);
    return (regno);
}

static void
_crr(jit_state_t *_jit, int32_t cc,
     int32_t r0, int32_t r1, int32_t r2)
{
    jit_word_t		w;
    int32_t		reg, rg;
    if (r0 == r1 || r0 == r2) {
	reg = jit_get_reg(jit_class_gpr);
	rg = rn(reg);
    }
    else
	rg = r0;
    movi(rg, 1);
    CMP_(r1, r2);
    w = _jit->pc.w;
    BRC(cc, 0);
    movi(rg, 0);
    patch_at(w, _jit->pc.w);
    if (r0 == r1 || r0 == r2) {
	movr(r0, rg);
	jit_unget_reg(reg);
    }
}

static void
_cri(jit_state_t *_jit, int32_t cc,
     int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr);
    movi(rn(reg), i0);
    crr(cc, r0, r1, rn(reg));
    jit_unget_reg(reg);
}

static void
_crr_u(jit_state_t *_jit, int32_t cc,
       int32_t r0, int32_t r1, int32_t r2)
{
    jit_word_t		w;
    int32_t		reg, rg;
    if (r0 == r1 || r0 == r2) {
	reg = jit_get_reg(jit_class_gpr);
	rg = rn(reg);
    }
    else
	rg = r0;
    movi(rg, 1);
    CMPU_(r1, r2);
    w = _jit->pc.w;
    BRC(cc, 0);
    movi(rg, 0);
    patch_at(w, _jit->pc.w);
    if (r0 == r1 || r0 == r2) {
	movr(r0, rg);
	jit_unget_reg(reg);
    }
}

static void
_cri_u(jit_state_t *_jit, int32_t cc,
       int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr);
    movi(rn(reg), i0);
    crr_u(cc, r0, r1, rn(reg));
    jit_unget_reg(reg);
}

static void
_brr(jit_state_t *_jit, int32_t cc,
     jit_word_t i0, int32_t r0, int32_t r1)
{
    jit_word_t		d;
    CMP_(r0, r1);
    d = (i0 - _jit->pc.w) >> 1;
    if (s16_p(d))
	BRC(cc, x16(d));
    else {
	assert(s32_p(d));
	BRCL(cc, d);
    }
}

static jit_word_t
_brr_p(jit_state_t *_jit, int32_t cc,
       jit_word_t i0, int32_t r0, int32_t r1)
{
    jit_word_t		w;
    CMP_(r0, r1);
    w = _jit->pc.w;
    BRCL(cc, 0);
    return (w);
}

static void
_bri(jit_state_t *_jit, int32_t cc,
     jit_word_t i0, int32_t r0, jit_word_t i1)
{
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
    movi(rn(reg), i1);
    brr(cc, i0, r0, rn(reg));
    jit_unget_reg(reg);
}

static jit_word_t
_bri_p(jit_state_t *_jit, int32_t cc,
     jit_word_t i0, int32_t r0, jit_word_t i1)
{
    jit_word_t		w;
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
    movi(rn(reg), i1);
    w = brr_p(cc, i0, r0, rn(reg));
    jit_unget_reg(reg);
    return (w);
}

static void
_brr_u(jit_state_t *_jit, int32_t cc,
       jit_word_t i0, int32_t r0, int32_t r1)
{
    jit_word_t		d;
    CMPU_(r0, r1);
    d = (i0 - _jit->pc.w) >> 1;
    if (s16_p(d))
	BRC(cc, x16(d));
    else {
	assert(s32_p(d));
	BRCL(cc, d);
    }
}

static jit_word_t
_brr_u_p(jit_state_t *_jit, int32_t cc,
	 jit_word_t i0, int32_t r0, int32_t r1)
{
    jit_word_t		w;
    CMPU_(r0, r1);
    w = _jit->pc.w;
    BRCL(cc, 0);
    return (w);
}

static void
_bri_u(jit_state_t *_jit, int32_t cc,
       jit_word_t i0, int32_t r0, jit_word_t i1)
{
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
    movi(rn(reg), i1);
    brr_u(cc, i0, r0, rn(reg));
    jit_unget_reg(reg);
}

static jit_word_t
_bri_u_p(jit_state_t *_jit, int32_t cc,
	 jit_word_t i0, int32_t r0, jit_word_t i1)
{
    jit_word_t		w;
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
    movi(rn(reg), i1);
    w = brr_u_p(cc, i0, r0, rn(reg));
    jit_unget_reg(reg);
    return (w);
}

static void
_baddr(jit_state_t *_jit, int32_t c, jit_bool_t s,
       jit_word_t i0, int32_t r0, int32_t r1)
{
    jit_word_t		d;
    if (s)		addr(r0, r0, r1);
    else		addcr(r0, r0, r1);
    d = (i0 - _jit->pc.w) >> 1;
    if (s16_p(d))
	BRC(c, x16(d));
    else {
	assert(s32_p(d));
	BRCL(c, d);
    }
}

static void
_baddi(jit_state_t *_jit, int32_t c, jit_bool_t s,
       jit_word_t i0, int32_t r0, jit_word_t i1)
{
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
    movi(rn(reg), i1);
    baddr(c, s, i0, r0, rn(reg));
    jit_unget_reg(reg);
}

static jit_word_t
_baddr_p(jit_state_t *_jit, int32_t c, jit_bool_t s,
	 jit_word_t i0, int32_t r0, int32_t r1)
{
    jit_word_t		d, w;
    if (s)		addr(r0, r0, r1);
    else		addcr(r0, r0, r1);
    d = (i0 - _jit->pc.w) >> 1;
    w = _jit->pc.w;
    BRCL(c, d);
    return (w);
}

static jit_word_t
_baddi_p(jit_state_t *_jit, int32_t c, jit_bool_t s,
	 jit_word_t i0, int32_t r0, jit_word_t i1)
{
    jit_word_t		w;
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
    movi(rn(reg), i1);
    w = baddr_p(c, s, i0, r0, rn(reg));
    jit_unget_reg(reg);
    return (w);
}

static void
_bsubr(jit_state_t *_jit, int32_t c, jit_bool_t s,
       jit_word_t i0, int32_t r0, int32_t r1)
{
    jit_word_t		d;
    if (s)		subr(r0, r0, r1);
    else		subcr(r0, r0, r1);
    d = (i0 - _jit->pc.w) >> 1;
    if (s16_p(d))
	BRC(c, x16(d));
    else {
	assert(s32_p(d));
	BRCL(c, d);
    }
}

static void
_bsubi(jit_state_t *_jit, int32_t c, jit_bool_t s,
       jit_word_t i0, int32_t r0, jit_word_t i1)
{
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
    movi(rn(reg), i1);
    bsubr(c, s, i0, r0, rn(reg));
    jit_unget_reg(reg);
}

static jit_word_t
_bsubr_p(jit_state_t *_jit, int32_t c, jit_bool_t s,
	 jit_word_t i0, int32_t r0, int32_t r1)
{
    jit_word_t		d, w;
    if (s)		subr(r0, r0, r1);
    else		subcr(r0, r0, r1);
    d = (i0 - _jit->pc.w) >> 1;
    w = _jit->pc.w;
    BRCL(c, d);
    return (w);
}

static jit_word_t
_bsubi_p(jit_state_t *_jit, int32_t c, jit_bool_t s,
	 jit_word_t i0, int32_t r0, jit_word_t i1)
{
    jit_word_t		w;
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
    movi(rn(reg), i1);
    w = bsubr_p(c, s, i0, r0, rn(reg));
    jit_unget_reg(reg);
    return (w);
}

static void
_bmxr(jit_state_t *_jit, int32_t cc,
      jit_word_t i0, int32_t r0, int32_t r1)
{
    jit_word_t		d;
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr);
    movr(rn(reg), r0);
    andr(rn(reg), rn(reg), r1);
    TEST_(rn(reg), rn(reg));
    jit_unget_reg(reg);
    d = (i0 - _jit->pc.w) >> 1;
    if (s16_p(d))
	BRC(cc, x16(d));
    else {
	assert(s32_p(d));
	BRCL(cc, d);
    }
}

static jit_word_t
_bmxr_p(jit_state_t *_jit, int32_t cc,
	jit_word_t i0, int32_t r0, int32_t r1)
{
    jit_word_t		w;
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr);
    movr(rn(reg), r0);
    andr(rn(reg), rn(reg), r1);
    TEST_(rn(reg), rn(reg));
    jit_unget_reg(reg);
    w = _jit->pc.w;
    BRCL(cc, 0);
    return (w);
}

static void
_bmxi(jit_state_t *_jit, int32_t cc,
      jit_word_t i0, int32_t r0, jit_word_t i1)
{
    jit_word_t		d;
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr);
    movi(rn(reg), i1);
    andr(rn(reg), rn(reg), r0);
    TEST_(rn(reg), rn(reg));
    jit_unget_reg(reg);
    d = (i0 - _jit->pc.w) >> 1;
    if (s16_p(d))
	BRC(cc, x16(d));
    else {
	assert(s32_p(d));
	BRCL(cc, d);
    }
}

static jit_word_t
_bmxi_p(jit_state_t *_jit, int32_t cc,
	jit_word_t i0, int32_t r0, jit_word_t i1)
{
    jit_word_t		w;
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr);
    movi(rn(reg), i1);
    andr(rn(reg), rn(reg), r0);
    TEST_(rn(reg), rn(reg));
    jit_unget_reg(reg);
    w = _jit->pc.w;
    BRCL(cc, 0);
    return (w);
}

static void
_movr(jit_state_t *_jit, int32_t r0, int32_t r1)
{
#if __WORDSIZE == 32
    if (r0 != r1)
	LR(r0, r1);
#else
    if (r0 != r1)
	LGR(r0, r1);
#endif
}

static void
_movi(jit_state_t *_jit, int32_t r0, jit_word_t i0)
{
    jit_word_t		d;
#if __WORDSIZE == 64
    int32_t		bits;
#endif
    d = (i0 - _jit->pc.w) >> 1;
    if (s16_p(i0)) {
#if __WORDSIZE == 32
	LHI(r0, x16(i0));
#else
	LGHI(r0, x16(i0));
#endif
    }
    /* easy way of loading a large amount of 32 bit values and
     * usually address of constants */
    else if (!(i0 & 1) &&
#if __WORDSIZE == 32
	     i0 > 0
#else
	     s32_p(d)
#endif
	     )
	LARL(r0, d);
    else {
#if __WORDSIZE == 32
	LHI(r0, x16(i0));
	IILH(r0, x16((jit_uword_t)i0 >> 16));
#else
	bits = 0;
	if (i0 &             0xffffL)	bits |= 1;
	if (i0 &         0xffff0000L)	bits |= 2;
	if (i0 &     0xffff00000000L)	bits |= 4;
	if (i0 & 0xffff000000000000L)	bits |= 8;
	if (bits != 15)			LGHI(r0, 0);
	if (bits & 1)			IILL(r0, x16(i0));
	if (bits & 2)			IILH(r0, x16((jit_uword_t)i0 >> 16));
	if (bits & 4)			IIHL(r0, x16((jit_uword_t)i0 >> 32));
	if (bits & 8)			IIHH(r0, x16((jit_uword_t)i0 >> 48));
#endif
    }
}

static jit_word_t
_movi_p(jit_state_t *_jit, int32_t r0, jit_word_t i0)
{
    jit_word_t		w;
    w = _jit->pc.w;
#if __WORDSIZE == 32
    LHI(r0, x16(i0));
#else
    IILL(r0, x16(i0));
#endif
    IILH(r0, x16((jit_uword_t)i0 >> 16));
#if __WORDSIZE == 64
    IIHL(r0, x16((jit_uword_t)i0 >> 32));
    IIHH(r0, x16((jit_uword_t)i0 >> 48));
#endif
    return (w);
}

static void
_addr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2)
	ADD_(r0, r1);
    else {
	movr(r0, r1);
	ADD_(r0, r2);
    }
}

static void
_addi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    if (r0 == r1 && s16_p(i0))
	ADDI_(r0, x16(i0));
#if __WORDSIZE == 64
    else if (s20_p(i0))
	LAY(r0, x20(i0), 0, r1);
#endif
    else {
	reg = jit_get_reg(jit_class_gpr);
	movi(rn(reg), i0);
	addr(r0, r1, rn(reg));
	jit_unget_reg(reg);
    }
}

static void
_addcr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2)
	ADDC_(r0, r1);
    else {
	movr(r0, r1);
	ADDC_(r0, r2);
    }
}

static void
_addci(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr);
    movi(rn(reg), i0);
    addcr(r0, r1, rn(reg));
    jit_unget_reg(reg);
}

static void
_addxr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2)
	ADDX_(r0, r1);
    else {
	movr(r0, r1);
	ADDX_(r0, r2);
    }
}

static void
_addxi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr);
    movi(rn(reg), i0);
    addxr(r0, r1, rn(reg));
    jit_unget_reg(reg);
}

static void
_subr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		reg;
    if (r0 == r2) {
	reg = jit_get_reg(jit_class_gpr);
	movr(rn(reg), r2);
	movr(r0, r1);
	SUB_(r0, rn(reg));
	jit_unget_reg(reg);
    }
    else {
	movr(r0, r1);
	SUB_(r0, r2);
    }
}

static void
_subi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    if (r0 == r1 && s16_p(-i0))
	ADDI_(r0, x16(-i0));
#if __WORDSIZE == 64
    else if (s20_p(-i0))
	LAY(r0, x20(-i0), 0, r1);
#endif
    else {
	reg = jit_get_reg(jit_class_gpr);
	movi(rn(reg), i0);
	subr(r0, r1, rn(reg));
	jit_unget_reg(reg);
    }
}

static void
_subcr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		reg;
    if (r0 == r2) {
	reg = jit_get_reg(jit_class_gpr);
	movr(rn(reg), r2);
	movr(r0, r1);
	SUBC_(r0, rn(reg));
	jit_unget_reg(reg);
    }
    else {
	movr(r0, r1);
	SUBC_(r0, r2);
    }
}

static void
_subci(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr);
    movi(rn(reg), i0);
    subcr(r0, r1, rn(reg));
    jit_unget_reg(reg);
}

static void
_subxr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		reg;
    if (r0 == r2) {
	reg = jit_get_reg(jit_class_gpr);
	movr(rn(reg), r2);
	movr(r0, r1);
	SUBX_(r0, rn(reg));
	jit_unget_reg(reg);
    }
    else {
	movr(r0, r1);
	SUBX_(r0, r2);
    }
}

static void
_subxi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr);
    movi(rn(reg), i0);
    subxr(r0, r1, rn(reg));
    jit_unget_reg(reg);
}

static void
_rsbi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    subi(r0, r1, i0);
    negr(r0, r0);
}

static void
_mulr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2)
	MUL_(r0, r1);
    else {
	movr(r0, r1);
	MUL_(r0, r2);
    }
}

static void
_muli(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    if (s16_p(i0)) {
	movr(r0, r1);
	MULI_(r0, x16(i0));
    }
    else {
	reg = jit_get_reg(jit_class_gpr);
	movi(rn(reg), i0);
	mulr(r0, r1, rn(reg));
	jit_unget_reg(reg);
    }
}

static void
_qmulr(jit_state_t *_jit,
       int32_t r0, int32_t r1, int32_t r2, int32_t r3)
{
    int32_t		reg;
    /* The only invalid condition is r0 == r1 */
    int32_t		t2, t3, s2, s3;
    if (r2 == r0 || r2 == r1) {
	s2 = jit_get_reg(jit_class_gpr);
	t2 = rn(s2);
	movr(t2, r2);
    }
    else
	t2 = r2;
    if (r3 == r0 || r3 == r1) {
	s3 = jit_get_reg(jit_class_gpr);
	t3 = rn(s3);
	movr(t3, r3);
    }
    else
	t3 = r3;
    qmulr_u(r0, r1, r2, r3);
    reg = jit_get_reg(jit_class_gpr);
    /**/
    rshi(rn(reg), t2, 63);
    mulr(rn(reg), rn(reg), t3);
    addr(r1, r1, rn(reg));
    /**/
    rshi(rn(reg), t3, 63);
    mulr(rn(reg), rn(reg), t2);
    addr(r1, r1, rn(reg));
    jit_unget_reg(reg);
    if (t2 != r2)
	jit_unget_reg(s2);
    if (t3 != r3)
	jit_unget_reg(s3);
}

static void
_qmuli(jit_state_t *_jit,
       int32_t r0, int32_t r1, int32_t r2, jit_word_t i0)
{
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr);
    movi(rn(reg), i0);
    qmulr(r0, r1, r2, rn(reg));
    jit_unget_reg(reg);
}

static void
_qmulr_u(jit_state_t *_jit,
	 int32_t r0, int32_t r1, int32_t r2, int32_t r3)
{
    int32_t		regno;
    regno = jit_get_reg_pair();
    movr(rn(regno) + 1, r2);
    MULU_(rn(regno), r3);
    movr(r0, rn(regno) + 1);
    movr(r1, rn(regno));
    jit_unget_reg_pair(regno);
}

static void
_qmuli_u(jit_state_t *_jit,
	 int32_t r0, int32_t r1, int32_t r2, jit_word_t i0)
{
    int32_t		regno;
    regno = jit_get_reg_pair();
    movr(rn(regno) + 1, r2);
    movi(rn(regno), i0);
    MULU_(rn(regno), rn(regno));
    movr(r0, rn(regno) + 1);
    movr(r1, rn(regno));
    jit_unget_reg_pair(regno);
}

static void
_divr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		regno;
    regno = xdivr(r1, r2);
    movr(r0, rn(regno) + 1);
}

static void
_divi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		regno;
    regno = xdivi(r1, i0);
    movr(r0, rn(regno) + 1);
}

static void
_divr_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		regno;
    regno = xdivr_u(r1, r2);
    movr(r0, rn(regno) + 1);
}

static void
_divi_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		regno;
    regno = xdivi_u(r1, i0);
    movr(r0, rn(regno) + 1);
}

static void
_remr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		regno;
    regno = xdivr(r1, r2);
    movr(r0, rn(regno));
}

static void
_remi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		regno;
    regno = xdivi(r1, i0);
    movr(r0, rn(regno));
}

static void
_remr_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		regno;
    regno = xdivr_u(r1, r2);
    movr(r0, rn(regno));
}

static void
_remi_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		regno;
    regno = xdivi_u(r1, i0);
    movr(r0, rn(regno));
}

static void
_qdivr(jit_state_t *_jit,
       int32_t r0, int32_t r1, int32_t r2, int32_t r3)
{
    int32_t		regno;
    regno = xdivr(r2, r3);
    movr(r0, rn(regno) + 1);
    movr(r1, rn(regno));
}

static void
_qdivi(jit_state_t *_jit,
       int32_t r0, int32_t r1, int32_t r2, jit_word_t i0)
{
    int32_t		regno;
    regno = xdivi(r2, i0);
    movr(r0, rn(regno) + 1);
    movr(r1, rn(regno));
}

static void
_qdivr_u(jit_state_t *_jit,
	 int32_t r0, int32_t r1, int32_t r2, int32_t r3)
{
    int32_t		regno;
    regno = xdivr_u(r2, r3);
    movr(r0, rn(regno) + 1);
    movr(r1, rn(regno));
}

static void
_qdivi_u(jit_state_t *_jit,
	 int32_t r0, int32_t r1, int32_t r2, jit_word_t i0)
{
    int32_t		regno;
    regno = xdivi_u(r2, i0);
    movr(r0, rn(regno) + 1);
    movr(r1, rn(regno));
}

#  if __WORDSIZE == 32
static void
_lshr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		reg;
    if (r0 == r2) {
	reg = jit_get_reg_but_zero(0);
	movr(rn(reg), r2);
	movr(r0, r1);
	SLL(r0, 0, rn(reg));
	jit_unget_reg_but_zero(reg);
    }
    else {
	movr(r0, r1);
	SLL(r0, 0, r2);
    }
}
#endif

static void
_lshi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    reg = jit_get_reg_but_zero(0);
    movi(rn(reg), i0);
    lshr(r0, r1, rn(reg));
    jit_unget_reg_but_zero(reg);
}

#  if __WORDSIZE == 32
static void
_rshr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		reg;
    if (r0 == r2) {
	reg = jit_get_reg_but_zero(0);
	movr(rn(reg), r2);
	movr(r0, r1);
	SRA(r0, 0, rn(reg));
	jit_unget_reg_but_zero(reg);
    }
    else {
	movr(r0, r1);
	SRA(r0, 0, r2);
    }
}
#endif

static void
_rshi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    reg = jit_get_reg_but_zero(0);
    movi(rn(reg), i0);
    rshr(r0, r1, rn(reg));
    jit_unget_reg_but_zero(reg);
}

#  if __WORDSIZE == 32
static void
_rshr_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		reg;
    if (r0 == r2) {
	reg = jit_get_reg_but_zero(0);
	movr(rn(reg), r2);
	movr(r0, r1);
	SRL(r0, 0, rn(reg));
	jit_unget_reg_but_zero(reg);
    }
    else {
	movr(r0, r1);
	SRL(r0, 0, r2);
    }
}
#endif

static void
_rshi_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    reg = jit_get_reg_but_zero(0);
    movi(rn(reg), i0);
    rshr_u(r0, r1, rn(reg));
    jit_unget_reg_but_zero(reg);
}

static void
_comr(jit_state_t *_jit, int32_t r0, int32_t r1)
{
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr);
    movi(rn(reg), -1);
    movr(r0, r1);
    XOR_(r0, rn(reg));
    jit_unget_reg(reg);
}

static void
_andr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2)
	AND_(r0, r1);
    else {
	movr(r0, r1);
	AND_(r0, r2);
    }
}

static void
_andi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    movr(r0, r1);
    NILL(r0, x16(i0));
    NILH(r0, x16((jit_uword_t)i0 >> 16));
#if __WORDSIZE == 64
    NIHL(r0, x16((jit_uword_t)i0 >> 32));
    NIHH(r0, x16((jit_uword_t)i0 >> 48));
#endif
}

static void
_orr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2)
	OR_(r0, r1);
    else {
	movr(r0, r1);
	OR_(r0, r2);
    }
}

static void
_ori(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    movr(r0, r1);
    OILL(r0, x16(i0));
    OILH(r0, x16((jit_uword_t)i0 >> 16));
#if __WORDSIZE == 64
    OIHL(r0, x16((jit_uword_t)i0 >> 32));
    OIHH(r0, x16((jit_uword_t)i0 >> 48));
#endif
}

static void
_xorr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2)
	XOR_(r0, r1);
    else {
	movr(r0, r1);
	XOR_(r0, r2);
    }
}

static void
_xori(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    reg = jit_get_reg(jit_class_gpr);
    movi(rn(reg), i0);
    xorr(r0, r1, rn(reg));
    jit_unget_reg(reg);
}

static void
_ldi_c(jit_state_t *_jit, int32_t r0, jit_word_t i0)
{
    movi(r0, i0);
    ldr_c(r0, r0);
}

static void
_ldxr_c(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2) {
	addr(r0, r0, r1);
	ldr_c(r0, r0);
    }
    else {
	movr(r0, r1);
	addr(r0, r0, r2);
	ldr_c(r0, r0);
    }
}

static void
_ldxi_c(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    if (s20_p(i0)) {
#if __WORDSIZE == 32
	LB(r0, x20(i0), 0, r1);
#else
	LGB(r0, x20(i0), 0, r1);
#endif
    }
    else if (r0 != r1) {
	movi(r0, i0);
	addr(r0, r0, r1);
	ldr_c(r0, r0);
    }
    else {
	reg = jit_get_reg_but_zero(0);
	movi(rn(reg), i0);
	addr(rn(reg), rn(reg), r1);
	ldr_c(r0, rn(reg));
	jit_unget_reg_but_zero(reg);
    }
}

static void
_ldi_uc(jit_state_t *_jit, int32_t r0, jit_word_t i0)
{
    movi(r0, i0);
    ldr_uc(r0, r0);
}

static void
_ldxr_uc(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2) {
	addr(r0, r0, r1);
	ldr_uc(r0, r0);
    }
    else {
	movr(r0, r1);
	addr(r0, r0, r2);
	ldr_uc(r0, r0);
    }
}

static void
_ldxi_uc(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    if (s20_p(i0))
	LLGC(r0, x20(i0), 0, r1);
    else if (r0 != r1) {
	movi(r0, i0);
	addr(r0, r0, r1);
	ldr_uc(r0, r0);
    }
    else {
	reg = jit_get_reg_but_zero(0);
	movi(rn(reg), i0);
	addr(rn(reg), rn(reg), r1);
	ldr_uc(r0, rn(reg));
	jit_unget_reg_but_zero(reg);
    }
}

static void
_ldi_s(jit_state_t *_jit, int32_t r0, jit_word_t i0)
{
    movi(r0, i0);
    ldr_s(r0, r0);
}

static void
_ldxr_s(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2) {
	addr(r0, r0, r1);
	ldr_s(r0, r0);
    }
    else {
	movr(r0, r1);
	addr(r0, r0, r2);
	ldr_s(r0, r0);
    }
}

static void
_ldxi_s(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
#if __WORDSIZE == 32
    if (u12_p(i0))
	LH(r0, i0, 0, r1);
    else
#endif
    if (s20_p(i0)) {
#if __WORDSIZE == 32
	LHY(r0, x20(i0), 0, r1);
#else
	LGH(r0, x20(i0), 0, r1);
#endif
    }
    else if (r0 != r1) {
	movi(r0, i0);
	addr(r0, r0, r1);
	ldr_s(r0, r0);
    }
    else {
	reg = jit_get_reg_but_zero(0);
	movi(rn(reg), i0);
	addr(rn(reg), rn(reg), r1);
	ldr_s(r0, rn(reg));
	jit_unget_reg_but_zero(reg);
    }
}

static void
_ldi_us(jit_state_t *_jit, int32_t r0, jit_word_t i0)
{
    movi(r0, i0);
    ldr_us(r0, r0);
}

static void
_ldxr_us(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2) {
	addr(r0, r0, r1);
	ldr_us(r0, r0);
    }
    else {
	movr(r0, r1);
	addr(r0, r0, r2);
	ldr_us(r0, r0);
    }
}

static void
_ldxi_us(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    if (s20_p(i0))
	LLGH(r0, x20(i0), 0, r1);
    else if (r0 != r1) {
	movi(r0, i0);
	addr(r0, r0, r1);
	ldr_us(r0, r0);
    }
    else {
	reg = jit_get_reg_but_zero(0);
	movi(rn(reg), i0);
	addr(rn(reg), rn(reg), r1);
	ldr_us(r0, rn(reg));
	jit_unget_reg_but_zero(reg);
    }
}

static void
_ldi_i(jit_state_t *_jit, int32_t r0, jit_word_t i0)
{
    movi(r0, i0);
    ldr_i(r0, r0);
}

static void
_ldxr_i(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2) {
	addr(r0, r0, r1);
	ldr_i(r0, r0);
    }
    else {
	movr(r0, r1);
	addr(r0, r0, r2);
	ldr_i(r0, r0);
    }
}

static void
_ldxi_i(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    if (s20_p(i0))
	LGF(r0, x20(i0), 0, r1);
    else if (r0 != r1) {
	movi(r0, i0);
	addr(r0, r0, r1);
	ldr_i(r0, r0);
    }
    else {
	reg = jit_get_reg_but_zero(0);
	movi(rn(reg), i0);
	addr(rn(reg), rn(reg), r1);
	ldr_i(r0, rn(reg));
	jit_unget_reg_but_zero(reg);
    }
}

#if __WORDSIZE == 64
static void
_ldi_ui(jit_state_t *_jit, int32_t r0, jit_word_t i0)
{
    movi(r0, i0);
    ldr_ui(r0, r0);
}

static void
_ldxr_ui(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2) {
	addr(r0, r0, r1);
	ldr_ui(r0, r0);
    }
    else {
	movr(r0, r1);
	addr(r0, r0, r2);
	ldr_ui(r0, r0);
    }
}

static void
_ldxi_ui(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    if (s20_p(i0))
	LLGF(r0, x20(i0), 0, r1);
    else if (r0 != r1) {
	movi(r0, i0);
	addr(r0, r0, r1);
	ldr_ui(r0, r0);
    }
    else {
	reg = jit_get_reg_but_zero(0);
	movi(rn(reg), i0);
	addr(rn(reg), rn(reg), r1);
	ldr_ui(r0, rn(reg));
	jit_unget_reg_but_zero(reg);
    }
}

static void
_ldi_l(jit_state_t *_jit, int32_t r0, jit_word_t i0)
{
    movi(r0, i0);
    ldr_l(r0, r0);
}

static void
_ldxr_l(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    if (r0 == r2) {
	addr(r0, r0, r1);
	ldr_l(r0, r0);
    }
    else {
	movr(r0, r1);
	addr(r0, r0, r2);
	ldr_l(r0, r0);
    }
}

static void
_ldxi_l(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
{
    int32_t		reg;
    if (s20_p(i0))
	LG(r0, x20(i0), 0, r1);
    else if (r0 != r1) {
	movi(r0, i0);
	addr(r0, r0, r1);
	ldr_l(r0, r0);
    }
    else {
	reg = jit_get_reg_but_zero(0);
	movi(rn(reg), i0);
	addr(rn(reg), rn(reg), r1);
	ldr_l(r0, rn(reg));
	jit_unget_reg_but_zero(reg);
    }
}
#endif

static void
_sti_c(jit_state_t *_jit, jit_word_t i0, int32_t r0)
{
    int32_t		reg;
    reg = jit_get_reg_but_zero(0);
    movi(rn(reg), i0);
    str_c(rn(reg), r0);
    jit_unget_reg_but_zero(reg);
}

static void
_stxr_c(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		reg;
    reg = jit_get_reg_but_zero(0);
    movr(rn(reg), r0);
    addr(rn(reg), rn(reg), r1);
    str_c(rn(reg), r2);
    jit_unget_reg_but_zero(reg);
}

static void
_stxi_c(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
{
    int32_t		reg;
    if (u12_p(i0))
	STC(r1, i0, 0, r0);
    else if (s20_p(i0))
	STCY(r1, x20(i0), 0, r0);
    else {
	reg = jit_get_reg_but_zero(0);
	addi(rn(reg), r0, i0);
	str_c(rn(reg), r1);
	jit_unget_reg_but_zero(reg);
    }
}

static void
_sti_s(jit_state_t *_jit, jit_word_t i0, int32_t r0)
{
    int32_t		reg;
    reg = jit_get_reg_but_zero(0);
    movi(rn(reg), i0);
    str_s(rn(reg), r0);
    jit_unget_reg_but_zero(reg);
}

static void
_stxr_s(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		reg;
    reg = jit_get_reg_but_zero(0);
    movr(rn(reg), r0);
    addr(rn(reg), rn(reg), r1);
    str_s(rn(reg), r2);
    jit_unget_reg_but_zero(reg);
}

static void
_stxi_s(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
{
    int32_t		reg;
    if (u12_p(i0))
	STH(r1, i0, 0, r0);
    else if (s20_p(i0))
	STHY(r1, x20(i0), 0, r0);
    else {
	reg = jit_get_reg_but_zero(0);
	addi(rn(reg), r0, i0);
	str_s(rn(reg), r1);
	jit_unget_reg_but_zero(reg);
    }
}

static void
_sti_i(jit_state_t *_jit, jit_word_t i0, int32_t r0)
{
    int32_t		reg;
    reg = jit_get_reg_but_zero(0);
    movi(rn(reg), i0);
    str_i(rn(reg), r0);
    jit_unget_reg_but_zero(reg);
}

static void
_stxr_i(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		reg;
    reg = jit_get_reg_but_zero(0);
    movr(rn(reg), r0);
    addr(rn(reg), rn(reg), r1);
    str_i(rn(reg), r2);
    jit_unget_reg_but_zero(reg);
}

static void
_stxi_i(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
{
    int32_t		reg;
    if (u12_p(i0))
	ST(r1, i0, 0, r0);
    else if (s20_p(i0))
	STY(r1, x20(i0), 0, r0);
    else {
	reg = jit_get_reg_but_zero(0);
	addi(rn(reg), r0, i0);
	str_i(rn(reg), r1);
	jit_unget_reg_but_zero(reg);
    }
}

#if __WORDSIZE == 64
static void
_sti_l(jit_state_t *_jit, jit_word_t i0, int32_t r0)
{
    int32_t		reg;
    reg = jit_get_reg_but_zero(0);
    movi(rn(reg), i0);
    str_l(rn(reg), r0);
    jit_unget_reg_but_zero(reg);
}

static void
_stxr_l(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
{
    int32_t		reg;
    reg = jit_get_reg_but_zero(0);
    movr(rn(reg), r0);
    addr(rn(reg), rn(reg), r1);
    str_l(rn(reg), r2);
    jit_unget_reg_but_zero(reg);
}

static void
_stxi_l(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
{
    int32_t		reg;
    if (s20_p(i0))
	STG(r1, x20(i0), 0, r0);
    else {
	reg = jit_get_reg_but_zero(0);
	addi(rn(reg), r0, i0);
	str_l(rn(reg), r1);
	jit_unget_reg_but_zero(reg);
    }
}
#endif

static void
_jmpi(jit_state_t *_jit, jit_word_t i0)
{
    jit_word_t		d;
    int32_t		reg;
    d = (i0 - _jit->pc.w) >> 1;
    if (s16_p(d))
	J(x16(d));
    else if (s32_p(d))
	BRL(d);
    else {
	reg = jit_get_reg_but_zero(jit_class_nospill);
	movi(rn(reg), i0);
	jmpr(rn(reg));
	jit_unget_reg_but_zero(reg);
    }
}

static jit_word_t
_jmpi_p(jit_state_t *_jit, jit_word_t i0)
{
    jit_word_t		w;
    int32_t		reg;
    reg = jit_get_reg_but_zero(jit_class_nospill);
    w = movi_p(rn(reg), i0);
    jmpr(rn(reg));
    jit_unget_reg_but_zero(reg);
    return (w);
}

static void
_calli(jit_state_t *_jit, jit_word_t i0)
{
    jit_word_t		d;
    int32_t		reg;
    d = (i0 - _jit->pc.w) >> 1;
    if (s32_p(d))
	BRASL(_R14_REGNO, d);
    else {
	reg = jit_get_reg_but_zero(0);
	movi(rn(reg), i0);
	callr(rn(reg));
	jit_unget_reg_but_zero(reg);
    }
}

static jit_word_t
_calli_p(jit_state_t *_jit, jit_word_t i0)
{
    jit_word_t		w;
    int32_t		reg;
    reg = jit_get_reg_but_zero(0);
    w = movi_p(rn(reg), i0);
    callr(rn(reg));
    jit_unget_reg_but_zero(reg);
    return (w);
}

static int32_t	gprs[] = {
    _R2, _R3, _R4, _R5,
    _R6, _R7, _R8, _R9, _R10, _R11, _R12, _R13
};

static void
_prolog(jit_state_t *_jit, jit_node_t *i0)
{
    int32_t		regno, offset;
    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 &= -8;
    _jitc->function->stack = ((_jitc->function->self.alen -
			      /* align stack at 8 bytes */
			      _jitc->function->self.aoff) + 7) & -8;
    /* *IFF* a non variadic function,
     * Lightning does not reserve stack space for spilling arguments
     * in registers.
     * S390x, as per gcc, has 8 stack slots for spilling arguments,
     * (%r6 is callee save) and uses an alloca like approach to save
     * callee save fpr registers.
     * Since argument registers are not saved in any lightning port,
     * use the 8 slots to spill any modified fpr register, and still
     * use the same stack frame logic as gcc.
     * Save at least %r13 to %r15, as %r13 is used as frame pointer.
     * *IFF* a variadic function, a "standard" stack frame, with
     * fpr registers saved in an alloca'ed area, is used.
     */
    if ((_jitc->function->self.call & jit_call_varargs) &&
	jit_arg_reg_p(_jitc->function->vagp))
	regno = _jitc->function->vagp;
    else {
	for (regno = 4; regno < jit_size(gprs) - 1; regno++) {
	    if (jit_regset_tstbit(&_jitc->function->regset, gprs[regno]))
		break;
	}
    }
#if __WORDSIZE == 32
#  define FP_OFFSET		64
    if (_jitc->function->self.call & jit_call_varargs)
	offset = regno * 4 + 8;
    else
	offset = (regno - 4) * 4 + 32;
    STM(rn(gprs[regno]), _R15_REGNO, x20(offset), _R15_REGNO);
#else
#  define FP_OFFSET		128
    if (_jitc->function->self.call & jit_call_varargs)
	offset = regno * 8 + 16;
    else
	offset = (regno - 4) * 8 + 48;
    STMG(rn(gprs[regno]), _R15_REGNO, x20(offset), _R15_REGNO);
#endif

#define SPILL(R, O)							\
    do {								\
	if (jit_regset_tstbit(&_jitc->function->regset, R))		\
	    stxi_d(O, _R15_REGNO, rn(R));				\
    } while (0)
    if (_jitc->function->self.call & jit_call_varargs) {
	for (regno = _jitc->function->vafp; jit_arg_f_reg_p(regno); ++regno)
	    stxi_d(FP_OFFSET + regno * 8, _R15_REGNO, rn(_F0 - regno));
	SPILL(_F8, _jitc->function->vaoff + offsetof(jit_va_list_t, f8));
	SPILL(_F9, _jitc->function->vaoff + offsetof(jit_va_list_t, f9));
	SPILL(_F10, _jitc->function->vaoff + offsetof(jit_va_list_t, f10));
	SPILL(_F11, _jitc->function->vaoff + offsetof(jit_va_list_t, f11));
	SPILL(_F12, _jitc->function->vaoff + offsetof(jit_va_list_t, f12));
	SPILL(_F13, _jitc->function->vaoff + offsetof(jit_va_list_t, f13));
	SPILL(_F14, _jitc->function->vaoff + offsetof(jit_va_list_t, f14));
    }
    else {
	/* First 4 in low address */
#if __WORDSIZE == 32
	SPILL(_F10, 0);
	SPILL(_F11, 8);
	SPILL(_F12, 16);
	SPILL(_F13, 24);
	/* gpr registers here */
	SPILL(_F14, 72);
	SPILL(_F8, 80);
	SPILL(_F9, 88);
#else
	SPILL(_F10, 16);
	SPILL(_F11, 24);
	SPILL(_F12, 32);
	SPILL(_F13, 48);
	/* Last 3 in high address */
	SPILL(_F14, 136);
	SPILL(_F8, 144);
	SPILL(_F9, 152);
#endif
    }
#undef SPILL
    movr(_R13_REGNO, _R15_REGNO);
    subi(_R15_REGNO, _R15_REGNO, stack_framesize + _jitc->function->stack);
    if (_jitc->function->allocar) {
	regno = jit_get_reg(jit_class_gpr);
	movi(rn(regno), _jitc->function->self.aoff);
	stxi_i(_jitc->function->aoffoff, _R13_REGNO, rn(regno));
	jit_unget_reg(regno);
    }
}

static void
_epilog(jit_state_t *_jit, jit_node_t *i0)
{
    int32_t		regno, offset;
    if (_jitc->function->assume_frame)
	return;
    if ((_jitc->function->self.call & jit_call_varargs) &&
	jit_arg_reg_p(_jitc->function->vagp))
	regno = _jitc->function->vagp;
    else {
	for (regno = 4; regno < jit_size(gprs) - 1; regno++) {
	    if (jit_regset_tstbit(&_jitc->function->regset, gprs[regno]))
		break;
	}
    }
#if __WORDSIZE == 32
    if (_jitc->function->self.call & jit_call_varargs)
	offset = regno * 4 + 8;
    else
	offset = (regno - 4) * 4 + 32;
#else
    if (_jitc->function->self.call & jit_call_varargs)
	offset = regno * 8 + 16;
    else
	offset = (regno - 4) * 8 + 48;
#endif
    movr(_R15_REGNO, _R13_REGNO);

#define LOAD(R, O)							\
    do {								\
	if (jit_regset_tstbit(&_jitc->function->regset, R))		\
	    ldxi_d(rn(R), _R15_REGNO, O);				\
    } while (0)
    if (_jitc->function->self.call & jit_call_varargs) {
	LOAD(_F8, _jitc->function->vaoff + offsetof(jit_va_list_t, f8));
	LOAD(_F9, _jitc->function->vaoff + offsetof(jit_va_list_t, f9));
	LOAD(_F10, _jitc->function->vaoff + offsetof(jit_va_list_t, f10));
	LOAD(_F11, _jitc->function->vaoff + offsetof(jit_va_list_t, f11));
	LOAD(_F12, _jitc->function->vaoff + offsetof(jit_va_list_t, f12));
	LOAD(_F13, _jitc->function->vaoff + offsetof(jit_va_list_t, f13));
	LOAD(_F14, _jitc->function->vaoff + offsetof(jit_va_list_t, f14));
    }
    else {
#if __WORDSIZE == 32
	LOAD(_F10, 0);
	LOAD(_F11, 8);
	LOAD(_F12, 16);
	LOAD(_F13, 24);
	LOAD(_F14, 72);
	LOAD(_F8, 80);
	LOAD(_F9, 88);
#else
	LOAD(_F10, 16);
	LOAD(_F11, 24);
	LOAD(_F12, 32);
	LOAD(_F13, 48);
	LOAD(_F14, 136);
	LOAD(_F8, 144);
	LOAD(_F9, 152);
#endif
    }
#undef LOAD
#if __WORDSIZE == 32
    LM(rn(gprs[regno]), _R15_REGNO, x20(offset), _R15_REGNO);
#else
    LMG(rn(gprs[regno]), _R15_REGNO, x20(offset), _R15_REGNO);
#endif
    BR(_R14_REGNO);
}

static void
_vastart(jit_state_t *_jit, int32_t r0)
{
    int32_t		reg;

    assert(_jitc->function->self.call & jit_call_varargs);

    /* Return jit_va_list_t in the register argument */
    addi(r0, _R13_REGNO, _jitc->function->vaoff);
    reg = jit_get_reg(jit_class_gpr);

    /* Initialize gp offset in the save area. */
    movi(rn(reg), _jitc->function->vagp);
    stxi(offsetof(jit_va_list_t, gpoff), r0, rn(reg));

    /* Initialize fp offset in the save area. */
    movi(rn(reg), _jitc->function->vafp);
    stxi(offsetof(jit_va_list_t, fpoff), r0, rn(reg));

    /* Initialize overflow pointer to the first stack argument. */
    addi(rn(reg), _R13_REGNO, _jitc->function->self.size);
    stxi(offsetof(jit_va_list_t, over), r0, rn(reg));

    /* Initialize register save area pointer. */
    stxi(offsetof(jit_va_list_t, save), r0, _R13_REGNO);

    jit_unget_reg(reg);
}

static void
_vaarg(jit_state_t *_jit, int32_t r0, int32_t r1)
{
    int32_t		rg0;
    int32_t		rg1;
    int32_t		rg2;
    jit_word_t		ge_code;
    jit_word_t		lt_code;

    assert(_jitc->function->self.call & jit_call_varargs);

    rg0 = jit_get_reg_but_zero(0);
    rg1 = jit_get_reg_but_zero(0);

    /* Load the gp offset in save area in the first temporary. */
    ldxi(rn(rg0), r1, offsetof(jit_va_list_t, gpoff));

    /* Jump over if there are no remaining arguments in the save area. */
    ge_code = bgei_p(_jit->pc.w, rn(rg0), 5);

    /* Load the save area pointer in the second temporary. */
    ldxi(rn(rg1), r1, offsetof(jit_va_list_t, save));

    /* Scale offset */
    rg2 = jit_get_reg_but_zero(0);
    lshi(rn(rg2), rn(rg0),
#if __WORDSIZE == 32
	 2
#else
	 3
#endif
	 );
    /* Add offset to saved area. */
    addi(rn(rg2), rn(rg2), 2 * sizeof(jit_word_t));

    /* Load the vararg argument in the first argument. */
    ldxr(r0, rn(rg1), rn(rg2));
    jit_unget_reg_but_zero(rg2);

    /* Update the gp offset. */
    addi(rn(rg0), rn(rg0), 1);
    stxi(offsetof(jit_va_list_t, gpoff), r1, rn(rg0));

    /* Will only need one temporary register below. */
    jit_unget_reg_but_zero(rg1);

    /* Jump over overflow code. */
    lt_code = jmpi_p(_jit->pc.w);

    /* Where to land if argument is in overflow area. */
    patch_at(ge_code, _jit->pc.w);

    /* Load overflow pointer. */
    ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over));

    /* Load argument. */
    ldr(r0, rn(rg0));

    /* Update overflow pointer. */
    addi(rn(rg0), rn(rg0), sizeof(jit_word_t));
    stxi(offsetof(jit_va_list_t, over), r1, rn(rg0));

    /* Where to land if argument is in save area. */
    patch_at(lt_code, _jit->pc.w);

    jit_unget_reg_but_zero(rg0);
}

static void
_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
{
    jit_word_t			 d;
    union {
	uint16_t		*s;
	jit_word_t		 w;
    } u;
    u.w = instr;
    union {
	struct {
	    uint16_t	op :  8;
	    uint16_t	r1 :  4;
	    uint16_t	r3 :  4;
	} b;
	uint16_t		s;
    } i0;
    union {
	struct {
	    uint16_t	i2;
	} b;
	uint16_t		s;
    } i1;
    union {
	struct {
	    uint32_t	ih : 16;
	    uint32_t	il : 16;
	} b;
	uint32_t		i;
    } i12;
    i0.s = u.s[0];
    /* movi_p */
    if (i0.b.op ==
#if __WORDSIZE == 32
	0xA7 && i0.b.r3 == 8
#else
	0xA5
#endif
	) {
#if __WORDSIZE == 64
	assert(i0.b.r3 == 3);
#endif
	i1.b.i2 = (jit_uword_t)label;
	u.s[1] = i1.s;
	i0.s = u.s[2];
	assert(i0.b.op == 0xA5 && i0.b.r3 == 2);
	i1.b.i2 = (jit_uword_t)label >> 16;
	u.s[3] = i1.s;
#if __WORDSIZE == 64
	i0.s = u.s[4];
	assert(i0.b.op == 0xA5 && i0.b.r3 == 1);
	i1.b.i2 = (jit_uword_t)label >> 32;
	u.s[5] = i1.s;
	i0.s = u.s[6];
	assert(i0.b.op == 0xA5 && i0.b.r3 == 0);
	i1.b.i2 = (jit_uword_t)label >> 48;
	u.s[7] = i1.s;
#endif
    }
    /* BRC */
    else if (i0.b.op == 0xA7) {
	assert(i0.b.r3 == 0x4);
	d = (label - instr) >> 1;
	assert(s16_p(d));
	i1.b.i2 = d;
	u.s[1] = i1.s;
    }
    /* BRCL */
    else if (i0.b.op == 0xC0) {
	assert(i0.b.r3 == 0x4);
	d = (label - instr) >> 1;
	assert(s32_p(d));
	i12.i = d;
	u.s[1] = i12.b.ih;
	u.s[2] = i12.b.il;
    }
    else
	abort();
}
#endif
