sparc.md (movtf reg/reg split): Don't generate SUBREGs by hand, gen the appropriate...
authorDavid S. Miller <davem@redhat.com>
Mon, 13 Dec 1999 01:20:07 +0000 (17:20 -0800)
committerDavid S. Miller <davem@gcc.gnu.org>
Mon, 13 Dec 1999 01:20:07 +0000 (17:20 -0800)
* config/sparc/sparc.md (movtf reg/reg split): Don't generate
SUBREGs by hand, gen the appropriate hard reg directly.
(movtf reg/mem split): Likewise and alter_subreg on destination
if necessary.
(movtf mem/reg split): Similarly.
(movdf_cc_sp64): Rename from hidden pattern.
(movtf_cc_hq_sp64): Renamed from movtf_cc_sp64.
(movtf_cc_sp64, following split): New pattern and splitter.
(movdf_cc_reg_sp64): Rename from hidden pattern.
(movtf_cc_reg_hq_sp64): Renamed from movtf_cc_reg_sp64, require
TARGET_HARD_QUAD.
(movtf_cc_reg_sp64, following split): New pattern and splitter.

Co-Authored-By: Jakub Jelinek <jakub@redhat.com>
From-SVN: r30880

gcc/ChangeLog
gcc/config/sparc/sparc.md

index 788025dd7f9a5abee5cfc7c3258941972c59948b..10ac35ab122145b1c7fcb2a758df4ec822a81440 100644 (file)
@@ -1,3 +1,19 @@
+1999-12-12  David S. Miller  <davem@redhat.com>
+           Jakub Jelinek    <jakub@redhat.com>
+
+       * config/sparc/sparc.md (movtf reg/reg split): Don't generate
+       SUBREGs by hand, gen the appropriate hard reg directly.
+       (movtf reg/mem split): Likewise and alter_subreg on destination
+       if necessary.
+       (movtf mem/reg split): Similarly.
+       (movdf_cc_sp64): Rename from hidden pattern.
+       (movtf_cc_hq_sp64): Renamed from movtf_cc_sp64.
+       (movtf_cc_sp64, following split): New pattern and splitter.
+       (movdf_cc_reg_sp64): Rename from hidden pattern.
+       (movtf_cc_reg_hq_sp64): Renamed from movtf_cc_reg_sp64, require
+       TARGET_HARD_QUAD.
+       (movtf_cc_reg_sp64, following split): New pattern and splitter.
+
 1999-12-12  Stephen L Moshier <moshier@mediaone.net>
 
        * loop.c (load_mems): Don't hoist written floating point mem
index b7025a860ce293fa6a6efc60c1187978c5622c9d..87243ebd6c1a9fc5eb0a7d3ad7de5cf92284a6a3 100644 (file)
   if (GET_CODE (set_src) == SUBREG)
     set_src = alter_subreg (set_src);
 
-  /* Ugly, but gen_highpart will crap out here for 32-bit targets.  */
-  dest1 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN == 0);
-  dest2 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN != 0);
-  src1 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN == 0);
-  src2 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN != 0);
+  dest1 = gen_rtx_REG (DFmode,
+                       REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 0 : 2));
+  dest2 = gen_rtx_REG (DFmode,
+                       REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 2 : 0));
+  src1 = gen_rtx_REG (DFmode,
+                      REGNO (set_src) + (WORDS_BIG_ENDIAN ? 0 : 2));
+  src2 = gen_rtx_REG (DFmode,
+                      REGNO (set_src) + (WORDS_BIG_ENDIAN ? 2 : 0));
 
   /* Now emit using the real source and destination we found, swapping
      the order if we detect overlap.  */
   rtx word0 = change_address (operands[1], DFmode, NULL_RTX);
   rtx word1 = change_address (operands[1], DFmode,
                              plus_constant_for_output (XEXP (word0, 0), 8));
-  rtx dest1, dest2;
+  rtx set_dest, dest1, dest2;
+
+  set_dest = operands[0];
+  if (GET_CODE (set_dest) == SUBREG)
+    set_dest = alter_subreg (set_dest);
 
