mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
2568 lines
75 KiB
C
2568 lines
75 KiB
C
/*
|
|
* Copyright (C) 2013-2017, 2019 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 _G2_REGNO 0x02
|
|
# define _G3_REGNO 0x03
|
|
# define _G4_REGNO 0x04
|
|
# define _O0_REGNO 0x08
|
|
# define _O1_REGNO 0x09
|
|
# define _SP_REGNO 0x0e
|
|
# define _FP_REGNO 0x1e
|
|
# define _O7_REGNO 0x0f
|
|
# define _L0_REGNO 0x10
|
|
# define _L1_REGNO 0x11
|
|
# define _L2_REGNO 0x12
|
|
# define _L3_REGNO 0x13
|
|
# define _L4_REGNO 0x14
|
|
# define _L5_REGNO 0x15
|
|
# define _L6_REGNO 0x16
|
|
# define _L7_REGNO 0x17
|
|
# define _I7_REGNO 0x1f
|
|
/*
|
|
* - previous stack frame
|
|
* fp ----
|
|
* fp- local variables (in lightning, 8 bytes space for float conversion)
|
|
* fp- alloca
|
|
* sp+ stack arguments
|
|
* sp+ 6 words to save register arguments
|
|
* sp+ 1 word for hidden address of aggregate return value (32 bits only)
|
|
* sp+ 16 words for in and local registers
|
|
* sp ----
|
|
* decreasing memory address - next stack frame (not yet allocated)
|
|
*/
|
|
# define stack_framesize ((16 + (__WORDSIZE == 32) + 6) * sizeof(jit_word_t))
|
|
typedef union {
|
|
struct { uint32_t b: 2; } op;
|
|
struct { uint32_t _: 2; uint32_t b: 1; } a;
|
|
struct { uint32_t _: 2; uint32_t b: 5; } rd;
|
|
struct { uint32_t _: 2; uint32_t b: 30; } disp30;
|
|
struct { uint32_t _: 3; uint32_t b: 4; } cond;
|
|
struct { uint32_t _: 7; uint32_t b: 3; } op2;
|
|
struct { uint32_t _: 7; uint32_t b: 6; } op3;
|
|
struct { uint32_t _: 10; uint32_t b: 1; } cc1;
|
|
struct { uint32_t _: 10; uint32_t b: 22; } imm22;
|
|
struct { uint32_t _: 10; uint32_t b: 22; } disp22;
|
|
struct { uint32_t _: 11; uint32_t b: 1; } cc0;
|
|
struct { uint32_t _: 12; uint32_t b: 1; } p;
|
|
struct { uint32_t _: 13; uint32_t b: 19; } disp19;
|
|
struct { uint32_t _: 13; uint32_t b: 5; } rs1;
|
|
struct { uint32_t _: 18; uint32_t b: 1; } i;
|
|
struct { uint32_t _: 18; uint32_t b: 9; } opf;
|
|
struct { uint32_t _: 19; uint32_t b: 1; } x;
|
|
struct { uint32_t _: 19; uint32_t b: 8; } asi;
|
|
struct { uint32_t _: 19; uint32_t b: 6; } res;
|
|
struct { uint32_t _: 19; uint32_t b: 13; } simm13;
|
|
struct { uint32_t _: 20; uint32_t b: 7; } asix;
|
|
struct { uint32_t _: 20; uint32_t b: 6; } asis;
|
|
struct { uint32_t _: 26; uint32_t b: 6; } shim;
|
|
struct { uint32_t _: 25; uint32_t b: 7; } imm7;
|
|
struct { uint32_t _: 27; uint32_t b: 5; } rs2;
|
|
int32_t v;
|
|
} jit_instr_t;
|
|
# define ii(i) *_jit->pc.ui++ = i
|
|
# define s7_p(imm) ((imm) <= 63 && (imm) >= -64)
|
|
# define s13_p(imm) ((imm) <= 4095 && (imm) >= -4096)
|
|
# define s19_p(imm) ((imm) <= 262143 && (imm) >= -262144)
|
|
# define s22_p(imm) ((imm) <= 2097151 && (imm) >= -20971512)
|
|
# define s30_p(imm) ((imm) <= 536870911 && (imm) >= -536870912)
|
|
# define f1(op, disp30) _f1(_jit, op, disp30)
|
|
static void _f1(jit_state_t*,int32_t,int32_t);
|
|
# define f2r(op, rd, op2, imm22) _f2r(_jit, op, rd, op2, imm22)
|
|
static void _f2r(jit_state_t*,int32_t,int32_t,int32_t,int32_t);
|
|
# define f2b(op, a, cond, op2, disp22) _f2b(_jit, op, a, cond, op2, disp22)
|
|
static void
|
|
_f2b(jit_state_t*,int32_t,int32_t,int32_t,int32_t,int32_t);
|
|
# if __WORDSIZE == 64
|
|
# define f2bp(op,a,cond,op2,cc1,cc0,p,disp19) \
|
|
_f2bp(_jit,op,a,cond,op2,cc1,cc0,p,disp19)
|
|
static void
|
|
_f2bp(jit_state_t*,int32_t,int32_t,int32_t,int32_t,int32_t,
|
|
int32_t,int32_t,int32_t);
|
|
# endif
|
|
# define f3r(op, rd, op3, rs1, rs2) _f3r(_jit, op, rd, op3, rs1, rs2)
|
|
static void _f3r(jit_state_t*,
|
|
int32_t,int32_t,int32_t,int32_t,int32_t);
|
|
# if __WORDSIZE == 64
|
|
# define f3rx(op, rd, op3, rs1, rs2) _f3rx(_jit, op, rd, op3, rs1, rs2)
|
|
static void _f3rx(jit_state_t*,
|
|
int32_t,int32_t,int32_t,int32_t,int32_t);
|
|
# endif
|
|
# define f3i(op, rd, op3, rs1, simm13) _f3i(_jit, op, rd, op3, rs1, simm13)
|
|
static void _f3i(jit_state_t*,
|
|
int32_t,int32_t,int32_t,int32_t,int32_t);
|
|
# define f3s(op, rd, op3, rs1, simm13) _f3s(_jit, op, rd, op3, rs1, simm13)
|
|
static void _f3s(jit_state_t*,
|
|
int32_t,int32_t,int32_t,int32_t,int32_t);
|
|
# define f3t(cond, rs1, i, ri) _f3t(_jit, cond, rs1, i, ri)
|
|
static void _f3t(jit_state_t*,int32_t,int32_t,int32_t,int32_t)
|
|
maybe_unused;
|
|
# define f3a(op, rd, op3, rs1, rs2) _f3a(_jit, op, rd, op3, rs1, asi, rs2)
|
|
static void _f3a(jit_state_t*,int32_t,
|
|
int32_t,int32_t,int32_t,int32_t,int32_t)
|
|
maybe_unused;
|
|
# define LDSB(rs1, rs2, rd) f3r(3, rd, 9, rs1, rs2)
|
|
# define LDSBI(rs1, imm, rd) f3i(3, rd, 9, rs1, imm)
|
|
# define LDSH(rs1, rs2, rd) f3r(3, rd, 10, rs1, rs2)
|
|
# define LDSHI(rs1, imm, rd) f3i(3, rd, 10, rs1, imm)
|
|
# define LDUB(rs1, rs2, rd) f3r(3, rd, 1, rs1, rs2)
|
|
# define LDUBI(rs1, imm, rd) f3i(3, rd, 1, rs1, imm)
|
|
# define LDUH(rs1, rs2, rd) f3r(3, rd, 2, rs1, rs2)
|
|
# define LDUHI(rs1, imm, rd) f3i(3, rd, 2, rs1, imm)
|
|
# if __WORDSIZE == 32
|
|
# define LD(rs1, rs2, rd) f3r(3, rd, 0, rs1, rs2)
|
|
# define LDI(rs1, imm, rd) f3i(3, rd, 0, rs1, imm)
|
|
# define LDD(rs1, rs2, rd) f3r(3, rd, 3, rs1, rs2)
|
|
# define LDDI(rs1, imm, rd) f3i(3, rd, 3, rs1, imm)
|
|
# else
|
|
# define LDSW(rs1, rs2, rd) f3r(3, rd, 8, rs1, rs2)
|
|
# define LDSWI(rs1, imm, rd) f3i(3, rd, 8, rs1, imm)
|
|
# define LDUW(rs1, rs2, rd) f3r(3, rd, 0, rs1, rs2)
|
|
# define LDUWI(rs1, imm, rd) f3i(3, rd, 0, rs1, imm)
|
|
# define LDX(rs1, rs2, rd) f3r(3, rd, 11, rs1, rs2)
|
|
# define LDXI(rs1, imm, rd) f3i(3, rd, 11, rs1, imm)
|
|
# endif
|
|
# define LDSBA(rs1, rs2, asi, rd) f3a(3, rd, 25, rs1, asi, rs2)
|
|
# define LDSHA(rs1, rs2, asi, rd) f3a(3, rd, 26, rs1, asi, rs2)
|
|
# define LDUBA(rs1, rs2, asi, rd) f3a(3, rd, 17, rs1, asi, rs2)
|
|
# define LDUHA(rs1, rs2, asi, rd) f3a(3, rd, 18, rs1, asi, rs2)
|
|
# if __WORDSIZE == 32
|
|
# define LDA(rs1, rs2, asi, rd) f3a(3, rd, 16, rs1, asi, rs2)
|
|
# define LDDA(rs1, rs2, asi, rd) f3a(3, rd, 19, rs1, asi, rs2)
|
|
# else
|
|
# define LDSWA(rs1, rs2, asi, rd) f3a(3, rd, 24, rs1, asi, rs2)
|
|
# define LDUWA(rs1, rs2, asi, rd) f3a(3, rd, 16, rs1, asi, rs2)
|
|
# define LDXA(rs1, rs2, asi, rd) f3a(3, rd, 27, rs1, asi, rs2)
|
|
# endif
|
|
# define LDC(rs1, rs2, rd) f3r(3, rd, 48, rs1, rs2)
|
|
# define LDCI(rs1, imm, rd) f3i(3, rd, 48, rs1, imm)
|
|
# define LDDC(rs1, rs2, rd) f3r(3, rd, 51, rs1, rs2)
|
|
# define LDDCI(rs1, imm, rd) f3i(3, rd, 51, rs1, imm)
|
|
# define LDCSR(rs1, rs2, rd) f3r(3, rd, 49, rs1, rs2)
|
|
# define LDCSRI(rs1, imm, rd) f3i(3, rd, 49, rs1, imm)
|
|
# define STB(rd, rs1, rs2) f3r(3, rd, 5, rs1, rs2)
|
|
# define STBI(rd, rs1, imm) f3i(3, rd, 5, rs1, imm)
|
|
# define STH(rd, rs1, rs2) f3r(3, rd, 6, rs1, rs2)
|
|
# define STHI(rd, rs1, imm) f3i(3, rd, 6, rs1, imm)
|
|
# if __WORDSIZE == 32
|
|
# define ST(rd, rs1, rs2) f3r(3, rd, 4, rs1, rs2)
|
|
# define STI(rd, rs1, imm) f3i(3, rd, 4, rs1, imm)
|
|
# define STD(rrd, s1, rs2) f3r(3, rd, 7, rs1, rs2)
|
|
# define STDI(rd, rs1, imm) f3i(3, rd, 7, rs1, imm)
|
|
# else
|
|
# define STW(rd, rs1, rs2) f3r(3, rd, 4, rs1, rs2)
|
|
# define STWI(rd, rs1, imm) f3i(3, rd, 4, rs1, imm)
|
|
# define STX(rd, rs1, rs2) f3r(3, rd, 14, rs1, rs2)
|
|
# define STXI(rd, rs1, imm) f3i(3, rd, 14, rs1, imm)
|
|
# endif
|
|
# define STBA(rd, rs1, rs2) f3a(3, rd, 21, rs1, asi, rs2)
|
|
# define STHA(rd, rs1, rs2) f3a(3, rd, 22, rs1, asi, rs2)
|
|
# if __WORDSIZE == 32
|
|
# define STA(rd, rs1, rs2) f3a(3, rd, 20, rs1, asi, rs2)
|
|
# define STDA(rd, rs1, rs2) f3a(3, rd, 23, rs1, asi, rs2)
|
|
# else
|
|
# define STWA(rd, rs1, rs2) f3a(3, rd, 20, rs1, asi, rs2)
|
|
# define STXA(rd, rs1, rs2) f3a(3, rd, 30, rs1, asi, rs2)
|
|
# endif
|
|
# define STC(rd, rs1, rs2) f3r(3, rd, 52, rs1, rs2)
|
|
# define STCI(rd, rs1, imm) f3i(3, rd, 52, rs1, imm)
|
|
# define STDC(rd, rs1, rs2) f3r(3, rd, 55, rs1, rs2)
|
|
# define STDCI(rd, rs1, imm) f3i(3, rd, 55, rs1, imm)
|
|
# define STCSR(rd, rs1, rs2) f3r(3, rd, 53, rs1, rs2)
|
|
# define STCSRI(rd, rs1, imm) f3i(3, rd, 53, rs1, imm)
|
|
# define STDCQ(rd, rs1, rs2) f3r(3, rd, 54, rs1, rs2)
|
|
# define STDCQI(rd, rs1, imm) f3i(3, rd, 54, rs1, imm)
|
|
# define LDSTUB(rs1, rs2, rd) f3r(3, rd, 13, rs1, rs2)
|
|
# define LDSTUBI(rs1, imm, rd) f3r(3, rd, 13, rs1, imm)
|
|
# define LDSTUBA(rs1, rs2, asi, rd) f3a(3, rd, 21, rs1, asi, rs2)
|
|
# define SWAP(rs1, rs2, rd) f3r(3, rd, 15, rs1, rs2)
|
|
# define SWAPI(rs1, imm, rd) f3r(3, rd, 15, rs1, imm)
|
|
# define SWAPA(rs1, rs2, asi, rd) f3a(3, rd, 23, rs1, asi, rs2)
|
|
# define NOP() SETHI(0, 0)
|
|
# define HI(im) ((im) >> 10)
|
|
# define LO(im) ((im) & 0x3ff)
|
|
# define SETHI(im, rd) f2r(0, rd, 4, im)
|
|
# define AND(rs1, rs2, rd) f3r(2, rd, 1, rs1, rs2)
|
|
# define ANDI(rs1, imm, rd) f3i(2, rd, 1, rs1, imm)
|
|
# define ANDcc(rs1, rs2, rd) f3r(2, rd, 17, rs1, rs2)
|
|
# define ANDIcc(rs1, imm, rd) f3i(2, rd, 17, rs1, imm)
|
|
# define BTST(rs1, rs2) ANDcc(rs1, rs2, 0)
|
|
# define BTSTI(rs1, imm) ANDIcc(rs1, imm, 0)
|
|
# define ANDN(rs1, rs2, rd) f3r(2, rd, 5, rs1, rs2)
|
|
# define ANDNI(rs1, imm, rd) f3i(2, rd, 5, rs1, imm)
|
|
# define ANDNcc(rs1, rs2, rd) f3r(2, rd, 21, rs1, rs2)
|
|
# define ANDNIcc(rs1, imm, rd) f3i(2, rd, 21, rs1, imm)
|
|
# define OR(rs1, rs2, rd) f3r(2, rd, 2, rs1, rs2)
|
|
# define ORI(rs1, imm, rd) f3i(2, rd, 2, rs1, imm)
|
|
# define ORcc(rs1, rs2, rd) f3r(2, rd, 18, rs1, rs2)
|
|
# define ORIcc(rs1, imm, rd) f3i(2, rd, 18, rs1, imm)
|
|
# define ORN(rs1, rs2, rd) f3r(2, rd, 6, rs1, rs2)
|
|
# define ORNI(rs1, imm, rd) f3i(2, rd, 6, rs1, imm)
|
|
# define ORNcc(rs1, rs2, rd) f3r(2, rd, 22, rs1, rs2)
|
|
# define ORNIcc(rs1, imm, rd) f3i(2, rd, 22, rs1, imm)
|
|
# define XOR(rs1, rs2, rd) f3r(2, rd, 3, rs1, rs2)
|
|
# define XORI(rs1, imm, rd) f3i(2, rd, 3, rs1, imm)
|
|
# define XORcc(rs1, rs2, rd) f3r(2, rd, 19, rs1, rs2)
|
|
# define XORIcc(rs1, imm, rd) f3i(2, rd, 19, rs1, imm)
|
|
# define XNOR(rs1, rs2, rd) f3r(2, rd, 7, rs1, rs2)
|
|
# define XNORI(rs1, imm, rd) f3i(2, rd, 7, rs1, imm)
|
|
# define XNORcc(rs1, rs2, rd) f3r(2, rd, 23, rs1, rs2)
|
|
# define XNORIcc(rs1, imm, rd) f3i(2, rd, 23, rs1, imm)
|
|
# define SLL(rs1, rs2, rd) f3r(2, rd, 37, rs1, rs2)
|
|
# define SLLI(rs1, imm, rd) f3i(2, rd, 37, rs1, imm)
|
|
# define SRL(rs1, rs2, rd) f3r(2, rd, 38, rs1, rs2)
|
|
# define SRLI(rs1, imm, rd) f3i(2, rd, 38, rs1, imm)
|
|
# define SRA(rs1, rs2, rd) f3r(2, rd, 39, rs1, rs2)
|
|
# define SRAI(rs1, imm, rd) f3i(2, rd, 39, rs1, imm)
|
|
# if __WORDSIZE == 64
|
|
# define SLLX(rs1, rs2, rd) f3rx(2, rd, 37, rs1, rs2)
|
|
# define SLLXI(rs1, imm, rd) f3s(2, rd, 37, rs1, imm)
|
|
# define SRLX(rs1, rs2, rd) f3rx(2, rd, 38, rs1, rs2)
|
|
# define SRLXI(rs1, imm, rd) f3s(2, rd, 38, rs1, imm)
|
|
# define SRAX(rs1, rs2, rd) f3rx(2, rd, 39, rs1, rs2)
|
|
# define SRAXI(rs1, imm, rd) f3s(2, rd, 39, rs1, imm)
|
|
# endif
|
|
# define ADD(rs1, rs2, rd) f3r(2, rd, 0, rs1, rs2)
|
|
# define ADDI(rs1, imm, rd) f3i(2, rd, 0, rs1, imm)
|
|
# define ADDcc(rs1, rs2, rd) f3r(2, rd, 16, rs1, rs2)
|
|
# define ADDIcc(rs1, imm, rd) f3i(2, rd, 16, rs1, imm)
|
|
# define ADDX(rs1, rs2, rd) f3r(2, rd, 8, rs1, rs2)
|
|
# define ADDXI(rs1, imm, rd) f3i(2, rd, 8, rs1, imm)
|
|
# define ADDXcc(rs1, rs2, rd) f3r(2, rd, 24, rs1, rs2)
|
|
# define ADDXIcc(rs1, imm, rd) f3i(2, rd, 24, rs1, imm)
|
|
# define TADDcc(rs1, rs2, rd) f3r(2, rd, 32, rs1, rs2)
|
|
# define TADDIcc(rs1, imm, rd) f3i(2, rd, 32, rs1, imm)
|
|
# define TADDccTV(rs1, rs2, rd) f3r(2, rd, 34, rs1, rs2)
|
|
# define TADDIccTV(rs1, imm, rd) f3i(2, rd, 34, rs1, imm)
|
|
# define SUB(rs1, rs2, rd) f3r(2, rd, 4, rs1, rs2)
|
|
# define NEG(rs1, rd) SUB(0, rs1, rd)
|
|
# define SUBI(rs1, imm, rd) f3i(2, rd, 4, rs1, imm)
|
|
# define SUBcc(rs1, rs2, rd) f3r(2, rd, 20, rs1, rs2)
|
|
# define SUBIcc(rs1, imm, rd) f3i(2, rd, 20, rs1, imm)
|
|
# define CMP(rs1, rs2) SUBcc(rs1, rs2, 0)
|
|
# define CMPI(rs1, imm) SUBIcc(rs1, imm, 0)
|
|
# define SUBX(rs1, rs2, rd) f3r(2, rd, 12, rs1, rs2)
|
|
# define SUBXI(rs1, imm, rd) f3i(2, rd, 12, rs1, imm)
|
|
# define SUBXcc(rs1, rs2, rd) f3r(2, rd, 28, rs1, rs2)
|
|
# define SUBXIcc(rs1, imm, rd) f3i(2, rd, 28, rs1, imm)
|
|
# define TSUBcc(rs1, rs2, rd) f3r(2, rd, 33, rs1, rs2)
|
|
# define TDADDIcc(rs1, imm, rd) f3i(2, rd, 33, rs1, imm)
|
|
# define TSUBccTV(rs1, rs2, rd) f3r(2, rd, 35, rs1, rs2)
|
|
# define TSUBIccTV(rs1, imm, rd) f3i(2, rd, 35, rs1, imm)
|
|
# define MULScc(rs1, rs2, rd) f3r(2, rd, 36, rs1, rs2)
|
|
# define MULSIcc(rs1, imm, rd) f3i(2, rd, 36, rs1, imm)
|
|
# define UMUL(rs1, rs2, rd) f3r(2, rd, 10, rs1, rs2)
|
|
# define UMULI(rs1, imm, rd) f3i(2, rd, 10, rs1, imm)
|
|
# define SMUL(rs1, rs2, rd) f3r(2, rd, 11, rs1, rs2)
|
|
# define SMULI(rs1, imm, rd) f3i(2, rd, 11, rs1, imm)
|
|
# define UMULcc(rs1, rs2, rd) f3r(2, rd, 26, rs1, rs2)
|
|
# define UMULIcc(rs1, imm, rd) f3i(2, rd, 26, rs1, imm)
|
|
# define SMULcc(rs1, rs2, rd) f3r(2, rd, 27, rs1, rs2)
|
|
# define SMULIcc(rs1, imm, rd) f3i(2, rd, 27, rs1, imm)
|
|
# define UDIV(rs1, rs2, rd) f3r(2, rd, 14, rs1, rs2)
|
|
# define UDIVI(rs1, imm, rd) f3i(2, rd, 14, rs1, imm)
|
|
# define SDIV(rs1, rs2, rd) f3r(2, rd, 15, rs1, rs2)
|
|
# define SDIVI(rs1, imm, rd) f3i(2, rd, 15, rs1, imm)
|
|
# define UDIVcc(rs1, rs2, rd) f3r(2, rd, 30, rs1, rs2)
|
|
# define UDIVIcc(rs1, imm, rd) f3i(2, rd, 30, rs1, imm)
|
|
# define SDIVcc(rs1, rs2, rd) f3r(2, rd, 31, rs1, rs2)
|
|
# define SDIVIcc(rs1, imm, rd) f3i(2, rd, 31, rs1, imm)
|
|
# if __WORDSIZE == 64
|
|
# define MULX(rs1, rs2, rd) f3r(2, rd, 9, rs1, rs2)
|
|
# define MULXI(rs1, imm, rd) f3i(2, rd, 9, rs1, imm)
|
|
# define SDIVX(rs1, rs2, rd) f3r(2, rd, 45, rs1, rs2)
|
|
# define SDIVXI(rs1, imm, rd) f3i(2, rd, 45, rs1, imm)
|
|
# define UDIVX(rs1, rs2, rd) f3r(2, rd, 13, rs1, rs2)
|
|
# define UDIVXI(rs1, imm, rd) f3i(2, rd, 13, rs1, imm)
|
|
# endif
|
|
# define SAVE(rs1, rs2, rd) f3r(2, rd, 60, rs1, rs2)
|
|
# define SAVEI(rs1, imm, rd) f3i(2, rd, 60, rs1, imm)
|
|
# define RESTORE(rs1, rs2, rd) f3r(2, rd, 61, rs1, rs2)
|
|
# define RESTOREI(rs1, imm, rd) f3i(2, rd, 61, rs1, imm)
|
|
# define SPARC_BA 8 /* always */
|
|
# define SPARC_BN 0 /* never */
|
|
# define SPARC_BNE 9 /* not equal - not Z */
|
|
# define SPARC_BNZ SPARC_BNE
|
|
# define SPARC_BE 1 /* equal - Z */
|
|
# define SPARC_BZ SPARC_BE
|
|
# define SPARC_BG 10 /* greater - not (Z or (N xor V)) */
|
|
# define SPARC_BLE 2 /* less or equal - Z or (N xor V) */
|
|
# define SPARC_BGE 11 /* greater or equal - not (N xor V) */
|
|
# define SPARC_BL 3 /* less - N xor V */
|
|
# define SPARC_BGU 12 /* greater unsigned - not (C or Z) */
|
|
# define SPARC_BLEU 4 /* less or equal unsigned - C or Z */
|
|
# define SPARC_BCC 13 /* carry clear - not C */
|
|
# define SPARC_BGEU SPARC_BCC
|
|
# define SPARC_BCS 5 /* carry set - C */
|
|
# define SPARC_BLU SPARC_BCS
|
|
# define SPARC_BPOS 14 /* positive - not N */
|
|
# define SPARC_BNEG 6 /* negative - N */
|
|
# define SPARC_BVC 15 /* overflow clear - not V */
|
|
# define SPARC_BVS 7 /* overflow set - V */
|
|
/* Preferred BPcc integer branch opcodes */
|
|
# if __WORDSIZE == 64
|
|
# define SPARC_BPA 8 /* always - 1 */
|
|
# define SPARC_BPN 0 /* never - 0 */
|
|
# define SPARC_BPNE 9 /* not equal - not Z */
|
|
# define SPARC_BPE 1 /* equal - Z */
|
|
# define SPARC_BPG 10 /* greater - not (Z or (N xor V)) */
|
|
# define SPARC_BPLE 2 /* less or equal - Z or (N xor V) */
|
|
# define SPARC_BPGE 11 /* greater or equal - not (N xor V) */
|
|
# define SPARC_BPL 3 /* less - N xor V */
|
|
# define SPARC_BPGU 12 /* greater unsigned - not (C or V) */
|
|
# define SPARC_BPLEU 4 /* less or equal unsigned - C or Z */
|
|
# define SPARC_BPCC 13 /* carry clear (greater than or equal, unsigned) - not C */
|
|
# define SPARC_BPCS 5 /* carry set (less than, unsigned) - C */
|
|
# define SPARC_BPPOS 14 /* positive - not N */
|
|
# define SPARC_BPNEG 6 /* negative - N */
|
|
# define SPARC_BPVC 15 /* overflow clear - not V */
|
|
# define SPARC_BPVS 7 /* overflow set - V */
|
|
# endif
|
|
# define B(cc, imm) f2b(0, 0, cc, 2, imm)
|
|
# define Ba(cc, imm) f2b(0, 1, cc, 2, imm)
|
|
# define BA(imm) B(SPARC_BA, imm)
|
|
# define BAa(imm) Ba(SPARC_BA, imm)
|
|
# define BN(imm) B(SPARC_BN, imm)
|
|
# define BNa(imm) Ba(SPARC_BN, imm)
|
|
# define BNE(imm) B(SPARC_BNE, imm)
|
|
# define BNEa(imm) Ba(SPARC_BNE, imm)
|
|
# define BNZ(imm) BNE(imm)
|
|
# define BNZa(imm) BNEa(imm)
|
|
# define BE(imm) B(SPARC_BE, imm)
|
|
# define BEa(imm) Ba(SPARC_BE, imm)
|
|
# define BZ(imm) BE(imm)
|
|
# define BZa(imm) BEa(imm)
|
|
# define BG(imm) B(SPARC_BG, imm)
|
|
# define BGa(imm) Ba(SPARC_BG, imm)
|
|
# define BLE(imm) B(SPARC_BLE, imm)
|
|
# define BLEa(imm) Ba(SPARC_BLE, imm)
|
|
# define BGE(imm) B(SPARC_BGE, imm)
|
|
# define BGEa(imm) Ba(SPARC_BGE, imm)
|
|
# define BL(imm) B(SPARC_BL, imm)
|
|
# define BLa(imm) Ba(SPARC_BL, imm)
|
|
# define BGU(imm) B(SPARC_BGU, imm)
|
|
# define BGUa(imm) Ba(SPARC_BGU, imm)
|
|
# define BLEU(imm) B(SPARC_BLEU, imm)
|
|
# define BLEUa(imm) Ba(SPARC_BLEU, imm)
|
|
# define BCC(imm) B(SPARC_BCC, imm)
|
|
# define BCCa(imm) Ba(SPARC_BCC, imm)
|
|
# define BGEU(imm) BCC(imm)
|
|
# define BGEUa(imm) BCCa(imm)
|
|
# define BCS(imm) B(SPARC_BCS, imm)
|
|
# define BCSa(imm) Ba(SPARC_BCS, imm)
|
|
# define BLU(imm) BCS(imm)
|
|
# define BLUa(imm) BCSa(imm)
|
|
# define BPOS(imm) B(SPARC_BPOS, imm)
|
|
# define BPOSa(imm) Ba(SPARC_BPOS, imm)
|
|
# define BNEG(imm) B(SPARC_BNEG, imm)
|
|
# define BNEGa(imm) Ba(SPARC_BNEG, imm)
|
|
# define BVC(imm) B(SPARC_BVC, imm)
|
|
# define BVCa(imm) Ba(SPARC_BVC, imm)
|
|
# define BVS(imm) B(SPARC_BVS, imm)
|
|
# define BVSa(imm) Ba(SPARC_BVS, imm)
|
|
# if __WORDSIZE == 64
|
|
# define BPccap(cc,a,cc1, cc2,p,imm) f2bp(0, a, cc, 1, cc1, cc0, p, imm)
|
|
# define BPap(cc, imm) f2bp(0, 1, cc, 1, 1, 0, p, imm)
|
|
# define BPa(cc, imm) f2bp(0, 1, cc, 1, 1, 0, 1, imm)
|
|
# define BP(cc, imm) f2bp(0, 0, cc, 1, 1, 0, 1, imm)
|
|
# define BPA(imm) BP(SPARC_BPA, imm)
|
|
# define BPN(imm) BP(SPARC_BPN, imm)
|
|
# define BNPE(imm) BP(SPARC_BPNE, imm)
|
|
# define BPE(imm) BP(SPARC_BPE, imm)
|
|
# define BPG(imm) BP(SPARC_BPG, imm)
|
|
# define BPLE(imm) BP(SPARC_BPLE, imm)
|
|
# define BPGE(imm) BP(SPARC_BPGE, imm)
|
|
# define BPL(imm) BP(SPARC_BPL, imm)
|
|
# define BPGU(imm) BP(SPARC_BPGU, imm)
|
|
# define BPLEU(imm) BP(SPARC_BPLEU, imm)
|
|
# define BPCC(imm) BP(SPARC_BPCC, imm)
|
|
# define BPCS(imm) BP(SPARC_BPCS, imm)
|
|
# define BPPOS(imm) BP(SPARC_BPPOS, imm)
|
|
# define BPNEG(imm) BP(SPARC_BPNEG, imm)
|
|
# define BPVC(imm) BP(SPARC_BPVC, imm)
|
|
# define BPVS(imm) BP(SPARC_BPVS, imm)
|
|
# endif
|
|
# define SPARC_CBA 8 /* always */
|
|
# define SPARC_CBN 0 /* never */
|
|
# define SPARC_CB3 7 /* 3 */
|
|
# define SPARC_CB2 6 /* 2 */
|
|
# define SPARC_CB23 5 /* 2 or 3 */
|
|
# define SPARC_CB1 4 /* 1 */
|
|
# define SPARC_CB13 3 /* 1 or 3 */
|
|
# define SPARC_CB12 2 /* 1 or 2 */
|
|
# define SPARC_CB123 1 /* 1 or 2 or 3 */
|
|
# define SPARC_CB0 9 /* 0 */
|
|
# define SPARC_CB03 10 /* 0 or 3 */
|
|
# define SPARC_CB02 11 /* 0 or 2 */
|
|
# define SPARC_CB023 12 /* 0 or 2 or 3 */
|
|
# define SPARC_CB01 13 /* 0 or 1 */
|
|
# define SPARC_CB013 14 /* 0 or 1 or 3 */
|
|
# define SPARC_CB012 15 /* 0 or 1 or 2 */
|
|
# define CB(cc, imm) f2b(0, 0, cc, 7, imm)
|
|
# define CBa(cc, imm) f2b(0, 1, cc, 7, imm)
|
|
# define CBA(imm) CB(SPARC_CBA, imm)
|
|
# define CBAa(imm) CBa(SPARC_CBA, imm)
|
|
# define CBN(imm) CB(SPARC_CBN, imm)
|
|
# define CBNa(imm) CBa(SPARC_CBN, imm)
|
|
# define CB3(imm) CB(SPARC_CB3, imm)
|
|
# define CB3a(imm) CBa(SPARC_CB3, imm)
|
|
# define CB2(imm) CB(SPARC_CB2, imm)
|
|
# define CB2a(imm) CBa(SPARC_CB2, imm)
|
|
# define CB23(imm) CB(SPARC_CB23, imm)
|
|
# define CB23a(imm) CBa(SPARC_CB23, imm)
|
|
# define CB1(imm) CB(SPARC_CB1, imm)
|
|
# define CB1a(imm) CBa(SPARC_CB1, imm)
|
|
# define CB13(imm) CB(SPARC_CB13, imm)
|
|
# define CB13a(imm) CBa(SPARC_CB13, imm)
|
|
# define CB12(imm) CB(SPARC_CB12, imm)
|
|
# define CB12a(imm) CBa(SPARC_CB12, imm)
|
|
# define CB123(imm) CB(SPARC_CB123, imm)
|
|
# define CB123a(imm) CBa(SPARC_CB123, imm)
|
|
# define CB0(imm) CB(SPARC_CB0, imm)
|
|
# define CB0a(imm) CBa(SPARC_CB0, imm)
|
|
# define CB03(imm) CB(SPARC_CB03, imm)
|
|
# define CB03a(imm) CBa(SPARC_CB03, imm)
|
|
# define CB02(imm) CB(SPARC_CB02, imm)
|
|
# define CB02a(imm) CBa(SPARC_CB02, imm)
|
|
# define CB023(imm) CB(SPARC_CB103, imm)
|
|
# define CB023a(imm) CBa(SPARC_CB023, imm)
|
|
# define CB01(imm) CB(SPARC_CB01, imm)
|
|
# define CB01a(imm) CBa(SPARC_CB01, imm)
|
|
# define CB013(imm) CB(SPARC_CB013, imm)
|
|
# define CB013a(imm) CBa(SPARC_CB013, imm)
|
|
# define CB012(imm) CB(SPARC_CB012, imm)
|
|
# define CB012a(imm) CBa(SPARC_CB012, imm)
|
|
# define CALLI(imm) f1(1, imm)
|
|
# define CALL(r0) JMPL(_O7_REGNO, r0, 0)
|
|
# define RETL() JMPLI(0, _O7_REGNO, 8)
|
|
# define RET() JMPLI(0, _I7_REGNO, 8)
|
|
# define JMPL(rd, rs1, rs2) f3r(2, rd, 56, rs1, rs2)
|
|
# define JMPLI(rd, rs1, imm) f3i(2, rd, 56, rs1, imm)
|
|
# define RETT(rs1, rs2) f3r(2, 0, 57, rs1, rs2)
|
|
# define RETTI(rs1, imm) f3i(2, 0, 57, rs1, imm)
|
|
# define SPARC_TA 8 /* always */
|
|
# define SPARC_TN 0 /* never */
|
|
# define SPARC_TNE 9 /* not equal - not Z */
|
|
# define SPARC_TNZ SPARC_BNE
|
|
# define SPARC_TE 1 /* equal - Z */
|
|
# define SPARC_TZ SPARC_BE
|
|
# define SPARC_TG 10 /* greater - not (Z or (N xor V)) */
|
|
# define SPARC_TLE 2 /* less or equal - Z or (N xor V) */
|
|
# define SPARC_TGE 11 /* greater or equal - not (N xor V) */
|
|
# define SPARC_TL 3 /* less - N xor V */
|
|
# define SPARC_TGU 12 /* greater unsigned - not (C or Z) */
|
|
# define SPARC_TLEU 4 /* less or equal unsigned - C or Z */
|
|
# define SPARC_TCC 13 /* carry clear - not C */
|
|
# define SPARC_TGEU SPARC_BCC
|
|
# define SPARC_TCS 5 /* carry set - C */
|
|
# define SPARC_TLU SPARC_BCS
|
|
# define SPARC_TPOS 14 /* positive - not N */
|
|
# define SPARC_TNEG 6 /* negative - N */
|
|
# define SPARC_TVC 15 /* overflow clear - not V */
|
|
# define SPARC_TVS 7 /* overflow set - V */
|
|
# define T(cc, rs1, rs2) f3t(cc, rs1, 0, rs2)
|
|
# define TI(cc, rs1, imm) f3t(cc, rs1, 1, imm)
|
|
# define TA(rs1, rs2) T(SPARC_TA, rs1, rs2)
|
|
# define TAI(rs1, imm) TI(SPARC_TA, rs1, imm)
|
|
# define TN(rs1, rs2) T(SPARC_TN, rs1, rs2)
|
|
# define TNI(rs1, imm) TI(SPARC_TN, rs1, imm)
|
|
# define TNE(rs1, rs2) T(SPARC_TNE, rs1, rs2)
|
|
# define TNEI(rs1, imm) TI(SPARC_TNE, rs1, imm)
|
|
# define TNZ(rs1, rs2) TNE(rs1, rs2)
|
|
# define TNZI(rs1, imm) TNEI(rs1, imm)
|
|
# define TE(rs1, rs2) T(SPARC_TE, rs1, rs2)
|
|
# define TEI(rs1, imm) TI(SPARC_TE, rs1, imm)
|
|
# define TZ(rs1, rs2) TE(rs1, rs2)
|
|
# define TZI(rs1, imm) TEI(rs1, imm)
|
|
# define TG(rs1, rs2) T(SPARC_TG, rs1, rs2)
|
|
# define TGI(rs1, imm) TI(SPARC_TG, rs1, imm)
|
|
# define TLE(rs1, rs2) T(SPARC_TLE, rs1, rs2)
|
|
# define TLEI(rs1, imm) TI(SPARC_TLE, rs1, imm)
|
|
# define TGE(rs1, rs2) T(SPARC_TGE, rs1, rs2)
|
|
# define TGEI(rs1, imm) TI(SPARC_TGE, rs1, imm)
|
|
# define TL(rs1, rs2) T(SPARC_TL, rs1, rs2)
|
|
# define TLI(rs1, imm) TI(SPARC_TL, rs1, imm)
|
|
# define TGU(rs1, rs2) T(SPARC_TGU, rs1, rs2)
|
|
# define TGUI(rs1, imm) TI(SPARC_TGU, rs1, imm)
|
|
# define TLEU(rs1, rs2) T(SPARC_TLEU, rs1, rs2)
|
|
# define TLEUI(rs1, imm) TI(SPARC_TLEU, rs1, imm)
|
|
# define TCC(rs1, rs2) T(SPARC_TCC, rs1, rs2)
|
|
# define TCCI(rs1, imm) TI(SPARC_TCC, rs1, imm)
|
|
# define TGEU(rs1, rs2) TCC(rs1, rs2)
|
|
# define TGEUI(rs1, imm) TCCI(rs1, imm)
|
|
# define TCS(rs1, rs2) T(SPARC_TCC, rs1, rs2)
|
|
# define TCSI(rs1, imm) TI(SPARC_TCC, rs1, imm)
|
|
# define TLU(rs1, rs2) TCS(rs1, rs2)
|
|
# define TLUI(rs1, imm) TCSI(rs1, imm)
|
|
# define TPOS(rs1, rs2) T(SPARC_TPOS, rs1, rs2)
|
|
# define TPOSI(rs1, imm) TI(SPARC_TPOS, rs1, imm)
|
|
# define TNEG(rs1, rs2) T(SPARC_TNEG, rs1, rs2)
|
|
# define TNEGI(rs1, imm) TI(SPARC_TNEG, rs1, imm)
|
|
# define TVC(rs1, rs2) T(SPARC_TVC, rs1, rs2)
|
|
# define TVCI(rs1, imm) TI(SPARC_TVC, rs1, imm)
|
|
# define TVS(rs1, rs2) T(SPARC_TVS, rs1, rs2)
|
|
# define TVSI(rs1, imm) TI(SPARC_TVS, rs1, imm)
|
|
# define RDY(rd) f3r(2, rd, 40, 0, 0)
|
|
# define RDASR(rs1, rd) f3r(2, rd, 40, rs1, 0)
|
|
# define RDPSR(rd) f3r(2, rd, 41, 0, 0)
|
|
# define RDWIM(rd) f3r(2, rd, 42, 0, 0)
|
|
# define RDTBR(rd) f3r(2, rd, 43, 0, 0)
|
|
# define WRY(rs1, rs2) f3r(2, 0, 48, rs1, rs2)
|
|
# define WRYI(rs1, imm) f3i(2, 0, 48, rs1, imm)
|
|
# define WRASR(rs1, rs2, rd) f3r(2, rd, 48, rs1, rs2)
|
|
# define WRASRI(rs1, imm, rd) f3i(2, rd, 48, rs1, imm)
|
|
# define WRPSR(rs1, rs2, rd) f3r(2, rd, 49, rs1, rs2)
|
|
# define WRPSRI(rs1, imm, rd) f3i(2, rd, 49, rs1, imm)
|
|
# define WRWIM(rs1, rs2, rd) f3r(2, rd, 50, rs1, rs2)
|
|
# define WRWIMI(rs1, imm, rd) f3i(2, rd, 50, rs1, imm)
|
|
# define WRTBR(rs1, rs2, rd) f3r(2, rd, 51, rs1, rs2)
|
|
# define WRTBRI(rs1, imm, rd) f3i(2, rd, 51, rs1, imm)
|
|
# define STBAR() f3i(2, 0, 40, 15, 0)
|
|
# define UNIMP(imm) f2r(0, 0, 0, imm)
|
|
# define FLUSH(rs1, rs2) f3r(2, 0, 59, rs1, rs2)
|
|
# define FLUSHI(rs1, im) f3i(2, 0, 59, rs1, imm)
|
|
# define nop(i0) _nop(_jit, i0)
|
|
static void _nop(jit_state_t*, int32_t);
|
|
# define movr(r0, r1) _movr(_jit, r0, r1)
|
|
static void _movr(jit_state_t*, int32_t, int32_t);
|
|
# define movi(r0, i0) _movi(_jit, r0, i0)
|
|
static void _movi(jit_state_t*, int32_t, jit_word_t);
|
|
# define movi_p(r0, i0) _movi_p(_jit, r0, i0)
|
|
static jit_word_t _movi_p(jit_state_t*, int32_t, jit_word_t);
|
|
# define comr(r0, r1) XNOR(r1, 0, r0)
|
|
# define negr(r0, r1) NEG(r1, r0)
|
|
# define addr(r0, r1, r2) ADD(r1, r2, r0)
|
|
# define addi(r0, r1, i0) _addi(_jit, r0, r1, i0)
|
|
static void _addi(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# if __WORDSIZE == 32
|
|
# define addcr(r0, r1, r2) ADDcc(r1, r2, r0)
|
|
# else
|
|
# define addcr(r0, r1, r2) _addcr(_jit, r0, r1, r2)
|
|
static void _addcr(jit_state_t*, int32_t, int32_t, int32_t);
|
|
# endif
|
|
# define addci(r0, r1, i0) _addci(_jit, r0, r1, i0)
|
|
static void _addci(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# if __WORDSIZE == 32
|
|
# define addxr(r0, r1, r2) ADDXcc(r1, r2, r0)
|
|
# else
|
|
# define addxr(r0, r1, r2) _addxr(_jit, r0, r1, r2)
|
|
static void _addxr(jit_state_t*, int32_t, int32_t, int32_t);
|
|
# endif
|
|
# define addxi(r0, r1, i0) _addxi(_jit, r0, r1, i0)
|
|
static void _addxi(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# define subr(r0, r1, r2) SUB(r1, r2, r0)
|
|
# define subi(r0, r1, i0) _subi(_jit, r0, r1, i0)
|
|
static void _subi(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# if __WORDSIZE == 32
|
|
# define subcr(r0, r1, r2) SUBcc(r1, r2, r0)
|
|
# else
|
|
# define subcr(r0, r1, r2) _subcr(_jit, r0, r1, r2)
|
|
static void _subcr(jit_state_t*, int32_t, int32_t, int32_t);
|
|
# endif
|
|
# define subci(r0, r1, i0) _subci(_jit, r0, r1, i0)
|
|
static void _subci(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# if __WORDSIZE == 32
|
|
# define subxr(r0, r1, r2) SUBXcc(r1, r2, r0)
|
|
# else
|
|
# define subxr(r0, r1, r2) _subxr(_jit, r0, r1, r2)
|
|
static void _subxr(jit_state_t*, int32_t, int32_t, int32_t);
|
|
# endif
|
|
# define subxi(r0, r1, i0) _subxi(_jit, r0, r1, i0)
|
|
static void _subxi(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# define rsbi(r0, r1, i0) _rsbi(_jit, r0, r1, i0)
|
|
static void _rsbi(jit_state_t*,int32_t,int32_t,jit_word_t);
|
|
# if __WORDSIZE == 32
|
|
# define mulr(r0, r1, r2) UMUL(r1, r2, r0)
|
|
# else
|
|
# define mulr(r0, r1, r2) MULX(r1, r2, r0)
|
|
# endif
|
|
# define muli(r0, r1, i0) _muli(_jit, r0, r1, i0)
|
|
static void _muli(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# if __WORDSIZE == 32
|
|
# 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,cc) _iqmulr(_jit,r0,r1,r2,r3,cc)
|
|
static void _iqmulr(jit_state_t*,int32_t,int32_t,
|
|
int32_t,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,cc) _iqmuli(_jit,r0,r1,r2,i0,cc)
|
|
static void _iqmuli(jit_state_t*,int32_t,int32_t,
|
|
int32_t,jit_word_t,jit_bool_t);
|
|
# else
|
|
# define qmulr(r0,r1,r2,r3) _qmulr(_jit,r0,r1,r2,r3)
|
|
static void _qmulr(jit_state_t*,int32_t,int32_t,
|
|
int32_t,int32_t);
|
|
# define qmuli(r0,r1,r2,i0) _qmuli(_jit,r0,r1,r2,i0)
|
|
static void _qmuli(jit_state_t*,int32_t,int32_t,
|
|
int32_t,jit_word_t);
|
|
# define qmulr_u(r0,r1,r2,r3) _qmulr_u(_jit,r0,r1,r2,r3)
|
|
static void _qmulr_u(jit_state_t*,int32_t,int32_t,
|
|
int32_t,int32_t);
|
|
# define qmuli_u(r0,r1,r2,i0) _qmuli_u(_jit,r0,r1,r2,i0)
|
|
static void _qmuli_u(jit_state_t*,int32_t,int32_t,
|
|
int32_t,jit_word_t);
|
|
# endif
|
|
# define divr(r0, r1, r2) _divr(_jit, r0, r1, r2)
|
|
static void _divr(jit_state_t*, int32_t, int32_t, int32_t);
|
|
# define divi(r0, r1, i0) _divi(_jit, r0, r1, i0)
|
|
static void _divi(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# define divr_u(r0, r1, r2) _divr_u(_jit, r0, r1, r2)
|
|
static void _divr_u(jit_state_t*, int32_t, int32_t, int32_t);
|
|
# define divi_u(r0, r1, i0) _divi_u(_jit, r0, r1, i0)
|
|
static void _divi_u(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# define 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,cc) _iqdivr(_jit,r0,r1,r2,r3,cc)
|
|
static void _iqdivr(jit_state_t*,int32_t,int32_t,
|
|
int32_t,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,cc) _iqdivi(_jit,r0,r1,r2,i0,cc)
|
|
static void _iqdivi(jit_state_t*,int32_t,int32_t,
|
|
int32_t,jit_word_t,jit_bool_t);
|
|
# define remr(r0, r1, r2) _remr(_jit, r0, r1, r2)
|
|
static void _remr(jit_state_t*, int32_t, int32_t, int32_t);
|
|
# define remi(r0, r1, i0) _remi(_jit, r0, r1, i0)
|
|
static void _remi(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# define remr_u(r0, r1, r2) _remr_u(_jit, r0, r1, r2)
|
|
static void _remr_u(jit_state_t*, int32_t, int32_t, int32_t);
|
|
# define remi_u(r0, r1, i0) _remi_u(_jit, r0, r1, i0)
|
|
static void _remi_u(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# define andr(r0, r1, r2) AND(r1, r2, r0)
|
|
# define andi(r0, r1, i0) _andi(_jit, r0, r1, i0)
|
|
static void _andi(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# define orr(r0, r1, r2) OR(r1, r2, r0)
|
|
# define ori(r0, r1, i0) _ori(_jit, r0, r1, i0)
|
|
static void _ori(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# define xorr(r0, r1, r2) XOR(r1, r2, r0)
|
|
# define xori(r0, r1, i0) _xori(_jit, r0, r1, i0)
|
|
static void _xori(jit_state_t*, int32_t, int32_t, jit_word_t);
|
|
# if __WORDSIZE == 32
|
|
# define lshr(r0, r1, r2) SLL(r1, r2, r0)
|
|
# define lshi(r0, r1, i0) SLLI(r1, i0, r0)
|
|
# define rshr(r0, r1, r2) SRA(r1, r2, r0)
|
|
# define rshi(r0, r1, i0) SRAI(r1, i0, r0)
|
|
# define rshr_u(r0, r1, r2) SRL(r1, r2, r0)
|
|
# define rshi_u(r0, r1, i0) SRLI(r1, i0, r0)
|
|
# else
|
|
# define lshr(r0, r1, r2) SLLX(r1, r2, r0)
|
|
# define lshi(r0, r1, i0) SLLXI(r1, i0, r0)
|
|
# define rshr(r0, r1, r2) SRAX(r1, r2, r0)
|
|
# define rshi(r0, r1, i0) SRAXI(r1, i0, r0)
|
|
# define rshr_u(r0, r1, r2) SRLX(r1, r2, r0)
|
|
# define rshi_u(r0, r1, i0) SRLXI(r1, i0, r0)
|
|
# endif
|
|
# define bswapr_us(r0,r1) extr_us(r0,r1)
|
|
# define extr_c(r0,r1) _extr_c(_jit,r0,r1)
|
|
static void _extr_c(jit_state_t*,int32_t,int32_t);
|
|
# define extr_uc(r0,r1) andi(r0, r1, 0xff)
|
|
# define extr_s(r0,r1) _extr_s(_jit,r0,r1)
|
|
static void _extr_s(jit_state_t*,int32_t,int32_t);
|
|
# define extr_us(r0,r1) _extr_us(_jit,r0,r1)
|
|
static void _extr_us(jit_state_t*,int32_t,int32_t);
|
|
# if __WORDSIZE == 32
|
|
# define bswapr_ui(r0,r1) movr(r0,r1)
|
|
# else
|
|
# define bswapr_ui(r0,r1) extr_ui(r0,r1)
|
|
# define bswapr_ul(r0,r1) movr(r0,r1)
|
|
# define extr_i(r0,r1) _extr_i(_jit,r0,r1)
|
|
static void _extr_i(jit_state_t*,int32_t,int32_t);
|
|
# define extr_ui(r0,r1) _extr_ui(_jit,r0,r1)
|
|
static void _extr_ui(jit_state_t*,int32_t,int32_t);
|
|
# endif
|
|
# define cr(cc, r0, r1, r2) _cr(_jit, cc, r0, r1, r2)
|
|
static void _cr(jit_state_t*,int32_t,int32_t,int32_t,int32_t);
|
|
# define cw(cc, r0, r1, i0) _cw(_jit, cc, r0, r1, i0)
|
|
static void _cw(jit_state_t*,int32_t,int32_t,int32_t,jit_word_t);
|
|
# if __WORDSIZE == 32
|
|
# define ltr(r0, r1, r2) cr(SPARC_BL, r0, r1, r2)
|
|
# define lti(r0, r1, i0) cw(SPARC_BL, r0, r1, i0)
|
|
# define ltr_u(r0, r1, r2) cr(SPARC_BLU, r0, r1, r2)
|
|
# define lti_u(r0, r1, i0) cw(SPARC_BLU, r0, r1, i0)
|
|
# define ler(r0, r1, r2) cr(SPARC_BLE, r0, r1, r2)
|
|
# define lei(r0, r1, i0) cw(SPARC_BLE, r0, r1, i0)
|
|
# define ler_u(r0, r1, r2) cr(SPARC_BLEU, r0, r1, r2)
|
|
# define lei_u(r0, r1, i0) cw(SPARC_BLEU, r0, r1, i0)
|
|
# define eqr(r0, r1, r2) cr(SPARC_BE, r0, r1, r2)
|
|
# define eqi(r0, r1, i0) cw(SPARC_BE, r0, r1, i0)
|
|
# define ger(r0, r1, r2) cr(SPARC_BGE, r0, r1, r2)
|
|
# define gei(r0, r1, i0) cw(SPARC_BGE, r0, r1, i0)
|
|
# define ger_u(r0, r1, r2) cr(SPARC_BGEU, r0, r1, r2)
|
|
# define gei_u(r0, r1, i0) cw(SPARC_BGEU, r0, r1, i0)
|
|
# define gtr(r0, r1, r2) cr(SPARC_BG, r0, r1, r2)
|
|
# define gti(r0, r1, i0) cw(SPARC_BG, r0, r1, i0)
|
|
# define gtr_u(r0, r1, r2) cr(SPARC_BGU, r0, r1, r2)
|
|
# define gti_u(r0, r1, i0) cw(SPARC_BGU, r0, r1, i0)
|
|
# define ner(r0, r1, r2) cr(SPARC_BNE, r0, r1, r2)
|
|
# define nei(r0, r1, i0) cw(SPARC_BNE, r0, r1, i0)
|
|
# else
|
|
# define ltr(r0, r1, r2) cr(SPARC_BPL, r0, r1, r2)
|
|
# define lti(r0, r1, i0) cw(SPARC_BPL, r0, r1, i0)
|
|
# define ltr_u(r0, r1, r2) cr(SPARC_BPCS, r0, r1, r2)
|
|
# define lti_u(r0, r1, i0) cw(SPARC_BPCS, r0, r1, i0)
|
|
# define ler(r0, r1, r2) cr(SPARC_BPLE, r0, r1, r2)
|
|
# define lei(r0, r1, i0) cw(SPARC_BPLE, r0, r1, i0)
|
|
# define ler_u(r0, r1, r2) cr(SPARC_BPLEU, r0, r1, r2)
|
|
# define lei_u(r0, r1, i0) cw(SPARC_BPLEU, r0, r1, i0)
|
|
# define eqr(r0, r1, r2) cr(SPARC_BPE, r0, r1, r2)
|
|
# define eqi(r0, r1, i0) cw(SPARC_BPE, r0, r1, i0)
|
|
# define ger(r0, r1, r2) cr(SPARC_BPGE, r0, r1, r2)
|
|
# define gei(r0, r1, i0) cw(SPARC_BPGE, r0, r1, i0)
|
|
# define ger_u(r0, r1, r2) cr(SPARC_BPCC, r0, r1, r2)
|
|
# define gei_u(r0, r1, i0) cw(SPARC_BPCC, r0, r1, i0)
|
|
# define gtr(r0, r1, r2) cr(SPARC_BPG, r0, r1, r2)
|
|
# define gti(r0, r1, i0) cw(SPARC_BPG, r0, r1, i0)
|
|
# define gtr_u(r0, r1, r2) cr(SPARC_BPGU, r0, r1, r2)
|
|
# define gti_u(r0, r1, i0) cw(SPARC_BPGU, r0, r1, i0)
|
|
# define ner(r0, r1, r2) cr(SPARC_BPNE, r0, r1, r2)
|
|
# define nei(r0, r1, i0) cw(SPARC_BPNE, r0, r1, i0)
|
|
# endif
|
|
# define ldr_c(r0, r1) LDSB(r1, 0, r0)
|
|
# define ldi_c(r0, i0) _ldi_c(_jit, r0, i0)
|
|
static void _ldi_c(jit_state_t*,int32_t,jit_word_t);
|
|
# define ldr_uc(r0, r1) LDUB(r1, 0, r0)
|
|
# define ldi_uc(r0, i0) _ldi_uc(_jit, r0, i0)
|
|
static void _ldi_uc(jit_state_t*,int32_t,jit_word_t);
|
|
# define ldr_s(r0, r1) LDSH(r1, 0, r0)
|
|
# define ldi_s(r0, i0) _ldi_s(_jit, r0, i0)
|
|
static void _ldi_s(jit_state_t*,int32_t,jit_word_t);
|
|
# define ldr_us(r0, r1) LDUH(r1, 0, r0)
|
|
# define ldi_us(r0, i0) _ldi_us(_jit, r0, i0)
|
|
static void _ldi_us(jit_state_t*,int32_t,jit_word_t);
|
|
# if __WORDSIZE == 32
|
|
# define ldr_i(r0, r1) LD(r1, 0, r0)
|
|
# define ldr(u, v) ldr_i(u, v)
|
|
# define ldi(u, v) ldi_i(u, v)
|
|
# else
|
|
# define ldr_i(r0, r1) LDSW(r1, 0, r0)
|
|
# define ldr_ui(r0, r1) LDUW(r1, 0, r0)
|
|
# define ldr_l(r0, r1) LDX(r1, 0, r0)
|
|
# define ldr(u, v) ldr_l(u, v)
|
|
# define ldi(u, v) ldi_l(u, v)
|
|
# endif
|
|
# define ldi_i(r0, i0) _ldi_i(_jit, r0, i0)
|
|
static void _ldi_i(jit_state_t*,int32_t,jit_word_t);
|
|
# if __WORDSIZE == 64
|
|
# define ldi_ui(r0, i0) _ldi_ui(_jit, r0, i0)
|
|
static void _ldi_ui(jit_state_t*,int32_t,jit_word_t);
|
|
# define ldi_l(r0, i0) _ldi_l(_jit, r0, i0)
|
|
static void _ldi_l(jit_state_t*,int32_t,jit_word_t);
|
|
# endif
|
|
# define ldxr_c(r0, r1, r2) LDSB(r1, r2, r0)
|
|
# define ldxi_c(r0, r1, i0) _ldxi_c(_jit, r0, r1, i0)
|
|
static void _ldxi_c(jit_state_t*,int32_t,int32_t,jit_word_t);
|
|
# define ldxr_uc(r0, r1, r2) LDUB(r1, r2, r0)
|
|
# define ldxi_uc(r0, r1, i0) _ldxi_uc(_jit, r0, r1, i0)
|
|
static void _ldxi_uc(jit_state_t*,int32_t,int32_t,jit_word_t);
|
|
# define ldxr_s(r0, r1, r2) LDSH(r1, r2, r0)
|
|
# define ldxi_s(r0, r1, i0) _ldxi_s(_jit, r0, r1, i0)
|
|
static void _ldxi_s(jit_state_t*,int32_t,int32_t,jit_word_t);
|
|
# define ldxr_us(r0, r1, r2) LDUH(r1, r2, r0)
|
|
# define ldxi_us(r0, r1, i0) _ldxi_us(_jit, r0, r1, i0)
|
|
static void _ldxi_us(jit_state_t*,int32_t,int32_t,jit_word_t);
|
|
# if __WORDSIZE == 32
|
|
# define ldxr(u, v, w) ldxr_i(u, v, w)
|
|
# define ldxr_i(r0, r1, r2) LD(r1, r2, r0)
|
|
# define ldxi(u, v, w) ldxi_i(u, v, w)
|
|
# else
|
|
# define ldxr(u, v, w) ldxr_l(u, v, w)
|
|
# define ldxr_i(r0, r1, r2) LDSW(r1, r2, r0)
|
|
# define ldxr_ui(r0, r1, r2) LDUW(r1, r2, r0)
|
|
# define ldxr_l(r0, r1, r2) LDX(r1, r2, r0)
|
|
# define ldxi(u, v, w) ldxi_l(u, v, w)
|
|
# endif
|
|
# define ldxi_i(r0, r1, i0) _ldxi_i(_jit, r0, r1, i0)
|
|
static void _ldxi_i(jit_state_t*,int32_t,int32_t,jit_word_t);
|
|
# if __WORDSIZE == 64
|
|
# define ldxi_ui(r0, r1, i0) _ldxi_ui(_jit, r0, r1, i0)
|
|
static void _ldxi_ui(jit_state_t*,int32_t,int32_t,jit_word_t);
|
|
# define ldxi_l(r0, r1, i0) _ldxi_l(_jit, r0, r1, i0)
|
|
static void _ldxi_l(jit_state_t*,int32_t,int32_t,jit_word_t);
|
|
# endif
|
|
# define str_c(r0, r1) STB(r1, r0, 0)
|
|
# define sti_c(i0, r0) _sti_c(_jit, i0, r0)
|
|
static void _sti_c(jit_state_t*,jit_word_t,int32_t);
|
|
# define str_s(r0, r1) STH(r1, r0, 0)
|
|
# define sti_s(i0, r0) _sti_s(_jit, i0, r0)
|
|
static void _sti_s(jit_state_t*,jit_word_t,int32_t);
|
|
# if __WORDSIZE == 32
|
|
# define str(u, v) str_i(u, v)
|
|
# define str_i(r0, r1) STI(r1, r0, 0)
|
|
# define sti(u, v) sti_i(u, v)
|
|
# else
|
|
# define str(u, v) str_l(u, v)
|
|
# define str_i(r0, r1) STW(r1, r0, 0)
|
|
# define str_l(r0, r1) STX(r1, r0, 0)
|
|
# define sti(u, v) sti_l(u, v)
|
|
# endif
|
|
# define sti_i(i0, r0) _sti_i(_jit, i0, r0)
|
|
static void _sti_i(jit_state_t*,jit_word_t,int32_t);
|
|
# if __WORDSIZE == 64
|
|
# define sti_l(i0, r0) _sti_l(_jit, i0, r0)
|
|
static void _sti_l(jit_state_t*,jit_word_t,int32_t);
|
|
# endif
|
|
# define stxr_c(r0, r1, r2) STB(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,int32_t,int32_t);
|
|
# define stxr_s(r0, r1, r2) STH(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,int32_t,int32_t);
|
|
# if __WORDSIZE == 32
|
|
# define stxr(u, v, w) stxr_i(u, v, w)
|
|
# define stxr_i(r0, r1, r2) ST(r2, r1, r0)
|
|
# define stxi(u, v, w) stxi_i(u, v, w)
|
|
# else
|
|
# define stxr(u, v, w) stxr_l(u, v, w)
|
|
# define stxr_i(r0, r1, r2) STW(r2, r1, r0)
|
|
# define stxi(u, v, w) stxi_l(u, v, w)
|
|
# define stxr_l(r0, r1, r2) STX(r2, r1, r0)
|
|
# endif
|
|
# define stxi_i(i0, r0, r1) _stxi_i(_jit, i0, r0, r1)
|
|
static void _stxi_i(jit_state_t*,jit_word_t,int32_t,int32_t);
|
|
# if __WORDSIZE == 64
|
|
# define stxi_l(i0, r0, r1) _stxi_l(_jit, i0, r0, r1)
|
|
static void _stxi_l(jit_state_t*,jit_word_t,int32_t,int32_t);
|
|
# endif
|
|
# define br(cc, i0, r0, r1) _br(_jit, cc, i0, r0, r1)
|
|
static jit_word_t
|
|
_br(jit_state_t*,int32_t,jit_word_t,int32_t,int32_t);
|
|
# define bw(cc, i0, r0, i1) _bw(_jit, cc, i0, r0, i1)
|
|
static jit_word_t
|
|
_bw(jit_state_t*,int32_t,jit_word_t,int32_t,jit_word_t);
|
|
# if __WORDSIZE == 32
|
|
# define bltr(i0, r0, r1) br(SPARC_BL, i0, r0, r1)
|
|
# define blti(i0, r0, i1) bw(SPARC_BL, i0, r0, i1)
|
|
# define bltr_u(i0, r0, r1) br(SPARC_BLU, i0, r0, r1)
|
|
# define blti_u(i0, r0, i1) bw(SPARC_BLU, i0, r0, i1)
|
|
# define bler(i0, r0, r1) br(SPARC_BLE, i0, r0, r1)
|
|
# define blei(i0, r0, i1) bw(SPARC_BLE, i0, r0, i1)
|
|
# define bler_u(i0, r0, r1) br(SPARC_BLEU, i0, r0, r1)
|
|
# define blei_u(i0, r0, i1) bw(SPARC_BLEU, i0, r0, i1)
|
|
# define beqr(i0, r0, r1) br(SPARC_BE, i0, r0, r1)
|
|
# define beqi(i0, r0, i1) bw(SPARC_BE, i0, r0, i1)
|
|
# define bger(i0, r0, r1) br(SPARC_BGE, i0, r0, r1)
|
|
# define bgei(i0, r0, i1) bw(SPARC_BGE, i0, r0, i1)
|
|
# define bger_u(i0, r0, r1) br(SPARC_BGEU, i0, r0, r1)
|
|
# define bgei_u(i0, r0, i1) bw(SPARC_BGEU, i0, r0, i1)
|
|
# define bgtr(i0, r0, r1) br(SPARC_BG, i0, r0, r1)
|
|
# define bgti(i0, r0, i1) bw(SPARC_BG, i0, r0, i1)
|
|
# define bgtr_u(i0, r0, r1) br(SPARC_BGU, i0, r0, r1)
|
|
# define bgti_u(i0, r0, i1) bw(SPARC_BGU, i0, r0, i1)
|
|
# define bner(i0, r0, r1) br(SPARC_BNE, i0, r0, r1)
|
|
# define bnei(i0, r0, i1) bw(SPARC_BNE, i0, r0, i1)
|
|
# else
|
|
# define bltr(i0, r0, r1) br(SPARC_BPL, i0, r0, r1)
|
|
# define blti(i0, r0, i1) bw(SPARC_BPL, i0, r0, i1)
|
|
# define bltr_u(i0, r0, r1) br(SPARC_BPCS, i0, r0, r1)
|
|
# define blti_u(i0, r0, i1) bw(SPARC_BPCS, i0, r0, i1)
|
|
# define bler(i0, r0, r1) br(SPARC_BPLE, i0, r0, r1)
|
|
# define blei(i0, r0, i1) bw(SPARC_BPLE, i0, r0, i1)
|
|
# define bler_u(i0, r0, r1) br(SPARC_BPLEU, i0, r0, r1)
|
|
# define blei_u(i0, r0, i1) bw(SPARC_BPLEU, i0, r0, i1)
|
|
# define beqr(i0, r0, r1) br(SPARC_BPE, i0, r0, r1)
|
|
# define beqi(i0, r0, i1) bw(SPARC_BPE, i0, r0, i1)
|
|
# define bger(i0, r0, r1) br(SPARC_BPGE, i0, r0, r1)
|
|
# define bgei(i0, r0, i1) bw(SPARC_BPGE, i0, r0, i1)
|
|
# define bger_u(i0, r0, r1) br(SPARC_BPCC, i0, r0, r1)
|
|
# define bgei_u(i0, r0, i1) bw(SPARC_BPCC, i0, r0, i1)
|
|
# define bgtr(i0, r0, r1) br(SPARC_BPG, i0, r0, r1)
|
|
# define bgti(i0, r0, i1) bw(SPARC_BPG, i0, r0, i1)
|
|
# define bgtr_u(i0, r0, r1) br(SPARC_BPGU, i0, r0, r1)
|
|
# define bgti_u(i0, r0, i1) bw(SPARC_BPGU, i0, r0, i1)
|
|
# define bner(i0, r0, r1) br(SPARC_BPNE, i0, r0, r1)
|
|
# define bnei(i0, r0, i1) bw(SPARC_BPNE, i0, r0, i1)
|
|
# endif
|
|
# define b_asr(jif,add,sgn,i0,r0,r1) _b_asr(_jit,jif,add,sgn,i0,r0,r1)
|
|
static jit_word_t
|
|
_b_asr(jit_state_t*,jit_bool_t,jit_bool_t,jit_bool_t,
|
|
jit_word_t,int32_t,int32_t);
|
|
# define b_asw(jif,add,sgn,i0,r0,i1) _b_asw(_jit,jif,add,sgn,i0,r0,i1)
|
|
static jit_word_t
|
|
_b_asw(jit_state_t*,jit_bool_t,jit_bool_t,jit_bool_t,
|
|
jit_word_t,int32_t,jit_word_t);
|
|
# define boaddr(i0, r0, r1) b_asr(1, 1, 1, i0, r0, r1)
|
|
# define boaddi(i0, r0, i1) b_asw(1, 1, 1, i0, r0, i1)
|
|
# define boaddr_u(i0, r0, r1) b_asr(1, 1, 0, i0, r0, r1)
|
|
# define boaddi_u(i0, r0, i1) b_asw(1, 1, 0, i0, r0, i1)
|
|
# define bxaddr(i0, r0, r1) b_asr(0, 1, 1, i0, r0, r1)
|
|
# define bxaddi(i0, r0, i1) b_asw(0, 1, 1, i0, r0, i1)
|
|
# define bxaddr_u(i0, r0, r1) b_asr(0, 1, 0, i0, r0, r1)
|
|
# define bxaddi_u(i0, r0, i1) b_asw(0, 1, 0, i0, r0, i1)
|
|
# define bosubr(i0, r0, r1) b_asr(1, 0, 1, i0, r0, r1)
|
|
# define bosubi(i0, r0, i1) b_asw(1, 0, 1, i0, r0, i1)
|
|
# define bosubr_u(i0, r0, r1) b_asr(1, 0, 0, i0, r0, r1)
|
|
# define bosubi_u(i0, r0, i1) b_asw(1, 0, 0, i0, r0, i1)
|
|
# define bxsubr(i0, r0, r1) b_asr(0, 0, 1, i0, r0, r1)
|
|
# define bxsubi(i0, r0, i1) b_asw(0, 0, 1, i0, r0, i1)
|
|
# define bxsubr_u(i0, r0, r1) b_asr(0, 0, 0, i0, r0, r1)
|
|
# define bxsubi_u(i0, r0, i1) b_asw(0, 0, 0, i0, r0, i1)
|
|
# define bm_r(set, i0, r0, r1) _bm_r(_jit,set,i0,r0,r1)
|
|
static jit_word_t
|
|
_bm_r(jit_state_t*,jit_bool_t,jit_word_t,int32_t,int32_t);
|
|
# define bm_w(set,i0,r0,i1) _bm_w(_jit,set,i0,r0,i1)
|
|
static jit_word_t
|
|
_bm_w(jit_state_t*,jit_bool_t,jit_word_t,int32_t,jit_word_t);
|
|
# define bmsr(i0, r0, r1) bm_r(1, i0, r0, r1)
|
|
# define bmsi(i0, r0, i1) bm_w(1, i0, r0, i1)
|
|
# define bmcr(i0, r0, r1) bm_r(0, i0, r0, r1)
|
|
# define bmci(i0, r0, i1) bm_w(0, i0, r0, i1)
|
|
# define jmpr(r0) _jmpr(_jit, r0)
|
|
static void _jmpr(jit_state_t*,int32_t);
|
|
# 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*,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 vastart(r0) _vastart(_jit, r0)
|
|
static void _vastart(jit_state_t*, int32_t);
|
|
#define vaarg(r0, r1) _vaarg(_jit, r0, r1)
|
|
static void _vaarg(jit_state_t*, int32_t, int32_t);
|
|
#define patch_at(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
|
|
_f2r(jit_state_t *_jit,
|
|
int32_t op, int32_t rd, int32_t op2, int32_t imm22)
|
|
{
|
|
jit_instr_t v;
|
|
assert(!(op & 0xfffffffc));
|
|
assert(!(rd & 0xffffffe0));
|
|
assert(!(op2 & 0xfffffff8));
|
|
assert(s22_p(imm22));
|
|
v.op.b = op;
|
|
v.rd.b = rd;
|
|
v.op2.b = op2;
|
|
v.imm22.b = imm22;
|
|
ii(v.v);
|
|
}
|
|
|
|
static void
|
|
_f2b(jit_state_t *_jit,
|
|
int32_t op, int32_t a, int32_t cond, int32_t op2,
|
|
int32_t disp22)
|
|
{
|
|
jit_instr_t v;
|
|
assert(!(op & 0xfffffffc));
|
|
assert(!(a & 0xfffffffe));
|
|
assert(!(cond & 0xfffffff0));
|
|
assert(!(op2 & 0xfffffff8));
|
|
assert(s22_p(disp22));
|
|
v.op.b = op;
|
|
v.a.b = a;
|
|
v.cond.b = cond;
|
|
v.op2.b = op2;
|
|
v.disp22.b = disp22;
|
|
ii(v.v);
|
|
}
|
|
|
|
# if __WORDSIZE == 64
|
|
static void
|
|
_f2bp(jit_state_t *_jit,
|
|
int32_t op, int32_t a, int32_t cond, int32_t op2,
|
|
int32_t cc1, int32_t cc0, int32_t p, int32_t disp19)
|
|
{
|
|
jit_instr_t v;
|
|
assert(!(op & 0xfffffffc));
|
|
assert(!(a & 0xfffffffe));
|
|
assert(!(cond & 0xfffffff0));
|
|
assert(!(op2 & 0xfffffff8));
|
|
assert(s19_p(disp19));
|
|
v.op.b = op;
|
|
v.a.b = a;
|
|
v.cond.b = cond;
|
|
v.op2.b = op2;
|
|
v.cc1.b = cc1;
|
|
v.cc0.b = cc0;
|
|
v.p.b = p;
|
|
v.disp19.b = disp19;
|
|
ii(v.v);
|
|
}
|
|
# endif
|
|
|
|
static void
|
|
_f3r(jit_state_t *_jit, int32_t op, int32_t rd,
|
|
int32_t op3, int32_t rs1, int32_t rs2)
|
|
{
|
|
jit_instr_t v;
|
|
assert(!(op & 0xfffffffc));
|
|
assert(!(rd & 0xffffffe0));
|
|
assert(!(op3 & 0xffffffc0));
|
|
assert(!(rs1 & 0xffffffe0));
|
|
assert(!(rs2 & 0xffffffe0));
|
|
v.op.b = op;
|
|
v.rd.b = rd;
|
|
v.op3.b = op3;
|
|
v.rs1.b = rs1;
|
|
v.i.b = 0;
|
|
v.asi.b = 0;
|
|
v.rs2.b = rs2;
|
|
ii(v.v);
|
|
}
|
|
|
|
# if __WORDSIZE == 64
|
|
static void
|
|
_f3rx(jit_state_t *_jit, int32_t op, int32_t rd,
|
|
int32_t op3, int32_t rs1, int32_t rs2)
|
|
{
|
|
jit_instr_t v;
|
|
assert(!(op & 0xfffffffc));
|
|
assert(!(rd & 0xffffffe0));
|
|
assert(!(op3 & 0xffffffc0));
|
|
assert(!(rs1 & 0xffffffe0));
|
|
assert(!(rs2 & 0xffffffe0));
|
|
v.op.b = op;
|
|
v.rd.b = rd;
|
|
v.op3.b = op3;
|
|
v.rs1.b = rs1;
|
|
v.i.b = 0;
|
|
v.x.b = 1;
|
|
v.asix.b = 0;
|
|
v.rs2.b = rs2;
|
|
ii(v.v);
|
|
}
|
|
|
|
static void
|
|
_f3s(jit_state_t *_jit, int32_t op, int32_t rd,
|
|
int32_t op3, int32_t rs1, int32_t shim)
|
|
{
|
|
jit_instr_t v;
|
|
assert(!(op & 0xfffffffc));
|
|
assert(!(rd & 0xffffffe0));
|
|
assert(!(op3 & 0xffffffc0));
|
|
assert(!(rs1 & 0xffffffe0));
|
|
assert(!(shim & 0xffffffc0));
|
|
v.op.b = op;
|
|
v.rd.b = rd;
|
|
v.op3.b = op3;
|
|
v.rs1.b = rs1;
|
|
v.i.b = 1;
|
|
v.x.b = 1;
|
|
v.asis.b = 0;
|
|
v.shim.b = shim;
|
|
ii(v.v);
|
|
}
|
|
# endif
|
|
|
|
static void
|
|
_f3i(jit_state_t *_jit, int32_t op, int32_t rd,
|
|
int32_t op3, int32_t rs1, int32_t simm13)
|
|
{
|
|
jit_instr_t v;
|
|
assert(!(op & 0xfffffffc));
|
|
assert(!(rd & 0xffffffe0));
|
|
assert(!(op3 & 0xffffffc0));
|
|
assert(!(rs1 & 0xffffffe0));
|
|
assert(s13_p(simm13));
|
|
v.op.b = op;
|
|
v.rd.b = rd;
|
|
v.op3.b = op3;
|
|
v.rs1.b = rs1;
|
|
v.i.b = 1;
|
|
v.simm13.b = simm13;
|
|
ii(v.v);
|
|
}
|
|
|
|
static void
|
|
_f3t(jit_state_t *_jit, int32_t cond,
|
|
int32_t rs1, int32_t i, int32_t rs2_imm7)
|
|
{
|
|
jit_instr_t v;
|
|
assert(!(cond & 0xfffffff0));
|
|
assert(!(i & 0xfffffffe));
|
|
assert(!(rs1 & 0xffffffe0));
|
|
v.op.b = 2;
|
|
v.rd.b = cond;
|
|
v.op3.b = 58;
|
|
v.i.b = i;
|
|
if (i) {
|
|
assert(s7_p(rs2_imm7));
|
|
v.res.b = 0;
|
|
v.imm7.b = rs2_imm7;
|
|
}
|
|
else {
|
|
assert(!(rs2_imm7 & 0xffffffe0));
|
|
v.asi.b = 0;
|
|
v.rs2.b = rs2_imm7;
|
|
}
|
|
ii(v.v);
|
|
}
|
|
|
|
static void
|
|
_f3a(jit_state_t *_jit, int32_t op, int32_t rd,
|
|
int32_t op3, int32_t rs1, int32_t asi, int32_t rs2)
|
|
{
|
|
jit_instr_t v;
|
|
assert(!(op & 0xfffffffc));
|
|
assert(!(rd & 0xffffffe0));
|
|
assert(!(op3 & 0xffffffc0));
|
|
assert(!(rs1 & 0xffffffe0));
|
|
assert(!(asi & 0xffffff00));
|
|
assert(!(rs2 & 0xffffffe0));
|
|
v.op.b = op;
|
|
v.rd.b = rd;
|
|
v.op3.b = op3;
|
|
v.rs1.b = rs1;
|
|
v.i.b = 0;
|
|
v.asi.b = asi;
|
|
v.rs2.b = rs2;
|
|
ii(v.v);
|
|
}
|
|
|
|
static void
|
|
_f1(jit_state_t *_jit, int32_t op, int32_t disp30)
|
|
{
|
|
jit_instr_t v;
|
|
assert(!(op & 0xfffffffc));
|
|
assert(s30_p(disp30));
|
|
v.op.b = op;
|
|
v.disp30.b = disp30;
|
|
ii(v.v);
|
|
}
|
|
|
|
static void
|
|
_nop(jit_state_t *_jit, int32_t i0)
|
|
{
|
|
for (; i0 > 0; i0 -= 4)
|
|
NOP();
|
|
assert(i0 == 0);
|
|
}
|
|
|
|
static void
|
|
_movr(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|
{
|
|
if (r0 != r1)
|
|
ORI(r1, 0, r0);
|
|
}
|
|
|
|
static void
|
|
_movi(jit_state_t *_jit, int32_t r0, jit_word_t i0)
|
|
{
|
|
if (s13_p(i0))
|
|
ORI(0, i0, r0);
|
|
else {
|
|
# if __WORDSIZE == 64
|
|
if (i0 & 0xffffffff00000000) {
|
|
int32_t reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), (i0 >> 32) & 0xffffffff);
|
|
movi(r0, i0 & 0xffffffff);
|
|
lshi(rn(reg), rn(reg), 32);
|
|
OR(rn(reg), r0, r0);
|
|
jit_unget_reg(reg);
|
|
}
|
|
else {
|
|
# endif
|
|
SETHI(HI((int)i0), r0);
|
|
if (LO(i0))
|
|
ORI(r0, LO(i0), r0);
|
|
# if __WORDSIZE == 64
|
|
}
|
|
# endif
|
|
}
|
|
}
|
|
|
|
static jit_word_t
|
|
_movi_p(jit_state_t *_jit, int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_word_t w;
|
|
# if __WORDSIZE == 64
|
|
int32_t reg;
|
|
# endif
|
|
w = _jit->pc.w;
|
|
# if __WORDSIZE == 64
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
SETHI(HI((int)i0), r0);
|
|
ORI(r0, LO(i0), r0);
|
|
i0 = (int)(i0 >> 32);
|
|
SETHI(HI(i0), rn(reg));
|
|
ORI(rn(reg), LO(i0), rn(reg));
|
|
SLLXI(rn(reg), 32, rn(reg));
|
|
OR(rn(reg), r0, r0);
|
|
jit_unget_reg(reg);
|
|
# else
|
|
SETHI(HI(i0), r0);
|
|
ORI(r0, LO(i0), r0);
|
|
# endif
|
|
return (w);
|
|
}
|
|
|
|
static void
|
|
_addi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
ADDI(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
addr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
# if __WORDSIZE == 64
|
|
static void
|
|
_addcr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
# endif
|
|
|
|
static void
|
|
_addci(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
# if __WORDSIZE == 32
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
ADDIcc(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
addcr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
# else
|
|
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);
|
|
}
|
|
# endif
|
|
}
|
|
|
|
# if __WORDSIZE == 64
|
|
static void
|
|
_addxr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
|
|
{
|
|
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);
|
|
}
|
|
# endif
|
|
|
|
static void
|
|
_addxi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
# if __WORDSIZE == 32
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
ADDXIcc(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
addxr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
# else
|
|
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);
|
|
# endif
|
|
}
|
|
|
|
static void
|
|
_subi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
SUBI(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
subr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
# if __WORDSIZE == 64
|
|
static void
|
|
_subcr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
# endif
|
|
|
|
static void
|
|
_subci(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
# if __WORDSIZE == 32
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
SUBIcc(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
subcr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
# else
|
|
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);
|
|
}
|
|
# endif
|
|
}
|
|
|
|
# if __WORDSIZE == 64
|
|
static void
|
|
_subxr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
|
|
{
|
|
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);
|
|
}
|
|
#endif
|
|
|
|
static void
|
|
_subxi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
# if __WORDSIZE == 32
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
SUBXIcc(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
subxr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
# else
|
|
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);
|
|
# endif
|
|
}
|
|
|
|
static void
|
|
_rsbi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
subi(r0, r1, i0);
|
|
negr(r0, r0);
|
|
}
|
|
|
|
static void
|
|
_muli(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0)) {
|
|
# if __WORDSIZE == 32
|
|
UMULI(r1, i0, r0);
|
|
# else
|
|
MULXI(r1, i0, r0);
|
|
# endif
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
mulr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
# if __WORDSIZE == 32
|
|
static void
|
|
_iqmulr(jit_state_t *_jit, int32_t r0, int32_t r1,
|
|
int32_t r2, int32_t r3, jit_bool_t sign)
|
|
{
|
|
if (sign)
|
|
SMUL(r2, r3, r0);
|
|
else
|
|
UMUL(r2, r3, r0);
|
|
RDY(r1);
|
|
}
|
|
|
|
static void
|
|
_iqmuli(jit_state_t *_jit, int32_t r0, int32_t r1,
|
|
int32_t r2, jit_word_t i0, jit_bool_t sign)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0)) {
|
|
if (sign)
|
|
SMULI(r2, i0, r0);
|
|
else
|
|
UMULI(r2, i0, r0);
|
|
RDY(r1);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
iqmulr(r0, r1, r2, rn(reg), sign);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
# else
|
|
static __int128_t __llmul(jit_word_t a, jit_word_t b)
|
|
{
|
|
return (__int128_t)a * (__int128_t)b;
|
|
}
|
|
|
|
# define QMUL_PROLOG() \
|
|
do { \
|
|
(void)jit_get_reg(_O0|jit_class_gpr|jit_class_named); \
|
|
(void)jit_get_reg(_O1|jit_class_gpr|jit_class_named); \
|
|
if (r0 != _G2_REGNO && r1 != _G2_REGNO) \
|
|
stxi(BIAS(-8), _FP_REGNO, _G2_REGNO); \
|
|
if (r0 != _G3_REGNO && r1 != _G3_REGNO) \
|
|
stxi(BIAS(-16), _FP_REGNO, _G3_REGNO); \
|
|
if (r0 != _G4_REGNO && r1 != _G4_REGNO) \
|
|
stxi(BIAS(-24), _FP_REGNO, _G4_REGNO); \
|
|
} while (0)
|
|
|
|
# define QMUL_EPILOG() \
|
|
do { \
|
|
if (r0 != _G2_REGNO && r1 != _G2_REGNO) \
|
|
ldxi(_G2_REGNO, _FP_REGNO, BIAS(-8)); \
|
|
if (r0 != _G3_REGNO && r1 != _G3_REGNO) \
|
|
ldxi(_G3_REGNO, _FP_REGNO, BIAS(-16)); \
|
|
if (r0 != _G4_REGNO && r1 != _G4_REGNO) \
|
|
ldxi(_G4_REGNO, _FP_REGNO, BIAS(-24)); \
|
|
(void)jit_unget_reg(_O0); \
|
|
(void)jit_unget_reg(_O1); \
|
|
} while (0)
|
|
|
|
static void
|
|
_qmulr(jit_state_t *_jit, int32_t r0, int32_t r1,
|
|
int32_t r2, int32_t r3)
|
|
{
|
|
QMUL_PROLOG();
|
|
movr(_O0_REGNO, r3);
|
|
movr(_O1_REGNO, r2);
|
|
calli((jit_word_t)__llmul);
|
|
movr(r0, _O1_REGNO);
|
|
movr(r1, _O0_REGNO);
|
|
QMUL_EPILOG();
|
|
}
|
|
|
|
static void
|
|
_qmuli(jit_state_t *_jit, int32_t r0, int32_t r1,
|
|
int32_t r2, jit_word_t i0)
|
|
{
|
|
QMUL_PROLOG();
|
|
movi(_O0_REGNO, i0);
|
|
movr(_O1_REGNO, r2);
|
|
calli((jit_word_t)__llmul);
|
|
movr(r0, _O1_REGNO);
|
|
movr(r1, _O0_REGNO);
|
|
QMUL_EPILOG();
|
|
}
|
|
|
|
static __uint128_t __ullmul(jit_uword_t a, jit_uword_t b)
|
|
{
|
|
return (__uint128_t)a * (__uint128_t)b;
|
|
}
|
|
|
|
static void
|
|
_qmulr_u(jit_state_t *_jit, int32_t r0, int32_t r1,
|
|
int32_t r2, int32_t r3)
|
|
{
|
|
QMUL_PROLOG();
|
|
movr(_O0_REGNO, r3);
|
|
movr(_O1_REGNO, r2);
|
|
calli((jit_word_t)__ullmul);
|
|
movr(r0, _O1_REGNO);
|
|
movr(r1, _O0_REGNO);
|
|
QMUL_EPILOG();
|
|
}
|
|
|
|
static void
|
|
_qmuli_u(jit_state_t *_jit, int32_t r0, int32_t r1,
|
|
int32_t r2, jit_word_t i0)
|
|
{
|
|
QMUL_PROLOG();
|
|
movi(_O0_REGNO, i0);
|
|
movr(_O1_REGNO, r2);
|
|
calli((jit_word_t)__ullmul);
|
|
movr(r0, _O1_REGNO);
|
|
movr(r1, _O0_REGNO);
|
|
QMUL_EPILOG();
|
|
}
|
|
# endif
|
|
|
|
static void
|
|
_divr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
|
|
{
|
|
# if __WORDSIZE == 32
|
|
int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
rshi(rn(reg), r1, 31);
|
|
WRY(rn(reg), 0);
|
|
SDIV(r1, r2, r0);
|
|
jit_unget_reg(reg);
|
|
# else
|
|
SDIVX(r1, r2, r0);
|
|
# endif
|
|
}
|
|
|
|
static void
|
|
_divi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
# if __WORDSIZE == 32
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
# endif
|
|
if (s13_p(i0)) {
|
|
# if __WORDSIZE == 32
|
|
rshi(rn(reg), r1, 31);
|
|
WRY(rn(reg), 0);
|
|
SDIVI(r1, i0, r0);
|
|
# else
|
|
SDIVXI(r1, i0, r0);
|
|
# endif
|
|
}
|
|
else {
|
|
# if __WORDSIZE == 64
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
# endif
|
|
movi(rn(reg), i0);
|
|
divr(r0, r1, rn(reg));
|
|
# if __WORDSIZE == 64
|
|
jit_unget_reg(reg);
|
|
# endif
|
|
}
|
|
# if __WORDSIZE == 32
|
|
jit_unget_reg(reg);
|
|
# endif
|
|
}
|
|
|
|
static void
|
|
_divr_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
|
|
{
|
|
# if __WORDSIZE == 32
|
|
WRYI(0, 0);
|
|
UDIV(r1, r2, r0);
|
|
# else
|
|
UDIVX(r1, r2, r0);
|
|
# endif
|
|
}
|
|
|
|
static void
|
|
_divi_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0)) {
|
|
# if __WORDSIZE == 32
|
|
WRYI(0, 0);
|
|
UDIVI(r1, i0, r0);
|
|
# else
|
|
UDIVXI(r1, i0, r0);
|
|
# endif
|
|
}
|
|
else {
|
|
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, int32_t r0, int32_t r1,
|
|
int32_t r2, int32_t r3, jit_bool_t sign)
|
|
{
|
|
int32_t sv0, rg0;
|
|
int32_t sv1, rg1;
|
|
|
|
if (r0 == r2 || r0 == r3) {
|
|
sv0 = jit_get_reg(jit_class_gpr);
|
|
rg0 = rn(sv0);
|
|
}
|
|
else
|
|
rg0 = r0;
|
|
if (r1 == r2 || r1 == r3) {
|
|
sv1 = jit_get_reg(jit_class_gpr);
|
|
rg1 = rn(sv1);
|
|
}
|
|
else
|
|
rg1 = r1;
|
|
|
|
if (sign)
|
|
divr(rg0, r2, r3);
|
|
else
|
|
divr_u(rg0, r2, r3);
|
|
mulr(rg1, r3, rg0);
|
|
subr(rg1, r2, rg1);
|
|
if (rg0 != r0) {
|
|
movr(r0, rg0);
|
|
jit_unget_reg(sv0);
|
|
}
|
|
if (rg1 != r1) {
|
|
movr(r1, rg1);
|
|
jit_unget_reg(sv1);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_iqdivi(jit_state_t *_jit, int32_t r0, int32_t r1,
|
|
int32_t r2, jit_word_t i0, jit_bool_t sign)
|
|
{
|
|
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
|
|
_remr(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
|
|
{
|
|
int32_t reg;
|
|
if (r0 == r1 || r0 == r2) {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
divr(rn(reg), r1, r2);
|
|
mulr(rn(reg), r2, rn(reg));
|
|
subr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
else {
|
|
divr(r0, r1, r2);
|
|
mulr(r0, r2, r0);
|
|
subr(r0, r1, r0);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_remi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
remr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_remr_u(jit_state_t *_jit, int32_t r0, int32_t r1, int32_t r2)
|
|
{
|
|
int32_t reg;
|
|
if (r0 == r1 || r0 == r2) {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
divr_u(rn(reg), r1, r2);
|
|
mulr(rn(reg), r2, rn(reg));
|
|
subr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
else {
|
|
divr_u(r0, r1, r2);
|
|
mulr(r0, r2, r0);
|
|
subr(r0, r1, r0);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_remi_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
remr_u(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_andi(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_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, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_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, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_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
|
|
_extr_c(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|
{
|
|
lshi(r0, r1, __WORDSIZE - 8);
|
|
rshi(r0, r0, __WORDSIZE - 8);
|
|
}
|
|
|
|
static void
|
|
_extr_s(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|
{
|
|
lshi(r0, r1, __WORDSIZE - 16);
|
|
rshi(r0, r0, __WORDSIZE - 16);
|
|
}
|
|
|
|
static void
|
|
_extr_us(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|
{
|
|
lshi(r0, r1, __WORDSIZE - 16);
|
|
rshi_u(r0, r0, __WORDSIZE - 16);
|
|
}
|
|
|
|
#if __WORDSIZE == 64
|
|
static void
|
|
_extr_i(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|
{
|
|
lshi(r0, r1, __WORDSIZE - 32);
|
|
rshi(r0, r0, __WORDSIZE - 32);
|
|
}
|
|
|
|
static void
|
|
_extr_ui(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|
{
|
|
lshi(r0, r1, __WORDSIZE - 32);
|
|
rshi_u(r0, r0, __WORDSIZE - 32);
|
|
}
|
|
#endif
|
|
|
|
static void
|
|
_cr(jit_state_t *_jit, int32_t cc,
|
|
int32_t r0, int32_t r1, int32_t r2)
|
|
{
|
|
CMP(r1, r2);
|
|
# if __WORDSIZE == 32
|
|
Ba(cc, 3);
|
|
# else
|
|
BPa(cc, 3);
|
|
# endif
|
|
movi(r0, 1);
|
|
movi(r0, 0);
|
|
}
|
|
|
|
static void
|
|
_cw(jit_state_t *_jit, int32_t cc,
|
|
int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0)) {
|
|
CMPI(r1, i0);
|
|
# if __WORDSIZE == 32
|
|
Ba(cc, 3);
|
|
# else
|
|
BPa(cc, 3);
|
|
# endif
|
|
movi(r0, 1);
|
|
movi(r0, 0);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
cr(cc, r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldi_c(jit_state_t *_jit, int32_t r0, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
LDSBI(0, i0, 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, int32_t r0, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
LDUBI(0, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldr_uc(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldi_s(jit_state_t *_jit, int32_t r0, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
LDSHI(0, i0, 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, int32_t r0, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
LDUHI(0, i0, r0);
|
|
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, int32_t r0, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0)) {
|
|
# if __WORDSIZE == 32
|
|
LDI(0, i0, r0);
|
|
# else
|
|
LDSWI(0, i0, r0);
|
|
# endif
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldr_i(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
# if __WORDSIZE == 64
|
|
static void
|
|
_ldi_ui(jit_state_t *_jit, int32_t r0, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
LDUWI(0, i0, 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, int32_t r0, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
LDXI(0, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldr_l(r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
# endif
|
|
|
|
static void
|
|
_ldxi_c(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
LDSBI(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldxr_c(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldxi_uc(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
LDUBI(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldxr_uc(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldxi_s(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
LDSHI(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldxr_s(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldxi_us(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
LDUHI(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldxr_us(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldxi_i(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0)) {
|
|
# if __WORDSIZE == 32
|
|
LDI(r1, i0, r0);
|
|
# else
|
|
LDSWI(r1, i0, r0);
|
|
# endif
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldxr_i(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
# if __WORDSIZE == 64
|
|
static void
|
|
_ldxi_ui(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
LDUWI(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldxr_ui(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ldxi_l(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
LDXI(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldxr_l(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
# endif
|
|
|
|
static void
|
|
_sti_c(jit_state_t *_jit, jit_word_t i0, int32_t r0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
STBI(r0, 0, 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, int32_t r0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
STHI(r0, 0, 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, int32_t r0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0)) {
|
|
# if __WORDSIZE == 32
|
|
STI(r0, 0, i0);
|
|
# else
|
|
STWI(r0, 0, i0);
|
|
# endif
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
str_i(rn(reg), r0);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
# if __WORDSIZE == 64
|
|
static void
|
|
_sti_l(jit_state_t *_jit, jit_word_t i0, int32_t r0)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
STXI(r0, 0, i0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
str_l(rn(reg), r0);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
# endif
|
|
|
|
static void
|
|
_stxi_c(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
STBI(r1, r0, i0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
stxr_c(r0, rn(reg), r1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_stxi_s(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
STHI(r1, r0, i0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
stxr_s(r0, rn(reg), r1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_stxi_i(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0)) {
|
|
# if __WORDSIZE == 32
|
|
STI(r1, r0, i0);
|
|
# else
|
|
STWI(r1, r0, i0);
|
|
# endif
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
stxr_i(r0, rn(reg), r1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
# if __WORDSIZE == 64
|
|
static void
|
|
_stxi_l(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
|
|
{
|
|
int32_t reg;
|
|
if (s13_p(i0))
|
|
STXI(r1, r0, i0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
stxr_l(r0, rn(reg), r1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
# endif
|
|
|
|
static jit_word_t
|
|
_br(jit_state_t *_jit, int32_t cc,
|
|
jit_word_t i0, int32_t r0, int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
CMP(r0, r1);
|
|
w = _jit->pc.w;
|
|
# if __WORDSIZE == 32
|
|
B(cc, (i0 - w) >> 2);
|
|
# else
|
|
BP(cc, (i0 - w) >> 2);
|
|
# endif
|
|
NOP();
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bw(jit_state_t *_jit, int32_t cc,
|
|
jit_word_t i0, int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
int32_t reg;
|
|
if (s13_p(i1)) {
|
|
CMPI(r0, i1);
|
|
w = _jit->pc.w;
|
|
# if __WORDSIZE == 32
|
|
B(cc, (i0 - w) >> 2);
|
|
# else
|
|
B(cc, (i0 - w) >> 2);
|
|
# endif
|
|
NOP();
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
movi(rn(reg), i1);
|
|
w = br(cc, i0, r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_b_asr(jit_state_t *_jit, jit_bool_t jif, jit_bool_t add, jit_bool_t sgn,
|
|
jit_word_t i0, int32_t r0, int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
if (add)
|
|
ADDcc(r0, r1, r0);
|
|
else
|
|
SUBcc(r0, r1, r0);
|
|
w = _jit->pc.w;
|
|
# if __WORDSIZE == 32
|
|
B(sgn ?
|
|
(jif ? SPARC_BVS : SPARC_BVC) :
|
|
(jif ? SPARC_BCS : SPARC_BCC),
|
|
(i0 - w) >> 2);
|
|
# else
|
|
BP(sgn ?
|
|
(jif ? SPARC_BPVS : SPARC_BPVC) :
|
|
(jif ? SPARC_BPCS : SPARC_BPCC),
|
|
(i0 - w) >> 2);
|
|
# endif
|
|
NOP();
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_b_asw(jit_state_t *_jit, jit_bool_t jif, jit_bool_t add, jit_bool_t sgn,
|
|
jit_word_t i0, int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
int32_t reg;
|
|
if (s13_p(i1)) {
|
|
if (add)
|
|
ADDIcc(r0, i1, r0);
|
|
else
|
|
SUBIcc(r0, i1, r0);
|
|
w = _jit->pc.w;
|
|
# if __WORDSIZE == 32
|
|
B(sgn ?
|
|
(jif ? SPARC_BVS : SPARC_BVC) :
|
|
(jif ? SPARC_BCS : SPARC_BCC),
|
|
(i0 - w) >> 2);
|
|
# else
|
|
BP(sgn ?
|
|
(jif ? SPARC_BPVS : SPARC_BPVC) :
|
|
(jif ? SPARC_BPCS : SPARC_BPCC),
|
|
(i0 - w) >> 2);
|
|
# endif
|
|
NOP();
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
movi(rn(reg), i1);
|
|
w = b_asr(jif, add, sgn, i0, r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bm_r(jit_state_t *_jit, jit_bool_t set,
|
|
jit_word_t i0, int32_t r0, int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
BTST(r0, r1);
|
|
w = _jit->pc.w;
|
|
# if __WORDSIZE == 32
|
|
B(set ? SPARC_BNZ : SPARC_BZ, (i0 - w) >> 2);
|
|
# else
|
|
BP(set ? SPARC_BPNE : SPARC_BPE, (i0 - w) >> 2);
|
|
# endif
|
|
NOP();
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bm_w(jit_state_t *_jit, jit_bool_t set,
|
|
jit_word_t i0, int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
int32_t reg;
|
|
if (s13_p(i1)) {
|
|
BTSTI(r0, i1);
|
|
w = _jit->pc.w;
|
|
# if __WORDSIZE == 32
|
|
B(set ? SPARC_BNZ : SPARC_BZ, (i0 - w) >> 2);
|
|
# else
|
|
BP(set ? SPARC_BPNE : SPARC_BPE, (i0 - w) >> 2);
|
|
# endif
|
|
NOP();
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
movi(rn(reg), i1);
|
|
w = bm_r(set, i0, r0, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
return (w);
|
|
}
|
|
|
|
static void
|
|
_jmpr(jit_state_t *_jit, int32_t r0)
|
|
{
|
|
JMPL(0, r0, 0);
|
|
NOP();
|
|
}
|
|
|
|
static void
|
|
_jmpi(jit_state_t *_jit, jit_word_t i0)
|
|
{
|
|
jit_word_t w;
|
|
int32_t reg;
|
|
w = (i0 - _jit->pc.w) >> 2;
|
|
if (s22_p(w)) {
|
|
BA(w);
|
|
NOP();
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
|
|
movi(rn(reg), i0);
|
|
jmpr(rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static jit_word_t
|
|
_jmpi_p(jit_state_t *_jit, jit_word_t i0)
|
|
{
|
|
jit_word_t w;
|
|
int32_t reg;
|
|
reg = jit_get_reg(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, int32_t r0)
|
|
{
|
|
CALL(r0);
|
|
NOP();
|
|
}
|
|
|
|
static void
|
|
_calli(jit_state_t *_jit, jit_word_t i0)
|
|
{
|
|
jit_word_t w;
|
|
w = (i0 - _jit->pc.w) >> 2;
|
|
CALLI(w);
|
|
NOP();
|
|
}
|
|
|
|
static jit_word_t
|
|
_calli_p(jit_state_t *_jit, jit_word_t i0)
|
|
{
|
|
jit_word_t w;
|
|
int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
w = movi_p(rn(reg), i0);
|
|
callr(rn(reg));
|
|
jit_unget_reg(reg);
|
|
return (w);
|
|
}
|
|
|
|
#define OFF(n) BIAS(((n) * sizeof(jit_word_t)))
|
|
static void
|
|
_prolog(jit_state_t *_jit, jit_node_t *node)
|
|
{
|
|
int32_t reg;
|
|
if (_jitc->function->define_frame || _jitc->function->assume_frame) {
|
|
int32_t frame = -_jitc->function->frame;
|
|
assert(_jitc->function->self.aoff >= frame);
|
|
if (_jitc->function->assume_frame)
|
|
return;
|
|
_jitc->function->self.aoff = frame;
|
|
}
|
|
if (_jitc->function->allocar)
|
|
_jitc->function->self.aoff &= -16;
|
|
/* align at 16 bytes boundary */
|
|
_jitc->function->stack = ((stack_framesize +
|
|
_jitc->function->self.alen -
|
|
_jitc->function->self.aoff) + 15) & -16;
|
|
SAVEI(_SP_REGNO, -_jitc->function->stack, _SP_REGNO);
|
|
|
|
/* (most) other backends do not save incoming arguments, so,
|
|
* only save locals here */
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L0))
|
|
stxi(OFF(0), _SP_REGNO, _L0_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L1))
|
|
stxi(OFF(1), _SP_REGNO, _L1_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L2))
|
|
stxi(OFF(2), _SP_REGNO, _L2_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L3))
|
|
stxi(OFF(3), _SP_REGNO, _L3_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L4))
|
|
stxi(OFF(4), _SP_REGNO, _L4_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L5))
|
|
stxi(OFF(5), _SP_REGNO, _L5_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L6))
|
|
stxi(OFF(6), _SP_REGNO, _L6_REGNO);
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L7))
|
|
stxi(OFF(7), _SP_REGNO, _L7_REGNO);
|
|
|
|
if (_jitc->function->allocar) {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), BIAS(_jitc->function->self.aoff));
|
|
/* Already "biased" by allocai */
|
|
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(BIAS((16 + (__WORDSIZE == 32)) * sizeof(jit_word_t) +
|
|
reg * sizeof(jit_word_t)), _FP_REGNO, rn(_I0 + reg));
|
|
}
|
|
}
|
|
|
|
static void
|
|
_epilog(jit_state_t *_jit, jit_node_t *node)
|
|
{
|
|
if (_jitc->function->assume_frame)
|
|
return;
|
|
/* (most) other backends do not save incoming arguments, so,
|
|
* only save locals here */
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L0))
|
|
ldxi(_L0_REGNO, _FP_REGNO, _jitc->function->stack + OFF(0));
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L1))
|
|
ldxi(_L1_REGNO, _FP_REGNO, _jitc->function->stack + OFF(1));
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L2))
|
|
ldxi(_L2_REGNO, _FP_REGNO, _jitc->function->stack + OFF(2));
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L3))
|
|
ldxi(_L3_REGNO, _FP_REGNO, _jitc->function->stack + OFF(3));
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L4))
|
|
ldxi(_L4_REGNO, _FP_REGNO, _jitc->function->stack + OFF(4));
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L5))
|
|
ldxi(_L5_REGNO, _FP_REGNO, _jitc->function->stack + OFF(5));
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L6))
|
|
ldxi(_L6_REGNO, _FP_REGNO, _jitc->function->stack + OFF(6));
|
|
if (jit_regset_tstbit(&_jitc->function->regset, _L7))
|
|
ldxi(_L7_REGNO, _FP_REGNO, _jitc->function->stack + OFF(7));
|
|
RESTOREI(0, 0, 0);
|
|
RETL();
|
|
NOP();
|
|
}
|
|
|
|
static void
|
|
_vastart(jit_state_t *_jit, int32_t r0)
|
|
{
|
|
/* Initialize stack pointer to the first stack argument. */
|
|
if (jit_arg_reg_p(_jitc->function->vagp))
|
|
addi(r0, _FP_REGNO, BIAS((16 + (__WORDSIZE == 32) +
|
|
_jitc->function->vagp) *
|
|
sizeof(jit_word_t)));
|
|
else
|
|
addi(r0, _FP_REGNO, BIAS(_jitc->function->self.size));
|
|
}
|
|
|
|
static void
|
|
_vaarg(jit_state_t *_jit, int32_t r0, int32_t r1)
|
|
{
|
|
assert(_jitc->function->self.call & jit_call_varargs);
|
|
|
|
/* Load argument. */
|
|
ldr(r0, r1);
|
|
|
|
/* Update vararg stack pointer. */
|
|
addi(r1, r1, sizeof(jit_word_t));
|
|
}
|
|
|
|
static void
|
|
_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
|
|
{
|
|
jit_instr_t i;
|
|
union {
|
|
int32_t *i;
|
|
jit_word_t w;
|
|
} u;
|
|
|
|
u.w = instr;
|
|
i.v = u.i[0];
|
|
|
|
if (i.op.b == 0) { /* conditional branch */
|
|
if (i.op2.b == 2 || i.op2.b == 6) { /* int or float condition */
|
|
i.disp22.b = (label - instr) >> 2;
|
|
u.i[0] = i.v;
|
|
}
|
|
# if __WORDSIZE == 64
|
|
else if (i.op2.b == 1) {
|
|
i.disp19.b = (label - instr) >> 2;
|
|
u.i[0] = i.v;
|
|
}
|
|
# endif
|
|
else if (i.op2.b == 4) { /* movi_p */
|
|
/* SETHI */
|
|
i.imm22.b = HI((int)label);
|
|
u.i[0] = i.v;
|
|
i.v = u.i[1];
|
|
if (i.op.b == 2 && i.op3.b == 2) {
|
|
/* ORI */
|
|
i.simm13.b = LO(label);
|
|
u.i[1] = i.v;
|
|
# if __WORDSIZE == 64
|
|
i.v = u.i[2];
|
|
assert(i.op2.b == 4);
|
|
label = (label >> 32) & 0xffffffff;
|
|
i.imm22.b = HI((int)label);
|
|
u.i[2] = i.v;
|
|
i.v = u.i[3];
|
|
assert(i.op.b == 2 && i.op3.b == 2);
|
|
/* ORI */
|
|
i.simm13.b = LO(label);
|
|
u.i[3] = i.v;
|
|
# endif
|
|
}
|
|
else
|
|
abort();
|
|
}
|
|
else
|
|
abort();
|
|
}
|
|
else
|
|
abort();
|
|
}
|
|
#endif
|