aarch64.md: New movtf split.
authorSofiane Naci <sofiane.naci@arm.com>
Thu, 9 May 2013 08:25:30 +0000 (08:25 +0000)
committerSofiane Naci <sofiane@gcc.gnu.org>
Thu, 9 May 2013 08:25:30 +0000 (08:25 +0000)
* config/aarch64/aarch64.md: New movtf split.
(*movtf_aarch64): Update.
(aarch64_movdi_tilow): Handle TF modes and rename to
aarch64_movdi_<mode>low.
(aarch64_movdi_tihigh): Handle TF modes and rename to
aarch64_movdi_<mode>high
(aarch64_movtihigh_di): Handle TF modes and rename to
aarch64_mov<mode>high_di
(aarch64_movtilow_di): Handle TF modes and rename to
aarch64_mov<mode>low_di
(aarch64_movtilow_tilow): Remove spurious whitespace.
* config/aarch64/aarch64.c (aarch64_split_128bit_move): Handle TFmode
splits.
(aarch64_print_operand): Update.

From-SVN: r198735

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md

index 1bd866d8a649f5b5d09123fcdd9647043e4fbb9c..4c04ea4a6130d64ac6cfe9f572def8696ec0ae5d 100644 (file)
@@ -1,3 +1,20 @@
+2013-05-09  Sofiane Naci  <sofiane.naci@arm.com>
+
+       * config/aarch64/aarch64.md: New movtf split.
+       (*movtf_aarch64): Update.
+       (aarch64_movdi_tilow): Handle TF modes and rename to
+       aarch64_movdi_<mode>low.
+       (aarch64_movdi_tihigh): Handle TF modes and rename to
+       aarch64_movdi_<mode>high
+       (aarch64_movtihigh_di): Handle TF modes and rename to
+       aarch64_mov<mode>high_di
+       (aarch64_movtilow_di): Handle TF modes and rename to
+       aarch64_mov<mode>low_di
+       (aarch64_movtilow_tilow): Remove spurious whitespace.
+       * config/aarch64/aarch64.c (aarch64_split_128bit_move): Handle TFmode
+       splits.
+       (aarch64_print_operand): Update.
+
 2013-05-09  Alan Modra  <amodra@gmail.com>
 
        * configure.ac (HAVE_AS_TLS): Enable tests for powerpcle and
