Extract the hardcoded values for the minimum PC-relative displacements
into named constants and document them.

gcc/ChangeLog:

        * config/aarch64/aarch64.md (BRANCH_LEN_P_128MiB): New constant.
        (BRANCH_LEN_N_128MiB): Likewise.
        (BRANCH_LEN_P_1MiB): Likewise.
        (BRANCH_LEN_N_1MiB): Likewise.
        (BRANCH_LEN_P_32KiB): Likewise.
        (BRANCH_LEN_N_32KiB): Likewise.
---
 gcc/config/aarch64/aarch64.md | 64 ++++++++++++++++++++++++++---------
 1 file changed, 48 insertions(+), 16 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 1b1e982d466..bba3d1c505d 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -692,12 +692,28 @@ (define_insn "indirect_jump"
 (define_insn "jump"
   [(set (pc) (label_ref (match_operand 0 "" "")))]
   ""
   "b\\t%l0"
   [(set_attr "type" "branch")]
 )
 
+;; Maximum PC-relative positive/negative displacements for various branching
+;; instructions.
+(define_constants
+  [
+    ;; +/- 128MiB.  Used by B, BL.
+    (BRANCH_LEN_P_128MiB  134217724)
+    (BRANCH_LEN_N_128MiB -134217728)
+
+    ;; +/- 1MiB.  Used by B.<cond>, CBZ, CBNZ.
+    (BRANCH_LEN_P_1MiB  1048572)
+    (BRANCH_LEN_N_1MiB -1048576)
 
+    ;; +/- 32KiB.  Used by TBZ, TBNZ.
+    (BRANCH_LEN_P_32KiB  32764)
+    (BRANCH_LEN_N_32KiB -32768)
+  ]
+)
 
 ;; -------------------------------------------------------------------
 ;; Conditional jumps
 ;; -------------------------------------------------------------------
@@ -743,41 +759,45 @@ (define_expand "cbranchcc4"
 ;; Emit `B<cond>`, assuming that the condition is already in the CC register.
 (define_insn "aarch64_bcond"
   [(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)))
+       (if_then_else (and (ge (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_N_1MiB))
+                          (lt (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_P_1MiB)))
                      (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)))
+       (if_then_else (and (ge (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_N_1MiB))
+                          (lt (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_P_1MiB)))
                      (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
@@ -809,69 +829,77 @@ (define_insn_and_split "*aarch64_bcond_wide_imm<GPI:mode>"
 ;; For an EQ/NE comparison against zero, emit `CBZ`/`CBNZ`
 (define_insn "aarch64_cbz<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)))
+       (if_then_else (and (ge (minus (match_dup 1) (pc))
+                              (const_int BRANCH_LEN_N_1MiB))
+                          (lt (minus (match_dup 1) (pc))
+                              (const_int BRANCH_LEN_P_1MiB)))
                      (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)))
+       (if_then_else (and (ge (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_N_1MiB))
+                          (lt (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_P_1MiB)))
                      (const_int 0)
                      (const_int 1)))]
 )
 
 ;; For an LT/GE comparison against zero, emit `TBZ`/`TBNZ`
 (define_insn "*aarch64_tbz<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)))
+       (if_then_else (and (ge (minus (match_dup 1) (pc))
+                              (const_int BRANCH_LEN_N_32KiB))
+                          (lt (minus (match_dup 1) (pc))
+                              (const_int BRANCH_LEN_P_32KiB)))
                      (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)))
+       (if_then_else (and (ge (minus (match_dup 1) (pc))
+                              (const_int BRANCH_LEN_N_1MiB))
+                          (lt (minus (match_dup 1) (pc))
+                              (const_int BRANCH_LEN_P_1MiB)))
                      (const_int 0)
                      (const_int 1)))]
 )
 
 ;; -------------------------------------------------------------------
 ;; Test bit and branch
 ;; -------------------------------------------------------------------
@@ -897,39 +925,43 @@ (define_expand "tbranch_<code><mode>3"
 (define_insn "@aarch64_tbz<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)))
+       (if_then_else (and (ge (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_N_32KiB))
+                          (lt (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_P_32KiB)))
                      (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)))
+       (if_then_else (and (ge (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_N_1MiB))
+                          (lt (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_P_1MiB)))
                      (const_int 0)
                      (const_int 1)))]
 
 )
-- 
2.45.2

Reply via email to