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]

[3.3] [PATCH] Do not promote integer return value...


The problem: Z80 port I'm working on require "char" and "int" passed
in the different registers (at least SDSI compiler do that). GCC
promotes integer types smaller than "int" to "int" without checking
for PROMOTE_FUNCTION_RETURN macros.

I'm not sure which of two patches I've made should be applied to the
tree and if it should be rewritten in the different way (f.e., by
using PROMOTE_MODE or if this code need to be removed at all). Here
are possible patches:

First version (removes promotion on all platforms):

2003-05-19  Alexander Aganichev  <aaganichev@yandex.ru>

	* c-decl.c (start_function):  Do not promote return value unless
	PROMOTE_FUNCTION_RETURN defined.

--- c-decl.orig	2003-05-15 12:53:36.000000000 +0000
+++ c-decl.c	2003-05-19 07:55:38.000000000 +0000
@@ -5869,6 +5869,8 @@
   make_decl_rtl (current_function_decl, NULL);
 
   restype = TREE_TYPE (TREE_TYPE (current_function_decl));
+
+#ifdef PROMOTE_FUNCTION_RETURN
   /* Promote the value to int before returning it.  */
   if (c_promoting_integer_type_p (restype))
     {
@@ -5880,6 +5882,8 @@
       else
 	restype = integer_type_node;
     }
+#endif
+
   DECL_RESULT (current_function_decl)
     = build_decl (RESULT_DECL, NULL_TREE, restype);

Second version (removes promotion only on those platforms which require
different registers; this version more safe in terms of effects, though
I'm not sure if no more checks need to be done):

2003-05-19  Alexander Aganichev  <aaganichev@yandex.ru>

	* c-decl.c (start_function):  Do not promote return value if
	promoted value is to be returned in different register.

--- c-decl.orig	2003-05-15 12:53:36.000000000 +0000
+++ c-decl.c	2003-05-19 11:04:56.000000000 +0000
@@ -5872,13 +5872,24 @@
   /* Promote the value to int before returning it.  */
   if (c_promoting_integer_type_p (restype))
     {
+      tree restype_new;
+      rtx value, value_new;
+
       /* It retains unsignedness if not really getting wider.  */
       if (TREE_UNSIGNED (restype)
 	  && (TYPE_PRECISION (restype)
 		  == TYPE_PRECISION (integer_type_node)))
-	restype = unsigned_type_node;
+	restype_new = unsigned_type_node;
       else
-	restype = integer_type_node;
+	restype_new = integer_type_node;
+
+      /* Only promote value if it will be returned in the same hard
+         register.  */
+      value = hard_function_value (restype, NULL, 1);
+      value_new = hard_function_value (restype_new, NULL, 1);
+      if (REG_P (value) && REG_P (value_new)
+	  && (REGNO (value) == REGNO (value_new)))
+          restype = restype_new;
     }
   DECL_RESULT (current_function_decl)
     = build_decl (RESULT_DECL, NULL_TREE, restype);

--
Alexander Aganichev

url: http://aaganichev.narod.ru
e-mail: aaganichev@yandex.ru
gsm: +7-095-786-1339


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