Rather than duplicating the rather verbose integral test,
pull it out to a predicate.

        * config/aarch64/predicates.md (const_dword_umaxp1): New.
        * config/aarch64/aarch64.c (aarch64_select_cc_mode): Use it.
        * config/aarch64/aarch64.md (add*add<GPI>3_carryinC): Likewise.
        (*add<GPI>3_carryinC_zero): Likewise.
        (add<mode>3_carryinC): Use <DWI>mode for constant, not TImode.
---
 gcc/config/aarch64/aarch64.c     |  5 +----
 gcc/config/aarch64/aarch64.md    | 16 +++++++---------
 gcc/config/aarch64/predicates.md |  9 +++++++++
 3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index ce306a10de6..f2c14818c79 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -9528,10 +9528,7 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
   if ((mode_x == DImode || mode_x == TImode)
       && (code == LTU || code == GEU)
       && code_x == PLUS
-      && CONST_SCALAR_INT_P (y)
-      && (rtx_mode_t (y, mode_x)
-         == (wi::shwi (1, mode_x)
-             << (GET_MODE_BITSIZE (mode_x).to_constant () / 2))))
+      && const_dword_umaxp1 (y, mode_x))
     return CC_ADCmode;
 
   /* A test for signed overflow.  */
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index d266a1edd64..6b21cc9c61b 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -2659,7 +2659,7 @@
   operands[5] = gen_rtx_LTU (<MODE>mode, ccin, const0_rtx);
   operands[6] = immed_wide_int_const (wi::shwi (1, <DWI>mode)
                                      << GET_MODE_BITSIZE (<MODE>mode),
-                                     TImode);
+                                     <DWI>mode);
 })
 
 (define_insn "*add<mode>3_carryinC_zero"
@@ -2668,13 +2668,12 @@
          (plus:<DWI>
            (match_operand:<DWI> 2 "aarch64_carry_operation" "")
            (zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")))
-         (match_operand 4 "const_scalar_int_operand" "")))
+         (match_operand:<DWI> 4 "const_dword_umaxp1" "")))
    (set (match_operand:GPI 0 "register_operand" "=r")
        (plus:GPI (match_operand:GPI 3 "aarch64_carry_operation" "")
                  (match_dup 1)))]
-  "rtx_mode_t (operands[4], <DWI>mode)
-   == (wi::shwi (1, <DWI>mode) << (unsigned) GET_MODE_BITSIZE (<MODE>mode))"
-   "adcs\\t%<w>0, %<w>1, <w>zr"
+  ""
+  "adcs\\t%<w>0, %<w>1, <w>zr"
   [(set_attr "type" "adc_reg")]
 )
 
@@ -2686,15 +2685,14 @@
              (match_operand:<DWI> 3 "aarch64_carry_operation" "")
              (zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")))
            (zero_extend:<DWI> (match_operand:GPI 2 "register_operand" "r")))
-         (match_operand 5 "const_scalar_int_operand" "")))
+         (match_operand:<DWI> 5 "const_dword_umaxp1" "")))
    (set (match_operand:GPI 0 "register_operand" "=r")
        (plus:GPI
          (plus:GPI (match_operand:GPI 4 "aarch64_carry_operation" "")
                    (match_dup 1))
          (match_dup 2)))]
-  "rtx_mode_t (operands[5], <DWI>mode)
-   == (wi::shwi (1, <DWI>mode) << (unsigned) GET_MODE_BITSIZE (<MODE>mode))"
-   "adcs\\t%<w>0, %<w>1, %<w>2"
+  ""
+  "adcs\\t%<w>0, %<w>1, %<w>2"
   [(set_attr "type" "adc_reg")]
 )
 
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 215fcec5955..99c3bfbace4 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -46,6 +46,15 @@
   return CONST_INT_P (op) && IN_RANGE (INTVAL (op), 1, 3);
 })
 
+;; True for 1 << (GET_MODE_BITSIZE (mode) / 2)
+;; I.e UINT_MAX + 1 for a given mode, in the double-word mode.
+(define_predicate "const_dword_umaxp1"
+  (match_code "const_int,const_wide_int")
+{
+  unsigned bits = GET_MODE_BITSIZE (mode).to_constant () / 2;
+  return rtx_mode_t (op, mode) == (wi::shwi (1, mode) << bits);
+})
+
 (define_predicate "subreg_lowpart_operator"
   (ior (match_code "truncate")
        (and (match_code "subreg")
-- 
2.20.1

Reply via email to