]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
arc: Update 64bit move split 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:12:57 +0000 (12:12 +0300)
ARCv2HS can use a limited number of instructions to implement 64bit
moves. The VADD2 is used as a 64bit move, the LDD/STD are 64 bit loads
and stores. All those instructions are not baseline, hence we need to
provide alternatives when they are not available or cannot be generate
due to instruction restriction.

This patch is cleaning up those move patterns, and updates splits
instruction lengths.

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

* config/arc/arc-protos.h (arc_split_move_p): New prototype.
* config/arc/arc.c (arc_split_move_p): New function.
(arc_split_move): Clean up.
* config/arc/arc.md (movdi_insn): Clean up, use arc_split_move_p.
(movdf_insn): Likewise.
* config/arc/simdext.md (mov<VWH>_insn): Likewise.

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

index 1f56a0d82e47cee308c1550359a3ba27120161b5..62d7e45d29df1b45c955db77a668cba500b6a1b0 100644 (file)
@@ -50,6 +50,7 @@ extern void arc_split_ior (rtx *);
 extern bool arc_check_mov_const (HOST_WIDE_INT );
 extern bool arc_split_mov_const (rtx *);
 extern bool arc_can_use_return_insn (void);
+extern bool arc_split_move_p (rtx *);
 #endif /* RTX_CODE */
 
 extern bool arc_ccfsm_branch_deleted_p (void);
index 0d34c96496386d1bc3c26223d011287fe8df1f2e..69f6ae464e1816a2bea94cceff9c4875b23dea0c 100644 (file)
@@ -10108,6 +10108,31 @@ arc_process_double_reg_moves (rtx *operands)
   return true;
 }
 
+
+/* Check if we need to split a 64bit move.  We do not need to split it if we can
+   use vadd2 or ldd/std instructions.  */
+
+bool
+arc_split_move_p (rtx *operands)
+{
+  machine_mode mode = GET_MODE (operands[0]);
+
+  if (TARGET_LL64
+      && ((memory_operand (operands[0], mode)
+          && (even_register_operand (operands[1], mode)
+              || satisfies_constraint_Cm3 (operands[1])))
+         || (memory_operand (operands[1], mode)
+             && even_register_operand (operands[0], mode))))
+    return false;
+
+  if (TARGET_PLUS_QMACW
+      && even_register_operand (operands[0], mode)
+      && even_register_operand (operands[1], mode))
+    return false;
+
+  return true;
+}
+
 /* operands 0..1 are the operands of a 64 bit move instruction.
    split it into two moves with operands 2/3 and 4/5.  */
 
@@ -10125,25 +10150,6 @@ arc_split_move (rtx *operands)
       return;
   }
 
-  if (TARGET_LL64
-      && ((memory_operand (operands[0], mode)
-          && (even_register_operand (operands[1], mode)
-              || satisfies_constraint_Cm3 (operands[1])))
-         || (memory_operand (operands[1], mode)
-             && even_register_operand (operands[0], mode))))
-    {
-      emit_move_insn (operands[0], operands[1]);
-      return;
-    }
-
-  if (TARGET_PLUS_QMACW
-      && even_register_operand (operands[0], mode)
-      && even_register_operand (operands[1], mode))
-    {
-      emit_move_insn (operands[0], operands[1]);
-      return;
-    }
-
   if (TARGET_PLUS_QMACW
       && GET_CODE (operands[1]) == CONST_VECTOR)
     {
index de61b2b790f7f72576cc0c455a72bd7f20623bcc..6f13b3a01d8e3d357929b7e628f2d110ba7cc0ca 100644 (file)
@@ -1330,47 +1330,20 @@ core_3, archs4x, archs4xd, archs4xd_slow"
   "register_operand (operands[0], DImode)
    || register_operand (operands[1], DImode)
    || (satisfies_constraint_Cm3 (operands[1])
-      && memory_operand (operands[0], DImode))"
-  "*
-{
-  switch (which_alternative)
-    {
-    default:
-      return \"#\";
-
-    case 0:
-    if (TARGET_PLUS_QMACW
-       && even_register_operand (operands[0], DImode)
-       && even_register_operand (operands[1], DImode))
-      return \"vadd2%?\\t%0,%1,0\";
-    return \"#\";
-
-    case 2:
-    if (TARGET_LL64
-        && memory_operand (operands[1], DImode)
-       && even_register_operand (operands[0], DImode))
-      return \"ldd%U1%V1 %0,%1%&\";
-    return \"#\";
-
-    case 3:
-    if (TARGET_LL64
-       && memory_operand (operands[0], DImode)
-       && (even_register_operand (operands[1], DImode)
-           || satisfies_constraint_Cm3 (operands[1])))
-     return \"std%U0%V0 %1,%0\";
-    return \"#\";
-    }
-}"
-  "&& reload_completed"
+       && memory_operand (operands[0], DImode))"
+  "@
+   vadd2\\t%0,%1,0
+   #
+   ldd%U1%V1\\t%0,%1
+   std%U0%V0\\t%1,%0"
+  "&& reload_completed && arc_split_move_p (operands)"
   [(const_int 0)]
   {
    arc_split_move (operands);
    DONE;
   }
   [(set_attr "type" "move,move,load,store")
-   ;; ??? The ld/st values could be 4 if it's [reg,bignum].
-   (set_attr "length" "8,16,*,*")])
-
+   (set_attr "length" "8,16,16,16")])
 
 ;; Floating point move insns.
 
