mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 20:00:19 +02:00
* check/float.tst: Add sparc to list of known NaN and +-Inf to integer conversion. * check/lightning.c: Define __sparc__ to preprocessor in the sparc backend. * include/lightning/jit_private.h: Correct wrong definition of emit_stxi_d, that has lived for a long time, but would cause problems whenever needing to spill/reload a float register. * include/lightning/jit_sparc.h: Can only use %g2,%g3,%g4 for scratch variables, as other "global" registers are reserved for the system, e.g. libc. Reorder float register naming to make it easier to access odd float registers, so that generating code for pusharg and getarg is easier for the IR. * lib/jit_mips-cpu.c, lib/jit_ppc-cpu.c: Update to match new code in jit_sparc-cpu.c. It must call jit_get_reg with jit_class_nospill if using the register to move an unconditional branch address to it, as the reload will not happen (actually could happen in the delay slot...) * lib/jit_sparc-cpu.c: Correct wrong macro definition for ldxr_s. Properly implement div* and implement rem. Div* needs to use the y register, and rem* needs to be synthesized. Correct b?sub* macro definitions. * lib/jit_sparc-fpu.c: Correct reversed float to/from double conversion. Correct wrong jit_get_reg call asking for a gpr and then using the fpr with that number. Correct wrong branch displacement computation for conditional branches. * lib/jit_sparc.c: Correct getarg_d and pushargi_d implementation. Add rem* entries to the switch converting IR to machine code. * lib/lightning.c: Correct a problem detected when adding the jit_class_nospill flag to jit_get_reg, that was caused when having a branch to an "epilog" node, what would cause the code to think all registers in unknown state were live, while in truth, all registers in unknown state in the "just after return" point are actually dead.
1628 lines
50 KiB
C
1628 lines
50 KiB
C
/*
|
|
* Copyright (C) 2013 Free Software Foundation, Inc.
|
|
*
|
|
* This is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This software is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* Authors:
|
|
* Paulo Cesar Pereira de Andrade
|
|
*/
|
|
|
|
#if PROTO
|
|
# define _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
|
|
* sp+ 16 words for in and local registers
|
|
* sp ----
|
|
* decreasing memory address - next stack frame (not yet allocated)
|
|
*/
|
|
/* FIXME need to allocate space for saving float registers f0-f7? */
|
|
# define stack_framesize ((16 + 1 + 6) * 4)
|
|
|
|
typedef union {
|
|
struct { jit_uint32_t b: 2; } op;
|
|
struct { jit_uint32_t _: 2; jit_uint32_t b: 1; } a;
|
|
struct { jit_uint32_t _: 2; jit_uint32_t b: 5; } rd;
|
|
struct { jit_uint32_t _: 2; jit_uint32_t b: 30; } disp30;
|
|
struct { jit_uint32_t _: 3; jit_uint32_t b: 4; } cond;
|
|
struct { jit_uint32_t _: 7; jit_uint32_t b: 3; } op2;
|
|
struct { jit_uint32_t _: 7; jit_uint32_t b: 6; } op3;
|
|
struct { jit_uint32_t _: 10; jit_uint32_t b: 22; } imm22;
|
|
struct { jit_uint32_t _: 10; jit_uint32_t b: 22; } disp22;
|
|
struct { jit_uint32_t _: 13; jit_uint32_t b: 5; } rs1;
|
|
struct { jit_uint32_t _: 18; jit_uint32_t b: 1; } i;
|
|
struct { jit_uint32_t _: 18; jit_uint32_t b: 9; } opf;
|
|
struct { jit_uint32_t _: 19; jit_uint32_t b: 8; } asi;
|
|
struct { jit_uint32_t _: 19; jit_uint32_t b: 6; } res;
|
|
struct { jit_uint32_t _: 19; jit_uint32_t b: 13; } simm13;
|
|
struct { jit_uint32_t _: 27; jit_uint32_t b: 5; } rs2;
|
|
struct { jit_uint32_t _: 25; jit_uint32_t b: 7; } imm7;
|
|
jit_int32_t v;
|
|
} jit_instr_t;
|
|
# define ii(i) *_jit->pc.ui++ = i
|
|
|
|
# define s7_p(imm) ((imm) <= 127 && (imm) >= -128)
|
|
# define s13_p(imm) ((imm) <= 8191 && (imm) >= -8192)
|
|
# define s22_p(imm) ((imm) <= 4194303 && (imm) >= -4194304)
|
|
# define s30_p(imm) ((imm) <= 1073741823 && (imm) >= -1073741824)
|
|
# define f1(op, disp30) _f1(_jit, op, disp30)
|
|
static void _f1(jit_state_t*,jit_int32_t,jit_int32_t);
|
|
# define f2r(op, rd, op2, imm22) _f2r(_jit, op, rd, op2, imm22)
|
|
static void _f2r(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define f2b(op, a, cond, op2, disp22) _f2b(_jit, op, a, cond, op2, disp22)
|
|
static void
|
|
_f2b(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define f3r(op, rd, op3, rs1, rs2) _f3r(_jit, op, rd, op3, rs1, rs2)
|
|
static void _f3r(jit_state_t*,
|
|
jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define f3i(op, rd, op3, rs1, simm13) _f3i(_jit, op, rd, op3, rs1, simm13)
|
|
static void _f3i(jit_state_t*,
|
|
jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# define f3t(cond, rs1, i, ri) _f3t(_jit, cond, rs1, i, ri)
|
|
static void _f3t(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_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*,jit_int32_t,
|
|
jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t,jit_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)
|
|
# 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)
|
|
# 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)
|
|
# 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)
|
|
# 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)
|
|
# 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)
|
|
# define STBA(rd, rs1, rs2) f3a(3, rd, 21, rs1, asi, rs2)
|
|
# define STHA(rd, rs1, rs2) f3a(3, rd, 22, rs1, asi, rs2)
|
|
# define STA(rd, rs1, rs2) f3a(3, rd, 20, rs1, asi, rs2)
|
|
# define STDA(rd, rs1, rs2) f3a(3, rd, 23, rs1, asi, rs2)
|
|
# 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)
|
|
# 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)
|
|
# 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 */
|
|
# 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)
|
|
# 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) f3i(2, rd, 40, 0, 0)
|
|
# define RDASR(rs1, rd) f3i(2, rd, 40, rs1, 0)
|
|
# define RDPSR(rd) f3i(2, rd, 41, 0, 0)
|
|
# define RDWIM(rd) f3i(2, rd, 42, 0, 0)
|
|
# define RDTBR(rd) f3i(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*, 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 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*, jit_int32_t, jit_int32_t, jit_word_t);
|
|
# define addcr(r0, r1, r2) ADDcc(r1, r2, r0)
|
|
# define addci(r0, r1, i0) _addci(_jit, r0, r1, i0)
|
|
static void _addci(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
|
|
# define addxr(r0, r1, r2) ADDXcc(r1, r2, r0)
|
|
# define addxi(r0, r1, i0) _addxi(_jit, r0, r1, i0)
|
|
static void _addxi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
|
|
# define subr(r0, r1, r2) SUB(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, r2) SUBcc(r1, r2, r0)
|
|
# define subci(r0, r1, i0) _subci(_jit, r0, r1, i0)
|
|
static void _subci(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
|
|
# define subxr(r0, r1, r2) SUBXcc(r1, r2, r0)
|
|
# define subxi(r0, r1, i0) _subxi(_jit, r0, r1, i0)
|
|
static void _subxi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
|
|
# define mulr(r0, r1, r2) UMUL(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 divr(r0, r1, r2) _divr(_jit, r0, r1, r2)
|
|
static void _divr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
|
|
# define divi(r0, r1, i0) _divi(_jit, r0, r1, i0)
|
|
static void _divi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
|
|
# define divr_u(r0, r1, r2) _divr_u(_jit, r0, r1, r2)
|
|
static void _divr_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
|
|
# define divi_u(r0, r1, i0) _divi_u(_jit, r0, r1, i0)
|
|
static void _divi_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
|
|
# define remr(r0, r1, r2) _remr(_jit, r0, r1, r2)
|
|
static void _remr(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
|
|
# define remi(r0, r1, i0) _remi(_jit, r0, r1, i0)
|
|
static void _remi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
|
|
# define remr_u(r0, r1, r2) _remr_u(_jit, r0, r1, r2)
|
|
static void _remr_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
|
|
# define remi_u(r0, r1, i0) _remi_u(_jit, r0, r1, i0)
|
|
static void _remi_u(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
|
|
|
|
# define 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 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)
|
|
|
|
# define htonr(r0,r1) movr(r0,r1)
|
|
# 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) andi(r0, r1, 0xff)
|
|
# 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 cr(cc, r0, r1, r2) _cr(_jit, cc, r0, r1, r2)
|
|
static void _cr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
|
|
# define cw(cc, r0, r1, i0) _cw(_jit, cc, r0, r1, i0)
|
|
static void _cw(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_word_t);
|
|
|
|
# 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)
|
|
|
|
# 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*,jit_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*,jit_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*,jit_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*,jit_int32_t,jit_word_t);
|
|
# define ldr(u, v) ldr_i(u, v)
|
|
# define ldr_i(r0, r1) LD(r1, 0, r0)
|
|
# define ldi(u, v) ldi_i(u, v)
|
|
# define ldi_i(r0, i0) _ldi_i(_jit, r0, i0)
|
|
static void _ldi_i(jit_state_t*,jit_int32_t,jit_word_t);
|
|
# define ldxr_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*,jit_int32_t,jit_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*,jit_int32_t,jit_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*,jit_int32_t,jit_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*,jit_int32_t,jit_int32_t,jit_word_t);
|
|
# 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)
|
|
# 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 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) STH(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(u, v) str_i(u, v)
|
|
# define str_i(r0, r1) STI(r1, r0, 0)
|
|
# define sti(u, v) sti_i(u, v)
|
|
# define sti_i(i0, r0) _sti_i(_jit, i0, r0)
|
|
static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t);
|
|
# define stxr_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,jit_int32_t,jit_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,jit_int32_t,jit_int32_t);
|
|
# 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)
|
|
# 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 br(cc, i0, r0, r1) _br(_jit, cc, i0, r0, r1)
|
|
static jit_word_t
|
|
_br(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t);
|
|
# define bw(cc, i0, r0, i1) _bw(_jit, cc, i0, r0, i1)
|
|
static jit_word_t
|
|
_bw(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_word_t);
|
|
# 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)
|
|
|
|
# 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,jit_int32_t,jit_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,jit_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,jit_int32_t,jit_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,jit_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*,jit_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*,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
|
|
_f2r(jit_state_t *_jit,
|
|
jit_int32_t op, jit_int32_t rd, jit_int32_t op2, jit_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,
|
|
jit_int32_t op, jit_int32_t a, jit_int32_t cond, jit_int32_t op2,
|
|
jit_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);
|
|
}
|
|
|
|
static void
|
|
_f3r(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd,
|
|
jit_int32_t op3, jit_int32_t rs1, jit_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);
|
|
}
|
|
|
|
static void
|
|
_f3i(jit_state_t *_jit, jit_int32_t op, jit_int32_t rd,
|
|
jit_int32_t op3, jit_int32_t rs1, jit_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, jit_int32_t cond,
|
|
jit_int32_t rs1, jit_int32_t i, jit_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, jit_int32_t op, jit_int32_t rd,
|
|
jit_int32_t op3, jit_int32_t rs1, jit_int32_t asi, jit_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, jit_int32_t op, jit_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, jit_int32_t i0)
|
|
{
|
|
while (i0--)
|
|
NOP();
|
|
}
|
|
|
|
static void
|
|
_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
if (r0 != r1)
|
|
ORI(r1, 0, r0);
|
|
}
|
|
|
|
static void
|
|
_movi(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
if (s13_p(i0))
|
|
ORI(0, i0, r0);
|
|
else {
|
|
SETHI(HI(i0), r0);
|
|
if (LO(i0))
|
|
ORI(r0, LO(i0), r0);
|
|
}
|
|
}
|
|
|
|
static jit_word_t
|
|
_movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_word_t w;
|
|
w = _jit->pc.w;
|
|
SETHI(HI(i0), r0);
|
|
ORI(r0, LO(i0), r0);
|
|
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 (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);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_addci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_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);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_addxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_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);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_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);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_subci(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_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);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_subxi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_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);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_muli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (s13_p(i0))
|
|
UMULI(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
|
|
_divr(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);
|
|
rshi(rn(reg), r1, 31);
|
|
WRY(rn(reg), 0);
|
|
SDIV(r1, r2, r0);
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
if (s13_p(i0)) {
|
|
rshi(rn(reg), r1, 31);
|
|
WRY(rn(reg), 0);
|
|
SDIVI(r1, i0, r0);
|
|
}
|
|
else {
|
|
movi(rn(reg), i0);
|
|
divr(r0, r1, rn(reg));
|
|
}
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
WRYI(0, 0);
|
|
UDIV(r1, r2, r0);
|
|
}
|
|
|
|
static void
|
|
_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (s13_p(i0)) {
|
|
WRYI(0, 0);
|
|
UDIVI(r1, i0, r0);
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
divr_u(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_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, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
remr(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
jit_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, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
remr_u(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
|
|
static void
|
|
_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (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, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_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, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_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, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
lshi(r0, r1, 24);
|
|
rshi(r0, r0, 24);
|
|
}
|
|
|
|
static void
|
|
_extr_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
lshi(r0, r1, 16);
|
|
rshi(r0, r0, 16);
|
|
}
|
|
|
|
static void
|
|
_extr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
lshi(r0, r1, 16);
|
|
rshi_u(r0, r0, 16);
|
|
}
|
|
|
|
static void
|
|
_cr(jit_state_t *_jit, jit_int32_t cc,
|
|
jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|
{
|
|
CMP(r1, r2);
|
|
Ba(cc, 3);
|
|
movi(r0, 1);
|
|
movi(r0, 0);
|
|
}
|
|
|
|
static void
|
|
_cw(jit_state_t *_jit, jit_int32_t cc,
|
|
jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (s13_p(i0)) {
|
|
CMPI(r1, i0);
|
|
Ba(cc, 3);
|
|
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, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_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, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_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, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_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, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_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, jit_int32_t r0, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (s13_p(i0))
|
|
LDI(0, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldr_i(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 (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, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_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, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (s13_p(i0))
|
|
LDSHI(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_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_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, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (s13_p(i0))
|
|
LDI(r1, i0, r0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
ldxr_i(r0, r1, rn(reg));
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_sti_c(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (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, jit_int32_t r0)
|
|
{
|
|
jit_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, jit_int32_t r0)
|
|
{
|
|
jit_int32_t reg;
|
|
if (s13_p(i0))
|
|
STI(r0, 0, i0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
str_i(rn(reg), r0);
|
|
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 (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, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_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, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_int32_t reg;
|
|
if (s13_p(i0))
|
|
STI(r1, r0, i0);
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
movi(rn(reg), i0);
|
|
stxr_i(r0, rn(reg), r1);
|
|
jit_unget_reg(reg);
|
|
}
|
|
}
|
|
|
|
static jit_word_t
|
|
_br(jit_state_t *_jit, jit_int32_t cc,
|
|
jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
CMP(r0, r1);
|
|
w = _jit->pc.w;
|
|
B(cc, (i0 - w) >> 2);
|
|
NOP();
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bw(jit_state_t *_jit, jit_int32_t cc,
|
|
jit_word_t i0, jit_int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
if (s13_p(i1)) {
|
|
CMPI(r0, i1);
|
|
w = _jit->pc.w;
|
|
B(cc, (i0 - w) >> 2);
|
|
NOP();
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
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, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
if (add)
|
|
ADDcc(r0, r1, r0);
|
|
else
|
|
SUBcc(r0, r1, r0);
|
|
w = _jit->pc.w;
|
|
B(sgn ?
|
|
(jif ? SPARC_BVS : SPARC_BVC) :
|
|
(jif ? SPARC_BCS : SPARC_BCC),
|
|
(i0 - w) >> 2);
|
|
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, jit_int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
if (s13_p(i1)) {
|
|
if (add)
|
|
ADDIcc(r0, i1, r0);
|
|
else
|
|
SUBIcc(r0, i1, r0);
|
|
w = _jit->pc.w;
|
|
B(sgn ?
|
|
(jif ? SPARC_BVS : SPARC_BVC) :
|
|
(jif ? SPARC_BCS : SPARC_BCC),
|
|
(i0 - w) >> 2);
|
|
NOP();
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
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, jit_int32_t r0, jit_int32_t r1)
|
|
{
|
|
jit_word_t w;
|
|
BTST(r0, r1);
|
|
w = _jit->pc.w;
|
|
B(set ? SPARC_BNZ : SPARC_BZ, (i0 - w) >> 2);
|
|
NOP();
|
|
return (w);
|
|
}
|
|
|
|
static jit_word_t
|
|
_bm_w(jit_state_t *_jit, jit_bool_t set,
|
|
jit_word_t i0, jit_int32_t r0, jit_word_t i1)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
if (s13_p(i1)) {
|
|
BTSTI(r0, i1);
|
|
w = _jit->pc.w;
|
|
B(set ? SPARC_BNZ : SPARC_BZ, (i0 - w) >> 2);
|
|
NOP();
|
|
}
|
|
else {
|
|
reg = jit_get_reg(jit_class_gpr);
|
|
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, jit_int32_t r0)
|
|
{
|
|
JMPL(0, r0, 0);
|
|
NOP();
|
|
}
|
|
|
|
static void
|
|
_jmpi(jit_state_t *_jit, jit_word_t i0)
|
|
{
|
|
jit_word_t w;
|
|
jit_int32_t reg;
|
|
w = (i0 - 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;
|
|
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)
|
|
{
|
|
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;
|
|
jit_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);
|
|
}
|
|
|
|
static void
|
|
_prolog(jit_state_t *_jit, jit_node_t *node)
|
|
{
|
|
/* align at 16 bytes boundary */
|
|
_jit->function->stack = ((stack_framesize +
|
|
_jit->function->self.alen -
|
|
_jit->function->self.aoff) + 15) & -16;
|
|
SAVEI(_SP_REGNO, -_jit->function->stack, _SP_REGNO);
|
|
|
|
/* (most) other backends do not save incoming arguments, so,
|
|
* only save locals here */
|
|
if (jit_regset_tstbit(_jit->function->regset, _L0))
|
|
stxi(0, _SP_REGNO, _L0_REGNO);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L1))
|
|
stxi(4, _SP_REGNO, _L1_REGNO);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L2))
|
|
stxi(8, _SP_REGNO, _L2_REGNO);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L3))
|
|
stxi(12, _SP_REGNO, _L3_REGNO);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L4))
|
|
stxi(16, _SP_REGNO, _L4_REGNO);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L5))
|
|
stxi(20, _SP_REGNO, _L5_REGNO);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L6))
|
|
stxi(24, _SP_REGNO, _L6_REGNO);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L7))
|
|
stxi(28, _SP_REGNO, _L7_REGNO);
|
|
}
|
|
|
|
static void
|
|
_epilog(jit_state_t *_jit, jit_node_t *node)
|
|
{
|
|
/* (most) other backends do not save incoming arguments, so,
|
|
* only save locals here */
|
|
if (jit_regset_tstbit(_jit->function->regset, _L0))
|
|
ldxi(_L0_REGNO, _SP_REGNO, 0);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L1))
|
|
ldxi(_L1_REGNO, _SP_REGNO, 4);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L2))
|
|
ldxi(_L2_REGNO, _SP_REGNO, 8);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L3))
|
|
ldxi(_L3_REGNO, _SP_REGNO, 12);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L4))
|
|
ldxi(_L4_REGNO, _SP_REGNO, 16);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L5))
|
|
ldxi(_L5_REGNO, _SP_REGNO, 20);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L6))
|
|
ldxi(_L6_REGNO, _SP_REGNO, 24);
|
|
if (jit_regset_tstbit(_jit->function->regset, _L7))
|
|
ldxi(_L7_REGNO, _SP_REGNO, 28);
|
|
RESTOREI(0, 0, 0);
|
|
RETL();
|
|
NOP();
|
|
}
|
|
|
|
static void
|
|
_patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
|
|
{
|
|
jit_instr_t i;
|
|
union {
|
|
jit_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;
|
|
}
|
|
else if (i.op2.b == 4) { /* movi_p */
|
|
/* SETHI */
|
|
i.imm22.b = HI(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;
|
|
}
|
|
else
|
|
abort();
|
|
}
|
|
else
|
|
abort();
|
|
}
|
|
else
|
|
abort();
|
|
}
|
|
#endif
|