]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/69305 (wrong code with -O and int128 @ aarch64)
authorRichard Henderson <rth@redhat.com>
Thu, 28 Jan 2016 17:48:22 +0000 (09:48 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 28 Jan 2016 17:48:22 +0000 (09:48 -0800)
PR target/69305

  * config/aarch64/aarch64-modes.def (CC_Cmode): New
  * config/aarch64/aarch64-protos.h: Update.
  * config/aarch64/aarch64.c (aarch64_zero_extend_const_eq): New.
  (aarch64_select_cc_mode): Add check for use of CC_Cmode.
  (aarch64_get_condition_code_1): Handle CC_Cmode.
  * config/aarch64/aarch64.md (addti3): Use adddi3_compareC.
  (*add<mode>3_compareC_cconly_imm): New.
  (*add<mode>3_compareC_cconly): New.
  (*add<mode>3_compareC_imm): New.
  (add<mode>3_compareC): New.
  (add<mode>3_carryin, *addsi3_carryin_uxtw): Sort compare operand
  to be first.  Use aarch64_carry_operation.
  (*add<mode>3_carryin_alt1, *addsi3_carryin_alt1_uxtw): Remove.
  (*add<mode>3_carryin_alt2, *addsi3_carryin_alt2_uxtw): Remove.
  (*add<mode>3_carryin_alt3, *addsi3_carryin_alt3_uxtw): Remove.
  (subti3): Use subdi3_compare1.
  (*sub<mode>3_compare0): Rename from sub<mode>3_compare0.
  (sub<mode>3_compare1): New.
  (*sub<mode>3_carryin0, *subsi3_carryin_uxtw): New.
  (*sub<mode>3_carryin): Use aarch64_borrow_operation.
  (*subsi3_carryin_uxtw): Likewise.
  (*ngc<mode>, *ngcsi_uxtw): Likewise.
  (*sub<mode>3_carryin_alt, *subsi3_carryin_alt_uxtw): New.
  * config/aarch64/iterators.md (DWI): New.
  * config/aarch64/predicates.md (aarch64_carry_operation): New.
  (aarch64_borrow_operation): New.

From-SVN: r232936

gcc/ChangeLog
gcc/config/aarch64/aarch64-modes.def
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/iterators.md
gcc/config/aarch64/predicates.md
gcc/testsuite/gcc.target/aarch64/ccmp_1.c
gcc/testsuite/gcc.target/aarch64/tst_3.c

index 2a1fca74f7986e753f7466cac685d015a9662ac5..910817b3b1d7f039fb450f7afb0a125c431373b4 100644 (file)
@@ -1,3 +1,33 @@
+2016-01-28  Richard Henderson  <rth@redhat.com>
+
+       PR target/69305
+       * config/aarch64/aarch64-modes.def (CC_Cmode): New
+       * config/aarch64/aarch64-protos.h: Update.
+       * config/aarch64/aarch64.c (aarch64_zero_extend_const_eq): New.
+       (aarch64_select_cc_mode): Add check for use of CC_Cmode.
+       (aarch64_get_condition_code_1): Handle CC_Cmode.
+       * config/aarch64/aarch64.md (addti3): Use adddi3_compareC.
+       (*add<mode>3_compareC_cconly_imm): New.
+       (*add<mode>3_compareC_cconly): New.
+       (*add<mode>3_compareC_imm): New.
+       (add<mode>3_compareC): New.
+       (add<mode>3_carryin, *addsi3_carryin_uxtw): Sort compare operand
+       to be first.  Use aarch64_carry_operation.
+       (*add<mode>3_carryin_alt1, *addsi3_carryin_alt1_uxtw): Remove.
+       (*add<mode>3_carryin_alt2, *addsi3_carryin_alt2_uxtw): Remove.
+       (*add<mode>3_carryin_alt3, *addsi3_carryin_alt3_uxtw): Remove.
+       (subti3): Use subdi3_compare1.
+       (*sub<mode>3_compare0): Rename from sub<mode>3_compare0.
+       (sub<mode>3_compare1): New.
+       (*sub<mode>3_carryin0, *subsi3_carryin_uxtw): New.
+       (*sub<mode>3_carryin): Use aarch64_borrow_operation.
+       (*subsi3_carryin_uxtw): Likewise.
+       (*ngc<mode>, *ngcsi_uxtw): Likewise.
+       (*sub<mode>3_carryin_alt, *subsi3_carryin_alt_uxtw): New.
+       * config/aarch64/iterators.md (DWI): New.
+       * config/aarch64/predicates.md (aarch64_carry_operation): New.
+       (aarch64_borrow_operation): New.
+
 2016-01-28  Abderrazek Zaafrani  <a.zaafrani@samsung.com>
 
        * graphite-optimize-isl.c (optimize_isl): Print a different debug
index 3fab2053cebad9aaa915667813ab0bb0765a30cc..7de0b3f2fec1024946e40c66088b5b48675c4b7a 100644 (file)
@@ -25,6 +25,7 @@ CC_MODE (CC_ZESWP); /* zero-extend LHS (but swap to make it RHS).  */
 CC_MODE (CC_SESWP); /* sign-extend LHS (but swap to make it RHS).  */
 CC_MODE (CC_NZ);    /* Only N and Z bits of condition flags are valid.  */
 CC_MODE (CC_Z);     /* Only Z bit of condition flags is valid.  */
+CC_MODE (CC_C);     /* Only C bit of condition flags is valid.  */
 
 /* Half-precision floating point for __fp16.  */
 FLOAT_MODE (HF, 2, 0);
index bd900c6269f992d810c73e63d336964242b917ff..78870e275279b1409dfc98b8e46b89b97c76274e 100644 (file)
@@ -290,6 +290,7 @@ void aarch64_declare_function_name (FILE *, const char*, tree);
 bool aarch64_legitimate_pic_operand_p (rtx);
 bool aarch64_modes_tieable_p (machine_mode mode1,
                              machine_mode mode2);
+bool aarch64_zero_extend_const_eq (machine_mode, rtx, machine_mode, rtx);
 bool aarch64_move_imm (HOST_WIDE_INT, machine_mode);
 bool aarch64_mov_operand_p (rtx, machine_mode);
 int aarch64_simd_attr_length_rglist (enum machine_mode);
index bba7a9b6f42c2587cefbcb84dd6ace6a5de4b1a8..aee6685f0adbdde00160959861af1a3d6e8195b4 100644 (file)
@@ -1493,6 +1493,16 @@ aarch64_split_simd_move (rtx dst, rtx src)
     }
 }
 
