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

This eliminates the target-specific function target_parse_constraint
and folds it into the single caller, process_op_defs.  Since this is
done directly into the switch statement, duplicates are compilation
errors rather than silently ignored at runtime.

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 15:27:46 -07:00
parent df903b94b3
commit 358b492392
4 changed files with 62 additions and 74 deletions

View File

@ -0,0 +1,33 @@
/* SPDX-License-Identifier: MIT */
/*
* Define i386 target-specific operand constraints.
* Copyright (c) 2021 Linaro
*
*/
/*
* Define constraint letters for register sets:
* REGS(letter, register_mask)
*/
REGS('a', 1u << TCG_REG_EAX)
REGS('b', 1u << TCG_REG_EBX)
REGS('c', 1u << TCG_REG_ECX)
REGS('d', 1u << TCG_REG_EDX)
REGS('S', 1u << TCG_REG_ESI)
REGS('D', 1u << TCG_REG_EDI)
REGS('r', ALL_GENERAL_REGS)
REGS('x', ALL_VECTOR_REGS)
REGS('q', ALL_BYTEL_REGS) /* regs that can be used as a byte operand */
REGS('Q', ALL_BYTEH_REGS) /* regs with a second byte (e.g. %ah) */
REGS('L', ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS) /* qemu_ld/st */
REGS('s', ALL_BYTEL_REGS & ~SOFTMMU_RESERVE_REGS) /* qemu_st8_i32 data */
/*
* Define constraint letters for constants:
* CONST(letter, TCG_CT_CONST_* bit set)
*/
CONST('e', TCG_CT_CONST_S32)
CONST('I', TCG_CT_CONST_I32)
CONST('W', TCG_CT_CONST_WSZ)
CONST('Z', TCG_CT_CONST_U32)

View File

@ -209,75 +209,6 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
return true; return true;
} }
/* parse target specific constraints */
static const char *target_parse_constraint(TCGArgConstraint *ct,
const char *ct_str, TCGType type)
{
switch(*ct_str++) {
case 'a':
tcg_regset_set_reg(ct->regs, TCG_REG_EAX);
break;
case 'b':
tcg_regset_set_reg(ct->regs, TCG_REG_EBX);
break;
case 'c':
tcg_regset_set_reg(ct->regs, TCG_REG_ECX);
break;
case 'd':
tcg_regset_set_reg(ct->regs, TCG_REG_EDX);
break;
case 'S':
tcg_regset_set_reg(ct->regs, TCG_REG_ESI);
break;
case 'D':
tcg_regset_set_reg(ct->regs, TCG_REG_EDI);
break;
case 'q':
/* A register that can be used as a byte operand. */
ct->regs |= ALL_BYTEL_REGS;
break;
case 'Q':
/* A register with an addressable second byte (e.g. %ah). */
ct->regs |= ALL_BYTEH_REGS;
break;
case 'r':
/* A general register. */
ct->regs |= ALL_GENERAL_REGS;
break;
case 'W':
/* With TZCNT/LZCNT, we can have operand-size as an input. */
ct->ct |= TCG_CT_CONST_WSZ;
break;
case 'x':
/* A vector register. */
ct->regs |= ALL_VECTOR_REGS;
break;
case 'L':
/* qemu_ld/st data+address constraint */
ct->regs |= ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS;
break;
case 's':
/* qemu_st8_i32 data constraint */
ct->regs |= ALL_BYTEL_REGS & ~SOFTMMU_RESERVE_REGS;
break;
case 'e':
ct->ct |= TCG_CT_CONST_S32;
break;
case 'Z':
ct->ct |= TCG_CT_CONST_U32;
break;
case 'I':
ct->ct |= TCG_CT_CONST_I32;
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)

View File

@ -235,5 +235,6 @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
#define TCG_TARGET_NEED_LDST_LABELS #define TCG_TARGET_NEED_LDST_LABELS
#endif #endif
#define TCG_TARGET_NEED_POOL_LABELS #define TCG_TARGET_NEED_POOL_LABELS
#define TCG_TARGET_CON_STR_H
#endif #endif

View File

@ -103,8 +103,10 @@ static void tcg_register_jit_int(const void *buf, size_t size,
__attribute__((unused)); __attribute__((unused));
/* Forward declarations for functions declared and used in tcg-target.c.inc. */ /* Forward declarations for functions declared and used in tcg-target.c.inc. */
#ifndef TCG_TARGET_CON_STR_H
static const char *target_parse_constraint(TCGArgConstraint *ct, static const char *target_parse_constraint(TCGArgConstraint *ct,
const char *ct_str, TCGType type); const char *ct_str, TCGType type);
#endif
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
intptr_t arg2); intptr_t arg2);
static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
@ -2415,7 +2417,6 @@ static void process_op_defs(TCGContext *s)
for (op = 0; op < NB_OPS; op++) { for (op = 0; op < NB_OPS; op++) {
TCGOpDef *def = &tcg_op_defs[op]; TCGOpDef *def = &tcg_op_defs[op];
const TCGTargetOpDef *tdefs; const TCGTargetOpDef *tdefs;
TCGType type;
int i, nb_args; int i, nb_args;
if (def->flags & TCG_OPF_NOT_PRESENT) { if (def->flags & TCG_OPF_NOT_PRESENT) {
@ -2431,7 +2432,6 @@ static void process_op_defs(TCGContext *s)
/* Missing TCGTargetOpDef entry. */ /* Missing TCGTargetOpDef entry. */
tcg_debug_assert(tdefs != NULL); tcg_debug_assert(tdefs != NULL);
type = (def->flags & TCG_OPF_64BIT ? TCG_TYPE_I64 : TCG_TYPE_I32);
for (i = 0; i < nb_args; i++) { for (i = 0; i < nb_args; i++) {
const char *ct_str = tdefs->args_ct_str[i]; const char *ct_str = tdefs->args_ct_str[i];
/* Incomplete TCGTargetOpDef entry. */ /* Incomplete TCGTargetOpDef entry. */
@ -2463,11 +2463,34 @@ static void process_op_defs(TCGContext *s)
def->args_ct[i].ct |= TCG_CT_CONST; def->args_ct[i].ct |= TCG_CT_CONST;
ct_str++; ct_str++;
break; break;
#ifdef TCG_TARGET_CON_STR_H
/* Include all of the target-specific constraints. */
#undef CONST
#define CONST(CASE, MASK) \
case CASE: def->args_ct[i].ct |= MASK; ct_str++; break;
#define REGS(CASE, MASK) \
case CASE: def->args_ct[i].regs |= MASK; ct_str++; break;
#include "tcg-target-con-str.h"
#undef REGS
#undef CONST
default: default:
ct_str = target_parse_constraint(&def->args_ct[i],
ct_str, type);
/* Typo in TCGTargetOpDef constraint. */ /* Typo in TCGTargetOpDef constraint. */
tcg_debug_assert(ct_str != NULL); g_assert_not_reached();
#else
default:
{
TCGType type = (def->flags & TCG_OPF_64BIT
? TCG_TYPE_I64 : TCG_TYPE_I32);
ct_str = target_parse_constraint(&def->args_ct[i],
ct_str, type);
/* Typo in TCGTargetOpDef constraint. */
tcg_debug_assert(ct_str != NULL);
}
#endif
} }
} }
} }