Message ID | 20250415192515.232910-123-richard.henderson@linaro.org |
---|---|
State | New |
Headers | show |
Series | tcg: Convert to TCGOutOp structures | expand |
On 4/15/25 12:24, Richard Henderson wrote: > 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. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > tcg/i386/tcg-target-con-set.h | 1 + > tcg/i386/tcg-target.c.inc | 46 ++++++++++++++++++++++++++++++++--- > 2 files changed, 44 insertions(+), 3 deletions(-) > > diff --git a/tcg/i386/tcg-target-con-set.h b/tcg/i386/tcg-target-con-set.h > index 85c93836bb..458d69c3c0 100644 > --- a/tcg/i386/tcg-target-con-set.h > +++ b/tcg/i386/tcg-target-con-set.h > @@ -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) > diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc > index 44f9afc0d6..da05f13b21 100644 > --- a/tcg/i386/tcg-target.c.inc > +++ b/tcg/i386/tcg-target.c.inc > @@ -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) Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
diff --git a/tcg/i386/tcg-target-con-set.h b/tcg/i386/tcg-target-con-set.h index 85c93836bb..458d69c3c0 100644 --- a/tcg/i386/tcg-target-con-set.h +++ b/tcg/i386/tcg-target-con-set.h @@ -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) diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index 44f9afc0d6..da05f13b21 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -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)
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. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- tcg/i386/tcg-target-con-set.h | 1 + tcg/i386/tcg-target.c.inc | 46 ++++++++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 3 deletions(-)