+bool
+aarch64_zero_extend_const_eq (machine_mode xmode, rtx x,
+                             machine_mode ymode, rtx y)
+{
+  rtx r = simplify_const_unary_operation (ZERO_EXTEND, xmode, y, ymode);
+  gcc_assert (r != NULL);
+  return rtx_equal_p (x, r);
+}
+                             
+
 static rtx
 aarch64_force_temporary (machine_mode mode, rtx x, rtx value)
 {
@@ -4189,6 +4199,13 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
     return ((code == GT || code == GE || code == LE || code == LT)
            ? CC_SESWPmode : CC_ZESWPmode);
 
+  /* A test for unsigned overflow.  */
+  if ((GET_MODE (x) == DImode || GET_MODE (x) == TImode)
+      && code == NE
+      && GET_CODE (x) == PLUS
+      && GET_CODE (y) == ZERO_EXTEND)
+    return CC_Cmode;
+
   /* For everything else, return CCmode.  */
   return CCmode;
 }
@@ -4288,6 +4305,15 @@ aarch64_get_condition_code_1 (enum machine_mode mode, enum rtx_code comp_code)
        }
       break;
 
+    case CC_Cmode:
+      switch (comp_code)
+       {
+       case NE: return AARCH64_CS;
+       case EQ: return AARCH64_CC;
+       default: return -1;
+       }
+      break;
+
     default:
       return -1;
       break;
index 5d35261bfbea0f1d8fb310f1daa4fb2bcbb92804..b42f550d29593a1c92ec3c76767a05d4c70357db 100644 (file)
   ""
 {
   rtx low = gen_reg_rtx (DImode);
-  emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
+  emit_insn (gen_adddi3_compareC (low, gen_lowpart (DImode, operands[1]),
                                  gen_lowpart (DImode, operands[2])));
 
   rtx high = gen_reg_rtx (DImode);
   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
 )
 
