diff mbox series

[v4,122/163] tcg/i386: Special case addci r, 0, 0

Message ID 20250415192515.232910-123-richard.henderson@linaro.org
State New
Headers show
Series tcg: Convert to TCGOutOp structures | expand

Commit Message

Richard Henderson April 15, 2025, 7:24 p.m. UTC
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(-)

Comments

Pierrick Bouvier April 16, 2025, 6:59 p.m. UTC | #1
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 mbox series

Patch

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)