tcg/loongarch64: Define the operand constraints

Signed-off-by: WANG Xuerui <git@xen0n.name>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20211221054105.178795-7-git@xen0n.name>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
staging
WANG Xuerui 2021-12-21 13:40:40 +08:00 committed by Richard Henderson
parent 1bcfbf03df
commit ba0cdd8040
2 changed files with 80 additions and 0 deletions

View File

@ -0,0 +1,28 @@
/* SPDX-License-Identifier: MIT */
/*
* Define LoongArch target-specific operand constraints.
*
* Copyright (c) 2021 WANG Xuerui <git@xen0n.name>
*
* Based on tcg/riscv/tcg-target-con-str.h
*
* Copyright (c) 2021 Linaro
*/
/*
* Define constraint letters for register sets:
* REGS(letter, register_mask)
*/
REGS('r', ALL_GENERAL_REGS)
REGS('L', ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS)
/*
* Define constraint letters for constants:
* CONST(letter, TCG_CT_CONST_* bit set)
*/
CONST('I', TCG_CT_CONST_S12)
CONST('N', TCG_CT_CONST_N12)
CONST('U', TCG_CT_CONST_U12)
CONST('Z', TCG_CT_CONST_ZERO)
CONST('C', TCG_CT_CONST_C12)
CONST('W', TCG_CT_CONST_WSZ)

View File

@ -116,3 +116,55 @@ static const int tcg_target_call_oarg_regs[] = {
TCG_REG_A0,
TCG_REG_A1,
};
#define TCG_CT_CONST_ZERO 0x100
#define TCG_CT_CONST_S12 0x200
#define TCG_CT_CONST_N12 0x400
#define TCG_CT_CONST_U12 0x800
#define TCG_CT_CONST_C12 0x1000
#define TCG_CT_CONST_WSZ 0x2000
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
/*
* For softmmu, we need to avoid conflicts with the first 5
* argument registers to call the helper. Some of these are
* also used for the tlb lookup.
*/
#ifdef CONFIG_SOFTMMU
#define SOFTMMU_RESERVE_REGS MAKE_64BIT_MASK(TCG_REG_A0, 5)
#else
#define SOFTMMU_RESERVE_REGS 0
#endif
static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len)
{
return sextract64(val, pos, len);
}
/* test if a constant matches the constraint */
static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
{
if (ct & TCG_CT_CONST) {
return true;
}
if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
return true;
}
if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
return true;
}
if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) {
return true;
}
if ((ct & TCG_CT_CONST_U12) && val >= 0 && val <= 0xfff) {
return true;
}
if ((ct & TCG_CT_CONST_C12) && ~val >= 0 && ~val <= 0xfff) {
return true;
}
if ((ct & TCG_CT_CONST_WSZ) && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
return true;
}
return false;
}