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]

PowerPC 32/64 mode incremental step


	This patch deals with most of the target-specific argument passing
changes to support the 64-bit computation / 32-bit ABI mode.

David


2003-10-31  Fariborz Jahanian  <fjahanian@apple.com>
            David Edelsohn  <edelsohn@gnu.org>

	* config/rs6000/rs6000.c (rs6000_mixed_function_arg): New.
	(function_arg): Call it.
	(rs6000_function_value): Widen integral return value to mode based
	on TARGET_32BIT, not word_mode.
	* config/rs6000/rs6000.h (PROMOTE_MODE): Likewise.

Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.537
diff -c -p -r1.537 rs6000.c
*** rs6000.c	30 Oct 2003 02:02:45 -0000	1.537
--- rs6000.c	30 Oct 2003 20:59:36 -0000
*************** static int rs6000_get_some_local_dynamic
*** 347,352 ****
--- 347,354 ----
  static rtx rs6000_complex_function_value (enum machine_mode);
  static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
  				    enum machine_mode, tree);
+ static rtx rs6000_mixed_function_arg (CUMULATIVE_ARGS *,
+ 				      enum machine_mode, tree, int);
  static void setup_incoming_varargs (CUMULATIVE_ARGS *,
  				    enum machine_mode, tree,
  				    int *, int);
*************** rs6000_emit_set_long_const (rtx dest, HO
*** 3211,3217 ****
  	  || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
  	{
  	  if (ud1 & 0x8000)
! 	    emit_move_insn (dest, GEN_INT (((ud1  ^ 0x8000) -  0x8000)));
  	  else
  	    emit_move_insn (dest, GEN_INT (ud1));
  	}
--- 3213,3219 ----
  	  || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
  	{
  	  if (ud1 & 0x8000)
! 	    emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) -  0x8000)));
  	  else
  	    emit_move_insn (dest, GEN_INT (ud1));
  	}
*************** function_arg_advance (CUMULATIVE_ARGS *c
*** 3894,3899 ****
--- 3896,3902 ----
  }
  
  /* Determine where to put a SIMD argument on the SPE.  */
+ 
  static rtx
  rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, 
  			 tree type)
*************** rs6000_spe_function_arg (CUMULATIVE_ARGS
*** 3919,3933 ****
  	  return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
  	}
        else
