This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

movtf changes on rs6000 for target/11848


This patch fixes target/11848.  We had a movtf expander that had
support for moving certain constants into GPRs, but not anything
useful like other GPRs or values in memory...

There are still some problems involving moving constants into FPRs on
Darwin, because simplify_subreg can't simplify
(subreg:DImode (const_double:TFmode ...))
into a VOIDmode CONST_DOUBLE.

Tested by a bootstrap & testrun on powerpc-darwin, plus running
the c-torture compile testsuite with -mlong-double-128.

-- 
- Geoffrey Keating <geoffk@apple.com>

===File ~/patches/gcc-11848.patch===========================
2003-12-08  Geoffrey Keating  <geoffk@apple.com>

	PR target/11848
	* rs6000.h (CANNOT_CHANGE_MODE_CLASS): Allow change of mode
	in floating-point registers between TFmode and DImode.
	* rs6000.c (rs6000_emit_move): Split moves early.
	(secondary_reload_class): Random Whitespace Change.
	(rs6000_split_multireg_move): Support moves involving FP registers.
	Emit instructions directly.
	* rs6000-protos.h (rs6000_split_multireg_move): Update prototype.
	* altivec.md: Update for changes to rs6000_split_multireg_move.
	* rs6000.md: Update for changes to rs6000_split_multireg_move.
	(movtf_internal): Support moves to/from GPRs.

Index: gcc/testsuite/gcc.c-torture/compile/20031208-1.c
===================================================================
RCS file: gcc/testsuite/gcc.c-torture/compile/20031208-1.c
diff -N gcc/testsuite/gcc.c-torture/compile/20031208-1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.c-torture/compile/20031208-1.c	8 Dec 2003 23:09:59 -0000
@@ -0,0 +1,6 @@
+extern int foo(int, ...);
+int bar(void) {
+  long double l = 1.2345E6;
+  foo(0, l);
+  return 0;
+}
Index: gcc/config/rs6000/altivec.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/altivec.md,v
retrieving revision 1.11
diff -u -p -u -p -r1.11 altivec.md
--- gcc/config/rs6000/altivec.md	5 Dec 2003 03:48:39 -0000	1.11
+++ gcc/config/rs6000/altivec.md	8 Dec 2003 23:10:00 -0000
@@ -113,26 +113,10 @@
 (define_split
   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
         (match_operand:V4SI 1 "input_operand" ""))]
-  "TARGET_ALTIVEC && reload_completed && TARGET_POWERPC64 
+  "TARGET_ALTIVEC && reload_completed
    && gpr_or_gpr_p (operands[0], operands[1])"