+(define_insn "*add<mode>3_compareC_cconly_imm"
+  [(set (reg:CC_C CC_REGNUM)
+       (ne:CC_C
+         (plus:<DWI>
+           (zero_extend:<DWI> (match_operand:GPI 0 "register_operand" "r,r"))
+           (match_operand:<DWI> 2 "const_scalar_int_operand" ""))
+         (zero_extend:<DWI>
+           (plus:GPI
+             (match_dup 0)
+             (match_operand:GPI 1 "aarch64_plus_immediate" "I,J")))))]
+  "aarch64_zero_extend_const_eq (<DWI>mode, operands[2],
+                                <MODE>mode, operands[1])"
+  "@
+  cmn\\t%<w>0, %<w>1
+  cmp\\t%<w>0, #%n1"
+  [(set_attr "type" "alus_imm")]
+)
+
+(define_insn "*add<mode>3_compareC_cconly"
+  [(set (reg:CC_C CC_REGNUM)
+       (ne:CC_C
+         (plus:<DWI>
+           (zero_extend:<DWI> (match_operand:GPI 0 "register_operand" "r"))
+           (zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")))
+         (zero_extend:<DWI> (plus:GPI (match_dup 0) (match_dup 1)))))]
+  ""
+  "cmn\\t%<w>0, %<w>1"
+  [(set_attr "type" "alus_sreg")]
+)
+
+(define_insn "*add<mode>3_compareC_imm"
+  [(set (reg:CC_C CC_REGNUM)
+       (ne:CC_C
+         (plus:<DWI>
+           (zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r,r"))
+           (match_operand:<DWI> 3 "const_scalar_int_operand" ""))
+         (zero_extend:<DWI>
+           (plus:GPI
+             (match_dup 1)
+             (match_operand:GPI 2 "aarch64_plus_immediate" "I,J")))))
+   (set (match_operand:GPI 0 "register_operand" "=r,r")
+       (plus:GPI (match_dup 1) (match_dup 2)))]
+  "aarch64_zero_extend_const_eq (<DWI>mode, operands[3],
+                                 <MODE>mode, operands[2])"
+  "@
+  adds\\t%<w>0, %<w>1, %<w>2
+  subs\\t%<w>0, %<w>1, #%n2"
+  [(set_attr "type" "alus_imm")]
+)
+(define_insn "add<mode>3_compareC"
+  [(set (reg:CC_C CC_REGNUM)
+       (ne:CC_C
+         (plus:<DWI>
+           (zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r"))
+           (zero_extend:<DWI> (match_operand:GPI 2 "register_operand" "r")))
+         (zero_extend:<DWI>
+           (plus:GPI (match_dup 1) (match_dup 2)))))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+       (plus:GPI (match_dup 1) (match_dup 2)))]
+  ""
+  "adds\\t%<w>0, %<w>1, %<w>2"
+  [(set_attr "type" "alus_sreg")]
+)
+
 (define_insn "*adds_shift_imm_<mode>"
   [(set (reg:CC_NZ CC_REGNUM)
        (compare:CC_NZ
   [(set_attr "type" "alu_ext")]
 )
 
-(define_insn "add<mode>3_carryin"
-  [(set
-    (match_operand:GPI 0 "register_operand" "=r")
-    (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
-             (plus:GPI
-               (match_operand:GPI 1 "register_operand" "r")
-               (match_operand:GPI 2 "register_operand" "r"))))]
-   ""
-   "adc\\t%<w>0, %<w>1, %<w>2"
-  [(set_attr "type" "adc_reg")]
-)
-
-;; zero_extend version of above
-(define_insn "*addsi3_carryin_uxtw"
-  [(set
-    (match_operand:DI 0 "register_operand" "=r")
-    (zero_extend:DI
-     (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
-             (plus:SI
-              (match_operand:SI 1 "register_operand" "r")
-              (match_operand:SI 2 "register_operand" "r")))))]
-   ""
-   "adc\\t%w0, %w1, %w2"
-  [(set_attr "type" "adc_reg")]
-)
-
-(define_insn "*add<mode>3_carryin_alt1"
-  [(set
-    (match_operand:GPI 0 "register_operand" "=r")
-    (plus:GPI (plus:GPI
-               (match_operand:GPI 1 "register_operand" "r")
-               (match_operand:GPI 2 "register_operand" "r"))
-              (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
+(define_expand "add<mode>3_carryin"
+  [(set (match_operand:GPI 0 "register_operand")
+       (plus:GPI
+         (plus:GPI
+           (ne:GPI (reg:CC_C CC_REGNUM) (const_int 0))
+           (match_operand:GPI 1 "aarch64_reg_or_zero"))
+         (match_operand:GPI 2 "aarch64_reg_or_zero")))]
    ""
-   "adc\\t%<w>0, %<w>1, %<w>2"
-  [(set_attr "type" "adc_reg")]
-)
-
-;; zero_extend version of above
-(define_insn "*addsi3_carryin_alt1_uxtw"
-  [(set
-    (match_operand:DI 0 "register_operand" "=r")
-    (zero_extend:DI
-     (plus:SI (plus:SI
-              (match_operand:SI 1 "register_operand" "r")
-              (match_operand:SI 2 "register_operand" "r"))
-              (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
    ""
-   "adc\\t%w0, %w1, %w2"
-  [(set_attr "type" "adc_reg")]
 )
 
-(define_insn "*add<mode>3_carryin_alt2"
-  [(set
-    (match_operand:GPI 0 "register_operand" "=r")
-    (plus:GPI (plus:GPI
-                (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
-               (match_operand:GPI 1 "register_operand" "r"))
-             (match_operand:GPI 2 "register_operand" "r")))]
-   ""
-   "adc\\t%<w>0, %<w>1, %<w>2"
-  [(set_attr "type" "adc_reg")]
-)
+;; Note that add with carry with two zero inputs is matched by cset,
+;; and that add with carry with one zero input is matched by cinc.
 
-;; zero_extend version of above
-(define_insn "*addsi3_carryin_alt2_uxtw"
-  [(set
-    (match_operand:DI 0 "register_operand" "=r")
-    (zero_extend:DI
-     (plus:SI (plus:SI
-               (geu:SI (reg:CC CC_REGNUM) (const_int 0))
-              (match_operand:SI 1 "register_operand" "r"))
-             (match_operand:SI 2 "register_operand" "r"))))]
-   ""
-   "adc\\t%w0, %w1, %w2"
-  [(set_attr "type" "adc_reg")]
-)
-
-(define_insn "*add<mode>3_carryin_alt3"
-  [(set
-    (match_operand:GPI 0 "register_operand" "=r")
-    (plus:GPI (plus:GPI
-                (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
-               (match_operand:GPI 2 "register_operand" "r"))
-             (match_operand:GPI 1 "register_operand" "r")))]
+(define_insn "*add<mode>3_carryin"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+       (plus:GPI
+         (plus:GPI
+           (match_operand:GPI 3 "aarch64_carry_operation" "")
+           (match_operand:GPI 1 "register_operand" "r"))
+         (match_operand:GPI 2 "register_operand" "r")))]
    ""
    "adc\\t%<w>0, %<w>1, %<w>2"
   [(set_attr "type" "adc_reg")]
 )
 
 ;; zero_extend version of above
-(define_insn "*addsi3_carryin_alt3_uxtw"
-  [(set
-    (match_operand:DI 0 "register_operand" "=r")
-    (zero_extend:DI
-     (plus:SI (plus:SI
-               (geu:SI (reg:CC CC_REGNUM) (const_int 0))
-              (match_operand:SI 2 "register_operand" "r"))
-             (match_operand:SI 1 "register_operand" "r"))))]
+(define_insn "*addsi3_carryin_uxtw"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (zero_extend:DI
+         (plus:SI
+           (plus:SI
+             (match_operand:SI 3 "aarch64_carry_operation" "")
+             (match_operand:SI 1 "register_operand" "r"))
+           (match_operand:SI 2 "register_operand" "r"))))]
    ""
    "adc\\t%w0, %w1, %w2"
   [(set_attr "type" "adc_reg")]
   ""
 {
   rtx low = gen_reg_rtx (DImode);
-  emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
+  emit_insn (gen_subdi3_compare1 (low, gen_lowpart (DImode, operands[1]),
                                  gen_lowpart (DImode, operands[2])));
 
   rtx high = gen_reg_rtx (DImode);
   DONE;
 })
 
-(define_insn "sub<mode>3_compare0"
+(define_insn "*sub<mode>3_compare0"
   [(set (reg:CC_NZ CC_REGNUM)
        (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
                                  (match_operand:GPI 2 "register_operand" "r"))
   [(set_attr "type" "alus_sreg")]
 )
 
+(define_insn "sub<mode>3_compare1"
+  [(set (reg:CC CC_REGNUM)
+       (compare:CC
+         (match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
+         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))
+   (set (match_operand:GPI 0 "register_operand" "=r")
+       (minus:GPI (match_dup 1) (match_dup 2)))]
+  ""
+  "subs\\t%<w>0, %<w>1, %<w>2"
+  [(set_attr "type" "alus_sreg")]
+)
+
 (define_insn "*sub_<shift>_<mode>"
   [(set (match_operand:GPI 0 "register_operand" "=r")
        (minus:GPI (match_operand:GPI 3 "register_operand" "r")
   [(set_attr "type" "alu_ext")]
 )
 
-(define_insn "sub<mode>3_carryin"
-  [(set
-    (match_operand:GPI 0 "register_operand" "=r")
-    (minus:GPI (minus:GPI
-               (match_operand:GPI 1 "register_operand" "r")
-               (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
-              (match_operand:GPI 2 "register_operand" "r")))]
+;; The hardware description is op1 + ~op2 + C.
+;;                           = op1 + (-op2 + 1) + (1 - !C)
+;;                           = op1 - op2 - 1 + 1 - !C
+;;                           = op1 - op2 - !C.
+;; We describe the latter.
+
+(define_insn "*sub<mode>3_carryin0"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+       (minus:GPI
+         (match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
+         (match_operand:GPI 2 "aarch64_borrow_operation" "")))]
+   ""
+   "sbc\\t%<w>0, %<w>1, <w>zr"
+  [(set_attr "type" "adc_reg")]
+)
+
+;; zero_extend version of the above
+(define_insn "*subsi3_carryin_uxtw"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (zero_extend:DI
+         (minus:SI
+           (match_operand:SI 1 "aarch64_reg_or_zero" "rZ")
+           (match_operand:SI 2 "aarch64_borrow_operation" ""))))]
+   ""
+   "sbc\\t%w0, %w1, wzr"
+  [(set_attr "type" "adc_reg")]
+)
+
+(define_expand "sub<mode>3_carryin"
+  [(set (match_operand:GPI 0 "register_operand")
+       (minus:GPI
+         (minus:GPI
+           (match_operand:GPI 1 "aarch64_reg_or_zero")
+           (match_operand:GPI 2 "register_operand"))
+         (ltu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
+   ""
+   ""
+)
+
+(define_insn "*sub<mode>3_carryin"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+       (minus:GPI
+         (minus:GPI
+           (match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
+           (match_operand:GPI 2 "register_operand" "r"))
+         (match_operand:GPI 3 "aarch64_borrow_operation" "")))]
+
    ""
    "sbc\\t%<w>0, %<w>1, %<w>2"
   [(set_attr "type" "adc_reg")]
 
 ;; zero_extend version of the above
 (define_insn "*subsi3_carryin_uxtw"
-  [(set
-    (match_operand:DI 0 "register_operand" "=r")
-    (zero_extend:DI
-     (minus:SI (minus:SI
-               (match_operand:SI 1 "register_operand" "r")
-               (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
-              (match_operand:SI 2 "register_operand" "r"))))]
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (zero_extend:DI
+         (minus:SI
+           (minus:SI
+             (match_operand:SI 1 "aarch64_reg_or_zero" "rZ")
+             (match_operand:SI 2 "register_operand" "r"))
+           (match_operand:SI 3 "aarch64_borrow_operation" ""))))]
+
+   ""
+   "sbc\\t%w0, %w1, %w2"
+  [(set_attr "type" "adc_reg")]
+)
+
+(define_insn "*sub<mode>3_carryin_alt"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+       (minus:GPI
+         (minus:GPI
+           (match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
+           (match_operand:GPI 3 "aarch64_borrow_operation" ""))
+         (match_operand:GPI 2 "register_operand" "r")))]
+   ""
+   "sbc\\t%<w>0, %<w>1, %<w>2"
+  [(set_attr "type" "adc_reg")]
+)
+
+;; zero_extend version of the above
+(define_insn "*subsi3_carryin_alt_uxtw"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (zero_extend:DI
+         (minus:SI
+           (minus:SI
+             (match_operand:SI 1 "aarch64_reg_or_zero" "rZ")
+             (match_operand:SI 3 "aarch64_borrow_operation" ""))
+           (match_operand:SI 2 "register_operand" "r"))))]
    ""
    "sbc\\t%w0, %w1, %w2"
   [(set_attr "type" "adc_reg")]
 
 (define_insn "*ngc<mode>"
   [(set (match_operand:GPI 0 "register_operand" "=r")
-       (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
-                  (match_operand:GPI 1 "register_operand" "r")))]
+       (minus:GPI
+         (neg:GPI (match_operand:GPI 2 "aarch64_borrow_operation" ""))
+         (match_operand:GPI 1 "register_operand" "r")))]
   ""
   "ngc\\t%<w>0, %<w>1"
   [(set_attr "type" "adc_reg")]
 (define_insn "*ngcsi_uxtw"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
-        (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
-                  (match_operand:SI 1 "register_operand" "r"))))]
+         (minus:SI
+           (neg:SI (match_operand:SI 2 "aarch64_borrow_operation" ""))
+           (match_operand:SI 1 "register_operand" "r"))))]
   ""
   "ngc\\t%w0, %w1"
   [(set_attr "type" "adc_reg")]
index 49598a2cd9356d2ff9920544c16f48bbb30022fb..d9bd39112c3f4af19781290778babdf919f1c514 100644 (file)
 ;; For constraints used in scalar immediate vector moves
 (define_mode_attr hq [(HI "h") (QI "q")])
 
+;; For doubling width of an integer mode
+(define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
+
 ;; For scalar usage of vector/FP registers
 (define_mode_attr v [(QI "b") (HI "h") (SI "s") (DI "d")
                    (SF "s") (DF "d")
index e96dc000bea8470daa187dfd7c44e9c9993dbb0f..e80e40683cada374303ea987017f95654531a032 100644 (file)
   return aarch64_get_condition_code (op) >= 0;
 })
 
+(define_special_predicate "aarch64_carry_operation"
+  (match_code "ne,geu")
+{
+  if (XEXP (op, 1) != const0_rtx)
+    return false;
+  machine_mode ccmode = (GET_CODE (op) == NE ? CC_Cmode : CCmode);
+  rtx op0 = XEXP (op, 0);
+  return REG_P (op0) && REGNO (op0) == CC_REGNUM && GET_MODE (op0) == ccmode;
+})
+
+(define_special_predicate "aarch64_borrow_operation"
+  (match_code "eq,ltu")
+{
+  if (XEXP (op, 1) != const0_rtx)
+    return false;
+  machine_mode ccmode = (GET_CODE (op) == EQ ? CC_Cmode : CCmode);
+  rtx op0 = XEXP (op, 0);
+  return REG_P (op0) && REGNO (op0) == CC_REGNUM && GET_MODE (op0) == ccmode;
+})
 
 ;; True if the operand is memory reference suitable for a load/store exclusive.
 (define_predicate "aarch64_sync_memory_operand"
index fd38b2cfdb834c6395ddb939b54d23345c51b8d9..7c962cbb396f5ef9634cf3091dd12327ad2a7b03 100644 (file)
@@ -85,7 +85,7 @@ f13 (int a, int b)
 /* { dg-final { scan-assembler "cmp\t(.)+34" } } */
 /* { dg-final { scan-assembler "cmp\t(.)+35" } } */
 
-/* { dg-final { scan-assembler-times "\tcmp\tw\[0-9\]+, 0" 4 } } */
+/* { dg-final { scan-assembler-times "\tcmp\tw\[0-9\]+, (0|wzr)" 4 } } */
 /* { dg-final { scan-assembler-times "fcmpe\t(.)+0\\.0" 2 } } */
 /* { dg-final { scan-assembler-times "fcmp\t(.)+0\\.0" 2 } } */
 
index 2204b33f3bc2ea974b3b0a7d1a5bdca7c6b37b82..3fea63357ebd8b2287a36453e16ab101e7ece2c5 100644 (file)
@@ -9,4 +9,4 @@ f1 (int x)
   return x;
 }
 
-/* { dg-final { scan-assembler "tst\t(x|w)\[0-9\]*.*1" } } */
+/* { dg-final { scan-assembler "(tst|ands)\t(x|w)\[0-9\]*.*1" } } */