! 	return NULL;
      }
    else
      {
        if (cum->sysv_gregno <= GP_ARG_MAX_REG)
  	return gen_rtx_REG (mode, cum->sysv_gregno);
        else
! 	return NULL;
      }
  }
  
  /* Determine where to put an argument to a function.
--- 3922,4040 ----
  	  return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
  	}
        else
! 	return NULL_RTX;
      }
    else
      {
        if (cum->sysv_gregno <= GP_ARG_MAX_REG)
  	return gen_rtx_REG (mode, cum->sysv_gregno);
        else
! 	return NULL_RTX;
!     }
! }
! 
! /* Determine where to place an argument in 64-bit mode with 32-bit ABI.  */
! 
! static rtx
! rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, 
! 			   tree type, int align_words)
! {
!   if (mode == DFmode)
!     {
!       /* -mpowerpc64 with 32bit ABI splits up a DFmode argument
! 	 in vararg list into zero, one or two GPRs */
!       if (align_words >= GP_ARG_NUM_REG)
! 	return gen_rtx_PARALLEL (DFmode,
! 		 gen_rtvec (2,
! 			    gen_rtx_EXPR_LIST (VOIDmode,
! 					       NULL_RTX, const0_rtx), 
! 			    gen_rtx_EXPR_LIST (VOIDmode,
! 					       gen_rtx_REG (mode,
! 							    cum->fregno),
! 					       const0_rtx)));
!       else if (align_words + RS6000_ARG_SIZE (mode, type)
! 	       > GP_ARG_NUM_REG)
! 	/* If this is partially on the stack, then we only
! 	   include the portion actually in registers here. */
! 	return gen_rtx_PARALLEL (DFmode,
! 		 gen_rtvec (2,   
! 			    gen_rtx_EXPR_LIST (VOIDmode,
! 					       gen_rtx_REG (SImode,
! 							    GP_ARG_MIN_REG
! 							    + align_words),
! 					       const0_rtx),
! 			    gen_rtx_EXPR_LIST (VOIDmode,
! 					       gen_rtx_REG (mode,
! 							    cum->fregno),
! 					       const0_rtx)));
! 
!       /* split a DFmode arg into two GPRs */
!       return gen_rtx_PARALLEL (DFmode,
! 	       gen_rtvec (3,
! 			  gen_rtx_EXPR_LIST (VOIDmode,       
! 					     gen_rtx_REG (SImode,
! 							  GP_ARG_MIN_REG
! 							  + align_words),
! 					     const0_rtx),
! 			  gen_rtx_EXPR_LIST (VOIDmode,
! 					     gen_rtx_REG (SImode,
! 							  GP_ARG_MIN_REG
! 							  + align_words + 1),
! 					     GEN_INT (4)),
! 			  gen_rtx_EXPR_LIST (VOIDmode,
! 					     gen_rtx_REG (mode, cum->fregno),
! 					     const0_rtx)));
      }
+   /* -mpowerpc64 with 32bit ABI splits up a DImode argument into one
+      or two GPRs */
+   else if (mode == DImode)
+     {
+       if (align_words < GP_ARG_NUM_REG - 1)
+ 	return gen_rtx_PARALLEL (DImode,
+ 		 gen_rtvec (2,
+ 			    gen_rtx_EXPR_LIST (VOIDmode,
+ 					       gen_rtx_REG (SImode,
+ 							    GP_ARG_MIN_REG
+ 							    + align_words),
+ 					       const0_rtx),
+ 			    gen_rtx_EXPR_LIST (VOIDmode,
+ 					       gen_rtx_REG (SImode,
+ 							    GP_ARG_MIN_REG
+ 							    + align_words + 1),
+ 					       GEN_INT (4))));
+       else if (align_words == GP_ARG_NUM_REG - 1)
+ 	  return gen_rtx_PARALLEL (DImode,
+ 		   gen_rtvec (2,
+ 			      gen_rtx_EXPR_LIST (VOIDmode,
+ 						 NULL_RTX, const0_rtx),
+ 			      gen_rtx_EXPR_LIST (VOIDmode,
+ 						 gen_rtx_REG (SImode,
+ 							      GP_ARG_MIN_REG
+ 							      + align_words),
+ 						 const0_rtx)));
+     }
+   else if (mode == BLKmode && align_words <= (GP_ARG_NUM_REG - 1))
+     {
+       int k;
+       int size = int_size_in_bytes (type);
+       int no_units = size / 4;
+       int max_no_words = GP_ARG_NUM_REG - align_words;
+       int rtlvec_len = no_units < max_no_words ? no_units : max_no_words;
+       rtx *rtlvec = (rtx *) alloca (rtlvec_len * sizeof (rtx));
+ 
+       memset ((char *) rtlvec, 0, rtlvec_len * sizeof (rtx));
+ 
+       for (k=0; k < rtlvec_len; k++)
+ 	rtlvec[k] = gen_rtx_EXPR_LIST (VOIDmode,
+ 				       gen_rtx_REG (SImode,
+ 						    GP_ARG_MIN_REG
+ 						    + align_words + k),
+ 				       k == 0 ? const0_rtx : GEN_INT (k*4));
+ 
+       return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k, rtlvec));
+   }
+ 
+   return NULL_RTX;
  }
  
  /* Determine where to put an argument to a function.
*************** function_arg (CUMULATIVE_ARGS *cum, enum
*** 4029,4035 ****
  	  if (cum->fregno <= FP_ARG_V4_MAX_REG)
  	    return gen_rtx_REG (mode, cum->fregno);
  	  else
! 	    return NULL;
  	}
        else
  	{
--- 4136,4142 ----
  	  if (cum->fregno <= FP_ARG_V4_MAX_REG)
  	    return gen_rtx_REG (mode, cum->fregno);
  	  else
! 	    return NULL_RTX;
  	}
        else
  	{
*************** function_arg (CUMULATIVE_ARGS *cum, enum
*** 4051,4057 ****
  	  if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
  	    return gen_rtx_REG (mode, gregno);
  	  else
! 	    return NULL;
  	}
      }
    else
--- 4158,4164 ----
  	  if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
  	    return gen_rtx_REG (mode, gregno);
  	  else
! 	    return NULL_RTX;
  	}
      }
    else
*************** function_arg (CUMULATIVE_ARGS *cum, enum
*** 4063,4068 ****
--- 4170,4179 ----
        if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
          return NULL_RTX;
  
+       if (TARGET_32BIT && TARGET_POWERPC64
+ 	  && (mode == DFmode || mode == DImode || mode == BLKmode))
+ 	return rs6000_mixed_function_arg (cum, mode, type, align_words);
+ 
        if (USE_FP_FOR_ARG_P (*cum, mode, type))
  	{
  	  if (! type
*************** function_arg (CUMULATIVE_ARGS *cum, enum
*** 4075,4127 ****
  		      || (align_words < GP_ARG_NUM_REG))))
  	    return gen_rtx_REG (mode, cum->fregno);
  
- 	  if (TARGET_32BIT && TARGET_POWERPC64 && mode == DFmode)
- 	    {
-               /* -mpowerpc64 with 32bit ABI splits up a DFmode argument
- 		 in vararg list into zero, one or two GPRs */
- 	      if (align_words >= GP_ARG_NUM_REG)
- 		return gen_rtx_PARALLEL (DFmode,
- 		  gen_rtvec (2,
- 			     gen_rtx_EXPR_LIST (VOIDmode,
- 						NULL_RTX, const0_rtx), 
- 			     gen_rtx_EXPR_LIST (VOIDmode,
- 						gen_rtx_REG (mode,
- 							     cum->fregno),
- 						const0_rtx)));
- 	      else if (align_words + RS6000_ARG_SIZE (mode, type)
- 		       > GP_ARG_NUM_REG)
- 		/* If this is partially on the stack, then we only
- 		   include the portion actually in registers here. */
- 		return gen_rtx_PARALLEL (DFmode,
- 		  gen_rtvec (2,   
- 			     gen_rtx_EXPR_LIST (VOIDmode,
- 						gen_rtx_REG (SImode,
- 							     GP_ARG_MIN_REG
- 							     + align_words),
- 						const0_rtx),
- 			     gen_rtx_EXPR_LIST (VOIDmode,
- 						gen_rtx_REG (mode,
- 							     cum->fregno),
- 						const0_rtx)));
- 
- 	      /* split a DFmode arg into two GPRs */
- 	      return gen_rtx_PARALLEL (DFmode,
- 		gen_rtvec (3,
- 			   gen_rtx_EXPR_LIST (VOIDmode,       
- 					      gen_rtx_REG (SImode,
- 							   GP_ARG_MIN_REG
- 							   + align_words),
- 					      const0_rtx),
- 			   gen_rtx_EXPR_LIST (VOIDmode,
- 					      gen_rtx_REG (SImode,
- 							   GP_ARG_MIN_REG
- 							   + align_words + 1),
- 					      GEN_INT (4)),
- 			   gen_rtx_EXPR_LIST (VOIDmode,
- 					      gen_rtx_REG (mode, cum->fregno),
- 					      const0_rtx)));
-             }
- 
            return gen_rtx_PARALLEL (mode,
  	    gen_rtvec (2,
  		       gen_rtx_EXPR_LIST (VOIDmode,
--- 4186,4191 ----
*************** function_arg (CUMULATIVE_ARGS *cum, enum
*** 4142,4178 ****
  				gen_rtx_REG (mode, cum->fregno),
  				const0_rtx)));
  	}
