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;
|
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)
|
||||||
|
@ -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
|
||||||
|
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));
|
__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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user