From: Paul Brook Date: Thu, 8 Apr 2004 18:26:09 +0000 (+0000) Subject: explow.c (promote_mode): Use PROMOTE_FUNCTION_MODE instead of PROMOTE_FOR_CALL_ONLY. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d4453b7ac50559127a64a0ee001918a8456cba54;p=gcc.git 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 --- 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 + + * 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 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