-  [(set (match_dup 2) (match_dup 4))
-   (set (match_dup 3) (match_dup 5))]
-"{
-     rs6000_split_multireg_move (operands);
-}")
-
-(define_split
-  [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
-        (match_operand:V4SI 1 "input_operand" ""))]
-  "TARGET_ALTIVEC && reload_completed && !TARGET_POWERPC64 
-   && gpr_or_gpr_p (operands[0], operands[1])"
-  [(set (match_dup 2) (match_dup 6))
-   (set (match_dup 3) (match_dup 7))
-   (set (match_dup 4) (match_dup 8))
-   (set (match_dup 5) (match_dup 9))]
-"{
-     rs6000_split_multireg_move (operands);
-}")
+  [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
 
 (define_split
   [(set (match_operand:V4SI 0 "altivec_register_operand" "")
@@ -175,26 +159,10 @@
 (define_split
   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
         (match_operand:V8HI 1 "input_operand" ""))]
-  "TARGET_ALTIVEC && reload_completed && TARGET_POWERPC64 
+  "TARGET_ALTIVEC && reload_completed
    && gpr_or_gpr_p (operands[0], operands[1])"
-  [(set (match_dup 2) (match_dup 4))
-   (set (match_dup 3) (match_dup 5))]
-"{
-     rs6000_split_multireg_move (operands);
-}")
-
-(define_split
-  [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
-        (match_operand:V8HI 1 "input_operand" ""))]
-  "TARGET_ALTIVEC && reload_completed && !TARGET_POWERPC64 
-   && gpr_or_gpr_p (operands[0], operands[1])"
-  [(set (match_dup 2) (match_dup 6))
-   (set (match_dup 3) (match_dup 7))
-   (set (match_dup 4) (match_dup 8))
-   (set (match_dup 5) (match_dup 9))]
-"{
-     rs6000_split_multireg_move (operands);
-}")
+  [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
 
 (define_split
   [(set (match_operand:V8HI 0 "altivec_register_operand" "")
@@ -237,26 +205,10 @@
 (define_split
   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
         (match_operand:V16QI 1 "input_operand" ""))]
-  "TARGET_ALTIVEC && reload_completed && TARGET_POWERPC64 
-   && gpr_or_gpr_p (operands[0], operands[1])"
-  [(set (match_dup 2) (match_dup 4))
-   (set (match_dup 3) (match_dup 5))]
-"{
-     rs6000_split_multireg_move (operands);
-}")
-
-(define_split
-  [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
-        (match_operand:V16QI 1 "input_operand" ""))]
-  "TARGET_ALTIVEC && reload_completed && !TARGET_POWERPC64 
+  "TARGET_ALTIVEC && reload_completed
    && gpr_or_gpr_p (operands[0], operands[1])"
-  [(set (match_dup 2) (match_dup 6))
-   (set (match_dup 3) (match_dup 7))
-   (set (match_dup 4) (match_dup 8))
-   (set (match_dup 5) (match_dup 9))]
-"{
-     rs6000_split_multireg_move (operands);
-}")
+  [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
 
 (define_split
   [(set (match_operand:V16QI 0 "altivec_register_operand" "")
@@ -299,26 +251,10 @@
 (define_split
   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
         (match_operand:V4SF 1 "input_operand" ""))]
-  "TARGET_ALTIVEC && reload_completed && TARGET_POWERPC64 
-   && gpr_or_gpr_p (operands[0], operands[1])"
-  [(set (match_dup 2) (match_dup 4))
-   (set (match_dup 3) (match_dup 5))]
-"{
-     rs6000_split_multireg_move (operands);
-}")
-
-(define_split
-  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
-        (match_operand:V4SF 1 "input_operand" ""))]
-  "TARGET_ALTIVEC && reload_completed && !TARGET_POWERPC64 
+  "TARGET_ALTIVEC && reload_completed
    && gpr_or_gpr_p (operands[0], operands[1])"
-  [(set (match_dup 2) (match_dup 6))
-   (set (match_dup 3) (match_dup 7))
-   (set (match_dup 4) (match_dup 8))
-   (set (match_dup 5) (match_dup 9))]
-"{
-     rs6000_split_multireg_move (operands);
-}")
+  [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
 
 (define_insn "get_vrsave_internal"
   [(set (match_operand:SI 0 "register_operand" "=r")
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.67
diff -u -p -u -p -r1.67 rs6000-protos.h
--- gcc/config/rs6000/rs6000-protos.h	5 Dec 2003 00:44:56 -0000	1.67
+++ gcc/config/rs6000/rs6000-protos.h	8 Dec 2003 23:10:00 -0000
@@ -125,7 +125,7 @@ extern int mfcr_operation (rtx, enum mac
 extern int mtcrf_operation (rtx, enum machine_mode);
 extern int lmw_operation (rtx, enum machine_mode);
 extern struct rtx_def *create_TOC_reference (rtx);
-extern void rs6000_split_multireg_move (rtx *);
+extern void rs6000_split_multireg_move (rtx, rtx);
 extern void rs6000_emit_move (rtx, rtx, enum machine_mode);
 extern rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
 extern rtx rs6000_legitimize_reload_address (rtx, enum machine_mode,
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.554
diff -u -p -u -p -r1.554 rs6000.c
--- gcc/config/rs6000/rs6000.c	7 Dec 2003 01:52:52 -0000	1.554
+++ gcc/config/rs6000/rs6000.c	8 Dec 2003 23:10:04 -0000
@@ -3457,7 +3457,26 @@ rs6000_emit_move (rtx dest, rtx source, 
   /* Handle the case of CONSTANT_P_RTX.  */
   if (GET_CODE (operands[1]) == CONSTANT_P_RTX)
     goto emit_set;
-  
+
+  /* 128-bit constant floating-point values on Darwin should really be
+     loaded as two parts.  */
+  if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+      && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
+      && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
+    {
+      /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
+	 know how to get a DFmode SUBREG of a TFmode.  */
+      rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode, 0),
+			simplify_gen_subreg (DImode, operands[1], mode, 0),
+			DImode);
+      rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode,
+					     GET_MODE_SIZE (DImode)),
+			simplify_gen_subreg (DImode, operands[1], mode,
+					     GET_MODE_SIZE (DImode)),
+			DImode);
+      return;
+    }
+
   /* FIXME:  In the long term, this switch statement should go away
      and be replaced by a sequence of tests based on things like
      mode == Pmode.  */
@@ -8302,7 +8321,8 @@ addrs_ok_for_quad_peep (rtx addr1, rtx a
 
 enum reg_class
 secondary_reload_class (enum reg_class class, 
-		enum machine_mode mode ATTRIBUTE_UNUSED, rtx in)
+			enum machine_mode mode ATTRIBUTE_UNUSED,
+			rtx in)
 {
   int regno;
 
@@ -10007,73 +10027,72 @@ rs6000_emit_minmax (rtx dest, enum rtx_c
     emit_move_insn (dest, target);
 }
 
-/* Called by splitter for multireg moves.
-   Input: 
-          operands[0] : Destination of move
-          operands[1] : Source of move
-
-   Output:
-	  operands[2-n] : Destination slots
-	  operands[n-m] : Source slots
-   where n = 2 + HARD_REGNO_NREGS (reg, GET_MODE (operands[0]))
-         m = 2 + 2 * HARD_REGNO_NREGS (reg, GET_MODE (operands[0])) - 1
-
-   Splits the move of operands[1] to operands[0].
-   This is done, if GPRs are one of the operands.  In this case
-   a sequence of simple move insns has to be issued.  The sequence of these
-   move insns has to be done in correct order to avoid early clobber of the
-   base register or destructive overlap of registers. 
-*/
-	  
+/* Emit instructions to move SRC to DST.  Called by splitters for
+   multi-register moves.  It will emit at most one instruction for
+   each register that is accessed; that is, it won't emit li/lis pairs
+   (or equivalent for 64-bit code).  One of SRC or DST must be a hard
+   register.  */
+
 void
-rs6000_split_multireg_move (rtx *operands)
+rs6000_split_multireg_move (rtx dst, rtx src)
 {
-  int nregs, reg, i, j, used_update = 0;
-  enum machine_mode mode; 
-  rtx dst = operands[0];
-  rtx src = operands[1];
-  rtx insn = 0;
-
-  /* Calculate number to move (2/4 for 32/64 bit mode).  */ 
-
-  reg = REG_P (operands[0]) ? REGNO (operands[0]) : REGNO (operands[1]); 
-  mode = GET_MODE (operands[0]);
-  nregs = HARD_REGNO_NREGS (reg, mode);                                  
+  /* The register number of the first register being moved.  */
+  int reg;
+  /* The mode that is to be moved.  */
+  enum machine_mode mode;
+  /* The mode that the move is being done in, and its size.  */
+  enum machine_mode reg_mode;
+  int reg_mode_size;
+  /* The number of registers that will be moved.  */
+  int nregs;
+
+  reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
+  mode = GET_MODE (dst);
+  nregs = HARD_REGNO_NREGS (reg, mode);
+  if (FP_REGNO_P (reg))
+    reg_mode = DFmode;
+  else if (ALTIVEC_REGNO_P (reg))
+    reg_mode = V16QImode;
+  else
+    reg_mode = word_mode;
+  reg_mode_size = GET_MODE_SIZE (reg_mode);
   
-  if (REG_P (operands[1]) 
-      && REG_P (operands[0]) 
-      && (REGNO (operands[1]) < REGNO (operands[0])))
-    {  
-      /* Move register range backwards, if we have destructive overlap.  */
-
-      j = nregs;
-      for (i = 0; i < nregs; i++)
-        {
-          j--;
-          operands[i+2] = operand_subword (operands[0], j, 0, mode);
-          operands[i+2+nregs] = 
-            operand_subword (operands[1], j, 0, mode);   
-        }
-    }     
+  if (reg_mode_size * nregs != GET_MODE_SIZE (mode))
+    abort ();
+  
+  if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
+    {
+      /* Move register range backwards, if we might have destructive
+	 overlap.  */
+      int i;
+      for (i = nregs - 1; i >= 0; i--)
+	emit_insn (gen_rtx_SET (VOIDmode, 
+				simplify_gen_subreg (reg_mode, dst, mode,
+						     i * reg_mode_size),
+				simplify_gen_subreg (reg_mode, src, mode,
+						     i * reg_mode_size)));
+    }
   else
     {
-      j = -1;
+      int i;
+      int j = -1;
+      bool used_update = false;
 
-      if (GET_CODE (operands[1]) == MEM)
+      if (GET_CODE (src) == MEM && INT_REGNO_P (reg))
         {
           rtx breg;
 
-	  if (GET_CODE (XEXP (operands[1], 0)) == PRE_INC
-	      || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
+	  if (GET_CODE (XEXP (src, 0)) == PRE_INC
+	      || GET_CODE (XEXP (src, 0)) == PRE_DEC)
 	    {
 	      rtx delta_rtx;
-	      breg = XEXP (XEXP (operands[1], 0), 0);
-	      delta_rtx =  GET_CODE (XEXP (operands[1], 0)) == PRE_INC 
-		  ? GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))) 
-		  : GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[1]))); 
-	      insn = emit_insn (TARGET_32BIT
-				? gen_addsi3 (breg, breg, delta_rtx)
-				: gen_adddi3 (breg, breg, delta_rtx));
+	      breg = XEXP (XEXP (src, 0), 0);
+	      delta_rtx =  GET_CODE (XEXP (src, 0)) == PRE_INC 
+		  ? GEN_INT (GET_MODE_SIZE (GET_MODE (src))) 
+		  : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))); 
+	      emit_insn (TARGET_32BIT
+			 ? gen_addsi3 (breg, breg, delta_rtx)
+			 : gen_adddi3 (breg, breg, delta_rtx));
 	      src = gen_rtx_MEM (mode, breg);
 	    }
 
@@ -10093,35 +10112,34 @@ rs6000_split_multireg_move (rtx *operand
 	    j = REGNO (breg) - REGNO (dst);
         }
 
-      if (GET_CODE (operands[0]) == MEM)
+      if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
 	{
 	  rtx breg;
 
-	  if (GET_CODE (XEXP (operands[0], 0)) == PRE_INC
-	      || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
+	  if (GET_CODE (XEXP (dst, 0)) == PRE_INC
+	      || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
 	    {
 	      rtx delta_rtx;
-	      breg = XEXP (XEXP (operands[0], 0), 0);
-	      delta_rtx = GET_CODE (XEXP (operands[0], 0)) == PRE_INC 
-		? GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))) 
-		: GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0]))); 
+	      breg = XEXP (XEXP (dst, 0), 0);
+	      delta_rtx = GET_CODE (XEXP (dst, 0)) == PRE_INC 
+		? GEN_INT (GET_MODE_SIZE (GET_MODE (dst))) 
+		: GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))); 
 
 	      /* We have to update the breg before doing the store.
 		 Use store with update, if available.  */
 
 	      if (TARGET_UPDATE)
 		{
-		  insn = emit_insn (TARGET_32BIT
-				    ? gen_movsi_update (breg, breg, delta_rtx, 
-					operand_subword (src, 0, 0, mode))
-				    : gen_movdi_update (breg, breg, delta_rtx,
-					operand_subword (src, 0, 0, mode)));
-		  used_update = 1;
+		  rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
+		  emit_insn (TARGET_32BIT
+			     ? gen_movsi_update (breg, breg, delta_rtx, nsrc)
+			     : gen_movdi_update (breg, breg, delta_rtx, nsrc));
+		  used_update = true;
 		}
 	      else
-		  insn = emit_insn (TARGET_32BIT
-				    ? gen_addsi3 (breg, breg, delta_rtx)
-				    : gen_adddi3 (breg, breg, delta_rtx));
+		emit_insn (TARGET_32BIT
+			   ? gen_addsi3 (breg, breg, delta_rtx)
+			   : gen_adddi3 (breg, breg, delta_rtx));
 	      dst = gen_rtx_MEM (mode, breg);
 	    }
 	}
@@ -10133,15 +10151,16 @@ rs6000_split_multireg_move (rtx *operand
 	  if (j == nregs) 
 	    j = 0;
 
-	  operands[i+2] = operand_subword (dst, j, 0, mode);
-	  operands[i+2+nregs] = operand_subword (src, j, 0, mode);
-
+	  /* If compiler already emited move of first word by 
+	     store with update, no need to do anything.  */
 	  if (j == 0 && used_update)
-	    {
-	      /* Already emited move of first word by 
-		 store with update -> emit dead insn instead (r := r).  */
-	      operands[i+2] = operands[i+2+nregs];
-	    }
+	    continue;
+	  
+	  emit_insn (gen_rtx_SET (VOIDmode,
+				  simplify_gen_subreg (reg_mode, dst, mode,
+						       j * reg_mode_size),
+				  simplify_gen_subreg (reg_mode, src, mode,
+						       j * reg_mode_size)));
 	}
     }
 }
