This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[csl-arm] Backport function arg promotion changes.
- From: Paul Brook <paul at codesourcery dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Cc: Mark Mitchell <mark at codesourcery dot com>
- Date: Tue, 18 May 2004 12:58:13 +0100
- Subject: [csl-arm] Backport function arg promotion changes.
- Organization: CodeSourcery
The attached patch backports the function arg promotion changes from mainline
to csl-arm-branch.
It includes
http://gcc.gnu.org/ml/gcc-patches/2004-04/msg00470.html
plus subsequent fixes.
Tested with cross to arm-none-elf.
Ok?
Paul
2004-05-12 Paul Brook <paul@codesourcery.com>
* calls.c (precompute_arguments): Use PROMOTE_FUNCTION_MODE instead
of PROMOTE_FOR_CALL_ONLY.
* explow.c (promote_mode): Ditto.
* function.c (assign_temp): Ditto.
* system.h: Poison PROMOTE_FOR_CALL_ONLY.
* config/arm/arm-protos.h (arm_function_value): Add prototype.
* config/arm/arm.c (arm_promote_prototypes): New function.
(TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN,
TARGET_PROMOTE_PROTOTYPES): Define.
(arm_function_value): New function.
* config/arm/arm.h (PROMOTE_FUNCTION_MODE): Define.
(FUNCTION_VALUE): Use arm_function_value.
(PROMOTE_PROTOTYPES): Define.
* config/cris/cris.h: Use PROMOTE_FUNCTION_MODE instead
of PROMOTE_FOR_CALL_ONLY/PROMOTE_MODE.
* config/mmix/mmix.h: Ditto.
* config/s390/s390.h: Ditto.
* config/sparc/sparc.h: Ditto.
* doc/tm.texi: Document PROMOTE_FUNCTION_MODE.
Remove PROMOTE_FOR_CALL_ONLY.
Index: calls.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/calls.c,v
retrieving revision 1.304.4.5
diff -u -p -r1.304.4.5 calls.c
--- a/calls.c 9 Apr 2004 13:39:50 -0000 1.304.4.5
+++ b/calls.c 13 May 2004 11:59:56 -0000
@@ -1417,7 +1417,7 @@ precompute_arguments (int flags, int num
args[i].value
= convert_modes (args[i].mode, mode,
args[i].value, args[i].unsignedp);
-#ifdef PROMOTE_FOR_CALL_ONLY
+#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. */
Index: explow.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/explow.c,v
retrieving revision 1.117.4.2
diff -u -p -r1.117.4.2 explow.c
--- a/explow.c 9 Apr 2004 13:39:58 -0000 1.117.4.2
+++ b/explow.c 13 May 2004 11:59:56 -0000
@@ -756,6 +756,10 @@ copy_to_suggested_reg (rtx x, rtx target
FOR_CALL is nonzero if this call is promoting args for a call. */
+#if defined(PROMOTE_MODE) && !defined(PROMOTE_FUNCTION_MODE)
+#define PROMOTE_FUNCTION_MODE PROMOTE_MODE
+#endif
+
enum machine_mode
promote_mode (tree type, enum machine_mode mode, int *punsignedp,
int for_call ATTRIBUTE_UNUSED)
@@ -763,17 +767,28 @@ promote_mode (tree type, enum machine_mo
enum tree_code code = TREE_CODE (type);
int unsignedp = *punsignedp;
-#ifdef PROMOTE_FOR_CALL_ONLY
+#ifndef PROMOTE_MODE
if (! for_call)
return mode;
#endif
switch (code)
{
-#ifdef PROMOTE_MODE
+#ifdef PROMOTE_FUNCTION_MODE
case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
case CHAR_TYPE: case REAL_TYPE: case OFFSET_TYPE:
- PROMOTE_MODE (mode, unsignedp, type);
+#ifdef PROMOTE_MODE
+ if (for_call)
+ {
+#endif
+ PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
+#ifdef PROMOTE_MODE
+ }
+ else
+ {
+ PROMOTE_MODE (mode, unsignedp, type);
+ }
+#endif
break;
#endif
Index: function.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/function.c,v
retrieving revision 1.463.4.4
diff -u -p -r1.463.4.4 function.c
--- a/function.c 9 Apr 2004 13:39:59 -0000 1.463.4.4
+++ b/function.c 13 May 2004 11:59:56 -0000
@@ -841,7 +841,7 @@ assign_temp (tree type_or_decl, int keep
{
tree type, decl;
enum machine_mode mode;
-#ifndef PROMOTE_FOR_CALL_ONLY
+#ifdef PROMOTE_MODE
int unsignedp;
#endif
@@ -851,7 +851,7 @@ assign_temp (tree type_or_decl, int keep
decl = NULL, type = type_or_decl;
mode = TYPE_MODE (type);
-#ifndef PROMOTE_FOR_CALL_ONLY
+#ifdef PROMOTE_MODE
unsignedp = TREE_UNSIGNED (type);
#endif
@@ -889,7 +889,7 @@ assign_temp (tree type_or_decl, int keep
return tmp;
}
-#ifndef PROMOTE_FOR_CALL_ONLY
+#ifdef PROMOTE_MODE
if (! dont_promote)
mode = promote_mode (type, mode, &unsignedp, 0);
#endif
Index: system.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/system.h,v
retrieving revision 1.171.4.4
diff -u -p -r1.171.4.4 system.h
--- a/system.h 9 Apr 2004 13:40:06 -0000 1.171.4.4
+++ b/system.h 13 May 2004 11:59:56 -0000
@@ -609,7 +609,7 @@ typedef char _Bool;
CONVERT_HARD_REGISTER_TO_SSA_P ASM_OUTPUT_MAIN_SOURCE_FILENAME \
FIRST_INSN_ADDRESS TEXT_SECTION SHARED_BSS_SECTION_ASM_OP \
PROMOTED_MODE EXPAND_BUILTIN_VA_END \
- LINKER_DOES_NOT_WORK_WITH_DWARF2
+ LINKER_DOES_NOT_WORK_WITH_DWARF2 PROMOTE_FOR_CALL_ONLY
/* Hooks that are no longer used. */
#pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \
Index: config/arm/arm-protos.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm-protos.h,v
retrieving revision 1.60.4.10
diff -u -p -r1.60.4.10 arm-protos.h
--- a/config/arm/arm-protos.h 6 May 2004 14:16:16 -0000 1.60.4.10
+++ b/config/arm/arm-protos.h 13 May 2004 11:59:56 -0000
@@ -158,6 +158,7 @@ extern rtx arm_va_arg (tree, tree);
extern int arm_function_arg_pass_by_reference (CUMULATIVE_ARGS *,
enum machine_mode, tree, int);
extern bool arm_needs_doubleword_align (enum machine_mode, tree);
+extern rtx arm_function_value(tree, tree);
#endif
#if defined AOF_ASSEMBLER
Index: config/arm/arm.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.303.2.32
diff -u -p -r1.303.2.32 arm.c
--- a/config/arm/arm.c 15 May 2004 13:02:08 -0000 1.303.2.32
+++ b/config/arm/arm.c 17 May 2004 15:42:36 -0000
@@ -156,6 +156,7 @@ static void aof_file_start (void);
static void aof_file_end (void);
#endif
static bool arm_align_anon_bitfield (void);
+static bool arm_promote_prototypes (tree);
/* Initialize the GCC target structure. */
@@ -240,6 +241,13 @@ static bool arm_align_anon_bitfield (voi
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN arm_expand_builtin
+#undef TARGET_PROMOTE_FUNCTION_ARGS
+#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
+#undef TARGET_PROMOTE_FUNCTION_RETURN
+#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
+#undef TARGET_PROMOTE_PROTOTYPES
+#define TARGET_PROMOTE_PROTOTYPES arm_promote_prototypes
+
#undef TARGET_ALIGN_ANON_BITFIELD
#define TARGET_ALIGN_ANON_BITFIELD arm_align_anon_bitfield
@@ -2072,6 +2080,24 @@ arm_canonicalize_comparison (enum rtx_co
return code;
}
+
+/* Define how to find the value returned by a function. */
+
+rtx arm_function_value(tree type, tree func ATTRIBUTE_UNUSED)
+{
+ enum machine_mode mode;
+ int unsignedp ATTRIBUTE_UNUSED;
+ rtx r ATTRIBUTE_UNUSED;
+
+
+ mode = TYPE_MODE (type);
+ /* Promote integer types. */
+ if (INTEGRAL_TYPE_P (type))
+ PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
+ return LIBCALL_VALUE(mode);
+}
+
+
/* Decide whether a type should be returned in memory (true)
or in a register (false). This is called by the macro
RETURN_IN_MEMORY. */
@@ -14330,6 +14356,16 @@ arm_no_early_mul_dep (rtx producer, rtx
}
+/* We can't rely on the caller doing the proper promotion when
+ using APCS or ATPCS. */
+
+static bool
+arm_promote_prototypes (tree t ATTRIBUTE_UNUSED)
+{
+ return TARGET_AAPCS_BASED;
+}
+
+
/* AAPCS requires that anonymous bitfields affect structure alignment. */
static bool
Index: config/arm/arm.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.210.2.30
diff -u -p -r1.210.2.30 arm.h
--- a/config/arm/arm.h 15 May 2004 13:02:09 -0000 1.210.2.30
+++ b/config/arm/arm.h 17 May 2004 15:32:30 -0000
@@ -587,6 +587,11 @@ extern int arm_is_6_or_7;
/* This is required to ensure that push insns always push a word. */
#define PROMOTE_FUNCTION_ARGS
+#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
+ if (GET_MODE_CLASS (MODE) == MODE_INT \
+ && GET_MODE_SIZE (MODE) < 4) \
+ (MODE) = SImode; \
+
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */
#define BITS_BIG_ENDIAN 0
@@ -1557,7 +1562,7 @@ enum reg_class
If the precise function being called is known, FUNC is its FUNCTION_DECL;
otherwise, FUNC is 0. */
#define FUNCTION_VALUE(VALTYPE, FUNC) \
- LIBCALL_VALUE (TYPE_MODE (VALTYPE))
+ arm_function_value (VALTYPE, FUNC);
/* 1 if N is a possible register number for a function value.
On the ARM, only r0 and f0 can return results. */
@@ -2279,9 +2284,6 @@ do { \
/* Calling from registers is a massive pain. */
#define NO_FUNCTION_CSE 1
-/* Chars and shorts should be passed as ints. */
-#define PROMOTE_PROTOTYPES 1
-
/* The machine modes of pointers and functions */
#define Pmode SImode
#define FUNCTION_MODE Pmode
Index: config/cris/cris.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/cris/cris.h,v
retrieving revision 1.58.4.2
diff -u -p -r1.58.4.2 cris.h
--- a/config/cris/cris.h 9 Apr 2004 13:40:24 -0000 1.58.4.2
+++ b/config/cris/cris.h 13 May 2004 11:59:56 -0000
@@ -511,13 +511,13 @@ extern int target_flags;
#define UNITS_PER_WORD 4
/* A combination of defining PROMOTE_MODE, PROMOTE_FUNCTION_ARGS,
- PROMOTE_FOR_CALL_ONLY and *not* defining PROMOTE_PROTOTYPES gives the
+ and *not* defining PROMOTE_PROTOTYPES or PROMOTE_MODE gives the
best code size and speed for gcc, ipps and products in gcc-2.7.2. */
#define CRIS_PROMOTED_MODE(MODE, UNSIGNEDP, TYPE) \
(GET_MODE_CLASS (MODE) == MODE_INT && GET_MODE_SIZE (MODE) < 4) \
? SImode : MODE
-#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
+#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
(MODE) = CRIS_PROMOTED_MODE (MODE, UNSIGNEDP, TYPE)
#define PROMOTE_FUNCTION_ARGS
@@ -528,7 +528,6 @@ extern int target_flags;
FIXME: Report this when cris.h is part of GCC, so others can easily
see the problem. Maybe check other systems that define
PROMOTE_FUNCTION_RETURN. */
-#define PROMOTE_FOR_CALL_ONLY
/* We will be using prototype promotion, so they will be 32 bit. */
#define PARM_BOUNDARY 32
Index: config/mmix/mmix.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/mmix/mmix.h,v
retrieving revision 1.58.8.1
diff -u -p -r1.58.8.1 mmix.h
--- a/config/mmix/mmix.h 9 Apr 2004 13:40:46 -0000 1.58.8.1
+++ b/config/mmix/mmix.h 13 May 2004 11:59:56 -0000
@@ -280,8 +280,10 @@ extern int target_flags;
/* FIXME: Promotion of modes currently generates slow code, extending
before every operation. */
+/* I'm a little bit undecided about this one. It might be beneficial to
+ promote all operations. */
-#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
+#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
do { \
if (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < 8) \
@@ -301,10 +303,6 @@ extern int target_flags;
#define PROMOTE_FUNCTION_RETURN
#endif
-/* I'm a little bit undecided about this one. It might be beneficial to
- promote all operations. */
-#define PROMOTE_FOR_CALL_ONLY
-
/* We need to align everything to 64 bits that can affect the alignment
of other types. Since address N is interpreted in MMIX as (N modulo
access_size), we must align. */
Index: config/s390/s390.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/s390/s390.h,v
retrieving revision 1.88.4.3
diff -u -p -r1.88.4.3 s390.h
--- a/config/s390/s390.h 9 Apr 2004 13:40:59 -0000 1.88.4.3
+++ b/config/s390/s390.h 13 May 2004 11:59:56 -0000
@@ -210,9 +210,8 @@ extern int target_flags;
/* Function arguments and return values are promoted to word size. */
#define PROMOTE_FUNCTION_ARGS
#define PROMOTE_FUNCTION_RETURN
-#define PROMOTE_FOR_CALL_ONLY
-#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
+#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
if (INTEGRAL_MODE_P (MODE) && \
GET_MODE_SIZE (MODE) < UNITS_PER_WORD) { \
(MODE) = Pmode; \
Index: config/sparc/sparc.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/sparc/sparc.h,v
retrieving revision 1.235.4.3
diff -u -p -r1.235.4.3 sparc.h
--- a/config/sparc/sparc.h 9 Apr 2004 13:41:06 -0000 1.235.4.3
+++ b/config/sparc/sparc.h 13 May 2004 11:59:56 -0000
@@ -744,44 +744,26 @@ extern struct sparc_cpu_select sparc_sel
if ptr_mode and Pmode are the same. */
#define POINTERS_EXTEND_UNSIGNED 1
-/* A macro to update MODE and UNSIGNEDP when an object whose type
- is TYPE and which has the specified mode and signedness is to be
- stored in a register. This macro is only called when TYPE is a
- scalar type. */
-#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
+/* For TARGET_ARCH64 we need this, as we don't have instructions
+ for arithmetic operations which do zero/sign extension at the same time,
+ so without this we end up with a srl/sra after every assignment to an
+ user variable, which means very very bad code. */
+#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
if (TARGET_ARCH64 \
&& GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
(MODE) = DImode;
-/* Define this macro if the promotion described by PROMOTE_MODE
- should also be done for outgoing function arguments. */
-/* This is only needed for TARGET_ARCH64, but since PROMOTE_MODE is a no-op
- for TARGET_ARCH32 this is ok. Otherwise we'd need to add a runtime test
- for this value. */
+/* This is only needed for TARGET_ARCH64, but since PROMOTE_FUNCTION_MODE is
+ a no-op for TARGET_ARCH32 this is ok. Otherwise we'd need to add a
+ runtime test for this value. */
#define PROMOTE_FUNCTION_ARGS
-/* Define this macro if the promotion described by PROMOTE_MODE
- should also be done for the return value of functions.
- If this macro is defined, FUNCTION_VALUE must perform the same
- promotions done by PROMOTE_MODE. */
-/* This is only needed for TARGET_ARCH64, but since PROMOTE_MODE is a no-op
- for TARGET_ARCH32 this is ok. Otherwise we'd need to add a runtime test
- for this value. */
+/* This is only needed for TARGET_ARCH64, but since PROMOTE_FUNCTION_MODE is
+ a no-op for TARGET_ARCH32 this is ok. Otherwise we'd need to add a
+ runtime test for this value. */
#define PROMOTE_FUNCTION_RETURN
-/* Define this macro if the promotion described by PROMOTE_MODE
- should _only_ be performed for outgoing function arguments or
- function return values, as specified by PROMOTE_FUNCTION_ARGS
- and PROMOTE_FUNCTION_RETURN, respectively. */
-/* This is only needed for TARGET_ARCH64, but since PROMOTE_MODE is a no-op
- for TARGET_ARCH32 this is ok. Otherwise we'd need to add a runtime test
- for this value. For TARGET_ARCH64 we need it, as we don't have instructions
- for arithmetic operations which do zero/sign extension at the same time,
- so without this we end up with a srl/sra after every assignment to an
- user variable, which means very very bad code. */
-#define PROMOTE_FOR_CALL_ONLY
-
/* Allocation boundary (in *bits*) for storing arguments in argument list. */
#define PARM_BOUNDARY (TARGET_ARCH64 ? 64 : 32)
Index: doc/tm.texi
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/doc/tm.texi,v
retrieving revision 1.264.2.5
diff -u -p -r1.264.2.5 tm.texi
--- a/doc/tm.texi 14 May 2004 13:23:53 -0000 1.264.2.5
+++ b/doc/tm.texi 17 May 2004 15:32:33 -0000
@@ -1059,27 +1059,29 @@ sign-extend the result to 64 bits. On s
Do not define this macro if it would never modify @var{m}.
@end defmac
+@defmac PROMOTE_FUNCTION_MODE
+Like @code{PROMOTE_MODE}, but is applied to outgoing function arguments or
+function return values, as specified by @code{TARGET_PROMOTE_FUNCTION_ARGS}
+and @code{TARGET_PROMOTE_FUNCTION_RETURN}, respectively.
+
+The default is @code{PROMOTE_MODE}.
+@end defmac
+
@deftypefn {Target Hook} bool TARGET_PROMOTE_FUNCTION_ARGS (tree @var{fntype})
This target hook should return @code{true} if the promotion described by
-@code{PROMOTE_MODE} should also be done for outgoing function arguments.
+@code{PROMOTE_FUNCTION_MODE} should be done for outgoing function
+arguments.
@end deftypefn
@deftypefn {Target Hook} bool TARGET_PROMOTE_FUNCTION_RETURN (tree @var{fntype})
This target hook should return @code{true} if the promotion described by
-@code{PROMOTE_MODE} should also be done for the return value of
+@code{PROMOTE_FUNCTION_MODE} should be done for the return value of
functions.
If this target hook returns @code{true}, @code{FUNCTION_VALUE} must
-perform the same promotions done by @code{PROMOTE_MODE}.
+perform the same promotions done by @code{PROMOTE_FUNCTION_MODE}.
@end deftypefn
-@defmac PROMOTE_FOR_CALL_ONLY
-Define this macro if the promotion described by @code{PROMOTE_MODE}
-should @emph{only} be performed for outgoing function arguments or
-function return values, as specified by @code{TARGET_PROMOTE_FUNCTION_ARGS}
-and @code{TARGET_PROMOTE_FUNCTION_RETURN}, respectively.
-@end defmac
-
@defmac PARM_BOUNDARY
Normal alignment required for function parameters on the stack, in
bits. All stack parameters receive at least this much alignment