arc: Update doloop_end patterns
authorClaudiu Zissulescu <claziss@synopsys.com>
Wed, 9 Jun 2021 09:12:57 +0000 (12:12 +0300)
committerClaudiu Zissulescu <claziss@synopsys.com>
Wed, 9 Jun 2021 09:17:01 +0000 (12:17 +0300)
ARC processor can use LP instruction to implement zero overlay loops.
The current inplementation doesn't handle the unlikely situation when
the loop iterator is located in memory.  Refurbish the loop_end insn
pattern into a define_insn_and_split pattern.

gcc/
2021-07-09  Claudiu Zissulescu  <claziss@synopsys.com>

* config/arc/arc.md (loop_end): Change it to
define_insn_and_split.

Signed-off-by: Claudiu Zissulescu <claziss@synopsys.com>
gcc/config/arc/arc.md

index aed0b40..90ba85e 100644 (file)
@@ -4962,7 +4962,7 @@ core_3, archs4x, archs4xd, archs4xd_slow"
 (define_expand "doloop_end"
   [(parallel [(set (pc)
                   (if_then_else
-                   (ne (match_operand 0 "" "")
+                   (ne (match_operand 0 "nonimmediate_operand")
                        (const_int 1))
                    (label_ref (match_operand 1 "" ""))
                    (pc)))
@@ -4988,44 +4988,38 @@ core_3, archs4x, archs4xd, archs4xd_slow"
 
 ;; if by any chance the lp_count is not used, then use an 'r'
 ;; register, instead of going to memory.
-(define_insn "loop_end"
-  [(set (pc)
-       (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,m")
-                         (const_int 1))
-                     (label_ref (match_operand 1 "" ""))
-                     (pc)))
-   (set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
-       (plus (match_dup 2) (const_int -1)))
-   (unspec [(const_int 0)] UNSPEC_ARC_LP)
-   (clobber (match_scratch:SI 3 "=X,&r"))]
-  ""
-  "; ZOL_END, begins @%l1"
-  [(set_attr "length" "0")
-   (set_attr "predicable" "no")
-   (set_attr "type" "loop_end")])
-
 ;; split pattern for the very slim chance when the loop register is
 ;; memory.
-(define_split
+(define_insn_and_split "loop_end"
   [(set (pc)
-       (if_then_else (ne (match_operand:SI 0 "memory_operand")
+       (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+r,!m")
                          (const_int 1))
-                     (label_ref (match_operand 1 ""))
+                     (label_ref (match_operand 1 "" ""))
                      (pc)))
    (set (match_dup 0) (plus (match_dup 0) (const_int -1)))
    (unspec [(const_int 0)] UNSPEC_ARC_LP)
-   (clobber (match_scratch:SI 2))]
-  "memory_operand (operands[0], SImode)"
+   (clobber (match_scratch:SI 2 "=X,&r"))]
+  ""
+  "@
+   ; ZOL_END, begins @%l1
+   #"
+  "reload_completed && memory_operand (operands[0], Pmode)"
   [(set (match_dup 2) (match_dup 0))
-   (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
+   (parallel
+    [(set (reg:CC_ZN CC_REG)
+         (compare:CC_ZN (plus:SI (match_dup 2) (const_int -1))
+                        (const_int 0)))
+     (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
    (set (match_dup 0) (match_dup 2))
-   (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0)))
    (set (pc)
-       (if_then_else (ne (reg:CC CC_REG)
+       (if_then_else (ne (reg:CC_ZN CC_REG)
                          (const_int 0))
                      (label_ref (match_dup 1))
                      (pc)))]
-  "")
+  ""
+  [(set_attr "length" "0,24")
+   (set_attr "predicable" "no")
+   (set_attr "type" "loop_end")])
 
 (define_insn "loop_fail"
   [(set (reg:SI LP_COUNT)