-       /* -mpowerpc64 with 32bit ABI splits up a DImode argument into one
- 	 or two GPRs */
-       else if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode
- 	       && align_words < GP_ARG_NUM_REG - 1)
- 	{
- 	  return gen_rtx_PARALLEL (DImode,
- 	    gen_rtvec (2,
- 		       gen_rtx_EXPR_LIST (VOIDmode,
- 					  gen_rtx_REG (SImode,
- 						       GP_ARG_MIN_REG
- 						       + align_words),
- 					  const0_rtx),
- 		       gen_rtx_EXPR_LIST (VOIDmode,
- 					  gen_rtx_REG (SImode,
- 						       GP_ARG_MIN_REG
- 						       + align_words + 1),
- 					  GEN_INT (4))));
- 	}
-       else if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode
- 	       && align_words == GP_ARG_NUM_REG - 1)
- 	{
- 	  return gen_rtx_PARALLEL (DImode,
- 	    gen_rtvec (2,
- 		       gen_rtx_EXPR_LIST (VOIDmode,
- 					  NULL_RTX, const0_rtx),
- 		       gen_rtx_EXPR_LIST (VOIDmode,
- 					  gen_rtx_REG (SImode,
- 						       GP_ARG_MIN_REG
- 						       + align_words),
- 					  const0_rtx)));
- 	}
        else if (align_words < GP_ARG_NUM_REG)
  	return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
        else
--- 4206,4211 ----
*************** rs6000_emit_prologue (void)
*** 11365,11371 ****
    rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
    rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
    rtx frame_reg_rtx = sp_reg_rtx;
!   rtx cr_save_rtx = NULL;
    rtx insn;
    int saving_FPRs_inline;
    int using_store_multiple;
--- 11398,11404 ----
    rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
    rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
    rtx frame_reg_rtx = sp_reg_rtx;
!   rtx cr_save_rtx = NULL_RTX;
    rtx insn;
    int saving_FPRs_inline;
    int using_store_multiple;
*************** rs6000_function_value (tree valtype, tre
*** 15456,15462 ****
    if ((INTEGRAL_TYPE_P (valtype)
         && TYPE_PRECISION (valtype) < BITS_PER_WORD)
        || POINTER_TYPE_P (valtype))
!     mode = word_mode;
    else
      mode = TYPE_MODE (valtype);
  
--- 15489,15495 ----
    if ((INTEGRAL_TYPE_P (valtype)
         && TYPE_PRECISION (valtype) < BITS_PER_WORD)
        || POINTER_TYPE_P (valtype))
!     mode = TARGET_32BIT ? SImode : DImode;
    else
      mode = TYPE_MODE (valtype);
  
Index: rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.294
diff -c -p -r1.294 rs6000.h
*** rs6000.h	30 Oct 2003 02:02:45 -0000	1.294
--- rs6000.h	30 Oct 2003 20:59:36 -0000
*************** extern enum rs6000_nop_insertion rs6000_
*** 604,610 ****
  #define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE)	\
    if (GET_MODE_CLASS (MODE) == MODE_INT		\
        && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
!     (MODE) = word_mode;
  
  /* Define this if most significant bit is lowest numbered
     in instructions that operate on numbered bit-fields.  */
--- 604,610 ----
  #define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE)	\
    if (GET_MODE_CLASS (MODE) == MODE_INT		\
        && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
!     (MODE) = TARGET_32BIT ? SImode : DImode;
  
  /* Define this if most significant bit is lowest numbered
     in instructions that operate on numbered bit-fields.  */


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