Index: gcc/config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.301
diff -u -p -u -p -r1.301 rs6000.h
--- gcc/config/rs6000/rs6000.h	28 Nov 2003 05:07:06 -0000	1.301
+++ gcc/config/rs6000/rs6000.h	8 Dec 2003 23:10:05 -0000
@@ -1480,11 +1480,14 @@ enum reg_class
 
 /* Return a class of registers that cannot change FROM mode to TO mode.  */
 
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)			\
-  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)				\
-   ? reg_classes_intersect_p (FLOAT_REGS, CLASS)			\
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)			  \
+  (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)		  \
+    && GET_MODE_SIZE (FROM) >= 8 && GET_MODE_SIZE (TO) >= 8)		  \
+   ? 0									  \
+   : GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)				  \
+   ? reg_classes_intersect_p (FLOAT_REGS, CLASS)			  \
    : (TARGET_SPE && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1) \
-   ? reg_classes_intersect_p (GENERAL_REGS, CLASS) 			\
+   ? reg_classes_intersect_p (GENERAL_REGS, CLASS)			  \
    : 0)
 
 /* Stack layout; function entry, exit and calling.  */
Index: gcc/config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.275
diff -u -p -u -p -r1.275 rs6000.md
--- gcc/config/rs6000/rs6000.md	5 Dec 2003 16:17:26 -0000	1.275
+++ gcc/config/rs6000/rs6000.md	8 Dec 2003 23:10:10 -0000
@@ -8206,110 +8206,21 @@
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }")
 
