+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
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
#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
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. */
(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
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. */
#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
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
/* 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) \
} \
} 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. */
#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; \
#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
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)
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
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)
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