This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[3.3] [PATCH] Do not promote integer return value...
- From: "Alexander Aganichev" <aaganichev at yandex dot ru>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 19 May 2003 11:12:18 +0400 (MSD)
- Subject: [3.3] [PATCH] Do not promote integer return value...
- Reply-to: aaganichev at yandex dot ru
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