@@ -1409,50 +1382,22 @@ core_3, archs4x, archs4xd, archs4xd_slow"
 (define_insn_and_split "*movdf_insn"
   [(set (match_operand:DF 0 "move_dest_operand"      "=D,r,r,r,r,m")
        (match_operand:DF 1 "move_double_src_operand" "r,D,r,E,m,r"))]
-  "register_operand (operands[0], DFmode)
-   || register_operand (operands[1], DFmode)"
-  "*
-{
- switch (which_alternative)
-   {
-    default:
-      return \"#\";
-
-    case 2:
-    if (TARGET_PLUS_QMACW
-       && even_register_operand (operands[0], DFmode)
-       && even_register_operand (operands[1], DFmode))
-      return \"vadd2%?\\t%0,%1,0\";
-    return \"#\";
-
-    case 4:
-    if (TARGET_LL64
-       && ((even_register_operand (operands[0], DFmode)
-            && memory_operand (operands[1], DFmode))
-           || (memory_operand (operands[0], DFmode)
-               && even_register_operand (operands[1], DFmode))))
-      return \"ldd%U1%V1 %0,%1%&\";
-    return \"#\";
-
-    case 5:
-    if (TARGET_LL64
-       && ((even_register_operand (operands[0], DFmode)
-            && memory_operand (operands[1], DFmode))
-           || (memory_operand (operands[0], DFmode)
-               && even_register_operand (operands[1], DFmode))))
-     return \"std%U0%V0 %1,%0\";
-    return \"#\";
-   }
-}"
-  "reload_completed"
+  "(register_operand (operands[0], DFmode)
+    || register_operand (operands[1], DFmode))"
+  "@
+   #
+   #
+   vadd2\\t%0,%1,0
+   #
+   ldd%U1%V1\\t%0,%1
+   std%U0%V0\\t%1,%0"
+  "&& reload_completed && arc_split_move_p (operands)"
   [(const_int 0)]
   {
    arc_split_move (operands);
    DONE;
   }
   [(set_attr "type" "move,move,move,move,load,store")
-   (set_attr "predicable" "no,no,no,yes,no,no")
-   ;; ??? The ld/st values could be 16 if it's [reg,bignum].
    (set_attr "length" "4,16,8,16,16,16")])
 
 (define_insn_and_split "*movdf_insn_nolrsr"
index dd63f93b3fd6039236896dc600b01ca375bc248c..303f52cf260d5f8a8ca39d99fae67c80b3558ac5 100644 (file)
        (match_operand:VWH 1 "general_operand"    "i,r,m,r"))]
   "(register_operand (operands[0], <MODE>mode)
        || register_operand (operands[1], <MODE>mode))"
-  "*
-{
-  switch (which_alternative)
-    {
-     default:
-       return \"#\";
-
-     case 1:
-       if (TARGET_PLUS_QMACW
-          && even_register_operand (operands[0], <MODE>mode)
-          && even_register_operand (operands[1], <MODE>mode))
-        return \"vadd2%?\\t%0,%1,0\";
-       return \"#\";
-
-     case 2:
-       if (TARGET_LL64)
-        return \"ldd%U1%V1\\t%0,%1\";
-       return \"#\";
-
-     case 3:
-       if (TARGET_LL64)
-          return \"std%U0%V0\\t%1,%0\";
-        return \"#\";
-    }
-}"
-  "reload_completed"
+  "@
+   #
+   vadd2\\t%0,%1,0
+   ldd%U1%V1\\t%0,%1
+   std%U0%V0\\t%1,%0"
+  "&& reload_completed && arc_split_move_p (operands)"
   [(const_int 0)]
   {
    arc_split_move (operands);
    DONE;
   }
-  [(set_attr "type" "move,multi,load,store")
-   (set_attr "predicable" "no,no,no,no")
-   (set_attr "iscompact"  "false,false,false,false")
-   ])
+  [(set_attr "type" "move,move,load,store")
+   (set_attr "length" "16,8,16,16")])
 
 (define_expand "movmisalign<mode>"
   [(set (match_operand:VWH 0 "general_operand" "")