Commit d4453b7a by Paul Brook Committed by Paul Brook

explow.c (promote_mode): Use PROMOTE_FUNCTION_MODE instead of PROMOTE_FOR_CALL_ONLY.

	* 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.

From-SVN: r80518
parent c00e272e
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> 2004-04-08 Joel Sherrill <joel@oarcorp.com>
PR ada/14538 PR ada/14538
......
...@@ -159,6 +159,7 @@ extern rtx arm_va_arg (tree, tree); ...@@ -159,6 +159,7 @@ extern rtx arm_va_arg (tree, tree);
extern int arm_function_arg_pass_by_reference (CUMULATIVE_ARGS *, extern int arm_function_arg_pass_by_reference (CUMULATIVE_ARGS *,
enum machine_mode, tree, int); enum machine_mode, tree, int);
extern bool arm_needs_doubleword_align (enum machine_mode, tree); extern bool arm_needs_doubleword_align (enum machine_mode, tree);
extern rtx arm_function_value(tree, tree);
#endif #endif
#if defined AOF_ASSEMBLER #if defined AOF_ASSEMBLER
......
...@@ -244,8 +244,10 @@ static void arm_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, ...@@ -244,8 +244,10 @@ static void arm_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
#undef TARGET_PROMOTE_FUNCTION_ARGS #undef TARGET_PROMOTE_FUNCTION_ARGS
#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true #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 #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 #undef TARGET_STRUCT_VALUE_RTX
#define TARGET_STRUCT_VALUE_RTX arm_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) ...@@ -2117,6 +2119,24 @@ arm_canonicalize_comparison (enum rtx_code code, rtx * op1)
return code; 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) /* Decide whether a type should be returned in memory (true)
or in a register (false). This is called by the macro or in a register (false). This is called by the macro
RETURN_IN_MEMORY. */ RETURN_IN_MEMORY. */
......
...@@ -798,6 +798,11 @@ extern int arm_is_6_or_7; ...@@ -798,6 +798,11 @@ extern int arm_is_6_or_7;
(MODE) = SImode; \ (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 /* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */ in instructions that operate on numbered bit-fields. */
#define BITS_BIG_ENDIAN 0 #define BITS_BIG_ENDIAN 0
...@@ -1726,7 +1731,7 @@ enum reg_class ...@@ -1726,7 +1731,7 @@ enum reg_class
If the precise function being called is known, FUNC is its FUNCTION_DECL; If the precise function being called is known, FUNC is its FUNCTION_DECL;
otherwise, FUNC is 0. */ otherwise, FUNC is 0. */
#define FUNCTION_VALUE(VALTYPE, FUNC) \ #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. /* 1 if N is a possible register number for a function value.
On the ARM, only r0 and f0 can return results. */ On the ARM, only r0 and f0 can return results. */
......
...@@ -511,15 +511,15 @@ extern int target_flags; ...@@ -511,15 +511,15 @@ extern int target_flags;
#define UNITS_PER_WORD 4 #define UNITS_PER_WORD 4
/* A combination of defining PROMOTE_MODE, /* A combination of defining PROMOTE_FUNCTION_MODE,
TARGET_PROMOTE_FUNCTION_ARGS that always returns true, TARGET_PROMOTE_FUNCTION_ARGS that always returns true
PROMOTE_FOR_CALL_ONLY and *not* defining TARGET_PROMOTE_PROTOTYPES gives the 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. */ best code size and speed for gcc, ipps and products in gcc-2.7.2. */
#define CRIS_PROMOTED_MODE(MODE, UNSIGNEDP, TYPE) \ #define CRIS_PROMOTED_MODE(MODE, UNSIGNEDP, TYPE) \
(GET_MODE_CLASS (MODE) == MODE_INT && GET_MODE_SIZE (MODE) < 4) \ (GET_MODE_CLASS (MODE) == MODE_INT && GET_MODE_SIZE (MODE) < 4) \
? SImode : MODE ? SImode : MODE
#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ #define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
(MODE) = CRIS_PROMOTED_MODE (MODE, UNSIGNEDP, TYPE) (MODE) = CRIS_PROMOTED_MODE (MODE, UNSIGNEDP, TYPE)
/* Defining PROMOTE_FUNCTION_RETURN in gcc-2.7.2 uncovers bug 981110 (even /* Defining PROMOTE_FUNCTION_RETURN in gcc-2.7.2 uncovers bug 981110 (even
...@@ -528,7 +528,6 @@ extern int target_flags; ...@@ -528,7 +528,6 @@ extern int target_flags;
FIXME: Report this when cris.h is part of GCC, so others can easily FIXME: Report this when cris.h is part of GCC, so others can easily
see the problem. Maybe check other systems that define see the problem. Maybe check other systems that define
TARGET_PROMOTE_FUNCTION_RETURN that always returns true. */ 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. */ /* We will be using prototype promotion, so they will be 32 bit. */
#define PARM_BOUNDARY 32 #define PARM_BOUNDARY 32
......
...@@ -280,8 +280,10 @@ extern int target_flags; ...@@ -280,8 +280,10 @@ extern int target_flags;
/* FIXME: Promotion of modes currently generates slow code, extending /* FIXME: Promotion of modes currently generates slow code, extending
before every operation. */ 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 { \ do { \
if (GET_MODE_CLASS (MODE) == MODE_INT \ if (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < 8) \ && GET_MODE_SIZE (MODE) < 8) \
...@@ -293,10 +295,6 @@ extern int target_flags; ...@@ -293,10 +295,6 @@ extern int target_flags;
} \ } \
} while (0) } 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 /* 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 of other types. Since address N is interpreted in MMIX as (N modulo
access_size), we must align. */ access_size), we must align. */
......
...@@ -208,9 +208,7 @@ extern int target_flags; ...@@ -208,9 +208,7 @@ extern int target_flags;
#define MAX_BITS_PER_WORD 64 #define MAX_BITS_PER_WORD 64
/* Function arguments and return values are promoted to word size. */ /* Function arguments and return values are promoted to word size. */
#define PROMOTE_FOR_CALL_ONLY #define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
if (INTEGRAL_MODE_P (MODE) && \ if (INTEGRAL_MODE_P (MODE) && \
GET_MODE_SIZE (MODE) < UNITS_PER_WORD) { \ GET_MODE_SIZE (MODE) < UNITS_PER_WORD) { \
(MODE) = Pmode; \ (MODE) = Pmode; \
......
...@@ -274,20 +274,15 @@ enum processor_type sparc_cpu; ...@@ -274,20 +274,15 @@ enum processor_type sparc_cpu;
#undef TARGET_ADDRESS_COST #undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST hook_int_rtx_0 #define TARGET_ADDRESS_COST hook_int_rtx_0
/* Return TRUE if the promotion described by PROMOTE_MODE should also be done /* This is only needed for TARGET_ARCH64, but since PROMOTE_FUNCTION_MODE is a
for outgoing function arguments. no-op for TARGET_ARCH32 this is ok. Otherwise we'd need to add a runtime
This is only needed for TARGET_ARCH64, but since PROMOTE_MODE is a no-op test for this value. */
for TARGET_ARCH32 this is ok. Otherwise we'd need to add a runtime test
for this value. */
#undef TARGET_PROMOTE_FUNCTION_ARGS #undef TARGET_PROMOTE_FUNCTION_ARGS
#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
/* Return TRUE if the promotion described by PROMOTE_MODE should also be done /* This is only needed for TARGET_ARCH64, but since PROMOTE_FUNCTION_MODE is a
for the return value of functions. If this macro is defined, FUNCTION_VALUE no-op for TARGET_ARCH32 this is ok. Otherwise we'd need to add a runtime
must perform the same promotions done by PROMOTE_MODE. test for this value. */
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. */
#undef TARGET_PROMOTE_FUNCTION_RETURN #undef TARGET_PROMOTE_FUNCTION_RETURN
#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
......
...@@ -712,24 +712,16 @@ extern struct sparc_cpu_select sparc_select[]; ...@@ -712,24 +712,16 @@ extern struct sparc_cpu_select sparc_select[];
if ptr_mode and Pmode are the same. */ if ptr_mode and Pmode are the same. */
#define POINTERS_EXTEND_UNSIGNED 1 #define POINTERS_EXTEND_UNSIGNED 1
/* A macro to update MODE and UNSIGNEDP when an object whose type /* For TARGET_ARCH64 we need this, as we don't have instructions
is TYPE and which has the specified mode and signedness is to be for arithmetic operations which do zero/sign extension at the same time,
stored in a register. This macro is only called when TYPE is a so without this we end up with a srl/sra after every assignment to an
scalar type. */ user variable, which means very very bad code. */
#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ #define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
if (TARGET_ARCH64 \ if (TARGET_ARCH64 \
&& GET_MODE_CLASS (MODE) == MODE_INT \ && GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \ && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
(MODE) = word_mode; (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. */ /* Allocation boundary (in *bits*) for storing arguments in argument list. */
#define PARM_BOUNDARY (TARGET_ARCH64 ? 64 : 32) #define PARM_BOUNDARY (TARGET_ARCH64 ? 64 : 32)
......
...@@ -1071,27 +1071,29 @@ sign-extend the result to 64 bits. On such machines, set ...@@ -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}. Do not define this macro if it would never modify @var{m}.
@end defmac @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}) @deftypefn {Target Hook} bool TARGET_PROMOTE_FUNCTION_ARGS (tree @var{fntype})
This target hook should return @code{true} if the promotion described by 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 @end deftypefn
@deftypefn {Target Hook} bool TARGET_PROMOTE_FUNCTION_RETURN (tree @var{fntype}) @deftypefn {Target Hook} bool TARGET_PROMOTE_FUNCTION_RETURN (tree @var{fntype})
This target hook should return @code{true} if the promotion described by 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. functions.
If this target hook returns @code{true}, @code{FUNCTION_VALUE} must 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 @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 @defmac PARM_BOUNDARY
Normal alignment required for function parameters on the stack, in Normal alignment required for function parameters on the stack, in
bits. All stack parameters receive at least this much alignment bits. All stack parameters receive at least this much alignment
......
...@@ -799,6 +799,10 @@ copy_to_suggested_reg (rtx x, rtx target, enum machine_mode mode) ...@@ -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. */ 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 enum machine_mode
promote_mode (tree type, enum machine_mode mode, int *punsignedp, promote_mode (tree type, enum machine_mode mode, int *punsignedp,
int for_call ATTRIBUTE_UNUSED) int for_call ATTRIBUTE_UNUSED)
...@@ -806,17 +810,28 @@ promote_mode (tree type, enum machine_mode mode, int *punsignedp, ...@@ -806,17 +810,28 @@ promote_mode (tree type, enum machine_mode mode, int *punsignedp,
enum tree_code code = TREE_CODE (type); enum tree_code code = TREE_CODE (type);
int unsignedp = *punsignedp; int unsignedp = *punsignedp;
#ifdef PROMOTE_FOR_CALL_ONLY #ifndef PROMOTE_MODE
if (! for_call) if (! for_call)
return mode; return mode;
#endif #endif
switch (code) switch (code)
{ {
#ifdef PROMOTE_MODE #ifdef PROMOTE_FUNCTION_MODE
case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
case CHAR_TYPE: case REAL_TYPE: case OFFSET_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; break;
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment