tcg/sparc: Split out target constraints to tcg-target-con-str.h

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2020-10-16 23:10:53 -05:00
parent c947deb13e
commit 77f268e80b
3 changed files with 55 additions and 54 deletions

View file

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: MIT */
/*
* Define Sparc target-specific operand constraints.
* Copyright (c) 2021 Linaro
*/
/*
* Define constraint letters for register sets:
* REGS(letter, register_mask)
*/
REGS('r', ALL_GENERAL_REGS)
REGS('R', ALL_GENERAL_REGS64)
REGS('s', ALL_QLDST_REGS)
REGS('S', ALL_QLDST_REGS64)
REGS('A', TARGET_LONG_BITS == 64 ? ALL_QLDST_REGS64 : ALL_QLDST_REGS)
/*
* Define constraint letters for constants:
* CONST(letter, TCG_CT_CONST_* bit set)
*/
CONST('I', TCG_CT_CONST_S11)
CONST('J', TCG_CT_CONST_S13)
CONST('Z', TCG_CT_CONST_ZERO)

View file

@ -67,18 +67,38 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
# define SPARC64 0
#endif
/* Note that sparcv8plus can only hold 64 bit quantities in %g and %o
registers. These are saved manually by the kernel in full 64-bit
slots. The %i and %l registers are saved by the register window
mechanism, which only allocates space for 32 bits. Given that this
window spill/fill can happen on any signal, we must consider the
high bits of the %i and %l registers garbage at all times. */
#if SPARC64
# define ALL_64 0xffffffffu
#define TCG_CT_CONST_S11 0x100
#define TCG_CT_CONST_S13 0x200
#define TCG_CT_CONST_ZERO 0x400
/*
* For softmmu, we need to avoid conflicts with the first 3
* argument registers to perform the tlb lookup, and to call
* the helper function.
*/
#ifdef CONFIG_SOFTMMU
#define SOFTMMU_RESERVE_REGS MAKE_64BIT_MASK(TCG_REG_O0, 3)
#else
# define ALL_64 0xffffu
#define SOFTMMU_RESERVE_REGS 0
#endif
/*
* Note that sparcv8plus can only hold 64 bit quantities in %g and %o
* registers. These are saved manually by the kernel in full 64-bit
* slots. The %i and %l registers are saved by the register window
* mechanism, which only allocates space for 32 bits. Given that this
* window spill/fill can happen on any signal, we must consider the
* 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)
/* Define some temporary registers. T2 is used for constant generation. */
#define TCG_REG_T1 TCG_REG_G1
#define TCG_REG_T2 TCG_REG_O7
@ -320,45 +340,6 @@ static bool patch_reloc(tcg_insn_unit *src_rw, int type,
return true;
}
/* parse target specific constraints */
static const char *target_parse_constraint(TCGArgConstraint *ct,
const char *ct_str, TCGType type)
{
switch (*ct_str++) {
case 'r':
ct->regs = 0xffffffff;
break;
case 'R':
ct->regs = ALL_64;
break;
case 'A': /* qemu_ld/st address constraint */
ct->regs = TARGET_LONG_BITS == 64 ? ALL_64 : 0xffffffff;
reserve_helpers:
tcg_regset_reset_reg(ct->regs, TCG_REG_O0);
tcg_regset_reset_reg(ct->regs, TCG_REG_O1);
tcg_regset_reset_reg(ct->regs, TCG_REG_O2);
break;
case 's': /* qemu_st data 32-bit constraint */
ct->regs = 0xffffffff;
goto reserve_helpers;
case 'S': /* qemu_st data 64-bit constraint */
ct->regs = ALL_64;
goto reserve_helpers;
case 'I':
ct->ct |= TCG_CT_CONST_S11;
break;
case 'J':
ct->ct |= TCG_CT_CONST_S13;
break;
case 'Z':
ct->ct |= TCG_CT_CONST_ZERO;
break;
default:
return NULL;
}
return ct_str;
}
/* test if a constant matches the constraint */
static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
const TCGArgConstraint *arg_ct)
@ -1746,8 +1727,8 @@ static void tcg_target_init(TCGContext *s)
}
#endif
tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
tcg_target_available_regs[TCG_TYPE_I64] = ALL_64;
tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS;
tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS64;
tcg_target_call_clobber_regs = 0;
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G1);

View file

@ -66,10 +66,6 @@ typedef enum {
TCG_REG_I7,
} TCGReg;
#define TCG_CT_CONST_S11 0x100
#define TCG_CT_CONST_S13 0x200
#define TCG_CT_CONST_ZERO 0x400
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_O6
@ -172,5 +168,6 @@ extern bool use_vis3_instructions;
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
#define TCG_TARGET_NEED_POOL_LABELS
#define TCG_TARGET_CON_STR_H
#endif