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
This commit is contained in:
parent
c00e272ed3
commit
d4453b7ac5
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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; \
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
21
gcc/explow.c
21
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue