From f6ee396ccbb4bc0bb898c8bd34726e2615ebf8ba Mon Sep 17 00:00:00 2001 From: pcpa Date: Sun, 28 Jul 2013 14:13:39 -0300 Subject: [PATCH] New s390x port built on the hercules emulator and fedora 16 image. * include/lightning/jit_s390x.h, lib/jit_s390x-cpu.c, lib/jit_s390x-fpu.c, lib/jit_s390x.c: New files implementing the new s390x port. * configure.ac, include/lightning.h, include/lightning/Makefile.am, include/lightning/jit_private.h, lib/Makefile.am, lib/jit_disasm.c, lib/lightning.c: Minor adaptation for the new s390x backend. * check/float.tst: Update for the s390x result of truncating +Inf to integer. * check/qalu_mul.tst: Add extra test cases to better test high word of signed multiplication as the result is adjust from unsigned multiplication on s390x. --- ChangeLog | 19 + check/float.tst | 2 +- check/qalu_mul.tst | 6 + configure.ac | 2 + include/lightning.h | 2 + include/lightning/Makefile.am | 4 + include/lightning/jit_private.h | 8 + include/lightning/jit_s390x.h | 70 + lib/Makefile.am | 3 + lib/jit_disasm.c | 7 +- lib/jit_s390x-cpu.c | 3392 +++++++++++++++++++++++++++++++ lib/jit_s390x-fpu.c | 1198 +++++++++++ lib/jit_s390x.c | 1281 ++++++++++++ lib/lightning.c | 2 + 14 files changed, 5994 insertions(+), 2 deletions(-) create mode 100644 include/lightning/jit_s390x.h create mode 100644 lib/jit_s390x-cpu.c create mode 100644 lib/jit_s390x-fpu.c create mode 100644 lib/jit_s390x.c diff --git a/ChangeLog b/ChangeLog index 5caa6cb8a..f33dc7990 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2013-07-28 Paulo Andrade + + * include/lightning/jit_s390x.h, lib/jit_s390x-cpu.c, + lib/jit_s390x-fpu.c, lib/jit_s390x.c: New files + implementing the new s390x port. + + * configure.ac, include/lightning.h, + include/lightning/Makefile.am, + include/lightning/jit_private.h, + lib/Makefile.am, lib/jit_disasm.c, lib/lightning.c: + Minor adaptation for the new s390x backend. + + * check/float.tst: Update for the s390x result of + truncating +Inf to integer. + + * check/qalu_mul.tst: Add extra test cases to better test + high word of signed multiplication as the result is + adjust from unsigned multiplication on s390x. + 2013-07-28 Paulo Andrade * check/lightning.c: Do not assume casting a double NaN or diff --git a/check/float.tst b/check/float.tst index 0aa8605f8..2cb51aff0 100644 --- a/check/float.tst +++ b/check/float.tst @@ -21,7 +21,7 @@ ok: #else # define wnan x80 #endif -#if __mips__ || __arm__ || __ppc__ || __sparc__ || __hppa__ || __aarch64__ +#if __mips__ || __arm__ || __ppc__ || __sparc__ || __hppa__ || __aarch64__ || __s390x__ # define wpinf x7f #else # define wpinf x80 diff --git a/check/qalu_mul.tst b/check/qalu_mul.tst index 378d38373..64b95a94c 100644 --- a/check/qalu_mul.tst +++ b/check/qalu_mul.tst @@ -12,10 +12,16 @@ QMUL(4, 0x7ffff, 0x7ffff, 0xfff00001, 0x3f) UQMUL(5, 0xffffff, 0xffffff, 0xfe000001, 0xffff) QMUL(6, 0x80000000, -2, 0, 1) + QMUL(7, 0x80000000, 2, 0, -1) + QMUL(8, 0x80000001, 3, 0x80000003, -2) + QMUL(9, 0x80000001, -3, 0x7ffffffd, 1) #else QMUL(4, 0x7ffffffff, 0x7ffffffff, 0xfffffff000000001, 0x3f) UQMUL(5, 0xffffffffff, 0xffffffffff, 0xfffffe0000000001, 0xffff) QMUL(6, 0x8000000000000000, -2, 0, 1) + QMUL(7, 0x8000000000000000, 2, 0, -1) + QMUL(8, 0x8000000000000001, 3, 0x8000000000000003, -2) + QMUL(9, 0x8000000000000001, -3, 0x7ffffffffffffffd, 1) #endif prepare pushargi ok diff --git a/configure.ac b/configure.ac index 92128c3a5..c51fd71d6 100644 --- a/configure.ac +++ b/configure.ac @@ -100,6 +100,7 @@ case "$target_cpu" in ia64) cpu=ia64 ;; hppa*) cpu=hppa ;; aarch64) cpu=aarch64 ;; + s390x) cpu=s390x ;; *) ;; esac AM_CONDITIONAL(cpu_arm, [test cpu-$cpu = cpu-arm]) @@ -110,6 +111,7 @@ AM_CONDITIONAL(cpu_x86, [test cpu-$cpu = cpu-x86]) AM_CONDITIONAL(cpu_ia64, [test cpu-$cpu = cpu-ia64]) AM_CONDITIONAL(cpu_hppa, [test cpu-$cpu = cpu-hppa]) AM_CONDITIONAL(cpu_aarch64, [test cpu-$cpu = cpu-aarch64]) +AM_CONDITIONAL(cpu_s390x, [test cpu-$cpu = cpu-s390x]) # Test x87 if both, x87 and sse2 available ac_cv_test_x86_x87= diff --git a/include/lightning.h b/include/lightning.h index fe9c86fce..399dbb068 100644 --- a/include/lightning.h +++ b/include/lightning.h @@ -126,6 +126,8 @@ typedef jit_int32_t jit_fpr_t; # include #elif defined(__aarch64__) # include +#elif defined(__s390x__) +# include #endif #define jit_flag_node 0x00000001 /* patch node not absolute */ diff --git a/include/lightning/Makefile.am b/include/lightning/Makefile.am index c9abb777d..2a51c1f1a 100644 --- a/include/lightning/Makefile.am +++ b/include/lightning/Makefile.am @@ -49,3 +49,7 @@ if cpu_aarch64 lightning_include_HEADERS = \ jit_aarch64.h endif +if cpu_s390x +lightning_include_HEADERS = \ + jit_s390x.h +endif diff --git a/include/lightning/jit_private.h b/include/lightning/jit_private.h index 6941caf11..cd59ff876 100644 --- a/include/lightning/jit_private.h +++ b/include/lightning/jit_private.h @@ -85,6 +85,10 @@ # define JIT_SP _SP # define JIT_RET _R0 # define JIT_FRET _V0 +#elif defined(__s390x__) +# define JIT_SP _R15 +# define JIT_RET _R2 +# define JIT_FRET _F0 #endif #define jit_size(vector) (sizeof(vector) / sizeof((vector)[0])) @@ -94,6 +98,10 @@ !jit_regset_tstbit(&_jitc->regarg, regno) && \ !jit_regset_tstbit(&_jitc->regsav, regno)) +#define jit_reg_free_if_spill_p(regno) \ + (!jit_regset_tstbit(&_jitc->regarg, regno) && \ + !jit_regset_tstbit(&_jitc->regsav, regno)) + /* * Private jit_class bitmasks */ diff --git a/include/lightning/jit_s390x.h b/include/lightning/jit_s390x.h new file mode 100644 index 000000000..5a3199a56 --- /dev/null +++ b/include/lightning/jit_s390x.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software 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 General Public License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#ifndef _jit_s390x_h +#define _jit_s390x_h + +#define JIT_HASH_CONSTS 1 +#define JIT_NUM_OPERANDS 2 + +/* + * Types + */ +#define JIT_FP _R13 +typedef enum { +#define jit_arg_reg_p(i) ((i) >= 0 && (i) <= 5) +#define jit_r(i) (_R12 + ((i) << 1)) +#define jit_r_num() 3 +#define jit_v(i) (_R11 + ((i) << 1)) +#define jit_v_num() 3 +#define jit_arg_f_reg_p(i) ((i) >= 0 && (i) <= 4) +#define jit_f(i) (_F8 + (i)) +#define jit_f_num() 6 +#define JIT_R0 _R12 +#define JIT_R1 _R10 +#define JIT_R2 _R8 +#define JIT_V0 _R11 +#define JIT_V1 _R9 +#define JIT_V2 _R7 + _R0, _R1, /* Volatile */ + _R12, /* Saved, GOT */ + _R11, _R10, _R9, _R8, /* Saved */ + _R7, /* Saved */ + _R6, /* Saved, parameter */ + _R5, _R4, _R3, /* Parameter passing */ + _R2, /* Volatile, parameter and return value */ + _R13, /* Saved, literal pool pointer */ + _R14, /* Volatile, return address */ + _R15, /* Saved, stack pointer */ +#define JIT_F0 _F8 +#define JIT_F1 _F9 +#define JIT_F2 _F10 +#define JIT_F3 _F11 +#define JIT_F4 _F12 +#define JIT_F5 _F13 + _F1, _F3, _F5, _F7, /* Volatile */ + _F14, _F15, _F8, _F9, /* Saved */ + _F10, _F11, _F12, _F13, /* Saved */ + _F6, _F4, _F2, /* Volatile, parameter */ + _F0, /* Volatile, parameter and return value */ + _NOREG, +#define JIT_NOREG _NOREG +} jit_reg_t; + +typedef jit_int32_t jit_regset_t; + +#endif /* _jit_s390x_h */ diff --git a/lib/Makefile.am b/lib/Makefile.am index 185263931..aa9d318ac 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -43,6 +43,9 @@ EXTRA_DIST = \ jit_ppc.c \ jit_ppc-cpu.c \ jit_ppc-fpu.c \ + jit_s390x.c \ + jit_s390x-cpu.c \ + jit_s390x-fpu.c \ jit_sparc.c \ jit_sparc-cpu.c \ jit_sparc-fpu.c \ diff --git a/lib/jit_disasm.c b/lib/jit_disasm.c index eb85f6ea5..aa266b28d 100644 --- a/lib/jit_disasm.c +++ b/lib/jit_disasm.c @@ -90,9 +90,14 @@ jit_init_debug(void) # endif disassemble_init_powerpc(&disasm_info); # endif - # if defined(__sparc__) disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG; +# endif +# if defined(__s390x__) + disasm_info.arch = bfd_arch_s390; + disasm_info.mach = bfd_mach_s390_64; + disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG; + disasm_info.disassembler_options = "zarch"; # endif disasm_info.print_address_func = disasm_print_address; diff --git a/lib/jit_s390x-cpu.c b/lib/jit_s390x-cpu.c new file mode 100644 index 000000000..527b1c1f3 --- /dev/null +++ b/lib/jit_s390x-cpu.c @@ -0,0 +1,3392 @@ +/* + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software 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 General Public License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# define ldxi(r0,r1,i0) ldxi_l(r0,r1,i0) +# define stxi(i0,r0,r1) stxi_l(i0,r0,r1) +# define is(i) *_jit->pc.us++ = i +# define stack_framesize 160 +# define _R0_REGNO 0 +# define _R1_REGNO 1 +# define _R7_REGNO 7 +# define _R13_REGNO 13 +# 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) +# define s32_p(i0) \ + ((i0) >= -2147483648L && (i0) < 2147483647L) + +/* + Condition Code Instruction (Mask) Bit Mask Value + 0 8 8 + 1 9 4 + 2 10 2 + 3 11 1 + +AGR: + 0 Zero + 1 < zero + 2 > zero + 3 Overflow +-- +1 -> overflow CC_O +14 -> no overflow CC_NO + +ALGR: + 0 Zero, no carry + 1 Not zero, no carry + 2 Zero, carry + 3 Not zero, carry +-- +2|1 -> carry CC_NLE +8|4 -> no carry CC_LE + +SGR: + 0 Zero + 1 < zero + 2 > zero + 3 Overflow +-- +1 -> overflow CC_O +14 -> no overflow CC_NO + +SLGR: + 0 -- + 1 Not zero, borrow + 2 Zero, no borrow + 3 Not zero, no borrow +-- +4 -> borrow CC_L +11 -> no borrow CC_NL + */ + +# define CC_NV 0x0 +# define CC_O 0x1 +# define CC_H 0x2 +# define CC_NLE 0x3 +# define CC_L 0x4 +# define CC_NHE 0x5 +# define CC_LH 0x6 +# define CC_NE 0x7 +# define CC_E 0x8 +# define CC_NLH 0x9 +# define CC_HE 0xA +# define CC_NL 0xB +# define CC_LE 0xC +# define CC_NH 0xD +# define CC_NO 0xE +# define CC_AL 0xF +# define _us jit_uint16_t +# define _ui jit_uint32_t +# define E_(Op) _E(_jit,Op) +static void _E(jit_state_t*,_ui); +# define I_(Op,I) _I(_jit,Op,I) +static void _I(jit_state_t*,_ui,_ui); +# define RR_(Op,R1,R2) _RR(_jit,Op,R1,R2) +static void _RR(jit_state_t*,_ui,_ui,_ui); +# define RRE_(Op,R1,R2) _RRE(_jit,Op,R1,R2) +static void _RRE(jit_state_t*,_ui,_ui,_ui); +# define RRF_(Op,R3,M4,R1,R2) _RRF(_jit,Op,R3,M4,R1,R2) +static void _RRF(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# define RX_(Op,R1,X2,B2,D2) _RX(_jit,Op,R1,X2,B2,D2) +static void _RX(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# define RXE_(Op,R1,X2,B2,D2,Op2) _RXE(_jit,Op,R1,X2,B2,D2,Op2) +static void _RXE(jit_state_t*,_ui,_ui,_ui,_ui,_ui,_ui); +# define RXF_(Op,R3,X2,B2,D2,R1,Op2) _RXF(_jit,Op,R3,X2,B2,D2,R1,Op2) +static void _RXF(jit_state_t*,_ui,_ui,_ui,_ui,_ui,_ui,_ui); +# define RXY_(Op,R1,X2,B2,D2,Op2) _RXY(_jit,Op,R1,X2,B2,D2,Op2) +static void _RXY(jit_state_t*,_ui,_ui,_ui,_ui,_ui,_ui); +# define RS_(Op,R1,R3,B2,D2) _RS(_jit,Op,R1,R3,B2,D2) +static void _RS(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# define RSY_(Op,R1,R3,B2,D2,Op2) RXY_(Op,R1,R3,B2,D2,Op2) +# define RSL_(Op,L1,B1,D1,Op2) _RSL(_jit,Op,L1,B1,D1,Op2) +static void _RSL(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# define RSI_(Op,R1,R3,I2) _RSI(_jit,Op,R1,R3,I2) +static void _RSI(jit_state_t*,_ui,_ui,_ui,_ui); +# define RI_(Op,R1,Op2,I2) RSI_(Op,R1,Op2,I2) +# define RIE_(Op,R1,R3,I2,Op2) _RIE(_jit,Op,R1,R3,I2,Op2) +static void _RIE(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# define RIL_(Op,R1,Op2,I2) _RIL(_jit,Op,R1,Op2,I2) +static void _RIL(jit_state_t*,_ui,_ui,_ui,_ui); +# define SI_(Op,I2,B1,D1) _SI(_jit,Op,I2,B1,D1) +static void _SI(jit_state_t*,_ui,_ui,_ui,_ui); +# define SIY_(Op,I2,B1,D1,Op2) _SIY(_jit,Op,I2,B1,D1,Op2) +static void _SIY(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# define S_(Op,B2,D2) _S(_jit,Op,B2,D2) +static void _S(jit_state_t*,_ui,_ui,_ui); +# define SSL_(Op,L,B1,D1,B2,D2) SS_(Op,(L)>>4,(L)&0xF,B1,D1,B2,D2) +# define SS_(Op,LL,LH,B1,D1,B2,D2) _SS(_jit,Op,LL,LH,B1,D1,B2,D2) +static void _SS(jit_state_t*,_ui,_ui,_ui,_ui,_ui,_ui,_ui); +# define SSE_(Op,B1,D1,B2,D2) _SSE(_jit,Op,B1,D1,B2,D2) +static void _SSE(jit_state_t*,_ui,_ui,_ui,_ui,_ui); +# undef _us +# undef _ui +# define nop(c) _nop(_jit,c) +static void _nop(jit_state_t*,jit_int32_t); +/**************************************************************** + * 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,D2,B2) +# define STMY(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x90) +# define STMG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x24) +/* STORE MULTIPLE HIGH */ +# define STMH(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x26) +/* STORE PAIR TO QUADWORD */ +# define STPQ(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x8E) +/* STORE REVERSED */ +# define STRVH(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x3F) +# define STRV(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x3E) +# define STRVG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x2F) +/* SUBTRACT */ +# define SR(R1,R2) RR_(0x1B,R1,R2) +# define SGR(R1,R2) RRE_(0xB909,R1,R2) +# define SGFR(R1,R2) RRE_(0xB919,R1,R2) +# define S(R1,D2,X2,B2) RX_(0x5B,R1,X2,B2,D2) +# define SY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x5B) +# define SG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x09) +# define SGF(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x19) +/* SUBTRACT HALFWORD */ +# define SH(R1,D2,X2,B2) RX_(0x4B,R1,X2,B2,D2) +# define SHY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x7B) +/* SUBTRACT LOGICAL */ +# define SLR(R1,R2) RR_(0x1F,R1,R2) +# define SLGR(R1,R2) RRE_(0xB90B,R1,R2) +# define SLGFR(R1,R2) RRE_(0xB91B,R1,R2) +# define SL(R1,D2,X2,B2) RX_(0x5F,R1,X2,B2,D2) +# define SLY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x5F) +# define SLG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x0B) +# define SLGF(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x1B) +/* SUBTRACT LOGICAL WITH BORROW */ +# define SLBR(R1,R2) RRE_(0xB999,R1,R2) +# define SLBGR(R1,R2) RRE_(0xB989,R1,R2) +# define SLB(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x99) +# define SLBG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x89) +/* SUPERVISOR CALL */ +# define SVC(I) I_(0xA,I) +/* TEST ADDRESSING MODE */ +# define TAM() E_(0x10B) +/* TEST AND SET */ +# define TS(D2,B2) RS_(0x93,0,0,B2,D2) +/* TEST UNDER MASK (TEST UNDER MASK HIGH, TEST UNDER MASK LOW) */ +# define TM(D1,B1,I2) SI_(0x91,I2,B1,D1) +# define TMY(D1,B1,I2) SIY_(0xEB,I2,B1,D1,0x51) +# define TMHH(R1,I2) RI_(0xA7,R1,0x2,I2) +# define TMHL(R1,I2) RI_(0xA7,R1,0x3,I2) +# define TMLH(R1,I2) RI_(0xA7,R1,0x0,I2) +# define TMH(R1,I2) TMLH(R1,I2) +# define TMLL(R1,I2) RI_(0xA7,R1,0x1,I2) +# define TML(R1,I2) TMLL(R1,I2) +/* TRANSLATE */ +# define TR(D1,L,B1,D2,B2) SSL_(0xDC,L,B1,D1,B2,D2) +/* TRANSLATE AND TEST */ +# define TRT(D1,L,B1,D2,B2) SSL_(0xDD,L,B1,D1,B2,D2) +/* TRANSLATE EXTENDED */ +# define TRE(R1,R2) RRE_(0xB2A5,R1,R2) +/* TRANSLATE ONE TO ONE */ +# define TROO(R1,R2) RRE_(0xB993,R1,R2) +/* TRANSLATE ONE TO TWO */ +# define TROT(R1,R2) RRE_(0xB992,R1,R2) +/* TRANSLATE TWO TO ONE */ +# define TRTO(R1,R2) RRE_(0xB991,R1,R2) +/* TRANSLATE TWO TO TWO */ +# define TRTT(R1,R2) RRE_(0xB990,R1,R2) +/* UNPACK */ +# define UNPK(D1,L1,B1,D2,L2,B2) SS_(0xF3,L1,L2,B1,D1,B2,D2) +/* UNPACK ASCII */ +# define UNPKA(D1,L1,B1,D2,L2,B2) SS_(0xEA,L1,L2,B1,D1,B2,D2) +/* UNPACK UNICODE */ +# define UNPKU(D1,L1,B1,D2,L2,B2) SS_(0xE2,L1,L2,B1,D1,B2,D2) +/* UPDATE TREE */ +# define UPT() E_(0x0102) +/**************************************************************** + * Decimal Instructions * + ****************************************************************/ +/* ADD DECIMAL */ +# define AP(D1,L1,B1,D2,L2,B2) SS_(0xFA,L1,L2,B1,D1,B2,D2) +/* COMPARE DECIMAL */ +# define CP(D1,L1,B1,D2,L2,B2) SS_(0xF9,L1,L2,B1,D1,B2,D2) +/* DIVIDE DECIMAL */ +# define DP(D1,L1,B1,D2,L2,B2) SS_(0xFD,L1,L2,B1,D1,B2,D2) +/* EDIT */ +# define ED(D1,L,B1,D2,B2) SSL_(0xDE,L,B1,D1,B2,D2) +/* EDIT AND MARK */ +# define EDMK(D1,L,B1,D2,B2) SSL_(0xDE,L,B1,D1,B2,D2) +/* MULTIPLY DECIMAL */ +# define MP(D1,L1,B1,D2,L2,B2) SS_(0xFC,L1,L2,B1,D1,B2,D2) +/* SHIFT AND ROUND DECIMAL */ +# define SRP(D1,L1,B1,D2,L2,B2) SS_(0xF0,L1,L2,B1,D1,B2,D2) +/* SUBTRACE DECIMAL */ +# define SP(D1,L1,B1,D2,L2,B2) SS_(0xFB,L1,L2,B1,D1,B2,D2) +/* TEST DECIMAL */ +# define TP(D1,L1,B1) RSL_(0xEB,L1,B1,D1,0xC0) +/* ZERO AND ADD */ +# define ZAP(D1,L1,B1,D2,L2,B2) SS_(0xF8,L1,L2,B1,D1,B2,D2) +/**************************************************************** + * Control Instructions * + ****************************************************************/ +/* BRANCH AND SET AUTHORITY */ +# define BSA(R1,R2) RRE_(0xB25A,R1,R2) +/* BRANCH AND STACK */ +# define BAKR(R1,R2) RRE_(0xB240,R1,R2) +/* BRANCH IN SUBSPACE GROUP */ +# define BSG(R1,R2) RRE_(0xB258,R1,R2) +/* COMPARE AND SWAP AND PURGE */ +# define CSP(R1,R2) RRE_(0xB250,R1,R2) +# define CSPG(R1,R2) RRE_(0xB98A,R1,R2) +/* DIAGNOSE */ +# define DIAG() SI_(0x83,0,0,0) +/* EXTRACT AND SET EXTENDED AUTHORITY */ +# define ESEA(R1) RRE_(0xB99D,R1,0) +/* EXTRACT PRIMARY ASN */ +# define EPAR(R1) RRE_(0xB226,R1,0) +/* EXTRACT SECONDARY ASN */ +# define ESAR(R1) RRE_(0xB227,R1,0) +/* EXTRACT STACKED REGISTERS */ +# define EREG(R1,R2) RRE_(0xB249,R1,R2) +# define EREGG(R1,R2) RRE_(0xB90E,R1,R2) +/* EXTRACT STACKED STATE */ +# define ESTA(R1,R2) RRE_(0xB24A,R1,R2) +/* INSERT ADDRESS SPACE CONTROL */ +# define IAC(R1) RRE_(0xB224,R1,0) +/* INSERT PSW KEY */ +# define IPK() S_(0xB20B,0,0) +/* INSERT STORAGE KEY EXTENDED */ +# define ISKE(R1,R2) RRE_(0xB229,R1,R2) +/* INSERT VIRTUAL STORAGE KEY */ +# define IVSK(R1,R2) RRE_(0xB223,R1,R2) +/* INVALIDATE DAT TABLE ENTRY */ +# define IDTE(R1,R2,R3) RRF_(0xB98E,R3,0,R1,R2) +/* INVALIDATE PAGE TABLE ENTRY */ +# define IPTE(R1,R2) RRE_(0xB221,R1,R2) +/* LOAD ADDRESS SPACE PARAMETER */ +# define LASP(D1,B1,D2,B2) SSE_(0xE500,B1,D1,B2,D2) +/* LOAD CONTROL */ +# define LCTL(R1,R3,D2,B2) RS_(0xB7,R1,R3,B2,D2) +# define LCTLG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x2F) +/* LOAD PSW */ +# define LPSW(D2,B2) SI_(0x82,0,B2,D2) +/* LOAD PSW EXTENDED */ +# define LPSWE(D2,B2) S_(0xB2B2,B2,D2) +/* LOAD REAL ADDRESS */ +# define LRA(R1,D2,X2,B2) RX_(0xB1,R1,X2,B2,D2) +# define LRAY(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x13) +# define LRAG(R1,D2,X2,B2) RXY_(0xE3,R1,X2,B2,D2,0x03) +/* LOAD USING REAL ADDRESS */ +# define LURA(R1,R2) RRE_(0xB24B,R1,R2) +# define LURAG(R1,R2) RRE_(0xB905,R1,R2) +/* MODIFY STACKED STATE */ +# define MSTA(R1) RRE_(0xB247,R1,0) +/* MOVE PAGE */ +# define MVPG(R1,R2) RRE_(0xB254,R1,R2) +/* MOVE TO PRIMARY */ +# define MVCP(D1,R1,B1,D2,B2,R3) SS_(0xDA,R1,R3,B1,D1,B2,D2) +/* MOVE TO SECONDARY */ +# define MVCS(D1,R1,B1,D2,B2,R3) SS_(0xDB,R1,R3,B1,D1,B2,D2) +/* MOVE WITH DESTINATION KEY */ +# define MVCDK(D1,B1,D2,B2) SSE_(0xE50F,B1,D1,B2,D2) +/* MOVE WITH KEY */ +# define MVCK(D1,R1,B1,D2,B2,R3) SS_(0xD9,R1,R3,B1,D1,B2,D2) +/* MOVE WITH SOURCE KEY */ +# define MVCSK(D1,B1,D2,B2) SSE_(0xE50E,B1,D1,B2,D2) +/* PAGE IN */ +# define PGIN(R1,R2) RRE_(0xB22E,R1,R2) +/* PAGE OUT */ +# define PGOUT(R1,R2) RRE_(0xB22F,R1,R2) +/* PROGRAM CALL */ +# define PC(D2,B2) S_(0xB218,B2,D2) +/* PROGRAM RETURN */ +# define PR() E_(0x0101) +/* PROGRAM TRANSFER */ +# define PT(R1,R2) RRE_(0xB228,R1,R2) +/* PURGE ALB */ +# define PALB() RRE_(0xB248,0,0) +/* PURGE TLB */ +# define PTLB() S_(0xB20D,0,0) +/* RESET REFERENCE BIT EXTENDED */ +# define RRBE(R1,R2) RRE_(0xB22A,R1,R2) +/* RESUME PROGRAM */ +# define RP(D2,B2) S_(0xB277,B2,D2) +/* SET ADDRESS SPACE CONTROL */ +# define SAC(D2,B2) S_(0xB219,B2,D2) +/* SET ADDRESS SPACE CONTROL FAST */ +# define SACF(D2,B2) S_(0xB279,B2,D2) +/* SET CLOCK */ +# define SCK(D2,B2) S_(0xB204,B2,D2) +/* SET CLOCK COMPARATOR */ +# define SCKC(D2,B2) S_(0xB206,B2,D2) +/* SET CLOCK PROGRAMMABLE FIELD */ +# define SCKPF() E_(0x0107) +/* SET CPU TIMER */ +# define SPT(D2,B2) S_(0xB208,B2,D2) +/* SET PREFIX */ +# define SPX(D2,B2) S_(0xB210,B2,D2) +/* SET PSW FROM ADDRESS */ +# define SPKA(D2,B2) S_(0xB20A,B2,D2) +/* SET SECONDARY ASN */ +# define SSAR(R1) RRE_(0xB225,R1,0) +/* SET STORAGE KEY EXTENDED */ +# define SSKE(R1,R2) RRE_(0xB22B,R1,R2) +/* SET SYSTEM MASK */ +# define SSM(D2,B2) SI_(0x80,0,B2,D2) +/* SIGNAL PROCESSOR */ +# define SIGP(R1,R3,D2,B2) RS_(0xAE,R1,R3,B2,D2) +/* STORE CLOCK COMPARATOR */ +# define STCKC(D2,B2) S_(0xB207,B2,D2) +/* STORE CONTROL */ +# define STCTL(R1,R3,D2,B2) RS_(0xB6,R1,R3,B2,D2) +# define STCTG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x25) +/* STORE CPU ADDRESS */ +# define STAP(D2,B2) S_(0xB212,B2,D2) +/* STORE CPU ID */ +# define STIDP(D2,B2) S_(0xB202,B2,D2) +/* STORE CPU TIMER */ +# define STPT(D2,B2) S_(0xB209,B2,D2) +/* STORE FACILITY LIST */ +# define STFL(D2,B2) S_(0xB2B1,B2,D2) +/* STORE PREFIX */ +# define STPX(D2,B2) S_(0xB211,B2,D2) +/* STORE REAL ADDRES */ +# define STRAG(D1,B1,D2,B2) SSE_(0xE502,B1,D1,B2,D2) +/* STORE SYSTEM INFORMATION */ +# define STSI(D2,B2) S_(0xB27D,B2,D2) +/* STORE THEN AND SYSTEM MASK */ +# define STNSM(D1,B1,I2) SI_(0xAC,I2,B1,D1) +/* STORE THEN OR SYSTEM MASK */ +# define STOSM(D1,B1,I2) SI_(0xAD,I2,B1,D1) +/* STORE USING REAL ADDRESS */ +# define STURA(R1,R2) RRE_(0xB246,R1,R2) +# define STURG(R1,R2) RRE_(0xB925,R1,R2) +/* TEST ACCESS */ +# define TAR(R1,R2) RRE_(0xB24C,R1,R2) +/* TEST BLOCK */ +# define TB(R1,R2) RRE_(0xB22C,R1,R2) +/* TEST PROTECTION */ +# define TPROT(D1,B1,D2,B2) SSE_(0xE501,B1,D1,B2,D2) +/* TRACE */ +# define TRACE(R1,R3,D2,B2) RS_(0x99,R1,R3,B2,D2) +# define TRACG(R1,R3,D2,B2) RSY_(0xEB,R1,R3,B2,D2,0x0F) +/* TRAP */ +# define TRAP2() E_(0x01FF) +# define TRAP4(D2,B2) S_(0xB2FF,B2,D2) +/**************************************************************** + * I/O Instructions * + ****************************************************************/ +/* CANCEL SUBCHANNEL */ +# define XSCH() S_(0xB276,0,0) +/* CLEAR SUBCHANNEL */ +# define CSCH() S_(0xB230,0,0) +/* HALT SUBCHANNEL */ +# define HSCH() S_(0xB231,0,0) +/* MODIFY SUBCHANNEL */ +# define MSCH(D2,B2) S_(0xB232,B2,D2) +/* RESET CHANNEL PATH */ +# define RCHP() S_(0xB23B,0,0) +/* RESUME SUBCHANNEL */ +# define RSCH() S_(0xB238,0,0) +/* SET ADDRESS LIMIT */ +# define SAL() S_(0xB237,0,0) +/* SET CHANNEL MONITOR */ +# define SCHM() S_(0xB23C,0,0) +/* START SUBCHANNEL */ +# define SSCH(D2,B2) S_(0xB233,B2,D2) +/* STORE CHANNEL PATH STATUS */ +# define STCPS(D2,B2) S_(0xB23A,B2,D2) +/* STORE CHANNEL REPORT WORD */ +# define STCRW(D2,B2) S_(0xB239,B2,D2) +/* STORE SUBCHANNEL */ +# define STSCH(D2,B2) S_(0xB234,B2,D2) +/* TEST PENDING INTERRUPTION */ +# define TPI(D2,B2) S_(0xB236,B2,D2) +/* TEST SUBCHANNEL */ +# define TSCH(D2,B2) S_(0xB235,B2,D2) +# define xdivr(r0,r1) _xdivr(_jit,r0,r1) +static jit_int32_t _xdivr(jit_state_t*,jit_int32_t,jit_int32_t); +# define xdivr_u(r0,r1) _xdivr_u(_jit,r0,r1) +static jit_int32_t _xdivr_u(jit_state_t*,jit_int32_t,jit_int32_t); +# define xdivi(r0,i0) _xdivi(_jit,r0,i0) +static jit_int32_t _xdivi(jit_state_t*,jit_int32_t,jit_word_t); +# define xdivi_u(r0,i0) _xdivi_u(_jit,r0,i0) +static jit_int32_t _xdivi_u(jit_state_t*,jit_int32_t,jit_word_t); +# define crr(cc,r0,r1,r2) _crr(_jit,cc,r0,r1,r2) +static void _crr(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define cri(cc,r0,r1,i0) _cri(_jit,cc,r0,r1,i0) +static void _cri(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +# define crr_u(cc,r0,r1,r2) _crr_u(_jit,cc,r0,r1,r2) +static void _crr_u(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define cri_u(cc,r0,r1,i0) _cri_u(_jit,cc,r0,r1,i0) +static void _cri_u(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +# define brr(cc,i0,r0,r1) _brr(_jit,cc,i0,r0,r1) +static void _brr(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define brr_p(cc,i0,r0,r1) _brr_p(_jit,cc,i0,r0,r1) +static jit_word_t _brr_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bri(cc,i0,r0,i1) _bri(_jit,cc,i0,r0,i1) +static void _bri(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bri_p(cc,i0,r0,i1) _bri_p(_jit,cc,i0,r0,i1) +static jit_word_t _bri_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define brr_u(cc,i0,r0,r1) _brr_u(_jit,cc,i0,r0,r1) +static void _brr_u(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define brr_u_p(cc,i0,r0,r1) _brr_u_p(_jit,cc,i0,r0,r1) +static jit_word_t _brr_u_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bri_u(cc,i0,r0,i1) _bri_u(_jit,cc,i0,r0,i1) +static void _bri_u(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bri_u_p(cc,i0,r0,i1) _bri_u_p(_jit,cc,i0,r0,i1) +static jit_word_t _bri_u_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define baddr(c,s,i0,r0,r1) _baddr(_jit,c,s,i0,r0,r1) +static void _baddr(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define baddr_p(c,s,i0,r0,r1) _baddr_p(_jit,c,s,i0,r0,r1) +static jit_word_t _baddr_p(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define baddi(c,s,i0,r0,i1) _baddi(_jit,c,s,i0,r0,i1) +static void _baddi(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_word_t); +# define baddi_p(c,s,i0,r0,i1) _baddi_p(_jit,c,s,i0,r0,i1) +static jit_word_t _baddi_p(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bsubr(c,s,i0,r0,r1) _bsubr(_jit,c,s,i0,r0,r1) +static void _bsubr(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bsubr_p(c,s,i0,r0,r1) _bsubr_p(_jit,c,s,i0,r0,r1) +static jit_word_t _bsubr_p(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bsubi(c,s,i0,r0,i1) _bsubi(_jit,c,s,i0,r0,i1) +static void _bsubi(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bsubi_p(c,s,i0,r0,i1) _bsubi_p(_jit,c,s,i0,r0,i1) +static jit_word_t _bsubi_p(jit_state_t*,jit_int32_t,jit_bool_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bmxr(cc,i0,r0,r1) _bmxr(_jit,cc,i0,r0,r1) +static void _bmxr(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bmxr_p(cc,i0,r0,r1) _bmxr_p(_jit,cc,i0,r0,r1) +static jit_word_t _bmxr_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bmxi(cc,i0,r0,i1) _bmxi(_jit,cc,i0,r0,i1) +static void _bmxi(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bmxi_p(cc,i0,r0,i1) _bmxi_p(_jit,cc,i0,r0,i1) +static jit_word_t _bmxi_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define movr(r0,r1) _movr(_jit,r0,r1) +static void _movr(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi(r0,i0) _movi(_jit,r0,i0) +static void _movi(jit_state_t*,jit_int32_t,jit_word_t); +# define movi_p(r0,i0) _movi_p(_jit,r0,i0) +static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t); +# define addr(r0,r1,r2) _addr(_jit,r0,r1,r2) +static void _addr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0) +static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addcr(r0,r1,r2) _addcr(_jit,r0,r1,r2) +static void _addcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addci(r0,r1,i0) _addci(_jit,r0,r1,i0) +static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addxr(r0,r1,r2) _addxr(_jit,r0,r1,r2) +static void _addxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0) +static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subr(r0,r1,r2) _subr(_jit,r0,r1,r2) +static void _subr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subi(r0,r1,i0) _subi(_jit,r0,r1,i0) +static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subcr(r0,r1,r2) _subcr(_jit,r0,r1,r2) +static void _subcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subci(r0,r1,i0) _subci(_jit,r0,r1,i0) +static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subxr(r0,r1,r2) _subxr(_jit,r0,r1,r2) +static void _subxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subxi(r0,r1,i0) _subxi(_jit,r0,r1,i0) +static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define mulr(r0,r1,r2) _mulr(_jit,r0,r1,r2) +static void _mulr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define muli(r0,r1,i0) _muli(_jit,r0,r1,i0) +static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr(r0,r1,r2,r3) _qmulr(_jit,r0,r1,r2,r3) +static void _qmulr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qmuli(r0,r1,r2,i0) _qmuli(_jit,r0,r1,r2,i0) +static void _qmuli(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr_u(r0,r1,r2,r3) _qmulr_u(_jit,r0,r1,r2,r3) +static void _qmulr_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qmuli_u(r0,r1,r2,i0) _qmuli_u(_jit,r0,r1,r2,i0) +static void _qmuli_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define divr(r0,r1,r2) _divr(_jit,r0,r1,r2) +static void _divr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi(r0,r1,i0) _divi(_jit,r0,r1,i0) +static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define divr_u(r0,r1,r2) _divr_u(_jit,r0,r1,r2) +static void _divr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0) +static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define remr(r0,r1,r2) _remr(_jit,r0,r1,r2) +static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi(r0,r1,i0) _remi(_jit,r0,r1,i0) +static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2) +static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0) +static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qdivr(r0,r1,r2,r3) _qdivr(_jit,r0,r1,r2,r3) +static void _qdivr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qdivi(r0,r1,r2,i0) _qdivi(_jit,r0,r1,r2,i0) +static void _qdivi(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define qdivr_u(r0,r1,r2,r3) _qdivr_u(_jit,r0,r1,r2,r3) +static void _qdivr_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qdivi_u(r0,r1,r2,i0) _qdivi_u(_jit,r0,r1,r2,i0) +static void _qdivi_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define lshr(r0,r1,r2) SLLG(r0,r1,0,r2) +# define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0) +static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr(r0,r1,r2) SRAG(r0,r1,0,r2) +# define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0) +static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr_u(r0,r1,r2) SRLG(r0,r1,0,r2) +# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0) +static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define negr(r0,r1) LCGR(r0,r1) +# define comr(r0,r1) _comr(_jit,r0,r1) +static void _comr(jit_state_t*,jit_int32_t,jit_int32_t); +# define andr(r0,r1,r2) _andr(_jit,r0,r1,r2) +static void _andr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0) +static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define orr(r0,r1,r2) _orr(_jit,r0,r1,r2) +static void _orr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ori(r0,r1,i0) _ori(_jit,r0,r1,i0) +static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define xorr(r0,r1,r2) _xorr(_jit,r0,r1,r2) +static void _xorr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define xori(r0,r1,i0) _xori(_jit,r0,r1,i0) +static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define htonr(r0,r1) movr(r0,r1) +# 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) +# define extr_i(r0,r1) LGFR(r0,r1) +# define extr_ui(r0,r1) LLGFR(r0,r1) +# define ldr_c(r0,r1) LGB(r0,0,0,r1) +# define ldi_c(r0,i0) _ldi_c(_jit,r0,i0) +static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_c(r0,r1,r2) _ldxr_c(_jit,r0,r1,r2) +static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0) +static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_uc(r0,r1) LLGC(r0,0,0,r1) +# define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0) +static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_uc(r0,r1,r2) _ldxr_uc(_jit,r0,r1,r2) +static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0) +static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_s(r0,r1) LGH(r0,0,0,r1) +# define ldi_s(r0,i0) _ldi_s(_jit,r0,i0) +static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_s(r0,r1,r2) _ldxr_s(_jit,r0,r1,r2) +static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0) +static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_us(r0,r1) LLGH(r0,0,0,r1) +# define ldi_us(r0,i0) _ldi_us(_jit,r0,i0) +static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_us(r0,r1,r2) _ldxr_us(_jit,r0,r1,r2) +static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0) +static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_i(r0,r1) LGF(r0,0,0,r1) +# define ldi_i(r0,i0) _ldi_i(_jit,r0,i0) +static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_i(r0,r1,r2) _ldxr_i(_jit,r0,r1,r2) +static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_i(r0,r1,i0) _ldxi_i(_jit,r0,r1,i0) +static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_ui(r0,r1) LLGF(r0,0,0,r1) +# define ldi_ui(r0,i0) _ldi_ui(_jit,r0,i0) +static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_ui(r0,r1,r2) _ldxr_ui(_jit,r0,r1,r2) +static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_ui(r0,r1,i0) _ldxi_ui(_jit,r0,r1,i0) +static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldr_l(r0,r1) LG(r0,0,0,r1) +# define ldi_l(r0,i0) _ldi_l(_jit,r0,i0) +static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_l(r0,r1,r2) _ldxr_l(_jit,r0,r1,r2) +static void _ldxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_l(r0,r1,i0) _ldxi_l(_jit,r0,r1,i0) +static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_c(r0,r1) STC(r1,0,0,r0) +# define sti_c(i0,r0) _sti_c(_jit,i0,r0) +static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_c(r0,r1,r2) _stxr_c(_jit,r0,r1,r2) +static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_c(i0,r0,r1) _stxi_c(_jit,i0,r0,r1) +static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define str_s(r0,r1) STH(r1,0,0,r0) +# define sti_s(i0,r0) _sti_s(_jit,i0,r0) +static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_s(r0,r1,r2) _stxr_s(_jit,r0,r1,r2) +static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_s(i0,r0,r1) _stxi_s(_jit,i0,r0,r1) +static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define str_i(r0,r1) ST(r1,0,0,r0) +# define sti_i(i0,r0) _sti_i(_jit,i0,r0) +static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_i(r0,r1,r2) _stxr_i(_jit,r0,r1,r2) +static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_i(i0,r0,r1) _stxi_i(_jit,i0,r0,r1) +static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define str_l(r0,r1) STG(r1,0,0,r0) +# define sti_l(i0,r0) _sti_l(_jit,i0,r0) +static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_l(r0,r1,r2) _stxr_l(_jit,r0,r1,r2) +static void _stxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1) +static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# 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 patch_at(instr,label) _patch_at(_jit,instr,label) +static void _patch_at(jit_state_t*,jit_word_t,jit_word_t); +#endif + +#if CODE +# define _us jit_uint16_t +# define _ui jit_uint32_t +static void +_E(jit_state_t *_jit, _ui Op) +{ + union { + struct { + _us op; + } b; + _us s; + } i0; + i0.b.op = Op; + assert(i0.b.op == Op); + is(i0.s); +} + +static void +_I(jit_state_t *_jit, _ui Op, _ui I) +{ + union { + struct { + _us op : 8; + _us i : 8; + } b; + _us s; + } i0; + i0.b.op = Op; + i0.b.i = I; + assert(i0.b.op == Op); + assert(i0.b.i == I); + is(i0.s); +} + +static void +_RR(jit_state_t *_jit, _ui Op, _ui R1, _ui R2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us r2 : 4; + } b; + _us s; + } i0; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.r2 = R2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.r2 == R2); + is(i0.s); +} + +static void +_RRE(jit_state_t *_jit, _ui Op, _ui R1, _ui R2) +{ + union { + struct { + _us op; + } b; + _us s; + } i0; + union { + struct { + _us _ : 8; + _us r1 : 4; + _us r2 : 4; + } b; + _us s; + } i1; + i0.b.op = Op; + i1.b._ = 0; + i1.b.r1 = R1; + i1.b.r2 = R2; + assert(i0.b.op == Op); + assert(i1.b.r1 == R1); + assert(i1.b.r2 == R2); + is(i0.s); + is(i1.s); +} + +static void +_RRF(jit_state_t *_jit, _ui Op, _ui R3, _ui M4, _ui R1, _ui R2) +{ + union { + struct { + _us op; + } b; + _us s; + } i0; + union { + struct { + _us r3 : 4; + _us m4 : 4; + _us r1 : 4; + _us r2 : 4; + } b; + _us s; + } i1; + i0.b.op = Op; + i1.b.r3 = R3; + i1.b.m4 = M4; + i1.b.r1 = R1; + i1.b.r2 = R2; + assert(i0.b.op == Op); + assert(i1.b.r3 == R3); + assert(i1.b.m4 == M4); + assert(i1.b.r1 == R1); + assert(i1.b.r2 == R2); + is(i0.s); + is(i1.s); +} + +static void +_RX(jit_state_t *_jit, _ui Op, _ui R1, _ui X2, _ui B2, _ui D2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us x2 : 4; + } b; + _us s; + } i0; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _us s; + } i1; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.x2 = X2; + i1.b.b2 = B2; + i1.b.d2 = D2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.x2 == X2); + assert(i1.b.b2 == B2); + assert(i1.b.d2 == D2); + is(i0.s); + is(i1.s); +} + +static void +_RXE(jit_state_t *_jit, _ui Op, _ui R1, _ui X2, _ui B2, _ui D2, _ui Op2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us x2 : 4; + } b; + _us s; + } i0; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _ui s; + } i1; + union { + struct { + _us _ : 8; + _us op : 8; + } b; + _us s; + } i2; + i2.b._ = 0; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.x2 = X2; + i1.b.b2 = B2; + i1.b.d2 = D2; + i2.b.op = Op2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.x2 == X2); + assert(i1.b.b2 == B2); + assert(i1.b.d2 == D2); + assert(i2.b.op == Op2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_RXF(jit_state_t *_jit, _ui Op, _ui R3, _ui X2, _ui B2, _ui D2, _ui R1, _ui Op2) +{ + union { + struct { + _us op : 8; + _us r3 : 4; + _us x2 : 4; + } b; + _us s; + } i0; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _us s; + } i1; + union { + struct { + _us r1 : 4; + _us _ : 4; + _us op : 8; + } b; + _us s; + } i2; + i2.b._ = 0; + i0.b.op = Op; + i0.b.r3 = R3; + i0.b.x2 = X2; + i1.b.b2 = B2; + i1.b.d2 = D2; + i2.b.r1 = R1; + i2.b.op = Op2; + assert(i0.b.op == Op); + assert(i0.b.r3 == R3); + assert(i0.b.x2 == X2); + assert(i1.b.b2 == B2); + assert(i1.b.d2 == D2); + assert(i2.b.r1 == R1); + assert(i2.b.op == Op2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_RXY(jit_state_t *_jit, _ui Op, _ui R1, _ui X2, _ui B2, _ui D2, _ui Op2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us x2 : 4; + } b; + _us s; + } i0; + union { + struct { + _us b2 : 4; + _us dl : 12; + } b; + _us s; + } i1; + union { + struct { + _us dh : 8; + _us op : 8; + } b; + _us s; + } i2; + i0.s = i1.s = i2.s = 0; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.x2 = X2; + i1.b.b2 = B2; + i1.b.dl = D2 & 0xfff; + i2.b.dh = D2 >> 12; + i2.b.op = Op2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.x2 == X2); + assert(i1.b.b2 == B2); + assert(i2.b.dh == D2 >> 12); + assert(i2.b.op == Op2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_RS(jit_state_t *_jit, _ui Op, _ui R1, _ui R3, _ui B2, _ui D2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us r3 : 4; + } b; + _us s; + } i0; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _us s; + } i1; + i0.s = i1.s = 0; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.r3 = R3; + i1.b.b2 = B2; + i1.b.d2 = D2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.r3 == R3); + assert(i1.b.b2 == B2); + assert(i1.b.d2 == D2); + is(i0.s); + is(i1.s); +} + +static void +_RSL(jit_state_t *_jit, _ui Op, _ui L1, _ui B1, _ui D1, _ui Op2) +{ + union { + struct { + _us op : 8; + _us l1 : 4; + _us _ : 4; + } b; + _us s; + } i0; + union { + struct { + _us b1 : 4; + _us d1 : 12; + } b; + _us s; + } i1; + union { + struct { + _us _ : 8; + _us op : 8; + } b; + _us s; + } i2; + i0.b._ = 0; + i2.b._ = 0; + i0.b.op = Op; + i0.b.l1 = L1; + i1.b.b1 = B1; + i1.b.d1 = D1; + i2.b.op = Op2; + assert(i0.b.op == Op); + assert(i0.b.l1 == L1); + assert(i1.b.b1 == B1); + assert(i1.b.d1 == D1); + assert(i2.b.op == Op2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_RSI(jit_state_t *_jit, _ui Op, _ui R1, _ui R3, _ui I2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us r3 : 4; + } b; + _us s; + } i0; + union { + struct { + _us i2; + } b; + _us s; + } i1; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.r3 = R3; + i1.b.i2 = I2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.r3 == R3); + assert(i1.b.i2 == I2); + is(i0.s); + is(i1.s); +} + +static void +_RIE(jit_state_t *_jit, _ui Op, _ui R1, _ui R3, _ui I2, _ui Op2) +{ + union { + struct { + _us op : 8; + _us r1 : 4; + _us r3 : 4; + } b; + _us s; + } i0; + union { + struct { + _us i2; + } b; + _us s; + } i1; + union { + struct { + _us _ : 8; + _us op : 8; + } b; + _us s; + } i2; + i2.b._ = 0; + i0.b.op = Op; + i0.b.r1 = R1; + i0.b.r3 = R3; + i1.b.i2 = I2; + i2.b.op = Op2; + assert(i0.b.op == Op); + assert(i0.b.r1 == R1); + assert(i0.b.r3 == R3); + assert(i1.b.i2 == I2); + assert(i2.b.op == Op2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_RIL(jit_state_t *_jit, _ui Op, _ui R1, _ui Op2, _ui I2) +{ + union { + struct { + _us o1 : 8; + _us r1 : 4; + _us o2 : 4; + } b; + _us s; + } i0; + union { + struct { + _ui ih : 16; + _ui il : 16; + } b; + _ui i; + } i12; + i0.b.o1 = Op; + i0.b.r1 = R1; + i0.b.o2 = Op2; + i12.i = I2; + assert(i0.b.o1 == Op); + assert(i0.b.r1 == R1); + assert(i0.b.o2 == Op2); + is(i0.s); + is(i12.b.ih); + is(i12.b.il); +} + +static void +_SI(jit_state_t *_jit, _ui Op, _ui I2, _ui B1, _ui D1) +{ + union { + struct { + _us op : 8; + _us i2 : 8; + } b; + _us s; + } i0; + union { + struct { + _us b1 : 4; + _us d1 : 12; + } b; + _us s; + } i1; + i0.b.op = Op; + i0.b.i2 = I2; + i1.b.b1 = B1; + i1.b.d1 = D1; + assert(i0.b.op == Op); + assert(i0.b.i2 == I2); + assert(i1.b.b1 == B1); + assert(i1.b.d1 == D1); + is(i0.s); + is(i1.s); +} + +static void +_SIY(jit_state_t *_jit, _ui Op, _ui I2, _ui B1, _ui D1, _ui Op2) +{ + union { + struct { + _us op : 8; + _us i2 : 8; + } b; + _us s; + } i0; + union { + struct { + _us b1 : 4; + _us dl : 12; + } b; + _us s; + } i1; + union { + struct { + _us dh : 8; + _us op : 8; + } b; + _us s; + } i2; + i0.b.op = Op; + i0.b.i2 = I2; + i1.b.b1 = B1; + i1.b.dl = D1 & 0xfff; + i2.b.dh = D1 >> 8; + i2.b.op = Op2; + assert(i0.b.op == Op); + assert(i0.b.i2 == I2); + assert(i1.b.b1 == B1); + assert(i2.b.dh == D1 >> 8); + assert(i2.b.op == Op2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_S(jit_state_t *_jit, _ui Op, _ui B2, _ui D2) +{ + union { + struct { + _us op; + } b; + _us s; + } i0; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _us s; + } i1; + i0.b.op = Op; + i1.b.b2 = B2; + i1.b.d2 = D2; + assert(i0.b.op == Op); + assert(i1.b.b2 == B2); + assert(i1.b.d2 == D2); + is(i0.s); + is(i1.s); +} + +static void +_SS(jit_state_t *_jit, _ui Op, _ui LL, _ui LH, _ui B1, _ui D1, _ui B2, _ui D2) +{ + union { + struct { + _us op : 8; + _us ll : 4; + _us lh : 4; + } b; + _us s; + } i0; + union { + struct { + _us b1 : 4; + _us d1 : 12; + } b; + _us s; + } i1; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _us s; + } i2; + i0.b.op = Op; + i0.b.ll = LL; + i0.b.lh = LH; + i1.b.b1 = B1; + i1.b.d1 = D1; + i2.b.b2 = B2; + i2.b.d2 = D2; + assert(i0.b.op == Op); + assert(i0.b.ll == LL); + assert(i0.b.lh == LH); + assert(i1.b.b1 == B1); + assert(i1.b.d1 == D1); + assert(i2.b.b2 == B2); + assert(i2.b.d2 == D2); + is(i0.s); + is(i1.s); + is(i2.s); +} + +static void +_SSE(jit_state_t *_jit, _ui Op, _ui B1, _ui D1, _ui B2, _ui D2) +{ + union { + struct { + _us op; + } b; + _us s; + } i0; + union { + struct { + _us b1 : 4; + _us d1 : 12; + } b; + _us s; + } i1; + union { + struct { + _us b2 : 4; + _us d2 : 12; + } b; + _us s; + } i2; + i0.b.op = Op; + i1.b.b1 = B1; + i1.b.d1 = D1; + i2.b.b2 = B2; + i2.b.d2 = D2; + assert(i0.b.op == Op); + assert(i1.b.b1 == B1); + assert(i1.b.d1 == D1); + assert(i2.b.b2 == B2); + assert(i2.b.d2 == D2); + is(i0.s); + is(i1.s); + is(i2.s); +} +# undef _us +# undef _ui + +static void +_nop(jit_state_t *_jit, jit_int32_t c) +{ + assert(c >= 0 && !(c & 1)); + while (c) { + NOPR(_R7_REGNO); + c -= 2; + } +} + +static jit_int32_t +_xdivr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t regno; + regno = jit_get_reg_pair(); + movr(rn(regno) + 1, r0); + DSGR(rn(regno), r1); + jit_unget_reg_pair(regno); + return (regno); +} + +static jit_int32_t +_xdivr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t regno; + regno = jit_get_reg_pair(); + movr(rn(regno) + 1, r0); + LGHI(rn(regno), 0); + DLGR(rn(regno), r1); + jit_unget_reg_pair(regno); + return (regno); +} + +static jit_int32_t +_xdivi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + /* overlap */ + jit_int32_t regno; + regno = jit_get_reg_pair(); + movr(rn(regno) + 1, r0); + movi(rn(regno), i0); + DSGR(rn(regno), rn(regno)); + jit_unget_reg_pair(regno); + return (regno); +} + +static jit_int32_t +_xdivi_u(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + /* cannot overlap because operand is 128-bit */ + jit_int32_t imm, regno; + regno = jit_get_reg_pair(); + imm = jit_get_reg(jit_class_gpr); + movr(rn(regno) + 1, r0); + LGHI(rn(regno), 0); + movi(rn(imm), i0); + DLGR(rn(regno), rn(imm)); + jit_unget_reg(imm); + jit_unget_reg_pair(regno); + return (regno); +} + +static void +_crr(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t reg, rg; + if (r0 == r1 || r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + rg = rn(reg); + } + else + rg = r0; + LGHI(rg, 1); + CGR(r1, r2); + w = _jit->pc.w; + BRC(cc, 0); + LGHI(rg, 0); + patch_at(w, _jit->pc.w); + if (r0 == r1 || r0 == r2) { + movr(r0, rg); + jit_unget_reg(reg); + } +} + +static void +_cri(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + crr(cc, r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_crr_u(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t reg, rg; + if (r0 == r1 || r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + rg = rn(reg); + } + else + rg = r0; + LGHI(rg, 1); + CLGR(r1, r2); + w = _jit->pc.w; + BRC(cc, 0); + LGHI(rg, 0); + patch_at(w, _jit->pc.w); + if (r0 == r1 || r0 == r2) { + movr(r0, rg); + jit_unget_reg(reg); + } +} + +static void +_cri_u(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + crr_u(cc, r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_brr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + CGR(r0, r1); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(cc, x16(d)); + else { + assert(s32_p(d)); + BRCL(cc, d); + } +} + +static jit_word_t +_brr_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CGR(r0, r1); + w = _jit->pc.w; + BRCL(cc, 0); + return (w); +} + +static void +_bri(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + brr(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static jit_word_t +_bri_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + w = brr_p(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_brr_u(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + CLGR(r0, r1); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(cc, x16(d)); + else { + assert(s32_p(d)); + BRCL(cc, d); + } +} + +static jit_word_t +_brr_u_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CLGR(r0, r1); + w = _jit->pc.w; + BRCL(cc, 0); + return (w); +} + +static void +_bri_u(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + brr_u(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static jit_word_t +_bri_u_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + w = brr_u_p(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_baddr(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + if (s) AGR(r0, r1); + else ALGR(r0, r1); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(c, x16(d)); + else { + assert(s32_p(d)); + BRCL(c, d); + } +} + +static void +_baddi(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + baddr(c, s, i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static jit_word_t +_baddr_p(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + if (s) AGR(r0, r1); + else ALGR(r0, r1); + d = (i0 - _jit->pc.w) >> 1; + w = _jit->pc.w; + BRCL(c, d); + return (w); +} + +static jit_word_t +_baddi_p(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + w = baddr_p(c, s, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_bsubr(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + if (s) SGR(r0, r1); + else SLGR(r0, r1); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(c, x16(d)); + else { + assert(s32_p(d)); + BRCL(c, d); + } +} + +static void +_bsubi(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + bsubr(c, s, i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static jit_word_t +_bsubr_p(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d, w; + if (s) SGR(r0, r1); + else SLGR(r0, r1); + d = (i0 - _jit->pc.w) >> 1; + w = _jit->pc.w; + BRCL(c, d); + return (w); +} + +static jit_word_t +_bsubi_p(jit_state_t *_jit, jit_int32_t c, jit_bool_t s, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + w = bsubr_p(c, s, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_bmxr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r0); + NGR(rn(reg), r1); + LTGR(rn(reg), rn(reg)); + jit_unget_reg(reg); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(cc, x16(d)); + else { + assert(s32_p(d)); + BRCL(cc, d); + } +} + +static jit_word_t +_bmxr_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r0); + NGR(rn(reg), r1); + LTGR(rn(reg), rn(reg)); + jit_unget_reg(reg); + w = _jit->pc.w; + BRCL(cc, 0); + return (w); +} + +static void +_bmxi(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t d; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + NGR(rn(reg), r0); + LTGR(rn(reg), rn(reg)); + jit_unget_reg(reg); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(cc, x16(d)); + else { + assert(s32_p(d)); + BRCL(cc, d); + } +} + +static jit_word_t +_bmxi_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i1); + NGR(rn(reg), r0); + LTGR(rn(reg), rn(reg)); + jit_unget_reg(reg); + w = _jit->pc.w; + BRCL(cc, 0); + return (w); +} + +static void +_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + LGR(r0, r1); +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t d; + jit_int32_t bits; + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(i0)) LGHI(r0, x16(i0)); + /* easy way of loading a large amount of 32 bit values and + * usually address of constants */ + else if (!(i0 & 1) && s32_p(d)) + LARL(r0, d); + 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)); + } +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + w = _jit->pc.w; + IILL(r0, x16(i0)); + IILH(r0, x16((jit_uword_t)i0 >> 16)); + IIHL(r0, x16((jit_uword_t)i0 >> 32)); + IIHH(r0, x16((jit_uword_t)i0 >> 48)); + return (w); +} + +static void +_addr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + AGR(r0, r1); + else { + movr(r0, r1); + AGR(r0, r2); + } +} + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (r0 == r1 && s16_p(i0)) + AGHI(r0, x16(i0)); + else if (s20_p(i0)) + LAY(r0, x20(i0), 0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + ALGR(r0, r1); + else { + movr(r0, r1); + ALGR(r0, r2); + } +} + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addcr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + ALCGR(r0, r1); + else { + movr(r0, r1); + ALCGR(r0, r2); + } +} + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addxr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r2); + movr(r0, r1); + SGR(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr(r0, r1); + SGR(r0, r2); + } +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (r0 == r1 && s16_p(i0)) + AGHI(r0, x16(-i0)); + else if (s20_p(i0)) + LAY(r0, x20(-i0), 0, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r2); + movr(r0, r1); + SLGR(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr(r0, r1); + SLGR(r0, r2); + } +} + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subcr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), r2); + movr(r0, r1); + SLBGR(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr(r0, r1); + SLBGR(r0, r2); + } +} + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subxr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_mulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + MSGR(r0, r1); + else { + movr(r0, r1); + MSGR(r0, r2); + } +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s16_p(i0)) { + movr(r0, r1); + MGHI(r0, x16(i0)); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + mulr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_qmulr(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t reg; + /* The only invalid condition is r0 == r1 */ + jit_int32_t t2, t3, s2, s3; + if (r2 == r0 || r2 == r1) { + s2 = jit_get_reg(jit_class_gpr); + t2 = rn(s2); + movr(t2, r2); + } + else + t2 = r2; + if (r3 == r0 || r3 == r1) { + s3 = jit_get_reg(jit_class_gpr); + t3 = rn(s3); + movr(t3, r3); + } + else + t3 = r3; + qmulr_u(r0, r1, r2, r3); + reg = jit_get_reg(jit_class_gpr); + /**/ + rshi(rn(reg), t2, 63); + mulr(rn(reg), rn(reg), t3); + addr(r1, r1, rn(reg)); + /**/ + rshi(rn(reg), t3, 63); + mulr(rn(reg), rn(reg), t2); + addr(r1, r1, rn(reg)); + jit_unget_reg(reg); + if (t2 != r2) + jit_unget_reg(s2); + if (t3 != r3) + jit_unget_reg(s3); +} + +static void +_qmuli(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + qmulr(r0, r1, r2, rn(reg)); + jit_unget_reg(reg); +} + +static void +_qmulr_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t regno; + regno = jit_get_reg_pair(); + movr(rn(regno) + 1, r2); + MLGR(rn(regno), r3); + movr(r0, rn(regno) + 1); + movr(r1, rn(regno)); + jit_unget_reg_pair(regno); +} + +static void +_qmuli_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t regno; + regno = jit_get_reg_pair(); + movr(rn(regno) + 1, r2); + movi(rn(regno), i0); + MLGR(rn(regno), rn(regno)); + movr(r0, rn(regno) + 1); + movr(r1, rn(regno)); + jit_unget_reg_pair(regno); +} + +static void +_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t regno; + regno = xdivr(r1, r2); + movr(r0, rn(regno) + 1); +} + +static void +_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t regno; + regno = xdivi(r1, i0); + movr(r0, rn(regno) + 1); +} + +static void +_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t regno; + regno = xdivr_u(r1, r2); + movr(r0, rn(regno) + 1); +} + +static void +_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t regno; + regno = xdivi_u(r1, i0); + movr(r0, rn(regno) + 1); +} + +static void +_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t regno; + regno = xdivr(r1, r2); + movr(r0, rn(regno)); +} + +static void +_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t regno; + regno = xdivi(r1, i0); + movr(r0, rn(regno)); +} + +static void +_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t regno; + regno = xdivr_u(r1, r2); + movr(r0, rn(regno)); +} + +static void +_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t regno; + regno = xdivi_u(r1, i0); + movr(r0, rn(regno)); +} + +static void +_qdivr(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t regno; + regno = xdivr(r2, r3); + movr(r0, rn(regno) + 1); + movr(r1, rn(regno)); +} + +static void +_qdivi(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t regno; + regno = xdivi(r2, i0); + movr(r0, rn(regno) + 1); + movr(r1, rn(regno)); +} + +static void +_qdivr_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t regno; + regno = xdivr_u(r2, r3); + movr(r0, rn(regno) + 1); + movr(r1, rn(regno)); +} + +static void +_qdivi_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t regno; + regno = xdivi_u(r2, i0); + movr(r0, rn(regno) + 1); + movr(r1, rn(regno)); +} + +static void +_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + lshr(r0, r1, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +static void +_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + rshr(r0, r1, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +static void +_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + rshr_u(r0, r1, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +static void +_comr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), -1); + movr(r0, r1); + XGR(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_andr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + NGR(r0, r1); + else { + movr(r0, r1); + NGR(r0, r2); + } +} + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(r0, r1); + NILL(r0, x16(i0)); + NILH(r0, x16((jit_uword_t)i0 >> 16)); + NIHL(r0, x16((jit_uword_t)i0 >> 32)); + NIHH(r0, x16((jit_uword_t)i0 >> 48)); +} + +static void +_orr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + OGR(r0, r1); + else { + movr(r0, r1); + OGR(r0, r2); + } +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(r0, r1); + OILL(r0, x16(i0)); + OILH(r0, x16((jit_uword_t)i0 >> 16)); + OIHL(r0, x16((jit_uword_t)i0 >> 32)); + OIHH(r0, x16((jit_uword_t)i0 >> 48)); +} + +static void +_xorr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + XGR(r0, r1); + else { + movr(r0, r1); + XGR(r0, r2); + } +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + xorr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_c(r0, r0); +} + +static void +_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + AGR(r0, r1); + ldr_c(r0, r0); + } + else { + movr(r0, r1); + AGR(r0, r2); + ldr_c(r0, r0); + } +} + +static void +_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s20_p(i0)) + LGB(r0, x20(i0), 0, r1); + else if (r0 != r1) { + movi(r0, i0); + AGR(r0, r1); + ldr_c(r0, r0); + } + else { + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + AGR(rn(reg), r1); + ldr_c(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_uc(r0, r0); +} + +static void +_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + AGR(r0, r1); + ldr_uc(r0, r0); + } + else { + movr(r0, r1); + AGR(r0, r2); + ldr_uc(r0, r0); + } +} + +static void +_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s20_p(i0)) + LLGC(r0, x20(i0), 0, r1); + else if (r0 != r1) { + movi(r0, i0); + AGR(r0, r1); + ldr_uc(r0, r0); + } + else { + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + AGR(rn(reg), r1); + ldr_uc(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_s(r0, r0); +} + +static void +_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + AGR(r0, r1); + ldr_s(r0, r0); + } + else { + movr(r0, r1); + AGR(r0, r2); + ldr_s(r0, r0); + } +} + +static void +_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s20_p(i0)) + LGH(r0, x20(i0), 0, r1); + else if (r0 != r1) { + movi(r0, i0); + AGR(r0, r1); + ldr_s(r0, r0); + } + else { + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + AGR(rn(reg), r1); + ldr_s(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_us(r0, r0); +} + +static void +_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + AGR(r0, r1); + ldr_us(r0, r0); + } + else { + movr(r0, r1); + AGR(r0, r2); + ldr_us(r0, r0); + } +} + +static void +_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s20_p(i0)) + LLGH(r0, x20(i0), 0, r1); + else if (r0 != r1) { + movi(r0, i0); + AGR(r0, r1); + ldr_us(r0, r0); + } + else { + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + AGR(rn(reg), r1); + ldr_us(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_i(r0, r0); +} + +static void +_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + AGR(r0, r1); + ldr_i(r0, r0); + } + else { + movr(r0, r1); + AGR(r0, r2); + ldr_i(r0, r0); + } +} + +static void +_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s20_p(i0)) + LGF(r0, x20(i0), 0, r1); + else if (r0 != r1) { + movi(r0, i0); + AGR(r0, r1); + ldr_i(r0, r0); + } + else { + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + AGR(rn(reg), r1); + ldr_i(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_ui(r0, r0); +} + +static void +_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + AGR(r0, r1); + ldr_ui(r0, r0); + } + else { + movr(r0, r1); + AGR(r0, r2); + ldr_ui(r0, r0); + } +} + +static void +_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s20_p(i0)) + LLGF(r0, x20(i0), 0, r1); + else if (r0 != r1) { + movi(r0, i0); + AGR(r0, r1); + ldr_ui(r0, r0); + } + else { + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + AGR(rn(reg), r1); + ldr_ui(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + movi(r0, i0); + ldr_l(r0, r0); +} + +static void +_ldxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) { + AGR(r0, r1); + ldr_l(r0, r0); + } + else { + movr(r0, r1); + AGR(r0, r2); + ldr_l(r0, r0); + } +} + +static void +_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (s20_p(i0)) + LG(r0, x20(i0), 0, r1); + else if (r0 != r1) { + movi(r0, i0); + AGR(r0, r1); + ldr_l(r0, r0); + } + else { + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + AGR(rn(reg), r1); + ldr_l(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + str_c(rn(reg), r0); + jit_unget_reg_but_zero(reg); +} + +static void +_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movr(rn(reg), r0); + AGR(rn(reg), r1); + str_c(rn(reg), r2); + jit_unget_reg_but_zero(reg); +} + +static void +_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (u12_p(i0)) + STC(r1, i0, 0, r0); + else if (s20_p(i0)) + STCY(r1, x20(i0), 0, r0); + else { + reg = jit_get_reg_but_zero(); + addi(rn(reg), r0, i0); + str_c(rn(reg), r1); + jit_unget_reg_but_zero(reg); + } +} + +static void +_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + str_s(rn(reg), r0); + jit_unget_reg_but_zero(reg); +} + +static void +_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movr(rn(reg), r0); + AGR(rn(reg), r1); + str_s(rn(reg), r2); + jit_unget_reg_but_zero(reg); +} + +static void +_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (u12_p(i0)) + STH(r1, i0, 0, r0); + else if (s20_p(i0)) + STHY(r1, x20(i0), 0, r0); + else { + reg = jit_get_reg_but_zero(); + addi(rn(reg), r0, i0); + str_s(r1, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + str_i(rn(reg), r0); + jit_unget_reg_but_zero(reg); +} + +static void +_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movr(rn(reg), r0); + AGR(rn(reg), r1); + str_i(rn(reg), r2); + jit_unget_reg_but_zero(reg); +} + +static void +_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (u12_p(i0)) + ST(r1, i0, 0, r0); + else if (s20_p(i0)) + STY(r1, x20(i0), 0, r0); + else { + reg = jit_get_reg_but_zero(); + addi(rn(reg), r0, i0); + str_i(rn(reg), r1); + jit_unget_reg_but_zero(reg); + } +} + +static void +_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + str_l(rn(reg), r0); + jit_unget_reg_but_zero(reg); +} + +static void +_stxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movr(rn(reg), r0); + AGR(rn(reg), r1); + str_l(rn(reg), r2); + jit_unget_reg_but_zero(reg); +} + +static void +_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (s20_p(i0)) + STG(r1, x20(i0), 0, r0); + else { + reg = jit_get_reg_but_zero(); + addi(rn(reg), r0, i0); + str_l(rn(reg), r1); + jit_unget_reg_but_zero(reg); + } +} + +static void +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t d; + jit_int32_t reg; + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + J(x16(d)); + else if (s32_p(d)) + BRL(d); + else { + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static jit_word_t +_jmpi_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + w = movi_p(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg_but_zero(reg); + return (w); +} + +static void +_calli(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t d; + jit_int32_t reg; + d = (i0 - _jit->pc.w) >> 1; + if (s32_p(d)) + BRASL(_R14_REGNO, d); + else { + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + callr(rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + w = movi_p(rn(reg), i0); + callr(rn(reg)); + jit_unget_reg_but_zero(reg); + return (w); +} + +static jit_int32_t gprs[] = { + _R6, _R7, _R8, _R9, _R10, _R11, _R12, _R13 +}; + +static void +_prolog(jit_state_t *_jit, jit_node_t *i0) +{ + jit_int32_t regno, offset; + _jitc->function->stack = ((_jitc->function->self.alen - + /* align stack at 8 bytes */ + _jitc->function->self.aoff) + 7) & -8; + /* 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. + */ + for (regno = 0; regno < jit_size(gprs) - 1; regno++) { + if (jit_regset_tstbit(&_jitc->function->regset, gprs[regno])) + break; + } + offset = regno * 8 + 48; + STMG(rn(gprs[regno]), _R15_REGNO, x20(offset), _R15_REGNO); +#define SPILL(R, O) \ + do { \ + if (jit_regset_tstbit(&_jitc->function->regset, R)) \ + stxi_d(O, _R15_REGNO, rn(R)); \ + } while (0) + /* First 4 in low address */ + SPILL(_F10, 16); + SPILL(_F11, 24); + SPILL(_F12, 32); + SPILL(_F13, 48); + /* Last 4 in high address */ + SPILL(_F10, 128); + SPILL(_F11, 136); + SPILL(_F12, 144); + SPILL(_F13, 152); +#undef SPILL + LGR(_R13_REGNO, _R15_REGNO); + subi(_R15_REGNO, _R15_REGNO, stack_framesize + _jitc->function->stack); +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *i0) +{ + jit_int32_t regno, offset; + for (regno = 0; regno < jit_size(gprs) - 1; regno++) { + if (jit_regset_tstbit(&_jitc->function->regset, gprs[regno])) + break; + } + offset = regno * 8 + 48; + LGR(_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) + LOAD(_F10, 16); + LOAD(_F11, 24); + LOAD(_F12, 32); + LOAD(_F13, 48); + LOAD(_F10, 128); + LOAD(_F11, 136); + LOAD(_F12, 144); + LOAD(_F13, 152); +#undef LOAD + LMG(rn(gprs[regno]), _R15_REGNO, x20(offset), _R15_REGNO); + BR(_R14_REGNO); +} + +static void +_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label) +{ + jit_word_t d; + union { + jit_uint16_t *s; + jit_word_t w; + } u; + u.w = instr; + union { + struct { + jit_uint16_t op : 8; + jit_uint16_t r1 : 4; + jit_uint16_t r3 : 4; + } b; + jit_uint16_t s; + } i0; + union { + struct { + jit_uint16_t i2; + } b; + jit_uint16_t s; + } i1; + union { + struct { + jit_uint32_t ih : 16; + jit_uint32_t il : 16; + } b; + jit_uint32_t i; + } i12; + i0.s = u.s[0]; + /* movi_p */ + if (i0.b.op == 0xA5) { + assert(i0.b.r3 == 3); + 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; + 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; + } + /* BRC */ + else if (i0.b.op == 0xA7) { + assert(i0.b.r3 == 0x4); + d = (label - instr) >> 1; + assert(s16_p(d)); + i1.b.i2 = d; + u.s[1] = i1.s; + } + /* BRCL */ + else if (i0.b.op == 0xC0) { + assert(i0.b.r3 == 0x4); + d = (label - instr) >> 1; + assert(s32_p(d)); + i12.i = d; + u.s[1] = i12.b.ih; + u.s[2] = i12.b.il; + } + else + abort(); +} +#endif diff --git a/lib/jit_s390x-fpu.c b/lib/jit_s390x-fpu.c new file mode 100644 index 000000000..750f058d6 --- /dev/null +++ b/lib/jit_s390x-fpu.c @@ -0,0 +1,1198 @@ +/* + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software 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 General Public License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# define RND_CUR 0 +# define RND_BIAS_NEAR 1 +# define RND_NEAR 4 +# define RND_ZERO 5 +# define RND_POS_INF 6 +# define RND_NEG_INF 7 +/**************************************************************** + * Floating Point Instructions * + ****************************************************************/ +/* CONVERT BFP TO HFP */ +# define THDER(R1,R2) RRE_(0xB358,R1,R2) +# define THDR(R1,R2) RRE_(0xB359,R1,R2) +/* CONVERT HFP TO BFP */ +# define TBEDR(R1,R2) RRE_(0xB350,R1,R2) +# define TBDR(R1,R2) RRE_(0xB351,R1,R2) +/* LOAD */ +# define LER(R1,R2) RR_(0x38,R1,R2) +# define LDR(R1,R2) RR_(0x28,R1,R2) +# define LXR(R1,R2) RRE_(0xB365,R1,R2) +# define LE(R1,D2,X2,B2) RX_(0x78,R1,X2,B2,D2) +# define LD(R1,D2,X2,B2) RX_(0x68,R1,X2,B2,D2) +# define LEY(R1,D2,X2,B2) RXY_(0xED,R1,X2,B2,D2,0x64) +# define LDY(R1,D2,X2,B2) RXY_(0xED,R1,X2,B2,D2,0x65) +/* LOAD ZERO */ +# define LZER(R1) RRE_(0xB374,R1,0) +# define LZDR(R1) RRE_(0xB375,R1,0) +# define LZXR(R1) RRE_(0xB376,R1,0) +/* STORE */ +# define STE(R1,D2,X2,B2) RX_(0x70,R1,X2,B2,D2) +# define STD(R1,D2,X2,B2) RX_(0x60,R1,X2,B2,D2) +# define STEY(R1,D2,X2,B2) RXY_(0xED,R1,X2,B2,D2,0x66) +# define STDY(R1,D2,X2,B2) RXY_(0xED,R1,X2,B2,D2,0x67) +/**************************************************************** + * Hexadecimal Floating Point Instructions * + ****************************************************************/ +/* ADD NORMALIZED */ +# define AER(R1,R2) RR_(0x3A,R1,R2) +# define ADR(R1,R2) RR_(0x2A,R1,R2) +# define AXR(R1,R2) RR_(0x36,R1,R2) +# define AE(R1,D2,X2,B2) RX_(0x7A,R1,X2,B2,D2) +# define AD(R1,D2,X2,B2) RX_(0x6A,R1,X2,B2,D2) +/* ADD UNNORMALIZED */ +# define AUR(R1,R2) RR_(0x3E,R1,R2) +# define AWR(R1,R2) RR_(0x2E,R1,R2) +# define AU(R1,D2,X2,B2) RX_(0x7E,R1,X2,B2,D2) +# define AW(R1,D2,X2,B2) RX_(0x6E,R1,X2,B2,D2) +/* COMPARE */ +# define CER(R1,R2) RR_(0x39,R1,R2) +# define CDR(R1,R2) RR_(0x29,R1,R2) +# define CXR(R1,R2) RRE_(0xB369,R1,R2) +# define CE(R1,D2,X2,B2) RX_(0x79,R1,X2,B2,D2) +# define CD(R1,D2,X2,B2) RX_(0x69,R1,X2,B2,D2) +/* CONVERT FROM FIXED */ +# define CEFR(R1,R2) RRE_(0xB3B4,R1,R2) +# define CDFR(R1,R2) RRE_(0xB3B5,R1,R2) +# define CXFR(R1,R2) RRE_(0xB3B6,R1,R2) +# define CEGR(R1,R2) RRE_(0xB3C4,R1,R2) +# define CDGR(R1,R2) RRE_(0xB3C5,R1,R2) +# define CXGR(R1,R2) RRE_(0xB3C6,R1,R2) +/* CONVERT TO FIXED */ +# define CFER(R1,R2) RRE_(0xB3B8,R1,R2) +# define CFDR(R1,R2) RRE_(0xB3B9,R1,R2) +# define CFXR(R1,R2) RRE_(0xB3BA,R1,R2) +# define CGER(R1,R2) RRE_(0xB3C8,R1,R2) +# define CGDR(R1,R2) RRE_(0xB3C9,R1,R2) +# define CGXR(R1,R2) RRE_(0xB3CA,R1,R2) +/* DIVIDE */ +# define DER(R1,R2) RR_(0x3D,R1,R2) +# define DDR(R1,R2) RR_(0x2D,R1,R2) +# define DXR(R1,R2) RRE_(0xB22D,R1,R2) +# define DE(R1,D2,X2,B2) RX_(0x7D,R1,X2,B2,D2) +# define DD(R1,D2,X2,B2) RX_(0x6D,R1,X2,B2,D2) +/* HALVE */ +# define HER(R1,R2) RR_(0x34,R1,R2) +# define HDR(R1,R2) RR_(0x24,R1,R2) +/* LOAD AND TEST */ +# define LTER(R1,R2) RR_(0x32,R1,R2) +# define LTDR(R1,R2) RR_(0x22,R1,R2) +# define LTXR(R1,R2) RRE_(0xB362,R1,R2) +/* LOAD COMPLEMENT */ +# define LCER(R1,R2) RR_(0x33,R1,R2) +# define LCDR(R1,R2) RR_(0x23,R1,R2) +# define LCXR(R1,R2) RRE_(0xB363,R1,R2) +/* LOAD FP INTEGER */ +# define FIER(R1,R2) RRE_(0xB377,R1,R2) +# define FIDR(R1,R2) RRE_(0xB37F,R1,R2) +# define FIXR(R1,R2) RRE_(0xB367,R1,R2) +/* LOAD LENGHTENED */ +# define LDER(R1,R2) RRE_(0xB324,R1,R2) +# define LXDR(R1,R2) RRE_(0xB325,R1,R2) +# define LXER(R1,R2) RRE_(0xB326,R1,R2) +# define LDE(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x24) +# define LXD(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x25) +# define LXE(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x26) +/* LOAD NEGATIVE */ +# define LNER(R1,R2) RR_(0x31,R1,R2) +# define LNDR(R1,R2) RR_(0x21,R1,R2) +# define LNXR(R1,R2) RRE_(0xB361,R1,R2) +/* LOAD POSITIVE */ +# define LPER(R1,R2) RR_(0x30,R1,R2) +# define LPDR(R1,R2) RR_(0x20,R1,R2) +# define LPXR(R1,R2) RRE_(0xB360,R1,R2) +/* LOAD ROUNDED */ +# define LEDR(R1,R2) RR_(0x35,R1,R2) +# define LDXR(R1,R2) RR_(0x25,R1,R2) +# define LRER(R1,R2) LEDR(R1,R2) +# define LRDR(R1,R2) LDXR(R1,R2) +# define LRXR(R1,R2) RRE_(0xB366,R1,R2) +/* MULTIPLY */ +# define MEER(R1,R2) RRE_(0xB337,R1,R2) +# define MDR(R1,R2) RR_(0x2C,R1,R2) +# define MXR(R1,R2) RR_(0x26,R1,R2) +# define MDER(R1,R2) RR_(0x3C,R1,R2) +# define MXDR(R1,R2) RR_(0x27,R1,R2) +# define MER(R1,R2) MDER(R1,R2) +# define MEE(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x37) +# define MD(R1,D2,X2,B2) RX_(0x6C,R1,X2,B2,D2) +# define MDE(R1,D2,X2,B2) RX_(0x7C,R1,X2,B2,D2) +# define MXD(R1,D2,X2,B2) RX_(0x67,R1,X2,B2,D2) +# define ME(R1,D2,X2,B2) MDE(R1,D2,X2,B2) +/* MULTIPLY AND ADD */ +# define MAER(R1,R3,R2) RRF_(0xB32E,R1,0,R3,R2) +# define MADR(R1,R3,R2) RRF_(0xB33E,R1,0,R3,R2) +# define MAE(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x2E) +# define MAD(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x3E) +/* MULTIPLY AND SUBTRACT */ +# define MSER(R1,R3,R2) RRF_(0xB32F,R1,0,R3,R2) +# define MSDR(R1,R3,R2) RRF_(0xB33F,R1,0,R3,R2) +# define MSE(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x2F) +# define MSD(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x3F) +/* SQUARE ROOT */ +# define SQER(R1,R2) RRE_(0xB245,R1,R2) +# define SQDR(R1,R2) RRE_(0xB244,R1,R2) +# define SQXR(R1,R2) RRE_(0xB336,R1,R2) +# define SQE(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x34) +# define SQD(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x35) +/* SUBTRACT NORMALIZED */ +# define SER(R1,R2) RR_(0x3B,R1,R2) +# define SDR(R1,R2) RR_(0x2B,R1,R2) +# define SXR(R1,R2) RR_(0x37,R1,R2) +# define SE(R1,D2,X2,B2) RX_(0x7B,R1,X2,B2,D2) +# define SD(R1,D2,X2,B2) RX_(0x6B,R1,X2,B2,D2) +/* SUBTRACT UNNORMALIZED */ +# define SUR(R1,R2) RR_(0x3F,R1,R2) +# define SWR(R1,R2) RR_(0x2F,R1,R2) +# define SU(R1,D2,X2,B2) RX_(0x7F,R1,X2,B2,D2) +# define SW(R1,D2,X2,B2) RX_(0x6F,R1,X2,B2,D2) +/**************************************************************** + * Binary Floating Point Instructions * + ****************************************************************/ +/* ADD */ +# define AEBR(R1,R2) RRE_(0xB30A,R1,R2) +# define ADBR(R1,R2) RRE_(0xB31A,R1,R2) +# define AXBR(R1,R2) RRE_(0xB34A,R1,R2) +# define AEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x0A) +# define ADB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x1A) +/* COMPARE */ +# define CEBR(R1,R2) RRE_(0xB309,R1,R2) +# define CDBR(R1,R2) RRE_(0xB319,R1,R2) +# define CXBR(R1,R2) RRE_(0xB349,R1,R2) +# define CEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x09) +# define CDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x19) +/* COMPARE AND SIGNAL */ +# define KEBR(R1,R2) RRE_(0xB308,R1,R2) +# define KDBR(R1,R2) RRE_(0xB318,R1,R2) +# define KXBR(R1,R2) RRE_(0xB348,R1,R2) +# define KEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x08) +# define KDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x18) +/* CONVERT FROM FIXED */ +# define CEFBR(R1,R2) RRE_(0xB394,R1,R2) +# define CDFBR(R1,R2) RRE_(0xB395,R1,R2) +# define CXFBR(R1,R2) RRE_(0xB396,R1,R2) +# define CEGBR(R1,R2) RRE_(0xB3A4,R1,R2) +# define CDGBR(R1,R2) RRE_(0xB3A5,R1,R2) +# define CXGBR(R1,R2) RRE_(0xB3A6,R1,R2) +/* CONVERT TO FIXED */ +# define CFEBR(R1,M3,R2) RRF_(0xB398,M3,0,R1,R2) +# define CFDBR(R1,M3,R2) RRF_(0xB399,M3,0,R1,R2) +# define CFXBR(R1,M3,R2) RRF_(0xB39A,M3,0,R1,R2) +# define CGEBR(R1,M3,R2) RRF_(0xB3A8,M3,0,R1,R2) +# define CGDBR(R1,M3,R2) RRF_(0xB3A9,M3,0,R1,R2) +# define CGXBR(R1,M3,R2) RRF_(0xB3AA,M3,0,R1,R2) +/* DIVIDE */ +# define DEBR(R1,R2) RRE_(0xB30D,R1,R2) +# define DDBR(R1,R2) RRE_(0xB31D,R1,R2) +# define DXBR(R1,R2) RRE_(0xB34D,R1,R2) +# define DEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x0D) +# define DDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x1D) +/* DIVIDE TO INTEGER */ +# define DIEBR(R1,R3,R2,M4) RRF_(0xB353,R3,M4,R1,R2) +# define DIDBR(R1,R3,R2,M4) RRF_(0xB35B,R3,M4,R1,R2) +/* EXTRACT FPC */ +# define EFPC(R1) RRE_(0xB38C,R1,0) +/* LOAD AND TEST */ +# define LTEBR(R1,R2) RRE_(0xB302,R1,R2) +# define LTDBR(R1,R2) RRE_(0xB312,R1,R2) +# define LTXBR(R1,R2) RRE_(0xB342,R1,R2) +/* LOAD COMPLEMENT */ +# define LCEBR(R1,R2) RRE_(0xB303,R1,R2) +# define LCDBR(R1,R2) RRE_(0xB313,R1,R2) +# define LCXBR(R1,R2) RRE_(0xB343,R1,R2) +/* LOAD FP INTEGER */ +# define FIEBR(R1,M3,R2) RRF_(0xB357,M3,0,R1,R2) +# define FIDBR(R1,M3,R2) RRF_(0xB35F,M3,0,R1,R2) +# define FIXBR(R1,M3,R2) RRF_(0xB347,M3,0,R1,R2) +/* LOAD FPC */ +# define LFPC(D2,B2) S_(0xB29D,B2,D2) +/* LOAD LENGTHENED */ +# define LDEBR(R1,R2) RRE_(0xB304,R1,R2) +# define LXDBR(R1,R2) RRE_(0xB305,R1,R2) +# define LXEBR(R1,R2) RRE_(0xB306,R1,R2) +# define LDEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x04) +# define LXDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x05) +# define LXEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x06) +/* LOAD NEGATIVE */ +# define LNEBR(R1,R2) RRE_(0xB301,R1,R2) +# define LNDBR(R1,R2) RRE_(0xB311,R1,R2) +# define LNXBR(R1,R2) RRE_(0xB341,R1,R2) +/* LOAD POSITIVE */ +# define LPEBR(R1,R2) RRE_(0xB300,R1,R2) +# define LPDBR(R1,R2) RRE_(0xB310,R1,R2) +# define LPXBR(R1,R2) RRE_(0xB340,R1,R2) +/* LOAD ROUNDED */ +# define LEDBR(R1,R2) RRE_(0xB344,R1,R2) +# define LDXBR(R1,R2) RRE_(0xB345,R1,R2) +# define LEXBR(R1,R2) RRE_(0xB346,R1,R2) +/* MULTIPLY */ +# define MEEBR(R1,R2) RRE_(0xB317,R1,R2) +# define MDBR(R1,R2) RRE_(0xB31C,R1,R2) +# define MXBR(R1,R2) RRE_(0xB34C,R1,R2) +# define MDEBR(R1,R2) RRE_(0xB30C,R1,R2) +# define MXDBR(R1,R2) RRE_(0xB307,R1,R2) +# define MEEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x17) +# define MDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x1C) +# define MDEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x0C) +# define MXDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x07) +/* MULTIPLY AND ADD */ +# define MAEBR(R1,R3,R2) RRF_(0xB30E,R1,0,R3,R2) +# define MADBR(R1,R3,R2) RRF_(0xB31E,R1,0,R3,R2) +# define MAEB(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x0E) +# define MADB(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x1E) +/* MULTIPLY AND SUBTRACT */ +# define MSEBR(R1,R3,R2) RRF_(0xB30F,R1,0,R3,R2) +# define MSDBR(R1,R3,R2) RRF_(0xB31F,R1,0,R3,R2) +# define MSEB(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x0F) +# define MSDB(R1,R3,D2,X2,B2) RXF_(0xED,R3,X2,B2,D2,R1,0x1F) +/* SET FPC */ +# define SFPC(R1) RRE_(0xB384,R1,0) +/* SET ROUNDING MODE */ +# define SRNM(D2,B2) S_(0xB299,B2,D2) +/* SQUARE ROOT */ +# define SQEBR(R1,R2) RRE_(0xB314,R1,R2) +# define SQDBR(R1,R2) RRE_(0xB315,R1,R2) +# define SQXBR(R1,R2) RRE_(0xB316,R1,R2) +/* STORE FPC */ +# define STFPC(D2,B2) S_(0xB29C,B2,D2) +/* SUBTRACT */ +# define SEBR(R1,R2) RRE_(0xB30B,R1,R2) +# define SDBR(R1,R2) RRE_(0xB31B,R1,R2) +# define SXBR(R1,R2) RRE_(0xB34B,R1,R2) +# define SEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x0B) +# define SDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x1B) +/* TEST DATA CLASS */ +# define TCEB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x10) +# define TCDB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x11) +# define TCXB(R1,D2,X2,B2) RXE_(0xED,R1,X2,B2,D2,0x12) +# define fp(code,r0,r1,i0) _fp(_jit,jit_code_##code##i_f,r0,r1,i0) +static void _fp(jit_state_t*,jit_code_t, + jit_int32_t,jit_int32_t,jit_float32_t*); +# define dp(code,r0,r1,i0) _dp(_jit,jit_code_##code##i_d,r0,r1,i0) +static void _dp(jit_state_t*,jit_code_t, + jit_int32_t,jit_int32_t,jit_float64_t*); +# define fr(cc,r0,r1,r2) _fr(_jit,cc,r0,r1,r2) +static void _fr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define dr(cc,r0,r1,r2) _dr(_jit,cc,r0,r1,r2) +static void _dr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define fi(cc,r0,r1,i0) _fi(_jit,cc,r0,r1,i0) +static void _fi(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_float32_t*); +# define di(cc,r0,r1,i0) _di(_jit,cc,r0,r1,i0) +static void _di(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_float64_t*); +# define bfr(cc,i0,r0,r1) _bfr(_jit,cc,i0,r0,r1) +static void _bfr(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bdr(cc,i0,r0,r1) _bdr(_jit,cc,i0,r0,r1) +static void _bdr(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bfr_p(cc,i0,r0,r1) _bfr_p(_jit,cc,i0,r0,r1) +static jit_word_t _bfr_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bdr_p(cc,i0,r0,r1) _bdr_p(_jit,cc,i0,r0,r1) +static jit_word_t _bdr_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bfi(cc,i0,r0,i1) _bfi(_jit,cc,i0,r0,i1) +static void _bfi(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_float32_t*); +# define bdi(cc,i0,r0,i1) _bdi(_jit,cc,i0,r0,i1) +static void _bdi(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_float64_t*); +# define bfi_p(cc,i0,r0,i1) _bfi_p(_jit,cc,i0,r0,i1) +static jit_word_t _bfi_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_float32_t*); +# define bdi_p(cc,i0,r0,i1) _bdi_p(_jit,cc,i0,r0,i1) +static jit_word_t _bdi_p(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_float64_t*); +# define buneqr(db,i0,r0,r1) _buneqr(_jit,db,i0,r0,r1) +static jit_word_t _buneqr(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define buneqi(db,i0,r0,i1) _buneqi(_jit,db,i0,r0,(jit_word_t)i1) +static jit_word_t _buneqi(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define bltgtr(db,i0,r0,r1) _bltgtr(_jit,db,i0,r0,r1) +static jit_word_t _bltgtr(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_int32_t); +# define bltgti(db,i0,r0,i1) _bltgti(_jit,db,i0,r0,(jit_word_t)i1) +static jit_word_t _bltgti(jit_state_t*,jit_int32_t, + jit_word_t,jit_int32_t,jit_word_t); +# define movr_f(r0,r1) _movr_f(_jit,r0,r1) +static void _movr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi_f(r0,i0) _movi_f(_jit,r0,i0) +static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*); +# define movr_d(r0,r1) _movr_d(_jit,r0,r1) +static void _movr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi_d(r0,i0) _movi_d(_jit,r0,i0) +static void _movi_d(jit_state_t*,jit_int32_t,jit_float64_t*); +# define absr_f(r0,r1) LPEBR(r0,r1) +# define absr_d(r0,r1) LPDBR(r0,r1) +# define negr_f(r0,r1) LCEBR(r0,r1) +# define negr_d(r0,r1) LCDBR(r0,r1) +# define sqrtr_f(r0,r1) SQEBR(r0,r1) +# define sqrtr_d(r0,r1) SQDBR(r0,r1) +# define truncr_f_i(r0,r1) CFEBR(r0,RND_ZERO,r1) +# define truncr_d_i(r0,r1) CFDBR(r0,RND_ZERO,r1) +# define truncr_f_l(r0,r1) CGEBR(r0,RND_ZERO,r1) +# define truncr_d_l(r0,r1) CGDBR(r0,RND_ZERO,r1) +# define extr_f(r0,r1) CEGBR(r0,r1) +# define extr_d(r0,r1) CDGBR(r0,r1) +# define extr_d_f(r0,r1) LEDBR(r0,r1) +# define extr_f_d(r0,r1) LDEBR(r0,r1) +# define addr_f(r0,r1,r2) _addr_f(_jit,r0,r1,r2) +static void _addr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addi_f(r0,r1,i0) fp(add,r0,r1,i0) +# define addr_d(r0,r1,r2) _addr_d(_jit,r0,r1,r2) +static void _addr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addi_d(r0,r1,i0) dp(add,r0,r1,i0) +# define subr_f(r0,r1,r2) _subr_f(_jit,r0,r1,r2) +static void _subr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subi_f(r0,r1,i0) fp(sub,r0,r1,i0) +# define subr_d(r0,r1,r2) _subr_d(_jit,r0,r1,r2) +static void _subr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subi_d(r0,r1,i0) dp(sub,r0,r1,i0) +# define mulr_f(r0,r1,r2) _mulr_f(_jit,r0,r1,r2) +static void _mulr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define muli_f(r0,r1,i0) fp(mul,r0,r1,i0) +# define mulr_d(r0,r1,r2) _mulr_d(_jit,r0,r1,r2) +static void _mulr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define muli_d(r0,r1,i0) dp(mul,r0,r1,i0) +# define divr_f(r0,r1,r2) _divr_f(_jit,r0,r1,r2) +static void _divr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_f(r0,r1,i0) fp(div,r0,r1,i0) +# define divr_d(r0,r1,r2) _divr_d(_jit,r0,r1,r2) +static void _divr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_d(r0,r1,i0) dp(div,r0,r1,i0) +# define ldr_f(r0,r1) LE(r0,0,0,r1) +# define ldr_d(r0,r1) LD(r0,0,0,r1) +# define ldi_f(r0,i0) _ldi_f(_jit,r0,i0) +static void _ldi_f(jit_state_t*,jit_int32_t,jit_word_t); +# define ldi_d(r0,i0) _ldi_d(_jit,r0,i0) +static void _ldi_d(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_f(r0,r1,r2) _ldxr_f(_jit,r0,r1,r2) +static void _ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxr_d(r0,r1,r2) _ldxr_d(_jit,r0,r1,r2) +static void _ldxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_f(r0,r1,i0) _ldxi_f(_jit,r0,r1,i0) +static void _ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxi_d(r0,r1,i0) _ldxi_d(_jit,r0,r1,i0) +static void _ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_f(r0,r1) STE(r1,0,0,r0) +# define str_d(r0,r1) STD(r1,0,0,r0) +# define sti_f(i0,r0) _sti_f(_jit,i0,r0) +static void _sti_f(jit_state_t*,jit_word_t,jit_int32_t); +# define sti_d(i0,r0) _sti_d(_jit,i0,r0) +static void _sti_d(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_f(r0,r1,r2) _stxr_f(_jit,r0,r1,r2) +static void _stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxr_d(r0,r1,r2) _stxr_d(_jit,r0,r1,r2) +static void _stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_f(i0,r0,r1) _stxi_f(_jit,i0,r0,r1) +static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxi_d(i0,r0,r1) _stxi_d(_jit,i0,r0,r1) +static void _stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define ltr_f(r0,r1,r2) fr(CC_L,r0,r1,r2) +# define ltr_d(r0,r1,r2) dr(CC_L,r0,r1,r2) +# define lti_f(r0,r1,i0) fi(CC_L,r0,r1,i0) +# define lti_d(r0,r1,i0) di(CC_L,r0,r1,i0) +# define ler_f(r0,r1,r2) fr(CC_LE,r0,r1,r2) +# define ler_d(r0,r1,r2) dr(CC_LE,r0,r1,r2) +# define lei_f(r0,r1,i0) fi(CC_LE,r0,r1,i0) +# define lei_d(r0,r1,i0) di(CC_LE,r0,r1,i0) +# define eqr_f(r0,r1,r2) fr(CC_E,r0,r1,r2) +# define eqr_d(r0,r1,r2) dr(CC_E,r0,r1,r2) +# define eqi_f(r0,r1,i0) fi(CC_E,r0,r1,i0) +# define eqi_d(r0,r1,i0) di(CC_E,r0,r1,i0) +# define ger_f(r0,r1,r2) fr(CC_HE,r0,r1,r2) +# define ger_d(r0,r1,r2) dr(CC_HE,r0,r1,r2) +# define gei_f(r0,r1,i0) fi(CC_HE,r0,r1,i0) +# define gei_d(r0,r1,i0) di(CC_HE,r0,r1,i0) +# define gtr_f(r0,r1,r2) fr(CC_H,r0,r1,r2) +# define gtr_d(r0,r1,r2) dr(CC_H,r0,r1,r2) +# define gti_f(r0,r1,i0) fi(CC_H,r0,r1,i0) +# define gti_d(r0,r1,i0) di(CC_H,r0,r1,i0) +# define ner_f(r0,r1,r2) fr(CC_NE,r0,r1,r2) +# define ner_d(r0,r1,r2) dr(CC_NE,r0,r1,r2) +# define nei_f(r0,r1,i0) fi(CC_NE,r0,r1,i0) +# define nei_d(r0,r1,i0) di(CC_NE,r0,r1,i0) +# define unltr_f(r0,r1,r2) fr(CC_NHE,r0,r1,r2) +# define unltr_d(r0,r1,r2) dr(CC_NHE,r0,r1,r2) +# define unlti_f(r0,r1,i0) fi(CC_NHE,r0,r1,i0) +# define unlti_d(r0,r1,i0) di(CC_NHE,r0,r1,i0) +# define unler_f(r0,r1,r2) fr(CC_NH,r0,r1,r2) +# define unler_d(r0,r1,r2) dr(CC_NH,r0,r1,r2) +# define unlei_f(r0,r1,i0) fi(CC_NH,r0,r1,i0) +# define unlei_d(r0,r1,i0) di(CC_NH,r0,r1,i0) +# define uneqr_f(r0,r1,r2) _uneqr_f(_jit,r0,r1,r2) +static void _uneqr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define uneqr_d(r0,r1,r2) _uneqr_d(_jit,r0,r1,r2) +static void _uneqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define uneqi_f(r0,r1,i0) fp(uneq,r0,r1,i0) +# define uneqi_d(r0,r1,i0) dp(uneq,r0,r1,i0) +# define unger_f(r0,r1,r2) fr(CC_NL,r0,r1,r2) +# define unger_d(r0,r1,r2) dr(CC_NL,r0,r1,r2) +# define ungei_f(r0,r1,i0) fi(CC_NL,r0,r1,i0) +# define ungei_d(r0,r1,i0) di(CC_NL,r0,r1,i0) +# define ungtr_f(r0,r1,r2) fr(CC_NLE,r0,r1,r2) +# define ungtr_d(r0,r1,r2) dr(CC_NLE,r0,r1,r2) +# define ungti_f(r0,r1,i0) fi(CC_NLE,r0,r1,i0) +# define ungti_d(r0,r1,i0) di(CC_NLE,r0,r1,i0) +# define ltgtr_f(r0,r1,r2) _ltgtr_f(_jit,r0,r1,r2) +static void _ltgtr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ltgtr_d(r0,r1,r2) _ltgtr_d(_jit,r0,r1,r2) +static void _ltgtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ltgti_f(r0,r1,i0) fp(ltgt,r0,r1,i0) +# define ltgti_d(r0,r1,i0) dp(ltgt,r0,r1,i0) +# define ordr_f(r0,r1,r2) fr(CC_NO,r0,r1,r2) +# define ordr_d(r0,r1,r2) dr(CC_NO,r0,r1,r2) +# define ordi_f(r0,r1,i0) fi(CC_NO,r0,r1,i0) +# define ordi_d(r0,r1,i0) di(CC_NO,r0,r1,i0) +# define unordr_f(r0,r1,r2) fr(CC_O,r0,r1,r2) +# define unordr_d(r0,r1,r2) dr(CC_O,r0,r1,r2) +# define unordi_f(r0,r1,i0) fi(CC_O,r0,r1,i0) +# define unordi_d(r0,r1,i0) di(CC_O,r0,r1,i0) +# define bltr_f(i0,r0,r1) bfr(CC_L,i0,r0,r1) +# define bltr_d(i0,r0,r1) bdr(CC_L,i0,r0,r1) +# define blti_f(i0,r0,i1) bfi(CC_L,i0,r0,i1) +# define blti_d(i0,r0,i1) bdi(CC_L,i0,r0,i1) +# define bltr_f_p(i0,r0,r1) bfr_p(CC_L,i0,r0,r1) +# define bltr_d_p(i0,r0,r1) bdr_p(CC_L,i0,r0,r1) +# define blti_f_p(i0,r0,i1) bfi_p(CC_L,i0,r0,i1) +# define blti_d_p(i0,r0,i1) bdi_p(CC_L,i0,r0,i1) +# define bler_f(i0,r0,r1) bfr(CC_LE,i0,r0,r1) +# define bler_d(i0,r0,r1) bdr(CC_LE,i0,r0,r1) +# define blei_f(i0,r0,i1) bfi(CC_LE,i0,r0,i1) +# define blei_d(i0,r0,i1) bdi(CC_LE,i0,r0,i1) +# define bler_f_p(i0,r0,r1) bfr_p(CC_LE,i0,r0,r1) +# define bler_d_p(i0,r0,r1) bdr_p(CC_LE,i0,r0,r1) +# define blei_f_p(i0,r0,i1) bfi_p(CC_LE,i0,r0,i1) +# define blei_d_p(i0,r0,i1) bdi_p(CC_LE,i0,r0,i1) +# define beqr_f(i0,r0,r1) bfr(CC_E,i0,r0,r1) +# define beqr_d(i0,r0,r1) bdr(CC_E,i0,r0,r1) +# define beqi_f(i0,r0,i1) bfi(CC_E,i0,r0,i1) +# define beqi_d(i0,r0,i1) bdi(CC_E,i0,r0,i1) +# define beqr_f_p(i0,r0,r1) bfr_p(CC_E,i0,r0,r1) +# define beqr_d_p(i0,r0,r1) bdr_p(CC_E,i0,r0,r1) +# define beqi_f_p(i0,r0,i1) bfi_p(CC_E,i0,r0,i1) +# define beqi_d_p(i0,r0,i1) bdi_p(CC_E,i0,r0,i1) +# define bger_f(i0,r0,r1) bfr(CC_HE,i0,r0,r1) +# define bger_d(i0,r0,r1) bdr(CC_HE,i0,r0,r1) +# define bgei_f(i0,r0,i1) bfi(CC_HE,i0,r0,i1) +# define bgei_d(i0,r0,i1) bdi(CC_HE,i0,r0,i1) +# define bger_f_p(i0,r0,r1) bfr_p(CC_HE,i0,r0,r1) +# define bger_d_p(i0,r0,r1) bdr_p(CC_HE,i0,r0,r1) +# define bgei_f_p(i0,r0,i1) bfi_p(CC_HE,i0,r0,i1) +# define bgei_d_p(i0,r0,i1) bdi_p(CC_HE,i0,r0,i1) +# define bgtr_f(i0,r0,r1) bfr(CC_H,i0,r0,r1) +# define bgtr_d(i0,r0,r1) bdr(CC_H,i0,r0,r1) +# define bgti_f(i0,r0,i1) bfi(CC_H,i0,r0,i1) +# define bgti_d(i0,r0,i1) bdi(CC_H,i0,r0,i1) +# define bgtr_f_p(i0,r0,r1) bfr_p(CC_H,i0,r0,r1) +# define bgtr_d_p(i0,r0,r1) bdr_p(CC_H,i0,r0,r1) +# define bgti_f_p(i0,r0,i1) bfi_p(CC_H,i0,r0,i1) +# define bgti_d_p(i0,r0,i1) bdi_p(CC_H,i0,r0,i1) +# define bner_f(i0,r0,r1) bfr(CC_NE,i0,r0,r1) +# define bner_d(i0,r0,r1) bdr(CC_NE,i0,r0,r1) +# define bnei_f(i0,r0,i1) bfi(CC_NE,i0,r0,i1) +# define bnei_d(i0,r0,i1) bdi(CC_NE,i0,r0,i1) +# define bner_f_p(i0,r0,r1) bfr_p(CC_NE,i0,r0,r1) +# define bner_d_p(i0,r0,r1) bdr_p(CC_NE,i0,r0,r1) +# define bnei_f_p(i0,r0,i1) bfi_p(CC_NE,i0,r0,i1) +# define bnei_d_p(i0,r0,i1) bdi_p(CC_NE,i0,r0,i1) +# define bunltr_f(i0,r0,r1) bfr(CC_NHE,i0,r0,r1) +# define bunltr_d(i0,r0,r1) bdr(CC_NHE,i0,r0,r1) +# define bunlti_f(i0,r0,i1) bfi(CC_NHE,i0,r0,i1) +# define bunlti_d(i0,r0,i1) bdi(CC_NHE,i0,r0,i1) +# define bunltr_f_p(i0,r0,r1) bfr_p(CC_NHE,i0,r0,r1) +# define bunltr_d_p(i0,r0,r1) bdr_p(CC_NHE,i0,r0,r1) +# define bunlti_f_p(i0,r0,i1) bfi_p(CC_NHE,i0,r0,i1) +# define bunlti_d_p(i0,r0,i1) bdi_p(CC_NHE,i0,r0,i1) +# define bunler_f(i0,r0,r1) bfr(CC_NH,i0,r0,r1) +# define bunler_d(i0,r0,r1) bdr(CC_NH,i0,r0,r1) +# define bunlei_f(i0,r0,i1) bfi(CC_NH,i0,r0,i1) +# define bunlei_d(i0,r0,i1) bdi(CC_NH,i0,r0,i1) +# define bunler_f_p(i0,r0,r1) bfr_p(CC_NH,i0,r0,r1) +# define bunler_d_p(i0,r0,r1) bdr_p(CC_NH,i0,r0,r1) +# define bunlei_f_p(i0,r0,i1) bfi_p(CC_NH,i0,r0,i1) +# define bunlei_d_p(i0,r0,i1) bdi_p(CC_NH,i0,r0,i1) +# define buneqr_f(i0,r0,r1) buneqr(0,i0,r0,r1) +# define buneqr_d(i0,r0,r1) buneqr(1,i0,r0,r1) +# define buneqi_f(i0,r0,i1) buneqi(0,i0,r0,i1) +# define buneqi_d(i0,r0,i1) buneqi(1,i0,r0,i1) +# define buneqr_f_p(i0,r0,r1) buneqr(0,i0,r0,r1) +# define buneqr_d_p(i0,r0,r1) buneqr(1,i0,r0,r1) +# define buneqi_f_p(i0,r0,i1) buneqi(0,i0,r0,i1) +# define buneqi_d_p(i0,r0,i1) buneqi(1,i0,r0,i1) +# define bunger_f(i0,r0,r1) bfr(CC_NL,i0,r0,r1) +# define bunger_d(i0,r0,r1) bdr(CC_NL,i0,r0,r1) +# define bungei_f(i0,r0,i1) bfi(CC_NL,i0,r0,i1) +# define bungei_d(i0,r0,i1) bdi(CC_NL,i0,r0,i1) +# define bunger_f_p(i0,r0,r1) bfr_p(CC_NL,i0,r0,r1) +# define bunger_d_p(i0,r0,r1) bdr_p(CC_NL,i0,r0,r1) +# define bungei_f_p(i0,r0,i1) bfi_p(CC_NL,i0,r0,i1) +# define bungei_d_p(i0,r0,i1) bdi_p(CC_NL,i0,r0,i1) +# define bungtr_f(i0,r0,r1) bfr(CC_NLE,i0,r0,r1) +# define bungtr_d(i0,r0,r1) bdr(CC_NLE,i0,r0,r1) +# define bungti_f(i0,r0,i1) bfi(CC_NLE,i0,r0,i1) +# define bungti_d(i0,r0,i1) bdi(CC_NLE,i0,r0,i1) +# define bungtr_f_p(i0,r0,r1) bfr_p(CC_NLE,i0,r0,r1) +# define bungtr_d_p(i0,r0,r1) bdr_p(CC_NLE,i0,r0,r1) +# define bungti_f_p(i0,r0,i1) bfi_p(CC_NLE,i0,r0,i1) +# define bungti_d_p(i0,r0,i1) bdi_p(CC_NLE,i0,r0,i1) +# define bltgtr_f(i0,r0,r1) bltgtr(0,i0,r0,r1) +# define bltgtr_d(i0,r0,r1) bltgtr(1,i0,r0,r1) +# define bltgti_f(i0,r0,i1) bltgti(0,i0,r0,i1) +# define bltgti_d(i0,r0,i1) bltgti(1,i0,r0,i1) +# define bltgtr_f_p(i0,r0,r1) bltgtr(0,i0,r0,r1) +# define bltgtr_d_p(i0,r0,r1) bltgtr(1,i0,r0,r1) +# define bltgti_f_p(i0,r0,i1) bltgti(0,i0,r0,i1) +# define bltgti_d_p(i0,r0,i1) bltgti(1,i0,r0,i1) +# define bordr_f(i0,r0,r1) bfr(CC_NO,i0,r0,r1) +# define bordr_d(i0,r0,r1) bdr(CC_NO,i0,r0,r1) +# define bordi_f(i0,r0,i1) bfi(CC_NO,i0,r0,i1) +# define bordi_d(i0,r0,i1) bdi(CC_NO,i0,r0,i1) +# define bordr_f_p(i0,r0,r1) bfr_p(CC_NO,i0,r0,r1) +# define bordr_d_p(i0,r0,r1) bdr_p(CC_NO,i0,r0,r1) +# define bordi_f_p(i0,r0,i1) bfi_p(CC_NO,i0,r0,i1) +# define bordi_d_p(i0,r0,i1) bdi_p(CC_NO,i0,r0,i1) +# define bunordr_f(i0,r0,r1) bfr(CC_O,i0,r0,r1) +# define bunordr_d(i0,r0,r1) bdr(CC_O,i0,r0,r1) +# define bunordi_f(i0,r0,i1) bfi(CC_O,i0,r0,i1) +# define bunordi_d(i0,r0,i1) bdi(CC_O,i0,r0,i1) +# define bunordr_f_p(i0,r0,r1) bfr_p(CC_O,i0,r0,r1) +# define bunordr_d_p(i0,r0,r1) bdr_p(CC_O,i0,r0,r1) +# define bunordi_f_p(i0,r0,i1) bfi_p(CC_O,i0,r0,i1) +# define bunordi_d_p(i0,r0,i1) bdi_p(CC_O,i0,r0,i1) +#endif + +#if CODE +static void +_fp(jit_state_t *_jit, jit_code_t code, + jit_int32_t r0, jit_int32_t r1, jit_float32_t *i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + movi_f(rn(reg), i0); + switch (code) { + case jit_code_addi_f: addr_f(r0, r1, rn(reg)); break; + case jit_code_subi_f: subr_f(r0, r1, rn(reg)); break; + case jit_code_muli_f: mulr_f(r0, r1, rn(reg)); break; + case jit_code_divi_f: divr_f(r0, r1, rn(reg)); break; + case jit_code_uneqi_f: uneqr_f(r0, r1, rn(reg)); break; + case jit_code_ltgti_f: ltgtr_f(r0, r1, rn(reg)); break; + default: abort(); + } + jit_unget_reg(reg); +} + +static void +_dp(jit_state_t *_jit, jit_code_t code, + jit_int32_t r0, jit_int32_t r1, jit_float64_t *i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + movi_d(rn(reg), i0); + switch (code) { + case jit_code_addi_d: addr_d(r0, r1, rn(reg)); break; + case jit_code_subi_d: subr_d(r0, r1, rn(reg)); break; + case jit_code_muli_d: mulr_d(r0, r1, rn(reg)); break; + case jit_code_divi_d: divr_d(r0, r1, rn(reg)); break; + case jit_code_uneqi_d: uneqr_d(r0, r1, rn(reg)); break; + case jit_code_ltgti_d: ltgtr_d(r0, r1, rn(reg)); break; + default: abort(); + } + jit_unget_reg(reg); +} + +static void +_fr(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + LGHI(r0, 1); + CEBR(r1, r2); + w = _jit->pc.w; + BRC(cc, 0); + LGHI(r0, 0); + patch_at(w, _jit->pc.w); +} + +static void +_dr(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + LGHI(r0, 1); + CDBR(r1, r2); + w = _jit->pc.w; + BRC(cc, 0); + LGHI(r0, 0); + patch_at(w, _jit->pc.w); +} + +static void +_fi(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_float32_t *i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + movi_f(rn(reg), i0); + fr(cc, r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_di(jit_state_t *_jit, jit_int32_t cc, + jit_int32_t r0, jit_int32_t r1, jit_float64_t *i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + movi_d(rn(reg), i0); + dr(cc, r0, r1, rn(reg)); + jit_unget_reg(reg); +} + + +static void +_bfr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + CEBR(r0, r1); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(cc, x16(d)); + else { + assert(s32_p(d)); + BRCL(cc, d); + } +} + +static void +_bdr(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t d; + CDBR(r0, r1); + d = (i0 - _jit->pc.w) >> 1; + if (s16_p(d)) + BRC(cc, x16(d)); + else { + assert(s32_p(d)); + BRCL(cc, d); + } +} + +static jit_word_t +_bfr_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CEBR(r0, r1); + w = _jit->pc.w; + BRCL(cc, 0); + return (w); +} + +static jit_word_t +_bdr_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + CDBR(r0, r1); + w = _jit->pc.w; + BRCL(cc, 0); + return (w); +} + +static void +_bfi(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_float32_t *i1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi_f(rn(reg), i1); + bfr(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_bdi(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_float64_t *i1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi_d(rn(reg), i1); + bdr(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static jit_word_t +_bfi_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_float32_t *i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi_f(rn(reg), i1); + w = bfr_p(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bdi_p(jit_state_t *_jit, jit_int32_t cc, + jit_word_t i0, jit_int32_t r0, jit_float64_t *i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi_d(rn(reg), i1); + w = bdr_p(cc, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_buneqr(jit_state_t *_jit, jit_int32_t db, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t unord, ne, w; + if (db) CDBR(r0, r1); + else CEBR(r0, r1); + unord = _jit->pc.w; + BRC(CC_O, 0); /* unord satisfies condition */ + ne = _jit->pc.w; + BRC(CC_NE, 0); /* ne does not satisfy condition */ + patch_at(unord, _jit->pc.w); + w = _jit->pc.w; + BRCL(CC_AL, (i0 - _jit->pc.w) >> 1); + patch_at(ne, _jit->pc.w); + return (w); +} + +static jit_word_t +_buneqi(jit_state_t *_jit, jit_int32_t db, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + if (db) + movi_d(rn(reg), (jit_float64_t *)i1); + else + movi_f(rn(reg), (jit_float32_t *)i1); + w = buneqr(db, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bltgtr(jit_state_t *_jit, jit_int32_t db, + jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t unord, eq, w; + if (db) CDBR(r0, r1); + else CEBR(r0, r1); + unord = _jit->pc.w; + BRC(CC_O, 0); /* unord does not satisfy condition */ + eq = _jit->pc.w; + BRC(CC_E, 0); /* eq does not satisfy condition */ + w = _jit->pc.w; + BRCL(CC_AL, (i0 - _jit->pc.w) >> 1); + patch_at(unord, _jit->pc.w); + patch_at(eq, _jit->pc.w); + return (w); +} + +static jit_word_t +_bltgti(jit_state_t *_jit, jit_int32_t db, + jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + if (db) + movi_d(rn(reg), (jit_float64_t *)i1); + else + movi_f(rn(reg), (jit_float32_t *)i1); + w = bltgtr(db, i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_movr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + LER(r0, r1); +} + +static void +_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) +{ + if (*(jit_int32_t *)i0 == 0) + LZER(r0); + else + ldi_f(r0, (jit_word_t)i0); +} + +static void +_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + LDR(r0, r1); +} + +static void +_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + if (*(jit_int64_t *)i0 == 0) + LZDR(r0); + else + ldi_d(r0, (jit_word_t)i0); +} + +static void +_addr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + AEBR(r0, r1); + else { + movr_f(r0, r1); + AEBR(r0, r2); + } +} + +static void +_addr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + ADBR(r0, r1); + else { + movr_d(r0, r1); + ADBR(r0, r2); + } +} + +static void +_subr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_fpr); + movr_f(rn(reg), r2); + movr_f(r0, r1); + SEBR(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr_f(r0, r1); + SEBR(r0, r2); + } +} + +static void +_subr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_fpr); + movr_d(rn(reg), r2); + movr_d(r0, r1); + SDBR(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr_d(r0, r1); + SDBR(r0, r2); + } +} + +static void +_mulr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + MEEBR(r0, r1); + else { + movr_f(r0, r1); + MEEBR(r0, r2); + } +} + +static void +_mulr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + if (r0 == r2) + MDBR(r0, r1); + else { + movr_d(r0, r1); + MDBR(r0, r2); + } +} + +static void +_divr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_fpr); + movr_f(rn(reg), r2); + movr_f(r0, r1); + DEBR(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr_f(r0, r1); + DEBR(r0, r2); + } +} + +static void +_divr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (r0 == r2) { + reg = jit_get_reg(jit_class_fpr); + movr_d(rn(reg), r2); + movr_d(r0, r1); + DDBR(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + movr_d(r0, r1); + DDBR(r0, r2); + } +} + +static void +_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + ldr_f(r0, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +static void +_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + ldr_d(r0, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +static void +_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movr(rn(reg), r1); + AGR(rn(reg), r2); + ldr_f(r0, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +static void +_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movr(rn(reg), r1); + AGR(rn(reg), r2); + ldr_d(r0, rn(reg)); + jit_unget_reg_but_zero(reg); +} + +static void +_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (u12_p(i0)) + LE(r0, i0, 0, r1); + else if (s20_p(i0)) + LEY(r0, x20(i0), 0, r1); + else { + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + AGR(rn(reg), r1); + ldr_f(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (u12_p(i0)) + LD(r0, i0, 0, r1); + else if (s20_p(i0)) + LDY(r0, x20(i0), 0, r1); + else { + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + AGR(rn(reg), r1); + ldr_d(r0, rn(reg)); + jit_unget_reg_but_zero(reg); + } +} + +static void +_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + str_f(rn(reg), r0); + jit_unget_reg_but_zero(reg); +} + +static void +_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + str_d(rn(reg), r0); + jit_unget_reg_but_zero(reg); +} + +static void +_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movr(rn(reg), r0); + AGR(rn(reg), r1); + str_f(rn(reg), r2); + jit_unget_reg_but_zero(reg); +} + +static void +_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg_but_zero(); + movr(rn(reg), r0); + AGR(rn(reg), r1); + str_d(rn(reg), r2); + jit_unget_reg_but_zero(reg); +} + +static void +_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (u12_p(i0)) + STE(r1, i0, 0, r0); + else if (s20_p(i0)) + STEY(r1, x20(i0), 0, r0); + else { + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + AGR(rn(reg), r0); + str_f(rn(reg), r1); + jit_unget_reg_but_zero(reg); + } +} + +static void +_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (u12_p(i0)) + STD(r1, i0, 0, r0); + else if (s20_p(i0)) + STDY(r1, x20(i0), 0, r0); + else { + reg = jit_get_reg_but_zero(); + movi(rn(reg), i0); + AGR(rn(reg), r0); + str_d(rn(reg), r1); + jit_unget_reg_but_zero(reg); + } +} + +static void +_uneqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t unord, eq; + LGHI(r0, 1); /* set to one */ + CEBR(r1, r2); + unord = _jit->pc.w; /* keep set to one if unord */ + BRC(CC_O, 0); + eq = _jit->pc.w; + BRC(CC_E, 0); /* keep set to one if eq */ + LGHI(r0, 0); /* set to zero */ + patch_at(unord, _jit->pc.w); + patch_at(eq, _jit->pc.w); +} + +static void +_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t unord, eq; + LGHI(r0, 1); /* set to one */ + CDBR(r1, r2); + unord = _jit->pc.w; /* keep set to one if unord */ + BRC(CC_O, 0); + eq = _jit->pc.w; + BRC(CC_E, 0); /* keep set to one if eq */ + LGHI(r0, 0); /* set to zero */ + patch_at(unord, _jit->pc.w); + patch_at(eq, _jit->pc.w); +} + +static void +_ltgtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t unord, eq; + LGHI(r0, 0); /* set to zero */ + CEBR(r1, r2); + unord = _jit->pc.w; /* keep set to zero if unord */ + BRC(CC_O, 0); + eq = _jit->pc.w; + BRC(CC_E, 0); /* keep set to zero if eq */ + LGHI(r0, 1); /* set to one */ + patch_at(unord, _jit->pc.w); + patch_at(eq, _jit->pc.w); +} + +static void +_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t unord, eq; + LGHI(r0, 0); /* set to zero */ + CDBR(r1, r2); + unord = _jit->pc.w; /* keep set to zero if unord */ + BRC(CC_O, 0); + eq = _jit->pc.w; + BRC(CC_E, 0); /* keep set to zero if eq */ + LGHI(r0, 1); /* set to one */ + patch_at(unord, _jit->pc.w); + patch_at(eq, _jit->pc.w); +} +#endif diff --git a/lib/jit_s390x.c b/lib/jit_s390x.c new file mode 100644 index 000000000..ab6432c21 --- /dev/null +++ b/lib/jit_s390x.c @@ -0,0 +1,1281 @@ +/* + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software 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 General Public License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include +#include + +#define rc(value) jit_class_##value +#define rn(reg) (jit_regno(_rvs[jit_regno(reg)].spec)) + +/* + * Prototypes + */ +#define jit_get_reg_pair() _jit_get_reg_pair(_jit) +static jit_int32_t _jit_get_reg_pair(jit_state_t*); +#define jit_unget_reg_pair(regno) _jit_unget_reg_pair(_jit,regno) +static void _jit_unget_reg_pair(jit_state_t*,jit_int32_t); +#define jit_get_reg_but_zero() _jit_get_reg_but_zero(_jit) +static jit_int32_t _jit_get_reg_but_zero(jit_state_t*); +#define jit_unget_reg_but_zero(reg) jit_unget_reg(reg) +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); + +/* libgcc */ +extern void __clear_cache(void *, void *); + +#define PROTO 1 +# include "jit_s390x-cpu.c" +# include "jit_s390x-fpu.c" +#undef PROTO + +/* + * Initialization + */ +jit_register_t _rvs[] = { + { rc(gpr) | 0x0, "%r0" }, + { rc(gpr) | 0x1, "%r1" }, + { rc(gpr) | rc(sav) | 0xc, "%r12" }, + { rc(gpr) | rc(sav) | 0xb, "%r11" }, + { rc(gpr) | rc(sav) | 0xa, "%r10" }, + { rc(gpr) | rc(sav) | 0x9, "%r9" }, + { rc(gpr) | rc(sav) | 0x8, "%r8" }, + { rc(gpr) | rc(sav) | 0x7, "%r7" }, + { rc(gpr) | rc(arg) | rc(sav) | 0x6,"%r6" }, + { rc(gpr) | rc(arg) | 0x5, "%r5" }, + { rc(gpr) | rc(arg) | 0x4, "%r4" }, + { rc(gpr) | rc(arg) | 0x3, "%r3" }, + { rc(gpr) | rc(arg) | 0x2, "%r2" }, + { rc(sav) | 0xd, "%r13" }, /* used as JIT_FP */ + { 0xe, "%r14" }, + { rc(sav) | 0xf, "%r15" }, + { rc(fpr) | 0x1, "%f1" }, + { rc(fpr) | 0x3, "%f3" }, + { rc(fpr) | 0x5, "%f5" }, + { rc(fpr) | 0x7, "%f7" }, + { rc(fpr) | rc(sav) | 0xe, "%f14" }, + { rc(fpr) | rc(sav) | 0xf, "%f15" }, + { rc(fpr) | rc(sav) | 0x8, "%f8" }, + { rc(fpr) | rc(sav) | 0x9, "%f9" }, + { rc(fpr) | rc(sav) | 0xa, "%f10" }, + { rc(fpr) | rc(sav) | 0xb, "%f11" }, + { rc(fpr) | rc(sav) | 0xc, "%f12" }, + { rc(fpr) | rc(sav) | 0xd, "%f13" }, + { rc(fpr) | rc(arg) | 0x6, "%f6" }, + { rc(fpr) | rc(arg) | 0x4, "%f4" }, + { rc(fpr) | rc(arg) | 0x2, "%f2" }, + { rc(fpr) | rc(arg) | 0x0, "%f0" }, + { _NOREG, "" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ +} + +void +_jit_init(jit_state_t *_jit) +{ + _jitc->reglen = jit_size(_rvs) - 1; +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + _jitc->function->self.size = stack_framesize; + _jitc->function->self.argi = _jitc->function->self.argf = + _jitc->function->self.aoff = _jitc->function->self.alen = + _jitc->function->self.aoff = 0; + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + assert(_jitc->function); + switch (length) { + case 0: case 1: break; + case 2: _jitc->function->self.aoff &= -2; break; + case 3: case 4: _jitc->function->self.aoff &= -4; break; + default: _jitc->function->self.aoff &= -8; break; + } + _jitc->function->self.aoff -= length; + return (_jitc->function->self.aoff); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + + assert(_jitc->function); + + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + jit_movr(JIT_RET, u); + jit_ret(); +} + +void +_jit_reti(jit_state_t *_jit, jit_word_t u) +{ + jit_movi(JIT_RET, u); + jit_ret(); +} + +void +_jit_retr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_movr_f(JIT_FRET, u); + jit_ret(); +} + +void +_jit_reti_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_movi_f(JIT_FRET, u); + jit_ret(); +} + +void +_jit_retr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_movr_d(JIT_FRET, u); + jit_ret(); +} + +void +_jit_reti_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_movi_d(JIT_FRET, u); + jit_ret(); +} + +void +_jit_epilog(jit_state_t *_jit) +{ + assert(_jitc->function); + assert(_jitc->function->epilog->next == NULL); + jit_link(_jitc->function->epilog); + _jitc->function = NULL; +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + jit_int32_t offset; + assert(_jitc->function); + if (_jitc->function->self.argi < 5) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + return (jit_new_node_w(jit_code_arg, offset)); +} + +jit_bool_t +_jit_arg_reg_p(jit_state_t *_jit, jit_int32_t offset) +{ + return (offset >= 0 && offset < 5); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + jit_int32_t offset; + assert(_jitc->function); + if (_jitc->function->self.argf < 4) + offset = _jitc->function->self.argf++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + return (jit_new_node_w(jit_code_arg_f, offset)); +} + +jit_bool_t +_jit_arg_f_reg_p(jit_state_t *_jit, jit_int32_t offset) +{ + return (offset >= 0 && offset < 4); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + jit_int32_t offset; + assert(_jitc->function); + if (_jitc->function->self.argf < 4) + offset = _jitc->function->self.argf++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + return (jit_new_node_w(jit_code_arg_d, offset)); +} + +jit_bool_t +_jit_arg_d_reg_p(jit_state_t *_jit, jit_int32_t offset) +{ + return (jit_arg_f_reg_p(offset)); +} + +void +_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 5) + jit_extr_c(u, _R2 - v->u.w); + else + jit_ldxi_c(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int8_t)); +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 5) + jit_extr_uc(u, _R2 - v->u.w); + else + jit_ldxi_uc(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint8_t)); +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 5) + jit_extr_s(u, _R2 - v->u.w); + else + jit_ldxi_s(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int16_t)); +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 5) + jit_extr_us(u, _R2 - v->u.w); + else + jit_ldxi_us(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint16_t)); +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 5) + jit_extr_i(u, _R2 - v->u.w); + else + jit_ldxi_i(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_int32_t)); +} + +void +_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 5) + jit_extr_ui(u, _R2 - v->u.w); + else + jit_ldxi_ui(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_uint32_t)); +} + +void +_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 5) + jit_movr(u, _R2 - v->u.w); + else + jit_ldxi_l(u, JIT_FP, v->u.w); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 4) + jit_movr_f(u, _F0 - v->u.w); + else + jit_ldxi_f(u, JIT_FP, + v->u.w + (__WORDSIZE >> 3) - sizeof(jit_float32_t)); +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 4) + jit_movr_d(u, _F0 - v->u.w); + else + jit_ldxi_d(u, JIT_FP, v->u.w); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + if (_jitc->function->call.argi < 5) { + jit_movr(_R2 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } +} + +void +_jit_pushargi(jit_state_t *_jit, jit_word_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + if (_jitc->function->call.argi < 5) { + jit_movi(_R2 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + if (_jitc->function->call.argf < 4) { + jit_movr_f(_F0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else { + jit_stxi_f(_jitc->function->call.size + stack_framesize + + (__WORDSIZE >> 3) - sizeof(jit_float32_t), JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + if (_jitc->function->call.argf < 4) { + jit_movi_f(_F0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(_jitc->function->call.size + stack_framesize + + (__WORDSIZE >> 3) - sizeof(jit_float32_t), JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + if (_jitc->function->call.argf < 4) { + jit_movr_d(_F0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else { + jit_stxi_d(_jitc->function->call.size + stack_framesize, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + if (_jitc->function->call.argf < 4) { + jit_movi_d(_F0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(_jitc->function->call.size + stack_framesize, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + jit_int32_t spec; + spec = jit_class(_rvs[regno].spec); + if (spec & jit_class_arg) { + regno = _R2 - regno; + if (regno >= 0 && regno < node->v.w) + return (1); + if (spec & jit_class_fpr) { + regno = _F0 - regno; + if (regno >= 0 && regno < node->w.w) + return (1); + } + } + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_node_t *call; + assert(_jitc->function); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + call = jit_callr(r0); + call->v.w = _jitc->function->call.argi; + call->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ + jit_node_t *node; + assert(_jitc->function); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_calli(i0); + node->v.w = _jitc->function->call.argi; + node->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + return (node); +} + +void +_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) +{ + jit_extr_c(r0, JIT_RET); +} + +void +_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) +{ + jit_extr_uc(r0, JIT_RET); +} + +void +_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) +{ + jit_extr_s(r0, JIT_RET); +} + +void +_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) +{ + jit_extr_us(r0, JIT_RET); +} + +void +_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) +{ + jit_extr_i(r0, JIT_RET); +} + +void +_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) +{ + jit_extr_ui(r0, JIT_RET); +} + +void +_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) +{ + jit_movr(r0, JIT_RET); +} + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + jit_movr_f(r0, JIT_FRET); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + jit_movr_d(r0, JIT_FRET); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_int32_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_word_t word; + jit_int32_t patch_offset; + } undo; + + _jitc->function = NULL; + + jit_reglive_setup(); + + undo.word = 0; + undo.node = NULL; + undo.patch_offset = 0; + +#define assert_data(node) /**/ +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_rf(name) \ + case jit_code_##name##i_f: \ + assert_data(node); \ + name##_f(rn(node->u.w), \ + (jit_float32_t *)node->v.n->u.w); \ + break +#define case_rd(name) \ + case jit_code_##name##i_d: \ + assert_data(node); \ + name##_d(rn(node->u.w), \ + (jit_float64_t *)node->v.n->u.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_rrf(name) \ + case jit_code_##name##i_f: \ + assert_data(node); \ + name##i_f(rn(node->u.w), rn(node->v.w), \ + (jit_float32_t *)node->w.n->u.w); \ + break +#define case_rrd(name) \ + case jit_code_##name##i_d: \ + assert_data(node); \ + name##i_d(rn(node->u.w), rn(node->v.w), \ + (jit_float64_t *)node->w.n->u.w); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type##_p(_jit->pc.w, \ + rn(node->v.w), \ + rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type##_p(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break; +#define case_brf(name) \ + case jit_code_##name##i_f: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i_f(temp->u.w, rn(node->v.w), \ + (jit_float32_t *)node->w.n->u.w); \ + else { \ + word = name##i_f_p(_jit->pc.w, rn(node->v.w), \ + (jit_float32_t *)node->w.n->u.w);\ + patch(word, node); \ + } \ + break +#define case_brd(name) \ + case jit_code_##name##i_d: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i_d(temp->u.w, rn(node->v.w), \ + (jit_float64_t *)node->w.n->u.w); \ + else { \ + word = name##i_d_p(_jit->pc.w, rn(node->v.w), \ + (jit_float64_t *)node->w.n->u.w);\ + patch(word, node); \ + } \ + break + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end && !jit_remap()) + return (NULL); + + value = jit_classify(node->code); + jit_regarg_set(node, value); + switch (node->code) { + case jit_code_note: case jit_code_name: + node->u.w = _jit->pc.w; + break; + case jit_code_label: + if (node->link && (word = _jit->pc.w & 3)) + nop(4 - word); + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + break; + case_rrr(add,); + case_rrw(add,); + case_rrr(addc,); + case_rrw(addc,); + case_rrr(addx,); + case_rrw(addx,); + case_rrr(sub,); + case_rrw(sub,); + case_rrr(subc,); + case_rrw(subc,); + case_rrr(subx,); + case_rrw(subx,); + case_rrr(mul,); + case_rrw(mul,); + case_rrrr(qmul,); + case_rrrw(qmul,); + case_rrrr(qmul, _u); + case_rrrw(qmul, _u); + case_rrr(div,); + case_rrw(div,); + case_rrr(div, _u); + case_rrw(div, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rr(neg,); + case_rr(com,); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_rr(trunc, _f_i); + case_rr(trunc, _d_i); + case_rr(trunc, _f_l); + case_rr(trunc, _d_l); + case_rr(ld, _c); + case_rw(ld, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rr(ld, _i); + case_rw(ld, _i); + case_rr(ld, _ui); + case_rw(ld, _ui); + case_rr(ld, _l); + case_rw(ld, _l); + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rrr(ldx, _i); + case_rrw(ldx, _i); + case_rrr(ldx, _ui); + case_rrw(ldx, _ui); + case_rrr(ldx, _l); + case_rrw(ldx, _l); + case_rr(st, _c); + case_wr(st, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rr(st, _i); + case_wr(st, _i); + case_rr(st, _l); + case_wr(st, _l); + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rrr(stx, _i); + case_wrr(stx, _i); + case_rrr(stx, _l); + case_wrr(stx, _l); + case_rr(hton,); + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); + case_rr(ext, _i); + case_rr(ext, _ui); + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), temp->u.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_rrr(add, _f); + case_rrf(add); + case_rrr(sub, _f); + case_rrf(sub); + case_rrr(mul, _f); + case_rrf(mul); + case_rrr(div, _f); + case_rrf(div); + case_rr(abs, _f); + case_rr(neg, _f); + case_rr(sqrt, _f); + case_rr(ext, _f); + case_rr(ld, _f); + case_rw(ld, _f); + case_rrr(ldx, _f); + case_rrw(ldx, _f); + case_rr(st, _f); + case_wr(st, _f); + case_rrr(stx, _f); + case_wrr(stx, _f); + case_rr(mov, _f); + case jit_code_movi_f: + assert_data(node); + movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); + break; + case_rr(ext, _d_f); + case_rrr(lt, _f); + case_rrf(lt); + case_rrr(le, _f); + case_rrf(le); + case_rrr(eq, _f); + case_rrf(eq); + case_rrr(ge, _f); + case_rrf(ge); + case_rrr(gt, _f); + case_rrf(gt); + case_rrr(ne, _f); + case_rrf(ne); + case_rrr(unlt, _f); + case_rrf(unlt); + case_rrr(unle, _f); + case_rrf(unle); + case_rrr(uneq, _f); + case_rrf(uneq); + case_rrr(unge, _f); + case_rrf(unge); + case_rrr(ungt, _f); + case_rrf(ungt); + case_rrr(ltgt, _f); + case_rrf(ltgt); + case_rrr(ord, _f); + case_rrf(ord); + case_rrr(unord, _f); + case_rrf(unord); + case_brr(blt, _f); + case_brf(blt); + case_brr(ble, _f); + case_brf(ble); + case_brr(beq, _f); + case_brf(beq); + case_brr(bge, _f); + case_brf(bge); + case_brr(bgt, _f); + case_brf(bgt); + case_brr(bne, _f); + case_brf(bne); + case_brr(bunlt, _f); + case_brf(bunlt); + case_brr(bunle, _f); + case_brf(bunle); + case_brr(buneq, _f); + case_brf(buneq); + case_brr(bunge, _f); + case_brf(bunge); + case_brr(bungt, _f); + case_brf(bungt); + case_brr(bltgt, _f); + case_brf(bltgt); + case_brr(bord, _f); + case_brf(bord); + case_brr(bunord, _f); + case_brf(bunord); + case_rrr(add, _d); + case_rrd(add); + case_rrr(sub, _d); + case_rrd(sub); + case_rrr(mul, _d); + case_rrd(mul); + case_rrr(div, _d); + case_rrd(div); + case_rr(abs, _d); + case_rr(neg, _d); + case_rr(sqrt, _d); + case_rr(ext, _d); + case_rr(ld, _d); + case_rw(ld, _d); + case_rrr(ldx, _d); + case_rrw(ldx, _d); + case_rr(st, _d); + case_wr(st, _d); + case_rrr(stx, _d); + case_wrr(stx, _d); + case_rr(mov, _d); + case jit_code_movi_d: + assert_data(node); + movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w); + break; + case_rr(ext, _f_d); + case_rrr(lt, _d); + case_rrd(lt); + case_rrr(le, _d); + case_rrd(le); + case_rrr(eq, _d); + case_rrd(eq); + case_rrr(ge, _d); + case_rrd(ge); + case_rrr(gt, _d); + case_rrd(gt); + case_rrr(ne, _d); + case_rrd(ne); + case_rrr(unlt, _d); + case_rrd(unlt); + case_rrr(unle, _d); + case_rrd(unle); + case_rrr(uneq, _d); + case_rrd(uneq); + case_rrr(unge, _d); + case_rrd(unge); + case_rrr(ungt, _d); + case_rrd(ungt); + case_rrr(ltgt, _d); + case_rrd(ltgt); + case_rrr(ord, _d); + case_rrd(ord); + case_rrr(unord, _d); + case_rrd(unord); + case_brr(blt, _d); + case_brd(blt); + case_brr(ble, _d); + case_brd(ble); + case_brr(beq, _d); + case_brd(beq); + case_brr(bge, _d); + case_brd(bge); + case_brr(bgt, _d); + case_brd(bgt); + case_brr(bne, _d); + case_brd(bne); + case_brr(bunlt, _d); + case_brd(bunlt); + case_brr(bunle, _d); + case_brd(bunle); + case_brr(buneq, _d); + case_brd(buneq); + case_brr(bunge, _d); + case_brd(bunge); + case_brr(bungt, _d); + case_brd(bungt); + case_brr(bltgt, _d); + case_brd(bltgt); + case_brr(bord, _d); + case_brd(bord); + case_brr(bunord, _d); + case_brd(bunord); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + break; + case jit_code_jmpi: + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } + break; + case jit_code_callr: + callr(rn(node->u.w)); + break; + case jit_code_calli: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + calli(temp->u.w); + else { + word = calli_p(_jit->pc.w); + patch(word, node); + } + } + else + calli(node->u.w); + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; + undo.patch_offset = _jitc->patches.offset; + restart_function: + _jitc->again = 0; + prolog(node); + break; + case jit_code_epilog: + assert(_jitc->function == _jitc->functions.ptr + node->w.w); + if (_jitc->again) { + for (temp = undo.node->next; + temp != node; temp = temp->next) { + if (temp->code == jit_code_label || + temp->code == jit_code_epilog) + temp->flag &= ~jit_flag_patch; + } + temp->flag &= ~jit_flag_patch; + node = undo.node; + _jit->pc.w = undo.word; + _jitc->patches.offset = undo.patch_offset; + goto restart_function; + } + if (node->link && (word = _jit->pc.w & 3)) + nop(4 - word); + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + epilog(node); + _jitc->function = NULL; + break; + case jit_code_live: + case jit_code_arg: + case jit_code_arg_f: case jit_code_arg_d: + break; + default: + abort(); + } + jit_regarg_clr(node, value); + /* update register live state */ + jit_reglive(node); + } +#undef case_brw +#undef case_brr +#undef case_wrr +#undef case_rrw +#undef case_rrr +#undef case_wr +#undef case_rw +#undef case_rr + + for (offset = 0; offset < _jitc->patches.offset; offset++) { + node = _jitc->patches.ptr[offset].node; + word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(_jitc->patches.ptr[offset].inst, word); + } + + word = sysconf(_SC_PAGE_SIZE); + __clear_cache(_jit->code.ptr, (void *)((_jit->pc.w + word) & -word)); + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_s390x-cpu.c" +# include "jit_s390x-fpu.c" +#undef CODE + +void +_emit_ldxi(jit_state_t *_jit, jit_gpr_t r0, jit_gpr_t r1, jit_word_t i0) +{ + ldxi(rn(r0), rn(r1), i0); +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_gpr_t r1) +{ + stxi(i0, rn(r0), rn(r1)); +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_fpr_t r0, jit_gpr_t r1, jit_word_t i0) +{ + ldxi_d(rn(r0), rn(r1), i0); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_gpr_t r0, jit_fpr_t r1) +{ + stxi_d(i0, rn(r0), rn(r1)); +} + +static jit_int32_t +_jit_get_reg_pair(jit_state_t *_jit) +{ + jit_int32_t r1, r2; + /* Try to find a register pair for use with operations that + * require a odd based register pair. Search for the best + * match to avoid spills or at least a valid operation. + */ + + /* Try non callee save first */ + if (jit_reg_free_p(_R0) && jit_reg_free_p(_R1)) + r1 = _R0, r2 = _R1; + else if (jit_reg_free_p(_R2) && jit_reg_free_p(_R3)) + r1 = _R2, r2 = _R3; + else if (jit_reg_free_p(_R4) && jit_reg_free_p(_R5)) + r1 = _R4, r2 = _R5; + /* Try callee save registers */ + else if (jit_reg_free_p(_R10) && jit_reg_free_p(_R11)) + r1 = _R10, r2 = _R11; + else if (jit_reg_free_p(_R8) && jit_reg_free_p(_R9)) + r1 = _R8, r2 = _R9; + else if (jit_reg_free_p(_R6) && jit_reg_free_p(_R7)) + r1 = _R6, r2 = _R7; + + /* We *must* find a register pair */ + else if (jit_reg_free_if_spill_p(_R0) && jit_reg_free_if_spill_p(_R1)) + r1 = _R0, r2 = _R1; + else if (jit_reg_free_if_spill_p(_R2) && jit_reg_free_if_spill_p(_R3)) + r1 = _R2, r2 = _R3; + else if (jit_reg_free_if_spill_p(_R4) && jit_reg_free_if_spill_p(_R5)) + r1 = _R4, r2 = _R5; + else if (jit_reg_free_if_spill_p(_R10) && jit_reg_free_if_spill_p(_R11)) + r1 = _R10, r2 = _R11; + else if (jit_reg_free_if_spill_p(_R8) && jit_reg_free_if_spill_p(_R9)) + r1 = _R8, r2 = _R9; + else if (jit_reg_free_if_spill_p(_R6) && jit_reg_free_if_spill_p(_R7)) + r1 = _R6, r2 = _R7; + else + /* Do not jit_get_reg() all registers to avoid it */ + abort(); + + (void)jit_get_reg(jit_class_gpr|jit_class_named|r1); + (void)jit_get_reg(jit_class_gpr|jit_class_named|r2); + + return (r1); +} + +static void +_jit_unget_reg_pair(jit_state_t *_jit, jit_int32_t reg) +{ + jit_int32_t r1, r2; + r1 = reg; + switch (r1) { + case _R0: r2 = _R1; break; + case _R2: r2 = _R3; break; + case _R4: r2 = _R5; break; + case _R6: r2 = _R7; break; + case _R8: r2 = _R9; break; + case _R10: r2 = _R11; break; + default: abort(); + } + jit_unget_reg(r1); + jit_unget_reg(r2); +} + +static jit_int32_t +_jit_get_reg_but_zero(jit_state_t *_jit) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + if (reg == _R0) { + reg = jit_get_reg(jit_class_gpr); + jit_unget_reg(_R0); + } + return (reg); +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) + flag = node->v.n->flag; + else + flag = node->u.n->flag; + assert(!(flag & jit_flag_patch)); + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} diff --git a/lib/lightning.c b/lib/lightning.c index 4223616f6..41423e210 100644 --- a/lib/lightning.c +++ b/lib/lightning.c @@ -2913,4 +2913,6 @@ _patch_register(jit_state_t *_jit, jit_node_t *node, jit_node_t *link, # include "jit_hppa.c" #elif defined(__aarch64__) # include "jit_aarch64.c" +#elif defined(__s390x__) +# include "jit_s390x.c" #endif