-  /* Ugly, but gen_highpart will crap out here for 32-bit targets.  */
-  dest1 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN == 0);
-  dest2 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN != 0);
+  dest1 = gen_rtx_REG (DFmode,
+                       REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 0 : 2));
+  dest2 = gen_rtx_REG (DFmode,
+                       REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 2 : 0));
 
   /* Now output, ordering such that we don't clobber any registers
      mentioned in the address.  */
   [(clobber (const_int 0))]
   "
 {
-  rtx word0 = change_address (operands[0], DFmode, NULL_RTX);
-  rtx word1 = change_address (operands[0], DFmode,
-                             plus_constant_for_output (XEXP (word0, 0), 8));
-  rtx src1, src2;
+  rtx word1 = change_address (operands[0], DFmode, NULL_RTX);
+  rtx word2 = change_address (operands[0], DFmode,
+                             plus_constant_for_output (XEXP (word1, 0), 8));
+  rtx set_src, src1, src2;
 
-  /* Ugly, but gen_highpart will crap out here for 32-bit targets.  */
-  src1 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN == 0);
-  src2 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN != 0);
-  emit_insn (gen_movdf (word0, src1));
-  emit_insn (gen_movdf (word1, src2));
+  set_src = operands[1];
+  if (GET_CODE (set_src) == SUBREG)
+    set_src = alter_subreg (set_src);
+
+  src1 = gen_rtx_REG (DFmode,
+                      REGNO (set_src) + (WORDS_BIG_ENDIAN ? 0 : 2));
+  src2 = gen_rtx_REG (DFmode,
+                      REGNO (set_src) + (WORDS_BIG_ENDIAN ? 2 : 0));
+  emit_insn (gen_movdf (word1, src1));
+  emit_insn (gen_movdf (word2, src2));
   DONE;
 }")
 \f
   [(set_attr "type" "fpcmove")
    (set_attr "length" "1")])
 
