From 24d91c0d04f99eed9a89e8d180a067e13ce8a0b2 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Wed, 19 Oct 2022 18:24:34 +0100 Subject: [PATCH] git subrepo pull (merge) --force deps/lightning subrepo: subdir: "deps/lightning" merged: "b910a469a9" upstream: origin: "https://github.com/pcercuei/gnu_lightning.git" branch: "pcsx_rearmed" commit: "b910a469a9" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" --- deps/lightning/.gitrepo | 4 +- deps/lightning/ChangeLog | 13 + deps/lightning/check/float.tst | 4 +- deps/lightning/check/lightning.c | 5 + deps/lightning/configure.ac | 31 +- deps/lightning/include/lightning.h.in | 2 + deps/lightning/include/lightning/Makefile.am | 4 + .../include/lightning/jit_loongarch.h | 77 + .../lightning/include/lightning/jit_private.h | 9 +- deps/lightning/lib/Makefile.am | 4 + deps/lightning/lib/jit_loongarch-cpu.c | 2716 +++++++++++++++++ deps/lightning/lib/jit_loongarch-fpu.c | 1318 ++++++++ deps/lightning/lib/jit_loongarch-sz.c | 408 +++ deps/lightning/lib/jit_loongarch.c | 1623 ++++++++++ deps/lightning/lib/jit_size.c | 2 + deps/lightning/lib/lightning.c | 83 +- 16 files changed, 6264 insertions(+), 39 deletions(-) create mode 100644 deps/lightning/include/lightning/jit_loongarch.h create mode 100644 deps/lightning/lib/jit_loongarch-cpu.c create mode 100644 deps/lightning/lib/jit_loongarch-fpu.c create mode 100644 deps/lightning/lib/jit_loongarch-sz.c create mode 100644 deps/lightning/lib/jit_loongarch.c diff --git a/deps/lightning/.gitrepo b/deps/lightning/.gitrepo index 5db5b905..6cc08780 100644 --- a/deps/lightning/.gitrepo +++ b/deps/lightning/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/pcercuei/gnu_lightning.git branch = pcsx_rearmed - commit = 4941e101f8b88837fc4aebe59ada85a0c0b17534 - parent = fdf33147c33ab1cb27c4bd06b377f744411030c3 + commit = b910a469a9bea63056eb53430dea4c7b56e447a8 + parent = 13b02197fcb7575646408094d5583ed7391b1153 method = merge cmdver = 0.4.3 diff --git a/deps/lightning/ChangeLog b/deps/lightning/ChangeLog index d25df3d0..40ade7a2 100644 --- a/deps/lightning/ChangeLog +++ b/deps/lightning/ChangeLog @@ -1,3 +1,16 @@ +2022-10-12 Paulo Andrade + + * include/lightning/jit_loongarch.h, lib/jit_loongarch-cpu.c, + lib/jit_loongarch-fpu.c, lib/jit_loongarch-sz.c, lib/jit_loongarch.c: + New files implementing the first version of the new loongarch port. + * check/float.tst: Add preprocessor checks for NaN and +-Inf + values converted to integers for loongarch. + * configure.ac: Add check and conditionals for new architecture. + * include/lightning.h.in, check/lightning.c, + include/lightning/Makefile.am, include/lightning/jit_private.h, + lib/Makefile.am, lib/jit_size.c, lib/lightning.c: Update for new + port. + 2022-10-05 Paulo Andrade * check/lightning.c: Remove -Dmacro=value from usage and attempt diff --git a/deps/lightning/check/float.tst b/deps/lightning/check/float.tst index ff5606ac..05a0889a 100644 --- a/deps/lightning/check/float.tst +++ b/deps/lightning/check/float.tst @@ -16,12 +16,12 @@ ok: #if __mips__ || __sparc__ || __hppa__ || __riscv # define wnan x7f -#elif __arm__ || __aarch64__ || __alpha__ +#elif __arm__ || __aarch64__ || __alpha__ || __loongarch__ # define wnan 0 #else # define wnan x80 #endif -#if __mips__ || __arm__ || __ppc__ || __sparc__ || __hppa__ || __aarch64__ || __s390__ || __riscv +#if __mips__ || __arm__ || __ppc__ || __sparc__ || __hppa__ || __aarch64__ || __s390__ || __riscv || __loongarch__ # define wpinf x7f #elif __alpha__ /* (at least) bug compatible with gcc 4.2.3 -ieee */ diff --git a/deps/lightning/check/lightning.c b/deps/lightning/check/lightning.c index 3d916f79..4f3b052b 100644 --- a/deps/lightning/check/lightning.c +++ b/deps/lightning/check/lightning.c @@ -4307,6 +4307,11 @@ main(int argc, char *argv[]) opt_short += snprintf(cmdline + opt_short, sizeof(cmdline) - opt_short, " -D__alpha__=1"); +#endif +#if defined(__loongarch__) + opt_short += snprintf(cmdline + opt_short, + sizeof(cmdline) - opt_short, + " -D__loongarch__=1"); #endif if ((parser.fp = popen(cmdline, "r")) == NULL) error("cannot execute %s", cmdline); diff --git a/deps/lightning/configure.ac b/deps/lightning/configure.ac index 63bbadb5..39d22091 100644 --- a/deps/lightning/configure.ac +++ b/deps/lightning/configure.ac @@ -14,8 +14,8 @@ dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public dnl License for more details. dnl -AC_PREREQ(2.64) -AC_INIT([GNU lightning], 2.1.3, pcpa@gnu.org, lightning) +AC_PREREQ([2.71]) +AC_INIT([GNU lightning],[2.1.3],[pcpa@gnu.org],[lightning]) AC_CONFIG_AUX_DIR([build-aux]) AC_CANONICAL_TARGET AC_CONFIG_SRCDIR([Makefile.am]) @@ -201,19 +201,21 @@ case "$target_cpu" in s390*) cpu=s390 ;; alpha*) cpu=alpha ;; riscv*) cpu=riscv ;; + loongarch*) cpu=loongarch ;; *) ;; esac -AM_CONDITIONAL(cpu_arm, [test cpu-$cpu = cpu-arm]) -AM_CONDITIONAL(cpu_mips, [test cpu-$cpu = cpu-mips]) -AM_CONDITIONAL(cpu_ppc, [test cpu-$cpu = cpu-ppc]) -AM_CONDITIONAL(cpu_sparc, [test cpu-$cpu = cpu-sparc]) -AM_CONDITIONAL(cpu_x86, [test cpu-$cpu = cpu-x86]) -AM_CONDITIONAL(cpu_ia64, [test cpu-$cpu = cpu-ia64]) -AM_CONDITIONAL(cpu_hppa, [test cpu-$cpu = cpu-hppa]) -AM_CONDITIONAL(cpu_aarch64, [test cpu-$cpu = cpu-aarch64]) -AM_CONDITIONAL(cpu_s390, [test cpu-$cpu = cpu-s390]) -AM_CONDITIONAL(cpu_alpha, [test cpu-$cpu = cpu-alpha]) -AM_CONDITIONAL(cpu_riscv, [test cpu-$cpu = cpu-riscv]) +AM_CONDITIONAL(cpu_arm, [test cpu-$cpu = cpu-arm]) +AM_CONDITIONAL(cpu_mips, [test cpu-$cpu = cpu-mips]) +AM_CONDITIONAL(cpu_ppc, [test cpu-$cpu = cpu-ppc]) +AM_CONDITIONAL(cpu_sparc, [test cpu-$cpu = cpu-sparc]) +AM_CONDITIONAL(cpu_x86, [test cpu-$cpu = cpu-x86]) +AM_CONDITIONAL(cpu_ia64, [test cpu-$cpu = cpu-ia64]) +AM_CONDITIONAL(cpu_hppa, [test cpu-$cpu = cpu-hppa]) +AM_CONDITIONAL(cpu_aarch64, [test cpu-$cpu = cpu-aarch64]) +AM_CONDITIONAL(cpu_s390, [test cpu-$cpu = cpu-s390]) +AM_CONDITIONAL(cpu_alpha, [test cpu-$cpu = cpu-alpha]) +AM_CONDITIONAL(cpu_riscv, [test cpu-$cpu = cpu-riscv]) +AM_CONDITIONAL(cpu_loongarch, [test cpu-$cpu = cpu-loongarch]) # Test x87 if both, x87 and sse2 available ac_cv_test_x86_x87= @@ -327,7 +329,7 @@ if test $ac_cv_header_stdint_h = yes; then AC_SUBST(MAYBE_INCLUDE_STDINT_H, ["#include "]) fi -AC_OUTPUT([Makefile +AC_CONFIG_FILES([Makefile lightning.pc gnulib-lib/Makefile doc/Makefile @@ -336,3 +338,4 @@ AC_OUTPUT([Makefile include/lightning.h lib/Makefile check/Makefile]) +AC_OUTPUT diff --git a/deps/lightning/include/lightning.h.in b/deps/lightning/include/lightning.h.in index 48957cb7..67c6af15 100644 --- a/deps/lightning/include/lightning.h.in +++ b/deps/lightning/include/lightning.h.in @@ -151,6 +151,8 @@ typedef jit_int32_t jit_fpr_t; # include #elif defined(__riscv) # include +#elif defined(__loongarch__) +# include #endif #define jit_flag_node 0x0001 /* patch node not absolute */ diff --git a/deps/lightning/include/lightning/Makefile.am b/deps/lightning/include/lightning/Makefile.am index 9bc1e86d..e21bbaa9 100644 --- a/deps/lightning/include/lightning/Makefile.am +++ b/deps/lightning/include/lightning/Makefile.am @@ -63,3 +63,7 @@ if cpu_riscv lightning_include_HEADERS = \ jit_riscv.h endif +if cpu_loongarch +lightning_include_HEADERS = \ + jit_loongarch.h +endif diff --git a/deps/lightning/include/lightning/jit_loongarch.h b/deps/lightning/include/lightning/jit_loongarch.h new file mode 100644 index 00000000..44982ecc --- /dev/null +++ b/deps/lightning/include/lightning/jit_loongarch.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2022 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#ifndef _jit_loongarch_h +#define _jit_loongarch_h + +/* + * Types + */ +#define JIT_FP _FP +typedef enum { +#define jit_r_num() 9 +#define jit_r(i) (_T0 - (i)) +#define JIT_R0 _T0 +#define JIT_R1 _T1 +#define JIT_R2 _T2 +#define JIT_R3 _T3 +#define JIT_R4 _T4 +#define JIT_R5 _T5 +#define JIT_R6 _T6 +#define JIT_R7 _T7 +#define JIT_R8 _T8 + _T8, _T7, _T6, _T5, _T4, _T3, _T2, _T1, _T0, +#define jit_v_num() 9 +#define jit_v(i) (_S0 - (i)) +#define JIT_V0 _S0 +#define JIT_V1 _S1 +#define JIT_V2 _S2 +#define JIT_V3 _S3 +#define JIT_V4 _S4 +#define JIT_V5 _S5 +#define JIT_V6 _S6 +#define JIT_V7 _S7 +#define JIT_V8 _S8 + _S8, _S7, _S6, _S5, _S4, _S3, _S2, _S1, _S0, + _A7, _A6, _A5, _A4, _A3, _A2, _A1, _A0, + _FP, + _R21, + _ZERO, + _RA, + _TP, + _SP, + _FT0, _FT1, _FT2, _FT3, _FT4, _FT5, _FT6, _FT7, + _FT8, _FT9, _FT10, _FT11, _FT12, _FT13, _FT14, _FT15, + _FA7, _FA6, _FA5, _FA4, FA3, _FA2, _FA1, _FA0, +#define jit_f_num() 8 +#define jit_f(i) (_FS0 - (i)) +#define JIT_F0 _FS0 +#define JIT_F1 _FS1 +#define JIT_F2 _FS2 +#define JIT_F3 _FS3 +#define JIT_F4 _FS4 +#define JIT_F5 _FS5 +#define JIT_F6 _FS6 +#define JIT_F7 _FS7 + _FS7, _FS6, _FS5, _FS4, _FS3, _FS2, _FS1, _FS0, +#define JIT_NOREG _NOREG + _NOREG, +} jit_reg_t; + +#endif /* _jit_loongarch_h */ diff --git a/deps/lightning/include/lightning/jit_private.h b/deps/lightning/include/lightning/jit_private.h index 8b4f5289..d0420b8b 100644 --- a/deps/lightning/include/lightning/jit_private.h +++ b/deps/lightning/include/lightning/jit_private.h @@ -150,6 +150,13 @@ typedef jit_uint64_t jit_regset_t; # define JIT_RET _A0 # define JIT_FRET _FA0 typedef jit_uint64_t jit_regset_t; +#elif defined(__loongarch__) +# define JIT_RA0 _A0 +# define JIT_FA0 _FA0 +# define JIT_SP _SP +# define JIT_RET _A0 +# define JIT_FRET _FA0 +typedef jit_uint64_t jit_regset_t; #endif #define jit_data(u,v,w) _jit_data(_jit,u,v,w) @@ -503,7 +510,7 @@ struct jit_compiler { jit_int32_t breg; /* base register for prolog/epilog */ #endif #if __mips__ || __ia64__ || __alpha__ || \ - (__sparc__ && __WORDSIZE == 64) || __riscv + (__sparc__ && __WORDSIZE == 64) || __riscv || __loongarch__ jit_int32_t carry; #define jit_carry _jitc->carry #endif diff --git a/deps/lightning/lib/Makefile.am b/deps/lightning/lib/Makefile.am index 28baee72..a30e7fda 100644 --- a/deps/lightning/lib/Makefile.am +++ b/deps/lightning/lib/Makefile.am @@ -58,6 +58,10 @@ EXTRA_DIST = \ jit_ia64-cpu.c \ jit_ia64-fpu.c \ jit_ia64-sz.c \ + jit_loongarch.c \ + jit_loongarch-cpu.c \ + jit_loongarch-fpu.c \ + jit_loongarch-sz.c \ jit_mips.c \ jit_mips-cpu.c \ jit_mips-fpu.c \ diff --git a/deps/lightning/lib/jit_loongarch-cpu.c b/deps/lightning/lib/jit_loongarch-cpu.c new file mode 100644 index 00000000..052d9ac5 --- /dev/null +++ b/deps/lightning/lib/jit_loongarch-cpu.c @@ -0,0 +1,2716 @@ +/* + * Copyright (C) 2022 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# define ii(i) *_jit->pc.ui++ = (i) +# define can_sign_extend_si12_p(s12) ((s12) <= 2047 && (s12) >= -2048) +# define can_zero_extend_u12_p(u12) ((u12) <= 4095 && (u12) >= 0) +# define can_sign_extend_si16_p(s16) ((s16) <= 32767 && (s16) >= -32768) +# define can_sign_extend_si21_p(s21) ((s21) <= 1048575 && (s21) >= -1048576) +# define can_sign_extend_si26_p(s26) \ + ((s26) <= 33554431 && (s26) >= -33554432) +# define can_sign_extend_si32_p(s32) \ + ((s32) <= 2147483647LL && (s32) >= -2147483648LL) +# define _ZERO_REGNO 0 +# define _RA_REGNO 1 +# define _SP_REGNO 3 +# define _FP_REGNO 22 +# define stack_framesize 160 +# define ldr(u, v) ldr_l(u, v) +# define ldi(u, v) ldi_l(u, v) +# define ldxi(u, v, w) ldxi_l(u, v, w) +# define sti(u, v) sti_l(u, v) +# define stxi(u, v, w) stxi_l(u, v, w) +# define orrr(op, rk, rj, rd) _orrr(_jit, op, rk, rj, rd) +# define ou5rr(op, i5, rj, rd) _orrr(_jit, op, i5, rj, rd) +# define orru5(op, rk, rj, i5) _orrr(_jit, op, rk, rj, i5) +static void _orrr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define ou2rrr(op, i2, rk, rj, rd) _ou2rrr(_jit, op, i2, rk, rj, rd) +static void _ou2rrr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define ou3rrr(op, u3, rk, rj, rd) _ou3rrr(_jit, op, u3, rk, rj, rd) +static void _ou3rrr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define ou6rr(op, u6, rj, rd) _ou6rr(_jit, op, u6, rj, rd) +static void _ou6rr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define ou5u1u5rr(op,m5,u1,l5,rj,rd) _ou5u1u5rr(_jit,op,m5,u1,l5,rj,rd) +static void _ou5u1u5rr(jit_state_t*,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define ou6u6rr(op, m6, l6, rj, rd) _ou6u6rr(_jit, op, m6, l6, rj, rd) +static void _ou6u6rr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define o5r23(op, i5, rj, i2, rd) _o5r23(_jit, op, i5, rj, i2, rd) +static void _o5r23(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define o523r(op, i5, i2, rj, i3) _o523r(_jit, op, i5, i2, rj, i3) +static void _o523r(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define os12rr(op, i12, rj, rd) _os12rr(_jit, op, i12, rj, rd) +# define os12ru5(op, i12, rj, u5) _os12rr(_jit, op, i12, rj, u5) +static void _os12rr(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define ou12rr(op, u12, rj, rd) _ou12rr(_jit, op, u12, rj, rd) +static void _ou12rr(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define ou14u5r(op, u14, u5, rd) _ou14u5r(_jit, op, u14, u5, rd) +static void _osu14u5r(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define os14rr(op, s14, rj, rd) _os14rr(_jit, op, s14, rj, rd) +static void _os14rr(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define ou8rr(op, u8, rd, rj) _ou8rr(_jit, op, u8, rd, rj) +# define ou8u5r(op, u8, u5, rj) _ou8rr(_jit, op, u8, u5, rj) +static void _ou8rr(jit_state_t*,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define ou15(op, u15) _ou15(_jit, op, u15) +static void _ou15(jit_state_t*, jit_int32_t,jit_int32_t); +# define orrrr(op, ra, rk, rj, rd) _orrrr(_jit, op, ra, rk, rj, rd) +static void _orrrr(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define ou5rru2u3(op,u5,rj,rk,u2,u3) _ou5rru2u3(_jit, op, u5, rj, rk, u2, u3) +static void _ou5rru2u3(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_int32_t); +# define os16rr(op, s16, rj, rd) _os16rr(_jit, op, s16, rj, rd) +static void _os16rr(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define os20r(op, s20, rd) _os20r(_jit, op, s20, rd) +static void _os20r(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define orj21(op, rj, j21) _orj21(_jit, op, rj, j21) +static void _orj21(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t); +# define ou2u3j21(op, u2, u3, j21) _ou2u3j21(_jit, op, u2, u3, j21) +static void _o2cj21(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define oj16rr(op, j16, rj, rd) _oj16rr(_jit, op, j16, rj, rd) +static void _oj16rr(jit_state_t*, + jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t); +# define oj26(op, j26) _oj26(_jit, op, j26) +static void _oj26(jit_state_t*, jit_int32_t,jit_int32_t); +# define CLO_W(rd, rj) ou5rr(0x000, 0x04, rj, rd) +# define CLZ_W(rd, rj) ou5rr(0x000, 0x05, rj, rd) +# define CTO_W(rd, rj) ou5rr(0x000, 0x06, rj, rd) +# define CTZ_W(rd, rj) ou5rr(0x000, 0x07, rj, rd) +# define CLO_D(rd, rj) ou5rr(0x000, 0x08, rj, rd) +# define CLZ_D(rd, rj) ou5rr(0x000, 0x09, rj, rd) +# define CTO_D(rd, rj) ou5rr(0x000, 0x0a, rj, rd) +# define CTZ_D(rd, rj) ou5rr(0x000, 0x0b, rj, rd) +# define REVB_2H(rd, rj) ou5rr(0x000, 0x0c, rj, rd) +# define REVB_4H(rd, rj) ou5rr(0x000, 0x0d, rj, rd) +# define REVB_2W(rd, rj) ou5rr(0x000, 0x0e, rj, rd) +# define REVB_D(rd, rj) ou5rr(0x000, 0x0f, rj, rd) +# define REVH_2W(rd, rj) ou5rr(0x000, 0x10, rj, rd) +# define REVH_D(rd, rj) ou5rr(0x000, 0x11, rj, rd) +# define BITREV_4B(rd, rj) ou5rr(0x000, 0x12, rj, rd) +# define BITREV_8B(rd, rj) ou5rr(0x000, 0x13, rj, rd) +# define BITREV_W(rd, rj) ou5rr(0x000, 0x14, rj, rd) +# define BITREV_D(rd, rj) ou5rr(0x000, 0x15, rj, rd) +# define EXT_W_H(rd, rj) ou5rr(0x000, 0x16, rj, rd) +# define EXT_W_B(rd, rj) ou5rr(0x000, 0x17, rj, rd) +# define RDTIMEL_W(rd, rj) ou5rr(0x000, 0x18, rj, rd) +# define RDTIMEH_W(rd, rj) ou5rr(0x000, 0x19, rj, rd) +# define RDTIME_D(rd, rj) ou5rr(0x000, 0x20, rj, rd) +# define CPUCFG(rd, rj) ou5rr(0x000, 0x21, rj, rd) +# define ASRTLE_D( rj, rk) orru5(0x002, rk, rj, 0x00) +# define ASRTGT_D( rj, rk) orru5(0x003, rk, rj, 0x00) +# define ALSL_W(rd, rj, rk, sa2) ou2rrr(0x002, sa2, rk, rj, rd) +# define ALSL_WU(rd, rj, rk, sa2) ou2rrr(0x003, sa2, rk, rj, rd) +# define BYTEPICK_W(rd, rj, rk, sa2) ou2rrr(0x004, sa2, rk, rj, rd) +# define BYTEPICK_D(rd, rj, rk, sa3) ou3rrr(0x003, sa3, rk, rj, rd) +# define ADD_W(rd, rj, rk) orrr(0x020, rk, rj, rd) +# define ADD_D(rd, rj, rk) orrr(0x021, rk, rj, rd) +# define SUB_W(rd, rj, rk) orrr(0x022, rk, rj, rd) +# define SUB_D(rd, rj, rk) orrr(0x023, rk, rj, rd) +# define SLT(rd, rj, rk) orrr(0x024, rk, rj, rd) +# define SLTU(rd, rj, rk) orrr(0x025, rk, rj, rd) +# define MASKEQZ(rd, rj, rk) orrr(0x026, rk, rj, rd) +# define MASKNEZ(rd, rj, rk) orrr(0x027, rk, rj, rd) +# define NOR(rd, rj, rk) orrr(0x028, rk, rj, rd) +# define AND(rd, rj, rk) orrr(0x029, rk, rj, rd) +# define OR(rd, rj, rk) orrr(0x02a, rk, rj, rd) +# define XOR(rd, rj, rk) orrr(0x02b, rk, rj, rd) +# define ORN(rd, rj, rk) orrr(0x02c, rk, rj, rd) +# define ANDN(rd, rj, rk) orrr(0x02d, rk, rj, rd) +# define SLL_W(rd, rj, rk) orrr(0x02e, rk, rj, rd) +# define SRL_W(rd, rj, rk) orrr(0x02f, rk, rj, rd) +# define SRA_W(rd, rj, rk) orrr(0x030, rk, rj, rd) +# define SLL_D(rd, rj, rk) orrr(0x031, rk, rj, rd) +# define SRL_D(rd, rj, rk) orrr(0x032, rk, rj, rd) +# define SRA_D(rd, rj, rk) orrr(0x033, rk, rj, rd) +# define ROTR_W(rd, rj, rk) orrr(0x036, rk, rj, rd) +# define ROTR_D(rd, rj, rk) orrr(0x037, rk, rj, rd) +# define MUL_W(rd, rj, rk) orrr(0x038, rk, rj, rd) +# define MULH_W(rd, rj, rk) orrr(0x039, rk, rj, rd) +# define MULH_WU(rd, rj, rk) orrr(0x03a, rk, rj, rd) +# define MUL_D(rd, rj, rk) orrr(0x03b, rk, rj, rd) +# define MULH_D(rd, rj, rk) orrr(0x03c, rk, rj, rd) +# define MULH_DU(rd, rj, rk) orrr(0x03d, rk, rj, rd) +# define MULW_D_W(rd, rj, rk) orrr(0x03e, rk, rj, rd) +# define MULW_D_WU(rd, rj, rk) orrr(0x03f, rk, rj, rd) +# define DIV_W(rd, rj, rk) orrr(0x040, rk, rj, rd) +# define MOD_W(rd, rj, rk) orrr(0x041, rk, rj, rd) +# define DIV_WU(rd, rj, rk) orrr(0x042, rk, rj, rd) +# define MOD_WU(rd, rj, rk) orrr(0x043, rk, rj, rd) +# define DIV_D(rd, rj, rk) orrr(0x044, rk, rj, rd) +# define MOD_D(rd, rj, rk) orrr(0x045, rk, rj, rd) +# define DIV_DU(rd, rj, rk) orrr(0x046, rk, rj, rd) +# define MOD_DU(rd, rj, rk) orrr(0x047, rk, rj, rd) +# define CRC_W_B_W(rd, rj, rk) orrr(0x048, rk, rj, rd) +# define CRC_W_H_W(rd, rj, rk) orrr(0x049, rk, rj, rd) +# define CRC_W_W_W(rd, rj, rk) orrr(0x04a, rk, rj, rd) +# define CRC_W_D_W(rd, rj, rk) orrr(0x04b, rk, rj, rd) +# define CRCC_W_B_W(rd, rj, rk) orrr(0x04c, rk, rj, rd) +# define CRCC_W_H_W(rd, rj, rk) orrr(0x04d, rk, rj, rd) +# define CCRC_W_W_W(rd, rj, rk) orrr(0x04e, rk, rj, rd) +# define CCRC_W_D_W(rd, rj, rk) orrr(0x04f, rk, rj, rd) +# define BREAK(code) ou15(0x054, code) +# define DBCL(code) ou15(0x055, code) +# define SYSCALL(code) ou15(0x056, code) +# define ALSL_D(rd, rj, rk, sa2) ou2rrr(0x016, sa2, rk, rj, rd) +# define SLLI_W(rd, rj, ui5) ou5rr(0x081, ui5, rj, rd) +# define SLLI_D(rd, rj, ui6) ou6rr(0x041, ui6, rj, rd) +# define SRLI_W(rd, rj, ui5) ou5rr(0x089, ui5, rj, rd) +# define SRLI_D(rd, rj, ui6) ou6rr(0x045, ui6, rj, rd) +# define SRAI_W(rd, rj, ui5) ou5rr(0x091, ui5, rj, rd) +# define SRAI_D(rd, rj, ui6) ou6rr(0x049, ui6, rj, rd) +# define ROTRI_W(rd, rj, ui5) ou5rr(0x099, ui5, rj, rd) +# define ROTRI_D(rd, rj, ui6) ou6rr(0x04d, ui6, rj, rd) +# define BSTRINS_W(rd, rj, m5, l5) ou5u1u5rr(0x003, m5, 0x0, l5, rj, rd) +# define BSTRPICK_W(rd, rj, m5, l5) ou5u1u5rr(0x003, m5, 0x1, l5, rj, rd) +# define BSTRINS_D(rd, rj, m6, l6) ou6u6rr(0x002, m6, l6, rj, rd) +# define BSTRPICK_D(rd, rj, m6, l6) ou6u6rr(0x003, m6, l6, rj, rd) +# define SLTI(rd, rj, i12) os12rr(0x008, i12, rj, rd) +# define SLTUI(rd, rj, i12) os12rr(0x009, i12, rj, rd) +# define ADDI_W(rd, rj, si12) os12rr(0x00a, si12, rj, rd) +# define ADDI_D(rd, rj, si12) os12rr(0x00b, si12, rj, rd) +# define LU52I_D(rd, rj, i12) os12rr(0x00c, i12, rj, rd) +# define ANDI(rd, rj, i12) ou12rr(0x00d, i12, rj, rd) +# define ORI(rd, rj, i12) ou12rr(0x00e, i12, rj, rd) +# define XORI(rd, rj, i12) ou12rr(0x00f, i12, rj, rd) +# define CSRRD(rd, csr) ou14u5r(0x004, csr, 0x00, rd) +# define CSRWR(rd, csr) ou14u5r(0x004, csr, 0x01, rd) +# define CSRXCHG(rd, rj, csr) ou14u5r(0x004, csr, rj, rd) +# define CACOP(i5, rj, si12) os12ru5(0x018, si12, rj, i5) +# define LDDIR(rd, rj, level) ou8rr(0x190, level, rj, rd) +# define LDPTE( rj, level) ou8u5r(0x191, level, rj, 0x00) +# define IOCSRRD_B(rd, rj) ou5rr(0xc90, 0x00, rj, rd) +# define IOCSRRD_H(rd, rj) ou5rr(0xc90, 0x01, rj, rd) +# define IOCSRRD_W(rd, rj) ou5rr(0xc90, 0x02, rj, rd) +# define IOCSRRD_D(rd, rj) ou5rr(0xc90, 0x03, rj, rd) +# define IOCSRWR_B(rd, rj) ou5rr(0xc90, 0x04, rj, rd) +# define IOCSRWR_H(rd, rj) ou5rr(0xc90, 0x05, rj, rd) +# define IOCSRWR_W(rd, rj) ou5rr(0xc90, 0x06, rj, rd) +# define IOCSRWR_D(rd, rj) ou5rr(0xc90, 0x07, rj, rd) +# define TLBCLR() ii( 0x6482000) +# define TLBFLUSH() ii( 0x6482400) +# define TLBSRCH() ii( 0x6482800) +# define TLBRD() ii( 0x6482c00) +# define TLBWR() ii( 0x6483000) +# define TLBFILL() ii( 0x6483400) +# define ERTN() ii( 0x6483800) +# define IDLE(level) ou15(0xc91, level) +# define INVTLB(op, rj, rk) orru5(0xc93, rk, rj, op) +# define ADDU16I_D(rd, rj, si16) os16rr(0x004, si16, rj, rd) +# define LU12I_W(rd, si20) os20r(0x00a, si20, rd) +# define LU32I_D(rd, si20) os20r(0x00b, si20, rd) +# define PCADDI(rd, si20) os20r(0x00c, si20, rd) +# define PCALAU12I(rd, si20) os20r(0x00d, si20, rd) +# define PCADDU12I(rd, si20) os20r(0x00e, si20, rd) +# define PCADDU18I(rd, si20) os20r(0x00f, si20, rd) +# define LL_W(rd, rj, si14) os14rr(0x020, si14, rj, rd) +# define SC_W(rd, rj, si14) os14rr(0x021, si14, rj, rd) +# define LL_D(rd, rj, si14) os14rr(0x022, si14, rj, rd) +# define SC_D(rd, rj, si14) os14rr(0x023, si14, rj, rd) +# define LDPTR_W(rd, rj, si14) os14rr(0x024, si14, rj, rd) +# define SDPTR_W(rd, rj, si14) os14rr(0x025, si14, rj, rd) +# define LDPTR_D(rd, rj, si14) os14rr(0x026, si14, rj, rd) +# define SDPTR_D(rd, rj, si14) os14rr(0x027, si14, rj, rd) +# define LD_B(rd, rj, si12) os12rr(0x0a0, si12, rj, rd) +# define LD_H(rd, rj, si12) os12rr(0x0a1, si12, rj, rd) +# define LD_W(rd, rj, si12) os12rr(0x0a2, si12, rj, rd) +# define LD_D(rd, rj, si12) os12rr(0x0a3, si12, rj, rd) +# define ST_B(rd, rj, si12) os12rr(0x0a4, si12, rj, rd) +# define ST_H(rd, rj, si12) os12rr(0x0a5, si12, rj, rd) +# define ST_W(rd, rj, si12) os12rr(0x0a6, si12, rj, rd) +# define ST_D(rd, rj, si12) os12rr(0x0a7, si12, rj, rd) +# define LD_BU(rd, rj, si12) os12rr(0x0a8, si12, rj, rd) +# define LD_HU(rd, rj, si12) os12rr(0x0a9, si12, rj, rd) +# define LD_WU(rd, rj, si12) os12rr(0x0aa, si12, rj, rd) +# define PRELD(hint, rj, si12) os12ru5(0x0ab, si12, rj , hint) +# define LDX_B(rd, rj, rk) orrr(0x7000, rk, rj, rd) +# define LDX_H(rd, rj, rk) orrr(0x7008, rk, rj, rd) +# define LDX_W(rd, rj, rk) orrr(0x7010, rk, rj, rd) +# define LDX_D(rd, rj, rk) orrr(0x7018, rk, rj, rd) +# define STX_B(rd, rj, rk) orrr(0x7020, rk, rj, rd) +# define STX_H(rd, rj, rk) orrr(0x7028, rk, rj, rd) +# define STX_W(rd, rj, rk) orrr(0x7030, rk, rj, rd) +# define STX_D(rd, rj, rk) orrr(0x7038, rk, rj, rd) +# define LDX_BU(rd, rj, rk) orrr(0x7040, rk, rj, rd) +# define LDX_HU(rd, rj, rk) orrr(0x7048, rk, rj, rd) +# define LDX_WU(rd, rj, rk) orrr(0x7050, rk, rj, rd) +# define PRELDX(hint, rj, rk) orru5(0x7058, rk, rj, hint) +# define AMSWAP_W(rd, rj, rk) orrr(0x70c0, rk, rj, rd) +# define AMSWAP_D(rd, rj, rk) orrr(0x70c1, rk, rj, rd) +# define AMADD_W(rd, rj, rk) orrr(0x70c2, rk, rj, rd) +# define AMADD_D(rd, rj, rk) orrr(0x70c3, rk, rj, rd) +# define AMAND_W(rd, rj, rk) orrr(0x70c4, rk, rj, rd) +# define AMAND_D(rd, rj, rk) orrr(0x70c5, rk, rj, rd) +# define AMOR_W(rd, rj, rk) orrr(0x70c6, rk, rj, rd) +# define AMOR_D(rd, rj, rk) orrr(0x70c7, rk, rj, rd) +# define AMXOR_W(rd, rj, rk) orrr(0x70c8, rk, rj, rd) +# define AMXOR_D(rd, rj, rk) orrr(0x70c9, rk, rj, rd) +# define AMMAX_W(rd, rj, rk) orrr(0x70ca, rk, rj, rd) +# define AMMAX_D(rd, rj, rk) orrr(0x70cb, rk, rj, rd) +# define AMMIN_W(rd, rj, rk) orrr(0x70cc, rk, rj, rd) +# define AMMIN_D(rd, rj, rk) orrr(0x70cd, rk, rj, rd) +# define AMMAX_WU(rd, rj, rk) orrr(0x70ce, rk, rj, rd) +# define AMMAX_DU(rd, rj, rk) orrr(0x70cf, rk, rj, rd) +# define AMMIN_WU(rd, rj, rk) orrr(0x70d0, rk, rj, rd) +# define AMMIN_DU(rd, rj, rk) orrr(0x70d1, rk, rj, rd) +# define AMSWAP_DB_W(rd, rj, rk) orrr(0x70d2, rk, rj, rd) +# define AMSWAP_DB_D(rd, rj, rk) orrr(0x70d3, rk, rj, rd) +# define AMADD_DB_W(rd, rj, rk) orrr(0x70d4, rk, rj, rd) +# define AMADD_DB_D(rd, rj, rk) orrr(0x70d5, rk, rj, rd) +# define AMAND_DB_W(rd, rj, rk) orrr(0x70d6, rk, rj, rd) +# define AMAND_DB_D(rd, rj, rk) orrr(0x70d7, rk, rj, rd) +# define AMOR_DB_W(rd, rj, rk) orrr(0x70d8, rk, rj, rd) +# define AMOR_DB_D(rd, rj, rk) orrr(0x70d9, rk, rj, rd) +# define AMXOR_DB_W(rd, rj, rk) orrr(0x70da, rk, rj, rd) +# define AMXOR_DB_D(rd, rj, rk) orrr(0x70db, rk, rj, rd) +# define AMMAX_DB_W(rd, rj, rk) orrr(0x70dc, rk, rj, rd) +# define AMMAX_DB_D(rd, rj, rk) orrr(0x70dd, rk, rj, rd) +# define AMMIN_DB_W(rd, rj, rk) orrr(0x70de, rk, rj, rd) +# define AMMIN_DB_D(rd, rj, rk) orrr(0x70df, rk, rj, rd) +# define AMMAX_DB_WU(rd, rj, rk) orrr(0x70e0, rk, rj, rd) +# define AMMAX_DB_DU(rd, rj, rk) orrr(0x70e1, rk, rj, rd) +# define AMMIN_DB_WU(rd, rj, rk) orrr(0x70e2, rk, rj, rd) +# define AMMIN_DB_DU(rd, rj, rk) orrr(0x70e3, rk, rj, rd) +# define DBAR(hint) ou15(0x70e4, hint) +# define IBAR(hint) ou15(0x70e5, hint) +# define LDGT_B(rd, rj, rk) orrr(0x70f0, rk, rj, rd) +# define LDGT_H(rd, rj, rk) orrr(0x70f1, rk, rj, rd) +# define LDGT_W(rd, rj, rk) orrr(0x70f2, rk, rj, rd) +# define LDGT_D(rd, rj, rk) orrr(0x70f3, rk, rj, rd) +# define LDLE_B(rd, rj, rk) orrr(0x70f4, rk, rj, rd) +# define LDLE_H(rd, rj, rk) orrr(0x70f5, rk, rj, rd) +# define LDLE_W(rd, rj, rk) orrr(0x70f6, rk, rj, rd) +# define LDLE_D(rd, rj, rk) orrr(0x70f7, rk, rj, rd) +# define STGT_B(rd, rj, rk) orrr(0x70f8, rk, rj, rd) +# define STGT_H(rd, rj, rk) orrr(0x70f9, rk, rj, rd) +# define STGT_W(rd, rj, rk) orrr(0x70fa, rk, rj, rd) +# define STGT_D(rd, rj, rk) orrr(0x70fb, rk, rj, rd) +# define STLE_B(rd, rj, rk) orrr(0x70fc, rk, rj, rd) +# define STLE_H(rd, rj, rk) orrr(0x70rd, rk, rj, rd) +# define STLE_W(rd, rj, rk) orrr(0x70fe, rk, rj, rd) +# define STLE_D(rd, rj, rk) orrr(0x70ff, rk, rj, rd) +# define BEQZ( rj, offs) orj21(0x010, rj, offs) +# define BNEZ( rj, offs) orj21(0x011, rj, offs) +# define BCEQZ( cj, offs) ou2u3j21(0x012, 0x0, cj, offs) +# define BCNEZ( cj, offs) ou2u3j21(0x012, 0x1, cj, offs) +# define JIRL(rd, rj, offs) oj16rr(0x013, offs, rj, rd) +# define B(offs) oj26(0x014, offs) +# define BL(offs) oj26(0x015, offs) +# define BEQ(rj, rd, offs) oj16rr(0x016, offs, rj, rd) +# define BNE(rj, rd, offs) oj16rr(0x017, offs, rj, rd) +# define BLT(rj, rd, offs) oj16rr(0x018, offs, rj, rd) +# define BGE(rj, rd, offs) oj16rr(0x019, offs, rj, rd) +# define BLTU(rj, rd, offs) oj16rr(0x01a, offs, rj, rd) +# define BGEU(rj, rd, offs) oj16rr(0x01b, offs, rj, rd) +# define NOP() ANDI(_ZERO_REGNO, _ZERO_REGNO, 0) +# define nop(i0) _nop(_jit, i0) +# define comr(r0, r1) NOR(r0, r1, r1) +# define negr(r0, r1) subr(r0, _ZERO_REGNO, r1) +static void _nop(jit_state_t*,jit_int32_t); +# define movr(r0, r1) _movr(_jit, r0, r1) +static void _movr(jit_state_t*, jit_int32_t, jit_int32_t); +# define movi(r0, i0) _movi(_jit, r0, i0) +static void _movi(jit_state_t*, jit_int32_t, jit_word_t); +# define movi_p(r0, i0) _movi_p(_jit, r0, i0) +static jit_word_t _movi_p(jit_state_t*, jit_int32_t, jit_word_t); +# define movnr(r0, r1, r2) _movnr(_jit, r0, r1, r2) +static void _movnr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define movzr(r0, r1, r2) _movzr(_jit, r0, r1, r2) +static void _movzr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define casx(r0, r1, r2, r3, i0) _casx(_jit, r0, r1, r2, r3, i0) +static void _casx(jit_state_t *_jit,jit_int32_t,jit_int32_t, + jit_int32_t,jit_int32_t,jit_word_t); +#define casr(r0, r1, r2, r3) casx(r0, r1, r2, r3, 0) +#define casi(r0, i0, r1, r2) casx(r0, _NOREG, r1, r2, i0) +# define addr(r0, r1, r2) ADD_D(r0, r1, r2) +# define addi(r0, r1, i0) _addi(_jit, r0, r1, i0) +static void _addi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define addcr(r0, r1, r2) _addcr(_jit, r0, r1, r2) +static void _addcr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define addci(r0, r1, i0) _addci(_jit, r0, r1, i0) +static void _addci(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define addxr(r0, r1, r2) _addxr(_jit, r0, r1, r2) +static void _addxr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define addxi(r0, r1, i0) _addxi(_jit, r0, r1, i0) +static void _addxi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define subr(r0, r1, r2) SUB_D(r0, r1, r2) +# define subi(r0, r1, i0) _subi(_jit, r0, r1, i0) +static void _subi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define subcr(r0, r1, r2) _subcr(_jit, r0, r1, r2) +static void _subcr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define subci(r0, r1, i0) _subci(_jit, r0, r1, i0) +static void _subci(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define subxr(r0, r1, r2) _subxr(_jit, r0, r1, r2) +static void _subxr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define subxi(r0, r1, i0) _subxi(_jit, r0, r1, i0) +static void _subxi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0) +static void _rsbi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define mulr(r0, r1, r2) MUL_D(r0, r1, r2) +# define muli(r0, r1, i0) _muli(_jit, r0, r1, i0) +static void _muli(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define qmulr(r0, r1, r2, r3) iqmulr(r0, r1, r2, r3, 1) +# define qmulr_u(r0, r1, r2, r3) iqmulr(r0, r1, r2, r3, 0) +# define iqmulr(r0, r1, r2, r3, sign) _iqmulr(_jit, r0, r1, r2, r3, sign) +static void _iqmulr(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t, jit_int32_t, jit_bool_t); +# define qmuli(r0, r1, r2, i0) iqmuli(r0, r1, r2, i0, 1) +# define qmuli_u(r0, r1, r2, i0) iqmuli(r0, r1, r2, i0, 0) +# define iqmuli(r0, r1, r2, i0, sign) _iqmuli(_jit, r0, r1, r2, i0, sign) +static void _iqmuli(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t, jit_word_t, jit_bool_t); +# define divr(r0, r1, r2) DIV_D(r0, r1, r2) +# define divi(r0, r1, i0) _divi(_jit, r0, r1, i0) +static void _divi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define divr_u(r0, r1, r2) DIV_DU(r0, r1, r2) +# define divi_u(r0, r1, i0) _divi_u(_jit, r0, r1, i0) +static void _divi_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define qdivr(r0, r1, r2, r3) iqdivr(r0, r1, r2, r3, 1) +# define qdivr_u(r0, r1, r2, r3) iqdivr(r0, r1, r2, r3, 0) +# define iqdivr(r0, r1, r2, r3, sign) _iqdivr(_jit, r0, r1, r2, r3, sign) +static void _iqdivr(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t, jit_int32_t, jit_bool_t); +# define qdivi(r0, r1, r2, i0) iqdivi(r0, r1, r2, i0, 1) +# define qdivi_u(r0, r1, r2, i0) iqdivi(r0, r1, r2, i0, 0) +# define iqdivi(r0, r1, r2, i0, sign) _iqdivi(_jit, r0, r1, r2, i0, sign) +static void _iqdivi(jit_state_t*, jit_int32_t, jit_int32_t, + jit_int32_t, jit_word_t, jit_bool_t); +# define remr(r0, r1, r2) MOD_D(r0, r1, r2) +# define remi(r0, r1, i0) _remi(_jit, r0, r1, i0) +static void _remi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define remr_u(r0, r1, r2) MOD_DU(r0, r1, r2) +# define remi_u(r0, r1, i0) _remi_u(_jit, r0, r1, i0) +static void _remi_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define lshr(r0, r1, r2) SLL_D(r0, r1, r2) +# define lshi(r0, r1, i0) SLLI_D(r0, r1, i0) +# define rshr(r0, r1, r2) SRA_D(r0, r1, r2) +# define rshi(r0, r1, i0) SRAI_D(r0, r1, i0) +# define rshr_u(r0, r1, r2) SRL_D(r0, r1, r2) +# define rshi_u(r0, r1, i0) SRLI_D(r0, r1, i0) +# define andr(r0, r1, r2) AND(r0, r1, r2) +# define andi(r0, r1, i0) _andi(_jit, r0, r1, i0) +static void _andi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define orr(r0, r1, r2) OR(r0, r1, r2) +# define ori(r0, r1, i0) _ori(_jit, r0, r1, i0) +static void _ori(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define xorr(r0, r1, r2) XOR(r0, r1, r2) +# define xori(r0, r1, i0) _xori(_jit, r0, r1, i0) +static void _xori(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ldr_c(r0, r1) LD_B(r0, r1, 0) +# define ldi_c(r0, i0) _ldi_c(_jit, r0, i0) +static void _ldi_c(jit_state_t*, jit_int32_t, jit_word_t); +# define ldr_uc( r0, r1) LD_BU(r0, r1, 0) +# define ldi_uc(r0, i0) _ldi_uc(_jit, r0, i0) +static void _ldi_uc(jit_state_t*, jit_int32_t, jit_word_t); +# define ldr_s(r0, r1) LD_H(r0, r1, 0) +# define ldi_s(r0, i0) _ldi_s(_jit, r0, i0) +static void _ldi_s(jit_state_t*, jit_int32_t, jit_word_t); +# define ldr_us(r0, r1) LD_HU(r0, r1, 0) +# define ldi_us(r0, i0) _ldi_us(_jit, r0, i0) +static void _ldi_us(jit_state_t*, jit_int32_t, jit_word_t); +# define ldr_i(r0, r1) LD_W(r0, r1, 0) +# define ldi_i(r0, i0) _ldi_i(_jit, r0, i0) +static void _ldi_i(jit_state_t*, jit_int32_t, jit_word_t); +# define ldr_ui(r0, r1) LD_WU(r0, r1, 0) +# define ldi_ui(r0, i0) _ldi_ui(_jit, r0, i0) +static void _ldi_ui(jit_state_t*, jit_int32_t, jit_word_t); +# define ldr_l(r0, r1) LD_D(r0, r1, 0) +# define ldi_l(r0, i0) _ldi_l(_jit, r0, i0) +static void _ldi_l(jit_state_t*, jit_int32_t, jit_word_t); +# define ldxr_c(r0, r1, r2) LDX_B(r0, r1, r2) +# define ldxi_c(r0, r1, i0) _ldxi_c(_jit, r0, r1, i0) +static void _ldxi_c(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ldxr_uc(r0, r1, r2) LDX_BU(r0, r1, r2) +# define ldxi_uc(r0, r1, i0) _ldxi_uc(_jit,r0, r1, i0) +static void _ldxi_uc(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ldxr_s(r0, r1, r2) LDX_H(r0, r1, r2) +# define ldxi_s(r0, r1, i0) _ldxi_s(_jit, r0, r1, i0) +static void _ldxi_s(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ldxr_us(r0, r1, r2) LDX_HU(r0, r1, r2) +# define ldxi_us(r0, r1, i0) _ldxi_us(_jit, r0, r1, i0) +static void _ldxi_us(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ldxr_i(r0, r1, r2) LDX_W(r0, r1, r2) +# define ldxi_i(r0, r1, i0) _ldxi_i(_jit, r0, r1, i0) +static void _ldxi_i(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ldxr_ui(r0, r1, r2) LDX_WU(r0, r1, r2) +# define ldxi_ui(r0, r1, i0) _ldxi_ui(_jit, r0, r1, i0) +static void _ldxi_ui(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ldxr_l(r0, r1, r2) LDX_D(r0, r1, r2) +# define ldxi_l(r0, r1, i0) _ldxi_l(_jit, r0, r1, i0) +static void _ldxi_l(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define str_c(r0, r1) ST_B(r1, r0, 0) +# define sti_c(i0, r0) _sti_c(_jit, i0, r0) +static void _sti_c(jit_state_t*, jit_word_t, jit_int32_t); +# define str_s(r0, r1) ST_H(r1, r0, 0) +# define sti_s(i0, r0) _sti_s(_jit, i0, r0) +static void _sti_s(jit_state_t*, jit_word_t, jit_int32_t); +# define str_i(r0, r1) ST_W(r1, r0, 0) +# define sti_i(i0, r0) _sti_i(_jit, i0, r0) +static void _sti_i(jit_state_t*, jit_word_t, jit_int32_t); +# define str_l(r0, r1) ST_D(r1, r0, 0) +# define sti_l(i0, r0) _sti_l(_jit, i0, r0) +static void _sti_l(jit_state_t*, jit_word_t, jit_int32_t); +# define stxr_c(r0, r1, r2) STX_B(r2, r1, r0) +# define stxi_c(i0, r0, r1) _stxi_c(_jit,i0, r0, r1) +static void _stxi_c(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define stxr_s(r0, r1, r2) STX_H(r2, r1, r0) +# define stxi_s(i0, r0, r1) _stxi_s(_jit, i0, r0, r1) +static void _stxi_s(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define stxr_i(r0, r1, r2) STX_W(r2, r1, r0) +# define stxi_i(i0, r0, r1) _stxi_i(_jit, i0, r0, r1) +static void _stxi_i(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define stxr_l(r0, r1, r2) STX_D(r2, r1, r0) +# define stxi_l(i0, r0, r1) _stxi_l(_jit, i0, r0, r1) +static void _stxi_l(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1) +static void _bswapr_us(jit_state_t*, jit_int32_t, jit_int32_t); +# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1) +static void _bswapr_ui(jit_state_t*, jit_int32_t, jit_int32_t); +# define bswapr_ul(r0, r1) REVB_D(r0, r1) +# define extr_c(r0, r1) EXT_W_B(r0, r1) +# define extr_uc(r0, r1) BSTRPICK_D(r0, r1, 7, 0) +# define extr_s(r0, r1) EXT_W_H(r0, r1) +# define extr_us(r0, r1) BSTRPICK_D(r0, r1, 15, 0) +# define extr_i(r0, r1) SLLI_W(r0, r1, 0) +# define extr_ui(r0, r1) BSTRPICK_D(r0, r1, 31, 0) +# define ltr(r0, r1, r2) SLT(r0, r1, r2) +# define lti(r0, r1, i0) _lti(_jit, r0, r1, i0) +static void _lti(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ltr_u(r0, r1, r2) SLTU(r0, r1, r2) +# define lti_u(r0, r1, i0) _lti_u(_jit, r0, r1, i0) +static void _lti_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ler(r0, r1, r2) _ler(_jit, r0, r1, r2) +static void _ler(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define lei(r0, r1, i0) _lei(_jit, r0, r1, i0) +static void _lei(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ler_u(r0, r1, r2) _ler_u(_jit, r0, r1, r2) +static void _ler_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define lei_u(r0, r1, i0) _lei_u(_jit, r0, r1, i0) +static void _lei_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define eqr(r0, r1, r2) _eqr(_jit, r0, r1, r2) +static void _eqr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define eqi(r0, r1, i0) _eqi(_jit, r0, r1, i0) +static void _eqi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ger(r0, r1, r2) _ger(_jit, r0, r1, r2) +static void _ger(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define gei(r0, r1, i0) _gei(_jit, r0, r1, i0) +static void _gei(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ger_u(r0, r1, r2) _ger_u(_jit, r0, r1, r2) +static void _ger_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define gei_u(r0, r1, i0) _gei_u(_jit, r0, r1, i0) +static void _gei_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define gtr(r0, r1, r2) SLT(r0, r2, r1) +# define gti(r0, r1, i0) _gti(_jit, r0, r1, i0) +static void _gti(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define gtr_u(r0, r1, r2) SLTU(r0, r2, r1) +# define gti_u(r0, r1, i0) _gti_u(_jit, r0, r1, i0) +static void _gti_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define ner(r0, r1, r2) _ner(_jit, r0, r1, r2) +static void _ner(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define nei(r0, r1, i0) _nei(_jit, r0, r1, i0) +static void _nei(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define bltr(i0, r0, r1) _bltr(_jit, i0, r0, r1) +static jit_word_t _bltr(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define blti(i0, r0, i1) _blti(_jit, i0, r0, i1) +static jit_word_t _blti(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bltr_u(i0, r0, r1) _bltr_u(_jit, i0, r0, r1) +static jit_word_t _bltr_u(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define blti_u(i0, r0, i1) _blti_u(_jit, i0, r0, i1) +static jit_word_t _blti_u(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bler(i0, r0, r1) _bler(_jit, i0, r0, r1) +static jit_word_t _bler(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define blei(i0, r0, i1) _blei(_jit, i0, r0, i1) +static jit_word_t _blei(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bler_u(i0, r0, r1) _bler_u(_jit, i0, r0, r1) +static jit_word_t _bler_u(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define blei_u(i0, r0, i1) _blei_u(_jit, i0, r0, i1) +static jit_word_t _blei_u(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define beqr(i0, r0, r1) _beqr(_jit, i0, r0, r1) +static jit_word_t _beqr(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define beqi(i0, r0, i1) _beqi(_jit, i0, r0, i1) +static jit_word_t _beqi(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bger(i0, r0, r1) _bger(_jit, i0, r0, r1) +static jit_word_t _bger(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bgei(i0, r0, i1) _bgei(_jit, i0, r0, i1) +static jit_word_t _bgei(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bger_u(i0, r0, r1) _bger_u(_jit, i0, r0, r1) +static jit_word_t _bger_u(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bgei_u(i0, r0, i1) _bgei_u(_jit, i0, r0, i1) +static jit_word_t _bgei_u(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bgtr(i0, r0, r1) _bgtr(_jit, i0, r0, r1) +static jit_word_t _bgtr(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bgti(i0, r0, i1) _bgti(_jit, i0, r0, i1) +static jit_word_t _bgti(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bgtr_u(i0, r0, r1) _bgtr_u(_jit, i0, r0, r1) +static jit_word_t _bgtr_u(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bgti_u(i0, r0, i1) _bgti_u(_jit, i0, r0, i1) +static jit_word_t _bgti_u(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bner(i0, r0, r1) _bner(_jit, i0, r0, r1) +static jit_word_t _bner(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bnei(i0, r0, i1) _bnei(_jit, i0, r0, i1) +static jit_word_t _bnei(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define jmpr(r0) JIRL(_ZERO_REGNO, r0, 0) +# define jmpi(i0) _jmpi(_jit, i0) +static void _jmpi(jit_state_t*, jit_word_t); +# define jmpi_p(i0) _jmpi_p(_jit, i0) +static jit_word_t _jmpi_p(jit_state_t*, jit_word_t); +# define boaddr(i0, r0, r1) _boaddr(_jit, i0, r0, r1) +static jit_word_t _boaddr(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define boaddi(i0, r0, i1) _boaddi(_jit, i0, r0, i1) +static jit_word_t _boaddi(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define boaddr_u(i0, r0, r1) _boaddr_u(_jit, i0, r0, r1) +static jit_word_t _boaddr_u(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define boaddi_u(i0, r0, i1) _boaddi_u(_jit, i0, r0, i1) +static jit_word_t _boaddi_u(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bxaddr(i0, r0, r1) _bxaddr(_jit, i0, r0, r1) +static jit_word_t _bxaddr(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bxaddi(i0, r0, i1) _bxaddi(_jit, i0, r0, i1) +static jit_word_t _bxaddi(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bxaddr_u(i0, r0, r1) _bxaddr_u(_jit, i0, r0, r1) +static jit_word_t _bxaddr_u(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bxaddi_u(i0, r0, i1) _bxaddi_u(_jit, i0, r0, i1) +static jit_word_t _bxaddi_u(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bosubr(i0, r0, r1) _bosubr(_jit, i0, r0, r1) +static jit_word_t _bosubr(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bosubi(i0, r0, i1) _bosubi(_jit, i0, r0, i1) +static jit_word_t _bosubi(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bosubr_u(i0, r0, r1) _bosubr_u(_jit, i0, r0, r1) +static jit_word_t _bosubr_u(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bosubi_u(i0, r0, i1) _bosubi_u(_jit, i0, r0, i1) +static jit_word_t _bosubi_u(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bxsubr(i0, r0, r1) _bxsubr(_jit, i0, r0, r1) +static jit_word_t _bxsubr(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bxsubi(i0, r0, i1) _bxsubi(_jit, i0, r0, i1) +static jit_word_t _bxsubi(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bxsubr_u(i0, r0, r1) _bxsubr_u(_jit, i0, r0, r1) +static jit_word_t _bxsubr_u(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bxsubi_u(i0, r0, i1) _bxsubi_u(_jit, i0, r0, i1) +static jit_word_t _bxsubi_u(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t); +# define bmsr(br, r0, r1) _bmsr(_jit, br, r0, r1) +static jit_word_t _bmsr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bmsi(br, r0, i0) _bmsi(_jit, br, r0, i0) +static jit_word_t _bmsi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define bmcr(br, r0, r1) _bmcr(_jit, br, r0, r1) +static jit_word_t _bmcr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t); +# define bmci(br, r0, i0) _bmci(_jit, br, r0, i0) +static jit_word_t _bmci(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); +# define callr(r0) JIRL(_RA_REGNO, r0, 0) +# define calli(i0) _calli(_jit, i0) +static void _calli(jit_state_t*, jit_word_t); +# define calli_p(i0) _calli_p(_jit, i0) +static jit_word_t _calli_p(jit_state_t*, jit_word_t); +# define prolog(i0) _prolog(_jit, i0) +static void _prolog(jit_state_t*, jit_node_t*); +# define epilog(i0) _epilog(_jit, i0) +static void _epilog(jit_state_t*, jit_node_t*); +# define vastart(r0) _vastart(_jit, r0) +static void _vastart(jit_state_t*, jit_int32_t); +# define vaarg(r0, r1) _vaarg(_jit, r0, r1) +static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t); +#define patch_at(jump, label) _patch_at(_jit, jump, label) +static void _patch_at(jit_state_t*,jit_word_t,jit_word_t); +#endif + +#if CODE +static void +_orrr(jit_state_t *_jit, + jit_int32_t op, jit_int32_t rk, jit_int32_t rj, jit_int32_t rd) +{ + assert(!(op & ~0xffff)); + assert(!(rk & ~0x1f)); + assert(!(rj & ~0x1f)); + assert(!(rd & ~0x1f)); + ii((op << 15) | (rk << 10) | (rj << 5) | rd); +} + +static void +_ou2rrr(jit_state_t *_jit, jit_int32_t op, + jit_int32_t u2, jit_int32_t rk, jit_int32_t rj, jit_int32_t rd) +{ + assert(!(op & ~0x7ff)); + assert(!(u2 & ~3)); + assert(!(rk & ~0x1f)); + assert(!(rj & ~0x1f)); + assert(!(rd & ~0x1f)); + ii((op << 17) | (u2 << 15) | (rk << 10) | (rj << 5) | rd); +} + +static void +_ou3rrr(jit_state_t *_jit, jit_int32_t op, + jit_int32_t u3, jit_int32_t rk, jit_int32_t rj, jit_int32_t rd) +{ + assert(!(op & ~0x3ff)); + assert(!(u3 & ~7)); + assert(!(rk & ~0x1f)); + assert(!(rj & ~0x1f)); + assert(!(rd & ~0x1f)); + ii((op << 18) | (u3 << 15) | (rk << 10) | (rj << 5) | rd); +} + +static void +_ou6rr(jit_state_t *_jit, jit_int32_t op, + jit_int32_t u6, jit_int32_t rj, jit_int32_t rd) +{ + assert(!(op & ~0x3ff)); + assert(!(u6 & ~0x3f)); + assert(!(rj & ~0x1f)); + assert(!(rd & ~0x1f)); + ii((op << 16) | (u6 << 10) | (rj << 5) | rd); +} + +static void +_ou5u1u5rr(jit_state_t *_jit, jit_int32_t op, jit_int32_t m5, + jit_int32_t u1, jit_int32_t l5, jit_int32_t rj, jit_int32_t rd) +{ + assert(!(op & ~0x7ff)); + assert(!(m5 & ~0x1f)); + assert(!(u1 & ~1)); + assert(!(l5 & ~0x1f)); + assert(!(rj & ~0x1f)); + assert(!(rd & ~0x1f)); + ii((op << 21) | (m5 << 16) | (u1 << 15) | (l5 << 10) | (rj << 5) | rd); +} + +static void +_ou6u6rr(jit_state_t *_jit, jit_int32_t op, + jit_int32_t m6, jit_int32_t l6, jit_int32_t rj, jit_int32_t rd) +{ + assert(!(op & ~0x3ff)); + assert(!(m6 & ~0x3f)); + assert(!(l6 & ~0x3f)); + assert(!(rj & ~0x1f)); + assert(!(rd & ~0x1f)); + ii((op << 22) | (m6 << 16) | (l6 << 10) | (rj << 5) | rd); +} + +static void +_o5r23(jit_state_t *_jit, jit_int32_t op, + jit_int32_t i5, jit_int32_t rj, jit_int32_t i2, jit_int32_t i3) +{ + assert(!(op & ~0xffff)); + assert(!(i5 & ~0x3f)); + assert(!(rj & ~0x3f)); + assert(!(i2 & ~0x3)); + assert(!(i3 & ~0x1f)); + ii((op << 15) | (i5 << 10) | (rj << 5) | (i2 << 3) | i3); +} + +static void +_o523r(jit_state_t *_jit, jit_int32_t op, + jit_int32_t i5, jit_int32_t i2, jit_int32_t i3, jit_int32_t rd) +{ + assert(!(op & ~0xffff)); + assert(!(i5 & ~0x3f)); + assert(!(i2 & ~0x3)); + assert(!(i3 & ~0x7)); + assert(!(rd & ~0x3f)); + ii((op << 15) | (i5 << 10) | (i2 << 8) | (i3 << 5) | rd); +} + +static void +_os12rr(jit_state_t *_jit, + jit_int32_t op, jit_int32_t s12, jit_int32_t rj, jit_int32_t rd) +{ + assert(!(op & ~0x3ff)); + assert(s12 <= 2047 && s12 >= -2048); s12 &= 0xfff; + assert(!(rj & ~0x1f)); + assert(!(rd & ~0x1f)); + ii((op << 22) | (s12 << 10) | (rj << 5) | rd); +} + +static void +_ou12rr(jit_state_t *_jit, + jit_int32_t op, jit_int32_t u12, jit_int32_t rj, jit_int32_t rd) +{ + assert(!(op & ~0x3ff)); + assert(!(u12 & ~0xfff)); + assert(!(rj & ~0x1f)); + assert(!(rd & ~0x1f)); + ii((op << 22) | (u12 << 10) | (rj << 5) | rd); +} + +static void +_ou14u5r(jit_state_t *_jit, + jit_int32_t op, jit_int32_t u14, jit_int32_t u5, jit_int32_t rd) +{ + assert(!(op & ~0xff)); + assert(!(u14 & ~0x3fff)); + assert(!(u5 & ~0x1f)); + assert(!(rd & ~0x1f)); + ii((op << 24) | (u14 << 10) | (u5 << 5) | rd); +} + +static void +_os14rr(jit_state_t *_jit, + jit_int32_t op, jit_int32_t s14, jit_int32_t rj, jit_int32_t rd) +{ + assert(!(op & ~0xff)); + assert(s14 <= 8191 && s14 >= -8192); s14 &= 0x3fff; + assert(!(rj & ~0x1f)); + assert(!(rd & ~0x1f)); + ii((op << 24) | (s14 << 10) | (rj << 5) | rd); +} + +static void +_ou8rr(jit_state_t *_jit, jit_int32_t op, + jit_int32_t u8, jit_int32_t rj, jit_int32_t rd) +{ + assert(!(op & ~0x3fff)); + assert(!(u8 & ~0xff)); + assert(!(rj & ~0x1f)); + assert(!(rd & ~0x1f)); + ii((op << 18) | (u8 << 10) | (rj << 5) | rd); +} + +static void +_ou15(jit_state_t *_jit, jit_int32_t op, jit_int32_t u15) +{ + assert(!(op & ~0x1ffff)); + assert(!(u15 & ~0x7fff)); + ii((op << 15) | u15); +} + +static void +_orrrr(jit_state_t *_jit, jit_int32_t op, + jit_int32_t ra, jit_int32_t rk, jit_int32_t rj, jit_int32_t rd) +{ + assert(!(op & ~0xfff)); + assert(!(ra & ~0x1f)); + assert(!(rk & ~0x1f)); + assert(!(rj & ~0x1f)); + assert(!(rd & ~0x1f)); + ii((op << 20) | (ra << 15) | (rk << 10) | (rj << 5) | rd); +} + +static void +_ou5rru2u3(jit_state_t *_jit,jit_int32_t op, jit_int32_t u5, + jit_int32_t rk, jit_int32_t rj, jit_int32_t u2, jit_int32_t u3) +{ + assert(!(op & ~0xfff)); + assert(!(u5 & ~0x1f)); + assert(!(rk & ~0x1f)); + assert(!(rj & ~0x1f)); + assert(!(u2 & ~3)); + assert(!(u3 & ~7)); + ii((op << 20) | (u5 << 15) | (rk << 10) | (rj << 5) | (u2 << 3) | u3); +} + +static void +_os16rr(jit_state_t *_jit, + jit_int32_t op, jit_int32_t s16, jit_int32_t rj, jit_int32_t rd) +{ + assert(!(op & ~0x3f)); + assert(s16 <= 32767 && s16 >= -32768); s16 &= 0xffff; + assert(!(rj & ~0x1f)); + assert(!(rd & ~0x1f)); + ii((op << 26) | (s16 << 10) | (rj << 5) | rd); +} + +static void +_os20r(jit_state_t *_jit, jit_int32_t op, jit_int32_t s20, jit_int32_t rd) +{ + assert(!(op & ~0x7f)); + assert(s20 <= 524287 && s20 >= -524288); s20 &= 0xfffff; + assert(!(rd & ~0x1f)); + ii((op << 25) | (s20 << 5) | rd); +} + +static void +_orj21(jit_state_t *_jit, jit_int32_t op, jit_int32_t rj ,jit_int32_t j21) +{ + assert(!(op & ~0x7f)); + assert(j21 <= 1048575 && j21 >= -1048576); j21 &= 0x1fffff; + assert(!(rj & ~0x1f)); + ii((op << 26) | ((j21 & 0xffff) << 10) | (rj << 5) | (j21 >> 16)); +} + +static void +_ou2u3j21(jit_state_t *_jit, + jit_int32_t op, jit_int32_t u2, jit_int32_t u3, jit_int32_t j21) +{ + assert(!(op & ~0x7f)); + assert(j21 <= 1048575 && j21 >= -1048576); j21 &= 0x1fffff; + assert(!(u2 & ~3)); + assert(!(u3 & ~7)); + ii((op << 26) | ((j21 & 0xffff) << 10) | (u2 << 8) | (u3 << 5) | (j21 >> 16)); +} + +static void +_oj16rr(jit_state_t *_jit, + jit_int32_t op, jit_int32_t j16, jit_int32_t rj, jit_int32_t rd) +{ + assert(!(op & ~0x7f)); + assert(j16 <= 32767 && j16 >= -32768); j16 &= 0xffff; + assert(!(rd & ~0x1f)); + assert(!(rj & ~0x1f)); + ii((op << 26) | (j16 << 10) | (rj << 5) | rd); +} + +static void +_oj26(jit_state_t *_jit, jit_int32_t op, jit_int32_t j26) +{ + assert(!(op & ~0x7f)); + assert(j26 <= 33554431 && j26 >= -33554432); j26 &= 0x3ffffff; + ii((op << 26) | ((j26 & 0x1ffffff) << 10) | (j26 >> 16)); +} + +static void +_nop(jit_state_t *_jit, jit_int32_t i0) +{ + for (; i0 > 0; i0 -= 4) + NOP(); + assert(i0 == 0); +} + +static void +_movnr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + MASKEQZ(rn(reg), r1, r2); + MASKNEZ(r0, r0, r2); + OR(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_movzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + MASKNEZ(rn(reg), r1, r2); + MASKEQZ(r0, r0, r2); + OR(r0, r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_casx(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_word_t i0) +{ + jit_int32_t t0, r1_reg, iscasi; + jit_word_t retry, done, jump0, jump1; + if ((iscasi = (r1 == _NOREG))) { + r1_reg = jit_get_reg(jit_class_gpr); + r1 = rn(r1_reg); + movi(r1, i0); + } + t0 = jit_get_reg(jit_class_gpr); + movi(r0, 0); /* Assume will fail */ + DBAR(0); /* Barrier */ + retry = _jit->pc.w; + LL_D(rn(t0), r1, 0); /* Load current value */ + jump0 = _jit->pc.w; + BNE(rn(t0), r2, 0); /* If not equal, already done and r0 is zero */ + movr(r0, r3); /* Make r0 an inout argument */ + SC_D(r0, r1, 0); /* r0 is 0 if failed, 1 if succeed */ + jump1 = _jit->pc.w; + BEQ(r0, _ZERO_REGNO, 0); + /* FIXME Not certain what 0x700 hint means. Copied from C generated code */ + DBAR(0x700); + done = _jit->pc.w; + patch_at(jump0, done); + patch_at(jump1, retry); + jit_unget_reg(t0); + if (iscasi) + jit_unget_reg(r1_reg); +} + +static void +_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + if (r0 != r1) + OR(r0, r1, _ZERO_REGNO); +} + +static void +_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + if (i0 == 0) + OR(r0, _ZERO_REGNO, _ZERO_REGNO); + else if (can_sign_extend_si12_p(i0)) + ADDI_D(r0, _ZERO_REGNO, i0); + else if (!(i0 & 0xffff) && can_sign_extend_si16_p(i0 >> 16)) + ADDU16I_D(r0, _ZERO_REGNO, i0 >> 16); + else { + jit_word_t w = i0 - _jit->pc.w; + /* If loading some constant reachable address */ + if (can_sign_extend_si32_p(w)) { + jit_int32_t lo = (jit_int32_t)w << 20 >> 20; + jit_int32_t hi = w - lo; + PCADDU12I(r0, hi >> 12); + if (lo) + ADDI_D(r0, r0, lo); + } + else { + jit_int32_t _00_11, _12_31, _32_51, _52_63; + _00_11 = i0 & 0xfff; + _12_31 = (i0 >> 12) & 0xfffff; + _32_51 = (i0 >> 32) & 0xfffff; + _52_63 = (i0 >> 52) & 0xfff; + if (_12_31) { + LU12I_W(r0, _12_31 << 12 >> 12); + if (_00_11) + ORI(r0, r0, _00_11); + } + else + ORI(r0, _ZERO_REGNO, _00_11); + if (_32_51 || (_12_31 & 0x80000)) + LU32I_D(r0, _32_51 << 12 >> 12); + if (_52_63 || (_12_31 & 0x80000) || (_32_51 & 0x80000)) + LU52I_D(r0, r0, _52_63 << 20 >> 20); + } + } +} + +static jit_word_t +_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t _00_11, _12_31, _32_51, _52_63; + _00_11 = i0 & 0xfff; + _12_31 = (i0 >> 12) & 0xfffff; + _32_51 = (i0 >> 32) & 0xfffff; + _52_63 = (i0 >> 52) & 0xfff; + w = _jit->pc.w; + LU12I_W(r0, _12_31 << 12 >> 12); + ORI(r0, r0, _00_11); + LU32I_D(r0, _32_51 << 12 >> 12); + LU52I_D(r0, r0, _52_63 << 20 >> 20); + return (w); +} + +static void +_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + movr(r0, r1); + else if (can_sign_extend_si12_p(i0)) + ADDI_D(r0, r1, i0); + else if (!(i0 & 0xffff) && can_sign_extend_si16_p(i0 >> 16)) + ADDU16I_D(r0, r1, i0 >> 16); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + addr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + t0 = jit_get_reg(jit_class_gpr); + addr(rn(t0), r1, r2); + SLTU(rn(jit_carry), rn(t0), r1); + movr(r0, rn(t0)); + jit_unget_reg(t0); + } + else { + addr(r0, r1, r2); + SLTU(rn(jit_carry), r0, r1); + } +} + +static void +_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + t0 = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + if (can_sign_extend_si12_p(i0)) + ADDI_D(rn(t0), r1, i0); + else if (!(i0 & 0xffff) && can_sign_extend_si16_p(i0 >> 16)) + ADDU16I_D(rn(t0), r1, i0 >> 16); + else { + movi(rn(t0), i0); + addr(rn(t0), r1, rn(t0)); + } + SLTU(rn(jit_carry), rn(t0), r1); + movr(r0, rn(t0)); + } + else { + if (can_sign_extend_si12_p(i0)) + ADDI_D(r0, r1, i0); + else if (!(i0 & 0xffff) && can_sign_extend_si16_p(i0 >> 16)) + ADDU16I_D(r0, r1, i0 >> 16); + else { + movi(rn(t0), i0); + addr(r0, r1, rn(t0)); + } + SLTU(rn(jit_carry), r0, r1); + } + jit_unget_reg(t0); +} + +static void +_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + assert(jit_carry != _NOREG); + t0 = jit_get_reg(jit_class_gpr); + movr(rn(t0), rn(jit_carry)); + addcr(r0, r1, r2); + addcr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + assert(jit_carry != _NOREG); + t0 = jit_get_reg(jit_class_gpr); + movr(rn(t0), rn(jit_carry)); + addci(r0, r1, i0); + addcr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + movr(r0, r1); + else if (can_sign_extend_si12_p(-i0)) + ADDI_D(r0, r1, -i0); + else if (!(-i0 & 0xffff) && can_sign_extend_si16_p(-i0 >> 16)) + ADDU16I_D(r0, r1, -i0 >> 16); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + subr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + t0 = jit_get_reg(jit_class_gpr); + subr(rn(t0), r1, r2); + SLTU(rn(jit_carry), r1, rn(t0)); + movr(r0, rn(t0)); + jit_unget_reg(t0); + } + else { + subr(r0, r1, r2); + SLTU(rn(jit_carry), r1, r0); + } +} + +static void +_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + if (jit_carry == _NOREG) + jit_carry = jit_get_reg(jit_class_gpr); + t0 = jit_get_reg(jit_class_gpr); + if (r0 == r1) { + if (can_sign_extend_si12_p(-i0)) + ADDI_D(rn(t0), r1, -i0); + else if (!(-i0 & 0xffff) && can_sign_extend_si16_p(-i0 >> 16)) + ADDU16I_D(rn(t0), r1, -i0 >> 16); + else { + movi(rn(t0), i0); + subr(rn(t0), r1, rn(t0)); + } + SLTU(rn(jit_carry), r1, rn(t0)); + movr(r0, rn(t0)); + } + else { + if (can_sign_extend_si12_p(-i0)) + ADDI_D(r0, r1, -i0); + else if (!(-i0 & 0xffff) && can_sign_extend_si16_p(-i0 >> 16)) + ADDU16I_D(r0, r1, -i0 >> 16); + else { + movi(rn(t0), i0); + subr(r0, r1, rn(t0)); + } + SLTU(rn(jit_carry), r1, r0); + } + jit_unget_reg(t0); +} + +static void +_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + jit_int32_t t0; + assert(jit_carry != _NOREG); + t0 = jit_get_reg(jit_class_gpr); + movr(rn(t0), rn(jit_carry)); + subcr(r0, r1, r2); + subcr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + assert(jit_carry != _NOREG); + t0 = jit_get_reg(jit_class_gpr); + movr(rn(t0), rn(jit_carry)); + subci(r0, r1, i0); + subcr(r0, r0, rn(t0)); + jit_unget_reg(t0); +} + +static void +_rsbi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + subi(r0, r1, i0); + negr(r0, r0); +} + +static void +_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + mulr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_iqmulr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + jit_int32_t t0; + if (r0 == r2 || r0 == r3) { + t0 = jit_get_reg(jit_class_gpr); + mulr(rn(t0), r2, r3); + } + else + mulr(r0, r2, r3); + if (sign) + MULH_D(r1, r2, r3); + else + MULH_DU(r1, r2, r3); + if (r0 == r2 || r0 == r3) { + movr(r0, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_iqmuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iqmulr(r0, r1, r2, rn(reg), sign); + jit_unget_reg(reg); +} + +static void +_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + divr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + divr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_iqdivr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_int32_t r3, jit_bool_t sign) +{ + jit_int32_t t0; + if (r0 == r2 || r0 == r3) + t0 = jit_get_reg(jit_class_gpr); + else + t0 = _NOREG; + if (sign) { + if (t0 == _NOREG) + DIV_D(r0, r2, r3); + else + DIV_D(rn(t0), r2, r3); + MOD_D(r1, r2, r3); + } + else { + if (t0 == _NOREG) + DIV_DU(r0, r2, r3); + else + DIV_DU(rn(t0), r2, r3); + MOD_DU(r1, r2, r3); + } + if (t0 != _NOREG) { + movr(r0, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_iqdivi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, + jit_int32_t r2, jit_word_t i0, jit_bool_t sign) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + iqdivr(r0, r1, r2, rn(reg), sign); + jit_unget_reg(reg); +} + +static void +_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + remr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); +} + +static void +_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_zero_extend_u12_p(i0)) + ANDI(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + AND(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_zero_extend_u12_p(i0)) + ORI(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + OR(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_zero_extend_u12_p(i0)) + XORI(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + XOR(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_B(r0, _ZERO_REGNO, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LD_B(r0, rn(reg), 0); + jit_unget_reg(reg); + } +} + +static void +_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_BU(r0, _ZERO_REGNO, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LD_BU(r0, rn(reg), 0); + jit_unget_reg(reg); + } +} + +static void +_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_H(r0, _ZERO_REGNO, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LD_H(r0, rn(reg), 0); + jit_unget_reg(reg); + } +} + +static void +_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_HU(r0, _ZERO_REGNO, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LD_HU(r0, rn(reg), 0); + jit_unget_reg(reg); + } +} + +static void +_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_W(r0, _ZERO_REGNO, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LD_W(r0, rn(reg), 0); + jit_unget_reg(reg); + } +} + +static void +_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_WU(r0, _ZERO_REGNO, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LD_WU(r0, rn(reg), 0); + jit_unget_reg(reg); + } +} + +static void +_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_D(r0, _ZERO_REGNO, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LD_D(r0, rn(reg), 0); + jit_unget_reg(reg); + } +} + +static void +_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_B(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDX_B(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_BU(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDX_BU(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_H(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDX_H(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_HU(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDX_HU(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_W(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDX_W(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_WU(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDX_WU(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + LD_D(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + LDX_D(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + ST_B(r0, _ZERO_REGNO, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ST_B(r0, rn(reg), 0); + jit_unget_reg(reg); + } +} + +static void +_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + ST_H(r0, _ZERO_REGNO, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ST_H(r0, rn(reg), 0); + jit_unget_reg(reg); + } +} + +static void +_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + ST_W(r0, _ZERO_REGNO, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ST_W(r0, rn(reg), 0); + jit_unget_reg(reg); + } +} + +static void +_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + ST_D(r0, _ZERO_REGNO, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ST_D(r0, rn(reg), 0); + jit_unget_reg(reg); + } +} + +static void +_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + ST_B(r1, r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + STX_B(r1, r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + ST_H(r1, r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + STX_H(r1, r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + ST_W(r1, r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + STX_W(r1, r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + ST_D(r1, r0, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + STX_D(r1, r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_bswapr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + REVB_2H(r0, r1); + extr_us(r0, r0); +} + +static void +_bswapr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + REVB_2W(r0, r1); + extr_ui(r0, r0); +} + +static void +_lti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + SLTI(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ltr(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_lti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) + SLTUI(r0, r1, i0); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ltr_u(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ler(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SLT(r0, r2, r1); + XORI(r0, r0, 1); +} + +static void +_lei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0 + 1)) + SLTI(r0, r1, i0 + 1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ler(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ler_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SLTU(r0, r2, r1); + XORI(r0, r0, 1); +} + +static void +_lei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0 + 1)) + SLTUI(r0, r1, i0 + 1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ler_u(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_eqr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + subr(r0, r1, r2); + SLTU(r0, _ZERO_REGNO, r0); + XORI(r0, r0, 1); +} + +static void +_eqi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0) { + subi(r0, r1, i0); + SLTU(r0, _ZERO_REGNO, r0); + } + else + SLTU(r0, _ZERO_REGNO, r1); + XORI(r0, r0, 1); +} + +static void +_ger(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SLT(r0, r1, r2); + XORI(r0, r0, 1); +} + +static void +_gei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) { + SLTI(r0, r1, i0); + XORI(r0, r0, 1); + } else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ger(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_ger_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + SLTU(r0, r1, r2); + XORI(r0, r0, 1); +} + +static void +_gei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (can_sign_extend_si12_p(i0)) { + SLTUI(r0, r1, i0); + XORI(r0, r0, 1); + } else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + ger_u(r0, r1, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_gti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + SLT(r0, _ZERO_REGNO, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + SLT(r0, rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_gti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t reg; + if (i0 == 0) + SLTU(r0, _ZERO_REGNO, r1); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), i0); + SLTU(r0, rn(reg), r1); + jit_unget_reg(reg); + } +} + +static void +_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + subr(r0, r1, r2); + SLTU(r0, _ZERO_REGNO, r0); +} + +static void +_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + if (i0) { + subi(r0, r1, i0); + SLTU(r0, _ZERO_REGNO, r0); + } + else + SLTU(r0, _ZERO_REGNO, r1); +} + +static jit_word_t +_bltr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BLT(r0, r1, (i0 - w) >> 2); + return (w); +} + +static jit_word_t +_blti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BLT(r0, _ZERO_REGNO, (i0 - w) >> 2); + } + if (i1) { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = _jit->pc.w; + BLT(r0, rn(reg), (i0 - w) >> 2); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bltr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BLTU(r0, r1, (i0 - w) >> 2); + return (w); +} + +static jit_word_t +_blti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) + w = bltr_u(i0, r0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = _jit->pc.w; + BLTU(r0, rn(reg), (i0 - w) >> 2); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bler(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLT(rn(reg), r1, r0); + w = _jit->pc.w; + BEQZ(rn(reg), (i0 - w) >> 2); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_blei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bler(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bler_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLTU(rn(reg), r1, r0); + w = _jit->pc.w; + BEQZ(rn(reg), (i0 - w) >> 2); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_blei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) + w = bler_u(i0, r0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bler_u(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_beqr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BEQ(r0, r1, (i0 - w) >> 2); + return (w); +} + +static jit_word_t +_beqi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BEQZ(r0, (i0 - w) >> 2); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = beqr(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bger(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BGE(r0, r1, (i0 - w) >> 2); + return (w); +} + +static jit_word_t +_bgei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) + w = bger(i0, r0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bger(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bger_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BGEU(r0, r1, (i0 - w) >> 2); + return (w); +} + +static jit_word_t +_bgei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + B((i0 - w) >> 2); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bger_u(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +static jit_word_t +_bgtr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLT(rn(reg), r1, r0); + w = _jit->pc.w; + BNEZ(rn(reg), (i0 - w) >> 2); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bgti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bgtr(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bgtr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + SLTU(rn(reg), r1, r0); + w = _jit->pc.w; + BNEZ(rn(reg), (i0 - w) >> 2); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bgti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bgtr_u(i0, r0, rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_bner(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + w = _jit->pc.w; + BNE(r0, r1, (i0 - w) >> 2); + return (w); +} + +static jit_word_t +_bnei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t reg; + if (i1 == 0) { + w = _jit->pc.w; + BNEZ(r0, (i0 - w) >> 2); + } + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i1); + w = bner(i0, r0, rn(reg)); + jit_unget_reg(reg); + } + return (w); +} + +static void +_jmpi(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + w = (i0 - _jit->pc.w) >> 2; + if (can_sign_extend_si26_p(i0)) + B(w); + else + (void)jmpi_p(i0); +} + +static jit_word_t +_jmpi_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + w = movi_p(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static jit_word_t +_boaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, b; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + /* t0 = r1 < 0; */ + SLT(rn(t0), r1, _ZERO_REGNO); + /* t1 = r0 */ + movr(rn(t1), r0); + /* r0 = r0 + r1 */ + addr(r0, r0, r1); + /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */ + w = _jit->pc.w; + BNEZ(rn(t0), 0); + /* r1 >= 0 */ + SLT(rn(t1), r0, rn(t1)); + b = _jit->pc.w; + B(0); + /* r1 < 0 */ + patch_at(w, _jit->pc.w); + SLT(rn(t1), rn(t1), r0); + /**/ + patch_at(b, _jit->pc.w); + w = _jit->pc.w; + BNEZ(rn(t1), (i0 - w) >> 2); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_boaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = boaddr(i0, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_boaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addr(rn(t0), r0, r1); + SLTU(rn(t1), rn(t0), r0); + movr(r0, rn(t0)); + w = _jit->pc.w; + BNEZ(rn(t1), (i0 - w) >> 2); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_boaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = boaddr_u(i0, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxaddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, b; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + /* t0 = r1 < 0; */ + SLT(rn(t0), r1, _ZERO_REGNO); + /* t1 = r0 */ + movr(rn(t1), r0); + /* r0 = r0 + r1 */ + addr(r0, r0, r1); + /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */ + w = _jit->pc.w; + BNEZ(rn(t0), 0); + /* r1 >= 0 */ + SLT(rn(t1), r0, rn(t1)); + b = _jit->pc.w; + B(0); + /* r1 < 0 */ + patch_at(w, _jit->pc.w); + SLT(rn(t1), rn(t1), r0); + /**/ + patch_at(b, _jit->pc.w); + w = _jit->pc.w; + BEQZ(rn(t1), (i0 - w) >> 2); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxaddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = bxaddr(i0, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxaddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + addr(rn(t0), r0, r1); + SLTU(rn(t1), rn(t0), r0); + movr(r0, rn(t0)); + w = _jit->pc.w; + BEQZ(rn(t1), (i0 - w) >> 2); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxaddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = bxaddr_u(i0, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bosubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, b; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + /* t0 = 0 < r1; */ + SLT(rn(t0), _ZERO_REGNO, r1); + /* t1 = r0 */ + movr(rn(t1), r0); + /* r0 = r0 - r1 */ + subr(r0, r0, r1); + /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */ + w = _jit->pc.w; + BNE(rn(t0), _ZERO_REGNO, 0); + /* r1 >= 0 */ + SLT(rn(t1), r0, rn(t1)); + b = _jit->pc.w; + B(0); + /* r1 < 0 */ + patch_at(w, _jit->pc.w); + SLT(rn(t1), rn(t1), r0); + /**/ + patch_at(b, _jit->pc.w); + w = _jit->pc.w; + BNEZ(rn(t1), (i0 - w) >> 2); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bosubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = bosubr(i0, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bosubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + subr(rn(t0), r0, r1); + SLTU(rn(t1), r0, rn(t0)); + movr(r0, rn(t0)); + w = _jit->pc.w; + BNEZ(rn(t1), (i0 - w) >> 2); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bosubi_u(jit_state_t *_jit, jit_word_t br, jit_int32_t r0, jit_word_t i0) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i0); + w = bosubr_u(br, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxsubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w, b; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + /* t0 = r1 < 0; */ + SLT(rn(t0), _ZERO_REGNO, r1); + /* t1 = r0 */ + movr(rn(t1), r0); + /* r0 = r0 - r1 */ + subr(r0, r0, r1); + /* overflow = r1 < 0 ? t1 < r0 : r0 < t1 */ + w = _jit->pc.w; + BNEZ(rn(t0), 0); + /* r1 >= 0 */ + SLT(rn(t1), r0, rn(t1)); + b = _jit->pc.w; + B(0); + /* r1 < 0 */ + patch_at(w, _jit->pc.w); + SLT(rn(t1), rn(t1), r0); + /**/ + patch_at(b, _jit->pc.w); + w = _jit->pc.w; + BEQZ(rn(t1), (i0 - w) >> 2); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxsubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = bxsubr(i0, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxsubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0, t1; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + t1 = jit_get_reg(jit_class_gpr|jit_class_nospill); + subr(rn(t0), r0, r1); + SLTU(rn(t1), r0, rn(t0)); + movr(r0, rn(t0)); + w = _jit->pc.w; + BEQZ(rn(t1), (i0 - w) >> 2); + jit_unget_reg(t1); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bxsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(t0), i1); + w = bxsubr_u(i0, r0, rn(t0)); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bmsr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + AND(rn(t0), r0, r1); + w = _jit->pc.w; + BNEZ(rn(t0), (i0 - w) >> 2); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bmsi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + andi(rn(t0), r0, i1); + w = _jit->pc.w; + BNEZ(rn(t0), (i0 - w) >> 2); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bmcr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + AND(rn(t0), r0, r1); + w = _jit->pc.w; + BEQZ(rn(t0), (i0 - w) >> 2); + jit_unget_reg(t0); + return (w); +} + +static jit_word_t +_bmci(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1) +{ + jit_word_t w; + jit_int32_t t0; + t0 = jit_get_reg(jit_class_gpr|jit_class_nospill); + andi(rn(t0), r0, i1); + w = _jit->pc.w; + BEQZ(rn(t0), (i0 - w) >> 2); + jit_unget_reg(t0); + return (w); +} + +static void +_calli(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + w = (i0 - _jit->pc.w) >> 2; + if (can_sign_extend_si26_p(i0)) + BL(w); + else + (void)calli_p(i0); +} + +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0) +{ + jit_word_t w; + jit_word_t reg; + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + w = movi_p(rn(reg), i0); + callr(rn(reg)); + jit_unget_reg(reg); + return (w); +} + +static void +_prolog(jit_state_t *_jit, jit_node_t *node) +{ + jit_int32_t reg; + if (_jitc->function->define_frame || _jitc->function->assume_frame) { + jit_int32_t frame = -_jitc->function->frame; + assert(_jitc->function->self.aoff >= frame); + if (_jitc->function->assume_frame) + return; + _jitc->function->self.aoff = frame; + } + if (_jitc->function->allocar) + _jitc->function->self.aoff &= -16; + _jitc->function->stack = ((_jitc->function->self.alen - + /* align stack at 16 bytes */ + _jitc->function->self.aoff) + 15) & -16; + subi(_SP_REGNO, _SP_REGNO, stack_framesize); + stxi(0, _SP_REGNO, _RA_REGNO); + stxi(8, _SP_REGNO, _FP_REGNO); + if (jit_regset_tstbit(&_jitc->function->regset, _S0)) + stxi(16, _SP_REGNO, rn(_S0)); + if (jit_regset_tstbit(&_jitc->function->regset, _S1)) + stxi(24, _SP_REGNO, rn(_S1)); + if (jit_regset_tstbit(&_jitc->function->regset, _S2)) + stxi(32, _SP_REGNO, rn(_S2)); + if (jit_regset_tstbit(&_jitc->function->regset, _S3)) + stxi(40, _SP_REGNO, rn(_S3)); + if (jit_regset_tstbit(&_jitc->function->regset, _S4)) + stxi(48, _SP_REGNO, rn(_S4)); + if (jit_regset_tstbit(&_jitc->function->regset, _S5)) + stxi(56, _SP_REGNO, rn(_S5)); + if (jit_regset_tstbit(&_jitc->function->regset, _S6)) + stxi(64, _SP_REGNO, rn(_S6)); + if (jit_regset_tstbit(&_jitc->function->regset, _S7)) + stxi(72, _SP_REGNO, rn(_S7)); + if (jit_regset_tstbit(&_jitc->function->regset, _S8)) + stxi(80, _SP_REGNO, rn(_S8)); + if (jit_regset_tstbit(&_jitc->function->regset, _FS0)) + stxi_d(88, _SP_REGNO, rn(_FS0)); + if (jit_regset_tstbit(&_jitc->function->regset, _FS1)) + stxi_d(96, _SP_REGNO, rn(_FS1)); + if (jit_regset_tstbit(&_jitc->function->regset, _FS2)) + stxi_d(104, _SP_REGNO, rn(_FS2)); + if (jit_regset_tstbit(&_jitc->function->regset, _FS3)) + stxi_d(112, _SP_REGNO, rn(_FS3)); + if (jit_regset_tstbit(&_jitc->function->regset, _FS4)) + stxi_d(120, _SP_REGNO, rn(_FS4)); + if (jit_regset_tstbit(&_jitc->function->regset, _FS5)) + stxi_d(128, _SP_REGNO, rn(_FS5)); + if (jit_regset_tstbit(&_jitc->function->regset, _FS6)) + stxi_d(136, _SP_REGNO, rn(_FS6)); + if (jit_regset_tstbit(&_jitc->function->regset, _FS7)) + stxi_d(144, _SP_REGNO, rn(_FS7)); + movr(_FP_REGNO, _SP_REGNO); + if (_jitc->function->stack) + subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack); + if (_jitc->function->allocar) { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), _jitc->function->self.aoff); + stxi_i(_jitc->function->aoffoff, _FP_REGNO, rn(reg)); + jit_unget_reg(reg); + } + if (_jitc->function->self.call & jit_call_varargs) { + for (reg = _jitc->function->vagp; jit_arg_reg_p(reg); ++reg) + stxi(stack_framesize - ((8 - reg) * 8), + _FP_REGNO, rn(JIT_RA0 - reg)); + } +} + +static void +_epilog(jit_state_t *_jit, jit_node_t *node) +{ + if (_jitc->function->assume_frame) + return; + movr(_SP_REGNO, _FP_REGNO); + ldxi(_RA_REGNO, _SP_REGNO, 0); + ldxi(_FP_REGNO, _SP_REGNO, 8); + if (jit_regset_tstbit(&_jitc->function->regset, _S0)) + ldxi(rn(_S0), _SP_REGNO, 16); + if (jit_regset_tstbit(&_jitc->function->regset, _S1)) + ldxi(rn(_S1), _SP_REGNO, 24); + if (jit_regset_tstbit(&_jitc->function->regset, _S2)) + ldxi(rn(_S2), _SP_REGNO, 32); + if (jit_regset_tstbit(&_jitc->function->regset, _S3)) + ldxi(rn(_S3), _SP_REGNO, 40); + if (jit_regset_tstbit(&_jitc->function->regset, _S4)) + ldxi(rn(_S4), _SP_REGNO, 48); + if (jit_regset_tstbit(&_jitc->function->regset, _S5)) + ldxi(rn(_S5), _SP_REGNO, 56); + if (jit_regset_tstbit(&_jitc->function->regset, _S6)) + ldxi(rn(_S6), _SP_REGNO, 64); + if (jit_regset_tstbit(&_jitc->function->regset, _S7)) + ldxi(rn(_S7), _SP_REGNO, 72); + if (jit_regset_tstbit(&_jitc->function->regset, _S8)) + ldxi(rn(_S8), _SP_REGNO, 80); + if (jit_regset_tstbit(&_jitc->function->regset, _FS0)) + ldxi_d(rn(_FS0), _SP_REGNO, 88); + if (jit_regset_tstbit(&_jitc->function->regset, _FS1)) + ldxi_d(rn(_FS1), _SP_REGNO, 96); + if (jit_regset_tstbit(&_jitc->function->regset, _FS2)) + ldxi_d(rn(_FS2), _SP_REGNO, 104); + if (jit_regset_tstbit(&_jitc->function->regset, _FS3)) + ldxi_d(rn(_FS3), _SP_REGNO, 112); + if (jit_regset_tstbit(&_jitc->function->regset, _FS4)) + ldxi_d(rn(_FS4), _SP_REGNO, 120); + if (jit_regset_tstbit(&_jitc->function->regset, _FS5)) + ldxi_d(rn(_FS5), _SP_REGNO, 128); + if (jit_regset_tstbit(&_jitc->function->regset, _FS6)) + ldxi_d(rn(_FS6), _SP_REGNO, 136); + if (jit_regset_tstbit(&_jitc->function->regset, _FS7)) + ldxi_d(rn(_FS7), _SP_REGNO, 144); + addi(_SP_REGNO, _SP_REGNO, stack_framesize); + JIRL(_ZERO_REGNO, _RA_REGNO, 0); +} + +static void +_vastart(jit_state_t *_jit, jit_int32_t r0) +{ + assert(_jitc->function->self.call & jit_call_varargs); + /* Initialize va_list to the first stack argument. */ + if (jit_arg_reg_p(_jitc->function->vagp)) + addi(r0, _FP_REGNO, stack_framesize - ((8 - _jitc->function->vagp) * 8)); + else + addi(r0, _FP_REGNO, _jitc->function->self.size); +} + +static void +_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(_jitc->function->self.call & jit_call_varargs); + /* Load argument. */ + ldr(r0, r1); + /* Update va_list. */ + addi(r1, r1, sizeof(jit_word_t)); +} + +static void +_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label) +{ + jit_uint32_t c; + union { + jit_uint32_t *i; + jit_word_t w; + } u; + u.w = instr; + c = u.i[0]; + /* movi_p? */ + if ((c >> 25) == 10) { /* LU12I_W */ + jit_int32_t _00_11, _12_31, _32_51, _52_63; + _00_11 = label & 0xfff; + _12_31 = (label >> 12) & 0xfffff; + _32_51 = (label >> 32) & 0xfffff; + _52_63 = (label >> 52) & 0xfff; + u.i[0] &= ~(0xfffff << 5); + u.i[0] |= _12_31 << 5; + assert((u.i[1] >> 22) == 14); /* ORI */ + u.i[1] &= ~(0xfff << 10); + u.i[1] |= _00_11 << 10; + assert((u.i[2] >> 25) == 11); /* LU32I_D */ + u.i[2] &= ~(0xfffff << 5); + u.i[2] |= _32_51 << 5; + assert((u.i[3] >> 22) == 12); /* LU52I_D */ + u.i[3] &= ~(0xfff << 10); + u.i[3] |= _52_63 << 0; + } + else if ((c >> 26) >= 22 && (c >> 26) <= 27) { + /* B{EQ,NE,LT,GE,LTU,GEU} */ + jit_word_t disp = (label - instr) >> 2; + assert(can_sign_extend_si16_p(disp)); + u.i[0] &= ~(0xffff << 10); + u.i[0] |= (disp & 0xffff) << 10; + } + else if ((c >> 26) == 20 || (c >> 26) == 21) { /* B or BL */ + jit_word_t disp = (label - instr) >> 2; + assert(can_sign_extend_si26_p(disp)); + disp &= 0x3ffffff; + u.i[0] &= ~0x3ffffff; + u.i[0] |= ((disp & 0xffff) << 10) | (disp >> 16); + } + else if ((c >> 26) >= 16 && (c >> 26) <= 18) { /* B{,C}{EQ,NE}Z */ + jit_word_t disp = (label - instr) >> 2; + assert(can_sign_extend_si21_p(disp)); + disp &= 0x1fffff; + u.i[0] &= ~((0xffff << 10) | 0x1f); + u.i[0] |= ((disp & 0xffff) << 10) | (disp >> 16); + } + else + abort(); +} +#endif diff --git a/deps/lightning/lib/jit_loongarch-fpu.c b/deps/lightning/lib/jit_loongarch-fpu.c new file mode 100644 index 00000000..5874afde --- /dev/null +++ b/deps/lightning/lib/jit_loongarch-fpu.c @@ -0,0 +1,1318 @@ +/* + * Copyright (C) 2022 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#if PROTO +# define FADD_S(fd, fj, fk) orrr(0x201, fk, fj, fd) +# define FADD_D(fd, fj, fk) orrr(0x202, fk, fj, fd) +# define FSUB_S(fd, fj, fk) orrr(0x205, fk, fj, fd) +# define FSUB_D(fd, fj, fk) orrr(0x206, fk, fj, fd) +# define FMUL_S(fd, fj, fk) orrr(0x209, fk, fj, fd) +# define FMUL_D(fd, fj, fk) orrr(0x20a, fk, fj, fd) +# define FDIV_S(fd, fj, fk) orrr(0x20d, fk, fj, fd) +# define FDIV_D(fd, fj, fk) orrr(0x20e, fk, fj, fd) +# define FMAX_S(fd, fj, fk) orrr(0x211, fk, fj, fd) +# define FMAX_D(fd, fj, fk) orrr(0x212, fk, fj, fd) +# define FMIN_S(fd, fj, fk) orrr(0x215, fk, fj, fd) +# define FMIN_D(fd, fj, fk) orrr(0x216, fk, fj, fd) +# define FMAXA_S(fd, fj, fk) orrr(0x219, fk, fj, fd) +# define FMAXA_D(fd, fj, fk) orrr(0x21a, fk, fj, fd) +# define FMINA_S(fd, fj, fk) orrr(0x21d, fk, fj, fd) +# define FMINA_D(fd, fj, fk) orrr(0x21e, fk, fj, fd) +# define FSCALEB_S(fd, fj, fk) orrr(0x221, fk, fj, fd) +# define FSCALEB_D(fd, fj, fk) orrr(0x222, fk, fj, fd) +# define FCOPYSIGN_S(fd, fj, fk) orrr(0x225, fk, fj, fd) +# define FCOPYSIGN_D(fd, fj, fk) orrr(0x226, fk, fj, fd) +# define FABS_S(fd, fj) ou5rr(0x228, 0x01, fj, fd) +# define FABS_D(fd, fj) ou5rr(0x228, 0x02, fj, fd) +# define FNEG_S(fd, fj) ou5rr(0x228, 0x05, fj, fd) +# define FNEG_D(fd, fj) ou5rr(0x228, 0x06, fj, fd) +# define FGLOB_S(fd, fj) ou5rr(0x228, 0x09, fj, fd) +# define FGLOB_D(fd, fj) ou5rr(0x228, 0x0a, fj, fd) +# define FCLASS_S(fd, fj) ou5rr(0x228, 0x0d, fj, fd) +# define FCLASS_D(fd, fj) ou5rr(0x228, 0x0e, fj, fd) +# define FSQRT_S(fd, fj) ou5rr(0x228, 0x11, fj, fd) +# define FSQRT_D(fd, fj) ou5rr(0x228, 0x12, fj, fd) +# define FRECIP_S(fd, fj) ou5rr(0x228, 0x15, fj, fd) +# define FRECIP_D(fd, fj) ou5rr(0x228, 0x16, fj, fd) +# define FRSQRT_S(fd, fj) ou5rr(0x228, 0x19, fj, fd) +# define FRSQRT_D(fd, fj) ou5rr(0x228, 0x1a, fj, fd) +# define FMOV_S(fd, fj) ou5rr(0x229, 0x05, fj, fd) +# define FMOV_D(fd, fj) ou5rr(0x229, 0x06, fj, fd) +# define MOVGR2FR_W(fd, rj) ou5rr(0x229, 0x09, rj, fd) +# define MOVGR2FR_D(fd, rj) ou5rr(0x229, 0x0a, rj, fd) +# define MOVGR2FRH_W(fd, rj) ou5rr(0x229, 0x0b, rj, fd) +# define MOVFR2GR_S(rd, fj) ou5rr(0x229, 0x0d, fj, rd) +# define MOVFR2GR_D(rd, fj) ou5rr(0x229, 0x0e, fj, rd) +# define MOVFRH2GR_S(rd, fj) ou5rr(0x229, 0x0f, fj, rd) +# define MOVGR2FCSR(fc, rj) ou5rr(0x229, 0x10, rj, fc) +# define MOVFCSR2GR(rd, fc) ou5rr(0x229, 0x12, fc, rd) +# define MOVFR2CF(cd, fj) o5r23(0x229, 0x14, fj, 0, cd) +# define MOVCF2FR(fd, cj) o523r(0x229, 0x15, 0, cj, fd) +# define MOVGR2CF(cd, fj) o5r23(0x229, 0x16, fj, 0, cd) +# define MOVCF2GR(fd, cj) o523r(0x229, 0x17, 0, cj, fd) +# define FCVT_S_D(fd, fj) ou5rr(0x232, 0x06, fj, fd) +# define FCVT_D_S(fd, fj) ou5rr(0x232, 0x09, fj, fd) +# define FTINTRM_W_S(fd, fj) ou5rr(0x234, 0x01, fj, fd) +# define FTINTRM_W_D(fd, fj) ou5rr(0x234, 0x02, fj, fd) +# define FTINTRM_L_S(fd, fj) ou5rr(0x234, 0x09, fj, fd) +# define FTINTRM_L_D(fd, fj) ou5rr(0x234, 0x0a, fj, fd) +# define FTINTRP_W_S(fd, fj) ou5rr(0x234, 0x11, fj, fd) +# define FTINTRP_W_D(fd, fj) ou5rr(0x234, 0x12, fj, fd) +# define FTINTRP_L_S(fd, fj) ou5rr(0x234, 0x19, fj, fd) +# define FTINTRP_L_D(fd, fj) ou5rr(0x234, 0x1a, fj, fd) +# define FTINTRZ_W_S(fd, fj) ou5rr(0x235, 0x01, fj, fd) +# define FTINTRZ_W_D(fd, fj) ou5rr(0x235, 0x02, fj, fd) +# define FTINTRZ_L_S(fd, fj) ou5rr(0x235, 0x09, fj, fd) +# define FTINTRZ_L_D(fd, fj) ou5rr(0x235, 0x0a, fj, fd) +# define FTINTRNE_W_S(fd, fj) ou5rr(0x235, 0x11, fj, fd) +# define FTINTRNE_W_D(fd, fj) ou5rr(0x235, 0x12, fj, fd) +# define FTINTRNE_L_S(fd, fj) ou5rr(0x235, 0x19, fj, fd) +# define FTINTRNE_L_D(fd, fj) ou5rr(0x235, 0x1a, fj, fd) +# define FTINT_W_S(fd, fj) ou5rr(0x236, 0x01, fj, fd) +# define FTINT_W_D(fd, fj) ou5rr(0x236, 0x02, fj, fd) +# define FTINT_L_S(fd, fj) ou5rr(0x236, 0x09, fj, fd) +# define FTINT_L_D(fd, fj) ou5rr(0x236, 0x0a, fj, fd) +# define FFINT_S_W(fd, fj) ou5rr(0x23a, 0x04, fj, fd) +# define FFINT_S_L(fd, fj) ou5rr(0x23a, 0x06, fj, fd) +# define FFINT_D_W(fd, fj) ou5rr(0x23a, 0x08, fj, fd) +# define FFINT_D_L(fd, fj) ou5rr(0x23a, 0x0a, fj, fd) +# define FRINT_S(fd, fj) ou5rr(0x23c, 0x11, fj, fd) +# define FRINT_D(fd, fj) ou5rr(0x23c, 0x12, fj, fd) +# define FMADD_S(fd, fj, fk, fa) orrrr(0x081, fa, fk, fj, fd) +# define FMADD_D(fd, fj, fk, fa) orrrr(0x082, fa, fk, fj, fd) +# define FMSUB_S(fd, fj, fk, fa) orrrr(0x085, fa, fk, fj, fd) +# define FMSUB_D(fd, fj, fk, fa) orrrr(0x086, fa, fk, fj, fd) +# define FNMADD_S(fd, fj, fk, fa) orrrr(0x089, fa, fk, fj, fd) +# define FNMADD_D(fd, fj, fk, fa) orrrr(0x08a, fa, fk, fj, fd) +# define FNMSUB_S(fd, fj, fk, fa) orrrr(0x08d, fa, fk, fj, fd) +# define FNMSUB_D(fd, fj, fk, fa) orrrr(0x08e, fa, fk, fj, fd) +/* No QNaN exception */ +# define _CAF 0x00 +# define _CUN 0x08 +# define _CEQ 0x04 +# define _CUEQ 0x0c +# define _CLT 0x02 +# define _CULT 0x0a +# define _CLE 0x06 +# define _CULE 0x0e +# define _CNE 0x10 +# define _COR 0x14 +# define _CUNE 0x18 +/* QNaN exception */ +# define _SAF 0x01 +# define _SUN 0x09 +# define _SEQ 0x05 +# define _SUEQ 0x0D +# define _SLT 0x03 +# define _SULT 0x0B +# define _SLE 0x07 +# define _SULE 0x0F +# define _SNE 0x11 +# define _SOR 0x15 +# define _SUNE 0x19 +# define FCMP_cond_S(cc, cd, fj, fk) ou5rru2u3(0x0c1, cc, fk, fj, 0, cd) +# define FCMP_CAF_S(cd, fj, fk) FCMP_cond_S( _CAF, cd, fj, fk) +# define FCMP_CUN_S(cd, fj, fk) FCMP_cond_S( _CUN, cd, fj, fk) +# define FCMP_CEQ_S(cd, fj, fk) FCMP_cond_S( _CEQ, cd, fj, fk) +# define FCMP_CUEQ_S(cd, fj, fk) FCMP_cond_S(_CUEQ, cd, fj, fk) +# define FCMP_CLT_S(cd, fj, fk) FCMP_cond_S( _CLT, cd, fj, fk) +# define FCMP_CULT_S(cd, fj, fk) FCMP_cond_S(_CULT, cd, fj, fk) +# define FCMP_CLE_S(cd, fj, fk) FCMP_cond_S( _CLE, cd, fj, fk) +# define FCMP_CULE_S(cd, fj, fk) FCMP_cond_S(_CULE, cd, fj, fk) +# define FCMP_CNE_S(cd, fj, fk) FCMP_cond_S( _CNE, cd, fj, fk) +# define FCMP_COR_S(cd, fj, fk) FCMP_cond_S( _COR, cd, fj, fk) +# define FCMP_CUNE_S(cd, fj, fk) FCMP_cond_S(_CUNE, cd, fj, fk) +# define FCMP_SAF_S(cd, fj, fk) FCMP_cond_S( _CAF, cd, fj, fk) +# define FCMP_SUN_S(cd, fj, fk) FCMP_cond_S( _CUN, cd, fj, fk) +# define FCMP_SEQ_S(cd, fj, fk) FCMP_cond_S( _CEQ, cd, fj, fk) +# define FCMP_SUEQ_S(cd, fj, fk) FCMP_cond_S(_CUEQ, cd, fj, fk) +# define FCMP_SLT_S(cd, fj, fk) FCMP_cond_S( _CLT, cd, fj, fk) +# define FCMP_SULT_S(cd, fj, fk) FCMP_cond_S(_CULT, cd, fj, fk) +# define FCMP_SLE_S(cd, fj, fk) FCMP_cond_S( _CLE, cd, fj, fk) +# define FCMP_SULE_S(cd, fj, fk) FCMP_cond_S(_CULE, cd, fj, fk) +# define FCMP_SNE_S(cd, fj, fk) FCMP_cond_S( _CNE, cd, fj, fk) +# define FCMP_SOR_S(cd, fj, fk) FCMP_cond_S( _COR, cd, fj, fk) +# define FCMP_SUNE_S(cd, fj, fk) FCMP_cond_S(_CUNE, cd, fj, fk) +# define FCMP_cond_D(cc, cd, fj, fk) ou5rru2u3(0x0c2, cc, fk, fj, 0, cd) +# define FCMP_CAF_D(cd, fj, fk) FCMP_cond_D( _CAF, cd, fj, fk) +# define FCMP_CUN_D(cd, fj, fk) FCMP_cond_D( _CUN, cd, fj, fk) +# define FCMP_CEQ_D(cd, fj, fk) FCMP_cond_D( _CEQ, cd, fj, fk) +# define FCMP_CUEQ_D(cd, fj, fk) FCMP_cond_D(_CUEQ, cd, fj, fk) +# define FCMP_CLT_D(cd, fj, fk) FCMP_cond_D( _CLT, cd, fj, fk) +# define FCMP_CULT_D(cd, fj, fk) FCMP_cond_D(_CULT, cd, fj, fk) +# define FCMP_CLE_D(cd, fj, fk) FCMP_cond_D( _CLE, cd, fj, fk) +# define FCMP_CULE_D(cd, fj, fk) FCMP_cond_D(_CULE, cd, fj, fk) +# define FCMP_CNE_D(cd, fj, fk) FCMP_cond_D( _CNE, cd, fj, fk) +# define FCMP_COR_D(cd, fj, fk) FCMP_cond_D( _COR, cd, fj, fk) +# define FCMP_CUNE_D(cd, fj, fk) FCMP_cond_D(_CUNE, cd, fj, fk) +# define FCMP_SAF_D(cd, fj, fk) FCMP_cond_D( _CAF, cd, fj, fk) +# define FCMP_SUN_D(cd, fj, fk) FCMP_cond_D( _CUN, cd, fj, fk) +# define FCMP_SEQ_D(cd, fj, fk) FCMP_cond_D( _CEQ, cd, fj, fk) +# define FCMP_SUEQ_D(cd, fj, fk) FCMP_cond_D(_CUEQ, cd, fj, fk) +# define FCMP_SLT_D(cd, fj, fk) FCMP_cond_D( _CLT, cd, fj, fk) +# define FCMP_SULT_D(cd, fj, fk) FCMP_cond_D(_CULT, cd, fj, fk) +# define FCMP_SLE_D(cd, fj, fk) FCMP_cond_D( _CLE, cd, fj, fk) +# define FCMP_SULE_D(cd, fj, fk) FCMP_cond_D(_CULE, cd, fj, fk) +# define FCMP_SNE_D(cd, fj, fk) FCMP_cond_D( _CNE, cd, fj, fk) +# define FCMP_SOR_D(cd, fj, fk) FCMP_cond_D( _COR, cd, fj, fk) +# define FCMP_SUNE_D(cd, fj, fk) FCMP_cond_D(_CUNE, cd, fj, fk) +# define FSEL(fd, fj, fk, u3) ou3rrr(0x340, u3, fk, fj, fd) +# define FLD_S(fd, rj, si12) os12rr(0x0ac, si12, rj, fd) +# define FST_S(fd, rj, si12) os12rr(0x0ad, si12, rj, fd) +# define FLD_D(fd, rj, si12) os12rr(0x0ae, si12, rj, fd) +# define FST_D(fd, rj, si12) os12rr(0x0af, si12, rj, fd) +# define FLDX_S(fd, rj, rk) orrr(0x7060, rk, rj, fd) +# define FLDX_D(fd, rj, rk) orrr(0x7068, rk, rj, fd) +# define FSTX_S(fd, rj, rk) orrr(0x7070, rk, rj, fd) +# define FSTX_D(fd, rj, rk) orrr(0x7078, rk, rj, fd) +# define FLDGT_S(fd, rj, rk) orrr(0x70e8, rk, rj, fd) +# define FLDGT_D(fd, rj, rk) orrr(0x70e9, rk, rj, fd) +# define FLDLE_S(fd, rj, rk) orrr(0x70ea, rk, rj, fd) +# define FLDLE_D(fd, rj, rk) orrr(0x70eb, rk, rj, fd) +# define FSTGT_S(fd, rj, rk) orrr(0x70ec, rk, rj, fd) +# define FSTGT_D(fd, rj, rk) orrr(0x70ed, rk, rj, fd) +# define FSTLE_S(fd, rj, rk) orrr(0x70ee, rk, rj, fd) +# define FSTLE_D(fd, rj, rk) orrr(0x70ef, rk, rj, fd) +# define truncr_f_i(r0, r1) _truncr_f_i(_jit, r0, r1) +static void _truncr_f_i(jit_state_t*, jit_int32_t, jit_int32_t); +# define truncr_d_i(r0, r1) _truncr_d_i(_jit, r0, r1) +static void _truncr_d_i(jit_state_t*, jit_int32_t, jit_int32_t); +# define truncr_f_l(r0, r1) _truncr_f_l(_jit, r0, r1) +static void _truncr_f_l(jit_state_t*, jit_int32_t, jit_int32_t); +# define truncr_d_l(r0, r1) _truncr_d_l(_jit, r0, r1) +static void _truncr_d_l(jit_state_t*, jit_int32_t, jit_int32_t); +# define addr_f(r0, r1, r2) FADD_S(r0, r1, r2) +# define addi_f(r0, r1, i0) _addi_f(_jit, r0, r1, i0) +static void _addi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define subr_f(r0, r1, r2) FSUB_S(r0, r1, r2) +# define subi_f(r0, r1, i0) _subi_f(_jit, r0, r1, i0) +static void _subi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define rsbr_f(r0, r1, r2) FSUB_S(r0, r2, r1) +# define rsbi_f(r0, r1, i0) _rsbi_f(_jit, r0, r1, i0) +static void _rsbi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define mulr_f(r0, r1, r2) FMUL_S(r0, r1, r2) +# define muli_f(r0, r1, i0) _muli_f(_jit, r0, r1, i0) +static void _muli_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define divr_f(r0, r1, r2) FDIV_S(r0, r1, r2) +# define divi_f(r0, r1, i0) _divi_f(_jit, r0, r1, i0) +static void _divi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define absr_f(r0, r1) FABS_S(r0, r1) +# define negr_f(r0, r1) FNEG_S(r0, r1) +# define sqrtr_f(r0, r1) FSQRT_S(r0, r1) +# define extr_f(r0, r1) _extr_f(_jit, r0, r1) +static void _extr_f(jit_state_t*, jit_int32_t, jit_int32_t); +# define ldr_f(r0, r1) FLD_S(r0, r1, 0) +# define ldi_f(r0, i0) _ldi_f(_jit, r0, i0) +static void _ldi_f(jit_state_t*, jit_int32_t, jit_word_t); +# define ldxr_f(r0, r1, r2) FLDX_S(r0, r1, r2) +# define ldxi_f(r0, r1, i0) _ldxi_f(_jit, r0, r1, i0) +static void _ldxi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define str_f(r0, r1) FST_S(r1, r0, 0) +# define sti_f(i0, r0) _sti_f(_jit, i0, r0) +static void _sti_f(jit_state_t*, jit_word_t, jit_int32_t); +# define stxr_f(r0, r1, r2) FSTX_S(r2, r1, r0) +# define stxi_f(i0, r0, r1) _stxi_f(_jit, i0, r0, r1) +static void _stxi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define movr_f(r0, r1) FMOV_S(r0, r1) +# define movi_f(r0, i0) _movi_f(_jit, r0, i0) +static void _movi_f(jit_state_t*, jit_int32_t, jit_float32_t); +# define movr_f_w(r0, r1) MOVFR2GR_S(r0, r1) +# define movi_f_w(r0, im) _movi_f_w(_jit, r0, im) +static void _movi_f_w(jit_state_t*, jit_int32_t, jit_float32_t); +# define movr_w_f(r0, r1) MOVGR2FR_W(r0, r1) +# define extr_d_f(r0, r1) FCVT_S_D(r0, r1) +# define ltr_f(r0, r1, r2) _ltr_f(_jit, r0, r1, r2) +static void _ltr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define lti_f(r0, r1, i0) _lti_f(_jit, r0, r1, i0) +static void _lti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define ler_f(r0, r1, r2) _ler_f(_jit, r0, r1, r2) +static void _ler_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define lei_f(r0, r1, i0) _lei_f(_jit, r0, r1, i0) +static void _lei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define eqr_f(r0, r1, r2) _eqr_f(_jit, r0, r1, r2) +static void _eqr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define eqi_f(r0, r1, i0) _eqi_f(_jit, r0, r1, i0) +static void _eqi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define ger_f(r0, r1, r2) _ger_f(_jit, r0, r1, r2) +static void _ger_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define gei_f(r0, r1, i0) _gei_f(_jit, r0, r1, i0) +static void _gei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define gtr_f(r0, r1, r2) _gtr_f(_jit, r0, r1, r2) +static void _gtr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define gti_f(r0, r1, i0) _gti_f(_jit, r0, r1, i0) +static void _gti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define ner_f(r0, r1, r2) _ner_f(_jit, r0, r1, r2) +static void _ner_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define nei_f(r0, r1, i0) _nei_f(_jit, r0, r1, i0) +static void _nei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define unltr_f(r0, r1, r2) _unltr_f(_jit, r0, r1, r2) +static void _unltr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define unlti_f(r0, r1, i0) _unlti_f(_jit, r0, r1, i0) +static void _unlti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define unler_f(r0, r1, r2) _unler_f(_jit, r0, r1, r2) +static void _unler_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define unlei_f(r0, r1, i1) _unlei_f(_jit, r0, r1, i1) +static void _unlei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define uneqr_f(r0, r1, r2) _uneqr_f(_jit, r0, r1, r2) +static void _uneqr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define uneqi_f(r0, r1, i0) _uneqi_f(_jit, r0, r1, i0) +static void _uneqi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define unger_f(r0, r1, r2) _unger_f(_jit, r0, r1, r2) +static void _unger_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ungei_f(r0, r1, i0) _ungei_f(_jit, r0, r1, i0) +static void _ungei_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define ungtr_f(r0, r1, r2) _ungtr_f(_jit, r0, r1, r2) +static void _ungtr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ungti_f(r0, r1, i0) _ungti_f(_jit, r0, r1, i0) +static void _ungti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define ltgtr_f(r0, r1, r2) _ltgtr_f(_jit, r0, r1, r2) +static void _ltgtr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ltgti_f(r0, r1, i0) _ltgti_f(_jit, r0, r1, i0) +static void _ltgti_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define ordr_f(r0, r1, r2) _ordr_f(_jit, r0, r1, r2) +static void _ordr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ordi_f(r0, r1, i0) _ordi_f(_jit, r0, r1, i0) +static void _ordi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define unordr_f(r0, r1, r2) _unordr_f(_jit, r0, r1, r2) +static void _unordr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define unordi_f(r0, r1, i0) _unordi_f(_jit, r0, r1, i0) +static void _unordi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_float32_t); +# define bltr_f(i0, r0, r1) _bltr_f(_jit, i0, r0, r1) +static jit_word_t _bltr_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define blti_f(i0, r0, i1) _blti_f(_jit, i0, r0, i1) +static jit_word_t _blti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t); +# define bler_f(i0, r0, r1) _bler_f(_jit, i0, r0, r1) +static jit_word_t _bler_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define blei_f(i0, r0, i1) _blei_f(_jit, i0, r0, i1) +static jit_word_t _blei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t); +# define beqr_f(i0, r0, r1) _beqr_f(_jit, i0, r0, r1) +static jit_word_t _beqr_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define beqi_f(i0, r0, i1) _beqi_f(_jit, i0, r0, i1) +static jit_word_t _beqi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t); +# define bger_f(i0, r0, r1) _bger_f(_jit, i0, r0, r1) +static jit_word_t _bger_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bgei_f(i0, r0, i1) _bgei_f(_jit, i0, r0, i1) +static jit_word_t _bgei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t); +# define bgtr_f(i0, r0, r1) _bgtr_f(_jit,i0, r0, r1) +static jit_word_t _bgtr_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bgti_f(i0, r0, i1) _bgti_f(_jit, i0, r0, i1) +static jit_word_t _bgti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t); +# define bner_f(i0, r0, r1) _bner_f(_jit, i0, r0, r1) +static jit_word_t _bner_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bnei_f(i0, r0, i1) _bnei_f(_jit, i0, r0, i1) +static jit_word_t _bnei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t); +# define bunltr_f(i0, r0, r1) _bunltr_f(_jit, i0, r0, r1) +static jit_word_t _bunltr_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bunlti_f(i0, r0, i1) _bunlti_f(_jit, i0, r0, i1) +static jit_word_t _bunlti_f(jit_state_t*, jit_word_t,jit_int32_t,jit_float32_t); +# define bunler_f(i0, r0, r1) _bunler_f(_jit, i0, r0, r1) +static jit_word_t _bunler_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bunlei_f(i0, r0, i1) _bunlei_f(_jit, i0, r0, i1) +static jit_word_t _bunlei_f(jit_state_t*, jit_word_t,jit_int32_t,jit_float32_t); +# define buneqr_f(i0, r0, r1) _buneqr_f(_jit, i0, r0, r1) +static jit_word_t _buneqr_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define buneqi_f(i0, r0, i1) _buneqi_f(_jit, i0, r0, i1) +static jit_word_t _buneqi_f(jit_state_t*, jit_word_t,jit_int32_t,jit_float32_t); +# define bunger_f(i0, r0, r1) _bunger_f(_jit, i0, r0, r1) +static jit_word_t _bunger_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bungei_f(i0, r0, i1) _bungei_f(_jit, i0, r0, i1) +static jit_word_t _bungei_f(jit_state_t*, jit_word_t,jit_int32_t,jit_float32_t); +# define bungtr_f(i0, r0, r1) _bungtr_f(_jit, i0, r0, r1) +static jit_word_t _bungtr_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bungti_f(i0, r0, i1) _bungti_f(_jit, i0, r0, i1) +static jit_word_t _bungti_f(jit_state_t*, jit_word_t,jit_int32_t,jit_float32_t); +# define bltgtr_f(i0, r0, r1) _bltgtr_f(_jit, i0, r0, r1) +static jit_word_t _bltgtr_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bltgti_f(i0, r0, i1) _bltgti_f(_jit, i0, r0, i1) +static jit_word_t _bltgti_f(jit_state_t*, jit_word_t,jit_int32_t,jit_float32_t); +# define bordr_f(i0, r0, r1) _bordr_f(_jit, i0, r0, r1) +static jit_word_t _bordr_f(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bordi_f(i0, r0, i1) _bordi_f(_jit, i0, r0, i1) +static jit_word_t _bordi_f(jit_state_t*, jit_word_t, jit_int32_t,jit_float32_t); +# define bunordr_f(i0, r0, r1) _bunordr_f(_jit, i0, r0, r1) +static jit_word_t _bunordr_f(jit_state_t*, jit_word_t, jit_int32_t,jit_int32_t); +# define bunordi_f(i0, r0, i1) _bunordi_f(_jit, i0,r0, i1) +static jit_word_t _bunordi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t); +# define addr_d(r0, r1, r2) FADD_D(r0, r1, r2) +# define addi_d(r0, r1, i0) _addi_d(_jit, r0, r1, i0) +static void _addi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define subr_d(r0, r1, r2) FSUB_D(r0, r1, r2) +# define subi_d(r0, r1, i0) _subi_d(_jit, r0, r1, i0) +static void _subi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define rsbr_d(r0, r1, r2) FSUB_D(r0, r2, r1) +# define rsbi_d(r0, r1, i0) _rsbi_d(_jit, r0, r1, i0) +static void _rsbi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define mulr_d(r0, r1, r2) FMUL_D(r0, r1, r2) +# define muli_d(r0, r1, i0) _muli_d(_jit, r0, r1, i0) +static void _muli_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define divr_d(r0, r1, r2) FDIV_D(r0, r1, r2) +# define divi_d(r0, r1, i0) _divi_d(_jit, r0, r1, i0) +static void _divi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define absr_d(r0, r1) FABS_D(r0, r1) +# define negr_d(r0, r1) FNEG_D(r0, r1) +# define sqrtr_d(r0, r1) FSQRT_D(r0, r1) +# define extr_d(r0, r1) _extr_d(_jit, r0, r1) +static void _extr_d(jit_state_t*, jit_int32_t, jit_int32_t); +# define ldr_d(r0, r1) FLD_D(r0, r1, 0) +# define ldi_d(r0, i0) _ldi_d(_jit, r0, i0) +static void _ldi_d(jit_state_t*, jit_int32_t, jit_word_t); +# define ldxr_d(r0, r1, r2) FLDX_D(r0, r1, r2) +# define ldxi_d(r0, r1, i0) _ldxi_d(_jit, r0, r1, i0) +static void _ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t); +# define str_d(r0, r1) FST_D(r1, r0, 0) +# define sti_d(i0, r0) _sti_d(_jit, i0, r0) +static void _sti_d(jit_state_t*, jit_word_t, jit_int32_t); +# define stxr_d(r0, r1, r2) FSTX_D(r2, r1, r0) +# define stxi_d(i0, r0, r1) _stxi_d(_jit, i0, r0, r1) +static void _stxi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define movr_d(r0, r1) FMOV_D(r0, r1) +# define movi_d(r0, i0) _movi_d(_jit, r0, i0) +static void _movi_d(jit_state_t*, jit_int32_t, jit_float64_t); +# define movr_d_w(r0, r1) MOVFR2GR_D(r0, r1) +# define movi_d_w(r0, im) _movi_d_w(_jit, r0, im) +static void _movi_d_w(jit_state_t*, jit_int32_t, jit_float64_t); +# define movr_w_d(r0, r1) MOVGR2FR_D(r0, r1) +# define extr_f_d(r0, r1) FCVT_D_S(r0, r1) +# define ltr_d(r0, r1, r2) _ltr_d(_jit, r0, r1, r2) +static void _ltr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define lti_d(r0, r1, i0) _lti_d(_jit, r0, r1, i0) +static void _lti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define ler_d(r0, r1, r2) _ler_d(_jit, r0, r1, r2) +static void _ler_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define lei_d(r0, r1, i0) _lei_d(_jit, r0, r1, i0) +static void _lei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define eqr_d(r0, r1, r2) _eqr_d(_jit, r0, r1, r2) +static void _eqr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define eqi_d(r0, r1, i0) _eqi_d(_jit, r0, r1, i0) +static void _eqi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define ger_d(r0, r1, r2) _ger_d(_jit, r0, r1, r2) +static void _ger_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define gei_d(r0, r1, i0) _gei_d(_jit, r0, r1, i0) +static void _gei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define gtr_d(r0, r1, r2) _gtr_d(_jit, r0, r1, r2) +static void _gtr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define gti_d(r0, r1, i0) _gti_d(_jit, r0, r1, i0) +static void _gti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define ner_d(r0, r1, r2) _ner_d(_jit, r0, r1, r2) +static void _ner_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define nei_d(r0, r1, i0) _nei_d(_jit, r0, r1, i0) +static void _nei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define unltr_d(r0, r1, r2) _unltr_d(_jit, r0, r1, r2) +static void _unltr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define unlti_d(r0, r1, i0) _unlti_d(_jit, r0, r1, i0) +static void _unlti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define unler_d(r0, r1, r2) _unler_d(_jit, r0, r1, r2) +static void _unler_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define unlei_d(r0, r1, i0) _unlei_d(_jit, r0, r1, i0) +static void _unlei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define uneqr_d(r0, r1, r2) _uneqr_d(_jit, r0, r1, r2) +static void _uneqr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define uneqi_d(r0, r1, i0) _uneqi_d(_jit, r0, r1, i0) +static void _uneqi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define unger_d(r0, r1, r2) _unger_d(_jit, r0, r1, r2) +static void _unger_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ungei_d(r0, r1, i0) _ungei_d(_jit, r0, r1, i0) +static void _ungei_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define ungtr_d(r0, r1, r2) _ungtr_d(_jit, r0, r1, r2) +static void _ungtr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ungti_d(r0, r1, i0) _ungti_d(_jit, r0, r1, i0) +static void _ungti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define ltgtr_d(r0, r1, r2) _ltgtr_d(_jit, r0, r1, r2) +static void _ltgtr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ltgti_d(r0, r1, i0) _ltgti_d(_jit, r0, r1, i0) +static void _ltgti_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define ordr_d(r0, r1, r2) _ordr_d(_jit, r0, r1, r2) +static void _ordr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define ordi_d(r0, r1, i0) _ordi_d(_jit, r0, r1, i0) +static void _ordi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define unordr_d(r0, r1, r2) _unordr_d(_jit, r0, r1, r2) +static void _unordr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t); +# define unordi_d(r0, r1, i0) _unordi_d(_jit, r0, r1, i0) +static void _unordi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_float64_t); +# define bltr_d(i0, r0, r1) _bltr_d(_jit, i0, r0, r1) +static jit_word_t _bltr_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define blti_d(i0, r0, i1) _blti_d(_jit, i0, r0, i1) +static jit_word_t _blti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t); +# define bler_d(i0, r0, r1) _bler_d(_jit, i0, r0, r1) +static jit_word_t _bler_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define blei_d(i0, r0, i1) _blei_d(_jit, i0,r0, i1) +static jit_word_t _blei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t); +# define beqr_d(i0, r0, r1) _beqr_d(_jit, i0, r0, r1) +static jit_word_t _beqr_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define beqi_d(i0, r0, i1) _beqi_d(_jit, i0, r0, i1) +static jit_word_t _beqi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t); +# define bger_d(i0, r0, r1) _bger_d(_jit, i0, r0, r1) +static jit_word_t _bger_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bgei_d(i0, r0, i1) _bgei_d(_jit, i0, r0, i1) +static jit_word_t _bgei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t); +# define bgtr_d(i0, r0, r1) _bgtr_d(_jit, i0, r0, r1) +static jit_word_t _bgtr_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bgti_d(i0, r0, i1) _bgti_d(_jit, i0, r0, i1) +static jit_word_t _bgti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t); +# define bner_d(i0, r0, r1) _bner_d(_jit, i0, r0, r1) +static jit_word_t _bner_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bnei_d(i0, r0, i1) _bnei_d(_jit, i0, r0, i1) +static jit_word_t _bnei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t); +# define bunltr_d(i0, r0, r1) _bunltr_d(_jit, i0, r0, r1) +static jit_word_t _bunltr_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bunlti_d(i0, r0, i1) _bunlti_d(_jit, i0, r0, i1) +static jit_word_t _bunlti_d(jit_state_t*, jit_word_t,jit_int32_t,jit_float64_t); +# define bunler_d(i0, r0, r1) _bunler_d(_jit, i0, r0, r1) +static jit_word_t _bunler_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bunlei_d(i0, r0, i1) _bunlei_d(_jit, i0, r0, i1) +static jit_word_t _bunlei_d(jit_state_t*, jit_word_t,jit_int32_t,jit_float64_t); +# define buneqr_d(i0, r0, r1) _buneqr_d(_jit, i0, r0, r1) +static jit_word_t _buneqr_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define buneqi_d(i0, r0, i1) _buneqi_d(_jit, i0,r0, i1) +static jit_word_t _buneqi_d(jit_state_t*, jit_word_t,jit_int32_t,jit_float64_t); +# define bunger_d(i0, r0, r1) _bunger_d(_jit, i0, r0, r1) +static jit_word_t _bunger_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bungei_d(i0, r0, i1) _bungei_d(_jit, i0, r0, i1) +static jit_word_t _bungei_d(jit_state_t*, jit_word_t,jit_int32_t,jit_float64_t); +# define bungtr_d(i0, r0, r1) _bungtr_d(_jit, i0, r0, r1) +static jit_word_t _bungtr_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bungti_d(i0, r0, i1) _bungti_d(_jit, i0, r0, i1) +static jit_word_t _bungti_d(jit_state_t*, jit_word_t,jit_int32_t,jit_float64_t); +# define bltgtr_d(i0, r0, r1) _bltgtr_d(_jit, i0, r0, r1) +static jit_word_t _bltgtr_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bltgti_d(i0, r0, i1) _bltgti_d(_jit, i0, r0, i1) +static jit_word_t _bltgti_d(jit_state_t*, jit_word_t,jit_int32_t,jit_float64_t); +# define bordr_d(i0, r0, r1) _bordr_d(_jit, i0, r0, r1) +static jit_word_t _bordr_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); +# define bordi_d(i0, r0, i1) _bordi_d(_jit, i0, r0, i1) +static jit_word_t _bordi_d(jit_state_t*, jit_word_t, jit_int32_t,jit_float64_t); +# define bunordr_d(i0, r0, r1) _bunordr_d(_jit, i0, r0, r1) +static jit_word_t _bunordr_d(jit_state_t*, jit_word_t, jit_int32_t,jit_int32_t); +# define bunordi_d(i0, r0, i1) _bunordi_d(_jit, i0, r0, i1) +static jit_word_t _bunordi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t); +# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1) +static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t); +#endif /* PROTO */ + +#if CODE +static void +_truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg = jit_get_reg(jit_class_fpr); + FTINTRZ_W_S(rn(reg), r1); + MOVFR2GR_S(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg = jit_get_reg(jit_class_fpr); + FTINTRZ_W_D(rn(reg), r1); + MOVFR2GR_S(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_truncr_f_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg = jit_get_reg(jit_class_fpr); + FTINTRZ_L_S(rn(reg), r1); + MOVFR2GR_D(r0, rn(reg)); + jit_unget_reg(reg); +} + +static void +_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t reg = jit_get_reg(jit_class_fpr); + FTINTRZ_L_D(rn(reg), r1); + MOVFR2GR_D(r0, rn(reg)); + jit_unget_reg(reg); +} + +# define fpr_opi(name, type, size) \ +static void \ +_##name##i_##type(jit_state_t *_jit, \ + jit_int32_t r0, jit_int32_t r1, \ + jit_float##size##_t i0) \ +{ \ + jit_int32_t reg = jit_get_reg(jit_class_fpr); \ + movi_##type(rn(reg), i0); \ + name##r_##type(r0, r1, rn(reg)); \ + jit_unget_reg(reg); \ +} +# define fopi(name) fpr_opi(name, f, 32) +# define dopi(name) fpr_opi(name, d, 64) + +# define fpr_bopi(name, type, size) \ +static jit_word_t \ +_b##name##i_##type(jit_state_t *_jit, \ + jit_word_t i0, jit_int32_t r0, \ + jit_float##size##_t i1) \ +{ \ + jit_word_t word; \ + jit_int32_t reg = jit_get_reg(jit_class_fpr| \ + jit_class_nospill); \ + movi_##type(rn(reg), i1); \ + word = b##name##r_##type(i0, r0, rn(reg)); \ + jit_unget_reg(reg); \ + return (word); \ +} +# define fbopi(name) fpr_bopi(name, f, 32) +# define dbopi(name) fpr_bopi(name, d, 64) + +fopi(add) +fopi(sub) +fopi(rsb) +fopi(mul) +fopi(div) + +static void +_extr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + MOVGR2FR_D(r0, r1); + FFINT_S_L(r0, r0); +} + +static void +_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t t0; + if (can_sign_extend_si12_p(i0)) + FLD_S(r0, _ZERO_REGNO, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + ldr_f(r0, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + if (can_sign_extend_si12_p(i0)) + FLD_S(r0, r1, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + ldxr_f(r0, r1, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t t0; + if (can_sign_extend_si12_p(i0)) + FST_S(r0, _ZERO_REGNO, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + str_f(rn(t0), r0); + jit_unget_reg(t0); + } +} + +static void +_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + if (can_sign_extend_si12_p(i0)) + FST_S(r1, r0, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + stxr_f(rn(t0), r0, r1); + jit_unget_reg(t0); + } +} + +static void +_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + jit_int32_t reg; + data.f = i0; + if (data.i == 0) + movr_w_f(r0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.i); + movr_w_f(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_movi_f_w(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0) +{ + union { + jit_int32_t i; + jit_float32_t f; + } data; + data.f = i0; + movi(r0, data.i); +} + +static void +_ltr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_SLT_S(0, r1, r2); + MOVCF2GR(r0, 0); +} +fopi(lt) + +static void +_ler_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_SLE_S(0, r1, r2); + MOVCF2GR(r0, 0); +} +fopi(le) + +static void +_eqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CEQ_S(0, r1, r2); + MOVCF2GR(r0, 0); +} +fopi(eq) + +static void +_ger_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_SLE_S(0, r2, r1); + MOVCF2GR(r0, 0); +} +fopi(ge) + +static void +_gtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_SLT_S(0, r2, r1); + MOVCF2GR(r0, 0); +} +fopi(gt) + +static void +_ner_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CUNE_S(0, r1, r2); + MOVCF2GR(r0, 0); +} +fopi(ne) + +static void +_unltr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CULT_S(0, r1, r2); + MOVCF2GR(r0, 0); +} +fopi(unlt) + +static void +_unler_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CULE_S(0, r1, r2); + MOVCF2GR(r0, 0); +} +fopi(unle) + +static void +_uneqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CUEQ_S(0, r1, r2); + MOVCF2GR(r0, 0); +} +fopi(uneq) + +static void +_unger_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CULE_S(0, r2, r1); + MOVCF2GR(r0, 0); +} +fopi(unge) + +static void +_ungtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CULT_S(0, r2, r1); + MOVCF2GR(r0, 0); +} +fopi(ungt) + +static void +_ltgtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CNE_S(0, r1, r2); + MOVCF2GR(r0, 0); +} +fopi(ltgt) + +static void +_ordr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_COR_S(0, r1, r2); + MOVCF2GR(r0, 0); +} +fopi(ord) + +static void +_unordr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_COR_S(0, r1, r2); + MOVCF2GR(r0, 0); + XORI(r0, r0, 1); +} +fopi(unord) + +static jit_word_t +_bltr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_SLT_S(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(lt) + +static jit_word_t +_bler_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_SLE_S(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(le) + +static jit_word_t +_beqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CEQ_S(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(eq) + +static jit_word_t +_bger_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_SLE_S(0, r2, r1); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(ge) + +static jit_word_t +_bgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_SLT_S(0, r2, r1); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(gt) + +static jit_word_t +_bner_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CUNE_S(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(ne) + +static jit_word_t +_bunltr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CULT_S(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(unlt) + +static jit_word_t +_bunler_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CULE_S(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(unle) + +static jit_word_t +_buneqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CUEQ_S(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(uneq) + +static jit_word_t +_bunger_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CULE_S(0, r2, r1); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(unge) + +static jit_word_t +_bungtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CULT_S(0, r2, r1); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(ungt) + +static jit_word_t +_bltgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CNE_S(0, r2, r1); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(ltgt) + +static jit_word_t +_bordr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_COR_S(0, r2, r1); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(ord) + +static jit_word_t +_bunordr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_COR_S(0, r2, r1); + w = _jit->pc.w; + BCEQZ(0, (i0 - w) >> 2); + return (w); +} +fbopi(unord) + +dopi(add) +dopi(sub) +dopi(rsb) +dopi(mul) +dopi(div) + +static void +_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + MOVGR2FR_D(r0, r1); + FFINT_D_L(r0, r0); +} + +static void +_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0) +{ + jit_int32_t t0; + if (can_sign_extend_si12_p(i0)) + FLD_D(r0, _ZERO_REGNO, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + ldr_d(r0, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + jit_int32_t t0; + if (can_sign_extend_si12_p(i0)) + FLD_D(r0, r1, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + ldxr_d(r0, r1, rn(t0)); + jit_unget_reg(t0); + } +} + +static void +_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0) +{ + jit_int32_t t0; + if (can_sign_extend_si12_p(i0)) + FST_D(r0, _ZERO_REGNO, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + str_d(rn(t0), r0); + jit_unget_reg(t0); + } +} + +static void +_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + jit_int32_t t0; + if (can_sign_extend_si12_p(i0)) + FST_D(r1, r0, i0); + else { + t0 = jit_get_reg(jit_class_gpr); + movi(rn(t0), i0); + stxr_d(rn(t0), r0, r1); + jit_unget_reg(t0); + } +} + +static void +_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0) +{ + union { + jit_word_t w; + jit_float64_t d; + } data; + jit_int32_t reg; + data.d = i0; + if (data.w == 0) + movr_w_d(r0, _ZERO_REGNO); + else { + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), data.w); + movr_w_d(r0, rn(reg)); + jit_unget_reg(reg); + } +} + +static void +_movi_d_w(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0) +{ + union { + jit_int64_t l; + jit_float64_t d; + } data; + data.d = i0; + movi(r0, data.l); +} + +static void +_ltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_SLT_D(0, r1, r2); + MOVCF2GR(r0, 0); +} +dopi(lt) + +static void +_ler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_SLE_D(0, r1, r2); + MOVCF2GR(r0, 0); +} +dopi(le) + +static void +_eqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CEQ_D(0, r1, r2); + MOVCF2GR(r0, 0); +} +dopi(eq) + +static void +_ger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_SLE_D(0, r2, r1); + MOVCF2GR(r0, 0); +} +dopi(ge) + +static void +_gtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_SLT_D(0, r2, r1); + MOVCF2GR(r0, 0); +} +dopi(gt) + +static void +_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CUNE_D(0, r1, r2); + MOVCF2GR(r0, 0); +} +dopi(ne) + +static void +_unltr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CULT_D(0, r1, r2); + MOVCF2GR(r0, 0); +} +dopi(unlt) + +static void +_unler_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CULE_D(0, r1, r2); + MOVCF2GR(r0, 0); +} +dopi(unle) + +static void +_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CUEQ_D(0, r1, r2); + MOVCF2GR(r0, 0); +} +dopi(uneq) + +static void +_unger_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CULE_D(0, r2, r1); + MOVCF2GR(r0, 0); +} +dopi(unge) + +static void +_ungtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CULT_D(0, r2, r1); + MOVCF2GR(r0, 0); +} +dopi(ungt) + +static void +_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_CNE_D(0, r1, r2); + MOVCF2GR(r0, 0); +} +dopi(ltgt) + +static void +_ordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_COR_D(0, r1, r2); + MOVCF2GR(r0, 0); +} +dopi(ord) + +static void +_unordr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) +{ + FCMP_COR_D(0, r1, r2); + MOVCF2GR(r0, 0); + XORI(r0, r0, 1); +} +dopi(unord) + +static jit_word_t +_bltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_SLT_D(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(lt) + +static jit_word_t +_bler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_SLE_D(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(le) + +static jit_word_t +_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CEQ_D(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(eq) + +static jit_word_t +_bger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_SLE_D(0, r2, r1); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(ge) + +static jit_word_t +_bgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_SLT_D(0, r2, r1); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(gt) + +static jit_word_t +_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CUNE_D(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(ne) + +static jit_word_t +_bunltr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CULT_D(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(unlt) + +static jit_word_t +_bunler_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CULE_D(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(unle) + +static jit_word_t +_buneqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CUEQ_D(0, r1, r2); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(uneq) + +static jit_word_t +_bunger_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CULE_D(0, r2, r1); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(unge) + +static jit_word_t +_bungtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CULT_D(0, r2, r1); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(ungt) + +static jit_word_t +_bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_CNE_D(0, r2, r1); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(ltgt) + +static jit_word_t +_bordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_COR_D(0, r2, r1); + w = _jit->pc.w; + BCNEZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(ord) + +static jit_word_t +_bunordr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r1, jit_int32_t r2) +{ + jit_word_t w; + FCMP_COR_D(0, r2, r1); + w = _jit->pc.w; + BCEQZ(0, (i0 - w) >> 2); + return (w); +} +dbopi(unord) + +static void +_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +{ + assert(_jitc->function->self.call & jit_call_varargs); + /* Load argument. */ + ldr_d(r0, r1); + /* Update va_list. */ + addi(r1, r1, sizeof(jit_float64_t)); +} + +#endif /* CODE */ diff --git a/deps/lightning/lib/jit_loongarch-sz.c b/deps/lightning/lib/jit_loongarch-sz.c new file mode 100644 index 00000000..2490cfa4 --- /dev/null +++ b/deps/lightning/lib/jit_loongarch-sz.c @@ -0,0 +1,408 @@ +#if __WORDSIZE == 64 +#define JIT_INSTR_MAX 88 + 0, /* data */ + 0, /* live */ + 28, /* align */ + 0, /* save */ + 0, /* load */ + 0, /* #name */ + 0, /* #note */ + 0, /* label */ + 88, /* prolog */ + 0, /* ellipsis */ + 0, /* va_push */ + 0, /* allocai */ + 0, /* allocar */ + 0, /* arg */ + 0, /* getarg_c */ + 0, /* getarg_uc */ + 0, /* getarg_s */ + 0, /* getarg_us */ + 0, /* getarg_i */ + 0, /* getarg_ui */ + 0, /* getarg_l */ + 0, /* putargr */ + 0, /* putargi */ + 4, /* va_start */ + 8, /* va_arg */ + 8, /* va_arg_d */ + 0, /* va_end */ + 4, /* addr */ + 20, /* addi */ + 12, /* addcr */ + 28, /* addci */ + 28, /* addxr */ + 28, /* addxi */ + 4, /* subr */ + 20, /* subi */ + 12, /* subcr */ + 28, /* subci */ + 28, /* subxr */ + 28, /* subxi */ + 24, /* rsbi */ + 4, /* mulr */ + 20, /* muli */ + 12, /* qmulr */ + 24, /* qmuli */ + 12, /* qmulr_u */ + 24, /* qmuli_u */ + 4, /* divr */ + 20, /* divi */ + 4, /* divr_u */ + 20, /* divi_u */ + 12, /* qdivr */ + 12, /* qdivi */ + 12, /* qdivr_u */ + 12, /* qdivi_u */ + 4, /* remr */ + 20, /* remi */ + 4, /* remr_u */ + 20, /* remi_u */ + 4, /* andr */ + 20, /* andi */ + 4, /* orr */ + 20, /* ori */ + 4, /* xorr */ + 20, /* xori */ + 4, /* lshr */ + 4, /* lshi */ + 4, /* rshr */ + 4, /* rshi */ + 4, /* rshr_u */ + 4, /* rshi_u */ + 4, /* negr */ + 4, /* comr */ + 4, /* ltr */ + 4, /* lti */ + 4, /* ltr_u */ + 4, /* lti_u */ + 8, /* ler */ + 4, /* lei */ + 8, /* ler_u */ + 4, /* lei_u */ + 12, /* eqr */ + 12, /* eqi */ + 8, /* ger */ + 8, /* gei */ + 8, /* ger_u */ + 8, /* gei_u */ + 4, /* gtr */ + 8, /* gti */ + 4, /* gtr_u */ + 8, /* gti_u */ + 8, /* ner */ + 8, /* nei */ + 4, /* movr */ + 16, /* movi */ + 12, /* movnr */ + 12, /* movzr */ + 4, /* extr_c */ + 4, /* extr_uc */ + 4, /* extr_s */ + 4, /* extr_us */ + 4, /* extr_i */ + 4, /* extr_ui */ + 8, /* htonr_us */ + 8, /* htonr_ui */ + 4, /* htonr_ul */ + 4, /* ldr_c */ + 16, /* ldi_c */ + 4, /* ldr_uc */ + 16, /* ldi_uc */ + 4, /* ldr_s */ + 16, /* ldi_s */ + 4, /* ldr_us */ + 16, /* ldi_us */ + 4, /* ldr_i */ + 16, /* ldi_i */ + 4, /* ldr_ui */ + 16, /* ldi_ui */ + 4, /* ldr_l */ + 16, /* ldi_l */ + 4, /* ldxr_c */ + 16, /* ldxi_c */ + 4, /* ldxr_uc */ + 16, /* ldxi_uc */ + 4, /* ldxr_s */ + 16, /* ldxi_s */ + 4, /* ldxr_us */ + 16, /* ldxi_us */ + 4, /* ldxr_i */ + 16, /* ldxi_i */ + 4, /* ldxr_ui */ + 16, /* ldxi_ui */ + 4, /* ldxr_l */ + 16, /* ldxi_l */ + 4, /* str_c */ + 16, /* sti_c */ + 4, /* str_s */ + 16, /* sti_s */ + 4, /* str_i */ + 16, /* sti_i */ + 4, /* str_l */ + 16, /* sti_l */ + 4, /* stxr_c */ + 16, /* stxi_c */ + 4, /* stxr_s */ + 16, /* stxi_s */ + 4, /* stxr_i */ + 16, /* stxi_i */ + 4, /* stxr_l */ + 16, /* stxi_l */ + 4, /* bltr */ + 8, /* blti */ + 4, /* bltr_u */ + 8, /* blti_u */ + 8, /* bler */ + 12, /* blei */ + 8, /* bler_u */ + 12, /* blei_u */ + 4, /* beqr */ + 20, /* beqi */ + 4, /* bger */ + 8, /* bgei */ + 4, /* bger_u */ + 8, /* bgei_u */ + 8, /* bgtr */ + 12, /* bgti */ + 8, /* bgtr_u */ + 12, /* bgti_u */ + 4, /* bner */ + 20, /* bnei */ + 8, /* bmsr */ + 8, /* bmsi */ + 8, /* bmcr */ + 8, /* bmci */ + 32, /* boaddr */ + 36, /* boaddi */ + 16, /* boaddr_u */ + 20, /* boaddi_u */ + 32, /* bxaddr */ + 36, /* bxaddi */ + 16, /* bxaddr_u */ + 20, /* bxaddi_u */ + 32, /* bosubr */ + 36, /* bosubi */ + 16, /* bosubr_u */ + 20, /* bosubi_u */ + 32, /* bxsubr */ + 36, /* bxsubi */ + 16, /* bxsubr_u */ + 20, /* bxsubi_u */ + 4, /* jmpr */ + 20, /* jmpi */ + 4, /* callr */ + 20, /* calli */ + 0, /* prepare */ + 0, /* pushargr */ + 0, /* pushargi */ + 0, /* finishr */ + 0, /* finishi */ + 0, /* ret */ + 0, /* retr */ + 0, /* reti */ + 0, /* retval_c */ + 0, /* retval_uc */ + 0, /* retval_s */ + 0, /* retval_us */ + 0, /* retval_i */ + 0, /* retval_ui */ + 0, /* retval_l */ + 88, /* epilog */ + 0, /* arg_f */ + 0, /* getarg_f */ + 0, /* putargr_f */ + 0, /* putargi_f */ + 4, /* addr_f */ + 12, /* addi_f */ + 4, /* subr_f */ + 12, /* subi_f */ + 12, /* rsbi_f */ + 4, /* mulr_f */ + 12, /* muli_f */ + 4, /* divr_f */ + 12, /* divi_f */ + 4, /* negr_f */ + 4, /* absr_f */ + 4, /* sqrtr_f */ + 8, /* ltr_f */ + 16, /* lti_f */ + 8, /* ler_f */ + 16, /* lei_f */ + 8, /* eqr_f */ + 16, /* eqi_f */ + 8, /* ger_f */ + 16, /* gei_f */ + 8, /* gtr_f */ + 16, /* gti_f */ + 8, /* ner_f */ + 16, /* nei_f */ + 8, /* unltr_f */ + 16, /* unlti_f */ + 8, /* unler_f */ + 16, /* unlei_f */ + 8, /* uneqr_f */ + 16, /* uneqi_f */ + 8, /* unger_f */ + 16, /* ungei_f */ + 8, /* ungtr_f */ + 16, /* ungti_f */ + 8, /* ltgtr_f */ + 16, /* ltgti_f */ + 8, /* ordr_f */ + 16, /* ordi_f */ + 12, /* unordr_f */ + 20, /* unordi_f */ + 8, /* truncr_f_i */ + 8, /* truncr_f_l */ + 8, /* extr_f */ + 4, /* extr_d_f */ + 4, /* movr_f */ + 8, /* movi_f */ + 4, /* ldr_f */ + 16, /* ldi_f */ + 4, /* ldxr_f */ + 16, /* ldxi_f */ + 4, /* str_f */ + 16, /* sti_f */ + 4, /* stxr_f */ + 16, /* stxi_f */ + 8, /* bltr_f */ + 16, /* blti_f */ + 8, /* bler_f */ + 16, /* blei_f */ + 8, /* beqr_f */ + 16, /* beqi_f */ + 8, /* bger_f */ + 16, /* bgei_f */ + 8, /* bgtr_f */ + 16, /* bgti_f */ + 8, /* bner_f */ + 16, /* bnei_f */ + 8, /* bunltr_f */ + 16, /* bunlti_f */ + 8, /* bunler_f */ + 16, /* bunlei_f */ + 8, /* buneqr_f */ + 16, /* buneqi_f */ + 8, /* bunger_f */ + 16, /* bungei_f */ + 8, /* bungtr_f */ + 16, /* bungti_f */ + 8, /* bltgtr_f */ + 16, /* bltgti_f */ + 8, /* bordr_f */ + 16, /* bordi_f */ + 8, /* bunordr_f */ + 16, /* bunordi_f */ + 0, /* pushargr_f */ + 0, /* pushargi_f */ + 0, /* retr_f */ + 0, /* reti_f */ + 0, /* retval_f */ + 0, /* arg_d */ + 0, /* getarg_d */ + 0, /* putargr_d */ + 0, /* putargi_d */ + 4, /* addr_d */ + 20, /* addi_d */ + 4, /* subr_d */ + 20, /* subi_d */ + 16, /* rsbi_d */ + 4, /* mulr_d */ + 20, /* muli_d */ + 4, /* divr_d */ + 20, /* divi_d */ + 4, /* negr_d */ + 4, /* absr_d */ + 4, /* sqrtr_d */ + 8, /* ltr_d */ + 24, /* lti_d */ + 8, /* ler_d */ + 24, /* lei_d */ + 8, /* eqr_d */ + 24, /* eqi_d */ + 8, /* ger_d */ + 24, /* gei_d */ + 8, /* gtr_d */ + 24, /* gti_d */ + 8, /* ner_d */ + 24, /* nei_d */ + 8, /* unltr_d */ + 24, /* unlti_d */ + 8, /* unler_d */ + 24, /* unlei_d */ + 8, /* uneqr_d */ + 24, /* uneqi_d */ + 8, /* unger_d */ + 24, /* ungei_d */ + 8, /* ungtr_d */ + 24, /* ungti_d */ + 8, /* ltgtr_d */ + 24, /* ltgti_d */ + 8, /* ordr_d */ + 24, /* ordi_d */ + 12, /* unordr_d */ + 28, /* unordi_d */ + 8, /* truncr_d_i */ + 8, /* truncr_d_l */ + 8, /* extr_d */ + 4, /* extr_f_d */ + 4, /* movr_d */ + 16, /* movi_d */ + 4, /* ldr_d */ + 16, /* ldi_d */ + 4, /* ldxr_d */ + 16, /* ldxi_d */ + 4, /* str_d */ + 16, /* sti_d */ + 4, /* stxr_d */ + 16, /* stxi_d */ + 8, /* bltr_d */ + 20, /* blti_d */ + 8, /* bler_d */ + 20, /* blei_d */ + 8, /* beqr_d */ + 24, /* beqi_d */ + 8, /* bger_d */ + 24, /* bgei_d */ + 8, /* bgtr_d */ + 24, /* bgti_d */ + 8, /* bner_d */ + 24, /* bnei_d */ + 8, /* bunltr_d */ + 24, /* bunlti_d */ + 8, /* bunler_d */ + 24, /* bunlei_d */ + 8, /* buneqr_d */ + 24, /* buneqi_d */ + 8, /* bunger_d */ + 24, /* bungei_d */ + 8, /* bungtr_d */ + 24, /* bungti_d */ + 8, /* bltgtr_d */ + 24, /* bltgti_d */ + 8, /* bordr_d */ + 20, /* bordi_d */ + 8, /* bunordr_d */ + 24, /* bunordi_d */ + 0, /* pushargr_d */ + 0, /* pushargi_d */ + 0, /* retr_d */ + 0, /* reti_d */ + 0, /* retval_d */ + 4, /* movr_w_f */ + 0, /* movr_ww_d */ + 4, /* movr_w_d */ + 0, /* movr_f_w */ + 4, /* movi_f_w */ + 0, /* movr_d_ww */ + 0, /* movi_d_ww */ + 4, /* movr_d_w */ + 12, /* movi_d_w */ + 8, /* bswapr_us */ + 8, /* bswapr_ui */ + 4, /* bswapr_ul */ + 32, /* casr */ + 44, /* casi */ +#endif /* __WORDSIZE */ diff --git a/deps/lightning/lib/jit_loongarch.c b/deps/lightning/lib/jit_loongarch.c new file mode 100644 index 00000000..78fac470 --- /dev/null +++ b/deps/lightning/lib/jit_loongarch.c @@ -0,0 +1,1623 @@ +/* + * Copyright (C) 2022 Free Software Foundation, Inc. + * + * This file is part of GNU lightning. + * + * GNU lightning is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU lightning is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 8) +#define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 8) + +/* + * Types + */ +typedef struct jit_pointer_t jit_va_list_t; + +/* + * Prototypes + */ +#define patch(instr, node) _patch(_jit, instr, node) +static void _patch(jit_state_t*,jit_word_t,jit_node_t*); + +#define PROTO 1 +# include "jit_loongarch-cpu.c" +# include "jit_loongarch-fpu.c" +#undef PROTO + +/* + * Initialization + */ +jit_register_t _rvs[] = { + { rc(gpr) | 0x14, "$t8" }, + { rc(gpr) | 0x13, "$t7" }, + { rc(gpr) | 0x12, "$t6" }, + { rc(gpr) | 0x11, "$t5" }, + { rc(gpr) | 0x10, "$t4" }, + { rc(gpr) | 0x0f, "$t3" }, + { rc(gpr) | 0x0e, "$t2" }, + { rc(gpr) | 0x0d, "$t1" }, + { rc(gpr) | 0x0c, "$t0" }, + { rc(sav) | rc(gpr) | 0x1f, "$s8" }, + { rc(sav) | rc(gpr) | 0x1e, "$s7" }, + { rc(sav) | rc(gpr) | 0x1d, "$s6" }, + { rc(sav) | rc(gpr) | 0x1c, "$s5" }, + { rc(sav) | rc(gpr) | 0x1b, "$s4" }, + { rc(sav) | rc(gpr) | 0x1a, "$s3" }, + { rc(sav) | rc(gpr) | 0x19, "$s2" }, + { rc(sav) | rc(gpr) | 0x18, "$s1" }, + { rc(sav) | rc(gpr) | 0x17, "$s0" }, + { rc(arg) | rc(gpr) | 0x0b, "$a7" }, + { rc(arg) | rc(gpr) | 0x0a, "$a6" }, + { rc(arg) | rc(gpr) | 0x09, "$a5" }, + { rc(arg) | rc(gpr) | 0x08, "$a4" }, + { rc(arg) | rc(gpr) | 0x07, "$a3" }, + { rc(arg) | rc(gpr) | 0x06, "$a2" }, + { rc(arg) | rc(gpr) | 0x05, "$a1" }, + { rc(arg) | rc(gpr) | 0x04, "$a0" }, + { 0x16, "$fp" }, + { 0x15, "" }, + { 0x00, "$zero" }, + { 0x01, "$ra" }, + { 0x02, "$tp" }, + { 0x03, "$sp" }, + { rc(fpr) | 0x08, "$ft0" }, + { rc(fpr) | 0x09, "$ft1" }, + { rc(fpr) | 0x0a, "$ft2" }, + { rc(fpr) | 0x0b, "$ft3" }, + { rc(fpr) | 0x0c, "$ft4" }, + { rc(fpr) | 0x0d, "$ft5" }, + { rc(fpr) | 0x0e, "$ft6" }, + { rc(fpr) | 0x0f, "$ft7" }, + { rc(fpr) | 0x10, "$ft8" }, + { rc(fpr) | 0x11, "$ft9" }, + { rc(fpr) | 0x12, "$ft10" }, + { rc(fpr) | 0x13, "$ft11" }, + { rc(fpr) | 0x14, "$ft12" }, + { rc(fpr) | 0x15, "$ft13" }, + { rc(fpr) | 0x16, "$ft14" }, + { rc(fpr) | 0x17, "$ft15" }, + { rc(arg) | rc(fpr) | 0x07, "$fa7" }, + { rc(arg) | rc(fpr) | 0x06, "$fa6" }, + { rc(arg) | rc(fpr) | 0x05, "$fa5" }, + { rc(arg) | rc(fpr) | 0x04, "$fa4" }, + { rc(arg) | rc(fpr) | 0x03, "$fa3" }, + { rc(arg) | rc(fpr) | 0x02, "$fa2" }, + { rc(arg) | rc(fpr) | 0x01, "$fa1" }, + { rc(arg) | rc(fpr) | 0x00, "$fa0" }, + { rc(sav) | rc(fpr) | 0x1f, "$fs7" }, + { rc(sav) | rc(fpr) | 0x1e, "$fs6" }, + { rc(sav) | rc(fpr) | 0x1d, "$fs5" }, + { rc(sav) | rc(fpr) | 0x1c, "$fs4" }, + { rc(sav) | rc(fpr) | 0x1b, "$fs3" }, + { rc(sav) | rc(fpr) | 0x1a, "$fs2" }, + { rc(sav) | rc(fpr) | 0x19, "$fs1" }, + { rc(sav) | rc(fpr) | 0x18, "$fs0" }, + { _NOREG, "" }, +}; + +/* + * Implementation + */ +void +jit_get_cpu(void) +{ +} + +void +_jit_init(jit_state_t *_jit) +{ + _jitc->reglen = jit_size(_rvs) - 1; + jit_carry = _NOREG; +} + +void +_jit_prolog(jit_state_t *_jit) +{ + jit_int32_t offset; + + if (_jitc->function) + jit_epilog(); + assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0); + jit_regset_set_ui(&_jitc->regsav, 0); + offset = _jitc->functions.offset; + if (offset >= _jitc->functions.length) { + jit_realloc((jit_pointer_t *)&_jitc->functions.ptr, + _jitc->functions.length * sizeof(jit_function_t), + (_jitc->functions.length + 16) * sizeof(jit_function_t)); + _jitc->functions.length += 16; + } + _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++; + _jitc->function->self.size = stack_framesize; + _jitc->function->self.argi = _jitc->function->self.argf = + _jitc->function->self.aoff = _jitc->function->self.alen = 0; + _jitc->function->self.call = jit_call_default; + jit_alloc((jit_pointer_t *)&_jitc->function->regoff, + _jitc->reglen * sizeof(jit_int32_t)); + + /* _no_link here does not mean the jit_link() call can be removed + * by rewriting as: + * _jitc->function->prolog = jit_new_node(jit_code_prolog); + */ + _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog); + jit_link(_jitc->function->prolog); + _jitc->function->prolog->w.w = offset; + _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog); + /* u: label value + * v: offset in blocks vector + * w: offset in functions vector + */ + _jitc->function->epilog->w.w = offset; + + jit_regset_new(&_jitc->function->regset); +} + +jit_int32_t +_jit_allocai(jit_state_t *_jit, jit_int32_t length) +{ + assert(_jitc->function); + switch (length) { + case 0: case 1: break; + case 2: _jitc->function->self.aoff &= -2; break; + case 3: case 4: _jitc->function->self.aoff &= -4; break; + default: _jitc->function->self.aoff &= -8; break; + } + _jitc->function->self.aoff -= length; + if (!_jitc->realize) { + jit_inc_synth_ww(allocai, _jitc->function->self.aoff, length); + jit_dec_synth(); + } + return (_jitc->function->self.aoff); +} + +void +_jit_allocar(jit_state_t *_jit, jit_int32_t u, jit_int32_t v) +{ + jit_int32_t reg; + assert(_jitc->function); + jit_inc_synth_ww(allocar, u, v); + if (!_jitc->function->allocar) { + _jitc->function->aoffoff = jit_allocai(sizeof(jit_int32_t)); + _jitc->function->allocar = 1; + } + reg = jit_get_reg(jit_class_gpr); + jit_negr(reg, v); + jit_andi(reg, reg, -16); + jit_ldxi_i(u, JIT_FP, _jitc->function->aoffoff); + jit_addr(u, u, reg); + jit_addr(JIT_SP, JIT_SP, reg); + jit_stxi_i(_jitc->function->aoffoff, JIT_FP, u); + jit_unget_reg(reg); + jit_dec_synth(); +} + +void +_jit_ret(jit_state_t *_jit) +{ + jit_node_t *instr; + assert(_jitc->function); + jit_inc_synth(ret); + /* jump to epilog */ + instr = jit_jmpi(); + jit_patch_at(instr, _jitc->function->epilog); + jit_dec_synth(); +} + +void +_jit_retr(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr, u); + if (JIT_RET != u) + jit_movr(JIT_RET, u); + jit_live(JIT_RET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti(jit_state_t *_jit, jit_word_t u) +{ + jit_inc_synth_w(reti, u); + jit_movi(JIT_RET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_f(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_f, u); + if (JIT_FRET != u) + jit_movr_f(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_inc_synth_f(reti_f, u); + jit_movi_f(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_retr_d(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(retr_d, u); + if (JIT_FRET != u) + jit_movr_d(JIT_FRET, u); + else + jit_live(JIT_FRET); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_reti_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_inc_synth_d(reti_d, u); + jit_movi_d(JIT_FRET, u); + jit_ret(); + jit_dec_synth(); +} + +void +_jit_epilog(jit_state_t *_jit) +{ + assert(_jitc->function); + assert(_jitc->function->epilog->next == NULL); + jit_link(_jitc->function->epilog); + _jitc->function = NULL; +} + +jit_bool_t +_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u) +{ + if (u->code == jit_code_arg) + return (jit_arg_reg_p(u->u.w)); + assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d); + return (jit_arg_f_reg_p(u->u.w)); +} + +void +_jit_ellipsis(jit_state_t *_jit) +{ + jit_inc_synth(ellipsis); + if (_jitc->prepare) { + jit_link_prepare(); + assert(!(_jitc->function->call.call & jit_call_varargs)); + _jitc->function->call.call |= jit_call_varargs; + } + else { + jit_link_prolog(); + assert(!(_jitc->function->self.call & jit_call_varargs)); + _jitc->function->self.call |= jit_call_varargs; + _jitc->function->vagp = _jitc->function->self.argi; + } + jit_dec_synth(); +} + +void +_jit_va_push(jit_state_t *_jit, jit_int32_t u) +{ + jit_inc_synth_w(va_push, u); + jit_pushargr(u); + jit_dec_synth(); +} + +jit_node_t * +_jit_arg(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + assert(!(_jitc->function->self.call & jit_call_varargs)); + if (jit_arg_reg_p(_jitc->function->self.argi)) + offset = _jitc->function->self.argi++; + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_f(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + assert(!(_jitc->function->self.call & jit_call_varargs)); + if (jit_arg_f_reg_p(_jitc->function->self.argf)) + offset = _jitc->function->self.argf++; + else if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi++; + offset += 8; + } + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg_f, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +jit_node_t * +_jit_arg_d(jit_state_t *_jit) +{ + jit_node_t *node; + jit_int32_t offset; + assert(_jitc->function); + assert(!(_jitc->function->self.call & jit_call_varargs)); + if (jit_arg_f_reg_p(_jitc->function->self.argf)) + offset = _jitc->function->self.argf++; + else if (jit_arg_reg_p(_jitc->function->self.argi)) { + offset = _jitc->function->self.argi++; + offset += 8; + } + else { + offset = _jitc->function->self.size; + _jitc->function->self.size += sizeof(jit_word_t); + } + node = jit_new_node_ww(jit_code_arg_d, offset, + ++_jitc->function->self.argn); + jit_link_prolog(); + return (node); +} + +void +_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_c, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_c(u, _A0 - v->u.w); + else + jit_ldxi_c(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_uc, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_uc(u, _A0 - v->u.w); + else + jit_ldxi_uc(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_s, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_s(u, _A0 - v->u.w); + else + jit_ldxi_s(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_us, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_us(u, _A0 - v->u.w); + else + jit_ldxi_us(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_i, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_i(u, _A0 - v->u.w); + else + jit_ldxi_i(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_ui, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_extr_ui(u, _A0 - v->u.w); + else + jit_ldxi_ui(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(getarg_l, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(u, _A0 - v->u.w); + else + jit_ldxi_l(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargr, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movr(_A0 - v->u.w, u); + else + jit_stxi(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg); + jit_inc_synth_wp(putargi, u, v); + if (jit_arg_reg_p(v->u.w)) + jit_movi(_A0 - v->u.w, u); + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(getarg_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_f(u, _FA0 - v->u.w); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_w_f(u, JIT_RA0 - (v->u.w - 8)); + else + jit_ldxi_f(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_f); + jit_inc_synth_wp(putargr_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_f(_FA0 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_f_w(JIT_RA0 - (v->u.w - 8), u); + else + jit_stxi_f(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_f); + jit_inc_synth_fp(putargi_f, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movi_f(_FA0 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) { + union { + jit_float32_t f; + jit_int32_t i; + } uu; + uu.f = u; + jit_movi(JIT_RA0 - (v->u.w - 8), uu.i); + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(getarg_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(u, _FA0 - v->u.w); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_w_d(u, JIT_RA0 - (v->u.w - 8)); + else + jit_ldxi_d(u, JIT_FP, v->u.w); + jit_dec_synth(); +} + +void +_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) +{ + assert(v->code == jit_code_arg_d); + jit_inc_synth_wp(putargr_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movr_d(_FA0 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_d_w(JIT_RA0 - (v->u.w - 8), u); + else + jit_stxi_d(v->u.w, JIT_FP, u); + jit_dec_synth(); +} + +void +_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) +{ + jit_int32_t regno; + assert(v->code == jit_code_arg_d); + jit_inc_synth_dp(putargi_d, u, v); + if (jit_arg_f_reg_p(v->u.w)) + jit_movi_d(_FA0 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) { + union { + jit_float64_t d; + jit_int64_t w; + } uu; + uu.d = u; + jit_movi(JIT_RA0 - (v->u.w - 8), uu.w); + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(v->u.w, JIT_FP, regno); + jit_unget_reg(regno); + } + jit_dec_synth(); +} + +void +_jit_pushargr(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi(jit_state_t *_jit, jit_word_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_w(pushargi, u); + jit_link_prepare(); + if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_gpr); + jit_movi(regno, u); + jit_stxi(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) && + !(_jitc->function->call.call & jit_call_varargs)) { + jit_movr_f(_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr_f_w(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi_f(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_f(pushargi_f, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) && + !(_jitc->function->call.call & jit_call_varargs)) { + jit_movi_f(_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi_f_w(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_stxi_f(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) +{ + assert(_jitc->function); + jit_inc_synth_w(pushargr_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) && + !(_jitc->function->call.call & jit_call_varargs)) { + jit_movr_d(_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movr_d_w(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + jit_stxi_d(_jitc->function->call.size, JIT_SP, u); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +void +_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) +{ + jit_int32_t regno; + assert(_jitc->function); + jit_inc_synth_d(pushargi_d, u); + jit_link_prepare(); + if (jit_arg_f_reg_p(_jitc->function->call.argf) && + !(_jitc->function->call.call & jit_call_varargs)) { + jit_movi_d(_FA0 - _jitc->function->call.argf, u); + ++_jitc->function->call.argf; + } + else if (jit_arg_reg_p(_jitc->function->call.argi)) { + jit_movi_d_w(_A0 - _jitc->function->call.argi, u); + ++_jitc->function->call.argi; + } + else { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_stxi_d(_jitc->function->call.size, JIT_SP, regno); + jit_unget_reg(regno); + _jitc->function->call.size += sizeof(jit_word_t); + } + jit_dec_synth(); +} + +jit_bool_t +_jit_regarg_p(jit_state_t *_jit, jit_node_t *node, jit_int32_t regno) +{ + jit_int32_t spec; + spec = jit_class(_rvs[regno].spec); + if (spec & jit_class_arg) { + regno = _A0 - regno; + if (regno >= 0 && regno < node->v.w) + return (1); + if (spec & jit_class_fpr) { + regno = _FA0 - regno; + if (regno >= 0 && regno < node->w.w) + return (1); + } + } + return (0); +} + +void +_jit_finishr(jit_state_t *_jit, jit_int32_t r0) +{ + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishr, r0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_callr(r0); + node->v.w = _jitc->function->call.argi; + node->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); +} + +jit_node_t * +_jit_finishi(jit_state_t *_jit, jit_pointer_t i0) +{ + jit_node_t *node; + assert(_jitc->function); + jit_inc_synth_w(finishi, (jit_word_t)i0); + if (_jitc->function->self.alen < _jitc->function->call.size) + _jitc->function->self.alen = _jitc->function->call.size; + node = jit_calli(i0); + node->v.w = _jitc->function->call.argi; + node->w.w = _jitc->function->call.argf; + _jitc->function->call.argi = _jitc->function->call.argf = + _jitc->function->call.size = 0; + _jitc->prepare = 0; + jit_dec_synth(); + return (node); +} + +void +_jit_retval_c(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_c, r0); + jit_extr_c(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_uc(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_uc, r0); + jit_extr_uc(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_s(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_s, r0); + jit_extr_s(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_us(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_us, r0); + jit_extr_us(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_i(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_i, r0); + jit_extr_i(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_ui(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_ui, r0); + jit_extr_ui(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_l(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_l, r0); + if (r0 != JIT_RET) + jit_movr(r0, JIT_RET); + jit_dec_synth(); +} + +void +_jit_retval_f(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_f, r0); + if (r0 != JIT_FRET) + jit_movr_f(r0, JIT_FRET); + jit_dec_synth(); +} + +void +_jit_retval_d(jit_state_t *_jit, jit_int32_t r0) +{ + jit_inc_synth_w(retval_d, r0); + if (r0 != JIT_FRET) + jit_movr_d(r0, JIT_FRET); + jit_dec_synth(); +} + +jit_pointer_t +_emit_code(jit_state_t *_jit) +{ + jit_node_t *node; + jit_node_t *temp; + jit_word_t word; + jit_int32_t value; + jit_int32_t offset; + struct { + jit_node_t *node; + jit_word_t word; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + jit_int32_t patch_offset; + } undo; +#if DEVEL_DISASSEMBLER + jit_word_t prevw; +#endif + + _jitc->function = NULL; + + jit_reglive_setup(); + + undo.word = 0; + undo.node = NULL; + undo.patch_offset = 0; + +#define assert_data(node) /**/ +#define case_rr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), rn(node->v.w)); \ + break +#define case_rw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), node->v.w); \ + break +#define case_wr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w)); \ + break +#define case_rrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.w), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrrr(name, type) \ + case jit_code_##name##r##type: \ + name##r##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), rn(node->w.w)); \ + break +#define case_rrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.w), rn(node->v.w), node->w.w); \ + break +#define case_rrrw(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(rn(node->u.q.l), rn(node->u.q.h), \ + rn(node->v.w), node->w.w); \ + break +#define case_rrf(name) \ + case jit_code_##name##i_f: \ + assert_data(node); \ + name##i_f(rn(node->u.w), rn(node->v.w), node->w.f); \ + break +#define case_rrd(name) \ + case jit_code_##name##i_d: \ + assert_data(node); \ + name##i_d(rn(node->u.w), rn(node->v.w),node->w.d); \ + break +#define case_wrr(name, type) \ + case jit_code_##name##i##type: \ + name##i##type(node->u.w, rn(node->v.w), rn(node->w.w)); \ + break +#define case_brr(name, type) \ + case jit_code_##name##r##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##r##type(temp->u.w, rn(node->v.w), \ + rn(node->w.w)); \ + else { \ + word = name##r##type(_jit->pc.w, \ + rn(node->v.w), \ + rn(node->w.w)); \ + patch(word, node); \ + } \ + break +#define case_brw(name, type) \ + case jit_code_##name##i##type: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i##type(temp->u.w, \ + rn(node->v.w), node->w.w); \ + else { \ + word = name##i##type(_jit->pc.w, \ + rn(node->v.w), node->w.w); \ + patch(word, node); \ + } \ + break; +#define case_brf(name) \ + case jit_code_##name##i_f: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i_f(temp->u.w, rn(node->v.w), node->w.f); \ + else { \ + word = name##i_f(_jit->pc.w, rn(node->v.w), \ + node->w.f); \ + patch(word, node); \ + } \ + break +#define case_brd(name) \ + case jit_code_##name##i_d: \ + temp = node->u.n; \ + assert(temp->code == jit_code_label || \ + temp->code == jit_code_epilog); \ + if (temp->flag & jit_flag_patch) \ + name##i_d(temp->u.w, rn(node->v.w), node->w.d); \ + else { \ + word = name##i_d(_jit->pc.w, rn(node->v.w), \ + node->w.d); \ + patch(word, node); \ + } \ + break +#if DEVEL_DISASSEMBLER + prevw = _jit->pc.w; +#endif + for (node = _jitc->head; node; node = node->next) { + if (_jit->pc.uc >= _jitc->code.end) + return (NULL); + +#if DEVEL_DISASSEMBLER + node->offset = (jit_uword_t)_jit->pc.w - (jit_uword_t)prevw; + prevw = _jit->pc.w; +#endif + value = jit_classify(node->code); + jit_regarg_set(node, value); + switch (node->code) { + case jit_code_align: + /* Must align to a power of two */ + assert(!(node->u.w & (node->u.w - 1))); + if ((word = _jit->pc.w & (node->u.w - 1))) + nop(node->u.w - word); + break; + case jit_code_note: case jit_code_name: + node->u.w = _jit->pc.w; + break; + case jit_code_label: + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + break; + case_rrr(add,); + case_rrw(add,); + case_rrr(addc,); + case_rrw(addc,); + case_rrr(addx,); + case_rrw(addx,); + case_rrr(sub,); + case_rrw(sub,); + case_rrr(subc,); + case_rrw(subc,); + case_rrr(subx,); + case_rrw(subx,); + case_rrw(rsb,); + case_rrr(mul,); + case_rrw(mul,); + case_rrrr(qmul,); + case_rrrw(qmul,); + case_rrrr(qmul, _u); + case_rrrw(qmul, _u); + case_rrr(div,); + case_rrw(div,); + case_rrr(div, _u); + case_rrw(div, _u); + case_rrr(rem,); + case_rrw(rem,); + case_rrr(rem, _u); + case_rrw(rem, _u); + case_rrrr(qdiv,); + case_rrrw(qdiv,); + case_rrrr(qdiv, _u); + case_rrrw(qdiv, _u); + case_rrr(lsh,); + case_rrw(lsh,); + case_rrr(rsh,); + case_rrw(rsh,); + case_rrr(rsh, _u); + case_rrw(rsh, _u); + case_rr(neg,); + case_rr(com,); + case_rrr(and,); + case_rrw(and,); + case_rrr(or,); + case_rrw(or,); + case_rrr(xor,); + case_rrw(xor,); + case_rr(trunc, _f_i); + case_rr(trunc, _d_i); + case_rr(trunc, _f_l); + case_rr(trunc, _d_l); + case_rr(ld, _c); + case_rw(ld, _c); + case_rr(ld, _uc); + case_rw(ld, _uc); + case_rr(ld, _s); + case_rw(ld, _s); + case_rr(ld, _us); + case_rw(ld, _us); + case_rr(ld, _i); + case_rw(ld, _i); + case_rr(ld, _ui); + case_rw(ld, _ui); + case_rr(ld, _l); + case_rw(ld, _l); + case_rrr(ldx, _c); + case_rrw(ldx, _c); + case_rrr(ldx, _uc); + case_rrw(ldx, _uc); + case_rrr(ldx, _s); + case_rrw(ldx, _s); + case_rrr(ldx, _us); + case_rrw(ldx, _us); + case_rrr(ldx, _i); + case_rrw(ldx, _i); + case_rrr(ldx, _ui); + case_rrw(ldx, _ui); + case_rrr(ldx, _l); + case_rrw(ldx, _l); + case_rr(st, _c); + case_wr(st, _c); + case_rr(st, _s); + case_wr(st, _s); + case_rr(st, _i); + case_wr(st, _i); + case_rr(st, _l); + case_wr(st, _l); + case_rrr(stx, _c); + case_wrr(stx, _c); + case_rrr(stx, _s); + case_wrr(stx, _s); + case_rrr(stx, _i); + case_wrr(stx, _i); + case_rrr(stx, _l); + case_wrr(stx, _l); + case_rr(hton, _us); + case_rr(hton, _ui); + case_rr(hton, _ul); + case_rr(bswap, _us); + case_rr(bswap, _ui); + case_rr(bswap, _ul); + case_rr(ext, _c); + case_rr(ext, _uc); + case_rr(ext, _s); + case_rr(ext, _us); + case_rr(ext, _i); + case_rr(ext, _ui); + case jit_code_casr: + casr(rn(node->u.w), rn(node->v.w), + rn(node->w.q.l), rn(node->w.q.h)); + break; + case jit_code_casi: + casi(rn(node->u.w), node->v.w, + rn(node->w.q.l), rn(node->w.q.h)); + break; + case_rrr(movn,); + case_rrr(movz,); + case_rr(mov,); + case jit_code_movi: + if (node->flag & jit_flag_node) { + temp = node->v.n; + if (temp->code == jit_code_data || + (temp->code == jit_code_label && + (temp->flag & jit_flag_patch))) + movi(rn(node->u.w), temp->u.w); + else { + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + word = movi_p(rn(node->u.w), temp->u.w); + patch(word, node); + } + } + else + movi(rn(node->u.w), node->v.w); + break; + case_rrr(lt,); + case_rrw(lt,); + case_rrr(lt, _u); + case_rrw(lt, _u); + case_rrr(le,); + case_rrw(le,); + case_rrr(le, _u); + case_rrw(le, _u); + case_rrr(eq,); + case_rrw(eq,); + case_rrr(ge,); + case_rrw(ge,); + case_rrr(ge, _u); + case_rrw(ge, _u); + case_rrr(gt,); + case_rrw(gt,); + case_rrr(gt, _u); + case_rrw(gt, _u); + case_rrr(ne,); + case_rrw(ne,); + case_brr(blt,); + case_brw(blt,); + case_brr(blt, _u); + case_brw(blt, _u); + case_brr(ble,); + case_brw(ble,); + case_brr(ble, _u); + case_brw(ble, _u); + case_brr(beq,); + case_brw(beq,); + case_brr(bge,); + case_brw(bge,); + case_brr(bge, _u); + case_brw(bge, _u); + case_brr(bgt,); + case_brw(bgt,); + case_brr(bgt, _u); + case_brw(bgt, _u); + case_brr(bne,); + case_brw(bne,); + case_brr(boadd,); + case_brw(boadd,); + case_brr(boadd, _u); + case_brw(boadd, _u); + case_brr(bxadd,); + case_brw(bxadd,); + case_brr(bxadd, _u); + case_brw(bxadd, _u); + case_brr(bosub,); + case_brw(bosub,); + case_brr(bosub, _u); + case_brw(bosub, _u); + case_brr(bxsub,); + case_brw(bxsub,); + case_brr(bxsub, _u); + case_brw(bxsub, _u); + case_brr(bms,); + case_brw(bms,); + case_brr(bmc,); + case_brw(bmc,); + case_rrr(add, _f); + case_rrf(add); + case_rrr(sub, _f); + case_rrf(sub); + case_rrf(rsb); + case_rrr(mul, _f); + case_rrf(mul); + case_rrr(div, _f); + case_rrf(div); + case_rr(abs, _f); + case_rr(neg, _f); + case_rr(sqrt, _f); + case_rr(ext, _f); + case_rr(ld, _f); + case_rw(ld, _f); + case_rrr(ldx, _f); + case_rrw(ldx, _f); + case_rr(st, _f); + case_wr(st, _f); + case_rrr(stx, _f); + case_wrr(stx, _f); + case_rr(mov, _f); + case jit_code_movi_f: + assert_data(node); + movi_f(rn(node->u.w), node->v.f); + break; + case_rr(ext, _d_f); + case_rrr(lt, _f); + case_rrf(lt); + case_rrr(le, _f); + case_rrf(le); + case_rrr(eq, _f); + case_rrf(eq); + case_rrr(ge, _f); + case_rrf(ge); + case_rrr(gt, _f); + case_rrf(gt); + case_rrr(ne, _f); + case_rrf(ne); + case_rrr(unlt, _f); + case_rrf(unlt); + case_rrr(unle, _f); + case_rrf(unle); + case_rrr(uneq, _f); + case_rrf(uneq); + case_rrr(unge, _f); + case_rrf(unge); + case_rrr(ungt, _f); + case_rrf(ungt); + case_rrr(ltgt, _f); + case_rrf(ltgt); + case_rrr(ord, _f); + case_rrf(ord); + case_rrr(unord, _f); + case_rrf(unord); + case_brr(blt, _f); + case_brf(blt); + case_brr(ble, _f); + case_brf(ble); + case_brr(beq, _f); + case_brf(beq); + case_brr(bge, _f); + case_brf(bge); + case_brr(bgt, _f); + case_brf(bgt); + case_brr(bne, _f); + case_brf(bne); + case_brr(bunlt, _f); + case_brf(bunlt); + case_brr(bunle, _f); + case_brf(bunle); + case_brr(buneq, _f); + case_brf(buneq); + case_brr(bunge, _f); + case_brf(bunge); + case_brr(bungt, _f); + case_brf(bungt); + case_brr(bltgt, _f); + case_brf(bltgt); + case_brr(bord, _f); + case_brf(bord); + case_brr(bunord, _f); + case_brf(bunord); + case_rrr(add, _d); + case_rrd(add); + case_rrr(sub, _d); + case_rrd(sub); + case_rrd(rsb); + case_rrr(mul, _d); + case_rrd(mul); + case_rrr(div, _d); + case_rrd(div); + case_rr(abs, _d); + case_rr(neg, _d); + case_rr(sqrt, _d); + case_rr(ext, _d); + case_rr(ld, _d); + case_rw(ld, _d); + case_rrr(ldx, _d); + case_rrw(ldx, _d); + case_rr(st, _d); + case_wr(st, _d); + case_rrr(stx, _d); + case_wrr(stx, _d); + case_rr(mov, _d); + case jit_code_movi_d: + assert_data(node); + movi_d(rn(node->u.w), node->v.d); + break; + case_rr(ext, _f_d); + case_rrr(lt, _d); + case_rrd(lt); + case_rrr(le, _d); + case_rrd(le); + case_rrr(eq, _d); + case_rrd(eq); + case_rrr(ge, _d); + case_rrd(ge); + case_rrr(gt, _d); + case_rrd(gt); + case_rrr(ne, _d); + case_rrd(ne); + case_rrr(unlt, _d); + case_rrd(unlt); + case_rrr(unle, _d); + case_rrd(unle); + case_rrr(uneq, _d); + case_rrd(uneq); + case_rrr(unge, _d); + case_rrd(unge); + case_rrr(ungt, _d); + case_rrd(ungt); + case_rrr(ltgt, _d); + case_rrd(ltgt); + case_rrr(ord, _d); + case_rrd(ord); + case_rrr(unord, _d); + case_rrd(unord); + case_brr(blt, _d); + case_brd(blt); + case_brr(ble, _d); + case_brd(ble); + case_brr(beq, _d); + case_brd(beq); + case_brr(bge, _d); + case_brd(bge); + case_brr(bgt, _d); + case_brd(bgt); + case_brr(bne, _d); + case_brd(bne); + case_brr(bunlt, _d); + case_brd(bunlt); + case_brr(bunle, _d); + case_brd(bunle); + case_brr(buneq, _d); + case_brd(buneq); + case_brr(bunge, _d); + case_brd(bunge); + case_brr(bungt, _d); + case_brd(bungt); + case_brr(bltgt, _d); + case_brd(bltgt); + case_brr(bord, _d); + case_brd(bord); + case_brr(bunord, _d); + case_brd(bunord); + case jit_code_jmpr: + jmpr(rn(node->u.w)); + break; + case jit_code_jmpi: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } + } + else + jmpi(node->u.w); + break; + case jit_code_callr: + callr(rn(node->u.w)); + break; + case jit_code_calli: + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + calli(temp->u.w); + else { + word = calli_p(_jit->pc.w); + patch(word, node); + } + } + else + calli(node->u.w); + break; + case jit_code_prolog: + _jitc->function = _jitc->functions.ptr + node->w.w; + undo.node = node; + undo.word = _jit->pc.w; +#if DEVEL_DISASSEMBLER + undo.prevw = prevw; +#endif + undo.patch_offset = _jitc->patches.offset; + restart_function: + _jitc->again = 0; + prolog(node); + break; + case jit_code_epilog: + assert(_jitc->function == _jitc->functions.ptr + node->w.w); + if (_jitc->again) { + for (temp = undo.node->next; + temp != node; temp = temp->next) { + if (temp->code == jit_code_label || + temp->code == jit_code_epilog) + temp->flag &= ~jit_flag_patch; + } + temp->flag &= ~jit_flag_patch; + node = undo.node; + _jit->pc.w = undo.word; +#if DEVEL_DISASSEMBLER + prevw = undo.prevw; +#endif + _jitc->patches.offset = undo.patch_offset; + goto restart_function; + } + if (node->link && (word = _jit->pc.w & 3)) + nop(4 - word); + /* remember label is defined */ + node->flag |= jit_flag_patch; + node->u.w = _jit->pc.w; + epilog(node); + _jitc->function = NULL; + break; + case jit_code_movr_w_f: + movr_w_f(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movr_f_w: + movr_f_w(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movi_f_w: + assert_data(node); + movi_f_w(rn(node->u.w), node->v.f); + break; + case jit_code_movr_w_d: + movr_w_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movr_d_w: + movr_d_w(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_movi_d_w: + assert_data(node); + movi_d_w(rn(node->u.w), node->v.d); + break; + case jit_code_va_start: + vastart(rn(node->u.w)); + break; + case jit_code_va_arg: + vaarg(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_va_arg_d: + vaarg_d(rn(node->u.w), rn(node->v.w)); + break; + case jit_code_live: case jit_code_ellipsis: + case jit_code_va_push: + case jit_code_allocai: case jit_code_allocar: + case jit_code_arg: + case jit_code_arg_f: case jit_code_arg_d: + case jit_code_va_end: + case jit_code_ret: + case jit_code_retr: case jit_code_reti: + case jit_code_retr_f: case jit_code_reti_f: + case jit_code_retr_d: case jit_code_reti_d: + case jit_code_getarg_c: case jit_code_getarg_uc: + case jit_code_getarg_s: case jit_code_getarg_us: + case jit_code_getarg_i: + case jit_code_getarg_ui: case jit_code_getarg_l: + case jit_code_getarg_f: case jit_code_getarg_d: + case jit_code_putargr: case jit_code_putargi: + case jit_code_putargr_f: case jit_code_putargi_f: + case jit_code_putargr_d: case jit_code_putargi_d: + case jit_code_pushargr: case jit_code_pushargi: + case jit_code_pushargr_f: case jit_code_pushargi_f: + case jit_code_pushargr_d: case jit_code_pushargi_d: + case jit_code_retval_c: case jit_code_retval_uc: + case jit_code_retval_s: case jit_code_retval_us: + case jit_code_retval_i: + case jit_code_retval_ui: case jit_code_retval_l: + case jit_code_retval_f: case jit_code_retval_d: + case jit_code_prepare: + case jit_code_finishr: case jit_code_finishi: + break; + default: + abort(); + } + if (jit_carry != _NOREG) { + switch (node->code) { + case jit_code_note: + case jit_code_addcr: case jit_code_addci: + case jit_code_addxr: case jit_code_addxi: + case jit_code_subcr: case jit_code_subci: + case jit_code_subxr: case jit_code_subxi: + break; + default: + jit_unget_reg(jit_carry); + jit_carry = _NOREG; + break; + } + } + jit_regarg_clr(node, value); + assert(_jitc->regarg == 0 || + (jit_carry != _NOREG && _jitc->regarg == (1 << jit_carry))); + assert(_jitc->synth == 0); + /* update register live state */ + jit_reglive(node); + } +#undef case_brw +#undef case_brr +#undef case_wrr +#undef case_rrw +#undef case_rrr +#undef case_wr +#undef case_rw +#undef case_rr + + for (offset = 0; offset < _jitc->patches.offset; offset++) { + node = _jitc->patches.ptr[offset].node; + word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; + patch_at(_jitc->patches.ptr[offset].inst, word); + } + + jit_flush(_jit->code.ptr, _jit->pc.uc); + + return (_jit->code.ptr); +} + +#define CODE 1 +# include "jit_loongarch-cpu.c" +# include "jit_loongarch-fpu.c" +#undef CODE + +void +jit_flush(void *fptr, void *tptr) +{ +#if defined(__GNUC__) + jit_word_t f, t, s; + + s = sysconf(_SC_PAGE_SIZE); + f = (jit_word_t)fptr & -s; + t = (((jit_word_t)tptr) + s - 1) & -s; + __clear_cache((void *)f, (void *)t); +#endif +} + +void +_emit_ldxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi(rn(r0), rn(r1), i0); +} + +void +_emit_stxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi(i0, rn(r0), rn(r1)); +} + +void +_emit_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0) +{ + ldxi_d(rn(r0), rn(r1), i0); +} + +void +_emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) +{ + stxi_d(i0, rn(r0), rn(r1)); +} + +static void +_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) +{ + jit_int32_t flag; + + assert(node->flag & jit_flag_node); + if (node->code == jit_code_movi) + flag = node->v.n->flag; + else + flag = node->u.n->flag; + assert(!(flag & jit_flag_patch)); + if (_jitc->patches.offset >= _jitc->patches.length) { + jit_realloc((jit_pointer_t *)&_jitc->patches.ptr, + _jitc->patches.length * sizeof(jit_patch_t), + (_jitc->patches.length + 1024) * sizeof(jit_patch_t)); + _jitc->patches.length += 1024; + } + _jitc->patches.ptr[_jitc->patches.offset].inst = instr; + _jitc->patches.ptr[_jitc->patches.offset].node = node; + ++_jitc->patches.offset; +} diff --git a/deps/lightning/lib/jit_size.c b/deps/lightning/lib/jit_size.c index dcfa0b0e..b3e1caea 100644 --- a/deps/lightning/lib/jit_size.c +++ b/deps/lightning/lib/jit_size.c @@ -52,6 +52,8 @@ static jit_int16_t _szs[jit_code_last_code] = { # include "jit_alpha-sz.c" # elif defined(__riscv) # include "jit_riscv-sz.c" +# elif defined(__loongarch__) +# include "jit_loongarch-sz.c" # endif #endif }; diff --git a/deps/lightning/lib/lightning.c b/deps/lightning/lib/lightning.c index b3c245eb..49244b51 100644 --- a/deps/lightning/lib/lightning.c +++ b/deps/lightning/lib/lightning.c @@ -67,6 +67,9 @@ _jit_dataset(jit_state_t *_jit); #define block_update_set(block, target) _block_update_set(_jit, block, target) static jit_bool_t _block_update_set(jit_state_t*, jit_block_t*, jit_block_t*); +#define propagate_backward(block) _propagate_backward(_jit, block) +static void _propagate_backward(jit_state_t*, jit_block_t*); + #define check_block_again() _check_block_again(_jit) static jit_bool_t _check_block_again(jit_state_t*); @@ -1670,6 +1673,21 @@ _block_update_set(jit_state_t *_jit, return (0); } +static void +_propagate_backward(jit_state_t *_jit, jit_block_t *block) +{ + jit_block_t *prev; + jit_word_t offset; + + for (offset = block->label->v.w - 1; + offset >= 0; --offset) { + prev = _jitc->blocks.ptr + offset; + if (!block_update_set(prev, block) || + !(prev->label->flag & jit_flag_head)) + break; + } +} + static jit_bool_t _check_block_again(jit_state_t *_jit) { @@ -1708,12 +1726,11 @@ _check_block_again(jit_state_t *_jit) block = NULL; target = _jitc->blocks.ptr + node->v.w; - /* Update if previous block pass through */ - if (block && block->again && block_update_set(target, block)) + if (block && target->again && block_update_set(block, target)) { + propagate_backward(block); todo = 1; + } block = target; - if (!block->again) - continue; } /* If not the first jmpi */ else if (block) { @@ -1724,8 +1741,10 @@ _check_block_again(jit_state_t *_jit) label = node->u.n; /* Mark predecessor needs updating due to target change */ target = _jitc->blocks.ptr + label->v.w; - if (target->again && block_update_set(block, target)) + if (target->again && block_update_set(block, target)) { + propagate_backward(block); todo = 1; + } } } } @@ -2870,36 +2889,59 @@ _split_branches(jit_state_t *_jit) jit_node_t *next; jit_node_t *label; jit_block_t *block; + jit_block_t *blocks; + jit_word_t offset; + jit_word_t length; + length = _jitc->blocks.length; + jit_alloc((jit_pointer_t *)&blocks, length * sizeof(jit_block_t)); + if ((node = _jitc->head) && + (node->code == jit_code_label || node->code == jit_code_prolog)) { + block = _jitc->blocks.ptr + node->v.w; + memcpy(blocks, block, sizeof(jit_block_t)); + node->v.w = 0; + offset = 1; + } + else + offset = 0; for (node = _jitc->head; node; node = next) { if ((next = node->next)) { if (next->code == jit_code_label || next->code == jit_code_prolog || - next->code == jit_code_epilog) - continue; + next->code == jit_code_epilog) { + if (offset >= length) { + jit_realloc((jit_pointer_t *)&blocks, + length * sizeof(jit_block_t), + (length + 16) * sizeof(jit_block_t)); + length += 16; + } + block = _jitc->blocks.ptr + next->v.w; + memcpy(blocks + offset, block, sizeof(jit_block_t)); + next->v.w = offset++; + } /* split block on branches */ - if (jit_classify(node->code) & jit_cc_a0_jmp) { + else if (jit_classify(node->code) & jit_cc_a0_jmp) { label = new_node(jit_code_label); label->next = next; node->next = label; - if (_jitc->blocks.offset >= _jitc->blocks.length) { - jit_word_t length; - - length = _jitc->blocks.length + 16; - jit_realloc((jit_pointer_t *)&_jitc->blocks.ptr, - _jitc->blocks.length * sizeof(jit_block_t), - length * sizeof(jit_block_t)); - _jitc->blocks.length = length; + if (offset >= length) { + jit_realloc((jit_pointer_t *)&blocks, + length * sizeof(jit_block_t), + (length + 16) * sizeof(jit_block_t)); + length += 16; } - block = _jitc->blocks.ptr + _jitc->blocks.offset; + block = blocks + offset; block->label = label; - label->v.w = _jitc->blocks.offset; + label->v.w = offset++; jit_regset_new(&block->reglive); jit_regset_new(&block->regmask); - ++_jitc->blocks.offset; } } } + jit_free((jit_pointer_t *)&_jitc->blocks.ptr); + _jitc->blocks.ptr = blocks; + _jitc->blocks.offset = offset; + _jitc->blocks.length = length; } static jit_bool_t @@ -3380,7 +3422,6 @@ _simplify_stxi(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node) /* no multiple information, so, if set to a constant, * prefer to keep that information */ if (value->kind == 0) { - value->kind = jit_kind_code; switch (node->code) { /* no information about signed/unsigned either */ case jit_code_stxi_c: value->code = jit_code_ldxi_c; break; @@ -3841,6 +3882,8 @@ generic_bswapr_ul(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1); # include "jit_alpha.c" #elif defined(__riscv) # include "jit_riscv.c" +#elif defined(__loongarch__) +# include "jit_loongarch.c" #endif static maybe_unused void -- 2.39.5