mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 20:30:28 +02:00
* check/alu_rsb.ok, check/alu_rsb.tst: New files implementing tests for jit_rsb*. * check/Makefile.am, check/lightning.c, include/lightning.h, lib/jit_aarch64-cpu.c, lib/jit_aarch64-fpu.c, lib/jit_aarch64-sz.c, lib/jit_aarch64.c, lib/jit_alpha-cpu.c, lib/jit_alpha-fpu.c, lib/jit_alpha-sz.c, lib/jit_alpha.c, lib/jit_arm-cpu.c, lib/jit_arm-swf.c, lib/jit_arm-sz.c, lib/jit_arm-vfp.c, lib/jit_arm.c, lib/jit_hppa-cpu.c, lib/jit_hppa-fpu.c, lib/jit_hppa-sz.c, lib/jit_hppa.c, lib/jit_ia64-cpu.c, lib/jit_ia64-fpu.c, lib/jit_ia64-sz.c, lib/jit_ia64.c, lib/jit_mips-cpu.c, lib/jit_mips-fpu.c, lib/jit_mips-sz.c, lib/jit_mips.c, lib/jit_names.c, lib/jit_ppc-cpu.c, lib/jit_ppc-fpu.c, lib/jit_ppc-sz.c, lib/jit_ppc.c, lib/jit_s390x-cpu.c, lib/jit_s390x-fpu.c, lib/jit_s390x-sz.c, lib/jit_s390x.c, lib/jit_sparc-cpu.c, lib/jit_sparc-fpu.c, lib/jit_sparc-sz.c, lib/jit_sparc.c, lib/jit_x86-cpu.c, lib/jit_x86-sse.c, lib/jit_x86-sz.c, lib/jit_x86-x87.c, lib/jit_x86.c, lib/lightning.c: Implement jit_rsb*. This was a missing lightning 1.x interface, that on most backends is synthesized, but on a few backends (hppa and ia64), it can generate better code as on those there is, or the only instruction with an immediate is in "rsb" format (left operand).
2669 lines
75 KiB
C
2669 lines
75 KiB
C
/*
|
|
* Copyright (C) 2014 Free Software Foundation, Inc.
|
|
*
|
|
* This file is part of GNU lightning.
|
|
*
|
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as published
|
|
* by the Free Software Foundation; either version 3, or (at your option)
|
|
* any later version.
|
|
*
|
|
* GNU lightning is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
* License for more details.
|
|
*
|
|
* Authors:
|
|
* Paulo Cesar Pereira de Andrade
|
|
*/
|
|
|
|
#if PROTO
|
|
# define _u2(v) ((v) & 0x3)
|
|
# define _s2_p(v) ((v) >= -0x2 && (v) <= 0x1)
|
|
# define _u2_p(v) ((v) >= 0 && (v) <= 0x3)
|
|
# define _u5(v) ((v) & 0x1f)
|
|
# define _s5_p(v) ((v) >= -0x10 && (v) <= 0xf)
|
|
# define _u5_p(v) ((v) >= 0 && (v) <= 0x1f)
|
|
# define _u6(v) ((v) & 0x3f)
|
|
# define _s6_p(v) ((v) >= -0x20 && (v) <= 0x1f)
|
|
# define _u6_p(v) ((v) >= 0 && (v) <= 0x3f)
|
|
# define _u7(v) ((v) & 0x7f)
|
|
# define _s7_p(v) ((v) >= -0x40 && (v) <= 0x3f)
|
|
# define _u7_p(v) ((v) >= 0 && (v) <= 0x7f)
|
|
# define _u8(v) ((v) & 0xff)
|
|
# define _s8_p(v) ((v) >= -0x80 && (v) <= 0x7f)
|
|
# define _u8_p(v) ((v) >= 0 && (v) <= 0xff)
|
|
# define _u11(v) ((v) & 0x7ff)
|
|
# define _s11_p(v) ((v) >= -0x400 && (v) <= 0x3ff)
|
|
# define _u11_p(v) ((v) >= 0 && (v) <= 0x7ff)
|
|
# define _u14(v) ((v) & 0x3fff)
|
|
# define _s14_p(v) ((v) >= -0x2000 && (v) <= 0x1fff)
|
|
# define _u14_p(v) ((v) >= 0 && (v) <= 0x3fff)
|
|
# define _u16(v) ((v) & 0xffff)
|
|
# define _s16_p(v) ((v) >= -0x8000 && (v) <= 0x7fff)
|
|
# define _u16_p(v) ((v) >= 0 && (v) <= 0xffff)
|
|
# define _u21(v) ((v) & 0x1fffff)
|
|
# define _s21_p(v) ((v) >= -0x100000 && (v) <= 0xfffff)
|
|
# define _u21_p(v) ((v) >= 0 && (v) <= 0x1fffff)
|
|
# define _u26(v) ((v) & 0x3ffffff)
|
|
# define _s26_p(v) ((v) >= -0x2000000 && (v) <= 0x1ffffff)
|
|
# define _u26_p(v) ((v) >= 0 && (v) <= 0x3ffffff)
|
|
# define _u32(v) ((v) & 0xffffffff)
|
|
# define _s32_p(v) ((v) >= -0x80000000 && (v) <= 0x7fffffff)
|
|
# define _u32_p(v) ((v) >= 0 && (v) <= 0xffffffff)
|
|
# define ii(i) *_jit->pc.ui++ = i
|
|
# define stack_framesize 128
|
|
# define _S0_REGNO 0x09
|
|
# define _S1_REGNO 0x0a
|
|
# define _S2_REGNO 0x0b
|
|
# define _S3_REGNO 0x0c
|
|
# define _S4_REGNO 0x0d
|
|
# define _S5_REGNO 0x0e
|
|
# define _FP_REGNO 0x0f
|
|
# define _A0_REGNO 0x10
|
|
# define _A1_REGNO 0x11
|
|
# define _A2_REGNO 0x12
|
|
# define _V0_REGNO 0x00
|
|
# define _T0_REGNO 0x01
|
|
# define _T1_REGNO 0x02
|
|
# define _RA_REGNO 0x1a
|
|
# define _PV_REGNO 0x1b
|
|
# define _GP_REGNO 0x1d
|
|
# define _SP_REGNO 0x1e
|
|
# define _R31_REGNO 0x1f
|
|
# define Pcd(o,n) _Pcd(_jit,o,n)
|
|
static void _Pcd(jit_state_t*,int,unsigned int) maybe_unused;
|
|
# define Bra(o,ra,d) _Bra(_jit,o,ra,d)
|
|
static void _Bra(jit_state_t*,int,int,int);
|
|
# define Mem(o,ra,rb,d) _Mem(_jit,o,ra,rb,d)
|
|
static void _Mem(jit_state_t*,int,int,int,unsigned int);
|
|
# define Mbr(o,ra,rb,h,d) _Mbr(_jit,o,ra,rb,h,d)
|
|
static void _Mbr(jit_state_t*,int,int,int,int,int);
|
|
# define Opr(o,ra,rb,f,rc) _Opr(_jit,o,ra,rb,f,rc)
|
|
static void _Opr(jit_state_t*,int,int,int,unsigned int,int);
|
|
# define Opi(o,ra,i,f,rc) _Opi(_jit,o,ra,i,f,rc)
|
|
static void _Opi(jit_state_t*,int,int,unsigned int,unsigned int,int);
|
|
# define ADDL(ra,rb,rc) Opr(0x10,ra,rb,0x00,rc)
|
|
# define ADDLi(ra,im,rc) Opi(0x10,ra,im,0x00,rc)
|
|
# define ADDL_V(ra,rb,rc) Opr(0x10,ra,rb,0x40,rc)
|
|
# define ADDL_Vi(ra,im,rc) Opi(0x10,ra,im,0x40,rc)
|
|
# define ADDQ(ra,rb,rc) Opr(0x10,ra,rb,0x20,rc)
|
|
# define ADDQi(ra,im,rc) Opi(0x10,ra,im,0x20,rc)
|
|
# define ADDQ_V(ra,rb,rc) Opr(0x10,ra,rb,0x60,rc)
|
|
# define ADDQ_Vi(ra,im,rc) Opi(0x10,ra,im,0x60,rc)
|
|
# define AMASK(rb,rc) Opr(0x11,_R31_REGNO,rb,0x61,rc)
|
|
# define AND(ra,rb,rc) Opr(0x11,ra,rb,0x00,rc)
|
|
# define ANDi(ra,im,rc) Opi(0x11,ra,im,0x00,rc)
|
|
# define BEQ(ra,d) Bra(0x39,ra,d)
|
|
# define BGE(ra,d) Bra(0x3e,ra,d)
|
|
# define BGT(ra,d) Bra(0x3f,ra,d)
|
|
# define BIC(ra,rb,rc) Opr(0x11,ra,rb,0x08,rc)
|
|
# define ANDNOT(ra,rb,rc) BIC(ra,rb,rc)
|
|
# define BICi(ra,im,rc) Opi(0x11,ra,im,0x08,rc)
|
|
# define ANDNOTi(ra,im,rc) BICi(ra,im,rc)
|
|
# define BIS(ra,rb,rc) Opr(0x11,ra,rb,0x20,rc)
|
|
# define BISi(ra,im,rc) Opi(0x11,ra,im,0x20,rc)
|
|
# define OR(ra,rb,rc) BIS(ra,rb,rc)
|
|
# define ORi(ra,im,rc) BISi(ra,im,rc)
|
|
# define BLBC(ra,d) Bra(0x38,ra,d)
|
|
# define BLBS(ra,d) Bra(0x3c,ra,d)
|
|
# define BLE(ra,d) Bra(0x3b,ra,d)
|
|
# define BLT(ra,d) Bra(0x3a,ra,d)
|
|
# define BNE(ra,d) Bra(0x3d,ra,d)
|
|
# define BR(ra,d) Bra(0x30,ra,d)
|
|
# define BSR(ra,d) Bra(0x34,ra,d)
|
|
# define CALL_PAL(c) Pcd(0x00,c)
|
|
# define CMOVEQ(ra,rb,rc) Opr(0x11,ra,rb,0x24,rc)
|
|
# define CMOVEQi(ra,im,rc) Opi(0x11,ra,im,0x24,rc)
|
|
# define CMOVGE(ra,rb,rc) Opr(0x11,ra,rb,0x46,rc)
|
|
# define CMOVGEi(ra,im,rc) Opi(0x11,ra,im,0x46,rc)
|
|
# define CMOVGT(ra,rb,rc) Opr(0x11,ra,rb,0x66,rc)
|
|
# define CMOVGTi(ra,im,rc) Opi(0x11,ra,im,0x66,rc)
|
|
# define CMOVLBC(ra,rb,rc) Opr(0x11,ra,rb,0x16,rc)
|
|
# define CMOVLBCi(ra,im,rc) Opi(0x11,ra,im,0x16,rc)
|
|
# define CMOVLBS(ra,rb,rc) Opr(0x11,ra,rb,0x14,rc)
|
|
# define CMOVLBSi(ra,im,rc) Opi(0x11,ra,im,0x14,rc)
|
|
# define CMOVLE(ra,rb,rc) Opr(0x11,ra,rb,0x64,rc)
|
|
# define CMOVLEi(ra,im,rc) Opi(0x11,ra,im,0x64,rc)
|
|
# define CMOVLT(ra,rb,rc) Opr(0x11,ra,rb,0x44,rc)
|
|
# define CMOVLTi(ra,im,rc) Opi(0x11,ra,im,0x44,rc)
|
|
# define CMOVNE(ra,rb,rc) Opr(0x11,ra,rb,0x26,rc)
|
|
# define CMOVNEi(ra,im,rc) Opi(0x11,ra,im,0x26,rc)
|
|
# define CMPBGE(ra,rb,rc) Opr(0x10,ra,rb,0x0f,rc)
|
|
# define CMPBGEi(ra,im,rc) Opi(0x10,ra,im,0x0f,rc)
|
|
# define CMPEQ(ra,rb,rc) Opr(0x10,ra,rb,0x2d,rc)
|
|
# define CMPEQi(ra,im,rc) Opi(0x10,ra,im,0x2d,rc)
|
|
# define CMPLE(ra,rb,rc) Opr(0x10,ra,rb,0x6d,rc)
|
|
# define CMPLEi(ra,im,rc) Opi(0x10,ra,im,0x6d,rc)
|
|
# define CMPLT(ra,rb,rc) Opr(0x10,ra,rb,0x4d,rc)
|
|
# define CMPLTi(ra,im,rc) Opi(0x10,ra,im,0x4d,rc)
|
|
# define CMPULE(ra,rb,rc) Opr(0x10,ra,rb,0x3d,rc)
|
|
# define CMPULEi(ra,im,rc) Opi(0x10,ra,im,0x3d,rc)
|
|
# define CMPULT(ra,rb,rc) Opr(0x10,ra,rb,0x1d,rc)
|
|
# define CMPULTi(ra,im,rc) Opi(0x10,ra,im,0x1d,rc)
|
|
# define CTLZ(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x32,rc)
|
|
# define CTPOP(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x30,rc)
|
|
# define CTTZ(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x33,rc)
|
|
# define ECB(rb,d) Mem(0x18,_R31_REGNO,rb,0xe800)
|
|
# define EQV(ra,rb,rc) Opr(0x11,ra,rb,0x48,rc)
|
|
# define XORNOT(ra,rb,rc) EQV(ra,rb,rc)
|
|
# define EQVi(ra,im,rc) Opi(0x11,ra,im,0x48,rc)
|
|
# define XORNOTi(ra,im,rc) EQVi(ra,im,rc)
|
|
# define EXCB() Mem(0x18,0,0,0x0400)
|
|
# define EXTBL(ra,rb,rc) Opr(0x12,ra,rb,0x06,rc)
|
|
# define EXTBLi(ra,im,rc) Opi(0x12,ra,im,0x06,rc)
|
|
# define EXTLH(ra,rb,rc) Opr(0x12,ra,rb,0x6a,rc)
|
|
# define EXTLHi(ra,im,rc) Opi(0x12,ra,im,0x6a,rc)
|
|
# define EXTLL(ra,rb,rc) Opr(0x12,ra,rb,0x26,rc)
|
|
# define EXTLLi(ra,im,rc) Opi(0x12,ra,im,0x26,rc)
|
|
# define EXTQH(ra,rb,rc) Opr(0x12,ra,rb,0x7a,rc)
|
|
# define EXTQHi(ra,im,rc) Opi(0x12,ra,im,0x7a,rc)
|
|
# define EXTQL(ra,rb,rc) Opr(0x12,ra,rb,0x36,rc)
|
|
# define EXTQLi(ra,im,rc) Opi(0x12,ra,im,0x36,rc)
|
|
# define EXTWH(ra,rb,rc) Opr(0x12,ra,rb,0x5a,rc)
|
|
# define EXTWHi(ra,im,rc) Opi(0x12,ra,im,0x5a,rc)
|
|
# define EXTWL(ra,rb,rc) Opr(0x12,ra,rb,0x16,rc)
|
|
# define EXTWLi(ra,im,rc) Opi(0x12,ra,im,0x16,rc)
|
|
# define FETCH(rb,d) Mem(0x18,_R31_REGNO,rb,0x8000)
|
|
# define FETCH_Mem(rb,d) Mem(0x18,_R31_REGNO,rb,0xa000)
|
|
/* FIXME IMPLVER not disassembled */
|
|
# define IMPLVER(rc) Opr(0x11,_R31_REGNO,1,0x6c,rc)
|
|
# define INSBL(ra,rb,rc) Opr(0x12,ra,rb,0x0b,rc)
|
|
# define INSBLi(ra,im,rc) Opi(0x12,ra,im,0x0b,rc)
|
|
# define INSLH(ra,rb,rc) Opr(0x12,ra,rb,0x67,rc)
|
|
# define INSLHi(ra,im,rc) Opi(0x12,ra,im,0x67,rc)
|
|
# define INSLL(ra,rb,rc) Opr(0x12,ra,rb,0x2b,rc)
|
|
# define INSLLi(ra,im,rc) Opi(0x12,ra,im,0x2b,rc)
|
|
# define INSQH(ra,rb,rc) Opr(0x12,ra,rb,0x77,rc)
|
|
# define INSQHi(ra,im,rc) Opi(0x12,ra,im,0x77,rc)
|
|
# define INSQL(ra,rb,rc) Opr(0x12,ra,rb,0x3b,rc)
|
|
# define INSQLi(ra,im,rc) Opi(0x12,ra,im,0x3b,rc)
|
|
# define INSWH(ra,rb,rc) Opr(0x12,ra,rb,0x57,rc)
|
|
# define INSWHi(ra,im,rc) Opi(0x12,ra,im,0x57,rc)
|
|
# define INSWL(ra,rb,rc) Opr(0x12,ra,rb,0x1b,rc)
|
|
# define INSWLi(ra,im,rc) Opi(0x12,ra,im,0x1b,rc)
|
|
# define JMP(ra,rb,d) Mbr(0x1a,ra,rb,0,d)
|
|
# define JSR(ra,rb,d) Mbr(0x1a,ra,rb,1,d)
|
|
# define JSR_COROUTINE(ra,rb,d) Mbr(0x1a,ra,rb,3,d)
|
|
# define JCR(ra,rb,rd) JSR_COROUTINE(ra,rb,d)
|
|
# define LDA(ra,rb,d) Mem(0x08,ra,rb,d)
|
|
# define LDAH(ra,rb,d) Mem(0x09,ra,rb,d)
|
|
# define LDBU(ra,rb,d) Mem(0x0a,ra,rb,d)
|
|
# define LDWU(ra,rb,d) Mem(0x0c,ra,rb,d)
|
|
# define LDL(ra,rb,d) Mem(0x28,ra,rb,d)
|
|
# define LDL_L(ra,rb,d) Mem(0x2a,ra,rb,d)
|
|
# define LDQ(ra,rb,d) Mem(0x29,ra,rb,d)
|
|
# define LDQ_L(ra,rb,d) Mem(0x2b,ra,rb,d)
|
|
# define LDQ_U(ra,rb,d) Mem(0x0b,ra,rb,d)
|
|
# define MAXSB8(ra,rb,rc) Opr(0x1c,ra,rb,0x3e,rc)
|
|
# define MAXSW4(ra,rb,rc) Opr(0x1c,ra,rb,0x3f,rc)
|
|
# define MAXSUB8(ra,rb,rc) Opr(0x1c,ra,rb,0x3c,rc)
|
|
# define MAXSUW4(ra,rb,rc) Opr(0x1c,ra,rb,0x3d,rc)
|
|
# define MB() Mem(0x18,_R31_REGNO,_R31_REGNO,0x4000)
|
|
# define MINSB8(ra,rb,rc) Opr(0x1c,ra,rb,0x38,rc)
|
|
# define MINSW4(ra,rb,rc) Opr(0x1c,ra,rb,0x39,rc)
|
|
# define MINSUB8(ra,rb,rc) Opr(0x1c,ra,rb,0x3a,rc)
|
|
# define MINSUW4(ra,rb,rc) Opr(0x1c,ra,rb,0x3b,rc)
|
|
# define MSKBL(ra,rb,rc) Opr(0x12,ra,rb,0x02,rc)
|
|
# define MSKBLi(ra,im,rc) Opi(0x12,ra,im,0x02,rc)
|
|
# define MSKLH(ra,rb,rc) Opr(0x12,ra,rb,0x62,rc)
|
|
# define MSKLHi(ra,im,rc) Opi(0x12,ra,im,0x62,rc)
|
|
# define MSKLL(ra,rb,rc) Opr(0x12,ra,rb,0x22,rc)
|
|
# define MSKLLi(ra,im,rc) Opi(0x12,ra,im,0x22,rc)
|
|
# define MSKQH(ra,rb,rc) Opr(0x12,ra,rb,0x72,rc)
|
|
# define MSKQHi(ra,im,rc) Opi(0x12,ra,im,0x72,rc)
|
|
# define MSKQL(ra,rb,rc) Opr(0x12,ra,rb,0x32,rc)
|
|
# define MSKQLi(ra,im,rc) Opi(0x12,ra,im,0x32,rc)
|
|
# define MSKWH(ra,rb,rc) Opr(0x12,ra,rb,0x52,rc)
|
|
# define MSKWHi(ra,im,rc) Opi(0x12,ra,im,0x52,rc)
|
|
# define MSKWL(ra,rb,rc) Opr(0x12,ra,rb,0x12,rc)
|
|
# define MSKWLi(ra,im,rc) Opi(0x12,ra,im,0x12,rc)
|
|
# define MULL(ra,rb,rc) Opr(0x13,ra,rb,0x00,rc)
|
|
# define MULLi(ra,im,rc) Opi(0x13,ra,im,0x00,rc)
|
|
# define MULL_V(ra,rb,rc) Opr(0x13,ra,rb,0x40,rc)
|
|
# define MULL_Vi(ra,im,rc) Opi(0x13,ra,im,0x40,rc)
|
|
# define MULQ(ra,rb,rc) Opr(0x13,ra,rb,0x20,rc)
|
|
# define MULQi(ra,im,rc) Opi(0x13,ra,im,0x20,rc)
|
|
# define MULQ_V(ra,rb,rc) Opr(0x13,ra,rb,0x60,rc)
|
|
# define MULQ_Vi(ra,im,rc) Opi(0x13,ra,im,0x60,rc)
|
|
# define ORNOT(ra,rb,rc) Opr(0x11,ra,rb,0x28,rc)
|
|
# define ORNOTi(ra,im,rc) Opi(0x11,ra,im,0x28,rc)
|
|
# define PERR(ra,rb,rc) Opr(0x1c,ra,rb,0x31,rc)
|
|
# define PKLB(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x37,rc)
|
|
# define PKWB(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x36,rc)
|
|
/* FIXME PREFETCH* not disassembled */
|
|
# define PREFETCH(rb,d) Mem(0x28,_R31_REGNO,rb,d)
|
|
# define PREFETCH_EN(rb,d) Mem(0x29,_R31_REGNO,rb,d)
|
|
# define PREFETCH_M(rb,d) Mem(0x22,_R31_REGNO,rb,d)
|
|
# define PREFETCH_MEN(rb,d) Mem(0x23,_R31_REGNO,rb,d)
|
|
# define RC(ra) Mem(0x18,ra,_R31_REGNO,0xe000)
|
|
# define RET(ra,rb,d) Mbr(0x1a,ra,rb,2,d)
|
|
# define RPCC(ra) Mem(0x18,ra,_R31_REGNO,0xc000)
|
|
# define RS(ra) Mem(0x18,ra,_R31_REGNO,0xf000)
|
|
# define S4ADDL(ra,rb,rc) Opr(0x10,ra,rb,0x02,rc)
|
|
# define S4ADDi(ra,im,rc) Opi(0x10,ra,im,0x02,rc)
|
|
# define S4ADDQ(ra,rb,rc) Opr(0x10,ra,rb,0x22,rc)
|
|
# define S4ADDQi(ra,im,rc) Opi(0x10,ra,im,0x22,rc)
|
|
# define S4SUBL(ra,rb,rc) Opr(0x10,ra,rb,0x0b,rc)
|
|
# define S4SUBLi(ra,im,rc) Opi(0x10,ra,im,0x0b,rc)
|
|
# define S4SUBQ(ra,rb,rc) Opr(0x10,ra,rb,0x2b,rc)
|
|
# define S4SUBQi(ra,im,rc) Opi(0x10,ra,im,0x2b,rc)
|
|
# define S8ADDL(ra,rb,rc) Opr(0x10,ra,rb,0x12,rc)
|
|
# define S8ADDLi(ra,im,rc) Opi(0x10,ra,im,0x12,rc)
|
|
# define S8ADDQ(ra,rb,rc) Opr(0x10,ra,rb,0x32,rc)
|
|
# define S8ADDQi(ra,im,rc) Opi(0x10,ra,im,0x32,rc)
|
|
# define S8SUBL(ra,rb,rc) Opr(0x10,ra,rb,0x1b,rc)
|
|
# define S8SUBLi(ra,im,rc) Opi(0x10,ra,im,0x1b,rc)
|
|
# define S8SUBQ(ra,rb,rc) Opr(0x10,ra,rb,0x3b,rc)
|
|
# define S8SUBQi(ra,im,rc) Opi(0x10,ra,im,0x3b,rc)
|
|
# define SEXTB(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x00,rc)
|
|
/* FIXME not disassembled */
|
|
# define SEXTBi(im,rc) Opi(0x1c,_R31_REGNO,im,0x00,rc)
|
|
# define SEXTW(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x01,rc)
|
|
/* FIXME not disassembled */
|
|
# define SEXTWi(im,rc) Opi(0x1c,_R31_REGNO,im,0x01,rc)
|
|
# define SLL(ra,rb,rc) Opr(0x12,ra,rb,0x39,rc)
|
|
# define SLLi(ra,im,rc) Opi(0x12,ra,im,0x39,rc)
|
|
# define SRA(ra,rb,rc) Opr(0x12,ra,rb,0x3c,rc)
|
|
# define SRAi(ra,im,rc) Opi(0x12,ra,im,0x3c,rc)
|
|
# define SRL(ra,rb,rc) Opr(0x12,ra,rb,0x34,rc)
|
|
# define SRLi(ra,im,rc) Opi(0x12,ra,im,0x34,rc)
|
|
# define STB(ra,rb,d) Mem(0x0e,ra,rb,d)
|
|
# define STL(ra,rb,d) Mem(0x2c,ra,rb,d)
|
|
# define STL_C(ra,rb,d) Mem(0x2e,ra,rb,d)
|
|
# define STQ(ra,rb,d) Mem(0x2d,ra,rb,d)
|
|
# define STQ_C(ra,rb,d) Mem(0x2f,ra,rb,d)
|
|
# define STQ_U(ra,rb,d) Mem(0x0f,ra,rb,d)
|
|
# define STW(ra,rb,d) Mem(0x0d,ra,rb,d)
|
|
# define SUBL(ra,rb,rc) Opr(0x10,ra,rb,0x09,rc)
|
|
# define SUBLi(ra,im,rc) Opi(0x10,ra,im,0x09,rc)
|
|
# define SUBL_V(ra,rb,rc) Opr(0x10,ra,rb,0x49,rc)
|
|
# define SUBL_Vi(ra,im,rc) Opi(0x10,ra,im,0x49,rc)
|
|
# define SUBQ(ra,rb,rc) Opr(0x10,ra,rb,0x29,rc)
|
|
# define SUBQi(ra,im,rc) Opi(0x10,ra,im,0x29,rc)
|
|
# define SUBQ_V(ra,rb,rc) Opr(0x10,ra,rb,0x69,rc)
|
|
# define SUBQ_Vi(ra,im,rc) Opi(0x10,ra,im,0x69,rc)
|
|
# define TRAPB() Mem(0x18,_R31_REGNO,_R31_REGNO,0x0000)
|
|
# define UMULH(ra,rb,rc) Opr(0x13,ra,rb,0x30,rc)
|
|
# define UMULHi(ra,im,rc) Opi(0x13,ra,im,0x30,rc)
|
|
# define UNPKBL(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x35,rc)
|
|
# define UNPKBW(rb,rc) Opr(0x1c,_R31_REGNO,rb,0x34,rc)
|
|
# define WH64(ra) Mem(0x18,ra,_R31_REGNO,0xf800)
|
|
# define WH64EN(ra) Mem(0x18,ra,_R31_REGNO,0xfc00)
|
|
# define WMB() Mem(0x18,_R31_REGNO,_R31_REGNO,0x4400)
|
|
# define XOR(ra,rb,rc) Opr(0x11,ra,rb,0x40,rc)
|
|
# define XORi(ra,im,rc) Opi(0x11,ra,im,0x40,rc)
|
|
# define ZAP(ra,rb,rc) Opr(0x12,ra,rb,0x30,rc)
|
|
# define ZAPi(ra,im,rc) Opi(0x12,ra,im,0x30,rc)
|
|
# define ZAPNOT(ra,rb,rc) Opr(0x12,ra,rb,0x31,rc)
|
|
# define ZAPNOTi(ra,im,rc) Opi(0x12,ra,im,0x31,rc)
|
|
# define NOP() BIS(_R31_REGNO,_R31_REGNO,_R31_REGNO)
|
|
# define MOV(ra,rc) BIS(ra,ra,rc)
|
|
# define MOVi(im,rc) BISi(_R31_REGNO,im,rc)
|
|
# define NEGL(ra,rc) SUBL(_R31_REGNO,ra,rc)
|
|
# define NEGQ(ra,rc) SUBQ(_R31_REGNO,ra,rc)
|
|
# define NOT(ra,rc) ORNOT(_R31_REGNO,ra,rc)
|
|
# define nop(i0) _nop(_jit,i0)
|
|
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 negr(r0,r1) NEGQ(r1,r0)
|
|
# define comr(r0,r1) NOT(r1,r0)
|
|
# define addr(r0,r1,r2) ADDQ(r1,r2,r0)
|
|
# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0)
|
|
static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define addcr(r0,r1,i0) _addcr(_jit,r0,r1,i0)
|
|
static void _addcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define addci(r0,r1,i0) _addci(_jit,r0,r1,i0)
|
|
static void _addci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define addxr(r0,r1,i0) _addxr(_jit,r0,r1,i0)
|
|
static void _addxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define addxi(r0,r1,i0) _addxi(_jit,r0,r1,i0)
|
|
static void _addxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define subr(r0,r1,r2) SUBQ(r1,r2,r0)
|
|
# define subi(r0,r1,i0) _subi(_jit,r0,r1,i0)
|
|
static void _subi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define subcr(r0,r1,i0) _subcr(_jit,r0,r1,i0)
|
|
static void _subcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define subci(r0,r1,i0) _subci(_jit,r0,r1,i0)
|
|
static void _subci(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define subxr(r0,r1,i0) _subxr(_jit,r0,r1,i0)
|
|
static void _subxr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define subxi(r0,r1,i0) _subxi(_jit,r0,r1,i0)
|
|
static void _subxi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define 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) MULQ(r1,r2,r0)
|
|
# define muli(r0,r1,i0) _muli(_jit,r0,r1,i0)
|
|
static void _muli(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define qmulr(r0,r1,r2,r3) _qmulr(_jit,r0,r1,r2,r3)
|
|
static void _qmulr(jit_state_t*,jit_int32_t,
|
|
jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define qmuli(r0,r1,r2,i0) _qmuli(_jit,r0,r1,r2,i0)
|
|
static void _qmuli(jit_state_t*,jit_int32_t,
|
|
jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define qmulr_u(r0,r1,r2,r3) _qmulr_u(_jit,r0,r1,r2,r3)
|
|
static void _qmulr_u(jit_state_t*,jit_int32_t,
|
|
jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define qmuli_u(r0,r1,r2,i0) _qmuli_u(_jit,r0,r1,r2,i0)
|
|
static void _qmuli_u(jit_state_t*,jit_int32_t,
|
|
jit_int32_t,jit_int32_t,jit_word_t);
|
|
static jit_word_t __idiv(jit_word_t, jit_word_t);
|
|
# define divr(r0,r1,r2) _divr(_jit,r0,r1,r2)
|
|
static void _divr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define divi(r0,r1,i0) _divi(_jit,r0,r1,i0)
|
|
static void _divi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
static jit_uword_t __udiv(jit_uword_t, jit_uword_t);
|
|
# define divr_u(r0,r1,r2) _divr_u(_jit,r0,r1,r2)
|
|
static void _divr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define divi_u(r0,r1,i0) _divi_u(_jit,r0,r1,i0)
|
|
static void _divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
static jit_word_t __irem(jit_word_t, jit_word_t);
|
|
# define remr(r0,r1,r2) _remr(_jit,r0,r1,r2)
|
|
static void _remr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define remi(r0,r1,i0) _remi(_jit,r0,r1,i0)
|
|
static void _remi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
static jit_uword_t __urem(jit_uword_t, jit_uword_t);
|
|
# define remr_u(r0,r1,r2) _remr_u(_jit,r0,r1,r2)
|
|
static void _remr_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define remi_u(r0,r1,i0) _remi_u(_jit,r0,r1,i0)
|
|
static void _remi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
static jit_word_t __idivrem(jit_word_t, jit_word_t, jit_word_t*);
|
|
# define qdivr(r0,r1,r2,r3) _qdivr(_jit,r0,r1,r2,r3)
|
|
static void _qdivr(jit_state_t*,
|
|
jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define qdivi(r0,r1,r2,i0) _qdivi(_jit,r0,r1,r2,i0)
|
|
static void _qdivi(jit_state_t*,
|
|
jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t);
|
|
static jit_word_t __udivrem(jit_uword_t, jit_uword_t, jit_uword_t*);
|
|
# define qdivr_u(r0,r1,r2,r3) _qdivr_u(_jit,r0,r1,r2,r3)
|
|
static void _qdivr_u(jit_state_t*,
|
|
jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define qdivi_u(r0,r1,r2,i0) _qdivi_u(_jit,r0,r1,r2,i0)
|
|
static void _qdivi_u(jit_state_t*,
|
|
jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define lshr(r0,r1,r2) SLL(r1,r2,r0)
|
|
# define lshi(r0,r1,i0) _lshi(_jit,r0,r1,i0)
|
|
static void _lshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define rshr(r0,r1,r2) SRA(r1,r2,r0)
|
|
# define rshi(r0,r1,i0) _rshi(_jit,r0,r1,i0)
|
|
static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define rshr_u(r0,r1,r2) SRL(r1,r2,r0)
|
|
# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0)
|
|
static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define andr(r0,r1,r2) AND(r1,r2,r0)
|
|
# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0)
|
|
static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define orr(r0,r1,r2) OR(r1,r2,r0)
|
|
# define ori(r0,r1,i0) _ori(_jit,r0,r1,i0)
|
|
static void _ori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define xorr(r0,r1,r2) XOR(r1,r2,r0)
|
|
# define xori(r0,r1,i0) _xori(_jit,r0,r1,i0)
|
|
static void _xori(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define ltr(r0,r1,r2) CMPLT(r1,r2,r0)
|
|
# define lti(r0,r1,i0) _lti(_jit,r0,r1,i0)
|
|
static void _lti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define ltr_u(r0,r1,r2) CMPULT(r1,r2,r0)
|
|
# define lti_u(r0,r1,i0) _lti_u(_jit,r0,r1,i0)
|
|
static void _lti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define ler(r0,r1,r2) CMPLE(r1,r2,r0)
|
|
# define lei(r0,r1,i0) _lei(_jit,r0,r1,i0)
|
|
static void _lei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define ler_u(r0,r1,r2) CMPULE(r1,r2,r0)
|
|
# define lei_u(r0,r1,i0) _lei_u(_jit,r0,r1,i0)
|
|
static void _lei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define eqr(r0,r1,r2) CMPEQ(r1,r2,r0)
|
|
# define eqi(r0,r1,i0) _eqi(_jit,r0,r1,i0)
|
|
static void _eqi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define ger(r0,r1,r2) CMPLE(r2,r1,r0)
|
|
# define gei(r0,r1,i0) _gei(_jit,r0,r1,i0)
|
|
static void _gei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define ger_u(r0,r1,r2) CMPULE(r2,r1,r0)
|
|
# define gei_u(r0,r1,i0) _gei_u(_jit,r0,r1,i0)
|
|
static void _gei_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define gtr(r0,r1,r2) CMPLT(r2,r1,r0)
|
|
# define gti(r0,r1,i0) _gti(_jit,r0,r1,i0)
|
|
static void _gti(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define gtr_u(r0,r1,r2) CMPULT(r2,r1,r0)
|
|
# define gti_u(r0,r1,i0) _gti_u(_jit,r0,r1,i0)
|
|
static void _gti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define ner(r0,r1,r2) _ner(_jit,r0,r1,r2)
|
|
static void _ner(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define nei(r0,r1,i0) _nei(_jit,r0,r1,i0)
|
|
static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define bltr(i0,r0,r1) _bltr(_jit,i0,r0,r1)
|
|
static jit_word_t _bltr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define blti(i0,r0,i1) _blti(_jit,i0,r0,i1)
|
|
static jit_word_t _blti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
|
|
# define bltr_u(i0,r0,r1) _bltr_u(_jit,i0,r0,r1)
|
|
static jit_word_t _bltr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define blti_u(i0,r0,i1) _blti_u(_jit,i0,r0,i1)
|
|
static jit_word_t _blti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
|
|
# define bler(i0,r0,r1) _bler(_jit,i0,r0,r1)
|
|
static jit_word_t _bler(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define blei(i0,r0,i1) _blei(_jit,i0,r0,i1)
|
|
static jit_word_t _blei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
|
|
# define bler_u(i0,r0,r1) _bler_u(_jit,i0,r0,r1)
|
|
static jit_word_t _bler_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define blei_u(i0,r0,i1) _blei_u(_jit,i0,r0,i1)
|
|
static jit_word_t _blei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
|
|
# define beqr(i0,r0,r1) _beqr(_jit,i0,r0,r1)
|
|
static jit_word_t _beqr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define beqi(i0,r0,i1) _beqi(_jit,i0,r0,i1)
|
|
static jit_word_t _beqi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
|
|
# define bger(i0,r0,r1) _bger(_jit,i0,r0,r1)
|
|
static jit_word_t _bger(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define bgei(i0,r0,i1) _bgei(_jit,i0,r0,i1)
|
|
static jit_word_t _bgei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
|
|
# define bger_u(i0,r0,r1) _bger_u(_jit,i0,r0,r1)
|
|
static jit_word_t _bger_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define bgei_u(i0,r0,i1) _bgei_u(_jit,i0,r0,i1)
|
|
static jit_word_t _bgei_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
|
|
# define bgtr(i0,r0,r1) _bgtr(_jit,i0,r0,r1)
|
|
static jit_word_t _bgtr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define bgti(i0,r0,i1) _bgti(_jit,i0,r0,i1)
|
|
static jit_word_t _bgti(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
|
|
# define bgtr_u(i0,r0,r1) _bgtr_u(_jit,i0,r0,r1)
|
|
static jit_word_t _bgtr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define bgti_u(i0,r0,i1) _bgti_u(_jit,i0,r0,i1)
|
|
static jit_word_t _bgti_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
|
|
# define bner(i0,r0,r1) _bner(_jit,i0,r0,r1)
|
|
static jit_word_t _bner(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define bnei(i0,r0,i1) _bnei(_jit,i0,r0,i1)
|
|
static jit_word_t _bnei(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
|
|
# define baddr(i0,r0,r1,cc) _baddr(_jit,i0,r0,r1,cc)
|
|
static jit_word_t _baddr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t,
|
|
jit_bool_t);
|
|
# define baddi(i0,r0,i1,cc) _baddi(_jit,i0,r0,i1,cc)
|
|
static jit_word_t _baddi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t,
|
|
jit_bool_t);
|
|
# define baddr_u(i0,r0,r1,cc) _baddr_u(_jit,i0,r0,r1,cc)
|
|
static jit_word_t _baddr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t,
|
|
jit_bool_t);
|
|
# define baddi_u(i0,r0,i1,cc) _baddi_u(_jit,i0,r0,i1,cc)
|
|
static jit_word_t _baddi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t,
|
|
jit_bool_t);
|
|
# define boaddr(i0,r0,r1) baddr(i0,r0,r1,1)
|
|
# define boaddi(i0,r0,i1) baddi(i0,r0,i1,1)
|
|
# define boaddr_u(i0,r0,r1) baddr_u(i0,r0,r1,1)
|
|
# define boaddi_u(i0,r0,i1) baddi_u(i0,r0,i1,1)
|
|
# define bxaddr(i0,r0,r1) baddr(i0,r0,r1,0)
|
|
# define bxaddi(i0,r0,i1) baddi(i0,r0,i1,0)
|
|
# define bxaddr_u(i0,r0,r1) baddr_u(i0,r0,r1,0)
|
|
# define bxaddi_u(i0,r0,i1) baddi_u(i0,r0,i1,0)
|
|
# define bsubr(i0,r0,r1,cc) _bsubr(_jit,i0,r0,r1,cc)
|
|
static jit_word_t _bsubr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t,
|
|
jit_bool_t);
|
|
# define bsubi(i0,r0,i1,cc) _bsubi(_jit,i0,r0,i1,cc)
|
|
static jit_word_t _bsubi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t,
|
|
jit_bool_t);
|
|
# define bsubr_u(i0,r0,r1,cc) _bsubr_u(_jit,i0,r0,r1,cc)
|
|
static jit_word_t _bsubr_u(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t,
|
|
jit_bool_t);
|
|
# define bsubi_u(i0,r0,i1,cc) _bsubi_u(_jit,i0,r0,i1,cc)
|
|
static jit_word_t _bsubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t,
|
|
jit_bool_t);
|
|
# define bosubr(i0,r0,r1) bsubr(i0,r0,r1,1)
|
|
# define bosubi(i0,r0,i1) bsubi(i0,r0,i1,1)
|
|
# define bosubr_u(i0,r0,r1) bsubr_u(i0,r0,r1,1)
|
|
# define bosubi_u(i0,r0,i1) bsubi_u(i0,r0,i1,1)
|
|
# define bxsubr(i0,r0,r1) bsubr(i0,r0,r1,0)
|
|
# define bxsubi(i0,r0,i1) bsubi(i0,r0,i1,0)
|
|
# define bxsubr_u(i0,r0,r1) bsubr_u(i0,r0,r1,0)
|
|
# define bxsubi_u(i0,r0,i1) bsubi_u(i0,r0,i1,0)
|
|
# define bmxr(i0,r0,r1,cc) _bmxr(_jit,i0,r0,r1,cc)
|
|
static jit_word_t _bmxr(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t,
|
|
jit_bool_t);
|
|
# define bmxi(i0,r0,i1,cc) _bmxi(_jit,i0,r0,i1,cc)
|
|
static jit_word_t _bmxi(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t,
|
|
jit_bool_t);
|
|
# define bmsr(i0,r0,r1) bmxr(i0,r0,r1,1)
|
|
# define bmsi(i0,r0,i1) bmxi(i0,r0,i1,1)
|
|
# define bmcr(i0,r0,r1) bmxr(i0,r0,r1,0)
|
|
# define bmci(i0,r0,i1) bmxi(i0,r0,i1,0)
|
|
# define ldr_c(r0,r1) _ldr_c(_jit,r0,r1)
|
|
static void _ldr_c(jit_state_t*,jit_int32_t,jit_int32_t);
|
|
# define ldi_c(r0,i0) _ldi_c(_jit,r0,i0)
|
|
static void _ldi_c(jit_state_t*,jit_int32_t,jit_word_t);
|
|
# define ldr_uc(r0,r1) LDBU(r0,r1,0)
|
|
# define ldi_uc(r0,i0) _ldi_uc(_jit,r0,i0)
|
|
static void _ldi_uc(jit_state_t*,jit_int32_t,jit_word_t);
|
|
# define ldr_s(r0,r1) _ldr_s(_jit,r0,r1)
|
|
static void _ldr_s(jit_state_t*,jit_int32_t,jit_int32_t);
|
|
# define ldi_s(r0,i0) _ldi_s(_jit,r0,i0)
|
|
static void _ldi_s(jit_state_t*,jit_int32_t,jit_word_t);
|
|
# define ldr_us(r0,r1) LDWU(r0,r1,0)
|
|
# define ldi_us(r0,i0) _ldi_us(_jit,r0,i0)
|
|
static void _ldi_us(jit_state_t*,jit_int32_t,jit_word_t);
|
|
# define ldr_i(r0,r1) LDL(r0,r1,0)
|
|
# define ldi_i(r0,i0) _ldi_i(_jit,r0,i0)
|
|
static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t);
|
|
# define ldr_ui(r0,r1) _ldr_ui(_jit,r0,r1)
|
|
static void _ldr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
|
|
# define ldi_ui(r0,i0) _ldi_ui(_jit,r0,i0)
|
|
static void _ldi_ui(jit_state_t*,jit_int32_t,jit_word_t);
|
|
# define ldr(r0,r1) ldr_l(r0,r1)
|
|
# define ldr_l(r0,r1) LDQ(r0,r1,0)
|
|
# define ldi_l(r0,i0) _ldi_l(_jit,r0,i0)
|
|
static void _ldi_l(jit_state_t*,jit_int32_t,jit_word_t);
|
|
# define ldxr_c(r0,r1,r2) _ldxr_c(_jit,r0,r1,r2)
|
|
static void _ldxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define ldxi_c(r0,r1,i0) _ldxi_c(_jit,r0,r1,i0)
|
|
static void _ldxi_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define ldxr_uc(r0,r1,r2) _ldxr_uc(_jit,r0,r1,r2)
|
|
static void _ldxr_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define ldxi_uc(r0,r1,i0) _ldxi_uc(_jit,r0,r1,i0)
|
|
static void _ldxi_uc(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define ldxr_s(r0,r1,r2) _ldxr_s(_jit,r0,r1,r2)
|
|
static void _ldxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define ldxi_s(r0,r1,i0) _ldxi_s(_jit,r0,r1,i0)
|
|
static void _ldxi_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define ldxr_us(r0,r1,r2) _ldxr_us(_jit,r0,r1,r2)
|
|
static void _ldxr_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define ldxi_us(r0,r1,i0) _ldxi_us(_jit,r0,r1,i0)
|
|
static void _ldxi_us(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define ldxr_i(r0,r1,r2) _ldxr_i(_jit,r0,r1,r2)
|
|
static void _ldxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define ldxi_i(r0,r1,i0) _ldxi_i(_jit,r0,r1,i0)
|
|
static void _ldxi_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define ldxr_ui(r0,r1,r2) _ldxr_ui(_jit,r0,r1,r2)
|
|
static void _ldxr_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define ldxi_ui(r0,r1,i0) _ldxi_ui(_jit,r0,r1,i0)
|
|
static void _ldxi_ui(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define ldxr_l(r0,r1,r2) _ldxr_l(_jit,r0,r1,r2)
|
|
static void _ldxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define ldxi(r0,r1,i0) ldxi_l(r0,r1,i0)
|
|
# define ldxi_l(r0,r1,i0) _ldxi_l(_jit,r0,r1,i0)
|
|
static void _ldxi_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define str_c(r0,r1) STB(r1,r0,0)
|
|
# define sti_c(i0,r0) _sti_c(_jit,i0,r0)
|
|
static void _sti_c(jit_state_t*,jit_word_t,jit_int32_t);
|
|
# define str_s(r0,r1) STW(r1,r0,0)
|
|
# define sti_s(i0,r0) _sti_s(_jit,i0,r0)
|
|
static void _sti_s(jit_state_t*,jit_word_t,jit_int32_t);
|
|
# define str_i(r0,r1) STL(r1,r0,0)
|
|
# define sti_i(i0,r0) _sti_i(_jit,i0,r0)
|
|
static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t);
|
|
# define str(r0,r1) str_l(r0,r1)
|
|
# define str_l(r0,r1) STQ(r1,r0,0)
|
|
# define sti_l(i0,r0) _sti_l(_jit,i0,r0)
|
|
static void _sti_l(jit_state_t*,jit_word_t,jit_int32_t);
|
|
# define stxr_c(r0,r1,r2) _stxr_c(_jit,r0,r1,r2)
|
|
static void _stxr_c(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define stxi_c(i0,r0,r1) _stxi_c(_jit,i0,r0,r1)
|
|
static void _stxi_c(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define stxr_s(r0,r1,r2) _stxr_s(_jit,r0,r1,r2)
|
|
static void _stxr_s(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define stxi_s(i0,r0,r1) _stxi_s(_jit,i0,r0,r1)
|
|
static void _stxi_s(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define stxr_i(r0,r1,r2) _stxr_i(_jit,r0,r1,r2)
|
|
static void _stxr_i(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define stxi_i(i0,r0,r1) _stxi_i(_jit,i0,r0,r1)
|
|
static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define stxr_l(r0,r1,r2) _stxr_l(_jit,r0,r1,r2)
|
|
static void _stxr_l(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define stxi(i0,r0,r1) stxi_l(i0,r0,r1)
|
|
# define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1)
|
|
static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define extr_c(r0,r1) _extr_c(_jit,r0,r1)
|
|
static void _extr_c(jit_state_t*,jit_int32_t,jit_int32_t);
|
|
# define extr_uc(r0,r1) _extr_uc(_jit,r0,r1)
|
|
static void _extr_uc(jit_state_t*,jit_int32_t,jit_int32_t);
|
|
# define extr_s(r0,r1) _extr_s(_jit,r0,r1)
|
|
static void _extr_s(jit_state_t*,jit_int32_t,jit_int32_t);
|
|
# define extr_us(r0,r1) _extr_us(_jit,r0,r1)
|
|
static void _extr_us(jit_state_t*,jit_int32_t,jit_int32_t);
|
|
# define extr_i(r0,r1) _extr_i(_jit,r0,r1)
|
|
static void _extr_i(jit_state_t*,jit_int32_t,jit_int32_t);
|
|
# define extr_ui(r0,r1) _extr_ui(_jit,r0,r1)
|
|
static void _extr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
|
|
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
# define htonr(r0,r1) _htonr(_jit,r0,r1)
|
|
static void _htonr(jit_state_t*,jit_int32_t,jit_int32_t);
|
|
# else
|
|
# define htonr(r0,r1) movr(r0,r1)
|
|
# endif
|
|
# define jmpr(r0) JMP(_R31_REGNO,r0,0)
|
|
# define jmpi(i0) _jmpi(_jit,i0)
|
|
static void _jmpi(jit_state_t*, jit_word_t);
|
|
# define jmpi_p(i0) _jmpi_p(_jit,i0)
|
|
static jit_word_t _jmpi_p(jit_state_t*, jit_word_t);
|
|
#define callr(r0) _callr(_jit,r0)
|
|
static void _callr(jit_state_t*, jit_int32_t);
|
|
# define calli(i0) _calli(_jit,i0)
|
|
static void _calli(jit_state_t*, jit_word_t);
|
|
# define calli_p(i0) _calli_p(_jit,i0)
|
|
static jit_word_t _calli_p(jit_state_t*, jit_word_t);
|
|
# define prolog(node) _prolog(_jit,node)
|
|
static void _prolog(jit_state_t*,jit_node_t*);
|
|
# define epilog(node) _epilog(_jit,node)
|
|
static void _epilog(jit_state_t*,jit_node_t*);
|
|
# define patch_at(jump,label) _patch_at(_jit,jump,label)
|
|
static void _patch_at(jit_state_t*,jit_word_t,jit_word_t);
|
|
#endif
|
|
|
|
#if CODE
|
|
static void
|
|
_Pcd(jit_state_t *_jit, int o, unsigned int n)
|
|
{
|
|
assert(_u6_p(o));
|
|
assert(_u26_p(n));
|
|
ii((o<<26)|_u26(n));
|
|
}
|
|
|
|
static void
|
|
_Bra(jit_state_t *_jit, int o, int ra, int d)
|
|
{
|
|
assert(_u6_p(o));
|
|
assert(_u5_p(ra));
|
|
assert(_s21_p(d));
|
|
ii((o<<26)|(ra<<21)|_u21(d));
|
|
}
|
|
|
|
static void
|
|
_Mem(jit_state_t *_jit, int o, int ra, int rb, unsigned int d)
|
|
{
|
|
assert(_u6_p(o));
|
|
assert(_u5_p(ra));
|
|
assert(_u5_p(rb));
|
|
assert(_u16_p(d));
|
|
ii((o<<26)|(ra<<21)|(rb<<16)|_u16(d));
|
|
}
|
|
|
|
static void
|
|
_Mbr(jit_state_t *_jit, int o, int ra, int rb, int h, int d)
|
|
{
|
|
assert(_u6_p(o));
|
|
assert(_u5_p(ra));
|
|
assert(_u5_p(rb));
|
|
assert(_u2_p(h));
|
|
assert(_s14_p(d));
|
|
ii((o<<26)|(ra<<21)|(rb<<16)|(h<<14)|_u14(d));
|
|
}
|
|
|
|
static void
|
|
_Opr(jit_state_t *_jit, int o, int ra, int rb, unsigned int f, int rc)
|
|
{
|
|
assert(_u6_p(o));
|
|
assert(_u5_p(ra));
|
|
assert(_u5_p(rb));
|
|
assert(_u5_p(rc));
|
|
assert(_u11_p(f));
|
|
ii((o<<26)|(ra<<21)|(rb<<16)|(_u11(f)<<5)|rc);
|
|
}
|
|
|
|
static void
|
|
_Opi(jit_state_t *_jit, int o, int ra, unsigned int i, unsigned int f, int rc)
|
|
{
|
|
assert(_u6_p(o));
|
|
assert(_u5_p(ra));
|
|
assert(_u8_p(i));
|
|
assert(_u5_p(rc));
|
|
assert(_u7_p(f));
|
|
ii((o<<26)|(ra<<21)|(_u8(i)<<13)|(1<<12)|(_u7(f)<<5)|rc);
|
|
}
|
|
|
|
static void
|
|
_nop(jit_state_t *_jit, jit_int32_t i0)
|
|
{
|
|
for (; i0 > 0; i0 -= 4)
|
|
NOP();
|
|
assert(i0 == 0);
|
|
}
|
|
|
|
static void
|
|
_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
if (r0 != r1)
|
|
MOV(r1, r0);
|
|
}
|
|
|
|
static void
|
|
_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
jit_int16_t s0, s1, s2, s3;
|
|
s0 = i0;
|
|
s1 = i0 >> 16;
|
|
s2 = i0 >> 32;
|
|
s3 = i0 >> 48;
|
|
if (s0 < 0)
|
|
++s1;
|
|
if (s2 < 0)
|
|
++s3;
|
|
if (_u8_p(i0))
|
|
MOVi(_u8(i0), r0);
|
|
else if (_s16_p(i0))
|
|
LDA(r0, _R31_REGNO, _u16(s0));
|
|
else if (_s32_p(i0)) {
|
|
LDA(r0, _R31_REGNO, _u16(s0));
|
|
LDAH(r0, r0, _u16(s1));
|
|
}
|
|
else if (_u32_p(i0)) {
|
|
LDA(r0, _R31_REGNO, _u16(s0));
|
|
if (s1)
|
|
LDAH(r0, r0, _u16(s1));
|
|
lshi(r0, r0, 32);
|
|
rshi_u(r0, r0, 32);
|
|
}
|
|
else if (_u32(i0) == 0) {
|
|
LDA(r0, _R31_REGNO, _u16(s2));
|
|
if (s3)
|
|
LDAH(r0, r0, _u16(s3));
|
|
lshi(r0, r0, 32);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
LDA(r0, _R31_REGNO, _u16(s0));
|
|
LDA(rn(reg), _R31_REGNO, _u16(s2));
|
|
if (s1)
|
|
LDAH(r0, r0, _u16(s1));
|
|
if (s3)
|
|
LDAH(rn(reg), rn(reg), _u16(s3));
|
|
lshi(r0, r0, 32);
|
|
rshi_u(r0, r0, 32);
|
|
lshi(rn(reg), rn(reg), 32);
|
|
orr(r0, r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static jit_word_t
|
|
_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
jit_int16_t s0, s1, s2, s3;
|
|
w = _jit->pc.w;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
s0 = i0;
|
|
s1 = i0 >> 16;
|
|
s2 = i0 >> 32;
|
|
s3 = i0 >> 48;
|
|
if (s0 < 0)
|
|
++s1;
|
|
if (s2 < 0)
|
|
++s3;
|
|
LDA(r0, _R31_REGNO, _u16(s0));
|
|
LDA(rn(reg), _R31_REGNO, _u16(s2));
|
|
LDAH(r0, r0, _u16(s1));
|
|
LDAH(rn(reg), rn(reg), _u16(s3));
|
|
lshi(r0, r0, 32);
|
|
rshi_u(r0, r0, 32);
|
|
lshi(rn(reg), rn(reg), 32);
|
|
orr(r0, r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static void
|
|
_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_u8_p(i0))
|
|
ADDQi(r1, i0, r0);
|
|
else if (_s16_p(i0))
|
|
LDA(r0, r1, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
addr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_addcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
if (jit_carry == _NOREG)
|
|
jit_carry = jit_get_reg(jit_class_gpr);
|
|
if (r0 == r1) {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addr(rn(reg), r1, r2);
|
|
ltr_u(rn(jit_carry), rn(reg), r1);
|
|
movr(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
else {
|
|
addr(r0, r1, r2);
|
|
ltr_u(rn(jit_carry), r0, r1);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (jit_carry == _NOREG)
|
|
jit_carry = jit_get_reg(jit_class_gpr);
|
|
if (r0 == r1) {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addi(rn(reg), r1, i0);
|
|
ltr_u(rn(jit_carry), rn(reg), r1);
|
|
movr(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
else {
|
|
addi(r0, r1, i0);
|
|
ltr_u(rn(jit_carry), r0, r1);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_addxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
assert(jit_carry != _NOREG);
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movr(rn(reg), rn(jit_carry));
|
|
addcr(r0, r1, r2);
|
|
addcr(r0, r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
assert(jit_carry != _NOREG);
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movr(rn(reg), rn(jit_carry));
|
|
addci(r0, r1, i0);
|
|
addcr(r0, r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_u8_p(i0))
|
|
SUBQi(r1, i0, r0);
|
|
else if (_s16_p(-i0))
|
|
LDA(r0, r1, _u16(-i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
subr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_subcr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
if (jit_carry == _NOREG)
|
|
jit_carry = jit_get_reg(jit_class_gpr);
|
|
if (r0 == r1) {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
subr(rn(reg), r1, r2);
|
|
ltr_u(rn(jit_carry), r1, rn(reg));
|
|
movr(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
else {
|
|
subr(r0, r1, r2);
|
|
ltr_u(rn(jit_carry), r1, r0);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (jit_carry == _NOREG)
|
|
jit_carry = jit_get_reg(jit_class_gpr);
|
|
if (r0 == r1) {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addi(rn(reg), r1, -i0);
|
|
ltr_u(rn(jit_carry), r1, rn(reg));
|
|
movr(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
else {
|
|
addi(r0, r1, -i0);
|
|
ltr_u(rn(jit_carry), r1, r0);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_subxr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
assert(jit_carry != _NOREG);
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movr(rn(reg), rn(jit_carry));
|
|
subcr(r0, r1, r2);
|
|
subcr(r0, r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
assert(jit_carry != _NOREG);
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movr(rn(reg), rn(jit_carry));
|
|
subci(r0, r1, i0);
|
|
subcr(r0, r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_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;
|
|
if (_u8_p(i0))
|
|
MULQi(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
mulr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_qmulr(jit_state_t *_jit, jit_int32_t r0,
|
|
jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
|
|
{
|
|
jit_int32_t reg;
|
|
/* The only invalid condition is r0 == r1 */
|
|
jit_int32_t t2, t3, s2, s3;
|
|
if (r2 == r0 || r2 == r1) {
|
|
s2 = jit_get_reg(jit_class_gpr);
|
|
t2 = rn(s2);
|
|
movr(t2, r2);
|
|
}
|
|
else
|
|
t2 = r2;
|
|
if (r3 == r0 || r3 == r1) {
|
|
s3 = jit_get_reg(jit_class_gpr);
|
|
t3 = rn(s3);
|
|
movr(t3, r3);
|
|
}
|
|
else
|
|
t3 = r3;
|
|
qmulr_u(r0, r1, r2, r3);
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
/**/
|
|
rshi(rn(reg), t2, 63);
|
|
mulr(rn(reg), rn(reg), t3);
|
|
addr(r1, r1, rn(reg));
|
|
/**/
|
|
rshi(rn(reg), t3, 63);
|
|
mulr(rn(reg), rn(reg), t2);
|
|
addr(r1, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
if (t2 != r2)
|
|
jit_unget_reg(s2);
|
|
if (t3 != r3)
|
|
jit_unget_reg(s3);
|
|
}
|
|
|
|
static void
|
|
_qmuli(jit_state_t *_jit, jit_int32_t r0,
|
|
jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
qmulr(r0, r1, r2, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_qmulr_u(jit_state_t *_jit, jit_int32_t r0,
|
|
jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
|
|
{
|
|
jit_int32_t reg;
|
|
if (r0 == r2 || r0 == r3) {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
mulr(rn(reg), r2, r3);
|
|
}
|
|
else
|
|
mulr(r0, r2, r3);
|
|
UMULH(r2, r3, r1);
|
|
if (r0 == r2 || r0 == r3) {
|
|
movr(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_qmuli_u(jit_state_t *_jit, jit_int32_t r0,
|
|
jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_u8_p(i0)) {
|
|
if (r0 == r2) {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
muli(rn(reg), r2, i0);
|
|
}
|
|
else
|
|
muli(r0, r2, i0);
|
|
UMULHi(r2, i0, r1);
|
|
if (r0 == r2) {
|
|
movr(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
qmulr_u(r0, r1, r2, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static jit_word_t
|
|
__idiv(jit_word_t u, jit_word_t v)
|
|
{
|
|
return (u / v);
|
|
}
|
|
|
|
static void
|
|
_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
movr(_A0_REGNO, r1);
|
|
movr(_A1_REGNO, r2);
|
|
calli((jit_word_t)__idiv);
|
|
movr(r0, _V0_REGNO);
|
|
}
|
|
|
|
static void
|
|
_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
movr(_A0_REGNO, r1);
|
|
movi(_A1_REGNO, i0);
|
|
calli((jit_word_t)__idiv);
|
|
movr(r0, _V0_REGNO);
|
|
}
|
|
|
|
static jit_uword_t
|
|
__udiv(jit_uword_t u, jit_uword_t v)
|
|
{
|
|
return (u / v);
|
|
}
|
|
|
|
static void
|
|
_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
movr(_A0_REGNO, r1);
|
|
movr(_A1_REGNO, r2);
|
|
calli((jit_word_t)__udiv);
|
|
movr(r0, _V0_REGNO);
|
|
}
|
|
|
|
static void
|
|
_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
movr(_A0_REGNO, r1);
|
|
movi(_A1_REGNO, i0);
|
|
calli((jit_word_t)__udiv);
|
|
movr(r0, _V0_REGNO);
|
|
}
|
|
|
|
static jit_word_t
|
|
__irem(jit_word_t u, jit_word_t v)
|
|
{
|
|
return (u % v);
|
|
}
|
|
|
|
static void
|
|
_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
movr(_A0_REGNO, r1);
|
|
movr(_A1_REGNO, r2);
|
|
calli((jit_word_t)__irem);
|
|
movr(r0, _V0_REGNO);
|
|
}
|
|
|
|
static void
|
|
_remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
movr(_A0_REGNO, r1);
|
|
movi(_A1_REGNO, i0);
|
|
calli((jit_word_t)__irem);
|
|
movr(r0, _V0_REGNO);
|
|
}
|
|
|
|
static jit_uword_t
|
|
__urem(jit_uword_t u, jit_uword_t v)
|
|
{
|
|
return (u % v);
|
|
}
|
|
|
|
static void
|
|
_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
movr(_A0_REGNO, r1);
|
|
movr(_A1_REGNO, r2);
|
|
calli((jit_word_t)__urem);
|
|
movr(r0, _V0_REGNO);
|
|
}
|
|
|
|
static void
|
|
_remi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
movr(_A0_REGNO, r1);
|
|
movi(_A1_REGNO, i0);
|
|
calli((jit_word_t)__urem);
|
|
movr(r0, _V0_REGNO);
|
|
}
|
|
|
|
static jit_word_t
|
|
__idivrem(jit_word_t u, jit_word_t v, jit_word_t *rem)
|
|
{
|
|
*rem = u % v;
|
|
return (u / v);
|
|
}
|
|
|
|
static void
|
|
_qdivr(jit_state_t *_jit,
|
|
jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
|
|
{
|
|
movr(_A0_REGNO, r2);
|
|
movr(_A1_REGNO, r3);
|
|
subi(_A2_REGNO, _FP_REGNO, 8);
|
|
calli((jit_word_t)__idivrem);
|
|
movr(r0, _V0_REGNO);
|
|
ldxi(r1, _FP_REGNO, -8);
|
|
}
|
|
|
|
static void
|
|
_qdivi(jit_state_t *_jit,
|
|
jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
|
|
{
|
|
movr(_A0_REGNO, r2);
|
|
movi(_A1_REGNO, i0);
|
|
subi(_A2_REGNO, _FP_REGNO, 8);
|
|
calli((jit_word_t)__idivrem);
|
|
movr(r0, _V0_REGNO);
|
|
ldxi(r1, _FP_REGNO, -8);
|
|
}
|
|
|
|
static jit_word_t
|
|
__udivrem(jit_uword_t u, jit_uword_t v, jit_uword_t *rem)
|
|
{
|
|
*rem = u % v;
|
|
return (u / v);
|
|
}
|
|
|
|
static void
|
|
_qdivr_u(jit_state_t *_jit,
|
|
jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
|
|
{
|
|
movr(_A0_REGNO, r2);
|
|
movr(_A1_REGNO, r3);
|
|
subi(_A2_REGNO, _FP_REGNO, 8);
|
|
calli((jit_word_t)__udivrem);
|
|
movr(r0, _V0_REGNO);
|
|
ldxi(r1, _FP_REGNO, -8);
|
|
}
|
|
|
|
static void
|
|
_qdivi_u(jit_state_t *_jit,
|
|
jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_word_t i0)
|
|
{
|
|
movr(_A0_REGNO, r2);
|
|
movi(_A1_REGNO, i0);
|
|
subi(_A2_REGNO, _FP_REGNO, 8);
|
|
calli((jit_word_t)__udivrem);
|
|
movr(r0, _V0_REGNO);
|
|
ldxi(r1, _FP_REGNO, -8);
|
|
}
|
|
|
|
static void
|
|
_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
assert(i0 >= 0 && i0 < 64);
|
|
SLLi(r1, i0, r0);
|
|
}
|
|
|
|
static void
|
|
_rshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
assert(i0 >= 0 && i0 < 64);
|
|
SRAi(r1, i0, r0);
|
|
}
|
|
|
|
static void
|
|
_rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
assert(i0 >= 0 && i0 < 64);
|
|
SRLi(r1, i0, r0);
|
|
}
|
|
|
|
static void
|
|
_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_u8_p(i0))
|
|
ANDi(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
andr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_u8_p(i0))
|
|
ORi(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
orr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_u8_p(i0))
|
|
XORi(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
xorr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_lti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_u8_p(i0))
|
|
CMPLTi(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ltr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_lti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_u8_p(i0))
|
|
CMPULTi(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ltr_u(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_lei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_u8_p(i0))
|
|
CMPLEi(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ler(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_lei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
jit_word_t ni0;
|
|
ni0 = -i0;
|
|
if (_u8_p(i0))
|
|
CMPULEi(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ler_u(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_eqi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_u8_p(i0))
|
|
CMPEQi(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
eqr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_gei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ger(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_gei_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ger_u(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_gti(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
gtr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_gti_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
gtr_u(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_ner(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
CMPEQ(r1, r2, r0);
|
|
CMPEQi(r0, 0, r0);
|
|
}
|
|
|
|
static void
|
|
_nei(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_u8_p(i0)) {
|
|
CMPEQi(r1, i0, r0);
|
|
CMPEQi(r0, 0, r0);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ner(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static jit_word_t
|
|
_bltr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
ltr(rn(reg), r0, r1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_blti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
if (i1 == 0) {
|
|
w = _jit->pc.w;
|
|
BLT(r0, ((i0 - w) >> 2) - 1);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
lti(rn(reg), r0, i1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bltr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
ltr_u(rn(reg), r0, r1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_blti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
/* FIXME cannot optimize zero because need to return a patcheable address */
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
lti_u(rn(reg), r0, i1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bler(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
ler(rn(reg), r0, r1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_blei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
if (i1 == 0) {
|
|
w = _jit->pc.w;
|
|
BLE(r0, ((i0 - w) >> 2) - 1);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
lei(rn(reg), r0, i1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bler_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
ler_u(rn(reg), r0, r1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_blei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
if (i1 == 0) {
|
|
w = _jit->pc.w;
|
|
BEQ(r0, ((i0 - w) >> 2) - 1);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
lei_u(rn(reg), r0, i1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_beqr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
eqr(rn(reg), r0, r1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_beqi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
if (i1 == 0) {
|
|
w = _jit->pc.w;
|
|
BEQ(r0, ((i0 - w) >> 2) - 1);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
eqi(rn(reg), r0, i1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bger(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
ger(rn(reg), r0, r1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bgei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
if (i1 == 0) {
|
|
w = _jit->pc.w;
|
|
BGE(r0, ((i0 - w) >> 2) - 1);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
gei(rn(reg), r0, i1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bger_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
ger_u(rn(reg), r0, r1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bgei_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
/* always true if i1 == 0 */
|
|
if (i0 == 0) {
|
|
w = _jit->pc.w;
|
|
BR(r0, ((i0 - w) >> 2) - 1);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
gei_u(rn(reg), r0, i1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bgtr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
gtr(rn(reg), r0, r1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bgti(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
if (i1 == 0) {
|
|
w = _jit->pc.w;
|
|
BGT(r0, ((i0 - w) >> 2) - 1);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
gti(rn(reg), r0, i1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bgtr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
gtr_u(rn(reg), r0, r1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bgti_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
gti_u(rn(reg), r0, i1);
|
|
w = _jit->pc.w;
|
|
BNE(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bner(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
eqr(rn(reg), r0, r1);
|
|
w = _jit->pc.w;
|
|
BEQ(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bnei(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
if (i1 == 0) {
|
|
w = _jit->pc.w;
|
|
BNE(r0, ((i0 - w) >> 2) - 1);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
eqi(rn(reg), r0, i1);
|
|
w = _jit->pc.w;
|
|
BEQ(rn(reg), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_baddr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1,
|
|
jit_bool_t carry)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t t0;
|
|
jit_int32_t t1;
|
|
jit_int32_t t2;
|
|
jit_int32_t t3;
|
|
/* t0 = r0 + r1; overflow = r1 < 0 ? r0 < t0 : t0 < r0 */
|
|
t0 = jit_get_reg(jit_class_gpr);
|
|
t1 = jit_get_reg(jit_class_gpr);
|
|
t2 = jit_get_reg(jit_class_gpr);
|
|
t3 = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
addr(rn(t0), r0, r1); /* t0 = r0 + r1 */
|
|
ltr(rn(t1), r1, _R31_REGNO); /* t1 = r1 < 0 */
|
|
ltr(rn(t2), r0, rn(t0)); /* t2 = r0 < t0 */
|
|
ltr(rn(t3), rn(t0), r0); /* t3 = t0 < r0 */
|
|
movr(r0, rn(t0)); /* r0 += r1 */
|
|
CMOVNE(rn(t1), rn(t2), rn(t3)); /* if (t1 == 0) t3 = t2; */
|
|
jit_unget_reg(t2);
|
|
jit_unget_reg(t1);
|
|
jit_unget_reg(t0);
|
|
w = _jit->pc.w;
|
|
if (carry)
|
|
BNE(rn(t3), ((i0 - w) >> 2) - 1);
|
|
else
|
|
BEQ(rn(t3), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(t3);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_baddi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1,
|
|
jit_bool_t carry)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
movi(rn(reg), i1);
|
|
w = baddr(i0, r0, rn(reg), carry);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_baddr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1,
|
|
jit_bool_t carry)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t t0;
|
|
jit_int32_t t1;
|
|
t0 = jit_get_reg(jit_class_gpr);
|
|
t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
addr(rn(t0), r0, r1);
|
|
ltr_u(rn(t1), rn(t0), r0);
|
|
movr(r0, rn(t0));
|
|
jit_unget_reg(t0);
|
|
w = _jit->pc.w;
|
|
if (carry)
|
|
BNE(rn(t1), ((i0 - w) >> 2) - 1);
|
|
else
|
|
BEQ(rn(t1), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(t1);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_baddi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1,
|
|
jit_bool_t carry)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t t0;
|
|
jit_int32_t t1;
|
|
t0 = jit_get_reg(jit_class_gpr);
|
|
t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
addi(rn(t0), r0, i1);
|
|
ltr_u(rn(t1), rn(t0), r0);
|
|
movr(r0, rn(t0));
|
|
jit_unget_reg(t0);
|
|
w = _jit->pc.w;
|
|
if (carry)
|
|
BNE(rn(t1), ((i0 - w) >> 2) - 1);
|
|
else
|
|
BEQ(rn(t1), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(t1);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bsubr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1,
|
|
jit_bool_t carry)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t t0;
|
|
jit_int32_t t1;
|
|
jit_int32_t t2;
|
|
jit_int32_t t3;
|
|
/* t0 = r0 - r1; overflow = 0 < r1 ? r0 < t0 : t0 < r0 */
|
|
t0 = jit_get_reg(jit_class_gpr);
|
|
t1 = jit_get_reg(jit_class_gpr);
|
|
t2 = jit_get_reg(jit_class_gpr);
|
|
t3 = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
subr(rn(t0), r0, r1); /* r0 = r0 - r1 */
|
|
ltr(rn(t1), _R31_REGNO, r1); /* t1 = 0 < r1 */
|
|
ltr(rn(t2), r0, rn(t0)); /* t2 = r0 < t0 */
|
|
ltr(rn(t3), rn(t0), r0); /* t3 = t0 < r0 */
|
|
movr(r0, rn(t0)); /* r0 -= r1 */
|
|
CMOVNE(rn(t1), rn(t2), rn(t3)); /* if (t1 == 0) t3 = t2; */
|
|
jit_unget_reg(t2);
|
|
jit_unget_reg(t1);
|
|
jit_unget_reg(t0);
|
|
w = _jit->pc.w;
|
|
if (carry)
|
|
BNE(rn(t3), ((i0 - w) >> 2) - 1);
|
|
else
|
|
BEQ(rn(t3), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(t3);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bsubi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1,
|
|
jit_bool_t carry)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
movi(rn(reg), i1);
|
|
w = bsubr(i0, r0, rn(reg), carry);
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bsubr_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1,
|
|
jit_bool_t carry)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t t0;
|
|
jit_int32_t t1;
|
|
t0 = jit_get_reg(jit_class_gpr);
|
|
t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
subr(rn(t0), r0, r1);
|
|
ltr_u(rn(t1), r0, rn(t0));
|
|
movr(r0, rn(t0));
|
|
jit_unget_reg(t0);
|
|
w = _jit->pc.w;
|
|
if (carry)
|
|
BNE(rn(t1), ((i0 - w) >> 2) - 1);
|
|
else
|
|
BEQ(rn(t1), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(t1);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1,
|
|
jit_bool_t carry)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t t0;
|
|
jit_int32_t t1;
|
|
t0 = jit_get_reg(jit_class_gpr);
|
|
t1 = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
subi(rn(t0), r0, i1);
|
|
ltr_u(rn(t1), r0, rn(t0));
|
|
movr(r0, rn(t0));
|
|
jit_unget_reg(t0);
|
|
w = _jit->pc.w;
|
|
if (carry)
|
|
BNE(rn(t1), ((i0 - w) >> 2) - 1);
|
|
else
|
|
BEQ(rn(t1), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(t1);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bmxr(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1,
|
|
jit_bool_t set)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t t0;
|
|
t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
andr(rn(t0), r0, r1);
|
|
w = _jit->pc.w;
|
|
if (set)
|
|
BNE(rn(t0), ((i0 - w) >> 2) - 1);
|
|
else
|
|
BEQ(rn(t0), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(t0);
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bmxi(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1,
|
|
jit_bool_t set)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t t0;
|
|
t0 = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
andi(rn(t0), r0, i1);
|
|
w = _jit->pc.w;
|
|
if (set)
|
|
BNE(rn(t0), ((i0 - w) >> 2) - 1);
|
|
else
|
|
BEQ(rn(t0), ((i0 - w) >> 2) - 1);
|
|
jit_unget_reg(t0);
|
|
return (w);
|
|
}
|
|
|
|
static void
|
|
_ldr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
ldr_uc(r0, r1);
|
|
extr_c(r0, r0);
|
|
}
|
|
|
|
static void
|
|
_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0)) {
|
|
LDBU(r0, _R31_REGNO, _u16(i0));
|
|
extr_c(r0, r0);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldr_c(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldi_uc(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
LDBU(r0, _R31_REGNO, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldr_uc(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
ldr_us(r0, r1);
|
|
extr_s(r0, r0);
|
|
}
|
|
|
|
static void
|
|
_ldi_s(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0)) {
|
|
LDWU(r0, _R31_REGNO, _u16(i0));
|
|
extr_s(r0, r0);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldr_s(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldi_us(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
LDWU(r0, _R31_REGNO, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldr_us(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldi_i(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
LDL(r0, _R31_REGNO, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldr_i(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
ldr_i(r0, r1);
|
|
extr_ui(r0, r0);
|
|
}
|
|
|
|
static void
|
|
_ldi_ui(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0)) {
|
|
LDL(r0, _R31_REGNO, _u16(i0));
|
|
extr_ui(r0, r0);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldr_ui(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldi_l(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
LDQ(r0, _R31_REGNO, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldr_l(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addr(rn(reg), r1, r2);
|
|
ldr_c(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_ldxi_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0)) {
|
|
LDBU(r0, r1, _u16(i0));
|
|
extr_c(r0, r0);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addi(rn(reg), r1, i0);
|
|
ldr_c(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldxr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addr(rn(reg), r1, r2);
|
|
ldr_uc(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_ldxi_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
LDBU(r0, r1, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addi(rn(reg), r1, i0);
|
|
ldr_uc(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addr(rn(reg), r1, r2);
|
|
ldr_s(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0)) {
|
|
LDWU(r0, r1, _u16(i0));
|
|
extr_s(r0, r0);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addi(rn(reg), r1, i0);
|
|
ldr_s(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldxr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addr(rn(reg), r1, r2);
|
|
ldr_us(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
LDWU(r0, r1, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addi(rn(reg), r1, i0);
|
|
ldr_us(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addr(rn(reg), r1, r2);
|
|
ldr_i(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
LDL(r0, r1, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addi(rn(reg), r1, i0);
|
|
ldr_i(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldxr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addr(rn(reg), r1, r2);
|
|
ldr_ui(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0)) {
|
|
LDL(r0, r1, _u16(i0));
|
|
extr_ui(r0, r0);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addi(rn(reg), r1, i0);
|
|
ldr_ui(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addr(rn(reg), r1, r2);
|
|
ldr_l(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
LDQ(r0, r1, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addi(rn(reg), r1, i0);
|
|
ldr_l(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
STB(r0, _R31_REGNO, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
str_c(rn(reg), r0);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_sti_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
STW(r0, _R31_REGNO, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
str_s(rn(reg), r0);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_sti_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
STL(r0, _R31_REGNO, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
str_i(rn(reg), r0);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_sti_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
STQ(r0, _R31_REGNO, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
str_l(rn(reg), r0);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_stxr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addr(rn(reg), r0, r1);
|
|
str_c(rn(reg), r2);
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_stxi_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
STB(r1, r0, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addi(rn(reg), r0, i0);
|
|
str_c(rn(reg), r1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_stxr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addr(rn(reg), r0, r1);
|
|
str_s(rn(reg), r2);
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
STW(r1, r0, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addi(rn(reg), r0, i0);
|
|
str_s(rn(reg), r1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_stxr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addr(rn(reg), r0, r1);
|
|
str_i(rn(reg), r2);
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
STL(r1, r0, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addi(rn(reg), r0, i0);
|
|
str_i(rn(reg), r1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_stxr_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addr(rn(reg), r0, r1);
|
|
str_l(rn(reg), r2);
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_int32_t reg;
|
|
if (_s16_p(i0))
|
|
STQ(r1, r0, _u16(i0));
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
addi(rn(reg), r0, i0);
|
|
str_l(rn(reg), r1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_extr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
lshi(r0, r1, 56);
|
|
rshi(r0, r0, 56);
|
|
}
|
|
|
|
static void
|
|
_extr_uc(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
lshi(r0, r1, 56);
|
|
rshi_u(r0, r0, 56);
|
|
}
|
|
|
|
static void
|
|
_extr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
lshi(r0, r1, 48);
|
|
rshi(r0, r0, 48);
|
|
}
|
|
|
|
static void
|
|
_extr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
lshi(r0, r1, 48);
|
|
rshi_u(r0, r0, 48);
|
|
}
|
|
|
|
static void
|
|
_extr_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
lshi(r0, r1, 32);
|
|
rshi(r0, r0, 32);
|
|
}
|
|
|
|
static void
|
|
_extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
lshi(r0, r1, 32);
|
|
rshi_u(r0, r0, 32);
|
|
}
|
|
|
|
static void
|
|
_htonr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_int32_t t0;
|
|
jit_int32_t t1;
|
|
jit_int32_t t2;
|
|
assert(_jitc->function != NULL);
|
|
t0 = jit_get_reg(jit_class_fpr);
|
|
t1 = jit_get_reg(jit_class_gpr);
|
|
t2 = jit_get_reg(jit_class_gpr);
|
|
stxi(-8, _FP_REGNO, r1); /* r1 = ABCD EFGH */
|
|
LDG(rn(t0), _FP_REGNO, _u16(-8)); /* t0 = GHEF CDAB */
|
|
STT(rn(t0), _FP_REGNO, _u16(-8));
|
|
ldxi(rn(t1), _FP_REGNO, -8); /* t1 = GHEF CDAB */
|
|
lshi(rn(t2), rn(t1), 8); /* t2 = HEFC DAB. */
|
|
rshi_u(rn(t1), rn(t1), 8); /* t1 = .GHE FCDA */
|
|
ZAPi(rn(t2), 0x55, rn(t2)); /* t2 = H.F. D.B. */
|
|
ZAPi(rn(t1), 0xaa, rn(t1)); /* t1 = .G.E .C.A */
|
|
orr(r0, rn(t1), rn(t2)); /* r0 = HGFE DCBA */
|
|
jit_unget_reg(t2);
|
|
jit_unget_reg(t1);
|
|
jit_unget_reg(t0);
|
|
}
|
|
|
|
static void
|
|
_jmpi(jit_state_t *_jit, jit_word_t i0)
|
|
{
|
|
jit_word_t w;
|
|
jit_word_t d;
|
|
w = _jit->pc.w;
|
|
d = ((i0 - w) >> 2) - 1;
|
|
if (_s21_p(d))
|
|
BR(_R31_REGNO, d);
|
|
else
|
|
(void)jmpi_p(i0);
|
|
}
|
|
|
|
static jit_word_t
|
|
_jmpi_p(jit_state_t *_jit, jit_word_t i0)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
w = movi_p(rn(reg), i0);
|
|
jmpr(rn(reg));
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
static void
|
|
_callr(jit_state_t *_jit, jit_int32_t r0)
|
|
{
|
|
if (r0 != _PV_REGNO)
|
|
MOV(r0, _PV_REGNO);
|
|
JSR(_RA_REGNO, _PV_REGNO, 0);
|
|
}
|
|
|
|
static void
|
|
_calli(jit_state_t *_jit, jit_word_t i0)
|
|
{
|
|
jit_word_t w;
|
|
jit_word_t d;
|
|
w = _jit->pc.w;
|
|
d = ((i0 - w) >> 2) - 1;
|
|
if (_s21_p(d))
|
|
BSR(_RA_REGNO, d);
|
|
else
|
|
(void)calli_p(i0);
|
|
}
|
|
|
|
static jit_word_t
|
|
_calli_p(jit_state_t *_jit, jit_word_t i0)
|
|
{
|
|
jit_word_t w;
|
|
w = movi_p(_PV_REGNO, i0);
|
|
callr(_PV_REGNO);
|
|
return (w);
|
|
}
|
|
|
|
static void
|
|
_prolog(jit_state_t *_jit, jit_node_t *node)
|
|
{
|
|
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;
|
|
}
|
|
_jitc->function->stack = ((_jitc->function->self.alen -
|
|
_jitc->function->self.aoff) + 7) & -8;
|
|
/* ldgp gp, 0(pv) */
|
|
LDAH(_PV_REGNO, _GP_REGNO, 0);
|
|
LDA(_GP_REGNO, _GP_REGNO, 0);
|
|
/* callee save registers */
|
|
subi(_SP_REGNO, _SP_REGNO, stack_framesize);
|
|
stxi(0, _SP_REGNO, _RA_REGNO);
|
|
stxi(8, _SP_REGNO, _FP_REGNO);
|
|
# define SPILL(N, O) \
|
|
if (jit_regset_tstbit(&_jitc->function->regset, N)) \
|
|
stxi(O, _SP_REGNO, N##_REGNO)
|
|
# define SPILLD(N, O) \
|
|
if (jit_regset_tstbit(&_jitc->function->regset, N)) \
|
|
stxi_d(O, _SP_REGNO, N##_REGNO)
|
|
SPILL(_S0, 16);
|
|
SPILL(_S1, 24);
|
|
SPILL(_S2, 32);
|
|
SPILL(_S3, 40);
|
|
SPILL(_S4, 48);
|
|
SPILL(_S5, 56);
|
|
SPILLD(_F2, 64);
|
|
SPILLD(_F3, 72);
|
|
SPILLD(_F4, 80);
|
|
SPILLD(_F5, 88);
|
|
SPILLD(_F6, 96);
|
|
SPILLD(_F7, 104);
|
|
SPILLD(_F8, 112);
|
|
SPILLD(_F9, 120);
|
|
# undef SPILLD
|
|
# undef SPILL
|
|
movr(_FP_REGNO, _SP_REGNO);
|
|
/* alloca */
|
|
if (_jitc->function->stack)
|
|
subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack);
|
|
}
|
|
|
|
static void
|
|
_epilog(jit_state_t *_jit, jit_node_t *node)
|
|
{
|
|
if (_jitc->function->assume_frame)
|
|
return;
|
|
movr(_SP_REGNO, _FP_REGNO);
|
|
ldxi(_RA_REGNO, _SP_REGNO, 0);
|
|
ldxi(_FP_REGNO, _SP_REGNO, 8);
|
|
# define LOAD(N, O) \
|
|
if (jit_regset_tstbit(&_jitc->function->regset, N)) \
|
|
ldxi(N##_REGNO, _SP_REGNO, O)
|
|
# define LOADD(N, O) \
|
|
if (jit_regset_tstbit(&_jitc->function->regset, N)) \
|
|
ldxi_d(N##_REGNO, _SP_REGNO, O)
|
|
LOAD(_S0, 16);
|
|
LOAD(_S1, 24);
|
|
LOAD(_S2, 32);
|
|
LOAD(_S3, 40);
|
|
LOAD(_S4, 48);
|
|
LOAD(_S5, 56);
|
|
LOADD(_F2, 64);
|
|
LOADD(_F3, 72);
|
|
LOADD(_F4, 80);
|
|
LOADD(_F5, 88);
|
|
LOADD(_F6, 96);
|
|
LOADD(_F7, 104);
|
|
LOADD(_F8, 112);
|
|
LOADD(_F9, 120);
|
|
# undef LOADD
|
|
# undef LOAD
|
|
addi(_SP_REGNO, _SP_REGNO, stack_framesize);
|
|
RET(_R31_REGNO, _RA_REGNO, 1); /* 1 means procedure return
|
|
* 0 means no procedure return
|
|
* other values are reserved */
|
|
}
|
|
|
|
static void
|
|
_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
|
|
{
|
|
union {
|
|
jit_int32_t *i;
|
|
jit_word_t w;
|
|
} u;
|
|
jit_word_t d;
|
|
jit_int16_t s0, s1, s2, s3;
|
|
u.w = instr;
|
|
switch (_u6(u.i[0] >> 26)) {
|
|
/* BLT BLE BEQ BGE */
|
|
case 0x3a: case 0x3b: case 0x39: case 0x3e:
|
|
/* BGT BNE BLBC BLBS */
|
|
case 0x3f: case 0x3d: case 0x38: case 0x3c:
|
|
/* BR BSR */
|
|
case 0x30: case 0x34:
|
|
/* FBLT FBLE FBEQ FBGE */
|
|
case 0x32: case 0x33: case 0x31: case 0x36:
|
|
/* FBGT FBNE */
|
|
case 0x37: case 0x35:
|
|
d = ((label - instr) >> 2) - 1;
|
|
assert(_s21_p(d));
|
|
u.i[0] &= ~0x1fffff;
|
|
u.i[0] |= _u21(d);
|
|
break;
|
|
/* LDA */
|
|
case 0x08: /* movi_p */
|
|
s0 = label;
|
|
s1 = label >> 16;
|
|
s2 = label >> 32;
|
|
s3 = label >> 48;
|
|
if (s0 < 0)
|
|
++s1;
|
|
if (s2 < 0)
|
|
++s3;
|
|
u.i[0] &= ~0xffff;
|
|
u.i[0] |= _u16(s0);
|
|
/* LDA */
|
|
assert(_u6(u.i[1] >> 26) == 0x08);
|
|
u.i[1] &= ~0xffff;
|
|
u.i[1] |= _u16(s2);
|
|
/* LDAH */
|
|
assert(_u6(u.i[2] >> 26) == 0x09);
|
|
u.i[2] &= ~0xffff;
|
|
u.i[2] |= _u16(s1);
|
|
/* LDAH */
|
|
assert(_u6(u.i[3] >> 26) == 0x09);
|
|
u.i[3] &= ~0xffff;
|
|
u.i[3] |= _u16(s3);
|
|
/* SLL */
|
|
assert(_u6(u.i[4] >> 26) == 0x12 && _u7(u.i[4] >> 5) == 0x39);
|
|
/* SRL */
|
|
assert(_u6(u.i[5] >> 26) == 0x12 && _u7(u.i[5] >> 5) == 0x34);
|
|
/* SLL */
|
|
assert(_u6(u.i[6] >> 26) == 0x12 && _u7(u.i[6] >> 5) == 0x39);
|
|
/* BIS */
|
|
assert(_u6(u.i[7] >> 26) == 0x11 && _u7(u.i[7] >> 5) == 0x20);
|
|
break;
|
|
default:
|
|
abort();
|
|
}
|
|
}
|
|
#endif
|