tcg/mips: Split out target constraints to tcg-target-con-str.h
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
7d1820a755
commit
51800e4346
24
tcg/mips/tcg-target-con-str.h
Normal file
24
tcg/mips/tcg-target-con-str.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
/*
|
||||||
|
* Define MIPS target-specific operand constraints.
|
||||||
|
* Copyright (c) 2021 Linaro
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define constraint letters for register sets:
|
||||||
|
* REGS(letter, register_mask)
|
||||||
|
*/
|
||||||
|
REGS('r', ALL_GENERAL_REGS)
|
||||||
|
REGS('L', ALL_QLOAD_REGS)
|
||||||
|
REGS('S', ALL_QSTORE_REGS)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define constraint letters for constants:
|
||||||
|
* CONST(letter, TCG_CT_CONST_* bit set)
|
||||||
|
*/
|
||||||
|
CONST('I', TCG_CT_CONST_U16)
|
||||||
|
CONST('J', TCG_CT_CONST_S16)
|
||||||
|
CONST('K', TCG_CT_CONST_P2M1)
|
||||||
|
CONST('N', TCG_CT_CONST_N16)
|
||||||
|
CONST('W', TCG_CT_CONST_WSZ)
|
||||||
|
CONST('Z', TCG_CT_CONST_ZERO)
|
@ -171,67 +171,27 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
|
|||||||
#define TCG_CT_CONST_N16 0x1000 /* "Negatable" 16-bit: -32767 - 32767 */
|
#define TCG_CT_CONST_N16 0x1000 /* "Negatable" 16-bit: -32767 - 32767 */
|
||||||
#define TCG_CT_CONST_WSZ 0x2000 /* word size */
|
#define TCG_CT_CONST_WSZ 0x2000 /* word size */
|
||||||
|
|
||||||
|
#define ALL_GENERAL_REGS 0xffffffffu
|
||||||
|
#define NOA0_REGS (ALL_GENERAL_REGS & ~(1 << TCG_REG_A0))
|
||||||
|
|
||||||
|
#ifdef CONFIG_SOFTMMU
|
||||||
|
#define ALL_QLOAD_REGS \
|
||||||
|
(NOA0_REGS & ~((TCG_TARGET_REG_BITS < TARGET_LONG_BITS) << TCG_REG_A2))
|
||||||
|
#define ALL_QSTORE_REGS \
|
||||||
|
(NOA0_REGS & ~(TCG_TARGET_REG_BITS < TARGET_LONG_BITS \
|
||||||
|
? (1 << TCG_REG_A2) | (1 << TCG_REG_A3) \
|
||||||
|
: (1 << TCG_REG_A1)))
|
||||||
|
#else
|
||||||
|
#define ALL_QLOAD_REGS NOA0_REGS
|
||||||
|
#define ALL_QSTORE_REGS NOA0_REGS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static inline bool is_p2m1(tcg_target_long val)
|
static inline bool is_p2m1(tcg_target_long val)
|
||||||
{
|
{
|
||||||
return val && ((val + 1) & val) == 0;
|
return val && ((val + 1) & val) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 'L': /* qemu_ld input arg constraint */
|
|
||||||
ct->regs = 0xffffffff;
|
|
||||||
tcg_regset_reset_reg(ct->regs, TCG_REG_A0);
|
|
||||||
#if defined(CONFIG_SOFTMMU)
|
|
||||||
if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
|
|
||||||
tcg_regset_reset_reg(ct->regs, TCG_REG_A2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 'S': /* qemu_st constraint */
|
|
||||||
ct->regs = 0xffffffff;
|
|
||||||
tcg_regset_reset_reg(ct->regs, TCG_REG_A0);
|
|
||||||
#if defined(CONFIG_SOFTMMU)
|
|
||||||
if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
|
|
||||||
tcg_regset_reset_reg(ct->regs, TCG_REG_A2);
|
|
||||||
tcg_regset_reset_reg(ct->regs, TCG_REG_A3);
|
|
||||||
} else {
|
|
||||||
tcg_regset_reset_reg(ct->regs, TCG_REG_A1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 'I':
|
|
||||||
ct->ct |= TCG_CT_CONST_U16;
|
|
||||||
break;
|
|
||||||
case 'J':
|
|
||||||
ct->ct |= TCG_CT_CONST_S16;
|
|
||||||
break;
|
|
||||||
case 'K':
|
|
||||||
ct->ct |= TCG_CT_CONST_P2M1;
|
|
||||||
break;
|
|
||||||
case 'N':
|
|
||||||
ct->ct |= TCG_CT_CONST_N16;
|
|
||||||
break;
|
|
||||||
case 'W':
|
|
||||||
ct->ct |= TCG_CT_CONST_WSZ;
|
|
||||||
break;
|
|
||||||
case 'Z':
|
|
||||||
/* We are cheating a bit here, using the fact that the register
|
|
||||||
ZERO is also the register number 0. Hence there is no need
|
|
||||||
to check for const_args in each instruction. */
|
|
||||||
ct->ct |= TCG_CT_CONST_ZERO;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return ct_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* test if a constant matches the constraint */
|
/* test if a constant matches the constraint */
|
||||||
static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
|
static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
|
||||||
const TCGArgConstraint *arg_ct)
|
const TCGArgConstraint *arg_ct)
|
||||||
@ -1697,6 +1657,11 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
|||||||
TCGArg a0, a1, a2;
|
TCGArg a0, a1, a2;
|
||||||
int c2;
|
int c2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that many operands use the constraint set "rZ".
|
||||||
|
* We make use of the fact that 0 is the ZERO register,
|
||||||
|
* and hence such cases need not check for const_args.
|
||||||
|
*/
|
||||||
a0 = args[0];
|
a0 = args[0];
|
||||||
a1 = args[1];
|
a1 = args[1];
|
||||||
a2 = args[2];
|
a2 = args[2];
|
||||||
|
@ -207,5 +207,6 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
|
|||||||
#ifdef CONFIG_SOFTMMU
|
#ifdef CONFIG_SOFTMMU
|
||||||
#define TCG_TARGET_NEED_LDST_LABELS
|
#define TCG_TARGET_NEED_LDST_LABELS
|
||||||
#endif
|
#endif
|
||||||
|
#define TCG_TARGET_CON_STR_H
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user