On 01/07/2025 11:02, Richard Sandiford wrote:
Karl Meakin <karl.mea...@arm.com> writes:
@@ -763,6 +784,68 @@ (define_expand "cbranchcc4"
    ""
  )
+;; Emit a `CB<cond> (register)` or `CB<cond> (immediate)` instruction.
+;; The immediate range depends on the comparison code.
+;; Comparisons against immediates outside this range fall back to
+;; CMP + B<cond>.
+(define_insn "aarch64_cb<INT_CMP:code><GPI:mode>"
+  [(set (pc) (if_then_else (INT_CMP
+                            (match_operand:GPI 0 "register_operand" "r")
+                            (match_operand:GPI 1 "nonmemory_operand"
+                               "r<INT_CMP:cmpbr_imm_constraint>"))
+                          (label_ref (match_operand 2))
+                          (pc)))]
+  "TARGET_CMPBR && aarch64_cb_rhs (<INT_CMP:CODE>, operands[1])"
+  {
+    if (get_attr_far_branch (insn) == FAR_BRANCH_YES)
+      return aarch64_gen_far_branch (operands, 2, "L",
+                                     "cb<INT_CMP:inv_cmp_op>\\t%<w>0, %<w>1, 
");
+    else
+      return "cb<INT_CMP:cmp_op>\\t%<w>0, %<w>1, %l2";
+  }
+  [(set_attr "type" "branch")
+   (set (attr "length")
+       (if_then_else (and (ge (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_N_1Kib))
+                          (lt (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_P_1Kib)))
+                     (const_int 4)
+                     (const_int 8)))
+   (set (attr "far_branch")
+       (if_then_else (and (ge (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_N_1Kib))
+                          (lt (minus (match_dup 2) (pc))
+                              (const_int BRANCH_LEN_P_1Kib)))
+                     (const_string "no")
+                     (const_string "yes")))]
+)
+
+;; Emit a `CBB<cond> (register)` or `CBH<cond> (register)` instruction.
+(define_insn "aarch64_cb<INT_CMP:code><SHORT:mode>"
+  [(set (pc) (if_then_else (INT_CMP
+                            (match_operand:SHORT 0 "register_operand" "r")
+                            (match_operand:SHORT 1 "aarch64_reg_or_zero" "rZ"))
+                          (label_ref (match_operand 2))
+                          (pc)))]
+  "TARGET_CMPBR"
+  "cb<SHORT:cmpbr_suffix><INT_CMP:cmp_op>\\t%<w>0, %<w>1, %l2"
This instruction also needs to handle far branches, in a similar way
to the GPI one.  (It would be good to have a test for that too).

Why does the code for u32_x0_uge_64 etc. not change?  I would have
expected 64 to be in range for that, whether it's treated as >= 64
or as > 63.
Because the comparison is normalized to `x0 <= 63` which does not fit in the range for `CBLS` (-1 to 62)

Reply via email to