index d32563d3e738185f04ce9101d624591756adc23c..b57416c8de5d918565519a0041a5563fb7044e70 100644 (file)
@@ -604,49 +604,85 @@ aarch64_split_128bit_move (rtx dst, rtx src)
 {
   rtx low_dst;
 
-  gcc_assert (GET_MODE (dst) == TImode);
+  enum machine_mode src_mode = GET_MODE (src);
+  enum machine_mode dst_mode = GET_MODE (dst);
+  int src_regno = REGNO (src);
+  int dst_regno = REGNO (dst);
+
+  gcc_assert (dst_mode == TImode || dst_mode == TFmode);
 
   if (REG_P (dst) && REG_P (src))
     {
-      int src_regno = REGNO (src);
-      int dst_regno = REGNO (dst);
-
-      gcc_assert (GET_MODE (src) == TImode);
+      gcc_assert (src_mode == TImode || src_mode == TFmode);
 
       /* Handle r -> w, w -> r.  */
       if (FP_REGNUM_P (dst_regno) && GP_REGNUM_P (src_regno))
        {
-         emit_insn (gen_aarch64_movtilow_di (dst,
-                                             gen_lowpart (word_mode, src)));
-         emit_insn (gen_aarch64_movtihigh_di (dst,
-                                              gen_highpart (word_mode, src)));
-         return;
+         switch (src_mode) {
+         case TImode:
+           emit_insn
+             (gen_aarch64_movtilow_di (dst, gen_lowpart (word_mode, src)));
+           emit_insn
+             (gen_aarch64_movtihigh_di (dst, gen_highpart (word_mode, src)));
+           return;
+         case TFmode:
+           emit_insn
+             (gen_aarch64_movtflow_di (dst, gen_lowpart (word_mode, src)));
+           emit_insn
+             (gen_aarch64_movtfhigh_di (dst, gen_highpart (word_mode, src)));
+           return;
+         default:
+           gcc_unreachable ();
+         }
        }
       else if (GP_REGNUM_P (dst_regno) && FP_REGNUM_P (src_regno))
        {
-         emit_insn (gen_aarch64_movdi_tilow (gen_lowpart (word_mode, dst),
-                                             src));
-         emit_insn (gen_aarch64_movdi_tihigh (gen_highpart (word_mode, dst),
-                                              src));
-         return;
+         switch (src_mode) {
+         case TImode:
+           emit_insn
+             (gen_aarch64_movdi_tilow (gen_lowpart (word_mode, dst), src));
+           emit_insn
+             (gen_aarch64_movdi_tihigh (gen_highpart (word_mode, dst), src));
+           return;
+         case TFmode:
+           emit_insn
+             (gen_aarch64_movdi_tflow (gen_lowpart (word_mode, dst), src));
+           emit_insn
+             (gen_aarch64_movdi_tfhigh (gen_highpart (word_mode, dst), src));
+           return;
+         default:
+           gcc_unreachable ();
+         }
        }
       /* Fall through to r -> r cases.  */
     }
 
-  low_dst = gen_lowpart (word_mode, dst);
-  if (REG_P (low_dst)
-      && reg_overlap_mentioned_p (low_dst, src))
-    {
-      aarch64_emit_move (gen_highpart (word_mode, dst),
-                        gen_highpart_mode (word_mode, TImode, src));
-      aarch64_emit_move (low_dst, gen_lowpart (word_mode, src));
-    }
-  else
-    {
-      aarch64_emit_move (low_dst, gen_lowpart (word_mode, src));
-      aarch64_emit_move (gen_highpart (word_mode, dst),
-                        gen_highpart_mode (word_mode, TImode, src));
-    }
+  switch (dst_mode) {
+  case TImode:
+    low_dst = gen_lowpart (word_mode, dst);
+    if (REG_P (low_dst)
+       && reg_overlap_mentioned_p (low_dst, src))
+      {
+       aarch64_emit_move (gen_highpart (word_mode, dst),
+                          gen_highpart_mode (word_mode, TImode, src));
+       aarch64_emit_move (low_dst, gen_lowpart (word_mode, src));
+      }
+    else
+      {
+       aarch64_emit_move (low_dst, gen_lowpart (word_mode, src));
+       aarch64_emit_move (gen_highpart (word_mode, dst),
+                          gen_highpart_mode (word_mode, TImode, src));
+      }
+    return;
+  case TFmode:
+    emit_move_insn (gen_rtx_REG (DFmode, dst_regno),
+                   gen_rtx_REG (DFmode, src_regno));
+    emit_move_insn (gen_rtx_REG (DFmode, dst_regno + 1),
+                   gen_rtx_REG (DFmode, src_regno + 1));
+    return;
+  default:
+    gcc_unreachable ();
+  }
 }
 
 bool
@@ -3324,26 +3360,6 @@ aarch64_print_operand (FILE *f, rtx x, char code)
       asm_fprintf (f, "%s", reg_names [REGNO (x) + 1]);
       break;
 
