tcg/i386: Special case addci r, 0, 0

Using addci with two zeros as input in order to capture the value
of the carry-in bit is common.  Special case this with sbb+neg so
that we do not have to load 0 into a register first.

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2025-01-17 22:39:14 -08:00
parent e37e98b711
commit 0ad6d64b7b
2 changed files with 44 additions and 3 deletions

View file

@ -45,6 +45,7 @@ C_O1_I2(r, L, L)
C_O1_I2(r, r, r)
C_O1_I2(r, r, re)
C_O1_I2(r, r, ri)
C_O1_I2(r, rO, re)
C_O1_I2(x, x, x)
C_N1_I2(r, r, r)
C_N1_I2(r, r, rW)

View file

@ -2670,10 +2670,50 @@ static const TCGOutOpBinary outop_addcio = {
.out_rri = tgen_addcio_imm,
};
static void tgen_addci_rrr(TCGContext *s, TCGType type,
TCGReg a0, TCGReg a1, TCGReg a2)
{
/* Because "0O" is not a valid constraint, we must match ourselves. */
if (a0 == a2) {
tgen_addcio(s, type, a0, a0, a1);
} else {
tcg_out_mov(s, type, a0, a1);
tgen_addcio(s, type, a0, a0, a2);
}
}
static void tgen_addci_rri(TCGContext *s, TCGType type,
TCGReg a0, TCGReg a1, tcg_target_long a2)
{
tcg_out_mov(s, type, a0, a1);
tgen_addcio_imm(s, type, a0, a0, a2);
}
static void tgen_addci_rir(TCGContext *s, TCGType type,
TCGReg a0, tcg_target_long a1, TCGReg a2)
{
tgen_addci_rri(s, type, a0, a2, a1);
}
static void tgen_addci_rii(TCGContext *s, TCGType type, TCGReg a0,
tcg_target_long a1, tcg_target_long a2)
{
if (a2 == 0) {
/* Implement 0 + 0 + C with -(x - x - c). */
tgen_arithr(s, ARITH_SBB, a0, a0);
tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_NEG, a0);
} else {
tcg_out_movi(s, type, a0, a2);
tgen_addcio_imm(s, type, a0, a0, a1);
}
}
static const TCGOutOpAddSubCarry outop_addci = {
.base.static_constraint = C_O1_I2(r, 0, re),
.out_rrr = tgen_addcio,
.out_rri = tgen_addcio_imm,
.base.static_constraint = C_O1_I2(r, rO, re),
.out_rrr = tgen_addci_rrr,
.out_rri = tgen_addci_rri,
.out_rir = tgen_addci_rir,
.out_rii = tgen_addci_rii,
};
static void tcg_out_set_carry(TCGContext *s)