@@ -25,8 +25,6 @@
#ifndef SPARC_TCG_TARGET_H
#define SPARC_TCG_TARGET_H
-#define TCG_TARGET_REG_BITS 64
-
#define TCG_TARGET_INSN_UNIT_SIZE 4
#define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
#define TCG_TARGET_NB_REGS 32
@@ -70,19 +68,10 @@ typedef enum {
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_O6
-#ifdef __arch64__
#define TCG_TARGET_STACK_BIAS 2047
#define TCG_TARGET_STACK_ALIGN 16
#define TCG_TARGET_CALL_STACK_OFFSET (128 + 6*8 + TCG_TARGET_STACK_BIAS)
-#else
-#define TCG_TARGET_STACK_BIAS 0
-#define TCG_TARGET_STACK_ALIGN 8
-#define TCG_TARGET_CALL_STACK_OFFSET (64 + 4 + 6*4)
-#endif
-
-#ifdef __arch64__
#define TCG_TARGET_EXTEND_ARGS 1
-#endif
#if defined(__VIS__) && __VIS__ >= 0x300
#define use_vis3_instructions 1
@@ -1487,39 +1487,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
}
#endif
-#if defined(__sparc__) && !defined(__arch64__) \
- && !defined(CONFIG_TCG_INTERPRETER)
- /* We have 64-bit values in one register, but need to pass as two
- separate parameters. Split them. */
- int orig_typemask = typemask;
- int orig_nargs = nargs;
- TCGv_i64 retl, reth;
- TCGTemp *split_args[MAX_OPC_PARAM];
-
- retl = NULL;
- reth = NULL;
- typemask = 0;
- for (i = real_args = 0; i < nargs; ++i) {
- int argtype = extract32(orig_typemask, (i + 1) * 3, 3);
- bool is_64bit = (argtype & ~1) == dh_typecode_i64;
-
- if (is_64bit) {
- TCGv_i64 orig = temp_tcgv_i64(args[i]);
- TCGv_i32 h = tcg_temp_new_i32();
- TCGv_i32 l = tcg_temp_new_i32();
- tcg_gen_extr_i64_i32(l, h, orig);
- split_args[real_args++] = tcgv_i32_temp(h);
- typemask |= dh_typecode_i32 << (real_args * 3);
- split_args[real_args++] = tcgv_i32_temp(l);
- typemask |= dh_typecode_i32 << (real_args * 3);
- } else {
- split_args[real_args++] = args[i];
- typemask |= argtype << (real_args * 3);
- }
- }
- nargs = real_args;
- args = split_args;
-#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
+#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
for (i = 0; i < nargs; ++i) {
int argtype = extract32(typemask, (i + 1) * 3, 3);
bool is_32bit = (argtype & ~1) == dh_typecode_i32;
@@ -1542,22 +1510,6 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
pi = 0;
if (ret != NULL) {
-#if defined(__sparc__) && !defined(__arch64__) \
- && !defined(CONFIG_TCG_INTERPRETER)
- if ((typemask & 6) == dh_typecode_i64) {
- /* The 32-bit ABI is going to return the 64-bit value in
- the %o0/%o1 register pair. Prepare for this by using
- two return temporaries, and reassemble below. */
- retl = tcg_temp_new_i64();
- reth = tcg_temp_new_i64();
- op->args[pi++] = tcgv_i64_arg(reth);
- op->args[pi++] = tcgv_i64_arg(retl);
- nb_rets = 2;
- } else {
- op->args[pi++] = temp_arg(ret);
- nb_rets = 1;
- }
-#else
if (TCG_TARGET_REG_BITS < 64 && (typemask & 6) == dh_typecode_i64) {
#if HOST_BIG_ENDIAN
op->args[pi++] = temp_arg(ret + 1);
@@ -1571,7 +1523,6 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
op->args[pi++] = temp_arg(ret);
nb_rets = 1;
}
-#endif
} else {
nb_rets = 0;
}
@@ -1634,29 +1585,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
tcg_debug_assert(TCGOP_CALLI(op) == real_args);
tcg_debug_assert(pi <= ARRAY_SIZE(op->args));
-#if defined(__sparc__) && !defined(__arch64__) \
- && !defined(CONFIG_TCG_INTERPRETER)
- /* Free all of the parts we allocated above. */
- for (i = real_args = 0; i < orig_nargs; ++i) {
- int argtype = extract32(orig_typemask, (i + 1) * 3, 3);
- bool is_64bit = (argtype & ~1) == dh_typecode_i64;
-
- if (is_64bit) {
- tcg_temp_free_internal(args[real_args++]);
- tcg_temp_free_internal(args[real_args++]);
- } else {
- real_args++;
- }
- }
- if ((orig_typemask & 6) == dh_typecode_i64) {
- /* The 32-bit ABI returned two 32-bit pieces. Re-assemble them.
- Note that describing these as TCGv_i64 eliminates an unnecessary
- zero-extension that tcg_gen_concat_i32_i64 would create. */
- tcg_gen_concat32_i64(temp_tcgv_i64(ret), retl, reth);
- tcg_temp_free_i64(retl);
- tcg_temp_free_i64(reth);
- }
-#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
+#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
for (i = 0; i < nargs; ++i) {
int argtype = extract32(typemask, (i + 1) * 3, 3);
bool is_32bit = (argtype & ~1) == dh_typecode_i32;
@@ -22,6 +22,11 @@
* THE SOFTWARE.
*/
+/* We only support generating code for 64-bit mode. */
+#ifndef __arch64__
+#error "unsupported code generation mode"
+#endif
+
#include "../tcg-pool.c.inc"
#ifdef CONFIG_DEBUG_TCG
@@ -61,12 +66,6 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
};
#endif
-#ifdef __arch64__
-# define SPARC64 1
-#else
-# define SPARC64 0
-#endif
-
#define TCG_CT_CONST_S11 0x100
#define TCG_CT_CONST_S13 0x200
#define TCG_CT_CONST_ZERO 0x400
@@ -91,11 +90,7 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
* high bits of the %i and %l registers garbage at all times.
*/
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
-#if SPARC64
# define ALL_GENERAL_REGS64 ALL_GENERAL_REGS
-#else
-# define ALL_GENERAL_REGS64 MAKE_64BIT_MASK(0, 16)
-#endif
#define ALL_QLDST_REGS (ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS)
#define ALL_QLDST_REGS64 (ALL_GENERAL_REGS64 & ~SOFTMMU_RESERVE_REGS)
@@ -306,11 +301,7 @@ static bool check_fit_i32(int32_t val, unsigned int bits)
}
#define check_fit_tl check_fit_i64
-#if SPARC64
-# define check_fit_ptr check_fit_i64
-#else
-# define check_fit_ptr check_fit_i32
-#endif
+#define check_fit_ptr check_fit_i64
static bool patch_reloc(tcg_insn_unit *src_rw, int type,
intptr_t value, intptr_t addend)
@@ -573,11 +564,6 @@ static void tcg_out_sety(TCGContext *s, TCGReg rs)
tcg_out32(s, WRY | INSN_RS1(TCG_REG_G0) | INSN_RS2(rs));
}
-static void tcg_out_rdy(TCGContext *s, TCGReg rd)
-{
- tcg_out32(s, RDY | INSN_RD(rd));
-}
-
static void tcg_out_div32(TCGContext *s, TCGReg rd, TCGReg rs1,
int32_t val2, int val2const, int uns)
{
@@ -914,9 +900,7 @@ static void emit_extend(TCGContext *s, TCGReg r, int op)
tcg_out_arithi(s, r, r, 16, SHIFT_SRL);
break;
case MO_32:
- if (SPARC64) {
- tcg_out_arith(s, r, r, 0, SHIFT_SRL);
- }
+ tcg_out_arith(s, r, r, 0, SHIFT_SRL);
break;
case MO_64:
break;
@@ -948,7 +932,6 @@ static void build_trampolines(TCGContext *s)
};
int i;
- TCGReg ra;
for (i = 0; i < ARRAY_SIZE(qemu_ld_helpers); ++i) {
if (qemu_ld_helpers[i] == NULL) {
@@ -961,16 +944,8 @@ static void build_trampolines(TCGContext *s)
}
qemu_ld_trampoline[i] = tcg_splitwx_to_rx(s->code_ptr);
- if (SPARC64 || TARGET_LONG_BITS == 32) {
- ra = TCG_REG_O3;
- } else {
- /* Install the high part of the address. */
- tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O2, 32, SHIFT_SRLX);
- ra = TCG_REG_O4;
- }
-
/* Set the retaddr operand. */
- tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O3, TCG_REG_O7);
/* Tail call. */
tcg_out_jmpl_const(s, qemu_ld_helpers[i], true, true);
/* delay slot -- set the env argument */
@@ -988,37 +963,10 @@ static void build_trampolines(TCGContext *s)
}
qemu_st_trampoline[i] = tcg_splitwx_to_rx(s->code_ptr);
- if (SPARC64) {
- emit_extend(s, TCG_REG_O2, i);
- ra = TCG_REG_O4;
- } else {
- ra = TCG_REG_O1;
- if (TARGET_LONG_BITS == 64) {
- /* Install the high part of the address. */
- tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);
- ra += 2;
- } else {
- ra += 1;
- }
- if ((i & MO_SIZE) == MO_64) {
- /* Install the high part of the data. */
- tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);
- ra += 2;
- } else {
- emit_extend(s, ra, i);
- ra += 1;
- }
- /* Skip the oi argument. */
- ra += 1;
- }
-
+ emit_extend(s, TCG_REG_O2, i);
+
/* Set the retaddr operand. */
- if (ra >= TCG_REG_O6) {
- tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_O7, TCG_REG_CALL_STACK,
- TCG_TARGET_CALL_STACK_OFFSET);
- } else {
- tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
- }
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O4, TCG_REG_O7);
/* Tail call. */
tcg_out_jmpl_const(s, qemu_st_helpers[i], true, true);
@@ -1047,11 +995,6 @@ static void build_trampolines(TCGContext *s)
qemu_unalign_st_trampoline = tcg_splitwx_to_rx(s->code_ptr);
}
- if (!SPARC64 && TARGET_LONG_BITS == 64) {
- /* Install the high part of the address. */
- tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O2, 32, SHIFT_SRLX);
- }
-
/* Tail call. */
tcg_out_jmpl_const(s, helper, true, true);
/* delay slot -- set the env argument */
@@ -1182,7 +1125,7 @@ static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addr, int mem_index,
tcg_out_cmp(s, r0, r2, 0);
/* If the guest address must be zero-extended, do so now. */
- if (SPARC64 && TARGET_LONG_BITS == 32) {
+ if (TARGET_LONG_BITS == 32) {
tcg_out_arithi(s, r0, addr, 0, SHIFT_SRL);
return r0;
}
@@ -1231,7 +1174,7 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
#ifdef CONFIG_SOFTMMU
unsigned memi = get_mmuidx(oi);
- TCGReg addrz, param;
+ TCGReg addrz;
const tcg_insn_unit *func;
addrz = tcg_out_tlb_load(s, addr, memi, memop,
@@ -1251,12 +1194,7 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
/* TLB Miss. */
- param = TCG_REG_O1;
- if (!SPARC64 && TARGET_LONG_BITS == 64) {
- /* Skip the high-part; we'll perform the extract in the trampoline. */
- param++;
- }
- tcg_out_mov(s, TCG_TYPE_REG, param++, addrz);
+ tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_O1, addrz);
/* We use the helpers to extend SB and SW data, leaving the case
of SL needing explicit extending below. */
@@ -1268,30 +1206,13 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
tcg_debug_assert(func != NULL);
tcg_out_call_nodelay(s, func, false);
/* delay slot */
- tcg_out_movi(s, TCG_TYPE_I32, param, oi);
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_O2, oi);
- /* Recall that all of the helpers return 64-bit results.
- Which complicates things for sparcv8plus. */
- if (SPARC64) {
- /* We let the helper sign-extend SB and SW, but leave SL for here. */
- if (is_64 && (memop & MO_SSIZE) == MO_SL) {
- tcg_out_arithi(s, data, TCG_REG_O0, 0, SHIFT_SRA);
- } else {
- tcg_out_mov(s, TCG_TYPE_REG, data, TCG_REG_O0);
- }
+ /* We let the helper sign-extend SB and SW, but leave SL for here. */
+ if (is_64 && (memop & MO_SSIZE) == MO_SL) {
+ tcg_out_arithi(s, data, TCG_REG_O0, 0, SHIFT_SRA);
} else {
- if ((memop & MO_SIZE) == MO_64) {
- tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O0, 32, SHIFT_SLLX);
- tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O1, 0, SHIFT_SRL);
- tcg_out_arith(s, data, TCG_REG_O0, TCG_REG_O1, ARITH_OR);
- } else if (is_64) {
- /* Re-extend from 32-bit rather than reassembling when we
- know the high register must be an extension. */
- tcg_out_arithi(s, data, TCG_REG_O1, 0,
- memop & MO_SIGN ? SHIFT_SRA : SHIFT_SRL);
- } else {
- tcg_out_mov(s, TCG_TYPE_I32, data, TCG_REG_O1);
- }
+ tcg_out_mov(s, TCG_TYPE_REG, data, TCG_REG_O0);
}
*label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
@@ -1301,7 +1222,7 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
unsigned s_bits = memop & MO_SIZE;
unsigned t_bits;
- if (SPARC64 && TARGET_LONG_BITS == 32) {
+ if (TARGET_LONG_BITS == 32) {
tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
addr = TCG_REG_T1;
}
@@ -1337,10 +1258,9 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
* operation in the delay slot, and failure need only invoke the
* handler for SIGBUS.
*/
- TCGReg arg_low = TCG_REG_O1 + (!SPARC64 && TARGET_LONG_BITS == 64);
tcg_out_call_nodelay(s, qemu_unalign_ld_trampoline, false);
/* delay slot -- move to low part of argument reg */
- tcg_out_mov_delay(s, arg_low, addr);
+ tcg_out_mov_delay(s, TCG_REG_O1, addr);
} else {
/* Underalignment: load by pieces of minimum alignment. */
int ld_opc, a_size, s_size, i;
@@ -1400,7 +1320,7 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
#ifdef CONFIG_SOFTMMU
unsigned memi = get_mmuidx(oi);
- TCGReg addrz, param;
+ TCGReg addrz;
const tcg_insn_unit *func;
addrz = tcg_out_tlb_load(s, addr, memi, memop,
@@ -1418,23 +1338,14 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
/* TLB Miss. */
- param = TCG_REG_O1;
- if (!SPARC64 && TARGET_LONG_BITS == 64) {
- /* Skip the high-part; we'll perform the extract in the trampoline. */
- param++;
- }
- tcg_out_mov(s, TCG_TYPE_REG, param++, addrz);
- if (!SPARC64 && (memop & MO_SIZE) == MO_64) {
- /* Skip the high-part; we'll perform the extract in the trampoline. */
- param++;
- }
- tcg_out_mov(s, TCG_TYPE_REG, param++, data);
+ tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_O1, addrz);
+ tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_O2, data);
func = qemu_st_trampoline[memop & (MO_BSWAP | MO_SIZE)];
tcg_debug_assert(func != NULL);
tcg_out_call_nodelay(s, func, false);
/* delay slot */
- tcg_out_movi(s, TCG_TYPE_I32, param, oi);
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_O3, oi);
*label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
#else
@@ -1443,7 +1354,7 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
unsigned s_bits = memop & MO_SIZE;
unsigned t_bits;
- if (SPARC64 && TARGET_LONG_BITS == 32) {
+ if (TARGET_LONG_BITS == 32) {
tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
addr = TCG_REG_T1;
}
@@ -1479,10 +1390,9 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
* operation in the delay slot, and failure need only invoke the
* handler for SIGBUS.
*/
- TCGReg arg_low = TCG_REG_O1 + (!SPARC64 && TARGET_LONG_BITS == 64);
tcg_out_call_nodelay(s, qemu_unalign_st_trampoline, false);
/* delay slot -- move to low part of argument reg */
- tcg_out_mov_delay(s, arg_low, addr);
+ tcg_out_mov_delay(s, TCG_REG_O1, addr);
} else {
/* Underalignment: store by pieces of minimum alignment. */
int st_opc, a_size, s_size, i;
@@ -1719,14 +1629,9 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_muls2_i32:
c = ARITH_SMUL;
do_mul2:
- /* The 32-bit multiply insns produce a full 64-bit result. If the
- destination register can hold it, we can avoid the slower RDY. */
+ /* The 32-bit multiply insns produce a full 64-bit result. */
tcg_out_arithc(s, a0, a2, args[3], const_args[3], c);
- if (SPARC64 || a0 <= TCG_REG_O7) {
- tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX);
- } else {
- tcg_out_rdy(s, a1);
- }
+ tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX);
break;
case INDEX_op_qemu_ld_i32:
@@ -1984,16 +1889,11 @@ static void tcg_target_init(TCGContext *s)
tcg_regset_set_reg(s->reserved_regs, TCG_REG_T2); /* for internal use */
}
-#if SPARC64
-# define ELF_HOST_MACHINE EM_SPARCV9
-#else
-# define ELF_HOST_MACHINE EM_SPARC32PLUS
-# define ELF_HOST_FLAGS EF_SPARC_32PLUS
-#endif
+#define ELF_HOST_MACHINE EM_SPARCV9
typedef struct {
DebugFrameHeader h;
- uint8_t fde_def_cfa[SPARC64 ? 4 : 2];
+ uint8_t fde_def_cfa[4];
uint8_t fde_win_save;
uint8_t fde_ret_save[3];
} DebugFrame;
@@ -2010,12 +1910,8 @@ static const DebugFrame debug_frame = {
.h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
.fde_def_cfa = {
-#if SPARC64
12, 30, /* DW_CFA_def_cfa i6, 2047 */
(2047 & 0x7f) | 0x80, (2047 >> 7)
-#else
- 13, 30 /* DW_CFA_def_cfa_register i6 */
-#endif
},
.fde_win_save = 0x2d, /* DW_CFA_GNU_window_save */
.fde_ret_save = { 9, 15, 31 }, /* DW_CFA_register o7, i7 */
Since 9b9c37c36439, we have only supported sparc64 cpus. Debian and Gentoo now only support 64-bit sparc64 userland, so it is time to drop the 32-bit sparc64 userland: sparc32plus. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- tcg/sparc/tcg-target.h | 11 --- tcg/tcg.c | 75 +---------------- tcg/sparc/tcg-target.c.inc | 166 +++++++------------------------------ 3 files changed, 33 insertions(+), 219 deletions(-)