From 05b88d9d45eb70d6029f5120c9e606ae2ee92fb1 Mon Sep 17 00:00:00 2001 From: pcpa Date: Sun, 10 Aug 2014 11:48:35 -0300 Subject: [PATCH] ALPHA: Implement lightning Alpha port. * include/lightning/jit_alpha.h, lib/jit_alpha-cpu.c, lib/jit_alpha-fpu.c, lib/jit_alpha-sz.c, lib/jit_alpha.c: New files implementing a lightning Alpha port. Thanks to Trent Nelson and snakebit.net staff for providing access to an Alpha system. * check/float.tst, check/lightning.c, configure.ac, include/lightning.h, include/lightning/Makefile.am, include/lightning/jit_private.h, lib/Makefile.am, lib/jit_disasm.c, lib/jit_size.c, lib/lightning.c: Minor changes to adapt for the new Alpha port. --- ChangeLog | 14 + check/float.tst | 12 +- check/lightning.c | 9 +- configure.ac | 29 +- include/lightning.h | 9 +- include/lightning/Makefile.am | 4 + include/lightning/jit_alpha.h | 107 ++ include/lightning/jit_private.h | 7 +- lib/Makefile.am | 4 + lib/jit_alpha-cpu.c | 2641 +++++++++++++++++++++++++++++++ lib/jit_alpha-fpu.c | 1538 ++++++++++++++++++ lib/jit_alpha-sz.c | 350 ++++ lib/jit_alpha.c | 1253 +++++++++++++++ lib/jit_disasm.c | 10 + lib/jit_size.c | 2 + lib/lightning.c | 2 + 16 files changed, 5979 insertions(+), 12 deletions(-) create mode 100644 include/lightning/jit_alpha.h create mode 100644 lib/jit_alpha-cpu.c create mode 100644 lib/jit_alpha-fpu.c create mode 100644 lib/jit_alpha-sz.c create mode 100644 lib/jit_alpha.c diff --git a/ChangeLog b/ChangeLog index eb9201ea8..e3c7cc0e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2014-08-10 Paulo Andrade + + * include/lightning/jit_alpha.h, lib/jit_alpha-cpu.c, + lib/jit_alpha-fpu.c, lib/jit_alpha-sz.c, lib/jit_alpha.c: + New files implementing a lightning Alpha port. Thanks + to Trent Nelson and snakebit.net staff for providing access + to an Alpha system. + + * check/float.tst, check/lightning.c, configure.ac, + include/lightning.h, include/lightning/Makefile.am, + include/lightning/jit_private.h, lib/Makefile.am, + lib/jit_disasm.c, lib/jit_size.c, lib/lightning.c: + Minor changes to adapt for the new Alpha port. + 2014-08-10 Paulo Andrade * lib/lightning.c: Always mark JIT_RET and JIT_FRET as diff --git a/check/float.tst b/check/float.tst index 2cb51aff0..ae268a9f9 100644 --- a/check/float.tst +++ b/check/float.tst @@ -16,17 +16,25 @@ ok: #if __mips__ || __sparc__ || __hppa__ # define wnan x7f -#elif __arm__ || __aarch64__ +#elif __arm__ || __aarch64__ || __alpha__ # define wnan 0 #else # define wnan x80 #endif #if __mips__ || __arm__ || __ppc__ || __sparc__ || __hppa__ || __aarch64__ || __s390x__ # define wpinf x7f +#elif __alpha__ +/* (at least) bug compatible with gcc 4.2.3 -ieee */ +# define wpinf 0 #else # define wpinf x80 #endif -#define wninf x80 +#if __alpha__ +/* (at least) bug compatible with gcc 4.2.3 -ieee */ +# define wninf 0 +#else +# define wninf x80 +#endif /* ensure result is correct and 0 or 1 in the result register */ #define xtcmp(l, t, op, r0, f0, f1, li, ri) \ diff --git a/check/lightning.c b/check/lightning.c index f0fd19be6..72555be12 100644 --- a/check/lightning.c +++ b/check/lightning.c @@ -36,7 +36,7 @@ #endif /* The label_t identifier clashes with a system definitions */ -#if defined(_AIX) || defined(__sun__) +#if defined(_AIX) || defined(__sun__) || defined(__osf__) # define label_t l_label_t #endif @@ -44,6 +44,8 @@ # define DL_HANDLE RTLD_NEXT #elif defined(__sgi) static void *DL_HANDLE; +#elif defined(__osf__) +# define DL_HANDLE NULL #else # define DL_HANDLE RTLD_DEFAULT #endif @@ -4144,6 +4146,11 @@ main(int argc, char *argv[]) opt_short += snprintf(cmdline + opt_short, sizeof(cmdline) - opt_short, " -D__s390x__=1"); +#endif +#if defined(__alpha__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__alpha__=1"); #endif if ((parser.fp = popen(cmdline, "r")) == NULL) error("cannot execute %s", cmdline); diff --git a/configure.ac b/configure.ac index 7f63608be..2103498f8 100644 --- a/configure.ac +++ b/configure.ac @@ -23,6 +23,10 @@ AC_CONFIG_MACRO_DIR(m4) AC_CONFIG_HEADERS(config.h) +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_LIBTOOL + case "$target_cpu" in ia64) case "$host_os" in @@ -39,16 +43,25 @@ case "$target_cpu" in CFLAGS="$CFLAGS -D__c99 -Drestrict=";; *) ;; esac ;; + alpha*) + case "$host_os" in + osf*) + # Get proper varargs and mmap prototypes and definitions + CFLAGS="$CFLAGS -D_ANSI_C_SOURCE -D_XOPEN_SOURCE_EXTENDED -D_OSF_SOURCE -D_POSIX_C_SOURCE=199309L" + # Want to generate NaN with 0.0/0.0 and Inf with 1.0/0.0 + if test x$GCC = "xyes"; then + CFLAGS="$CFLAGS -mieee" + else + CFLAGS="$CFLAGS -ieee_with_no_inexact" + fi ;; + *) ;; + esac ;; *) ;; esac -AC_PROG_CC -AC_PROG_INSTALL -AC_PROG_LIBTOOL - AC_CHECK_FUNCS(mremap ffsl getopt_long_only isnan isinf,,) -AC_CHECK_HEADERS([getopt.h],,,) +AC_CHECK_HEADERS([getopt.h stdint.h],,,) AC_ARG_ENABLE(disassembler, AS_HELP_STRING([--enable-disassembler], @@ -100,7 +113,7 @@ AC_ARG_ENABLE(devel-get-jit-size, AM_CONDITIONAL(get_jit_size, [test $GET_JIT_SIZE = yes]) case "$host_os" in - *bsd*) SHLIB="" ;; + *bsd*|osf*) SHLIB="" ;; *hpux*) SHLIB="-ldld" ;; *) SHLIB="-ldl" ;; esac @@ -117,6 +130,7 @@ case "$target_cpu" in hppa*) cpu=hppa ;; aarch64) cpu=aarch64 ;; s390x) cpu=s390x ;; + alpha*) cpu=alpha ;; *) ;; esac AM_CONDITIONAL(cpu_arm, [test cpu-$cpu = cpu-arm]) @@ -128,6 +142,7 @@ 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]) +AM_CONDITIONAL(cpu_alpha, [test cpu-$cpu = cpu-alpha]) # Test x87 if both, x87 and sse2 available ac_cv_test_x86_x87= @@ -221,7 +236,7 @@ AM_CONDITIONAL(test_x86_x87, [test x$ac_cv_test_x86_x87 = xyes]) AM_CONDITIONAL(test_arm_arm, [test x$ac_cv_test_arm_arm = xyes]) AM_CONDITIONAL(test_arm_swf, [test x$ac_cv_test_arm_swf = xyes]) -AM_CONDITIONAL(test_nodata, [test cpu-$cpu = cpu-mips -o cpu-$cpu = cpu-ppc -o cpu-$cpu = cpu-sparc -o cpu-$cpu = cpu-x86 -o cpu-$cpu = cpu-ia64 -o cpu-$cpu = cpu-hppa -o cpu-$cpu = cpu-s390x]) +AM_CONDITIONAL(test_nodata, [test cpu-$cpu = cpu-mips -o cpu-$cpu = cpu-ppc -o cpu-$cpu = cpu-sparc -o cpu-$cpu = cpu-x86 -o cpu-$cpu = cpu-ia64 -o cpu-$cpu = cpu-hppa -o cpu-$cpu = cpu-s390x -o cpu-$cpu = cpu-alpha]) if test $cpu = arm; then AC_CHECK_LIB(m, sqrtf, , diff --git a/include/lightning.h b/include/lightning.h index 2f6d43f94..fc9fb9dfa 100644 --- a/include/lightning.h +++ b/include/lightning.h @@ -26,12 +26,17 @@ #include #include -#include +#if HAVE_STDINT_H +# include +#endif #include #if defined(__hpux) && defined(__hppa__) # include #endif +#if defined(__alpha__) && defined(__osf__) +# include +#endif #ifndef __WORDSIZE # if defined(WORDSIZE) /* ppc darwin */ @@ -137,6 +142,8 @@ typedef jit_int32_t jit_fpr_t; # include #elif defined(__s390x__) # include +#elif defined(__alpha__) +# include #endif #define jit_flag_node 0x00000001 /* patch node not absolute */ diff --git a/include/lightning/Makefile.am b/include/lightning/Makefile.am index 05e07b60b..5e3fef3af 100644 --- a/include/lightning/Makefile.am +++ b/include/lightning/Makefile.am @@ -55,3 +55,7 @@ if cpu_s390x lightning_include_HEADERS = \ jit_s390x.h endif +if cpu_alpha +lightning_include_HEADERS = \ + jit_alpha.h +endif diff --git a/include/lightning/jit_alpha.h b/include/lightning/jit_alpha.h new file mode 100644 index 000000000..99771b621 --- /dev/null +++ b/include/lightning/jit_alpha.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2014 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#ifndef _jit_alpha_h +#define _jit_alpha_h + +#define JIT_HASH_CONSTS 1 +#define JIT_NUM_OPERANDS 3 + +/* + * Types + */ +#define JIT_FP _FP +typedef enum { +#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 6) +#define jit_r(i) (_S0 + (i)) +#define jit_r_num() 3 +#define jit_v(i) (_S3 + (i)) +#define jit_v_num() 3 +#define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 6) +#define jit_f(i) (_F2 + (i)) +#define jit_f_num() 8 + /* Volatile - Assembly temporary register */ + _AT, + /* Volatile - Return value register */ + _V0, + /* Volatile - Temporary registers */ + _T0, _T1, _T2, _T3, + _T4, _T5, _T6, _T7, + _T8, _T9, _T10, _T11, + /* FIXME Use callee save register for r0-r2 (instead of 12+ JIT_RN + * and 6 JIT_VN because division must call a function) + * FIX would be to create proper functions that do not clobber + * registers and inject/inline them in the jit */ +#define JIT_R0 _S0 +#define JIT_R1 _S1 +#define JIT_R2 _S2 +#define JIT_V0 _S3 +#define JIT_V1 _S4 +#define JIT_V2 _S5 + /* Nonvolatile - Saved registers */ + _S0, _S1, _S2, _S3, + _S4, _S5, + /* Nonvolatile - Frame pointer */ + _FP, + /* Volatile - Argument registers */ + _A5, _A4, _A3, _A2, + _A1, _A0, + /* Volatile - Return address register */ + _RA, + /* Volatile - Temporary register */ + _PV, + /* Nonvolatile - Global pointer */ + _GP, + /* Nonvolatile - Stack pointer */ + _SP, + /* Constant RAZ / writes ignored */ + _ZERO, +#define JIT_F0 _F2 +#define JIT_F1 _F3 +#define JIT_F2 _F4 +#define JIT_F3 _F5 +#define JIT_F4 _F6 +#define JIT_F5 _F7 +#define JIT_F6 _F8 +#define JIT_F7 _F9 + /* Volatile - Return value register (real part) */ + _F0, + /* Volatile - Return value register (imaginary part) */ + _F1, + /* Nonvolatile - Saved registers */ + _F2, _F3, _F4, _F5, + _F6, _F7, _F8, _F9, + /* Volatile - Temporary registers */ + _F10, _F11, _F12, _F13, + _F14, _F15, + /* Volatile - Argument registers */ + _F21, _F20, _F19, _F18, + _F17, _F16, + /* Volatile - Temporary registers */ + _F22, _F23, _R24, _F25, + _F26, _F27, _F28, _F29, + _F30, + /* Constant - RAZ / writes ignored */ + _F31, + /* Lightning internal invalid register identifier */ + _NOREG, +#define JIT_NOREG _NOREG +} jit_reg_t; + +#endif /* _jit_alpha_h */ diff --git a/include/lightning/jit_private.h b/include/lightning/jit_private.h index 1915ce256..9b50d1f86 100644 --- a/include/lightning/jit_private.h +++ b/include/lightning/jit_private.h @@ -116,6 +116,11 @@ typedef jit_uint64_t jit_regset_t; # define JIT_RET _R2 # define JIT_FRET _F0 typedef jit_uint32_t jit_regset_t; +#elif defined(__alpha__) +# define JIT_SP _SP +# define JIT_RET _V0 +# define JIT_FRET _F0 +typedef jit_uint64_t jit_regset_t; #endif #define jit_size(vector) (sizeof(vector) / sizeof((vector)[0])) @@ -355,7 +360,7 @@ struct jit_compiler { jit_int32_t rout; /* first output register */ jit_int32_t breg; /* base register for prolog/epilog */ #endif -#if __mips__ || __ia64__ +#if __mips__ || __ia64__ || __alpha__ jit_int32_t carry; #define jit_carry _jitc->carry #endif diff --git a/lib/Makefile.am b/lib/Makefile.am index f9f44f5e4..e1f99ce44 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -36,6 +36,10 @@ EXTRA_DIST = \ jit_aarch64-cpu.c \ jit_aarch64-fpu.c \ jit_aarch64-sz.c \ + jit_alpha.c \ + jit_alpha-cpu.c \ + jit_alpha-fpu.c \ + jit_alpha-sz.c \ jit_arm.c \ jit_arm-cpu.c \ jit_arm-swf.c \ diff --git a/lib/jit_alpha-cpu.c b/lib/jit_alpha-cpu.c new file mode 100644 index 000000000..a43c94ce9 --- /dev/null +++ b/lib/jit_alpha-cpu.c @@ -0,0 +1,2641 @@ +/* + * Copyright (C) 2014 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# define _u2(v) ((v) & 0x3) +# define _s2_p(v) ((v) >= -0x2 && (v) <= 0x1) +# define _u2_p(v) ((v) >= 0 && (v) <= 0x3) +# define _u5(v) ((v) & 0x1f) +# define _s5_p(v) ((v) >= -0x10 && (v) <= 0xf) +# define _u5_p(v) ((v) >= 0 && (v) <= 0x1f) +# define _u6(v) ((v) & 0x3f) +# define _s6_p(v) ((v) >= -0x20 && (v) <= 0x1f) +# define _u6_p(v) ((v) >= 0 && (v) <= 0x3f) +# define _u7(v) ((v) & 0x7f) +# define _s7_p(v) ((v) >= -0x40 && (v) <= 0x3f) +# define _u7_p(v) ((v) >= 0 && (v) <= 0x7f) +# define _u8(v) ((v) & 0xff) +# define _s8_p(v) ((v) >= -0x80 && (v) <= 0x7f) +# define _u8_p(v) ((v) >= 0 && (v) <= 0xff) +# define _u11(v) ((v) & 0x7ff) +# define _s11_p(v) ((v) >= -0x400 && (v) <= 0x3ff) +# define _u11_p(v) ((v) >= 0 && (v) <= 0x7ff) +# define _u14(v) ((v) & 0x3fff) +# define _s14_p(v) ((v) >= -0x2000 && (v) <= 0x1fff) +# define _u14_p(v) ((v) >= 0 && (v) <= 0x3fff) +# define _u16(v) ((v) & 0xffff) +# define _s16_p(v) ((v) >= -0x8000 && (v) <= 0x7fff) +# define _u16_p(v) ((v) >= 0 && (v) <= 0xffff) +# define _u21(v) ((v) & 0x1fffff) +# define _s21_p(v) ((v) >= -0x100000 && (v) <= 0xfffff) +# define _u21_p(v) ((v) >= 0 && (v) <= 0x1fffff) +# define _u26(v) ((v) & 0x3ffffff) +# define _s26_p(v) ((v) >= -0x2000000 && (v) <= 0x1ffffff) +# define _u26_p(v) ((v) >= 0 && (v) <= 0x3ffffff) +# define _u32(v) ((v) & 0xffffffff) +# define _s32_p(v) ((v) >= -0x80000000 && (v) <= 0x7fffffff) +# define _u32_p(v) ((v) >= 0 && (v) <= 0xffffffff) +# define ii(i) *_jit->pc.ui++ = i +# define stack_framesize 128 +# define _S0_REGNO 0x09 +# define _S1_REGNO 0x0a +# define _S2_REGNO 0x0b +# define _S3_REGNO 0x0c +# define _S4_REGNO 0x0d +# define _S5_REGNO 0x0e +# define _FP_REGNO 0x0f +# define _A0_REGNO 0x10 +# define _A1_REGNO 0x11 +# define _A2_REGNO 0x12 +# define _V0_REGNO 0x00 +# define _T0_REGNO 0x01 +# define _T1_REGNO 0x02 +# define _RA_REGNO 0x1a +# define _PV_REGNO 0x1b +# define _GP_REGNO 0x1d +# define _SP_REGNO 0x1e +# define _R31_REGNO 0x1f +# define Pcd(o,n) _Pcd(_jit,o,n) +static void _Pcd(jit_state_t*,int,unsigned int) maybe_unused; +# define Bra(o,ra,d) _Bra(_jit,o,ra,d) +static void _Bra(jit_state_t*,int,int,int); +# define Mem(o,ra,rb,d) _Mem(_jit,o,ra,rb,d) +static void _Mem(jit_state_t*,int,int,int,unsigned int); +# define Mbr(o,ra,rb,h,d) _Mbr(_jit,o,ra,rb,h,d) +static void _Mbr(jit_state_t*,int,int,int,int,int); +# define Opr(o,ra,rb,f,rc) _Opr(_jit,o,ra,rb,f,rc) +static void _Opr(jit_state_t*,int,int,int,unsigned int,int); +# define Opi(o,ra,i,f,rc) _Opi(_jit,o,ra,i,f,rc) +static void _Opi(jit_state_t*,int,int,unsigned int,unsigned int,int); +# define ADDL(ra,rb,rc) Opr(0x10,ra,rb,0x00,rc) +# define ADDLi(ra,im,rc) Opi(0x10,ra,im,0x00,rc) +# define ADDL_V(ra,rb,rc) Opr(0x10,ra,rb,0x40,rc) +# define ADDL_Vi(ra,im,rc) Opi(0x10,ra,im,0x40,rc) +# define ADDQ(ra,rb,rc) Opr(0x10,ra,rb,0x20,rc) +# define ADDQi(ra,im,rc) Opi(0x10,ra,im,0x20,rc) +# define ADDQ_V(ra,rb,rc) Opr(0x10,ra,rb,0x60,rc) +# define ADDQ_Vi(ra,im,rc) Opi(0x10,ra,im,0x60,rc) +# define AMASK(rb,rc) Opr(0x11,_R31_REGNO,rb,0x61,rc) +# define AND(ra,rb,rc) Opr(0x11,ra,rb,0x00,rc) +# define ANDi(ra,im,rc) Opi(0x11,ra,im,0x00,rc) +# define BEQ(ra,d) Bra(0x39,ra,d) +# define BGE(ra,d) Bra(0x3e,ra,d) +# define BGT(ra,d) Bra(0x3f,ra,d) +# define BIC(ra,rb,rc) Opr(0x11,ra,rb,0x08,rc) +# define ANDNOT(ra,rb,rc) BIC(ra,rb,rc) +# define BICi(ra,im,rc) Opi(0x11,ra,im,0x08,rc) +# define ANDNOTi(ra,im,rc) BICi(ra,im,rc) +# define BIS(ra,rb,rc) Opr(0x11,ra,rb,0x20,rc) +# define BISi(ra,im,rc) Opi(0x11,ra,im,0x20,rc) +# define OR(ra,rb,rc) BIS(ra,rb,rc) +# define ORi(ra,im,rc) BISi(ra,im,rc) +# define BLBC(ra,d) Bra(0x38,ra,d) +# define BLBS(ra,d) Bra(0x3c,ra,d) +# define BLE(ra,d) Bra(0x3b,ra,d) +# define BLT(ra,d) Bra(0x3a,ra,d) +# define BNE(ra,d) Bra(0x3d,ra,d) +# define BR(ra,d) Bra(0x30,ra,d) +# define BSR(ra,d) Bra(0x34,ra,d) +# define CALL_PAL(c) Pcd(0x00,c) +# define CMOVEQ(ra,rb,rc) Opr(0x11,ra,rb,0x24,rc) +# define CMOVEQi(ra,im,rc) Opi(0x11,ra,im,0x24,rc) +# define CMOVGE(ra,rb,rc) Opr(0x11,ra,rb,0x46,rc) +# define CMOVGEi(ra,im,rc) Opi(0x11,ra,im,0x46,rc) +# define CMOVGT(ra,rb,rc) Opr(0x11,ra,rb,0x66,rc) +# define CMOVGTi(ra,im,rc) Opi(0x11,ra,im,0x66,rc) +# define CMOVLBC(ra,rb,rc) Opr(0x11,ra,rb,0x16,rc) +# define CMOVLBCi(ra,im,rc) Opi(0x11,ra,im,0x16,rc) +# define CMOVLBS(ra,rb,rc) Opr(0x11,ra,rb,0x14,rc) +# define CMOVLBSi(ra,im,rc) Opi(0x11,ra,im,0x14,rc) +# define CMOVLE(ra,rb,rc) Opr(0x11,ra,rb,0x64,rc) +# define CMOVLEi(ra,im,rc) Opi(0x11,ra,im,0x64,rc) +# define CMOVLT(ra,rb,rc) Opr(0x11,ra,rb,0x44,rc) +# define CMOVLTi(ra,im,rc) Opi(0x11,ra,im,0x44,rc) +# define CMOVNE(ra,rb,rc) Opr(0x11,ra,rb,0x26,rc) +# define CMOVNEi(ra,im,rc) Opi(0x11,ra,im,0x26,rc) +# define CMPBGE(ra,rb,rc) Opr(0x10,ra,rb,0x0f,rc) +# define CMPBGEi(ra,im,rc) Opi(0x10,ra,im,0x0f,rc) +# define CMPEQ(ra,rb,rc) Opr(0x10,ra,rb,0x2d,rc) +# define CMPEQi(ra,im,rc) Opi(0x10,ra,im,0x2d,rc) +# define CMPLE(ra,rb,rc) Opr(0x10,ra,rb,0x6d,rc) +# define CMPLEi(ra,im,rc) Opi(0x10,ra,im,0x6d,rc) +# define CMPLT(ra,rb,rc) Opr(0x10,ra,rb,0x4d,rc) +# define CMPLTi(ra,im,rc) Opi(0x10,ra,im,0x4d,rc) +# define CMPULE(ra,rb,rc) Opr(0x10,ra,rb,0x3d,rc) +# define CMPULEi(ra,im,rc) Opi(0x10,ra,im,0x3d,rc) +# define CMPULT(ra,rb,rc) Opr(0x10,ra,rb,0x1d,rc) +# define CMPULTi(ra,im,rc) Opi(0x10,ra,im,0x1d,rc) +# define CTLZ(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x32,rc) +# define CTPOP(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x30,rc) +# define CTTZ(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x33,rc) +# define ECB(rb,d) Mem(0x18,_R31_REGNO,rb,0xe800) +# define EQV(ra,rb,rc) Opr(0x11,ra,rb,0x48,rc) +# define XORNOT(ra,rb,rc) EQV(ra,rb,rc) +# define EQVi(ra,im,rc) Opi(0x11,ra,im,0x48,rc) +# define XORNOTi(ra,im,rc) EQVi(ra,im,rc) +# define EXCB() Mem(0x18,0,0,0x0400) +# define EXTBL(ra,rb,rc) Opr(0x12,ra,rb,0x06,rc) +# define EXTBLi(ra,im,rc) Opi(0x12,ra,im,0x06,rc) +# define EXTLH(ra,rb,rc) Opr(0x12,ra,rb,0x6a,rc) +# define EXTLHi(ra,im,rc) Opi(0x12,ra,im,0x6a,rc) +# define EXTLL(ra,rb,rc) Opr(0x12,ra,rb,0x26,rc) +# define EXTLLi(ra,im,rc) Opi(0x12,ra,im,0x26,rc) +# define EXTQH(ra,rb,rc) Opr(0x12,ra,rb,0x7a,rc) +# define EXTQHi(ra,im,rc) Opi(0x12,ra,im,0x7a,rc) +# define EXTQL(ra,rb,rc) Opr(0x12,ra,rb,0x36,rc) +# define EXTQLi(ra,im,rc) Opi(0x12,ra,im,0x36,rc) +# define EXTWH(ra,rb,rc) Opr(0x12,ra,rb,0x5a,rc) +# define EXTWHi(ra,im,rc) Opi(0x12,ra,im,0x5a,rc) +# define EXTWL(ra,rb,rc) Opr(0x12,ra,rb,0x16,rc) +# define EXTWLi(ra,im,rc) Opi(0x12,ra,im,0x16,rc) +# define FETCH(rb,d) Mem(0x18,_R31_REGNO,rb,0x8000) +# define FETCH_Mem(rb,d) Mem(0x18,_R31_REGNO,rb,0xa000) +/* FIXME IMPLVER not disassembled */ +# define IMPLVER(rc) Opr(0x11,_R31_REGNO,1,0x6c,rc) +# define INSBL(ra,rb,rc) Opr(0x12,ra,rb,0x0b,rc) +# define INSBLi(ra,im,rc) Opi(0x12,ra,im,0x0b,rc) +# define INSLH(ra,rb,rc) Opr(0x12,ra,rb,0x67,rc) +# define INSLHi(ra,im,rc) Opi(0x12,ra,im,0x67,rc) +# define INSLL(ra,rb,rc) Opr(0x12,ra,rb,0x2b,rc) +# define INSLLi(ra,im,rc) Opi(0x12,ra,im,0x2b,rc) +# define INSQH(ra,rb,rc) Opr(0x12,ra,rb,0x77,rc) +# define INSQHi(ra,im,rc) Opi(0x12,ra,im,0x77,rc) +# define INSQL(ra,rb,rc) Opr(0x12,ra,rb,0x3b,rc) +# define INSQLi(ra,im,rc) Opi(0x12,ra,im,0x3b,rc) +# define INSWH(ra,rb,rc) Opr(0x12,ra,rb,0x57,rc) +# define INSWHi(ra,im,rc) Opi(0x12,ra,im,0x57,rc) +# define INSWL(ra,rb,rc) Opr(0x12,ra,rb,0x1b,rc) +# define INSWLi(ra,im,rc) Opi(0x12,ra,im,0x1b,rc) +# define JMP(ra,rb,d) Mbr(0x1a,ra,rb,0,d) +# define JSR(ra,rb,d) Mbr(0x1a,ra,rb,1,d) +# define JSR_COROUTINE(ra,rb,d) Mbr(0x1a,ra,rb,3,d) +# define JCR(ra,rb,rd) JSR_COROUTINE(ra,rb,d) +# define LDA(ra,rb,d) Mem(0x08,ra,rb,d) +# define LDAH(ra,rb,d) Mem(0x09,ra,rb,d) +# define LDBU(ra,rb,d) Mem(0x0a,ra,rb,d) +# define LDWU(ra,rb,d) Mem(0x0c,ra,rb,d) +# define LDL(ra,rb,d) Mem(0x28,ra,rb,d) +# define LDL_L(ra,rb,d) Mem(0x2a,ra,rb,d) +# define LDQ(ra,rb,d) Mem(0x29,ra,rb,d) +# define LDQ_L(ra,rb,d) Mem(0x2b,ra,rb,d) +# define LDQ_U(ra,rb,d) Mem(0x0b,ra,rb,d) +# define MAXSB8(ra,rb,rc) Opr(0x1c,ra,rb,0x3e,rc) +# define MAXSW4(ra,rb,rc) Opr(0x1c,ra,rb,0x3f,rc) +# define MAXSUB8(ra,rb,rc) Opr(0x1c,ra,rb,0x3c,rc) +# define MAXSUW4(ra,rb,rc) Opr(0x1c,ra,rb,0x3d,rc) +# define MB() Mem(0x18,_R31_REGNO,_R31_REGNO,0x4000) +# define MINSB8(ra,rb,rc) Opr(0x1c,ra,rb,0x38,rc) +# define MINSW4(ra,rb,rc) Opr(0x1c,ra,rb,0x39,rc) +# define MINSUB8(ra,rb,rc) Opr(0x1c,ra,rb,0x3a,rc) +# define MINSUW4(ra,rb,rc) Opr(0x1c,ra,rb,0x3b,rc) +# define MSKBL(ra,rb,rc) Opr(0x12,ra,rb,0x02,rc) +# define MSKBLi(ra,im,rc) Opi(0x12,ra,im,0x02,rc) +# define MSKLH(ra,rb,rc) Opr(0x12,ra,rb,0x62,rc) +# define MSKLHi(ra,im,rc) Opi(0x12,ra,im,0x62,rc) +# define MSKLL(ra,rb,rc) Opr(0x12,ra,rb,0x22,rc) +# define MSKLLi(ra,im,rc) Opi(0x12,ra,im,0x22,rc) +# define MSKQH(ra,rb,rc) Opr(0x12,ra,rb,0x72,rc) +# define MSKQHi(ra,im,rc) Opi(0x12,ra,im,0x72,rc) +# define MSKQL(ra,rb,rc) Opr(0x12,ra,rb,0x32,rc) +# define MSKQLi(ra,im,rc) Opi(0x12,ra,im,0x32,rc) +# define MSKWH(ra,rb,rc) Opr(0x12,ra,rb,0x52,rc) +# define MSKWHi(ra,im,rc) Opi(0x12,ra,im,0x52,rc) +# define MSKWL(ra,rb,rc) Opr(0x12,ra,rb,0x12,rc) +# define MSKWLi(ra,im,rc) Opi(0x12,ra,im,0x12,rc) +# define MULL(ra,rb,rc) Opr(0x13,ra,rb,0x00,rc) +# define MULLi(ra,im,rc) Opi(0x13,ra,im,0x00,rc) +# define MULL_V(ra,rb,rc) Opr(0x13,ra,rb,0x40,rc) +# define MULL_Vi(ra,im,rc) Opi(0x13,ra,im,0x40,rc) +# define MULQ(ra,rb,rc) Opr(0x13,ra,rb,0x20,rc) +# define MULQi(ra,im,rc) Opi(0x13,ra,im,0x20,rc) +# define MULQ_V(ra,rb,rc) Opr(0x13,ra,rb,0x60,rc) +# define MULQ_Vi(ra,im,rc) Opi(0x13,ra,im,0x60,rc) +# define ORNOT(ra,rb,rc) Opr(0x11,ra,rb,0x28,rc) +# define ORNOTi(ra,im,rc) Opi(0x11,ra,im,0x28,rc) +# define PERR(ra,rb,rc) Opr(0x1c,ra,rb,0x31,rc) +# define PKLB(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x37,rc) +# define PKWB(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x36,rc) +/* FIXME PREFETCH* not disassembled */ +# define PREFETCH(rb,d) Mem(0x28,_R31_REGNO,rb,d) +# define PREFETCH_EN(rb,d) Mem(0x29,_R31_REGNO,rb,d) +# define PREFETCH_M(rb,d) Mem(0x22,_R31_REGNO,rb,d) +# define PREFETCH_MEN(rb,d) Mem(0x23,_R31_REGNO,rb,d) +# define RC(ra) Mem(0x18,ra,_R31_REGNO,0xe000) +# define RET(ra,rb,d) Mbr(0x1a,ra,rb,2,d) +# define RPCC(ra) Mem(0x18,ra,_R31_REGNO,0xc000) +# define RS(ra) Mem(0x18,ra,_R31_REGNO,0xf000) +# define S4ADDL(ra,rb,rc) Opr(0x10,ra,rb,0x02,rc) +# define S4ADDi(ra,im,rc) Opi(0x10,ra,im,0x02,rc) +# define S4ADDQ(ra,rb,rc) Opr(0x10,ra,rb,0x22,rc) +# define S4ADDQi(ra,im,rc) Opi(0x10,ra,im,0x22,rc) +# define S4SUBL(ra,rb,rc) Opr(0x10,ra,rb,0x0b,rc) +# define S4SUBLi(ra,im,rc) Opi(0x10,ra,im,0x0b,rc) +# define S4SUBQ(ra,rb,rc) Opr(0x10,ra,rb,0x2b,rc) +# define S4SUBQi(ra,im,rc) Opi(0x10,ra,im,0x2b,rc) +# define S8ADDL(ra,rb,rc) Opr(0x10,ra,rb,0x12,rc) +# define S8ADDLi(ra,im,rc) Opi(0x10,ra,im,0x12,rc) +# define S8ADDQ(ra,rb,rc) Opr(0x10,ra,rb,0x32,rc) +# define S8ADDQi(ra,im,rc) Opi(0x10,ra,im,0x32,rc) +# define S8SUBL(ra,rb,rc) Opr(0x10,ra,rb,0x1b,rc) +# define S8SUBLi(ra,im,rc) Opi(0x10,ra,im,0x1b,rc) +# define S8SUBQ(ra,rb,rc) Opr(0x10,ra,rb,0x3b,rc) +# define S8SUBQi(ra,im,rc) Opi(0x10,ra,im,0x3b,rc) +# define SEXTB(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x00,rc) +/* FIXME not disassembled */ +# define SEXTBi(im,rc) Opi(0x1c,_R31_REGNO,im,0x00,rc) +# define SEXTW(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x01,rc) +/* FIXME not disassembled */ +# define SEXTWi(im,rc) Opi(0x1c,_R31_REGNO,im,0x01,rc) +# define SLL(ra,rb,rc) Opr(0x12,ra,rb,0x39,rc) +# define SLLi(ra,im,rc) Opi(0x12,ra,im,0x39,rc) +# define SRA(ra,rb,rc) Opr(0x12,ra,rb,0x3c,rc) +# define SRAi(ra,im,rc) Opi(0x12,ra,im,0x3c,rc) +# define SRL(ra,rb,rc) Opr(0x12,ra,rb,0x34,rc) +# define SRLi(ra,im,rc) Opi(0x12,ra,im,0x34,rc) +# define STB(ra,rb,d) Mem(0x0e,ra,rb,d) +# define STL(ra,rb,d) Mem(0x2c,ra,rb,d) +# define STL_C(ra,rb,d) Mem(0x2e,ra,rb,d) +# define STQ(ra,rb,d) Mem(0x2d,ra,rb,d) +# define STQ_C(ra,rb,d) Mem(0x2f,ra,rb,d) +# define STQ_U(ra,rb,d) Mem(0x0f,ra,rb,d) +# define STW(ra,rb,d) Mem(0x0d,ra,rb,d) +# define SUBL(ra,rb,rc) Opr(0x10,ra,rb,0x09,rc) +# define SUBLi(ra,im,rc) Opi(0x10,ra,im,0x09,rc) +# define SUBL_V(ra,rb,rc) Opr(0x10,ra,rb,0x49,rc) +# define SUBL_Vi(ra,im,rc) Opi(0x10,ra,im,0x49,rc) +# define SUBQ(ra,rb,rc) Opr(0x10,ra,rb,0x29,rc) +# define SUBQi(ra,im,rc) Opi(0x10,ra,im,0x29,rc) +# define SUBQ_V(ra,rb,rc) Opr(0x10,ra,rb,0x69,rc) +# define SUBQ_Vi(ra,im,rc) Opi(0x10,ra,im,0x69,rc) +# define TRAPB() Mem(0x18,_R31_REGNO,_R31_REGNO,0x0000) +# define UMULH(ra,rb,rc) Opr(0x13,ra,rb,0x30,rc) +# define UMULHi(ra,im,rc) Opi(0x13,ra,im,0x30,rc) +# define UNPKBL(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x35,rc) +# define UNPKBW(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x34,rc) +# define WH64(ra) Mem(0x18,ra,_R31_REGNO,0xf800) +# define WH64EN(ra) Mem(0x18,ra,_R31_REGNO,0xfc00) +# define WMB() Mem(0x18,_R31_REGNO,_R31_REGNO,0x4400) +# define XOR(ra,rb,rc) Opr(0x11,ra,rb,0x40,rc) +# define XORi(ra,im,rc) Opi(0x11,ra,im,0x40,rc) +# define ZAP(ra,rb,rc) Opr(0x12,ra,rb,0x30,rc) +# define ZAPi(ra,im,rc) Opi(0x12,ra,im,0x30,rc) +# define ZAPNOT(ra,rb,rc) Opr(0x12,ra,rb,0x31,rc) +# define ZAPNOTi(ra,im,rc) Opi(0x12,ra,im,0x31,rc) +# define NOP() BIS(_R31_REGNO,_R31_REGNO,_R31_REGNO) +# define MOV(ra,rc) BIS(ra,ra,rc) +# define MOVi(im,rc) BISi(_R31_REGNO,im,rc) +# define NEGL(ra,rc) SUBL(_R31_REGNO,ra,rc) +# define NEGQ(ra,rc) SUBQ(_R31_REGNO,ra,rc) +# define NOT(ra,rc) ORNOT(_R31_REGNO,ra,rc) +# define movr(r0,r1) _movr(_jit,r0,r1) +static void _movr(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi(r0,i0) _movi(_jit,r0,i0) +static void _movi(jit_state_t*,jit_int32_t,jit_word_t); +# define movi_p(r0,i0) _movi_p(_jit,r0,i0) +static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t); +# define negr(r0,r1) NEGQ(r1,r0) +# define comr(r0,r1) NOT(r1,r0) +# define addr(r0,r1,r2) ADDQ(r1,r2,r0) +# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0) +static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addcr(r0,r1,i0) _addcr(_jit,r0,r1,i0) +static void _addcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addci(r0,r1,i0) _addci(_jit,r0,r1,i0) +static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define addxr(r0,r1,i0) _addxr(_jit,r0,r1,i0) +static void _addxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0) +static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subr(r0,r1,r2) SUBQ(r1,r2,r0) +# define subi(r0,r1,i0) _subi(_jit,r0,r1,i0) +static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subcr(r0,r1,i0) _subcr(_jit,r0,r1,i0) +static void _subcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subci(r0,r1,i0) _subci(_jit,r0,r1,i0) +static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define subxr(r0,r1,i0) _subxr(_jit,r0,r1,i0) +static void _subxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subxi(r0,r1,i0) _subxi(_jit,r0,r1,i0) +static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define mulr(r0,r1,r2) MULQ(r1,r2,r0) +# define muli(r0,r1,i0) _muli(_jit,r0,r1,i0) +static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr(r0,r1,r2,r3) _qmulr(_jit,r0,r1,r2,r3) +static void _qmulr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qmuli(r0,r1,r2,i0) _qmuli(_jit,r0,r1,r2,i0) +static void _qmuli(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +# define qmulr_u(r0,r1,r2,r3) _qmulr_u(_jit,r0,r1,r2,r3) +static void _qmulr_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define qmuli_u(r0,r1,r2,i0) _qmuli_u(_jit,r0,r1,r2,i0) +static void _qmuli_u(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +static jit_word_t __idiv(jit_word_t, jit_word_t); +# define divr(r0,r1,r2) _divr(_jit,r0,r1,r2) +static void _divr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi(r0,r1,i0) _divi(_jit,r0,r1,i0) +static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +static jit_uword_t __udiv(jit_uword_t, jit_uword_t); +# define divr_u(r0,r1,r2) _divr_u(_jit,r0,r1,r2) +static void _divr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0) +static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +static jit_word_t __irem(jit_word_t, jit_word_t); +# define remr(r0,r1,r2) _remr(_jit,r0,r1,r2) +static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi(r0,r1,i0) _remi(_jit,r0,r1,i0) +static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +static jit_uword_t __urem(jit_uword_t, jit_uword_t); +# define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2) +static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0) +static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +static jit_word_t __idivrem(jit_word_t, jit_word_t, jit_word_t*); +# define qdivr(r0,r1,r2,r3) _qdivr(_jit,r0,r1,r2,r3) +static void _qdivr(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define qdivi(r0,r1,r2,i0) _qdivi(_jit,r0,r1,r2,i0) +static void _qdivi(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +static jit_word_t __udivrem(jit_uword_t, jit_uword_t, jit_uword_t*); +# define qdivr_u(r0,r1,r2,r3) _qdivr_u(_jit,r0,r1,r2,r3) +static void _qdivr_u(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define qdivi_u(r0,r1,r2,i0) _qdivi_u(_jit,r0,r1,r2,i0) +static void _qdivi_u(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t); +# define lshr(r0,r1,r2) SLL(r1,r2,r0) +# define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0) +static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr(r0,r1,r2) SRA(r1,r2,r0) +# define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0) +static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define rshr_u(r0,r1,r2) SRL(r1,r2,r0) +# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0) +static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define andr(r0,r1,r2) AND(r1,r2,r0) +# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0) +static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define orr(r0,r1,r2) OR(r1,r2,r0) +# define ori(r0,r1,i0) _ori(_jit,r0,r1,i0) +static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define xorr(r0,r1,r2) XOR(r1,r2,r0) +# define xori(r0,r1,i0) _xori(_jit,r0,r1,i0) +static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ltr(r0,r1,r2) CMPLT(r1,r2,r0) +# define lti(r0,r1,i0) _lti(_jit,r0,r1,i0) +static void _lti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ltr_u(r0,r1,r2) CMPULT(r1,r2,r0) +# define lti_u(r0,r1,i0) _lti_u(_jit,r0,r1,i0) +static void _lti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ler(r0,r1,r2) CMPLE(r1,r2,r0) +# define lei(r0,r1,i0) _lei(_jit,r0,r1,i0) +static void _lei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ler_u(r0,r1,r2) CMPULE(r1,r2,r0) +# define lei_u(r0,r1,i0) _lei_u(_jit,r0,r1,i0) +static void _lei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define eqr(r0,r1,r2) CMPEQ(r1,r2,r0) +# define eqi(r0,r1,i0) _eqi(_jit,r0,r1,i0) +static void _eqi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ger(r0,r1,r2) CMPLE(r2,r1,r0) +# define gei(r0,r1,i0) _gei(_jit,r0,r1,i0) +static void _gei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ger_u(r0,r1,r2) CMPULE(r2,r1,r0) +# define gei_u(r0,r1,i0) _gei_u(_jit,r0,r1,i0) +static void _gei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define gtr(r0,r1,r2) CMPLT(r2,r1,r0) +# define gti(r0,r1,i0) _gti(_jit,r0,r1,i0) +static void _gti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define gtr_u(r0,r1,r2) CMPULT(r2,r1,r0) +# define gti_u(r0,r1,i0) _gti_u(_jit,r0,r1,i0) +static void _gti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ner(r0,r1,r2) _ner(_jit,r0,r1,r2) +static void _ner(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define nei(r0,r1,i0) _nei(_jit,r0,r1,i0) +static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define bltr(i0,r0,r1) _bltr(_jit,i0,r0,r1) +static jit_word_t _bltr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blti(i0,r0,i1) _blti(_jit,i0,r0,i1) +static jit_word_t _blti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bltr_u(i0,r0,r1) _bltr_u(_jit,i0,r0,r1) +static jit_word_t _bltr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blti_u(i0,r0,i1) _blti_u(_jit,i0,r0,i1) +static jit_word_t _blti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bler(i0,r0,r1) _bler(_jit,i0,r0,r1) +static jit_word_t _bler(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blei(i0,r0,i1) _blei(_jit,i0,r0,i1) +static jit_word_t _blei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bler_u(i0,r0,r1) _bler_u(_jit,i0,r0,r1) +static jit_word_t _bler_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blei_u(i0,r0,i1) _blei_u(_jit,i0,r0,i1) +static jit_word_t _blei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define beqr(i0,r0,r1) _beqr(_jit,i0,r0,r1) +static jit_word_t _beqr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define beqi(i0,r0,i1) _beqi(_jit,i0,r0,i1) +static jit_word_t _beqi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bger(i0,r0,r1) _bger(_jit,i0,r0,r1) +static jit_word_t _bger(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgei(i0,r0,i1) _bgei(_jit,i0,r0,i1) +static jit_word_t _bgei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bger_u(i0,r0,r1) _bger_u(_jit,i0,r0,r1) +static jit_word_t _bger_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgei_u(i0,r0,i1) _bgei_u(_jit,i0,r0,i1) +static jit_word_t _bgei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bgtr(i0,r0,r1) _bgtr(_jit,i0,r0,r1) +static jit_word_t _bgtr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgti(i0,r0,i1) _bgti(_jit,i0,r0,i1) +static jit_word_t _bgti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bgtr_u(i0,r0,r1) _bgtr_u(_jit,i0,r0,r1) +static jit_word_t _bgtr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgti_u(i0,r0,i1) _bgti_u(_jit,i0,r0,i1) +static jit_word_t _bgti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bner(i0,r0,r1) _bner(_jit,i0,r0,r1) +static jit_word_t _bner(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bnei(i0,r0,i1) _bnei(_jit,i0,r0,i1) +static jit_word_t _bnei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define baddr(i0,r0,r1,cc) _baddr(_jit,i0,r0,r1,cc) +static jit_word_t _baddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t, + jit_bool_t); +# define baddi(i0,r0,i1,cc) _baddi(_jit,i0,r0,i1,cc) +static jit_word_t _baddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t, + jit_bool_t); +# define baddr_u(i0,r0,r1,cc) _baddr_u(_jit,i0,r0,r1,cc) +static jit_word_t _baddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t, + jit_bool_t); +# define baddi_u(i0,r0,i1,cc) _baddi_u(_jit,i0,r0,i1,cc) +static jit_word_t _baddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t, + jit_bool_t); +# define boaddr(i0,r0,r1) baddr(i0,r0,r1,1) +# define boaddi(i0,r0,i1) baddi(i0,r0,i1,1) +# define boaddr_u(i0,r0,r1) baddr_u(i0,r0,r1,1) +# define boaddi_u(i0,r0,i1) baddi_u(i0,r0,i1,1) +# define bxaddr(i0,r0,r1) baddr(i0,r0,r1,0) +# define bxaddi(i0,r0,i1) baddi(i0,r0,i1,0) +# define bxaddr_u(i0,r0,r1) baddr_u(i0,r0,r1,0) +# define bxaddi_u(i0,r0,i1) baddi_u(i0,r0,i1,0) +# define bsubr(i0,r0,r1,cc) _bsubr(_jit,i0,r0,r1,cc) +static jit_word_t _bsubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t, + jit_bool_t); +# define bsubi(i0,r0,i1,cc) _bsubi(_jit,i0,r0,i1,cc) +static jit_word_t _bsubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t, + jit_bool_t); +# define bsubr_u(i0,r0,r1,cc) _bsubr_u(_jit,i0,r0,r1,cc) +static jit_word_t _bsubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t, + jit_bool_t); +# define bsubi_u(i0,r0,i1,cc) _bsubi_u(_jit,i0,r0,i1,cc) +static jit_word_t _bsubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t, + jit_bool_t); +# define bosubr(i0,r0,r1) bsubr(i0,r0,r1,1) +# define bosubi(i0,r0,i1) bsubi(i0,r0,i1,1) +# define bosubr_u(i0,r0,r1) bsubr_u(i0,r0,r1,1) +# define bosubi_u(i0,r0,i1) bsubi_u(i0,r0,i1,1) +# define bxsubr(i0,r0,r1) bsubr(i0,r0,r1,0) +# define bxsubi(i0,r0,i1) bsubi(i0,r0,i1,0) +# define bxsubr_u(i0,r0,r1) bsubr_u(i0,r0,r1,0) +# define bxsubi_u(i0,r0,i1) bsubi_u(i0,r0,i1,0) +# define bmxr(i0,r0,r1,cc) _bmxr(_jit,i0,r0,r1,cc) +static jit_word_t _bmxr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t, + jit_bool_t); +# define bmxi(i0,r0,i1,cc) _bmxi(_jit,i0,r0,i1,cc) +static jit_word_t _bmxi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t, + jit_bool_t); +# define bmsr(i0,r0,r1) bmxr(i0,r0,r1,1) +# define bmsi(i0,r0,i1) bmxi(i0,r0,i1,1) +# define bmcr(i0,r0,r1) bmxr(i0,r0,r1,0) +# define bmci(i0,r0,i1) bmxi(i0,r0,i1,0) +# define ldr_c(r0,r1) _ldr_c(_jit,r0,r1) +static void _ldr_c(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_c(r0,i0) _ldi_c(_jit,r0,i0) +static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_uc(r0,r1) LDBU(r0,r1,0) +# define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0) +static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_s(r0,r1) _ldr_s(_jit,r0,r1) +static void _ldr_s(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_s(r0,i0) _ldi_s(_jit,r0,i0) +static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_us(r0,r1) LDWU(r0,r1,0) +# define ldi_us(r0,i0) _ldi_us(_jit,r0,i0) +static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_i(r0,r1) LDL(r0,r1,0) +# define ldi_i(r0,i0) _ldi_i(_jit,r0,i0) +static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_ui(r0,r1) _ldr_ui(_jit,r0,r1) +static void _ldr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# define ldi_ui(r0,i0) _ldi_ui(_jit,r0,i0) +static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr(r0,r1) ldr_l(r0,r1) +# define ldr_l(r0,r1) LDQ(r0,r1,0) +# define ldi_l(r0,i0) _ldi_l(_jit,r0,i0) +static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_c(r0,r1,r2) _ldxr_c(_jit,r0,r1,r2) +static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0) +static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_uc(r0,r1,r2) _ldxr_uc(_jit,r0,r1,r2) +static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0) +static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_s(r0,r1,r2) _ldxr_s(_jit,r0,r1,r2) +static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0) +static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_us(r0,r1,r2) _ldxr_us(_jit,r0,r1,r2) +static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0) +static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_i(r0,r1,r2) _ldxr_i(_jit,r0,r1,r2) +static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_i(r0,r1,i0) _ldxi_i(_jit,r0,r1,i0) +static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_ui(r0,r1,r2) _ldxr_ui(_jit,r0,r1,r2) +static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_ui(r0,r1,i0) _ldxi_ui(_jit,r0,r1,i0) +static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_l(r0,r1,r2) _ldxr_l(_jit,r0,r1,r2) +static void _ldxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi(r0,r1,i0) ldxi_l(r0,r1,i0) +# define ldxi_l(r0,r1,i0) _ldxi_l(_jit,r0,r1,i0) +static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_c(r0,r1) STB(r1,r0,0) +# define sti_c(i0,r0) _sti_c(_jit,i0,r0) +static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t); +# define str_s(r0,r1) STW(r1,r0,0) +# define sti_s(i0,r0) _sti_s(_jit,i0,r0) +static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t); +# define str_i(r0,r1) STL(r1,r0,0) +# define sti_i(i0,r0) _sti_i(_jit,i0,r0) +static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t); +# define str(r0,r1) str_l(r0,r1) +# define str_l(r0,r1) STQ(r1,r0,0) +# define sti_l(i0,r0) _sti_l(_jit,i0,r0) +static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_c(r0,r1,r2) _stxr_c(_jit,r0,r1,r2) +static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_c(i0,r0,r1) _stxi_c(_jit,i0,r0,r1) +static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_s(r0,r1,r2) _stxr_s(_jit,r0,r1,r2) +static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_s(i0,r0,r1) _stxi_s(_jit,i0,r0,r1) +static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_i(r0,r1,r2) _stxr_i(_jit,r0,r1,r2) +static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_i(i0,r0,r1) _stxi_i(_jit,i0,r0,r1) +static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_l(r0,r1,r2) _stxr_l(_jit,r0,r1,r2) +static void _stxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi(i0,r0,r1) stxi_l(i0,r0,r1) +# define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1) +static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define extr_c(r0,r1) _extr_c(_jit,r0,r1) +static void _extr_c(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_uc(r0,r1) _extr_uc(_jit,r0,r1) +static void _extr_uc(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_s(r0,r1) _extr_s(_jit,r0,r1) +static void _extr_s(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_us(r0,r1) _extr_us(_jit,r0,r1) +static void _extr_us(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_i(r0,r1) _extr_i(_jit,r0,r1) +static void _extr_i(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_ui(r0,r1) _extr_ui(_jit,r0,r1) +static void _extr_ui(jit_state_t*,jit_int32_t,jit_int32_t); +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define htonr(r0,r1) _htonr(_jit,r0,r1) +static void _htonr(jit_state_t*,jit_int32_t,jit_int32_t); +# else +# define htonr(r0,r1) movr(r0,r1) +# endif +# define jmpr(r0) JMP(_R31_REGNO,r0,0) +# define jmpi(i0) _jmpi(_jit,i0) +static void _jmpi(jit_state_t*, jit_word_t); +# define jmpi_p(i0) _jmpi_p(_jit,i0) +static jit_word_t _jmpi_p(jit_state_t*, jit_word_t); +#define callr(r0) _callr(_jit,r0) +static void _callr(jit_state_t*, jit_int32_t); +# define calli(i0) _calli(_jit,i0) +static void _calli(jit_state_t*, jit_word_t); +# define calli_p(i0) _calli_p(_jit,i0) +static jit_word_t _calli_p(jit_state_t*, jit_word_t); +# define prolog(node) _prolog(_jit,node) +static void _prolog(jit_state_t*,jit_node_t*); +# define epilog(node) _epilog(_jit,node) +static void _epilog(jit_state_t*,jit_node_t*); +# define patch_at(jump,label) _patch_at(_jit,jump,label) +static void _patch_at(jit_state_t*,jit_word_t,jit_word_t); +#endif + +#if CODE +static void +_Pcd(jit_state_t *_jit, int o, unsigned int n) +{ + assert(_u6_p(o)); + assert(_u26_p(n)); + ii((o<<26)|_u26(n)); +} + +static void +_Bra(jit_state_t *_jit, int o, int ra, int d) +{ + assert(_u6_p(o)); + assert(_u5_p(ra)); + assert(_s21_p(d)); + ii((o<<26)|(ra<<21)|_u21(d)); +} + +static void +_Mem(jit_state_t *_jit, int o, int ra, int rb, unsigned int d) +{ + assert(_u6_p(o)); + assert(_u5_p(ra)); + assert(_u5_p(rb)); + assert(_u16_p(d)); + ii((o<<26)|(ra<<21)|(rb<<16)|_u16(d)); +} + +static void +_Mbr(jit_state_t *_jit, int o, int ra, int rb, int h, int d) +{ + assert(_u6_p(o)); + assert(_u5_p(ra)); + assert(_u5_p(rb)); + assert(_u2_p(h)); + assert(_s14_p(d)); + ii((o<<26)|(ra<<21)|(rb<<16)|(h<<14)|_u14(d)); +} + +static void +_Opr(jit_state_t *_jit, int o, int ra, int rb, unsigned int f, int rc) +{ + assert(_u6_p(o)); + assert(_u5_p(ra)); + assert(_u5_p(rb)); + assert(_u5_p(rc)); + assert(_u11_p(f)); + ii((o<<26)|(ra<<21)|(rb<<16)|(_u11(f)<<5)|rc); +} + +static void +_Opi(jit_state_t *_jit, int o, int ra, unsigned int i, unsigned int f, int rc) +{ + assert(_u6_p(o)); + assert(_u5_p(ra)); + assert(_u8_p(i)); + assert(_u5_p(rc)); + assert(_u7_p(f)); + ii((o<<26)|(ra<<21)|(_u8(i)<<13)|(1<<12)|(_u7(f)<<5)|rc); +} + +static void +_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + MOV(r1, r0); +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + jit_int16_t s0, s1, s2, s3; + s0 = i0; + s1 = i0 >> 16; + s2 = i0 >> 32; + s3 = i0 >> 48; + if (s0 < 0) + ++s1; + if (s2 < 0) + ++s3; + if (_u8_p(i0)) + MOVi(_u8(i0), r0); + else if (_s16_p(i0)) + LDA(r0, _R31_REGNO, _u16(s0)); + else if (_s32_p(i0)) { + LDA(r0, _R31_REGNO, _u16(s0)); + LDAH(r0, r0, _u16(s1)); + } + else if (_u32_p(i0)) { + LDA(r0, _R31_REGNO, _u16(s0)); + if (s1) + LDAH(r0, r0, _u16(s1)); + lshi(r0, r0, 32); + rshi_u(r0, r0, 32); + } + else if (_u32(i0) == 0) { + LDA(r0, _R31_REGNO, _u16(s2)); + if (s3) + LDAH(r0, r0, _u16(s3)); + lshi(r0, r0, 32); + } + else { + reg = jit_get_reg(jit_class_gpr); + LDA(r0, _R31_REGNO, _u16(s0)); + LDA(rn(reg), _R31_REGNO, _u16(s2)); + if (s1) + LDAH(r0, r0, _u16(s1)); + if (s3) + LDAH(rn(reg), rn(reg), _u16(s3)); + lshi(r0, r0, 32); + rshi_u(r0, r0, 32); + lshi(rn(reg), rn(reg), 32); + orr(r0, r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + jit_int16_t s0, s1, s2, s3; + w = _jit->pc.w; + reg = jit_get_reg(jit_class_gpr); + s0 = i0; + s1 = i0 >> 16; + s2 = i0 >> 32; + s3 = i0 >> 48; + if (s0 < 0) + ++s1; + if (s2 < 0) + ++s3; + LDA(r0, _R31_REGNO, _u16(s0)); + LDA(rn(reg), _R31_REGNO, _u16(s2)); + LDAH(r0, r0, _u16(s1)); + LDAH(rn(reg), rn(reg), _u16(s3)); + lshi(r0, r0, 32); + rshi_u(r0, r0, 32); + lshi(rn(reg), rn(reg), 32); + orr(r0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + ADDQi(r1, i0, r0); + else if (_s16_p(i0)) + LDA(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ltr_u(rn(jit_carry), rn(reg), r1); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + addr(r0, r1, r2); + ltr_u(rn(jit_carry), r0, r1); + } +} + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ltr_u(rn(jit_carry), rn(reg), r1); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + addi(r0, r1, i0); + ltr_u(rn(jit_carry), r0, r1); + } +} + +static void +_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + addcr(r0, r1, r2); + addcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + addci(r0, r1, i0); + addcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + SUBQi(r1, i0, r0); + else if (_s16_p(-i0)) + LDA(r0, r1, _u16(-i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + subr(rn(reg), r1, r2); + ltr_u(rn(jit_carry), r1, rn(reg)); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + subr(r0, r1, r2); + ltr_u(rn(jit_carry), r1, r0); + } +} + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, -i0); + ltr_u(rn(jit_carry), r1, rn(reg)); + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + else { + addi(r0, r1, -i0); + ltr_u(rn(jit_carry), r1, r0); + } +} + +static void +_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + subcr(r0, r1, r2); + subcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + assert(jit_carry != _NOREG); + reg = jit_get_reg(jit_class_gpr); + movr(rn(reg), rn(jit_carry)); + subci(r0, r1, i0); + subcr(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + MULQi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + mulr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_qmulr(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t reg; + /* The only invalid condition is r0 == r1 */ + jit_int32_t t2, t3, s2, s3; + if (r2 == r0 || r2 == r1) { + s2 = jit_get_reg(jit_class_gpr); + t2 = rn(s2); + movr(t2, r2); + } + else + t2 = r2; + if (r3 == r0 || r3 == r1) { + s3 = jit_get_reg(jit_class_gpr); + t3 = rn(s3); + movr(t3, r3); + } + else + t3 = r3; + qmulr_u(r0, r1, r2, r3); + reg = jit_get_reg(jit_class_gpr); + /**/ + rshi(rn(reg), t2, 63); + mulr(rn(reg), rn(reg), t3); + addr(r1, r1, rn(reg)); + /**/ + rshi(rn(reg), t3, 63); + mulr(rn(reg), rn(reg), t2); + addr(r1, r1, rn(reg)); + jit_unget_reg(reg); + if (t2 != r2) + jit_unget_reg(s2); + if (t3 != r3) + jit_unget_reg(s3); +} + +static void +_qmuli(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + qmulr(r0, r1, r2, rn(reg)); + jit_unget_reg(reg); +} + +static void +_qmulr_u(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + jit_int32_t reg; + if (r0 == r2 || r0 == r3) { + reg = jit_get_reg(jit_class_gpr); + mulr(rn(reg), r2, r3); + } + else + mulr(r0, r2, r3); + UMULH(r2, r3, r1); + if (r0 == r2 || r0 == r3) { + movr(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_qmuli_u(jit_state_t *_jit, jit_int32_t r0, + jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) { + if (r0 == r2) { + reg = jit_get_reg(jit_class_gpr); + muli(rn(reg), r2, i0); + } + else + muli(r0, r2, i0); + UMULHi(r2, i0, r1); + if (r0 == r2) { + movr(r0, rn(reg)); + jit_unget_reg(reg); + } + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + qmulr_u(r0, r1, r2, rn(reg)); + jit_unget_reg(reg); + } +} + +static jit_word_t +__idiv(jit_word_t u, jit_word_t v) +{ + return (u / v); +} + +static void +_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + movr(_A0_REGNO, r1); + movr(_A1_REGNO, r2); + calli((jit_word_t)__idiv); + movr(r0, _V0_REGNO); +} + +static void +_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(_A0_REGNO, r1); + movi(_A1_REGNO, i0); + calli((jit_word_t)__idiv); + movr(r0, _V0_REGNO); +} + +static jit_uword_t +__udiv(jit_uword_t u, jit_uword_t v) +{ + return (u / v); +} + +static void +_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + movr(_A0_REGNO, r1); + movr(_A1_REGNO, r2); + calli((jit_word_t)__udiv); + movr(r0, _V0_REGNO); +} + +static void +_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(_A0_REGNO, r1); + movi(_A1_REGNO, i0); + calli((jit_word_t)__udiv); + movr(r0, _V0_REGNO); +} + +static jit_word_t +__irem(jit_word_t u, jit_word_t v) +{ + return (u % v); +} + +static void +_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + movr(_A0_REGNO, r1); + movr(_A1_REGNO, r2); + calli((jit_word_t)__irem); + movr(r0, _V0_REGNO); +} + +static void +_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(_A0_REGNO, r1); + movi(_A1_REGNO, i0); + calli((jit_word_t)__irem); + movr(r0, _V0_REGNO); +} + +static jit_uword_t +__urem(jit_uword_t u, jit_uword_t v) +{ + return (u % v); +} + +static void +_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + movr(_A0_REGNO, r1); + movr(_A1_REGNO, r2); + calli((jit_word_t)__urem); + movr(r0, _V0_REGNO); +} + +static void +_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + movr(_A0_REGNO, r1); + movi(_A1_REGNO, i0); + calli((jit_word_t)__urem); + movr(r0, _V0_REGNO); +} + +static jit_word_t +__idivrem(jit_word_t u, jit_word_t v, jit_word_t *rem) +{ + *rem = u % v; + return (u / v); +} + +static void +_qdivr(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + movr(_A0_REGNO, r2); + movr(_A1_REGNO, r3); + subi(_A2_REGNO, _FP_REGNO, 8); + calli((jit_word_t)__idivrem); + movr(r0, _V0_REGNO); + ldxi(r1, _FP_REGNO, -8); +} + +static void +_qdivi(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + movr(_A0_REGNO, r2); + movi(_A1_REGNO, i0); + subi(_A2_REGNO, _FP_REGNO, 8); + calli((jit_word_t)__idivrem); + movr(r0, _V0_REGNO); + ldxi(r1, _FP_REGNO, -8); +} + +static jit_word_t +__udivrem(jit_uword_t u, jit_uword_t v, jit_uword_t *rem) +{ + *rem = u % v; + return (u / v); +} + +static void +_qdivr_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3) +{ + movr(_A0_REGNO, r2); + movr(_A1_REGNO, r3); + subi(_A2_REGNO, _FP_REGNO, 8); + calli((jit_word_t)__udivrem); + movr(r0, _V0_REGNO); + ldxi(r1, _FP_REGNO, -8); +} + +static void +_qdivi_u(jit_state_t *_jit, + jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0) +{ + movr(_A0_REGNO, r2); + movi(_A1_REGNO, i0); + subi(_A2_REGNO, _FP_REGNO, 8); + calli((jit_word_t)__udivrem); + movr(r0, _V0_REGNO); + ldxi(r1, _FP_REGNO, -8); +} + +static void +_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + assert(i0 >= 0 && i0 < 64); + SLLi(r1, i0, r0); +} + +static void +_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + assert(i0 >= 0 && i0 < 64); + SRAi(r1, i0, r0); +} + +static void +_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + assert(i0 >= 0 && i0 < 64); + SRLi(r1, i0, r0); +} + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + ANDi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + andr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + ORi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + orr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + XORi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + xorr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_lti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + CMPLTi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ltr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_lti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + CMPULTi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ltr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_lei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + CMPLEi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ler(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_lei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + jit_word_t ni0; + ni0 = -i0; + if (_u8_p(i0)) + CMPULEi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ler_u(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_eqi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) + CMPEQi(r1, i0, r0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + eqr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_gei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ger(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_gei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ger_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_gti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + gtr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_gti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + gtr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + CMPEQ(r1, r2, r0); + CMPEQi(r0, 0, r0); +} + +static void +_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_u8_p(i0)) { + CMPEQi(r1, i0, r0); + CMPEQi(r0, 0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ner(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static jit_word_t +_bltr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + ltr(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_blti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BLT(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + lti(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bltr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + ltr_u(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_blti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + /* FIXME cannot optimize zero because need to return a patcheable address */ + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + lti_u(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bler(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + ler(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_blei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BLE(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + lei(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bler_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + ler_u(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_blei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BEQ(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + lei_u(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_beqr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + eqr(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_beqi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BEQ(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + eqi(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bger(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + ger(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bgei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BGE(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + gei(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bger_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + ger_u(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bgei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + /* always true if i1 == 0 */ + if (i0 == 0) { + w = _jit->pc.w; + BR(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + gei_u(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bgtr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + gtr(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bgti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BGT(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + gti(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bgtr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + gtr_u(rn(reg), r0, r1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bgti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + gti_u(rn(reg), r0, i1); + w = _jit->pc.w; + BNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bner(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + eqr(rn(reg), r0, r1); + w = _jit->pc.w; + BEQ(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bnei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BNE(r0, ((i0 - w) >> 2) - 1); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + eqi(rn(reg), r0, i1); + w = _jit->pc.w; + BEQ(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_baddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + jit_int32_t t3; + /* t0 = r0 + r1; overflow = r1 < 0 ? r0 < t0 : t0 < r0 */ + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr); + t2 = jit_get_reg(jit_class_gpr); + t3 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addr(rn(t0), r0, r1); /* t0 = r0 + r1 */ + ltr(rn(t1), r1, _R31_REGNO); /* t1 = r1 < 0 */ + ltr(rn(t2), r0, rn(t0)); /* t2 = r0 < t0 */ + ltr(rn(t3), rn(t0), r0); /* t3 = t0 < r0 */ + movr(r0, rn(t0)); /* r0 += r1 */ + CMOVNE(rn(t1), rn(t2), rn(t3)); /* if (t1 == 0) t3 = t2; */ + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + w = _jit->pc.w; + if (carry) + BNE(rn(t3), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t3), ((i0 - w) >> 2) - 1); + jit_unget_reg(t3); + return (w); +} + +static jit_word_t +_baddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = baddr(i0, r0, rn(reg), carry); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_baddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addr(rn(t0), r0, r1); + ltr_u(rn(t1), rn(t0), r0); + movr(r0, rn(t0)); + jit_unget_reg(t0); + w = _jit->pc.w; + if (carry) + BNE(rn(t1), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t1), ((i0 - w) >> 2) - 1); + jit_unget_reg(t1); + return (w); +} + +static jit_word_t +_baddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addi(rn(t0), r0, i1); + ltr_u(rn(t1), rn(t0), r0); + movr(r0, rn(t0)); + jit_unget_reg(t0); + w = _jit->pc.w; + if (carry) + BNE(rn(t1), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t1), ((i0 - w) >> 2) - 1); + jit_unget_reg(t1); + return (w); +} + +static jit_word_t +_bsubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + jit_int32_t t3; + /* t0 = r0 - r1; overflow = 0 < r1 ? r0 < t0 : t0 < r0 */ + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr); + t2 = jit_get_reg(jit_class_gpr); + t3 = jit_get_reg(jit_class_gpr|jit_class_nospill); + subr(rn(t0), r0, r1); /* r0 = r0 - r1 */ + ltr(rn(t1), _R31_REGNO, r1); /* t1 = 0 < r1 */ + ltr(rn(t2), r0, rn(t0)); /* t2 = r0 < t0 */ + ltr(rn(t3), rn(t0), r0); /* t3 = t0 < r0 */ + movr(r0, rn(t0)); /* r0 -= r1 */ + CMOVNE(rn(t1), rn(t2), rn(t3)); /* if (t1 == 0) t3 = t2; */ + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); + w = _jit->pc.w; + if (carry) + BNE(rn(t3), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t3), ((i0 - w) >> 2) - 1); + jit_unget_reg(t3); + return (w); +} + +static jit_word_t +_bsubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bsubr(i0, r0, rn(reg), carry); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bsubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + subr(rn(t0), r0, r1); + ltr_u(rn(t1), r0, rn(t0)); + movr(r0, rn(t0)); + jit_unget_reg(t0); + w = _jit->pc.w; + if (carry) + BNE(rn(t1), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t1), ((i0 - w) >> 2) - 1); + jit_unget_reg(t1); + return (w); +} + +static jit_word_t +_bsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t carry) +{ + jit_word_t w; + jit_int32_t t0; + jit_int32_t t1; + t0 = jit_get_reg(jit_class_gpr); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + subi(rn(t0), r0, i1); + ltr_u(rn(t1), r0, rn(t0)); + movr(r0, rn(t0)); + jit_unget_reg(t0); + w = _jit->pc.w; + if (carry) + BNE(rn(t1), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t1), ((i0 - w) >> 2) - 1); + jit_unget_reg(t1); + return (w); +} + +static jit_word_t +_bmxr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1, + jit_bool_t set) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + andr(rn(t0), r0, r1); + w = _jit->pc.w; + if (set) + BNE(rn(t0), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t0), ((i0 - w) >> 2) - 1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bmxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1, + jit_bool_t set) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + andi(rn(t0), r0, i1); + w = _jit->pc.w; + if (set) + BNE(rn(t0), ((i0 - w) >> 2) - 1); + else + BEQ(rn(t0), ((i0 - w) >> 2) - 1); + jit_unget_reg(t0); + return (w); +} + +static void +_ldr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + ldr_uc(r0, r1); + extr_c(r0, r0); +} + +static void +_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) { + LDBU(r0, _R31_REGNO, _u16(i0)); + extr_c(r0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDBU(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + ldr_us(r0, r1); + extr_s(r0, r0); +} + +static void +_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) { + LDWU(r0, _R31_REGNO, _u16(i0)); + extr_s(r0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDWU(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDL(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + ldr_i(r0, r1); + extr_ui(r0, r0); +} + +static void +_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) { + LDL(r0, _R31_REGNO, _u16(i0)); + extr_ui(r0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDQ(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) { + LDBU(r0, r1, _u16(i0)); + extr_c(r0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_c(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDBU(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_uc(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) { + LDWU(r0, r1, _u16(i0)); + extr_s(r0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_s(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDWU(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_us(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDL(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_i(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) { + LDL(r0, r1, _u16(i0)); + extr_ui(r0, r0); + } + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_ui(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + LDQ(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_l(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STB(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_c(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STW(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_s(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STL(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_i(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STQ(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_l(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_c(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STB(r1, r0, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_c(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_s(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STW(r1, r0, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_s(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_i(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STL(r1, r0, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_i(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_l(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (_s16_p(i0)) + STQ(r1, r0, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_l(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_extr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 56); + rshi(r0, r0, 56); +} + +static void +_extr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 56); + rshi_u(r0, r0, 56); +} + +static void +_extr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 48); + rshi(r0, r0, 48); +} + +static void +_extr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 48); + rshi_u(r0, r0, 48); +} + +static void +_extr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 32); + rshi(r0, r0, 32); +} + +static void +_extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + lshi(r0, r1, 32); + rshi_u(r0, r0, 32); +} + +static void +_htonr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + jit_int32_t t1; + jit_int32_t t2; + assert(_jitc->function != NULL); + t0 = jit_get_reg(jit_class_fpr); + t1 = jit_get_reg(jit_class_gpr); + t2 = jit_get_reg(jit_class_gpr); + stxi(-8, _FP_REGNO, r1); /* r1 = ABCD EFGH */ + LDG(rn(t0), _FP_REGNO, _u16(-8)); /* t0 = GHEF CDAB */ + STT(rn(t0), _FP_REGNO, _u16(-8)); + ldxi(rn(t1), _FP_REGNO, -8); /* t1 = GHEF CDAB */ + lshi(rn(t2), rn(t1), 8); /* t2 = HEFC DAB. */ + rshi_u(rn(t1), rn(t1), 8); /* t1 = .GHE FCDA */ + ZAPi(rn(t2), 0x55, rn(t2)); /* t2 = H.F. D.B. */ + ZAPi(rn(t1), 0xaa, rn(t1)); /* t1 = .G.E .C.A */ + orr(r0, rn(t1), rn(t2)); /* r0 = HGFE DCBA */ + jit_unget_reg(t2); + jit_unget_reg(t1); + jit_unget_reg(t0); +} + +static void +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_word_t d; + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 1; + if (_s21_p(d)) + BR(_R31_REGNO, d); + else + (void)jmpi_p(i0); +} + +static jit_word_t +_jmpi_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + w = movi_p(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_callr(jit_state_t *_jit, jit_int32_t r0) +{ + if (r0 != _PV_REGNO) + MOV(r0, _PV_REGNO); + JSR(_RA_REGNO, _PV_REGNO, 0); +} + +static void +_calli(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_word_t d; + w = _jit->pc.w; + d = ((i0 - w) >> 2) - 1; + if (_s21_p(d)) + BSR(_RA_REGNO, d); + else + (void)calli_p(i0); +} + +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + w = movi_p(_PV_REGNO, i0); + callr(_PV_REGNO); + return (w); +} + +static void +_prolog(jit_state_t *_jit, jit_node_t *node) +{ + _jitc->function->stack = ((_jitc->function->self.alen - + _jitc->function->self.aoff) + 7) & -8; + /* ldgp gp, 0(pv) */ + LDAH(_PV_REGNO, _GP_REGNO, 0); + LDA(_GP_REGNO, _GP_REGNO, 0); + /* callee save registers */ + subi(_SP_REGNO, _SP_REGNO, stack_framesize); + stxi(0, _SP_REGNO, _RA_REGNO); + stxi(8, _SP_REGNO, _FP_REGNO); +# define SPILL(N, O) \ + if (jit_regset_tstbit(&_jitc->function->regset, N)) \ + stxi(O, _SP_REGNO, N##_REGNO) +# define SPILLD(N, O) \ + if (jit_regset_tstbit(&_jitc->function->regset, N)) \ + stxi_d(O, _SP_REGNO, N##_REGNO) + SPILL(_S0, 16); + SPILL(_S1, 24); + SPILL(_S2, 32); + SPILL(_S3, 40); + SPILL(_S4, 48); + SPILL(_S5, 56); + SPILLD(_F2, 64); + SPILLD(_F3, 72); + SPILLD(_F4, 80); + SPILLD(_F5, 88); + SPILLD(_F6, 96); + SPILLD(_F7, 104); + SPILLD(_F8, 112); + SPILLD(_F9, 120); +# undef SPILLD +# undef SPILL + movr(_FP_REGNO, _SP_REGNO); + /* alloca */ + if (_jitc->function->stack) + subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack); +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *node) +{ + movr(_SP_REGNO, _FP_REGNO); + ldxi(_RA_REGNO, _SP_REGNO, 0); + ldxi(_FP_REGNO, _SP_REGNO, 8); +# define LOAD(N, O) \ + if (jit_regset_tstbit(&_jitc->function->regset, N)) \ + ldxi(N##_REGNO, _SP_REGNO, O) +# define LOADD(N, O) \ + if (jit_regset_tstbit(&_jitc->function->regset, N)) \ + ldxi_d(N##_REGNO, _SP_REGNO, O) + LOAD(_S0, 16); + LOAD(_S1, 24); + LOAD(_S2, 32); + LOAD(_S3, 40); + LOAD(_S4, 48); + LOAD(_S5, 56); + LOADD(_F2, 64); + LOADD(_F3, 72); + LOADD(_F4, 80); + LOADD(_F5, 88); + LOADD(_F6, 96); + LOADD(_F7, 104); + LOADD(_F8, 112); + LOADD(_F9, 120); +# undef LOADD +# undef LOAD + addi(_SP_REGNO, _SP_REGNO, stack_framesize); + RET(_R31_REGNO, _RA_REGNO, 1); /* 1 means procedure return + * 0 means no procedure return + * other values are reserved */ +} + +static void +_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label) +{ + union { + jit_int32_t *i; + jit_word_t w; + } u; + jit_word_t d; + jit_int16_t s0, s1, s2, s3; + u.w = instr; + switch (_u6(u.i[0] >> 26)) { + /* BLT BLE BEQ BGE */ + case 0x3a: case 0x3b: case 0x39: case 0x3e: + /* BGT BNE BLBC BLBS */ + case 0x3f: case 0x3d: case 0x38: case 0x3c: + /* BR BSR */ + case 0x30: case 0x34: + /* FBLT FBLE FBEQ FBGE */ + case 0x32: case 0x33: case 0x31: case 0x36: + /* FBGT FBNE */ + case 0x37: case 0x35: + d = ((label - instr) >> 2) - 1; + assert(_s21_p(d)); + u.i[0] &= ~0x1fffff; + u.i[0] |= _u21(d); + break; + /* LDA */ + case 0x08: /* movi_p */ + s0 = label; + s1 = label >> 16; + s2 = label >> 32; + s3 = label >> 48; + if (s0 < 0) + ++s1; + if (s2 < 0) + ++s3; + u.i[0] &= ~0xffff; + u.i[0] |= _u16(s0); + /* LDA */ + assert(_u6(u.i[1] >> 26) == 0x08); + u.i[1] &= ~0xffff; + u.i[1] |= _u16(s2); + /* LDAH */ + assert(_u6(u.i[2] >> 26) == 0x09); + u.i[2] &= ~0xffff; + u.i[2] |= _u16(s1); + /* LDAH */ + assert(_u6(u.i[3] >> 26) == 0x09); + u.i[3] &= ~0xffff; + u.i[3] |= _u16(s3); + /* SLL */ + assert(_u6(u.i[4] >> 26) == 0x12 && _u7(u.i[4] >> 5) == 0x39); + /* SRL */ + assert(_u6(u.i[5] >> 26) == 0x12 && _u7(u.i[5] >> 5) == 0x34); + /* SLL */ + assert(_u6(u.i[6] >> 26) == 0x12 && _u7(u.i[6] >> 5) == 0x39); + /* BIS */ + assert(_u6(u.i[7] >> 26) == 0x11 && _u7(u.i[7] >> 5) == 0x20); + break; + default: + abort(); + } +} +#endif diff --git a/lib/jit_alpha-fpu.c b/lib/jit_alpha-fpu.c new file mode 100644 index 000000000..026fd4127 --- /dev/null +++ b/lib/jit_alpha-fpu.c @@ -0,0 +1,1538 @@ +/* + * Copyright (C) 2014 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# define _F2_REGNO 0x02 +# define _F3_REGNO 0x03 +# define _F4_REGNO 0x04 +# define _F5_REGNO 0x05 +# define _F6_REGNO 0x06 +# define _F7_REGNO 0x07 +# define _F8_REGNO 0x08 +# define _F9_REGNO 0x09 +# define F_P(o,ra,rb,f,rc) _Opr(_jit,o,ra,rb,f,rc) +static void _Opr(jit_state_t*,int,int,int,unsigned int,int); +# define ADDF(ra,rb,rc) F_P(0x15,ra,rb,0x080,rc) +# define ADDG(ra,rb,rc) F_P(0x15,ra,rb,0x0a0,rc) +# define ADDS(ra,rb,rc) F_P(0x16,ra,rb,0x080,rc) +# define ADDS_C(ra,rb,rc) F_P(0x16,ra,rb,0x000,rc) +# define ADDS_M(ra,rb,rc) F_P(0x16,ra,rb,0x040,rc) +# define ADDS_D(ra,rb,rc) F_P(0x16,ra,rb,0x0c0,rc) +# define ADDS_U(ra,rb,rc) F_P(0x16,ra,rb,0x180,rc) +# define ADDS_UC(ra,rb,rc) F_P(0x16,ra,rb,0x100,rc) +# define ADDS_UM(ra,rb,rc) F_P(0x16,ra,rb,0x140,rc) +# define ADDS_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1c0,rc) +# define ADDS_SU(ra,rb,rc) F_P(0x16,ra,rb,0x580,rc) +# define ADDS_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x500,rc) +# define ADDS_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x540,rc) +# define ADDS_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5c0,rc) +# define ADDS_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x780,rc) +# define ADDS_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x700,rc) +# define ADDS_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x740,rc) +# define ADDS_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7c0,rc) +# define ADDT(ra,rb,rc) F_P(0x16,ra,rb,0x0a0,rc) +# define ADDT_C(ra,rb,rc) F_P(0x16,ra,rb,0x020,rc) +# define ADDT_M(ra,rb,rc) F_P(0x16,ra,rb,0x060,rc) +# define ADDT_D(ra,rb,rc) F_P(0x16,ra,rb,0x0e0,rc) +# define ADDT_U(ra,rb,rc) F_P(0x16,ra,rb,0x1a0,rc) +# define ADDT_UC(ra,rb,rc) F_P(0x16,ra,rb,0x120,rc) +# define ADDT_UM(ra,rb,rc) F_P(0x16,ra,rb,0x160,rc) +# define ADDT_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1e0,rc) +# define ADDT_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a0,rc) +# define ADDT_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x520,rc) +# define ADDT_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x560,rc) +# define ADDT_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5e0,rc) +# define ADDT_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x7a0,rc) +# define ADDT_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x720,rc) +# define ADDT_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x760,rc) +# define ADDT_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7e0,rc) +# define CMPGEQ(ra,rb,rc) F_P(0x15,ra,rb,0x0a5,rc) +# define CMPGLE(ra,rb,rc) F_P(0x15,ra,rb,0x0a7,rc) +# define CMPTEQ(ra,rb,rc) F_P(0x16,ra,rb,0x0a5,rc) +# define CMPTEQ_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a5,rc) +# define CMPTLE(ra,rb,rc) F_P(0x16,ra,rb,0x0a7,rc) +# define CMPTLE_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a7,rc) +# define CMPTLT(ra,rb,rc) F_P(0x16,ra,rb,0x0a6,rc) +# define CMPTLT_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a6,rc) +# define CMPTUN(ra,rb,rc) F_P(0x16,ra,rb,0x0a4,rc) +# define CMPTUN_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a4,rc) +# define CPYS(ra,rb,rc) F_P(0x17,ra,rb,0x020,rc) +# define CPYSE(ra,rb,rc) F_P(0x17,ra,rb,0x022,rc) +# define CPYSN(ra,rb,rc) F_P(0x17,ra,rb,0x021,rc) +# define DIVF(ra,rb,rc) F_P(0x15,ra,rb,0x083,rc) +# define DIVG(ra,rb,rc) F_P(0x15,ra,rb,0x0a3,rc) +# define DIVS(ra,rb,rc) F_P(0x16,ra,rb,0x083,rc) +# define DIVS_C(ra,rb,rc) F_P(0x16,ra,rb,0x003,rc) +# define DIVS_M(ra,rb,rc) F_P(0x16,ra,rb,0x043,rc) +# define DIVS_D(ra,rb,rc) F_P(0x16,ra,rb,0x0c3,rc) +# define DIVS_U(ra,rb,rc) F_P(0x16,ra,rb,0x183,rc) +# define DIVS_UC(ra,rb,rc) F_P(0x16,ra,rb,0x103,rc) +# define DIVS_UM(ra,rb,rc) F_P(0x16,ra,rb,0x143,rc) +# define DIVS_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1c3,rc) +# define DIVS_SU(ra,rb,rc) F_P(0x16,ra,rb,0x583,rc) +# define DIVS_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x503,rc) +# define DIVS_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x543,rc) +# define DIVS_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5c3,rc) +# define DIVS_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x783,rc) +# define DIVS_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x703,rc) +# define DIVS_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x743,rc) +# define DIVS_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7c3,rc) +# define DIVT(ra,rb,rc) F_P(0x16,ra,rb,0x0a3,rc) +# define DIVT_C(ra,rb,rc) F_P(0x16,ra,rb,0x023,rc) +# define DIVT_M(ra,rb,rc) F_P(0x16,ra,rb,0x063,rc) +# define DIVT_D(ra,rb,rc) F_P(0x16,ra,rb,0x0e3,rc) +# define DIVT_U(ra,rb,rc) F_P(0x16,ra,rb,0x1a3,rc) +# define DIVT_UC(ra,rb,rc) F_P(0x16,ra,rb,0x123,rc) +# define DIVT_UM(ra,rb,rc) F_P(0x16,ra,rb,0x163,rc) +# define DIVT_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1e3,rc) +# define DIVT_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a3,rc) +# define DIVT_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x523,rc) +# define DIVT_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x563,rc) +# define DIVT_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5e3,rc) +# define DIVT_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x7a3,rc) +# define DIVT_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x723,rc) +# define DIVT_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x7a3,rc) +# define DIVT_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7e3,rc) +# define CVTDG(rb,rc) F_P(0x15,_R31_REGNO,rb,0x09e,rc) +# define CVTGD(rb,rc) F_P(0x15,_R31_REGNO,rb,0x0ad,rc) +# define CVTGF(rb,rc) F_P(0x15,_R31_REGNO,rb,0x0ac,rc) +# define CVTGQ(rb,rc) F_P(0x15,_R31_REGNO,rb,0x0af,rc) +# define CVTLQ(rb,rc) F_P(0x17,_R31_REGNO,rb,0x010,rc) +# define CVTQF(rb,rc) F_P(0x15,_R31_REGNO,rb,0x0bc,rc) +# define CVTQG(rb,rc) F_P(0x15,_R31_REGNO,rb,0x0be,rc) +# define CVTQL(rb,rc) F_P(0x17,_R31_REGNO,rb,0x030,rc) +# define CVTQS(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0bc,rc) +# define CVTQS_C(rb,rc) F_P(0x16,_R31_REGNO,rb,0x03c,rc) +# define CVTQS_M(rb,rc) F_P(0x16,_R31_REGNO,rb,0x07c,rc) +# define CVTQS_D(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0fc,rc) +# define CVTQS_SUI(rb,rc) F_P(0x16,_R31_REGNO,rb,0x7bc,rc) +# define CVTQS_SUIC(rb,rc) F_P(0x16,_R31_REGNO,rb,0x73c,rc) +# define CVTQS_SUIM(rb,rc) F_P(0x16,_R31_REGNO,rb,0x77c,rc) +# define CVTQS_SUID(rb,rc) F_P(0x16,_R31_REGNO,rb,0x7fc,rc) +# define CVTQT(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0be,rc) +# define CVTQT_C(rb,rc) F_P(0x16,_R31_REGNO,rb,0x03e,rc) +# define CVTQT_M(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0te,rc) +# define CVTQT_D(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0fe,rc) +# define CVTQT_SUI(rb,rc) F_P(0x16,_R31_REGNO,rb,0x7be,rc) +# define CVTQT_SUIC(rb,rc) F_P(0x16,_R31_REGNO,rb,0x73e,rc) +# define CVTQT_SUIM(rb,rc) F_P(0x16,_R31_REGNO,rb,0x77e,rc) +# define CVTQT_SUID(rb,rc) F_P(0x16,_R31_REGNO,rb,0x7fe,rc) +# define CVTST(rb,rc) F_P(0x16,_R31_REGNO,rb,0x2ac,rc) +# define CVTST_S(rb,rc) F_P(0x16,_R31_REGNO,rb,0x6ac,rc) +# define CVTTQ(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0af,rc) +# define CVTTQ_C(rb,rc) F_P(0x16,_R31_REGNO,rb,0x02f,rc) +# define CVTTQ_V(rb,rc) F_P(0x16,_R31_REGNO,rb,0x1af,rc) +# define CVTTQ_VC(rb,rc) F_P(0x16,_R31_REGNO,rb,0x12f,rc) +# define CVTTQ_SV(rb,rc) F_P(0x16,_R31_REGNO,rb,0x5af,rc) +# define CVTTQ_SVC(rb,rc) F_P(0x16,_R31_REGNO,rb,0x52f,rc) +# define CVTTQ_SVI(rb,rc) F_P(0x16,_R31_REGNO,rb,0x7af,rc) +# define CVTTQ_SVIC(rb,rc) F_P(0x16,_R31_REGNO,rb,0x72f,rc) +# define CVTTQ_D(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0ef,rc) +# define CVTTQ_VD(rb,rc) F_P(0x16,_R31_REGNO,rb,0x1ef,rc) +# define CVTTQ_SVD(rb,rc) F_P(0x16,_R31_REGNO,rb,0x5ef,rc) +# define CVTTQ_SVID(rb,rc) F_P(0x16,_R31_REGNO,rb,0x7ef,rc) +# define CVTTQ_M(rb,rc) F_P(0x16,_R31_REGNO,rb,0x06f,rc) +# define CVTTQ_VM(rb,rc) F_P(0x16,_R31_REGNO,rb,0x16f,rc) +# define CVTTQ_SVM(rb,rc) F_P(0x16,_R31_REGNO,rb,0x56f,rc) +# define CVTTQ_SVIM(rb,rc) F_P(0x16,_R31_REGNO,rb,0x76f,rc) +# define CVTTS(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0ac,rc) +# define CVTTS_C(rb,rc) F_P(0x16,_R31_REGNO,rb,0x02c,rc) +# define CVTTS_M(rb,rc) F_P(0x16,_R31_REGNO,rb,0x06c,rc) +# define CVTTS_D(rb,rc) F_P(0x16,_R31_REGNO,rb,0x0ec,rc) +# define CVTTS_U(rb,rc) F_P(0x16,_R31_REGNO,rb,0x1ac,rc) +# define CVTTS_UC(rb,rc) F_P(0x16,_R31_REGNO,rb,0x12c,rc) +# define CVTTS_UM(rb,rc) F_P(0x16,_R31_REGNO,rb,0x16c,rc) +# define CVTTS_UD(rb,rc) F_P(0x16,_R31_REGNO,rb,0x1ec,rc) +# define FBEQ(ra,d) Bra(0x31,ra,d) +# define FBGE(ra,d) Bra(0x36,ra,d) +# define FBGT(ra,d) Bra(0x37,ra,d) +# define FBLE(ra,d) Bra(0x33,ra,d) +# define FBLT(ra,d) Bra(0x32,ra,d) +# define FBNE(ra,d) Bra(0x35,ra,d) +# define FCMOVEQ(ra,rb,rc) F_P(0x17,ra,rb,0x02a,rc) +# define FCMOVGE(ra,rb,rc) F_P(0x17,ra,rb,0x02d,rc) +# define FCMOVGT(ra,rb,rc) F_P(0x17,ra,rb,0x02f,rc) +# define FCMOVLE(ra,rb,rc) F_P(0x17,ra,rb,0x02e,rc) +# define FCMOVLT(ra,rb,rc) F_P(0x17,ra,rb,0x02c,rc) +# define FCMOVNE(ra,rb,rc) F_P(0x17,ra,rb,0x02b,rc) +# define FTOIS(ra,rc) F_P(0x1c,ra,_R31_REGNO,0x078,rc) +# define FTOIT(ra,rc) F_P(0x1c,ra,_R31_REGNO,0x070,rc) +# define ITOFF(ra,rc) F_P(0x14,ra,_R31_REGNO,0x014,rc) +# define ITOFS(ra,rc) F_P(0x14,ra,_R31_REGNO,0x004,rc) +# define ITOFT(ra,rc) F_P(0x14,ra,_R31_REGNO,0x024,rc) +# define LDF(ra,rb,d) Mem(0x20,ra,rb,d) +# define LDG(ra,rb,d) Mem(0x21,ra,rb,d) +# define LDS(ra,rb,d) Mem(0x22,ra,rb,d) +# define LDT(ra,rb,d) Mem(0x23,ra,rb,d) +# define MF_FPCR(ra) F_P(0x17,ra,ra,0x025,ra) +# define MT_FPCR(ra) F_P(0x17,ra,ra,0x024,ra) +# define MULF(ra,rb,rc) F_P(0x15,ra,rb,0x082,rc) +# define MULG(ra,rb,rc) F_P(0x15,ra,rb,0x0a2,rc) +# define MULS(ra,rb,rc) F_P(0x16,ra,rb,0x082,rc) +# define MULS_C(ra,rb,rc) F_P(0x16,ra,rb,0x002,rc) +# define MULS_M(ra,rb,rc) F_P(0x16,ra,rb,0x042,rc) +# define MULS_D(ra,rb,rc) F_P(0x16,ra,rb,0x0c2,rc) +# define MULS_U(ra,rb,rc) F_P(0x16,ra,rb,0x182,rc) +# define MULS_UC(ra,rb,rc) F_P(0x16,ra,rb,0x102,rc) +# define MULS_UM(ra,rb,rc) F_P(0x16,ra,rb,0x142,rc) +# define MULS_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1c2,rc) +# define MULS_SU(ra,rb,rc) F_P(0x16,ra,rb,0x582,rc) +# define MULS_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x502,rc) +# define MULS_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x642,rc) +# define MULS_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5c2,rc) +# define MULS_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x782,rc) +# define MULS_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x702,rc) +# define MULS_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x742,rc) +# define MULS_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7c2,rc) +# define MULT(ra,rb,rc) F_P(0x16,ra,rb,0x0a2,rc) +# define MULT_C(ra,rb,rc) F_P(0x16,ra,rb,0x022,rc) +# define MULT_M(ra,rb,rc) F_P(0x16,ra,rb,0x062,rc) +# define MULT_D(ra,rb,rc) F_P(0x16,ra,rb,0x0e2,rc) +# define MULT_U(ra,rb,rc) F_P(0x16,ra,rb,0x1a2,rc) +# define MULT_UC(ra,rb,rc) F_P(0x16,ra,rb,0x122,rc) +# define MULT_UM(ra,rb,rc) F_P(0x16,ra,rb,0x162,rc) +# define MULT_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1e2,rc) +# define MULT_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a2,rc) +# define MULT_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x522,rc) +# define MULT_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x562,rc) +# define MULT_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5e2,rc) +# define MULT_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x7a2,rc) +# define MULT_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x722,rc) +# define MULT_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x762,rc) +# define MULT_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7e2,rc) +# define SQRTF(rb,rc) F_P(0x14,_R31_REGNO,rb,0x08a,rc) +# define SQRTG(rb,rc) F_P(0x14,_R31_REGNO,rb,0x0aa,rc) +# define SQRTS(rb,rc) F_P(0x14,_R31_REGNO,rb,0x08b,rc) +# define SQRTS_C(rb,rc) F_P(0x14,_R31_REGNO,rb,0x00b,rc) +# define SQRTS_M(rb,rc) F_P(0x14,_R31_REGNO,rb,0x04b,rc) +# define SQRTS_D(rb,rc) F_P(0x14,_R31_REGNO,rb,0x0cb,rc) +# define SQRTS_U(rb,rc) F_P(0x14,_R31_REGNO,rb,0x18b,rc) +# define SQRTS_UC(rb,rc) F_P(0x14,_R31_REGNO,rb,0x10b,rc) +# define SQRTS_UM(rb,rc) F_P(0x14,_R31_REGNO,rb,0x14b,rc) +# define SQRTS_UD(rb,rc) F_P(0x14,_R31_REGNO,rb,0x1cb,rc) +# define SQRTS_SU(rb,rc) F_P(0x14,_R31_REGNO,rb,0x58b,rc) +# define SQRTS_SUC(rb,rc) F_P(0x14,_R31_REGNO,rb,0x50b,rc) +# define SQRTS_SUM(rb,rc) F_P(0x14,_R31_REGNO,rb,0x54b,rc) +# define SQRTS_SUD(rb,rc) F_P(0x14,_R31_REGNO,rb,0x5cb,rc) +# define SQRTS_SUI(rb,rc) F_P(0x14,_R31_REGNO,rb,0x78b,rc) +# define SQRTS_SUIC(rb,rc) F_P(0x14,_R31_REGNO,rb,0x70b,rc) +# define SQRTS_SUIM(rb,rc) F_P(0x14,_R31_REGNO,rb,0x74b,rc) +# define SQRTS_SUID(rb,rc) F_P(0x14,_R31_REGNO,rb,0x7cb,rc) +# define SQRTT(rb,rc) F_P(0x14,_R31_REGNO,rb,0x0ab,rc) +# define SQRTT_C(rb,rc) F_P(0x14,_R31_REGNO,rb,0x02b,rc) +# define SQRTT_M(rb,rc) F_P(0x14,_R31_REGNO,rb,0x06b,rc) +# define SQRTT_D(rb,rc) F_P(0x14,_R31_REGNO,rb,0x0eb,rc) +# define SQRTT_U(rb,rc) F_P(0x14,_R31_REGNO,rb,0x1ab,rc) +# define SQRTT_UC(rb,rc) F_P(0x14,_R31_REGNO,rb,0x12b,rc) +# define SQRTT_UM(rb,rc) F_P(0x14,_R31_REGNO,rb,0x16b,rc) +# define SQRTT_UD(rb,rc) F_P(0x14,_R31_REGNO,rb,0x1eb,rc) +# define SQRTT_SU(rb,rc) F_P(0x14,_R31_REGNO,rb,0x5ab,rc) +# define SQRTT_SUC(rb,rc) F_P(0x14,_R31_REGNO,rb,0x52b,rc) +# define SQRTT_SUM(rb,rc) F_P(0x14,_R31_REGNO,rb,0x56b,rc) +# define SQRTT_SUD(rb,rc) F_P(0x14,_R31_REGNO,rb,0x5eb,rc) +# define SQRTT_SUI(rb,rc) F_P(0x14,_R31_REGNO,rb,0x7ab,rc) +# define SQRTT_SUIC(rb,rc) F_P(0x14,_R31_REGNO,rb,0x72b,rc) +# define SQRTT_SUIM(rb,rc) F_P(0x14,_R31_REGNO,rb,0x76b,rc) +# define SQRTT_SUID(rb,rc) F_P(0x14,_R31_REGNO,rb,0x7eb,rc) +# define STF(ra,rb,d) Mem(0x24,ra,rb,d) +# define STG(ra,rb,d) Mem(0x25,ra,rb,d) +# define STS(ra,rb,d) Mem(0x26,ra,rb,d) +# define STT(ra,rb,d) Mem(0x27,ra,rb,d) +# define SUBF(ra,rb,rc) F_P(0x15,ra,rb,0x081,rc) +# define SUBG(ra,rb,rc) F_P(0x15,ra,rb,0x0a1,rc) +# define SUBS(ra,rb,rc) F_P(0x16,ra,rb,0x081,rc) +# define SUBS_C(ra,rb,rc) F_P(0x16,ra,rb,0x001,rc) +# define SUBS_M(ra,rb,rc) F_P(0x16,ra,rb,0x041,rc) +# define SUBS_D(ra,rb,rc) F_P(0x16,ra,rb,0x0c1,rc) +# define SUBS_U(ra,rb,rc) F_P(0x16,ra,rb,0x181,rc) +# define SUBS_UC(ra,rb,rc) F_P(0x16,ra,rb,0x101,rc) +# define SUBS_UM(ra,rb,rc) F_P(0x16,ra,rb,0x141,rc) +# define SUBS_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1c1,rc) +# define SUBS_SU(ra,rb,rc) F_P(0x16,ra,rb,0x581,rc) +# define SUBS_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x501,rc) +# define SUBS_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x541,rc) +# define SUBS_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5c1,rc) +# define SUBS_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x781,rc) +# define SUBS_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x701,rc) +# define SUBS_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x741,rc) +# define SUBS_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7c1,rc) +# define SUBT(ra,rb,rc) F_P(0x16,ra,rb,0x0a1,rc) +# define SUBT_C(ra,rb,rc) F_P(0x16,ra,rb,0x021,rc) +# define SUBT_M(ra,rb,rc) F_P(0x16,ra,rb,0x061,rc) +# define SUBT_D(ra,rb,rc) F_P(0x16,ra,rb,0x0e1,rc) +# define SUBT_U(ra,rb,rc) F_P(0x16,ra,rb,0x1a1,rc) +# define SUBT_UC(ra,rb,rc) F_P(0x16,ra,rb,0x121,rc) +# define SUBT_UM(ra,rb,rc) F_P(0x16,ra,rb,0x161,rc) +# define SUBT_UD(ra,rb,rc) F_P(0x16,ra,rb,0x1e1,rc) +# define SUBT_SU(ra,rb,rc) F_P(0x16,ra,rb,0x5a1,rc) +# define SUBT_SUC(ra,rb,rc) F_P(0x16,ra,rb,0x521,rc) +# define SUBT_SUM(ra,rb,rc) F_P(0x16,ra,rb,0x561,rc) +# define SUBT_SUD(ra,rb,rc) F_P(0x16,ra,rb,0x5e1,rc) +# define SUBT_SUI(ra,rb,rc) F_P(0x16,ra,rb,0x7a1,rc) +# define SUBT_SUIC(ra,rb,rc) F_P(0x16,ra,rb,0x721,rc) +# define SUBT_SUIM(ra,rb,rc) F_P(0x16,ra,rb,0x761,rc) +# define SUBT_SUID(ra,rb,rc) F_P(0x16,ra,rb,0x7e1,rc) +# define FABS(ra,rc) CPYS(_R31_REGNO,ra,rc) +# define FMOV(ra,rc) CPYS(ra,ra,rc) +# define NEGF(ra,rc) SUBF(_R31_REGNO,ra,rc) +# define NEGG(ra,rc) SUBG(_R31_REGNO,ra,rc) +# define NEGS(ra,rc) SUBS(_R31_REGNO,ra,rc) +# define NEGT(ra,rc) SUBT(_R31_REGNO,ra,rc) +# define FNEGF(ra,rc) CPYSN(ra,ra,rc) +# define FNEGG(ra,rc) CPYSN(ra,ra,rc) +# define FNEGS(ra,rc) CPYSN(ra,ra,rc) +# define FNEGT(ra,rc) CPYSN(ra,ra,rc) +# define movr_f(r0,r1) movr_d(r0,r1) +# define movr_d(r0,r1) _movr_d(_jit,r0,r1) +static void _movr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define movi_f(r0,i0) _movi_f(_jit,r0,i0) +static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*); +# define movi_d(r0,i0) _movi_d(_jit,r0,i0) +static void _movi_d(jit_state_t*,jit_int32_t,jit_float64_t*); +# define absr_f(r0,r1) FABS(r1,r0) +# define absr_d(r0,r1) FABS(r1,r0) +# define negr_f(r0,r1) FNEGS(r1,r0) +# define negr_d(r0,r1) FNEGT(r1,r0) +# define sqrtr_f(r0,r1) _sqrtr_f(_jit,r0,r1) +static void _sqrtr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define sqrtr_d(r0,r1) _sqrtr_d(_jit,r0,r1) +static void _sqrtr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_f_d(r0,r1) movr_d(r0,r1) +# define extr_d_f(r0,r1) movr_f(r0,r1) +# define truncr_f_i(r0,r1) truncr_d_i(r0,r1) +# define truncr_f_l(r0,r1) truncr_d_l(r0,r1) +# define truncr_d_i(r0,r1) truncr_d_l(r0,r1) +# define truncr_d_l(r0,r1) _truncr_d_l(_jit,r0,r1) +static void _truncr_d_l(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_f(r0,r1) _extr_f(_jit,r0,r1) +static void _extr_f(jit_state_t*,jit_int32_t,jit_int32_t); +# define extr_d(r0,r1) _extr_d(_jit,r0,r1) +static void _extr_d(jit_state_t*,jit_int32_t,jit_int32_t); +# define addr_f(r0,r1,r2) _addr_f(_jit,r0,r1,r2) +static void _addr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addi_f(r0,r1,i0) _addi_f(_jit,r0,r1,i0) +static void _addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define addr_d(r0,r1,r2) _addr_d(_jit,r0,r1,r2) +static void _addr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define addi_d(r0,r1,i0) _addi_d(_jit,r0,r1,i0) +static void _addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define subr_f(r0,r1,r2) _subr_f(_jit,r0,r1,r2) +static void _subr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subi_f(r0,r1,i0) _subi_f(_jit,r0,r1,i0) +static void _subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define subr_d(r0,r1,r2) _subr_d(_jit,r0,r1,r2) +static void _subr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define subi_d(r0,r1,i0) _subi_d(_jit,r0,r1,i0) +static void _subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define mulr_f(r0,r1,r2) _mulr_f(_jit,r0,r1,r2) +static void _mulr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define muli_f(r0,r1,i0) _muli_f(_jit,r0,r1,i0) +static void _muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define mulr_d(r0,r1,r2) _mulr_d(_jit,r0,r1,r2) +static void _mulr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define muli_d(r0,r1,i0) _muli_d(_jit,r0,r1,i0) +static void _muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define divr_f(r0,r1,r2) _divr_f(_jit,r0,r1,r2) +static void _divr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_f(r0,r1,i0) _divi_f(_jit,r0,r1,i0) +static void _divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define divr_d(r0,r1,r2) _divr_d(_jit,r0,r1,r2) +static void _divr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define divi_d(r0,r1,i0) _divi_d(_jit,r0,r1,i0) +static void _divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ltr_f(r0,r1,r2) ltr_d(r0,r1,r2) +# define ltr_d(r0,r1,r2) _ltr_d(_jit,r0,r1,r2) +static void _ltr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lti_f(r0,r1,i0) _lti_f(_jit,r0,r1,i0) +static void _lti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define lti_d(r0,r1,i0) _lti_d(_jit,r0,r1,i0) +static void _lti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ler_f(r0,r1,r2) ler_d(r0,r1,r2) +# define ler_d(r0,r1,r2) _ler_d(_jit,r0,r1,r2) +static void _ler_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define lei_f(r0,r1,i0) _lei_f(_jit,r0,r1,i0) +static void _lei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define lei_d(r0,r1,i0) _lei_d(_jit,r0,r1,i0) +static void _lei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define eqr_f(r0,r1,r2) eqr_d(r0,r1,r2) +# define eqr_d(r0,r1,r2) _eqr_d(_jit,r0,r1,r2) +static void _eqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define eqi_f(r0,r1,i0) _eqi_f(_jit,r0,r1,i0) +static void _eqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define eqi_d(r0,r1,i0) _eqi_d(_jit,r0,r1,i0) +static void _eqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ger_f(r0,r1,r2) ger_d(r0,r1,r2) +# define ger_d(r0,r1,r2) _ger_d(_jit,r0,r1,r2) +static void _ger_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gei_f(r0,r1,i0) _gei_f(_jit,r0,r1,i0) +static void _gei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define gei_d(r0,r1,i0) _gei_d(_jit,r0,r1,i0) +static void _gei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define gtr_f(r0,r1,r2) gtr_d(r0,r1,r2) +# define gtr_d(r0,r1,r2) _gtr_d(_jit,r0,r1,r2) +static void _gtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define gti_f(r0,r1,i0) _gti_f(_jit,r0,r1,i0) +static void _gti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define gti_d(r0,r1,i0) _gti_d(_jit,r0,r1,i0) +static void _gti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ner_f(r0,r1,r2) ner_d(r0,r1,r2) +# define ner_d(r0,r1,r2) _ner_d(_jit,r0,r1,r2) +static void _ner_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define nei_f(r0,r1,i0) _nei_f(_jit,r0,r1,i0) +static void _nei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define nei_d(r0,r1,i0) _nei_d(_jit,r0,r1,i0) +static void _nei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unltr_f(r0,r1,r2) unltr_d(r0,r1,r2) +# define unltr_d(r0,r1,r2) _unltr_d(_jit,r0,r1,r2) +static void _unltr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unlti_f(r0,r1,i0) _unlti_f(_jit,r0,r1,i0) +static void _unlti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define unlti_d(r0,r1,i0) _unlti_d(_jit,r0,r1,i0) +static void _unlti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unler_f(r0,r1,r2) unler_d(r0,r1,r2) +# define unler_d(r0,r1,r2) _unler_d(_jit,r0,r1,r2) +static void _unler_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unlei_f(r0,r1,i0) _unlei_f(_jit,r0,r1,i0) +static void _unlei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define unlei_d(r0,r1,i0) _unlei_d(_jit,r0,r1,i0) +static void _unlei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define uneqr_f(r0,r1,r2) uneqr_d(r0,r1,r2) +# define uneqr_d(r0,r1,r2) _uneqr_d(_jit,r0,r1,r2) +static void _uneqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define uneqi_f(r0,r1,i0) _uneqi_f(_jit,r0,r1,i0) +static void _uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define uneqi_d(r0,r1,i0) _uneqi_d(_jit,r0,r1,i0) +static void _uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unger_f(r0,r1,r2) unger_d(r0,r1,r2) +# define unger_d(r0,r1,r2) _unger_d(_jit,r0,r1,r2) +static void _unger_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ungei_f(r0,r1,i0) _ungei_f(_jit,r0,r1,i0) +static void _ungei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ungei_d(r0,r1,i0) _ungei_d(_jit,r0,r1,i0) +static void _ungei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ungtr_f(r0,r1,r2) ungtr_d(r0,r1,r2) +# define ungtr_d(r0,r1,r2) _ungtr_d(_jit,r0,r1,r2) +static void _ungtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ungti_f(r0,r1,i0) _ungti_f(_jit,r0,r1,i0) +static void _ungti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ungti_d(r0,r1,i0) _ungti_d(_jit,r0,r1,i0) +static void _ungti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ltgtr_f(r0,r1,r2) ltgtr_d(r0,r1,r2) +# define ltgtr_d(r0,r1,r2) _ltgtr_d(_jit,r0,r1,r2) +static void _ltgtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ltgti_f(r0,r1,i0) _ltgti_f(_jit,r0,r1,i0) +static void _ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ltgti_d(r0,r1,i0) _ltgti_d(_jit,r0,r1,i0) +static void _ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define ordr_f(r0,r1,r2) ordr_d(r0,r1,r2) +# define ordr_d(r0,r1,r2) _ordr_d(_jit,r0,r1,r2) +static void _ordr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ordi_f(r0,r1,i0) _ordi_f(_jit,r0,r1,i0) +static void _ordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define ordi_d(r0,r1,i0) _ordi_d(_jit,r0,r1,i0) +static void _ordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define unordr_f(r0,r1,r2) unordr_d(r0,r1,r2) +# define unordr_d(r0,r1,r2) _unordr_d(_jit,r0,r1,r2) +static void _unordr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define unordi_f(r0,r1,i0) _unordi_f(_jit,r0,r1,i0) +static void _unordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*); +# define unordi_d(r0,r1,i0) _unordi_d(_jit,r0,r1,i0) +static void _unordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); +# define bltr_f(i0,r0,r1) bltr_d(i0,r0,r1) +# define bltr_d(i0,r0,r1) _bltr_d(_jit,i0,r0,r1) +static jit_word_t _bltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blti_f(i0,r0,i1) _blti_f(_jit,i0,r0,i1) +static jit_word_t _blti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define blti_d(i0,r0,i1) _blti_d(_jit,i0,r0,i1) +static jit_word_t _blti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bler_f(i0,r0,r1) bler_d(i0,r0,r1) +# define bler_d(i0,r0,r1) _bler_d(_jit,i0,r0,r1) +static jit_word_t _bler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define blei_f(i0,r0,i1) _blei_f(_jit,i0,r0,i1) +static jit_word_t _blei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define blei_d(i0,r0,i1) _blei_d(_jit,i0,r0,i1) +static jit_word_t _blei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define beqr_f(i0,r0,r1) beqr_d(i0,r0,r1) +# define beqr_d(i0,r0,r1) _beqr_d(_jit,i0,r0,r1) +static jit_word_t _beqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define beqi_f(i0,r0,i1) _beqi_f(_jit,i0,r0,i1) +static jit_word_t _beqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define beqi_d(i0,r0,i1) _beqi_d(_jit,i0,r0,i1) +static jit_word_t _beqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bger_f(i0,r0,r1) bger_d(i0,r0,r1) +# define bger_d(i0,r0,r1) _bger_d(_jit,i0,r0,r1) +static jit_word_t _bger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgei_f(i0,r0,i1) _bgei_f(_jit,i0,r0,i1) +static jit_word_t _bgei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bgei_d(i0,r0,i1) _bgei_d(_jit,i0,r0,i1) +static jit_word_t _bgei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bgtr_f(i0,r0,r1) bgtr_d(i0,r0,r1) +# define bgtr_d(i0,r0,r1) _bgtr_d(_jit,i0,r0,r1) +static jit_word_t _bgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bgti_f(i0,r0,i1) _bgti_f(_jit,i0,r0,i1) +static jit_word_t _bgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bgti_d(i0,r0,i1) _bgti_d(_jit,i0,r0,i1) +static jit_word_t _bgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bner_f(i0,r0,r1) bner_d(i0,r0,r1) +# define bner_d(i0,r0,r1) _bner_d(_jit,i0,r0,r1) +static jit_word_t _bner_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bnei_f(i0,r0,i1) _bnei_f(_jit,i0,r0,i1) +static jit_word_t _bnei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bnei_d(i0,r0,i1) _bnei_d(_jit,i0,r0,i1) +static jit_word_t _bnei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bunltr_f(i0,r0,r1) bunltr_d(i0,r0,r1) +# define bunltr_d(i0,r0,r1) _bunltr_d(_jit,i0,r0,r1) +static jit_word_t _bunltr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlti_f(i0,r0,i1) _bunlti_f(_jit,i0,r0,i1) +static jit_word_t _bunlti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bunlti_d(i0,r0,i1) _bunlti_d(_jit,i0,r0,i1) +static jit_word_t _bunlti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bunler_f(i0,r0,r1) bunler_d(i0,r0,r1) +# define bunler_d(i0,r0,r1) _bunler_d(_jit,i0,r0,r1) +static jit_word_t _bunler_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunlei_f(i0,r0,i1) _bunlei_f(_jit,i0,r0,i1) +static jit_word_t _bunlei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bunlei_d(i0,r0,i1) _bunlei_d(_jit,i0,r0,i1) +static jit_word_t _bunlei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define buneqr_f(i0,r0,r1) buneqr_d(i0,r0,r1) +# define buneqr_d(i0,r0,r1) _buneqr_d(_jit,i0,r0,r1) +static jit_word_t _buneqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define buneqi_f(i0,r0,i1) _buneqi_f(_jit,i0,r0,i1) +static jit_word_t _buneqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define buneqi_d(i0,r0,i1) _buneqi_d(_jit,i0,r0,i1) +static jit_word_t _buneqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bunger_f(i0,r0,r1) bunger_d(i0,r0,r1) +# define bunger_d(i0,r0,r1) _bunger_d(_jit,i0,r0,r1) +static jit_word_t _bunger_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungei_f(i0,r0,i1) _bungei_f(_jit,i0,r0,i1) +static jit_word_t _bungei_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bungei_d(i0,r0,i1) _bungei_d(_jit,i0,r0,i1) +static jit_word_t _bungei_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bungtr_f(i0,r0,r1) bungtr_d(i0,r0,r1) +# define bungtr_d(i0,r0,r1) _bungtr_d(_jit,i0,r0,r1) +static jit_word_t _bungtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bungti_f(i0,r0,i1) _bungti_f(_jit,i0,r0,i1) +static jit_word_t _bungti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bungti_d(i0,r0,i1) _bungti_d(_jit,i0,r0,i1) +static jit_word_t _bungti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bltgtr_f(i0,r0,r1) bltgtr_d(i0,r0,r1) +# define bltgtr_d(i0,r0,r1) _bltgtr_d(_jit,i0,r0,r1) +static jit_word_t _bltgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bltgti_f(i0,r0,i1) _bltgti_f(_jit,i0,r0,i1) +static jit_word_t _bltgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bltgti_d(i0,r0,i1) _bltgti_d(_jit,i0,r0,i1) +static jit_word_t _bltgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bordr_f(i0,r0,r1) bordr_d(i0,r0,r1) +# define bordr_d(i0,r0,r1) _bordr_d(_jit,i0,r0,r1) +static jit_word_t _bordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bordi_f(i0,r0,i1) _bordi_f(_jit,i0,r0,i1) +static jit_word_t _bordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bordi_d(i0,r0,i1) _bordi_d(_jit,i0,r0,i1) +static jit_word_t _bordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define bunordr_f(i0,r0,r1) bunordr_d(i0,r0,r1) +# define bunordr_d(i0,r0,r1) _bunordr_d(_jit,i0,r0,r1) +static jit_word_t _bunordr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bunordi_f(i0,r0,i1) _bunordi_f(_jit,i0,r0,i1) +static jit_word_t _bunordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t*); +# define bunordi_d(i0,r0,i1) _bunordi_d(_jit,i0,r0,i1) +static jit_word_t _bunordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t*); +# define ldr_f(r0,r1) LDS(r0,r1,0) +# define ldi_f(r0,i0) _ldi_f(_jit,r0,i0) +static void _ldi_f(jit_state_t*,jit_int32_t,jit_word_t); +# define ldr_d(r0,r1) LDT(r0,r1,0) +# define ldi_d(r0,i0) _ldi_d(_jit,r0,i0) +static void _ldi_d(jit_state_t*,jit_int32_t,jit_word_t); +# define ldxr_f(r0,r1,r2) _ldxr_f(_jit,r0,r1,r2) +static void _ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_f(r0,r1,i0) _ldxi_f(_jit,r0,r1,i0) +static void _ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define ldxr_d(r0,r1,r2) _ldxr_d(_jit,r0,r1,r2) +static void _ldxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ldxi_d(r0,r1,i0) _ldxi_d(_jit,r0,r1,i0) +static void _ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); +# define str_f(r0,r1) STS(r1,r0,0) +# define sti_f(i0,r0) _sti_f(_jit,i0,r0) +static void _sti_f(jit_state_t*,jit_word_t,jit_int32_t); +# define str_d(r0,r1) STT(r1,r0,0) +# define sti_d(i0,r0) _sti_d(_jit,i0,r0) +static void _sti_d(jit_state_t*,jit_word_t,jit_int32_t); +# define stxr_f(r0,r1,r2) _stxr_f(_jit,r0,r1,r2) +static void _stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_f(i0,r0,r1) _stxi_f(_jit,i0,r0,r1) +static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define stxr_d(r0,r1,r2) _stxr_d(_jit,r0,r1,r2) +static void _stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define stxi_d(i0,r0,r1) _stxi_d(_jit,i0,r0,r1) +static void _stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +#endif + +#if CODE +# define fpr_opi(name, type, size) \ +static void \ +_##name##i_##type(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, \ + jit_float##size##_t *i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr); \ + movi_##type(rn(reg), i0); \ + name##r_##type(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +# define fpr_bopi(name, type, size) \ +static jit_word_t \ +_b##name##i_##type(jit_state_t *_jit, \ + jit_word_t i0, jit_int32_t r0, \ + jit_float##size##_t *i1) \ +{ \ + jit_word_t word; \ + jit_int32_t reg = jit_get_reg(jit_class_fpr|jit_class_nospill);\ + movi_##type(rn(reg), i1); \ + word = b##name##r_##type(i0, r0, rn(reg)); \ + jit_unget_reg(reg); \ + return (word); \ +} +# define fopi(name) fpr_opi(name, f, 32) +# define fbopi(name) fpr_bopi(name, f, 32) +# define dopi(name) fpr_opi(name, d, 64) +# define dbopi(name) fpr_bopi(name, d, 64) + +static void +_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + FMOV(r1, r0); +} + +static void +_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_int32_t reg; + + if (_jitc->no_data) { + data.f = *i0; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.i & 0xffffffff); + stxi_i(-8, _FP_REGNO, rn(reg)); + jit_unget_reg(reg); + ldxi_f(r0, _FP_REGNO, -8); + } + else + ldi_f(r0, (jit_word_t)i0); +} + +static void +_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) +{ + union { + jit_word_t w; + jit_float64_t d; + } data; + jit_int32_t reg; + + if (_jitc->no_data) { + data.d = *i0; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.w); + stxi_l(-8, _FP_REGNO, rn(reg)); + jit_unget_reg(reg); + ldxi_d(r0, _FP_REGNO, -8); + } + else + ldi_d(r0, (jit_word_t)i0); +} + +static void +_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr); + CVTTQ_SVC(r1, rn(reg)); + TRAPB(); + stxi_d(-8, _FP_REGNO, rn(reg)); + ldxi(r0, _FP_REGNO, -8); + jit_unget_reg(reg); +} + +static void +_sqrtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + SQRTS_SU(r1, r0); + TRAPB(); +} + +static void +_sqrtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + SQRTT_SU(r1, r0); + TRAPB(); +} + +static void +_extr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + stxi_l(-8, _FP_REGNO, r1); + ldxi_d(r0, _FP_REGNO, -8); + CVTQS(r0, r0); +} + +static void +_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + stxi_l(-8, _FP_REGNO, r1); + ldxi_d(r0, _FP_REGNO, -8); + CVTQT(r0, r0); +} + +static void +_addr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + ADDS_SU(r1, r2, r0); + TRAPB(); +} +fopi(add) + +static void +_addr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + ADDT_SU(r1, r2, r0); + TRAPB(); +} +dopi(add) + +static void +_subr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SUBS_SU(r1, r2, r0); + TRAPB(); +} +fopi(sub) + +static void +_subr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SUBT_SU(r1, r2, r0); + TRAPB(); +} +dopi(sub) + +static void +_mulr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + MULS_SU(r1, r2, r0); + TRAPB(); +} +fopi(mul) + +static void +_mulr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + MULT_SU(r1, r2, r0); + TRAPB(); +} +dopi(mul) + +static void +_divr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + DIVS_SU(r1, r2, r0); + TRAPB(); +} +fopi(div) + +static void +_divr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + DIVT_SU(r1, r2, r0); + TRAPB(); +} +dopi(div) + +static void +_ltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLT_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), 1); + movi(r0, 1); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(lt); +dopi(lt); + +static void +_ler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLE_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), 1); + movi(r0, 1); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(le); +dopi(le); + +static void +_eqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTEQ_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), 1); + movi(r0, 1); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(eq); +dopi(eq); + +static void +_ger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLT_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 1); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(ge); +dopi(ge); + +static void +_gtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLE_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 1); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(gt); +dopi(gt); + +static void +_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 3); + CMPTEQ_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), 1); + movi(r0, 0); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(ne); +dopi(ne); + +static void +_unltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLT_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 0); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(unlt); +dopi(unlt); + +static void +_unler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLE_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 0); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(unle); +dopi(unle); + +static void +_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTEQ_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 0); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(uneq); +dopi(uneq); + +static void +_unger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLT_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), 1); + movi(r0, 0); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(unge); +dopi(unge); + +static void +_ungtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLE_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), 1); + movi(r0, 0); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(ungt); +dopi(ungt); + +static void +_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTEQ_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 1); + patch_at(v, _jit->pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(ltgt); +dopi(ltgt); + +static void +_ordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 0); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + movi(r0, 1); + patch_at(w, _jit->pc.w); + jit_unget_reg(reg); +} +fopi(ord); +dopi(ord); + +static void +_unordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + movi(r0, 1); + CMPTUN_SU(r1, r2, rn(reg)); + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), 1); + jit_unget_reg(reg); + movi(r0, 0); + patch_at(w, _jit->pc.w); +} +fopi(unord); +dopi(unord); + +static jit_word_t +_bltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 3); + CMPTLT_SU(r0, r1, rn(reg)); /* lt satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(lt); +dbopi(lt); + +static jit_word_t +_bler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 3); + CMPTLE_SU(r0, r1, rn(reg)); /* le satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(le); +dbopi(le); + +static jit_word_t +_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 3); + CMPTEQ_SU(r0, r1, rn(reg)); /* eq satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(eq); +dbopi(eq); + +static jit_word_t +_bger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 3); + CMPTLT_SU(r0, r1, rn(reg)); /* ge satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(ge); +dbopi(ge); + +static jit_word_t +_bgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 3); + CMPTLE_SU(r0, r1, rn(reg)); /* gt satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(gt); +dbopi(gt); + +static jit_word_t +_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t u, v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTEQ_SU(r0, r1, rn(reg)); /* ne satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 1); + patch_at(u, _jit->pc.w); + w = _jit->pc.w; + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(ne); +dbopi(ne); + +static jit_word_t +_bunltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t u, v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLT_SU(r0, r1, rn(reg)); /* lt satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBEQ(rn(reg), 1); + w = _jit->pc.w; + patch_at(u, _jit->pc.w); + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(unlt); +dbopi(unlt); + +static jit_word_t +_bunler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t u, v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLE_SU(r0, r1, rn(reg)); /* le satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBEQ(rn(reg), 1); + w = _jit->pc.w; + patch_at(u, _jit->pc.w); + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(unle); +dbopi(unle); + +static jit_word_t +_buneqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t u, v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTEQ_SU(r0, r1, rn(reg)); /* eq satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBEQ(rn(reg), 1); + w = _jit->pc.w; + patch_at(u, _jit->pc.w); + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(uneq); +dbopi(uneq); + +static jit_word_t +_bunger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t u, v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLT_SU(r0, r1, rn(reg)); /* ge satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 1); + w = _jit->pc.w; + patch_at(u, _jit->pc.w); + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(unge); +dbopi(unge); + +static jit_word_t +_bungtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + jit_word_t u, v, w; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTLE_SU(r0, r1, rn(reg)); /* gt does satisfy condition */ + TRAPB(); + v = _jit->pc.w; + FBNE(rn(reg), 1); + w = _jit->pc.w; + patch_at(u, _jit->pc.w); + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(ungt); +dbopi(ungt); + +static jit_word_t +_bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t u, v, w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + u = _jit->pc.w; + FBNE(rn(reg), 4); + CMPTEQ_SU(r1, r0, rn(reg)); + TRAPB(); + v = _jit->pc.w; /* eq does not satisfy condition */ + FBNE(rn(reg), 1); + w = _jit->pc.w; + BR(_R31_REGNO, ((i0 - w) >> 2) - 1); + patch_at(u, _jit->pc.w); + patch_at(v, _jit->pc.w); + jit_unget_reg(reg); + return (w); +} +fbopi(ltgt); +dbopi(ltgt); + +static jit_word_t +_bordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord does not satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBEQ(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} +fbopi(ord); +dbopi(ord); + +static jit_word_t +_bunordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_fpr|jit_class_nospill); + CMPTUN_SU(r0, r1, rn(reg)); /* unord satisfy condition */ + TRAPB(); + w = _jit->pc.w; + FBNE(rn(reg), ((i0 - w) >> 2) - 1); + jit_unget_reg(reg); + return (w); +} +fbopi(unord); +dbopi(unord); + +static void +_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t reg; + if (_s16_p(i0)) + LDS(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t reg; + if (_s16_p(i0)) + LDT(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_word_t reg; + if (_s16_p(i0)) + LDS(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_f(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r1, r2); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_word_t reg; + if (_s16_p(i0)) + LDT(r0, r1, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r1, i0); + ldr_d(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_word_t reg; + if (_s16_p(i0)) + STS(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_f(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_word_t reg; + if (_s16_p(i0)) + STT(r0, _R31_REGNO, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + str_d(rn(reg), r0); + jit_unget_reg(reg); + } +} + +static void +_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_f(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t reg; + if (_s16_p(i0)) + STS(r1, r0, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_f(rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t reg; + reg = jit_get_reg(jit_class_gpr); + addr(rn(reg), r0, r1); + str_d(rn(reg), r2); + jit_unget_reg(reg); +} + +static void +_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t reg; + if (_s16_p(i0)) + STT(r1, r0, _u16(i0)); + else { + reg = jit_get_reg(jit_class_gpr); + addi(rn(reg), r0, i0); + str_d(rn(reg), r1); + jit_unget_reg(reg); + } +} +#endif diff --git a/lib/jit_alpha-sz.c b/lib/jit_alpha-sz.c new file mode 100644 index 000000000..b2544fe07 --- /dev/null +++ b/lib/jit_alpha-sz.c @@ -0,0 +1,350 @@ + +#if __WORDSIZE == 64 +#define JIT_INSTR_MAX 76 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 76, + 0, + 4, + 32, + 12, + 40, + 28, + 28, + 4, + 32, + 12, + 40, + 28, + 28, + 4, + 32, + 44, + 56, + 12, + 32, + 48, + 72, + 48, + 72, + 56, + 56, + 56, + 56, + 48, + 72, + 48, + 72, + 4, + 32, + 4, + 32, + 4, + 32, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 8, + 4, + 8, + 4, + 4, + 4, + 4, + 4, + 8, + 4, + 8, + 4, + 8, + 4, + 8, + 8, + 12, + 4, + 32, + 8, + 8, + 8, + 8, + 8, + 8, + 36, + 12, + 40, + 4, + 32, + 12, + 40, + 4, + 32, + 4, + 32, + 12, + 40, + 4, + 32, + 16, + 12, + 8, + 4, + 16, + 12, + 8, + 4, + 8, + 4, + 16, + 12, + 8, + 4, + 4, + 32, + 4, + 32, + 4, + 32, + 4, + 32, + 8, + 4, + 8, + 4, + 8, + 4, + 8, + 4, + 8, + 8, + 8, + 12, + 8, + 12, + 8, + 12, + 8, + 40, + 8, + 12, + 8, + 12, + 8, + 12, + 8, + 12, + 8, + 36, + 8, + 8, + 8, + 8, + 28, + 32, + 16, + 16, + 28, + 32, + 16, + 16, + 28, + 32, + 16, + 16, + 28, + 32, + 16, + 16, + 0, + 36, + 8, + 36, + 68, + 0, + 8, + 32, + 8, + 32, + 8, + 32, + 8, + 32, + 4, + 4, + 8, + 32, + 56, + 32, + 56, + 32, + 56, + 32, + 56, + 32, + 56, + 32, + 56, + 32, + 56, + 32, + 56, + 32, + 56, + 32, + 56, + 32, + 56, + 32, + 56, + 20, + 44, + 20, + 44, + 16, + 16, + 12, + 4, + 4, + 24, + 4, + 32, + 8, + 4, + 4, + 32, + 8, + 4, + 24, + 48, + 24, + 48, + 24, + 48, + 24, + 48, + 24, + 48, + 28, + 52, + 28, + 52, + 28, + 52, + 28, + 52, + 28, + 52, + 28, + 52, + 28, + 52, + 12, + 36, + 12, + 36, + 0, + 8, + 28, + 8, + 28, + 8, + 28, + 8, + 28, + 4, + 4, + 8, + 32, + 52, + 32, + 52, + 32, + 52, + 32, + 52, + 32, + 52, + 32, + 52, + 32, + 52, + 32, + 52, + 32, + 52, + 32, + 52, + 32, + 52, + 32, + 52, + 20, + 40, + 20, + 40, + 16, + 16, + 12, + 4, + 4, + 20, + 4, + 32, + 8, + 4, + 4, + 32, + 8, + 4, + 24, + 44, + 24, + 44, + 24, + 44, + 24, + 44, + 24, + 44, + 28, + 48, + 28, + 48, + 28, + 48, + 28, + 48, + 28, + 48, + 28, + 48, + 28, + 48, + 12, + 32, + 12, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +#endif /* __WORDSIZE */ diff --git a/lib/jit_alpha.c b/lib/jit_alpha.c new file mode 100644 index 000000000..081151711 --- /dev/null +++ b/lib/jit_alpha.c @@ -0,0 +1,1253 @@ +/* + * Copyright (C) 2014 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#define rc(value) jit_class_##value +#define rn(reg) (jit_regno(_rvs[jit_regno(reg)].spec)) + +/* + * Prototypes + */ +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); + +#define PROTO 1 +# include "jit_alpha-cpu.c" +# include "jit_alpha-fpu.c" +#undef PROTO + +/* + * Initialization + */ +jit_register_t _rvs[] = { + { rc(gpr) | 0x1c, "at" }, + { rc(gpr) | 0x00, "v0" }, + { rc(gpr) | 0x01, "t0" }, + { rc(gpr) | 0x02, "t1" }, + { rc(gpr) | 0x03, "t2" }, + { rc(gpr) | 0x04, "t3" }, + { rc(gpr) | 0x05, "t4" }, + { rc(gpr) | 0x06, "t5" }, + { rc(gpr) | 0x07, "t6" }, + { rc(gpr) | 0x08, "t7" }, + { rc(gpr) | 0x16, "t8" }, + { rc(gpr) | 0x17, "t9" }, + { rc(gpr) | 0x18, "t10" }, + { rc(gpr) | 0x19, "t11" }, + { rc(sav) | rc(gpr) | 0x09, "s0" }, + { rc(sav) | rc(gpr) | 0x0a, "s1" }, + { rc(sav) | rc(gpr) | 0x0b, "s2" }, + { rc(sav) | rc(gpr) | 0x0c, "s3" }, + { rc(sav) | rc(gpr) | 0x0d, "s4" }, + { rc(sav) | rc(gpr) | 0x0e, "s5" }, + { 0x0f, "fp" }, + { rc(arg) | rc(gpr) | 0x15, "a5" }, + { rc(arg) | rc(gpr) | 0x14, "a4" }, + { rc(arg) | rc(gpr) | 0x13, "a3" }, + { rc(arg) | rc(gpr) | 0x12, "a2" }, + { rc(arg) | rc(gpr) | 0x11, "a1" }, + { rc(arg) | rc(gpr) | 0x10, "a0" }, + { 0x1a, "ra" }, + { 0x1b, "pv" }, + { 0x1d, "gp" }, + { 0x1e, "sp" }, + { 0x1f, "zero" }, + { rc(fpr) | 0x00, "$f0" }, + { rc(fpr) | 0x01, "$f1" }, + { rc(sav) | rc(fpr) | 0x02, "$f2" }, + { rc(sav) | rc(fpr) | 0x03, "$f3" }, + { rc(sav) | rc(fpr) | 0x04, "$f4" }, + { rc(sav) | rc(fpr) | 0x05, "$f5" }, + { rc(sav) | rc(fpr) | 0x06, "$f6" }, + { rc(sav) | rc(fpr) | 0x07, "$f7" }, + { rc(sav) | rc(fpr) | 0x08, "$f8" }, + { rc(sav) | rc(fpr) | 0x09, "$f9" }, + { rc(fpr) | 0x0a, "$f10" }, + { rc(fpr) | 0x0b, "$f11" }, + { rc(fpr) | 0x0c, "$f12" }, + { rc(fpr) | 0x0d, "$f13" }, + { rc(fpr) | 0x0e, "$f14" }, + { rc(fpr) | 0x0f, "$f15" }, + { rc(sav) | rc(fpr) | 0x15, "$f21" }, + { rc(sav) | rc(fpr) | 0x14, "$f20" }, + { rc(sav) | rc(fpr) | 0x13, "$f19" }, + { rc(sav) | rc(fpr) | 0x12, "$f18" }, + { rc(sav) | rc(fpr) | 0x11, "$f17" }, + { rc(arg) | rc(fpr) | 0x10, "$f16" }, + { rc(fpr) | 0x16, "$f22" }, + { rc(fpr) | 0x17, "$f23" }, + { rc(fpr) | 0x18, "$f24" }, + { rc(fpr) | 0x19, "$f25" }, + { rc(fpr) | 0x1a, "$f26" }, + { rc(fpr) | 0x1b, "$f27" }, + { rc(fpr) | 0x1c, "$f28" }, + { rc(fpr) | 0x1d, "$f29" }, + { rc(fpr) | 0x1e, "$f30" }, + { 0x1f, "$f31" }, + { _NOREG, "" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ +} + +void +_jit_init(jit_state_t *_jit) +{ + _jitc->reglen = jit_size(_rvs) - 1; + jit_carry = _NOREG; +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + _jitc->function->self.size = stack_framesize; + _jitc->function->self.argi = _jitc->function->self.alen = 0; + /* float conversion */ + _jitc->function->self.aoff = -8; + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + assert(_jitc->function != NULL); + switch (length) { + case 0: case 1: break; + case 2: _jitc->function->self.aoff &= -2; break; + case 3: case 4: _jitc->function->self.aoff &= -4; break; + default: _jitc->function->self.aoff &= -8; break; + } + _jitc->function->self.aoff -= length; + return (_jitc->function->self.aoff); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + + assert(_jitc->function != NULL); + + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + if (JIT_RET != u) + jit_movr(JIT_RET, u); + else + jit_live(JIT_RET); + 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) +{ + if (u != JIT_FRET) + jit_movr_f(JIT_FRET, u); + else + jit_live(JIT_FRET); + 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) +{ + if (u != JIT_FRET) + jit_movr_d(JIT_FRET, u); + else + jit_live(JIT_FRET); + 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 != NULL); + 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 != NULL); + if (_jitc->function->self.argi < 6) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += 8; + } + 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 < 6); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + jit_int32_t offset; + assert(_jitc->function != NULL); + if (_jitc->function->self.argi < 6) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += 8; + } + 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 < 6); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + jit_int32_t offset; + assert(_jitc->function != NULL); + if (_jitc->function->self.argi < 6) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += 8; + } + 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 < 6) + jit_extr_c(u, _A0 - v->u.w); + else { +#if __BYTE_ORDER == __LITTLE_ENDIAN + jit_ldxi_c(u, _FP, v->u.w); +#else + jit_ldxi_c(u, JIT_FP, v->u.w + 8 - sizeof(jit_int8_t)); +#endif + } +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 6) + jit_extr_uc(u, _A0 - v->u.w); + else { +#if __BYTE_ORDER == __LITTLE_ENDIAN + jit_ldxi_uc(u, _FP, v->u.w); +#else + jit_ldxi_uc(u, JIT_FP, v->u.w + 8 - sizeof(jit_uint8_t)); +#endif + } +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 6) + jit_extr_s(u, _A0 - v->u.w); + else { +#if __BYTE_ORDER == __LITTLE_ENDIAN + jit_ldxi_s(u, _FP, v->u.w); +#else + jit_ldxi_s(u, JIT_FP, v->u.w + 8 - sizeof(jit_int16_t)); +#endif + } +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 6) + jit_extr_us(u, _A0 - v->u.w); + else { +#if __BYTE_ORDER == __LITTLE_ENDIAN + jit_ldxi_us(u, _FP, v->u.w); +#else + jit_ldxi_us(u, JIT_FP, v->u.w + 8 - sizeof(jit_uint16_t)); +#endif + } +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 6) + jit_extr_i(u, _A0 - v->u.w); + else { +#if __BYTE_ORDER == __LITTLE_ENDIAN + jit_ldxi_i(u, _FP, v->u.w); +#else + jit_ldxi_i(u, JIT_FP, v->u.w + 8 - sizeof(jit_int32_t)); +#endif + } +} + +void +_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 6) + jit_extr_ui(u, _A0 - v->u.w); + else { +#if __BYTE_ORDER == __LITTLE_ENDIAN + jit_ldxi_ui(u, _FP, v->u.w); +#else + jit_ldxi_ui(u, JIT_FP, v->u.w + 8 - sizeof(jit_uint32_t)); +#endif + } +} + +void +_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 6) + jit_movr(u, _A0 - v->u.w); + else + jit_ldxi_l(u, _FP, v->u.w); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 6) + jit_movr_f(u, _F16 - v->u.w); + else { +#if __BYTE_ORDER == __LITTLE_ENDIAN + jit_ldxi_f(u, _FP, v->u.w); +#else + jit_ldxi_f(u, JIT_FP, v->u.w + 8 - sizeof(jit_float32_t)); +#endif + } +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + if (v->u.w < 6) + jit_movr_d(u, _F16 - v->u.w); + else + jit_ldxi_d(u, _FP, v->u.w); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function != NULL); + if (_jitc->function->call.argi < 6) { + jit_movr(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += 8; + } +} + +void +_jit_pushargi(jit_state_t *_jit, jit_int64_t u) +{ + jit_int32_t regno; + assert(_jitc->function != NULL); + if (_jitc->function->call.argi < 6) { + jit_movi(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size, JIT_SP, regno); + _jitc->function->call.size += 8; + jit_unget_reg(regno); + } +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function != NULL); + if (_jitc->function->call.argi < 6) { + jit_movr_f(_F16 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { +#if __BYTE_ORDER == __LITTLE_ENDIAN + jit_stxi_f(_jitc->function->call.size, JIT_SP, u); +#else + jit_stxi_f(_jitc->function->call.size + 8 - sizeof(jit_float32_t), + JIT_SP, u); +#endif + _jitc->function->call.size += 8; + } +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_int32_t regno; + assert(_jitc->function != NULL); + if (_jitc->function->call.argi < 6) { + jit_movi_f(_F16 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); +#if __BYTE_ORDER == __LITTLE_ENDIAN + jit_stxi_f(_jitc->function->call.size, JIT_SP, regno); +#else + jit_stxi_f(_jitc->function->call.size + 8 - sizeof(jit_float32_t), + JIT_SP, regno); +#endif + _jitc->function->call.size += 8; + jit_unget_reg(regno); + } +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function != NULL); + if (_jitc->function->call.argi < 6) { + jit_movr_d(_F16 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi_d(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += 8; + } +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; + assert(_jitc->function != NULL); + if (_jitc->function->call.argi < 6) { + jit_movi_d(_F16 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(_jitc->function->call.size, JIT_SP, regno); + _jitc->function->call.size += 8; + jit_unget_reg(regno); + } +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + jit_int32_t spec; + + spec = jit_class(_rvs[regno].spec); + if (spec & jit_class_arg) { + if (spec & jit_class_gpr) { + regno = _A0 - regno; + if (regno >= 0 && regno < node->v.w) + return (1); + } + else if (spec & jit_class_fpr) { + regno = _F16 - regno; + if (regno >= 0 && regno < node->w.w) + return (1); + } + } + + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_node_t *call; + + assert(_jitc->function != NULL); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + call = jit_callr(r0); + call->v.w = call->w.w = _jitc->function->self.argi; + _jitc->function->call.argi = _jitc->function->call.size = 0; + _jitc->prepare = 0; +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ + jit_node_t *call; + + assert(_jitc->function != NULL); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + call = jit_calli(i0); + call->v.w = call->w.w = _jitc->function->self.argf; + _jitc->function->call.argi = _jitc->function->call.size = 0; + _jitc->prepare = 0; + return (call); +} + +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) +{ + if (r0 != JIT_RET) + jit_movr(r0, JIT_RET); +} + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + if (r0 != JIT_FRET) + jit_movr_f(r0, JIT_FRET); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + if (r0 != JIT_FRET) + jit_movr_d(r0, JIT_FRET); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_word_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_uint8_t *data; + jit_word_t word; + jit_int32_t const_offset; + jit_int32_t patch_offset; + } undo; + + _jitc->function = NULL; + + jit_reglive_setup(); + + undo.word = 0; + undo.node = NULL; + undo.const_offset = undo.patch_offset = 0; +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \ + break +#define case_rrf(name, type, size) \ + case jit_code_##name##i##type: \ + assert(node->flag & jit_flag_data); \ + name##i##type(rn(node->u.w), rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type(_jit->pc.w, \ + rn(node->v.w), rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break +#define case_brf(name, type, size) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + else { \ + word = name##i##type(_jit->pc.w, rn(node->v.w), \ + (jit_float##size##_t *)node->w.n->u.w); \ + patch(word, node); \ + } \ + break + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end) + 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: + /* 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_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_rr(trunc, _f_i); + case_rr(trunc, _d_i); + case_rr(trunc, _f_l); + case_rr(trunc, _d_l); + case_rr(ld, _c); + case_rw(ld, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rr(ld, _i); + case_rw(ld, _i); + case_rr(ld, _ui); + case_rw(ld, _ui); + case_rr(ld, _l); + case_rw(ld, _l); + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rrr(ldx, _i); + case_rrw(ldx, _i); + case_rrr(ldx, _ui); + case_rrw(ldx, _ui); + case_rrr(ldx, _l); + case_rrw(ldx, _l); + case_rr(st, _c); + case_wr(st, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rr(st, _i); + case_wr(st, _i); + case_rr(st, _l); + case_wr(st, _l); + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rrr(stx, _i); + case_wrr(stx, _i); + case_rrr(stx, _l); + case_wrr(stx, _l); + case_rr(hton,); + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); + case_rr(ext, _i); + case_rr(ext, _ui); + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), node->v.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rr(neg,); + case_rr(com,); + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_rrr(add, _f); + case_rrf(add, _f, 32); + case_rrr(sub, _f); + case_rrf(sub, _f, 32); + case_rrr(mul, _f); + case_rrf(mul, _f, 32); + case_rrr(div, _f); + case_rrf(div, _f, 32); + case_rr(abs, _f); + case_rr(neg, _f); + case_rr(sqrt, _f); + case_rr(ext, _f); + case_rr(ld, _f); + case_rw(ld, _f); + case_rrr(ldx, _f); + case_rrw(ldx, _f); + case_rr(st, _f); + case_wr(st, _f); + case_rrr(stx, _f); + case_wrr(stx, _f); + case_rr(mov, _f); + case jit_code_movi_f: + assert(node->flag & jit_flag_data); + movi_f(rn(node->u.w), (jit_float32_t *)node->v.n->u.w); + break; + case_rr(ext, _d_f); + case_rrr(lt, _f); + case_rrf(lt, _f, 32); + case_rrr(le, _f); + case_rrf(le, _f, 32); + case_rrr(eq, _f); + case_rrf(eq, _f, 32); + case_rrr(ge, _f); + case_rrf(ge, _f, 32); + case_rrr(gt, _f); + case_rrf(gt, _f, 32); + case_rrr(ne, _f); + case_rrf(ne, _f, 32); + case_rrr(unlt, _f); + case_rrf(unlt, _f, 32); + case_rrr(unle, _f); + case_rrf(unle, _f, 32); + case_rrr(uneq, _f); + case_rrf(uneq, _f, 32); + case_rrr(unge, _f); + case_rrf(unge, _f, 32); + case_rrr(ungt, _f); + case_rrf(ungt, _f, 32); + case_rrr(ltgt, _f); + case_rrf(ltgt, _f, 32); + case_rrr(ord, _f); + case_rrf(ord, _f, 32); + case_rrr(unord, _f); + case_rrf(unord, _f, 32); + case_brr(blt, _f); + case_brf(blt, _f, 32); + case_brr(ble, _f); + case_brf(ble, _f, 32); + case_brr(beq, _f); + case_brf(beq, _f, 32); + case_brr(bge, _f); + case_brf(bge, _f, 32); + case_brr(bgt, _f); + case_brf(bgt, _f, 32); + case_brr(bne, _f); + case_brf(bne, _f, 32); + case_brr(bunlt, _f); + case_brf(bunlt, _f, 32); + case_brr(bunle, _f); + case_brf(bunle, _f, 32); + case_brr(buneq, _f); + case_brf(buneq, _f, 32); + case_brr(bunge, _f); + case_brf(bunge, _f, 32); + case_brr(bungt, _f); + case_brf(bungt, _f, 32); + case_brr(bltgt, _f); + case_brf(bltgt, _f, 32); + case_brr(bord, _f); + case_brf(bord, _f, 32); + case_brr(bunord, _f); + case_brf(bunord, _f, 32); + case_rrr(add, _d); + case_rrf(add, _d, 64); + case_rrr(sub, _d); + case_rrf(sub, _d, 64); + case_rrr(mul, _d); + case_rrf(mul, _d, 64); + case_rrr(div, _d); + case_rrf(div, _d, 64); + case_rr(abs, _d); + case_rr(neg, _d); + case_rr(sqrt, _d); + case_rr(ext, _d); + case_rr(ld, _d); + case_rw(ld, _d); + case_rrr(ldx, _d); + case_rrw(ldx, _d); + case_rr(st, _d); + case_wr(st, _d); + case_rrr(stx, _d); + case_wrr(stx, _d); + case_rr(mov, _d); + case jit_code_movi_d: + assert(node->flag & jit_flag_data); + movi_d(rn(node->u.w), (jit_float64_t *)node->v.n->u.w); + break; + case_rr(ext, _f_d); + case_rrr(lt, _d); + case_rrf(lt, _d, 64); + case_rrr(le, _d); + case_rrf(le, _d, 64); + case_rrr(eq, _d); + case_rrf(eq, _d, 64); + case_rrr(ge, _d); + case_rrf(ge, _d, 64); + case_rrr(gt, _d); + case_rrf(gt, _d, 64); + case_rrr(ne, _d); + case_rrf(ne, _d, 64); + case_rrr(unlt, _d); + case_rrf(unlt, _d, 64); + case_rrr(unle, _d); + case_rrf(unle, _d, 64); + case_rrr(uneq, _d); + case_rrf(uneq, _d, 64); + case_rrr(unge, _d); + case_rrf(unge, _d, 64); + case_rrr(ungt, _d); + case_rrf(ungt, _d, 64); + case_rrr(ltgt, _d); + case_rrf(ltgt, _d, 64); + case_rrr(ord, _d); + case_rrf(ord, _d, 64); + case_rrr(unord, _d); + case_rrf(unord, _d, 64); + case_brr(blt, _d); + case_brf(blt, _d, 64); + case_brr(ble, _d); + case_brf(ble, _d, 64); + case_brr(beq, _d); + case_brf(beq, _d, 64); + case_brr(bge, _d); + case_brf(bge, _d, 64); + case_brr(bgt, _d); + case_brf(bgt, _d, 64); + case_brr(bne, _d); + case_brf(bne, _d, 64); + case_brr(bunlt, _d); + case_brf(bunlt, _d, 64); + case_brr(bunle, _d); + case_brf(bunle, _d, 64); + case_brr(buneq, _d); + case_brf(buneq, _d, 64); + case_brr(bunge, _d); + case_brf(bunge, _d, 64); + case_brr(bungt, _d); + case_brf(bungt, _d, 64); + case_brr(bltgt, _d); + case_brf(bltgt, _d, 64); + case_brr(bord, _d); + case_brf(bord, _d, 64); + case_brr(bunord, _d); + case_brf(bunord, _d, 64); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + break; + case jit_code_jmpi: + 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)) { + word = calli_p(temp->u.w); + patch(word, node); + } + else + calli(temp->u.w); + } + else + calli(node->u.w); + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; + 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; + } + /* 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(); + } + if (jit_carry != _NOREG) { + switch (node->code) { + case jit_code_note: + case jit_code_addcr: case jit_code_addci: + case jit_code_addxr: case jit_code_addxi: + case jit_code_subcr: case jit_code_subci: + case jit_code_subxr: case jit_code_subxi: + break; + default: + jit_unget_reg(jit_carry); + jit_carry = _NOREG; + break; + } + } + jit_regarg_clr(node, value); + /* update register live state */ + jit_reglive(node); + } +#undef case_brf +#undef case_brw +#undef case_brr +#undef case_wrr +#undef case_rrrw +#undef case_rrrr +#undef case_rrf +#undef case_rrw +#undef case_rrr +#undef case_wr +#undef case_rw +#undef case_rr + for (offset = 0; offset < _jitc->patches.offset; offset++) { + node = _jitc->patches.ptr[offset].node; + word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(_jitc->patches.ptr[offset].inst, word); + } + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_alpha-cpu.c" +# include "jit_alpha-fpu.c" +#undef CODE + +void +_emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi(rn(r0), rn(r1), i0); +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi(i0, rn(r0), rn(r1)); +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi_d(rn(r0), rn(r1), i0); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi_d(i0, rn(r0), rn(r1)); +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) + flag = node->v.n->flag; + else + flag = node->u.n->flag; + assert(!(flag & jit_flag_patch)); + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} diff --git a/lib/jit_disasm.c b/lib/jit_disasm.c index a56e8b63c..361200e95 100644 --- a/lib/jit_disasm.c +++ b/lib/jit_disasm.c @@ -100,6 +100,10 @@ jit_init_debug(char *progname) disasm_info.mach = bfd_mach_s390_64; disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG; disasm_info.disassembler_options = "zarch"; +# endif +# if defined(__alpha__) + disasm_info.arch = bfd_arch_alpha; + disasm_info.mach = bfd_mach_alpha_ev6; # endif disasm_info.print_address_func = disasm_print_address; @@ -117,7 +121,13 @@ jit_init_debug(char *progname) if (bfd_get_file_flags(disasm_bfd) & DYNAMIC) { dyn_storage = bfd_get_dynamic_symtab_upper_bound(disasm_bfd); +# if defined(__alpha__) + /* XXX */ + if (dyn_storage < 0) + dyn_storage = 0; +# else assert(dyn_storage >= 0); +# endif } else dyn_storage = 0; diff --git a/lib/jit_size.c b/lib/jit_size.c index 6678915a2..1215c3ca9 100644 --- a/lib/jit_size.c +++ b/lib/jit_size.c @@ -48,6 +48,8 @@ static jit_int16_t _szs[jit_code_x86_retval_d + 1] = { # include "jit_aarch64-sz.c" # elif defined(__s390x__) # include "jit_s390x-sz.c" +# elif defined(__alpha__) +# include "jit_alpha-sz.c" # endif #endif }; diff --git a/lib/lightning.c b/lib/lightning.c index cb6ddac4a..d816a45c0 100644 --- a/lib/lightning.c +++ b/lib/lightning.c @@ -3113,4 +3113,6 @@ _patch_register(jit_state_t *_jit, jit_node_t *node, jit_node_t *link, # include "jit_aarch64.c" #elif defined(__s390x__) # include "jit_s390x.c" +#elif defined(__alpha__) +# include "jit_alpha.c" #endif