From 2e6c96419d34a2921e746e14facbb403e2cf06ee Mon Sep 17 00:00:00 2001
From: Fariborz Jahanian <fjahanian@apple.com>
Date: Thu, 26 Aug 2004 17:20:20 +0000
Subject: [PATCH] Fixed several -mcpu=G5 and 'long double' issues for
 apple-ppc-darwin.

OK'ed by David Edehlson.

From-SVN: r86629
---
 gcc/ChangeLog               | 24 ++++++++++++++++++++++++
 gcc/config/rs6000/rs6000.c  | 34 +++++++++++++++++++++++++++++-----
 gcc/config/rs6000/rs6000.h  |  2 +-
 gcc/config/rs6000/rs6000.md | 16 ++++++++++------
 4 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e6ca31f22bb9..96bfe42a4f07 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,27 @@
+2004-08-26  Fariborz Jahanian  <fjahanian@apple.com>
+
+	* config/rs6000/rs6000.h (HARD_REGNO_CALL_PART_CLOBBERED): Added 
+	TFmode as additional register mode cloberred by call.
+
+2004-08-26  Fariborz Jahanian  <fjahanian@apple.com>
+
+	* config/rs6000/rs6000.c (rs6000_libcall_value): Generate
+	parallel pattern for library call returning DImode in
+	mixed mode.
+
+2004-08-26  Fariborz Jahanian  <fjahanian@apple.com>
+
+	* config/rs6000/rs6000.c (function_arg): Generate parallel
+	pattern for more split args.
+
+2004-08-26  Fariborz Jahanian  <fjahanian@apple.com>
+
+	* config/rs6000/rs6000.c (rs6000_split_multireg_move): Call
+	either gen_movdi_di_update or gen_movdi_si_update depending on
+	target mode.
+	* config/rs6000/rs6000.md (movdi_update): Changed to movdi_<mode>_update,
+	to generate two versions.
+ 
 2004-08-26  Daniel Berlin  <dberlin@dberlin.org>
 
 	* Makefile.in (lambda-code.o): New.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 745b4759d3b9..49fe3bac77fe 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -5120,11 +5120,19 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
 			 include the portion actually in registers here.  */
 		      enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
 		      rtx off;
+		      int i=0;
+                      if (align_words + n_words > GP_ARG_NUM_REG 
+                          && (TARGET_32BIT && TARGET_POWERPC64))
+                      /* Not all of the arg fits in gprs.  Say that it goes in memory too,
+                         using a magic NULL_RTX component. Also see comment in 
+			 rs6000_mixed_function_arg for why the normal 
+			 function_arg_partial_nregs scheme doesn't work in this case. */
+                        rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
 		      do
 			{
 			  r = gen_rtx_REG (rmode,
 					   GP_ARG_MIN_REG + align_words);
-			  off = GEN_INT (k * GET_MODE_SIZE (rmode));
+			  off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
 			  rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
 			}
 		      while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
@@ -11383,9 +11391,11 @@ rs6000_split_multireg_move (rtx dst, rtx src)
 	      if (TARGET_UPDATE)
 		{
 		  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));
+                  emit_insn (TARGET_32BIT
+                             ? (TARGET_POWERPC64
+                                ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
+                                : gen_movsi_update (breg, breg, delta_rtx, nsrc))
+                             : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
 		  used_update = true;
 		}
 	      else
@@ -12583,7 +12593,7 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
       insn = emit_insn (TARGET_32BIT
 			? gen_movsi_update (stack_reg, stack_reg,
 					    todec, stack_reg)
-			: gen_movdi_update (stack_reg, stack_reg,
+			: gen_movdi_di_update (stack_reg, stack_reg, 
 					    todec, stack_reg));
     }
   else
@@ -17520,6 +17530,20 @@ rs6000_libcall_value (enum machine_mode mode)
 {
   unsigned int regno;
 
+  if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
+    {
+      /* Long long return value need be split in -mpowerpc64, 32bit ABI.  */
+      return gen_rtx_PARALLEL (DImode,
+	gen_rtvec (2,
+		   gen_rtx_EXPR_LIST (VOIDmode,
+				      gen_rtx_REG (SImode, GP_ARG_RETURN),
+				      const0_rtx),
+		   gen_rtx_EXPR_LIST (VOIDmode,
+				      gen_rtx_REG (SImode,
+						   GP_ARG_RETURN + 1),
+				      GEN_INT (4))));
+    }
+
   if (GET_MODE_CLASS (mode) == MODE_FLOAT
 	   && TARGET_HARD_FLOAT && TARGET_FPRS)
     regno = FP_ARG_RETURN;
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index f1bf91b5eb01..801d54fd93f7 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1016,7 +1016,7 @@ extern const char *rs6000_warn_altivec_long_switch;
 
 #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)	\
   ((TARGET_32BIT && TARGET_POWERPC64			\
-    && (MODE == DImode || MODE == DFmode)		\
+    && (GET_MODE_SIZE (MODE) > 4)  \
     && INT_REGNO_P (REGNO)) ? 1 : 0)
 
 #define ALTIVEC_VECTOR_MODE(MODE)	\
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 149adf7e0e7a..819e8a3d8e64 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -104,6 +104,10 @@
 (include "darwin.md")
 
 
+;; This mode macro allows :P to be used for patterns that operate on
+;; pointer-sized quantities.  Exactly one of the two alternatives will match.
+(define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
+
 ;; Start with fixed-point load and store insns.  Here we put only the more
 ;; complex forms.  Basic data transfer is done later.
 
@@ -9483,12 +9487,12 @@
    ldu %3,%2(%0)"
   [(set_attr "type" "load_ux,load_u")])
 
-(define_insn "movdi_update"
-  [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
-			 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
+(define_insn "movdi_<mode>_update"
+  [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
+			 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
 	(match_operand:DI 3 "gpc_reg_operand" "r,r"))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
-	(plus:DI (match_dup 1) (match_dup 2)))]
+   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
+	(plus:P (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64 && TARGET_UPDATE"
   "@
    stdux %3,%0,%2
@@ -9956,7 +9960,7 @@
     neg_op0 = GEN_INT (- INTVAL (operands[1]));
 
   if (TARGET_UPDATE)
-    emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update : gen_movdi_update))
+    emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update : gen_movdi_di_update))
 		(stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
 
   else
-- 
GitLab