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:
parent
df903b94b3
commit
358b492392
33
tcg/i386/tcg-target-con-str.h
Normal file
33
tcg/i386/tcg-target-con-str.h
Normal 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)
|
@ -209,75 +209,6 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, 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 '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 */
|
||||
static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
|
||||
const TCGArgConstraint *arg_ct)
|
||||
|
@ -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
|
||||
#endif
|
||||
#define TCG_TARGET_NEED_POOL_LABELS
|
||||
#define TCG_TARGET_CON_STR_H
|
||||
|
||||
#endif
|
||||
|
33
tcg/tcg.c
33
tcg/tcg.c
@ -103,8 +103,10 @@ static void tcg_register_jit_int(const void *buf, size_t size,
|
||||
__attribute__((unused));
|
||||
|
||||
/* 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,
|
||||
const char *ct_str, TCGType type);
|
||||
#endif
|
||||
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
|
||||
intptr_t arg2);
|
||||
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++) {
|
||||
TCGOpDef *def = &tcg_op_defs[op];
|
||||
const TCGTargetOpDef *tdefs;
|
||||
TCGType type;
|
||||
int i, nb_args;
|
||||
|
||||
if (def->flags & TCG_OPF_NOT_PRESENT) {
|
||||
@ -2431,7 +2432,6 @@ static void process_op_defs(TCGContext *s)
|
||||
/* Missing TCGTargetOpDef entry. */
|
||||
tcg_debug_assert(tdefs != NULL);
|
||||
|
||||
type = (def->flags & TCG_OPF_64BIT ? TCG_TYPE_I64 : TCG_TYPE_I32);
|
||||
for (i = 0; i < nb_args; i++) {
|
||||
const char *ct_str = tdefs->args_ct_str[i];
|
||||
/* Incomplete TCGTargetOpDef entry. */
|
||||
@ -2463,11 +2463,34 @@ static void process_op_defs(TCGContext *s)
|
||||
def->args_ct[i].ct |= TCG_CT_CONST;
|
||||
ct_str++;
|
||||
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:
|
||||
ct_str = target_parse_constraint(&def->args_ct[i],
|
||||
ct_str, type);
|
||||
/* 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user