-(define_insn "*movtf_internal"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,m,!r,!r,!r")
-	(match_operand:TF 1 "input_operand" "f,m,f,G,H,F"))]
+; It's important to list the o->f and f->o moves before f->f because
+; otherwise reload, given m->f, will try to pick f->f and reload it,
+; which doesn't make progress.
+(define_insn_and_split "*movtf_internal"
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,rm,r")
+	(match_operand:TF 1 "input_operand"         "f,o,f,r,mGHF"))]
   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
    && (gpc_reg_operand (operands[0], TFmode)
        || gpc_reg_operand (operands[1], TFmode))"
-  "*
-{
-  switch (which_alternative)
-    {
-    default:
-      abort ();
-    case 0:
-      /* We normally copy the low-numbered register first.  However, if
-	 the first register operand 0 is the same as the second register of
-	 operand 1, we must copy in the opposite order.  */
-      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
-	return \"fmr %L0,%L1\;fmr %0,%1\";
-      else
-	return \"fmr %0,%1\;fmr %L0,%L1\";
-    case 1:
-      return \"lfd %0,%1\;lfd %L0,%Y1\";
-    case 2:
-      return \"stfd %1,%0\;stfd %L1,%Y0\";
-    case 3:
-    case 4:
-    case 5:
-      return \"#\";
-    }
-}"
-  [(set_attr "type" "fp,fpload,fpstore,*,*,*")
-   (set_attr "length" "8,8,8,12,16,20")])
-
-(define_split
-  [(set (match_operand:TF 0 "gpc_reg_operand" "")
-	(match_operand:TF 1 "easy_fp_constant" ""))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
-   && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_POWERPC64
-   && TARGET_LONG_DOUBLE_128 && reload_completed
-   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
-       || (GET_CODE (operands[0]) == SUBREG
-	   && GET_CODE (SUBREG_REG (operands[0])) == REG
-	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
-  [(set (match_dup 2) (match_dup 6))
-   (set (match_dup 3) (match_dup 7))
-   (set (match_dup 4) (match_dup 8))
-   (set (match_dup 5) (match_dup 9))]
-  "
-{
-  long l[4];
-  REAL_VALUE_TYPE rv;
-
-  REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-  REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
-
-  operands[2] = operand_subword (operands[0], 0, 0, TFmode);
-  operands[3] = operand_subword (operands[0], 1, 0, TFmode);
-  operands[4] = operand_subword (operands[0], 2, 0, TFmode);
-  operands[5] = operand_subword (operands[0], 3, 0, TFmode);
-  operands[6] = gen_int_mode (l[0], SImode);
-  operands[7] = gen_int_mode (l[1], SImode);
-  operands[8] = gen_int_mode (l[2], SImode);
-  operands[9] = gen_int_mode (l[3], SImode);
-}")
-
-(define_split
-  [(set (match_operand:TF 0 "gpc_reg_operand" "")
-	(match_operand:TF 1 "easy_fp_constant" ""))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
-   && TARGET_LONG_DOUBLE_128 && reload_completed
-   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
-       || (GET_CODE (operands[0]) == SUBREG
-	   && GET_CODE (SUBREG_REG (operands[0])) == REG
-	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
-  [(set (match_dup 2) (match_dup 4))
-   (set (match_dup 3) (match_dup 5))]
-  "
-{
-  long l[4];
-  REAL_VALUE_TYPE rv;
-#if HOST_BITS_PER_WIDE_INT >= 64
-  HOST_WIDE_INT val;
-#endif
-
-  REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-  REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
-
-  operands[2] = gen_lowpart (DImode, operands[0]);
-  operands[3] = gen_highpart (DImode, operands[0]);
-#if HOST_BITS_PER_WIDE_INT >= 64
-  val = ((HOST_WIDE_INT)(unsigned long)l[0] << 32
-         | ((HOST_WIDE_INT)(unsigned long)l[1]));
-  operands[4] = gen_int_mode (val, DImode);
-
-  val = ((HOST_WIDE_INT)(unsigned long)l[2] << 32
-         | ((HOST_WIDE_INT)(unsigned long)l[3]));
-  operands[5] = gen_int_mode (val, DImode);
-#else
-  operands[4] = immed_double_const (l[1], l[0], DImode);
-  operands[5] = immed_double_const (l[3], l[2], DImode);
-#endif
-}")
+  "#"
+  "reload_completed"
+  [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
+  [(set_attr "length" "8,8,8,20,20")])
 
 (define_insn "extenddftf2"
   [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
@@ -8527,31 +8438,12 @@
 }")
 
 (define_split
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-	(match_operand:DI 1 "const_double_operand" ""))]
-  "HOST_BITS_PER_WIDE_INT == 32 && ! TARGET_POWERPC64 && reload_completed"
-  [(set (match_dup 2) (match_dup 4))
-   (set (match_dup 3) (match_dup 5))]
-  "
-{
-  operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
-				       DImode);
-  operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
-				       DImode);
-  operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
-  operands[5] = GEN_INT (CONST_DOUBLE_LOW  (operands[1]));
-}")
-
-(define_split
   [(set (match_operand:DI 0 "nonimmediate_operand" "")
         (match_operand:DI 1 "input_operand" ""))]
   "reload_completed && !TARGET_POWERPC64 
    && gpr_or_gpr_p (operands[0], operands[1])"
-  [(set (match_dup 2) (match_dup 4))
-   (set (match_dup 3) (match_dup 5))]
-"{
-     rs6000_split_multireg_move (operands);
-}")
+  [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
 
 (define_split
   [(set (match_operand:TI 0 "gpc_reg_operand" "")
@@ -8780,28 +8672,10 @@
 (define_split
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
         (match_operand:TI 1 "input_operand" ""))]
-  "reload_completed && TARGET_POWERPC64 
-   && gpr_or_gpr_p (operands[0], operands[1])"
-  [(set (match_dup 2) (match_dup 4))
-   (set (match_dup 3) (match_dup 5))]
-"{
-     rs6000_split_multireg_move (operands);
-}")
-
-(define_split
-  [(set (match_operand:TI 0 "nonimmediate_operand" "")
-        (match_operand:TI 1 "input_operand" ""))]
-  "reload_completed && !TARGET_POWERPC64 
+  "reload_completed
    && gpr_or_gpr_p (operands[0], operands[1])"
-  [(set (match_dup 2) (match_dup 6))
-   (set (match_dup 3) (match_dup 7))
-   (set (match_dup 4) (match_dup 8))
-   (set (match_dup 5) (match_dup 9))]
-"{
-     rs6000_split_multireg_move (operands);
-}")
-
-
+  [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
 
 (define_expand "load_multiple"
   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
============================================================


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]