The rules for conditional branches were spread throughout `aarch64.md`.
Group them together so it is easier to understand how `cbranch<mode>4`
is lowered to RTL.

gcc/ChangeLog:

        * config/aarch64/aarch64.md (condjump): move.
        (*compare_condjump<GPI:mode>): likewise.
        (aarch64_cb<optab><mode>1): likewise.
        (*cb<optab><mode>1): likewise.
        (tbranch_<code><mode>3): likewise.
        (@aarch64_tb<optab><ALLI:mode><GPI:mode>): likewise.
---
 gcc/config/aarch64/aarch64.md | 387 ++++++++++++++++++----------------
 1 file changed, 201 insertions(+), 186 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index c678f7afb1a..4d556d886bc 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -674,6 +674,10 @@ (define_insn "aarch64_write_sysregti"
  "msrr\t%x0, %x1, %H1"
 )
 
+;; -------------------------------------------------------------------
+;; Unconditional jumps
+;; -------------------------------------------------------------------
+
 (define_insn "indirect_jump"
   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
   ""
@@ -692,6 +696,12 @@ (define_insn "jump"
   [(set_attr "type" "branch")]
 )
 
+
+
+;; -------------------------------------------------------------------
+;; Conditional jumps
+;; -------------------------------------------------------------------
+
 (define_expand "cbranch<mode>4"
   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
                            [(match_operand:GPI 1 "register_operand")
@@ -731,6 +741,197 @@ (define_expand "cbranchcc4"
   ""
   "")
 
+(define_insn "condjump"
+  [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
+                           [(match_operand 1 "cc_register" "") (const_int 0)])
+                          (label_ref (match_operand 2 "" ""))
+                          (pc)))]
+  ""
+  {
+    /* GCC's traditional style has been to use "beq" instead of "b.eq", etc.,
+       but the "." is required for SVE conditions.  */
+    bool use_dot_p = GET_MODE (operands[1]) == CC_NZCmode;
+    if (get_attr_length (insn) == 8)
+      return aarch64_gen_far_branch (operands, 2, "Lbcond",
+                                    use_dot_p ? "b.%M0\\t" : "b%M0\\t");
+    else
+      return use_dot_p ? "b.%m0\\t%l2" : "b%m0\\t%l2";
+  }
+  [(set_attr "type" "branch")
+   (set (attr "length")
+       (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
+                          (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
+                     (const_int 4)
+                     (const_int 8)))
+   (set (attr "far_branch")
+       (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
+                          (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
+                     (const_int 0)
+                     (const_int 1)))]
+)
+
+;; For a 24-bit immediate CST we can optimize the compare for equality
+;; and branch sequence from:
+;;     mov     x0, #imm1
+;;     movk    x0, #imm2, lsl 16 /* x0 contains CST.  */
+;;     cmp     x1, x0
+;;     b<ne,eq> .Label
+;; into the shorter:
+;;     sub     x0, x1, #(CST & 0xfff000)
+;;     subs    x0, x0, #(CST & 0x000fff)
+;;     b<ne,eq> .Label
+(define_insn_and_split "*compare_condjump<GPI:mode>"
+  [(set (pc) (if_then_else (EQL
+                             (match_operand:GPI 0 "register_operand" "r")
+                             (match_operand:GPI 1 "aarch64_imm24" "n"))
+                          (label_ref:P (match_operand 2 "" ""))
+                          (pc)))]
+  "!aarch64_move_imm (INTVAL (operands[1]), <GPI:MODE>mode)
+   && !aarch64_plus_operand (operands[1], <GPI:MODE>mode)
+   && !reload_completed"
+  "#"
+  "&& true"
+  [(const_int 0)]
+  {
+    HOST_WIDE_INT lo_imm = UINTVAL (operands[1]) & 0xfff;
+    HOST_WIDE_INT hi_imm = UINTVAL (operands[1]) & 0xfff000;
+    rtx tmp = gen_reg_rtx (<GPI:MODE>mode);
+    emit_insn (gen_add<GPI:mode>3 (tmp, operands[0], GEN_INT (-hi_imm)));
+    emit_insn (gen_add<GPI:mode>3_compare0 (tmp, tmp, GEN_INT (-lo_imm)));
+    rtx cc_reg = gen_rtx_REG (CC_NZmode, CC_REGNUM);
+    rtx cmp_rtx = gen_rtx_fmt_ee (<EQL:CMP>, <GPI:MODE>mode,
+                                 cc_reg, const0_rtx);
+    emit_jump_insn (gen_condjump (cmp_rtx, cc_reg, operands[2]));
+    DONE;
+  }
+)
+
+(define_insn "aarch64_cb<optab><mode>1"
+  [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
+                               (const_int 0))
+                          (label_ref (match_operand 1 "" ""))
+                          (pc)))]
+  "!aarch64_track_speculation"
+  {
+    if (get_attr_length (insn) == 8)
+      return aarch64_gen_far_branch (operands, 1, "Lcb", "<inv_cb>\\t%<w>0, ");
+    else
+      return "<cbz>\\t%<w>0, %l1";
+  }
+  [(set_attr "type" "branch")
+   (set (attr "length")
+       (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576))
+                          (lt (minus (match_dup 1) (pc)) (const_int 1048572)))
+                     (const_int 4)
+                     (const_int 8)))
+   (set (attr "far_branch")
+       (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
+                          (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
+                     (const_int 0)
+                     (const_int 1)))]
+)
+
+(define_insn "*cb<optab><mode>1"
+  [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
+                                (const_int 0))
+                          (label_ref (match_operand 1 "" ""))
+                          (pc)))
+   (clobber (reg:CC CC_REGNUM))]
+  "!aarch64_track_speculation"
+  {
+    if (get_attr_length (insn) == 8)
+      {
+       if (get_attr_far_branch (insn) == 1)
+         return aarch64_gen_far_branch (operands, 1, "Ltb",
+                                        "<inv_tb>\\t%<w>0, <sizem1>, ");
+       else
+         {
+           char buf[64];
+           uint64_t val = ((uint64_t) 1)
+               << (GET_MODE_SIZE (<MODE>mode) * BITS_PER_UNIT - 1);
+           sprintf (buf, "tst\t%%<w>0, %" PRId64, val);
+           output_asm_insn (buf, operands);
+           return "<bcond>\t%l1";
+         }
+      }
+    else
+      return "<tbz>\t%<w>0, <sizem1>, %l1";
+  }
+  [(set_attr "type" "branch")
+   (set (attr "length")
+       (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
+                          (lt (minus (match_dup 1) (pc)) (const_int 32764)))
+                     (const_int 4)
+                     (const_int 8)))
+   (set (attr "far_branch")
+       (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576))
+                          (lt (minus (match_dup 1) (pc)) (const_int 1048572)))
+                     (const_int 0)
+                     (const_int 1)))]
+)
+
+;; -------------------------------------------------------------------
+;; Test bit and branch
+;; -------------------------------------------------------------------
+
+(define_expand "tbranch_<code><mode>3"
+  [(set (pc) (if_then_else
+             (EQL (match_operand:SHORT 0 "register_operand")
+                  (match_operand 1 "const0_operand"))
+             (label_ref (match_operand 2 ""))
+             (pc)))]
+  ""
+{
+  rtx bitvalue = gen_reg_rtx (<ZEROM>mode);
+  rtx reg = gen_lowpart (<ZEROM>mode, operands[0]);
+  rtx val = gen_int_mode (HOST_WIDE_INT_1U << UINTVAL (operands[1]),
+                         <MODE>mode);
+  emit_insn (gen_and<zerom>3 (bitvalue, reg, val));
+  operands[1] = const0_rtx;
+  operands[0] = aarch64_gen_compare_reg (<CODE>, bitvalue,
+                                        operands[1]);
+})
+
+(define_insn "@aarch64_tb<optab><ALLI:mode><GPI:mode>"
+  [(set (pc) (if_then_else
+             (EQL (zero_extract:GPI (match_operand:ALLI 0 "register_operand" 
"r")
+                                    (const_int 1)
+                                    (match_operand 1
+                                      "aarch64_simd_shift_imm_<ALLI:mode>" 
"n"))
+                  (const_int 0))
+            (label_ref (match_operand 2 "" ""))
+            (pc)))
+   (clobber (reg:CC CC_REGNUM))]
+  "!aarch64_track_speculation"
+  {
+    if (get_attr_length (insn) == 8)
+      {
+       if (get_attr_far_branch (insn) == 1)
+         return aarch64_gen_far_branch (operands, 2, "Ltb",
+                                        "<inv_tb>\\t%<ALLI:w>0, %1, ");
+       else
+         {
+           operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1]));
+           return "tst\t%<ALLI:w>0, %1\;<bcond>\t%l2";
+         }
+      }
+    else
+      return "<tbz>\t%<ALLI:w>0, %1, %l2";
+  }
+  [(set_attr "type" "branch")
+   (set (attr "length")
+       (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
+                          (lt (minus (match_dup 2) (pc)) (const_int 32764)))
+                     (const_int 4)
+                     (const_int 8)))
+   (set (attr "far_branch")
+       (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
+                          (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
+                     (const_int 0)
+                     (const_int 1)))]
+
+)
+
 (define_insn "@ccmp<CC_ONLY:mode><GPI:mode>"
   [(set (match_operand:CC_ONLY 1 "cc_register")
        (if_then_else:CC_ONLY
@@ -861,71 +1062,6 @@ (define_expand "mod<mode>3"
   }
 )
 
-(define_insn "condjump"
-  [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
-                           [(match_operand 1 "cc_register" "") (const_int 0)])
-                          (label_ref (match_operand 2 "" ""))
-                          (pc)))]
-  ""
-  {
-    /* GCC's traditional style has been to use "beq" instead of "b.eq", etc.,
-       but the "." is required for SVE conditions.  */
-    bool use_dot_p = GET_MODE (operands[1]) == CC_NZCmode;
-    if (get_attr_length (insn) == 8)
-      return aarch64_gen_far_branch (operands, 2, "Lbcond",
-                                    use_dot_p ? "b.%M0\\t" : "b%M0\\t");
-    else
-      return use_dot_p ? "b.%m0\\t%l2" : "b%m0\\t%l2";
-  }
-  [(set_attr "type" "branch")
-   (set (attr "length")
-       (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
-                          (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
-                     (const_int 4)
-                     (const_int 8)))
-   (set (attr "far_branch")
-       (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
-                          (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
-                     (const_int 0)
-                     (const_int 1)))]
-)
-
-;; For a 24-bit immediate CST we can optimize the compare for equality
-;; and branch sequence from:
-;;     mov     x0, #imm1
-;;     movk    x0, #imm2, lsl 16 /* x0 contains CST.  */
-;;     cmp     x1, x0
-;;     b<ne,eq> .Label
-;; into the shorter:
-;;     sub     x0, x1, #(CST & 0xfff000)
-;;     subs    x0, x0, #(CST & 0x000fff)
-;;     b<ne,eq> .Label
-(define_insn_and_split "*compare_condjump<GPI:mode>"
-  [(set (pc) (if_then_else (EQL
-                             (match_operand:GPI 0 "register_operand" "r")
-                             (match_operand:GPI 1 "aarch64_imm24" "n"))
-                          (label_ref:P (match_operand 2 "" ""))
-                          (pc)))]
-  "!aarch64_move_imm (INTVAL (operands[1]), <GPI:MODE>mode)
-   && !aarch64_plus_operand (operands[1], <GPI:MODE>mode)
-   && !reload_completed"
-  "#"
-  "&& true"
-  [(const_int 0)]
-  {
-    HOST_WIDE_INT lo_imm = UINTVAL (operands[1]) & 0xfff;
-    HOST_WIDE_INT hi_imm = UINTVAL (operands[1]) & 0xfff000;
-    rtx tmp = gen_reg_rtx (<GPI:MODE>mode);
-    emit_insn (gen_add<GPI:mode>3 (tmp, operands[0], GEN_INT (-hi_imm)));
-    emit_insn (gen_add<GPI:mode>3_compare0 (tmp, tmp, GEN_INT (-lo_imm)));
-    rtx cc_reg = gen_rtx_REG (CC_NZmode, CC_REGNUM);
-    rtx cmp_rtx = gen_rtx_fmt_ee (<EQL:CMP>, <GPI:MODE>mode,
-                                 cc_reg, const0_rtx);
-    emit_jump_insn (gen_condjump (cmp_rtx, cc_reg, operands[2]));
-    DONE;
-  }
-)
-
 (define_expand "casesi"
   [(match_operand:SI 0 "register_operand")     ; Index
    (match_operand:SI 1 "const_int_operand")    ; Lower bound
@@ -1117,127 +1253,6 @@ (define_insn "simple_return"
    (set_attr "sls_length" "retbr")]
 )
 
-(define_insn "aarch64_cb<optab><mode>1"
-  [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
-                               (const_int 0))
-                          (label_ref (match_operand 1 "" ""))
-                          (pc)))]
-  "!aarch64_track_speculation"
-  {
-    if (get_attr_length (insn) == 8)
-      return aarch64_gen_far_branch (operands, 1, "Lcb", "<inv_cb>\\t%<w>0, ");
-    else
-      return "<cbz>\\t%<w>0, %l1";
-  }
-  [(set_attr "type" "branch")
-   (set (attr "length")
-       (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576))
-                          (lt (minus (match_dup 1) (pc)) (const_int 1048572)))
-                     (const_int 4)
-                     (const_int 8)))
-   (set (attr "far_branch")
-       (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
-                          (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
-                     (const_int 0)
-                     (const_int 1)))]
-)
-
-(define_expand "tbranch_<code><mode>3"
-  [(set (pc) (if_then_else
-              (EQL (match_operand:SHORT 0 "register_operand")
-                   (match_operand 1 "const0_operand"))
-              (label_ref (match_operand 2 ""))
-              (pc)))]
-  ""
-{
-  rtx bitvalue = gen_reg_rtx (<ZEROM>mode);
-  rtx reg = gen_lowpart (<ZEROM>mode, operands[0]);
-  rtx val = gen_int_mode (HOST_WIDE_INT_1U << UINTVAL (operands[1]), 
<MODE>mode);
-  emit_insn (gen_and<zerom>3 (bitvalue, reg, val));
-  operands[1] = const0_rtx;
-  operands[0] = aarch64_gen_compare_reg (<CODE>, bitvalue,
-                                        operands[1]);
-})
-
-(define_insn "@aarch64_tb<optab><ALLI:mode><GPI:mode>"
-  [(set (pc) (if_then_else
-             (EQL (zero_extract:GPI (match_operand:ALLI 0 "register_operand" 
"r")
-                                    (const_int 1)
-                                    (match_operand 1
-                                      "aarch64_simd_shift_imm_<ALLI:mode>" 
"n"))
-                  (const_int 0))
-            (label_ref (match_operand 2 "" ""))
-            (pc)))
-   (clobber (reg:CC CC_REGNUM))]
-  "!aarch64_track_speculation"
-  {
-    if (get_attr_length (insn) == 8)
-      {
-       if (get_attr_far_branch (insn) == 1)
-         return aarch64_gen_far_branch (operands, 2, "Ltb",
-                                        "<inv_tb>\\t%<ALLI:w>0, %1, ");
-       else
-         {
-           operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1]));
-           return "tst\t%<ALLI:w>0, %1\;<bcond>\t%l2";
-         }
-      }
-    else
-      return "<tbz>\t%<ALLI:w>0, %1, %l2";
-  }
-  [(set_attr "type" "branch")
-   (set (attr "length")
-       (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
-                          (lt (minus (match_dup 2) (pc)) (const_int 32764)))
-                     (const_int 4)
-                     (const_int 8)))
-   (set (attr "far_branch")
-       (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
-                          (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
-                     (const_int 0)
-                     (const_int 1)))]
-
-)
-
-(define_insn "*cb<optab><mode>1"
-  [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
-                                (const_int 0))
-                          (label_ref (match_operand 1 "" ""))
-                          (pc)))
-   (clobber (reg:CC CC_REGNUM))]
-  "!aarch64_track_speculation"
-  {
-    if (get_attr_length (insn) == 8)
-      {
-       if (get_attr_far_branch (insn) == 1)
-         return aarch64_gen_far_branch (operands, 1, "Ltb",
-                                        "<inv_tb>\\t%<w>0, <sizem1>, ");
-       else
-         {
-           char buf[64];
-           uint64_t val = ((uint64_t) 1)
-               << (GET_MODE_SIZE (<MODE>mode) * BITS_PER_UNIT - 1);
-           sprintf (buf, "tst\t%%<w>0, %" PRId64, val);
-           output_asm_insn (buf, operands);
-           return "<bcond>\t%l1";
-         }
-      }
-    else
-      return "<tbz>\t%<w>0, <sizem1>, %l1";
-  }
-  [(set_attr "type" "branch")
-   (set (attr "length")
-       (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
-                          (lt (minus (match_dup 1) (pc)) (const_int 32764)))
-                     (const_int 4)
-                     (const_int 8)))
-   (set (attr "far_branch")
-       (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576))
-                          (lt (minus (match_dup 1) (pc)) (const_int 1048572)))
-                     (const_int 0)
-                     (const_int 1)))]
-)
-
 (define_expand "save_stack_nonlocal"
   [(set (match_operand 0 "memory_operand")
         (match_operand 1 "register_operand"))]
-- 
2.45.2

Reply via email to