aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/arm/mve.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/arm/mve.md')
-rw-r--r--gcc/config/arm/mve.md50
1 files changed, 50 insertions, 0 deletions
diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 9fe5129..4b4d629 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -6930,3 +6930,53 @@
}
}
)
+
+;; Originally expanded by 'predicated_doloop_end'.
+;; In the rare situation where the branch is too far, we do also need to
+;; revert FPSCR.LTPSIZE back to 0x100 after the last iteration.
+(define_insn "predicated_doloop_end_internal<letp_num_lanes>"
+ [(set (pc)
+ (if_then_else
+ (gtu (plus:SI (reg:SI LR_REGNUM)
+ (const_int <letp_num_lanes_neg>))
+ (const_int <letp_num_lanes_minus_1>))
+ (match_operand 0 "" "")
+ (pc)))
+ (set (reg:SI LR_REGNUM)
+ (plus:SI (reg:SI LR_REGNUM) (const_int <letp_num_lanes_neg>)))
+ ;; We use UNSPEC here to guarantee this pattern can not be
+ ;; generated by a RTL optimization and be matched by other
+ ;; patterns, since this pattern is also responsible for turning off
+ ;; the tail predication machinery if we were to exit the loop.
+ ;; This is done by either the LETP or the LCTP instructions that
+ ;; this pattern generates.
+ (use (unspec:SI [(const_int 0)] LETP))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_HAVE_MVE"
+ {
+ if (get_attr_length (insn) == 4)
+ return "letp\t%|lr, %l0";
+ else
+ return "subs\t%|lr, #<letp_num_lanes>\n\tbhi\t%l0\n\tlctp";
+ }
+ [(set (attr "length")
+ (if_then_else
+ (ltu (minus (pc) (match_dup 0)) (const_int 1024))
+ (const_int 4)
+ (const_int 12)))
+ (set_attr "type" "branch")
+ (set_attr "conds" "unconditional")])
+
+(define_insn "dlstp<dlstp_elemsize>_insn"
+ [
+ (set (reg:SI LR_REGNUM)
+;; Similar to the previous pattern, we use UNSPEC here to make sure this
+;; rtx construct is not matched by other patterns, as this pattern is also
+;; responsible for setting the element size of the tail predication machinery
+;; using the dlsp.<size> instruction.
+ (unspec_volatile:SI [(match_operand:SI 0 "s_register_operand" "r")]
+ DLSTP))
+ ]
+ "TARGET_HAVE_MVE"
+ "dlstp.<dlstp_elemsize>\t%|lr, %0"
+ [(set_attr "type" "mve_misc")])