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]

[PATCH RFC 1/3] Hookize PROMOTE_FUNCTION_MODE with provision for ARM HFmode


The aim of this series is to cleanup uses of promote_mode and to
turn all three hooks PROMOTE_FUNCTION_MODE, TARGET_PROMOTE_FUNCTION_RETURN
and TARGET_PROMOTE_FUNCTION_ARGS into a single hook.  This, among other
things, should make it simpler to distinguish the passing of HFmode
values for libcalls and ordinary functions for the ARM.

This first part introduces two new functions.  One is promote_function_mode,
a low-level function whose semantics and signature are the same as the
intended target hook.

The second is promote_decl_mode, which wraps the low-level promote_mode
and promote_function_mode so that it can be used most of the time.

Overall, the series does not succeed in deleting more lines than it adds :-)
but the result is strictly more powerful, as it allows tweaking the
promotions *per argument and per function*.  Right now, if a function
does not want to promote something, it cannot promoting everything.

The patch is being bootstrapped right now on i686-pc-linux-gnu; I
have already built the relevant targets.

Paolo

2009-04-17  Paolo Bonzini  <bonzini@gnu.org>

	* expr.c (store_constructor): Use promote_decl_mode.  Remove
	now write-only variable unsignedp.
	(expand_expr_real_1): Use promote_decl_mode.
	* expr.h (promote_function_mode, promote_decl_mode): New.
	(promote_mode): Remove last argument.
	* function.c (assign_temp): Drop last argument of promote_mode.
	(assign_parm_find_data_types): Use promote_function_mode.
	(assign_parm_setup_reg): Likewise.
	(expand_function_end): Use promote_function_mode.
	* calls.c (initialize_argument_information): Use promote_function_mode.
	(precompute_arguments): Use promote_mode instead of checking if
	only PROMOTE_FUNCTION_MODE is defined.
	(expand_call): When making sibcall decisions, use promote_function_mode.
	Below, remove an if for targetm.calls.promote_function_return and
	and use promote_function_mode.
	(emit_library_call_value_1): Use promote_function_mode, fix bug
	where promote_mode was passed FOR_CALL == 0 for a return value in an
	assertion.
	* cfgexpand.c (expand_one_register_var): Use promote_decl_mode.
	* explow.c (promote_function_mode, promote_decl_mode): New.
	(promote_mode): Keep only the FOR_CALL == 0 case.
	* combine.c (setup_incoming_promotion): Remove test of
	promote_function_args.  Use promote_function_mode.
	* stmt.c (expand_value_return): Use promote_decl_mode.
	(expand_decl): Use promote_decl_mode.