-(define_insn "*movdf_cc_sp64"
+(define_insn "movdf_cc_sp64"
   [(set (match_operand:DF 0 "register_operand" "=e,e")
        (if_then_else:DF (match_operator 1 "comparison_operator"
                                [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
   [(set_attr "type" "fpcmove")
    (set_attr "length" "1")])
 
-(define_insn "*movtf_cc_sp64"
+(define_insn "*movtf_cc_hq_sp64"
   [(set (match_operand:TF 0 "register_operand" "=e,e")
        (if_then_else:TF (match_operator 1 "comparison_operator"
                                [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
   [(set_attr "type" "fpcmove")
    (set_attr "length" "1")])
 
+(define_insn "*movtf_cc_sp64"
+  [(set (match_operand:TF 0 "register_operand" "=e,e")
+       (if_then_else:TF (match_operator 1 "comparison_operator"
+                               [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
+                                (const_int 0)])
+                         (match_operand:TF 3 "register_operand" "e,0")
+                         (match_operand:TF 4 "register_operand" "0,e")))]
+  "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
+  "#"
+  [(set_attr "type" "fpcmove")
+   (set_attr "length" "2")])
+
+(define_split
+  [(set (match_operand:TF 0 "register_operand" "=e,e")
+       (if_then_else:TF (match_operator 1 "comparison_operator"
+                               [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
+                                (const_int 0)])
+                         (match_operand:TF 3 "register_operand" "e,0")
+                         (match_operand:TF 4 "register_operand" "0,e")))]
+  "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
+  [(clobber (const_int 0))]
+  "
+{
+  rtx set_dest = operands[0];
+  rtx set_srca = operands[3];
+  rtx set_srcb = operands[4];
+  int third = rtx_equal_p (set_dest, set_srca);
+  rtx dest1, dest2;
+  rtx srca1, srca2, srcb1, srcb2;
+
+  if (GET_CODE (set_dest) == SUBREG)
+    set_dest = alter_subreg (set_dest);
+  if (GET_CODE (set_srca) == SUBREG)
+    set_srca = alter_subreg (set_srca);
+  if (GET_CODE (set_srcb) == SUBREG)
+    set_srcb = alter_subreg (set_srcb);
+
+  dest1 = gen_rtx_REG (DFmode,
+                       REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 0 : 2));
+  dest2 = gen_rtx_REG (DFmode,
+                       REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 2 : 0));
+  srca1 = gen_rtx_REG (DFmode,
+                       REGNO (set_srca) + (WORDS_BIG_ENDIAN ? 0 : 2));
+  srca2 = gen_rtx_REG (DFmode,
+                       REGNO (set_srca) + (WORDS_BIG_ENDIAN ? 2 : 0));
+  srcb1 = gen_rtx_REG (DFmode,
+                       REGNO (set_srcb) + (WORDS_BIG_ENDIAN ? 0 : 2));
+  srcb2 = gen_rtx_REG (DFmode,
+                       REGNO (set_srcb) + (WORDS_BIG_ENDIAN ? 2 : 0));
+
+  /* Now emit using the real source and destination we found, swapping
+     the order if we detect overlap.  */
+  if ((third && reg_overlap_mentioned_p (dest1, srcb2))
+      || (!third && reg_overlap_mentioned_p (dest1, srca2)))
+    {
+      emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
+      emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
+    }
+  else
+    {
+      emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
+      emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
+    }
+  DONE;
+}")
+
 (define_insn "*movqi_cc_reg_sp64"
   [(set (match_operand:QI 0 "register_operand" "=r,r")
        (if_then_else:QI (match_operator 1 "v9_regcmp_op"
   [(set_attr "type" "fpcmove")
    (set_attr "length" "1")])
 
-(define_insn "*movdf_cc_reg_sp64"
+(define_insn "movdf_cc_reg_sp64"
   [(set (match_operand:DF 0 "register_operand" "=e,e")
        (if_then_else:DF (match_operator 1 "v9_regcmp_op"
                                [(match_operand:DI 2 "register_operand" "r,r")
   [(set_attr "type" "fpcmove")
    (set_attr "length" "1")])
 
-(define_insn "*movtf_cc_reg_sp64"
+(define_insn "*movtf_cc_reg_hq_sp64"
   [(set (match_operand:TF 0 "register_operand" "=e,e")
        (if_then_else:TF (match_operator 1 "v9_regcmp_op"
                                [(match_operand:DI 2 "register_operand" "r,r")
                                 (const_int 0)])
                          (match_operand:TF 3 "register_operand" "e,0")
                          (match_operand:TF 4 "register_operand" "0,e")))]
-  "TARGET_ARCH64 && TARGET_FPU"
+  "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
   "@
    fmovrq%D1\\t%2, %3, %0
    fmovrq%d1\\t%2, %4, %0"
   [(set_attr "type" "fpcmove")
    (set_attr "length" "1")])
+
+(define_insn "*movtf_cc_reg_sp64"
+  [(set (match_operand:TF 0 "register_operand" "=e,e")
+       (if_then_else:TF (match_operator 1 "v9_regcmp_op"
+                               [(match_operand:DI 2 "register_operand" "r,r")
+                                (const_int 0)])
+                         (match_operand:TF 3 "register_operand" "e,0")
+                         (match_operand:TF 4 "register_operand" "0,e")))]
+  "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
+  "#"
+  [(set_attr "type" "fpcmove")
+   (set_attr "length" "2")])
+
+(define_split
+  [(set (match_operand:TF 0 "register_operand" "=e,e")
+       (if_then_else:TF (match_operator 1 "v9_regcmp_op"
+                               [(match_operand:DI 2 "register_operand" "r,r")
+                                (const_int 0)])
+                         (match_operand:TF 3 "register_operand" "e,0")
+                         (match_operand:TF 4 "register_operand" "0,e")))]
+  "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
+  [(clobber (const_int 0))]
+  "
+{
+  rtx set_dest = operands[0];
+  rtx set_srca = operands[3];
+  rtx set_srcb = operands[4];
+  int third = rtx_equal_p (set_dest, set_srca);
+  rtx dest1, dest2;
+  rtx srca1, srca2, srcb1, srcb2;
+
+  if (GET_CODE (set_dest) == SUBREG)
+    set_dest = alter_subreg (set_dest);
+  if (GET_CODE (set_srca) == SUBREG)
+    set_srca = alter_subreg (set_srca);
+  if (GET_CODE (set_srcb) == SUBREG)
+    set_srcb = alter_subreg (set_srcb);
+
+  dest1 = gen_rtx_REG (DFmode,
+                       REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 0 : 2));
+  dest2 = gen_rtx_REG (DFmode,
+                       REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 2 : 0));
+  srca1 = gen_rtx_REG (DFmode,
+                       REGNO (set_srca) + (WORDS_BIG_ENDIAN ? 0 : 2));
+  srca2 = gen_rtx_REG (DFmode,
+                       REGNO (set_srca) + (WORDS_BIG_ENDIAN ? 2 : 0));
+  srcb1 = gen_rtx_REG (DFmode,
+                       REGNO (set_srcb) + (WORDS_BIG_ENDIAN ? 0 : 2));
+  srcb2 = gen_rtx_REG (DFmode,
+                       REGNO (set_srcb) + (WORDS_BIG_ENDIAN ? 2 : 0));
+
+  /* Now emit using the real source and destination we found, swapping
+     the order if we detect overlap.  */
+  if ((third && reg_overlap_mentioned_p (dest1, srcb2))
+      || (!third && reg_overlap_mentioned_p (dest1, srca2)))
+    {
+      emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
+      emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
+    }
+  else
+    {
+      emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
+      emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
+    }
+  DONE;
+}")
+
 \f
 ;;- zero extension instructions