summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4>2004-04-08 18:26:09 +0000
committerpbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4>2004-04-08 18:26:09 +0000
commit1934732785c2b3f204ef475da4aca96231152b79 (patch)
tree975bc90ebcfbd9e00b4fc643af4ffb7ff6029bf9
parent2440d8dd25f6284415b1ed2e6cbd908748f0de79 (diff)
downloadgcc-1934732785c2b3f204ef475da4aca96231152b79.tar.gz
* explow.c (promote_mode): Use PROMOTE_FUNCTION_MODE instead of
PROMOTE_FOR_CALL_ONLY. * config/arm/arm-protos.h (arm_function_value): Declare. * config/arm/arm.h (TARGET_PROMOTE_FUNCTION_ARGS): Define. (TARGET_PROMOTE_PROTOTYPES): Return false. (arm_function_value): New function. * config/arm/arm.h (PROMOTE_FUNCTION_MODE): Define. (FUNCTION_VALUE): Call arm_function_value. * config/cris/cris.h (PROMOTE_MODE): Rename ... (PROMOTE_FUNCTION_MODE): ... to this. (PROMOTE_FOR_CALL_ONLY): Remove. * config/mmix/mmix.h: Likewise. * config/s390/s390.h: Likewise. * config/sparc/sparc.h: Likewise. * config/sparc/sparc.c: Update comments about PROMOTE_MODE. * doc/tm.texi (PROMOTE_FUNCTION_MODE): Document. (TARGET_PROMOTE_FUNCTION_MODE, TARGET_PROMOTE_FUNCTION_RETURN): Update. (PROMOTE_FOR_CALL_ONLY): Remove. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@80518 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c22
-rw-r--r--gcc/config/arm/arm.h7
-rw-r--r--gcc/config/cris/cris.h9
-rw-r--r--gcc/config/mmix/mmix.h8
-rw-r--r--gcc/config/s390/s390.h4
-rw-r--r--gcc/config/sparc/sparc.c17
-rw-r--r--gcc/config/sparc/sparc.h18
-rw-r--r--gcc/doc/tm.texi22
-rw-r--r--gcc/explow.c21
11 files changed, 98 insertions, 52 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ac6a4119438..231b9e76e70 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2004-04-08 Paul Brook <paul@codesourcery.com>
+
+ * explow.c (promote_mode): Use PROMOTE_FUNCTION_MODE instead of
+ PROMOTE_FOR_CALL_ONLY.
+ * config/arm/arm-protos.h (arm_function_value): Declare.
+ * config/arm/arm.h (TARGET_PROMOTE_FUNCTION_ARGS): Define.
+ (TARGET_PROMOTE_PROTOTYPES): Return false.
+ (arm_function_value): New function.
+ * config/arm/arm.h (PROMOTE_FUNCTION_MODE): Define.
+ (FUNCTION_VALUE): Call arm_function_value.
+ * config/cris/cris.h (PROMOTE_MODE): Rename ...
+ (PROMOTE_FUNCTION_MODE): ... to this.
+ (PROMOTE_FOR_CALL_ONLY): Remove.
+ * config/mmix/mmix.h: Likewise.
+ * config/s390/s390.h: Likewise.
+ * config/sparc/sparc.h: Likewise.
+ * config/sparc/sparc.c: Update comments about PROMOTE_MODE.
+ * doc/tm.texi (PROMOTE_FUNCTION_MODE): Document.
+ (TARGET_PROMOTE_FUNCTION_MODE, TARGET_PROMOTE_FUNCTION_RETURN): Update.
+ (PROMOTE_FOR_CALL_ONLY): Remove.
+
2004-04-08 Joel Sherrill <joel@oarcorp.com>
PR ada/14538
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 437455f452d..0359fe77116 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -159,6 +159,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
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index b16836d5d69..6f340df7a90 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -244,8 +244,10 @@ static void arm_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
#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 hook_bool_tree_true
+#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false
#undef TARGET_STRUCT_VALUE_RTX
#define TARGET_STRUCT_VALUE_RTX arm_struct_value_rtx
@@ -2117,6 +2119,24 @@ arm_canonicalize_comparison (enum rtx_code code, rtx * op1)
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. */
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index fa8b8f9e0a4..0c3f2fe326e 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -798,6 +798,11 @@ extern int arm_is_6_or_7;
(MODE) = SImode; \
}
+#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
@@ -1726,7 +1731,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. */
diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h
index 302484c5268..7b028e062e9 100644
--- a/gcc/config/cris/cris.h
+++ b/gcc/config/cris/cris.h
@@ -511,15 +511,15 @@ extern int target_flags;
#define UNITS_PER_WORD 4
-/* A combination of defining PROMOTE_MODE,
- TARGET_PROMOTE_FUNCTION_ARGS that always returns true,
- PROMOTE_FOR_CALL_ONLY and *not* defining TARGET_PROMOTE_PROTOTYPES gives the
+/* A combination of defining PROMOTE_FUNCTION_MODE,
+ TARGET_PROMOTE_FUNCTION_ARGS that always returns true
+ and *not* defining TARGET_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)
/* Defining PROMOTE_FUNCTION_RETURN in gcc-2.7.2 uncovers bug 981110 (even
@@ -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
TARGET_PROMOTE_FUNCTION_RETURN that always returns true. */
-#define PROMOTE_FOR_CALL_ONLY
/* We will be using prototype promotion, so they will be 32 bit. */
#define PARM_BOUNDARY 32
diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h
index b4df95d8d46..01090b7771a 100644
--- a/gcc/config/mmix/mmix.h
+++ b/gcc/config/mmix/mmix.h
@@ -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) \
@@ -293,10 +295,6 @@ extern int target_flags;
} \
} while (0)
-/* 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. */
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index f1386a7edcc..3354f45beed 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -208,9 +208,7 @@ extern int target_flags;
#define MAX_BITS_PER_WORD 64
/* Function arguments and return values are promoted to word size. */
-#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; \
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 30b789b9217..76ccb34eade 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -274,20 +274,15 @@ enum processor_type sparc_cpu;
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST hook_int_rtx_0
-/* Return TRUE 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. */
#undef TARGET_PROMOTE_FUNCTION_ARGS
#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
-/* Return TRUE 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. */
#undef TARGET_PROMOTE_FUNCTION_RETURN
#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 58eb4c8e3c3..33c1256e805 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -712,24 +712,16 @@ extern struct sparc_cpu_select sparc_select[];
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) = word_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. 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)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index e8b6d9dacfd..b2fe858a013 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1071,27 +1071,29 @@ sign-extend the result to 64 bits. On such machines, set
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_FUNCTON_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
diff --git a/gcc/explow.c b/gcc/explow.c
index 1eec943eb26..1629fa85582 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -799,6 +799,10 @@ copy_to_suggested_reg (rtx x, rtx target, enum machine_mode mode)
FOR_CALL is nonzero if this call is promoting args for a call. */
+#if defined(PROMOTE_MODE) && !defined(PROMOTE_FUNCTION_MODE)
+#define PROMOTE_FUNCTON_MODE PROMOTE_MODE
+#endif
+
enum machine_mode
promote_mode (tree type, enum machine_mode mode, int *punsignedp,
int for_call ATTRIBUTE_UNUSED)
@@ -806,17 +810,28 @@ promote_mode (tree type, enum machine_mode mode, int *punsignedp,
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