-    case 'Q':
-      /* Print the least significant register of a pair (TImode) of regs.  */
-      if (GET_CODE (x) != REG || !GP_REGNUM_P (REGNO (x) + 1))
-       {
-         output_operand_lossage ("invalid operand for '%%%c'", code);
-         return;
-       }
-      asm_fprintf (f, "%s", reg_names [REGNO (x) + (WORDS_BIG_ENDIAN ? 1 : 0)]);
-      break;
-
-    case 'R':
-      /* Print the most significant register of a pair (TImode) of regs.  */
-      if (GET_CODE (x) != REG || !GP_REGNUM_P (REGNO (x) + 1))
-       {
-         output_operand_lossage ("invalid operand for '%%%c'", code);
-         return;
-       }
-      asm_fprintf (f, "%s", reg_names [REGNO (x) + (WORDS_BIG_ENDIAN ? 0 : 1)]);
-      break;
-
     case 'm':
       /* Print a condition (eq, ne, etc).  */
 
index 797cc9b02ccebd13f4fa41ceb058b7f52d2fc5c1..b27bcdaa97c8b4fb16e5b8f81e98e09e5508b9ba 100644 (file)
     || register_operand (operands[1], TFmode))"
   "@
    orr\\t%0.16b, %1.16b, %1.16b
-   mov\\t%0, %1\;mov\\t%H0, %H1
-   fmov\\t%d0, %Q1\;fmov\\t%0.d[1], %R1
-   fmov\\t%Q0, %d1\;fmov\\t%R0, %1.d[1]
+   #
+   #
+   #
    movi\\t%0.2d, #0
    fmov\\t%s0, wzr
    ldr\\t%q0, %1
    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
 )
 
+(define_split
+   [(set (match_operand:TF 0 "register_operand" "")
+        (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
+  "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
+  [(const_int 0)]
+  {
+    aarch64_split_128bit_move (operands[0], operands[1]);
+    DONE;
+  }
+)
+
 ;; Operands 1 and 3 are tied together by the final condition; so we allow
 ;; fairly lax checking on the second memory operation.
 (define_insn "load_pair<mode>"
 ;; after or during reload as we don't want these patterns to start
 ;; kicking in during the combiner.
  
-(define_insn "aarch64_movdi_tilow"
+(define_insn "aarch64_movdi_<mode>low"
   [(set (match_operand:DI 0 "register_operand" "=r")
-        (truncate:DI (match_operand:TI 1 "register_operand" "w")))]
+        (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
   "reload_completed || reload_in_progress"
   "fmov\\t%x0, %d1"
   [(set_attr "v8type" "fmovf2i")
    (set_attr "length" "4")
   ])
 
-(define_insn "aarch64_movdi_tihigh"
+(define_insn "aarch64_movdi_<mode>high"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (truncate:DI
-         (lshiftrt:TI (match_operand:TI 1 "register_operand" "w")
+         (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
                       (const_int 64))))]
   "reload_completed || reload_in_progress"
   "fmov\\t%x0, %1.d[1]"
    (set_attr "length" "4")
   ])
 
-(define_insn "aarch64_movtihigh_di"
-  [(set (zero_extract:TI (match_operand:TI 0 "register_operand" "+w")
+(define_insn "aarch64_mov<mode>high_di"
+  [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
                          (const_int 64) (const_int 64))
-        (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
+        (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
   "reload_completed || reload_in_progress"
   "fmov\\t%0.d[1], %x1"
-
   [(set_attr "v8type" "fmovi2f")
    (set_attr "mode"   "DI")
    (set_attr "length" "4")
   ])
 
-(define_insn "aarch64_movtilow_di"
-  [(set (match_operand:TI 0 "register_operand" "=w")
-        (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
+(define_insn "aarch64_mov<mode>low_di"
+  [(set (match_operand:TX 0 "register_operand" "=w")
+        (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
   "reload_completed || reload_in_progress"
   "fmov\\t%d0, %x1"
-
   [(set_attr "v8type" "fmovi2f")
    (set_attr "mode"   "DI")
    (set_attr "length" "4")
          (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
   "reload_completed || reload_in_progress"
   "fmov\\t%d0, %d1"
-
   [(set_attr "v8type" "fmovi2f")
    (set_attr "mode"   "DI")
    (set_attr "length" "4")