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

Backports 51800e434679a88bff8b48f62e55ab14642d223e
This commit is contained in:
Richard Henderson 2021-03-04 16:01:18 -05:00 committed by Lioncash
parent 6632fe21bd
commit 154faa6df6
3 changed files with 45 additions and 56 deletions

View 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)

View file

@ -218,5 +218,6 @@ void tb_target_set_jmp_target(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

View file

@ -184,67 +184,26 @@ 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)
@ -1718,6 +1677,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];