Index: gcc/expr.c
===================================================================
--- gcc/expr.c	(branch promote-function-mode)
+++ gcc/expr.c	(working copy)
@@ -5401,13 +5401,11 @@ store_constructor (tree exp, rtx target,
 	    enum machine_mode mode;
 	    HOST_WIDE_INT bitsize;
 	    HOST_WIDE_INT bitpos;
-	    int unsignedp;
 	    rtx xtarget = target;
 
 	    if (cleared && initializer_zerop (value))
 	      continue;
 
-	    unsignedp = TYPE_UNSIGNED (elttype);
 	    mode = TYPE_MODE (elttype);
 	    if (mode == BLKmode)
 	      bitsize = (host_integerp (TYPE_SIZE (elttype), 1)
@@ -5463,13 +5461,9 @@ store_constructor (tree exp, rtx target,
 		    tree exit_cond;
 
 		    expand_normal (hi_index);
-		    unsignedp = TYPE_UNSIGNED (domain);
 
 		    index = build_decl (VAR_DECL, NULL_TREE, domain);
-
-		    index_r
-		      = gen_reg_rtx (promote_mode (domain, DECL_MODE (index),
-						   &unsignedp, 0));
+		    index_r = gen_reg_rtx (promote_decl_mode (index, NULL));
 		    SET_DECL_RTL (index, index_r);
 		    store_expr (lo_index, index_r, 0, false);
 
@@ -7356,9 +7350,7 @@ expand_expr_real_1 (tree exp, rtx target
 
 	  /* Get the signedness used for this variable.  Ensure we get the
 	     same mode we got when the variable was declared.  */
-	  pmode = promote_mode (type, DECL_MODE (exp), &unsignedp,
-				(TREE_CODE (exp) == RESULT_DECL
-				 || TREE_CODE (exp) == PARM_DECL) ? 1 : 0);
+	  pmode = promote_decl_mode (exp, &unsignedp);
 	  gcc_assert (GET_MODE (decl_rtl) == pmode);
 
 	  temp = gen_lowpart_SUBREG (mode, decl_rtl);
Index: gcc/expr.h
===================================================================
--- gcc/expr.h	(branch promote-function-mode)
+++ gcc/expr.h	(working copy)
@@ -723,8 +723,17 @@ extern rtx force_reg (enum machine_mode,
 /* Return given rtx, copied into a new temp reg if it was in memory.  */
 extern rtx force_not_mem (rtx);
 
+/* Return mode and signedness to use when an argument or result in the
+   given mode is promoted.  */
+extern enum machine_mode promote_function_mode (const_tree, enum machine_mode, int *,
+					        const_tree, int);
+
+/* Return mode and signedness to use when an object in the given mode
+   is promoted.  */
+extern enum machine_mode promote_mode (const_tree, enum machine_mode, int *);
+
 /* Return mode and signedness to use when object is promoted.  */
-extern enum machine_mode promote_mode (const_tree, enum machine_mode, int *, int);
+enum machine_mode promote_decl_mode (const_tree, int *);
 
 /* Remove some bytes from the stack.  An rtx says how many.  */
 extern void adjust_stack (rtx);
Index: gcc/function.c
===================================================================
--- gcc/function.c	(branch promote-function-mode)
+++ gcc/function.c	(working copy)
@@ -925,7 +925,7 @@ assign_temp (tree type_or_decl, int keep
 
 #ifdef PROMOTE_MODE
   if (! dont_promote)
-    mode = promote_mode (type, mode, &unsignedp, 0);
+    mode = promote_mode (type, mode, &unsignedp);
 #endif
 
   return gen_reg_rtx (mode);
@@ -2147,6 +2147,7 @@ assign_parm_find_data_types (struct assi
 {
   tree nominal_type, passed_type;
   enum machine_mode nominal_mode, passed_mode, promoted_mode;
+  int unsignedp;
 
   memset (data, 0, sizeof (*data));
 
@@ -2199,13 +2200,9 @@ assign_parm_find_data_types (struct assi
     }
 
   /* Find mode as it is passed by the ABI.  */
-  promoted_mode = passed_mode;
-  if (targetm.calls.promote_function_args (TREE_TYPE (current_function_decl)))
-    {
-      int unsignedp = TYPE_UNSIGNED (passed_type);
-      promoted_mode = promote_mode (passed_type, promoted_mode,
-				    &unsignedp, 1);
-    }
+  unsignedp = TYPE_UNSIGNED (passed_type);
+  promoted_mode = promote_function_mode (passed_type, passed_mode, &unsignedp,
+				         TREE_TYPE (current_function_decl), 0);
 
  egress:
   data->nominal_type = nominal_type;
@@ -2758,7 +2755,8 @@ assign_parm_setup_reg (struct assign_par
   /* This is not really promoting for a call.  However we need to be
      consistent with assign_parm_find_data_types and expand_expr_real_1.  */
   promoted_nominal_mode
-    = promote_mode (data->nominal_type, data->nominal_mode, &unsignedp, 1);
+    = promote_function_mode (data->nominal_type, data->nominal_mode, &unsignedp,
+			     TREE_TYPE (current_function_decl), 0);
 
   parmreg = gen_reg_rtx (promoted_nominal_mode);
 
@@ -4699,10 +4697,9 @@ expand_function_end (void)
 	  else if (GET_MODE (real_decl_rtl) != GET_MODE (decl_rtl))
 	    {
 	      int unsignedp = TYPE_UNSIGNED (TREE_TYPE (decl_result));
-
-	      if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
-		promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl),
-			      &unsignedp, 1);
+	      promote_function_mode (TREE_TYPE (decl_result),
+				     GET_MODE (decl_rtl), &unsignedp,
+				     TREE_TYPE (current_function_decl), 1);
 
 	      convert_move (real_decl_rtl, decl_rtl, unsignedp);
 	    }
Index: gcc/calls.c
===================================================================
--- gcc/calls.c	(branch promote-function-mode)
+++ gcc/calls.c	(working copy)
@@ -1119,13 +1119,9 @@ initialize_argument_information (int num
 	    }
 	}
 
-      mode = TYPE_MODE (type);
       unsignedp = TYPE_UNSIGNED (type);
-
-      if (targetm.calls.promote_function_args (fndecl
-					       ? TREE_TYPE (fndecl)
-					       : fntype))
-	mode = promote_mode (type, mode, &unsignedp, 1);
+      mode = promote_function_mode (type, TYPE_MODE (type), &unsignedp,
+				    fndecl ? TREE_TYPE (fndecl) : fntype, 0);
 
       args[i].unsignedp = unsignedp;
       args[i].mode = mode;
@@ -1305,29 +1301,33 @@ precompute_arguments (int num_actuals, s
 
   for (i = 0; i < num_actuals; i++)
     {
+      tree type;
       enum machine_mode mode;
 
       if (TREE_CODE (args[i].tree_value) != CALL_EXPR)
 	continue;
 
       /* If this is an addressable type, we cannot pre-evaluate it.  */
-      gcc_assert (!TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)));
+      type = TREE_TYPE (args[i].tree_value);
+      gcc_assert (!TREE_ADDRESSABLE (type));
 
       args[i].initial_value = args[i].value
 	= expand_normal (args[i].tree_value);
 
-      mode = TYPE_MODE (TREE_TYPE (args[i].tree_value));
+      mode = TYPE_MODE (type);
       if (mode != args[i].mode)
 	{
+	  int unsignedp = args[i].unsignedp;
 	  args[i].value
 	    = convert_modes (args[i].mode, mode,
 			     args[i].value, args[i].unsignedp);
-#if defined(PROMOTE_FUNCTION_MODE) && !defined(PROMOTE_MODE)
+
 	  /* CSE will replace this only if it contains args[i].value
 	     pseudo, so convert it down to the declared mode using
 	     a SUBREG.  */
 	  if (REG_P (args[i].value)
-	      && GET_MODE_CLASS (args[i].mode) == MODE_INT)
+	      && GET_MODE_CLASS (args[i].mode) == MODE_INT
+	      && promote_mode (type, mode, &unsignedp) != args[i].mode)
 	    {
 	      args[i].initial_value
 		= gen_lowpart_SUBREG (mode, args[i].value);
@@ -1335,7 +1335,6 @@ precompute_arguments (int num_actuals, s
 	      SUBREG_PROMOTED_UNSIGNED_SET (args[i].initial_value,
 					    args[i].unsignedp);
 	    }
-#endif
 	}
     }
 }
@@ -2343,17 +2342,17 @@ expand_call (tree exp, rtx target, int i
       tree caller_res = DECL_RESULT (current_function_decl);
 
       caller_unsignedp = TYPE_UNSIGNED (TREE_TYPE (caller_res));
-      caller_mode = caller_promoted_mode = DECL_MODE (caller_res);
+      caller_mode = DECL_MODE (caller_res);
       callee_unsignedp = TYPE_UNSIGNED (TREE_TYPE (funtype));
-      callee_mode = callee_promoted_mode = TYPE_MODE (TREE_TYPE (funtype));
-      if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
-	caller_promoted_mode
-	  = promote_mode (TREE_TYPE (caller_res), caller_mode,
-			  &caller_unsignedp, 1);
-      if (targetm.calls.promote_function_return (funtype))
-	callee_promoted_mode
-	  = promote_mode (TREE_TYPE (funtype), callee_mode,
-			  &callee_unsignedp, 1);
+      callee_mode = TYPE_MODE (TREE_TYPE (funtype));
+      caller_promoted_mode
+	= promote_function_mode (TREE_TYPE (caller_res), caller_mode,
+				 &caller_unsignedp,
+				 TREE_TYPE (current_function_decl), 1);
+      callee_promoted_mode
+	= promote_function_mode (TREE_TYPE (caller_res), callee_mode,
+				 &callee_unsignedp,
+				 TREE_TYPE (funtype), 1);
       if (caller_mode != VOIDmode
 	  && (caller_promoted_mode != callee_promoted_mode
 	      || ((caller_mode != caller_promoted_mode
@@ -3027,38 +3026,37 @@ expand_call (tree exp, rtx target, int i
       else
 	target = copy_to_reg (avoid_likely_spilled_reg (valreg));
 
-      if (targetm.calls.promote_function_return(funtype))
+      /* If we promoted this return value, make the proper SUBREG.
+         TARGET might be const0_rtx here, so be careful.  */
+      if (REG_P (target)
+	  && TYPE_MODE (TREE_TYPE (exp)) != BLKmode
+	  && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
 	{
-	  /* If we promoted this return value, make the proper SUBREG.
-	     TARGET might be const0_rtx here, so be careful.  */
-	  if (REG_P (target)
-	      && TYPE_MODE (TREE_TYPE (exp)) != BLKmode
-	      && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
-	    {
-	      tree type = TREE_TYPE (exp);
-	      int unsignedp = TYPE_UNSIGNED (type);
-	      int offset = 0;
-	      enum machine_mode pmode;
-
-	      pmode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
-	      /* If we don't promote as expected, something is wrong.  */
-	      gcc_assert (GET_MODE (target) == pmode);
-
-	      if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
-		  && (GET_MODE_SIZE (GET_MODE (target))
-		      > GET_MODE_SIZE (TYPE_MODE (type))))
-		{
-		  offset = GET_MODE_SIZE (GET_MODE (target))
-		    - GET_MODE_SIZE (TYPE_MODE (type));
-		  if (! BYTES_BIG_ENDIAN)
-		    offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
-		  else if (! WORDS_BIG_ENDIAN)
-		    offset %= UNITS_PER_WORD;
-		}
-	      target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset);
-	      SUBREG_PROMOTED_VAR_P (target) = 1;
-	      SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp);
-	    }
+	  tree type = TREE_TYPE (exp);
+	  int unsignedp = TYPE_UNSIGNED (type);
+	  int offset = 0;
+	  enum machine_mode pmode;
+
+	  /* Ensure we promote as expected, and get the new unsignedness.  */
+	  pmode = promote_function_mode (type, TYPE_MODE (type), &unsignedp,
+					 funtype, 1);
+	  gcc_assert (GET_MODE (target) == pmode);
+
+	  if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
+	      && (GET_MODE_SIZE (GET_MODE (target))
+		  > GET_MODE_SIZE (TYPE_MODE (type))))
+	    {
+	      offset = GET_MODE_SIZE (GET_MODE (target))
+	        - GET_MODE_SIZE (TYPE_MODE (type));
+	      if (! BYTES_BIG_ENDIAN)
+	        offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
+	      else if (! WORDS_BIG_ENDIAN)
+	        offset %= UNITS_PER_WORD;
+	    }
+
+	  target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset);
+	  SUBREG_PROMOTED_VAR_P (target) = 1;
+	  SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp);
 	}
 
       /* If size of args is variable or this was a constructor call for a stack
@@ -3872,15 +3870,14 @@ emit_library_call_value_1 (int retval, r
 	}
       else
 	{
-	  /* Convert to the proper mode if PROMOTE_MODE has been active.  */
+	  /* Convert to the proper mode if a promotion has been active.  */
 	  if (GET_MODE (valreg) != outmode)
 	    {
 	      int unsignedp = TYPE_UNSIGNED (tfom);
 
-	      gcc_assert (targetm.calls.promote_function_return (tfom));
-	      gcc_assert (promote_mode (tfom, outmode, &unsignedp, 0)
+	      gcc_assert (promote_function_mode (tfom, outmode, &unsignedp,
+						 fndecl ? TREE_TYPE (fndecl) : fntype, 1)
 			  == GET_MODE (valreg));
-
 	      valreg = convert_modes (outmode, GET_MODE (valreg), valreg, 0);
 	    }
 
Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c	(branch promote-function-mode)
+++ gcc/cfgexpand.c	(working copy)
@@ -984,9 +984,7 @@ static void
 expand_one_register_var (tree var)
 {
   tree type = TREE_TYPE (var);
-  int unsignedp = TYPE_UNSIGNED (type);
-  enum machine_mode reg_mode
-    = promote_mode (type, DECL_MODE (var), &unsignedp, 0);
+  enum machine_mode reg_mode = promote_decl_mode (var, NULL);
   rtx x = gen_reg_rtx (reg_mode);
 
   SET_DECL_RTL (var, x);
Index: gcc/explow.c
===================================================================
--- gcc/explow.c	(branch promote-function-mode)
+++ gcc/explow.c	(working copy)
@@ -744,63 +744,108 @@ copy_to_suggested_reg (rtx x, rtx target
   return temp;
 }
 
-/* Return the mode to use to store a scalar of TYPE and MODE.
+/* Return the mode to use to pass or return a scalar of TYPE and MODE.
    PUNSIGNEDP points to the signedness of the type and may be adjusted
    to show what signedness to use on extension operations.
 
-   FOR_CALL is nonzero if this call is promoting args for a call.  */
+   FOR_RETURN is nonzero if the caller is promoting the return value
+   of FNDECL, else it is for promoting args.  */
+
+enum machine_mode
+promote_function_mode (const_tree type, enum machine_mode mode, int *punsignedp,
+		       const_tree funtype, int for_return)
+{
+  if (for_return && !targetm.calls.promote_function_return (funtype))
+    return mode;
+  if (!for_return && !targetm.calls.promote_function_args (funtype))
+    return mode;
+
+#ifdef PROMOTE_FUNCTION_MODE
+  switch (TREE_CODE (type))
+    {
+    case INTEGER_TYPE:   case ENUMERAL_TYPE:   case BOOLEAN_TYPE:
+    case REAL_TYPE:      case OFFSET_TYPE:     case FIXED_POINT_TYPE:
+      {
+	int unsignedp = *punsignedp;
+	PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
+	*punsignedp = unsignedp;
+	return mode;
+      }
 
-#if defined(PROMOTE_MODE) && !defined(PROMOTE_FUNCTION_MODE)
-#define PROMOTE_FUNCTION_MODE PROMOTE_MODE
+    default:
+      break;
+    }
 #endif
 
+  return promote_mode (type, mode, punsignedp);
+}
+
+/* Return the mode to use to store a scalar of TYPE and MODE.
+   PUNSIGNEDP points to the signedness of the type and may be adjusted
+   to show what signedness to use on extension operations.  */
+
 enum machine_mode
-promote_mode (const_tree type, enum machine_mode mode, int *punsignedp,
-	      int for_call ATTRIBUTE_UNUSED)
+promote_mode (const_tree type, enum machine_mode mode, int *punsignedp)
 {
+  /* FIXME: this is the same logic that was there until GCC 4.4, but we
+     probably want to test POINTERS_EXTEND_UNSIGNED even if PROMOTE_MODE
+     is not defined.  The affected targets are M32C, S390, SPARC.  */
+#ifdef PROMOTE_MODE
   const enum tree_code code = TREE_CODE (type);
   int unsignedp = *punsignedp;
 
-#ifndef PROMOTE_MODE
-  if (! for_call)
-    return mode;
-#endif
-
   switch (code)
     {
-#ifdef PROMOTE_FUNCTION_MODE
     case INTEGER_TYPE:   case ENUMERAL_TYPE:   case BOOLEAN_TYPE:
     case REAL_TYPE:      case OFFSET_TYPE:     case FIXED_POINT_TYPE:
-#ifdef PROMOTE_MODE
-      if (for_call)
-	{
-#endif
-	  PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
-#ifdef PROMOTE_MODE
-	}
-      else
-	{
-	  PROMOTE_MODE (mode, unsignedp, type);
-	}
-#endif
+      PROMOTE_MODE (mode, unsignedp, type);
+      *punsignedp = unsignedp;
+      return mode;
       break;
-#endif
 
 #ifdef POINTERS_EXTEND_UNSIGNED
     case REFERENCE_TYPE:
     case POINTER_TYPE:
-      mode = Pmode;
-      unsignedp = POINTERS_EXTEND_UNSIGNED;
+      *punsignedp = POINTERS_EXTEND_UNSIGNED;
+      return Pmode;
       break;
 #endif
 
     default:
-      break;
+      return mode;
     }
-
-  *punsignedp = unsignedp;
+#else
   return mode;
+#endif
 }
+
+
+/* Use one of promote_mode or promote_function_mode to find the promoted
+   mode of DECL.  If PUNSIGNEDP is not NULL, store there the unsignedness
+   of DECL after promotion.  */
+
+enum machine_mode
+promote_decl_mode (const_tree decl, int *punsignedp)
+{
+  tree type = TREE_TYPE (decl);
+  int unsignedp = TYPE_UNSIGNED (type);
+  enum machine_mode mode = DECL_MODE (decl);
+  enum machine_mode pmode;
+
+  if (TREE_CODE (decl) == RESULT_DECL)
+    pmode = promote_function_mode (type, mode, &unsignedp,
+                                   TREE_TYPE (current_function_decl), 1);
+  else if (TREE_CODE (decl) == PARM_DECL)
+    pmode = promote_function_mode (type, mode, &unsignedp,
+                                   TREE_TYPE (current_function_decl), 0);
+  else
+    pmode = promote_mode (type, mode, &unsignedp);
+
+  if (punsignedp)
+    *punsignedp = unsignedp;
+  return pmode;
+}
+
 
 /* Adjust the stack pointer by ADJUST (an rtx for a number of bytes).
    This pops when ADJUST is positive.  ADJUST need not be constant.  */
Index: gcc/combine.c
===================================================================
--- gcc/combine.c	(branch promote-function-mode)
+++ gcc/combine.c	(working copy)
@@ -1328,9 +1328,6 @@ setup_incoming_promotions (rtx first)
   tree arg;
   bool strictly_local = false;
 
-  if (!targetm.calls.promote_function_args (TREE_TYPE (cfun->decl)))
-    return;
-
   for (arg = DECL_ARGUMENTS (current_function_decl); arg;
        arg = TREE_CHAIN (arg))
     {
@@ -1360,7 +1357,8 @@ setup_incoming_promotions (rtx first)
 
       /* The mode and signedness of the argument as it is actually passed, 
          after any TARGET_PROMOTE_FUNCTION_ARGS-driven ABI promotions.  */
-      mode3 = promote_mode (DECL_ARG_TYPE (arg), mode2, &uns3, 1);
+      mode3 = promote_function_mode (DECL_ARG_TYPE (arg), mode2, &uns3,
+				     TREE_TYPE (cfun->decl), 0);
 
       /* The mode of the register in which the argument is being passed.  */
       mode4 = GET_MODE (reg);
Index: gcc/stmt.c
===================================================================
--- gcc/stmt.c	(branch promote-function-mode)
+++ gcc/stmt.c	(working copy)
@@ -1512,23 +1512,22 @@ expand_value_return (rtx val)
   /* Copy the value to the return location
      unless it's already there.  */
 
-  rtx return_reg = DECL_RTL (DECL_RESULT (current_function_decl));
+  tree decl = DECL_RESULT (current_function_decl);
+  rtx return_reg = DECL_RTL (decl);
   if (return_reg != val)
     {
-      tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
-      if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
-      {
-	int unsignedp = TYPE_UNSIGNED (type);
-	enum machine_mode old_mode
-	  = DECL_MODE (DECL_RESULT (current_function_decl));
-	enum machine_mode mode
-	  = promote_mode (type, old_mode, &unsignedp, 1);
-
-	if (mode != old_mode)
-	  val = convert_modes (mode, old_mode, val, unsignedp);
-      }
+      int unsignedp;
+      enum machine_mode old_mode = DECL_MODE (decl);
+      enum machine_mode mode = promote_decl_mode (decl, &unsignedp);
+
+      if (mode != old_mode)
+	val = convert_modes (mode, old_mode, val, unsignedp);
+
       if (GET_CODE (return_reg) == PARALLEL)
-	emit_group_load (return_reg, val, type, int_size_in_bytes (type));
+	{
+          tree type = TREE_TYPE (decl);
+	  emit_group_load (return_reg, val, type, int_size_in_bytes (type));
+	}
       else
 	emit_move_insn (return_reg, val);
     }
@@ -1846,9 +1845,7 @@ expand_decl (tree decl)
   else if (use_register_for_decl (decl))
     {
       /* Automatic variable that can go in a register.  */
-      int unsignedp = TYPE_UNSIGNED (type);
-      enum machine_mode reg_mode
-	= promote_mode (type, DECL_MODE (decl), &unsignedp, 0);
+      enum machine_mode reg_mode = promote_decl_mode (decl, NULL);
 
       SET_DECL_RTL (decl, gen_reg_rtx (reg_mode));
 


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