Patchwork RX: Promote small integers to SImode

login
register
mail settings
Submitter Nick Clifton
Date Oct. 19, 2010, 10:25 a.m.
Message ID <m3vd4yscmf.fsf@redhat.com>
Download mbox | patch
Permalink /patch/68303/
State New
Headers show

Comments

Nick Clifton - Oct. 19, 2010, 10:25 a.m.
Hi Guys,

  I am applying the patch below to fix a small problem with the RX GCC
  port.  The RX ABI specifies that functions that return small integers
  (less than 32-bits) should promote them to 32-bits, so this patch
  implements the TARGET_PROMOTE_FUNCTION_MODE macro and also updates
  rx_function_value to describe this behaviour.

  This actually makes no change to gcc's current behaviour, but I have
  put it in to ensure compatibility with Renesas's own C compiler.

Cheers
  Nick

gcc/ChangeLog
2010-10-19  Nick Clifton  <nickc@redhat.com>

	* config/rx/rx.c (rx_function_value): Small integer types are
	promotes to SImode.
	(rx_promote_function_mode): New function.
	(TARGET_PROMOTE_FUNCTION_MODE): Define.

Patch

Index: config/rx/rx.c
===================================================================
--- config/rx/rx.c	(revision 165680)
+++ config/rx/rx.c	(working copy)
@@ -830,9 +830,34 @@ 
 		   const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
 		   bool       outgoing ATTRIBUTE_UNUSED)
 {
-  return gen_rtx_REG (TYPE_MODE (ret_type), FUNC_RETURN_REGNUM);
+  enum machine_mode mode = TYPE_MODE (ret_type);
+
+  /* RX ABI specifies that small integer types are
+     promoted to int when returned by a function.  */
+  if (GET_MODE_SIZE (mode) > 0 && GET_MODE_SIZE (mode) < 4)
+    return gen_rtx_REG (SImode, FUNC_RETURN_REGNUM);
+    
+  return gen_rtx_REG (mode, FUNC_RETURN_REGNUM);
 }
 
+/* TARGET_PROMOTE_FUNCTION_MODE must behave in the same way with
+   regard to function returns as does TARGET_FUNCTION_VALUE.  */
+
+static enum machine_mode
+rx_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
+			  enum machine_mode mode,
+			  int * punsignedp,
+			  const_tree funtype ATTRIBUTE_UNUSED,
+			  int for_return)
+{
+  if (for_return != 1
+      || GET_MODE_SIZE (mode) >= 4
+      || GET_MODE_SIZE (mode) < 1)
+    return mode;
+
+  return SImode;
+}
+
 static bool
 rx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
 {
@@ -2825,6 +2850,9 @@ 
 #undef  TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE			rx_option_override
 
+#undef  TARGET_PROMOTE_FUNCTION_MODE
+#define TARGET_PROMOTE_FUNCTION_MODE		rx_promote_function_mode
+
 #undef  TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
 #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE	rx_override_options_after_change