+Thu Feb 25 21:52:54 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.h (PASS_IN_REG_P): For TARGET_HITACHI, don't pass structures
+ in registers.
+
+ * expr.h (PRETEND_OUTGOING_VARARGS_NAMED): Provide default definition.
+ * function.c (assign_parms): Honour PRETEND_OUTGOING_VARARGS_NAMED.
+ * calls.c (expand_call): Likewise.
+
+ * sh.c (sh_expand_prologue): For TARGET_HITACHI, don't push varargs /
+ stdarg arguments.
+ * sh.h (CPP_SPEC): Add -D__HITACHI__ for -mhitachi.
+ (FUNCTION_ARG): For TARGET_HITACHI, don't pass unnamed
+ arguments in registers.
+ (PRETEND_OUTGOING_VARARGS_NAMED): Define.
+ * va-sh.h (entire file): If __HITACHI__ is defined, use sh[123]
+ flavour varargs.
+
Thu Feb 25 14:32:40 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* cse.c (dump_class): Revert last change and make the prototype
(If no anonymous args follow, the result of list_length is actually
one too large. This is harmless.)
- If SETUP_INCOMING_VARARGS is defined and STRICT_ARGUMENT_NAMING is zero,
- this machine will be able to place unnamed args that were passed in
+ If PRETEND_OUTGOING_VARARGS_NAMED is set and STRICT_ARGUMENT_NAMING is
+ zero, this machine will be able to place unnamed args that were passed in
registers into the stack. So treat all args as named. This allows the
insns emitting for a specific argument list to be independent of the
function declaration.
- If SETUP_INCOMING_VARARGS is not defined, we do not have any reliable
+ If PRETEND_OUTGOING_VARARGS_NAMED is not set, we do not have any reliable
way to pass unnamed args in registers, so we must force them into
memory. */
if ((STRICT_ARGUMENT_NAMING
-#ifndef SETUP_INCOMING_VARARGS
- || 1
-#endif
- )
+ || ! PRETEND_OUTGOING_VARARGS_NAMED)
&& TYPE_ARG_TYPES (funtype) != 0)
n_named_args
= (list_length (TYPE_ARG_TYPES (funtype))
current_function_anonymous_args = 0;
/* This is not used by the SH3E calling convention */
- if (!TARGET_SH3E)
+ if (! TARGET_SH3E && ! TARGET_HITACHI)
{
/* Push arg regs as if they'd been provided by caller in stack. */
for (i = 0; i < NPARM_REGS(SImode); i++)
%{m4-single-only:-D__SH4_SINGLE_ONLY__} \
%{m4-single:-D__SH4_SINGLE__} \
%{m4:-D__SH4__} \
-%{!m1:%{!m2:%{!m3:%{!m3e:%{!m4:%{!m4-single:%{!m4-single-only:-D__sh1__}}}}}}}"
+%{!m1:%{!m2:%{!m3:%{!m3e:%{!m4:%{!m4-single:%{!m4-single-only:-D__sh1__}}}}}}} \
+%{mhitachi:-D__HITACHI__}"
#define CPP_PREDEFINES "-D__sh__ -Acpu(sh) -Amachine(sh)"
This macro is only used in this file. */
#define PASS_IN_REG_P(CUM, MODE, TYPE) \
- (((TYPE) == 0 || ! TREE_ADDRESSABLE ((tree)(TYPE))) \
+ (((TYPE) == 0 \
+ || (! TREE_ADDRESSABLE ((tree)(TYPE))) \
+ && (! TARGET_HITACHI || ! AGGREGATE_TYPE_P (TYPE))) \
&& (TARGET_SH3E \
? ((MODE) == BLKmode \
? (((CUM).arg_count[(int) SH_ARG_INT] * UNITS_PER_WORD \
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
((PASS_IN_REG_P ((CUM), (MODE), (TYPE)) \
- && ((NAMED) || TARGET_SH3E || ! current_function_varargs)) \
+ && ((NAMED) \
+ || (! TARGET_HITACHI && (TARGET_SH3E || ! current_function_varargs)))) \
? gen_rtx (REG, (MODE), \
((BASE_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))) \
^ ((MODE) == SFmode && TARGET_SH4 \
&& TARGET_LITTLE_ENDIAN != 0))) \
: 0)
+#define PRETEND_OUTGOING_VARARGS_NAMED (! TARGET_HITACHI)
+
/* For an arg passed partly in registers and partly in memory,
this is the number of registers used.
For args passed entirely in registers or entirely in memory, zero.
#define STRICT_ARGUMENT_NAMING 0
#endif
+/* Provide a default value for PRETEND_OUTGOING_VARARGS_NAMED. */
+#ifdef SETUP_INCOMING_VARARGS
+#ifndef PRETEND_OUTGOING_VARARGS_NAMED
+#define PRETEND_OUTGOING_VARARGS_NAMED 1
+#endif
+#else
+/* It is an error to define PRETEND_OUTGOING_VARARGS_NAMED without
+ defining SETUP_INCOMING_VARARGS. */
+#define PRETEND_OUTGOING_VARARGS_NAMED 0
+#endif
+
/* Nonzero if we do not know how to pass TYPE solely in registers.
We cannot do so in the following cases:
int did_conversion = 0;
tree passed_type = DECL_ARG_TYPE (parm);
tree nominal_type = TREE_TYPE (parm);
+ int pretend_named;
/* Set LAST_NAMED if this is last named arg before some
anonymous args. */
In this case, we call FUNCTION_ARG with NAMED set to 1 instead of
0 as it was the previous time. */
+ pretend_named = named_arg || PRETEND_OUTGOING_VARARGS_NAMED;
locate_and_pad_parm (nominal_mode, passed_type,
#ifdef STACK_PARMS_IN_REG_PARM_AREA
1,
#ifdef FUNCTION_INCOMING_ARG
FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
passed_type,
- (named_arg
- || varargs_setup)) != 0,
+ pretend_named) != 0,
#else
FUNCTION_ARG (args_so_far, promoted_mode,
passed_type,
- named_arg || varargs_setup) != 0,
+ pretend_named) != 0,
#endif
#endif
fndecl, &stack_args_size, &stack_offset, &arg_size);
-/* This is just like the default gvarargs.h
- except for differences described below. */
+/* The ! __SH3E_VARG case is similar to the default gvarargs.h . */
+
+#if (defined (__SH3E__) || defined (__SH4_SINGLE__) || defined (__SH4__) || defined (__SH4_SINGLE_ONLY__)) && ! defined (__HITACHI__)
+#define __SH3E_VARG
+#endif
/* Define __gnuc_va_list. */
#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST
-#if defined (__SH3E__) || defined (__SH4_SINGLE__) || defined (__SH4__) || defined (__SH4_SINGLE_ONLY__)
+#ifdef __SH3E_VARG
typedef long __va_greg;
typedef float __va_freg;
#ifdef _STDARG_H
-#if defined (__SH3E__) || defined (__SH4_SINGLE__) || defined (__SH4__) || defined (__SH4_SINGLE_ONLY__)
+#ifdef __SH3E_VARG
#define va_start(AP, LASTARG) \
__extension__ \
#define va_alist __builtin_va_alist
#define va_dcl int __builtin_va_alist;...
-#if defined (__SH3E__) || defined (__SH4_SINGLE__) || defined (__SH4__) || defined (__SH4_SINGLE_ONLY__)
+#ifdef __SH3E_VARG
#define va_start(AP) \
__extension__ \
? (((union { TYPE t; int i;} *__VA_REF) (AP))++)->t \
: ((union {TYPE t;TYPE u;}*) ((char *)++(int *__VA_REF)(AP) - sizeof (TYPE)))->t);})
-#if defined (__SH3E__) || defined (__SH4_SINGLE__) || defined (__SH4__) || defined (__SH4_SINGLE_ONLY__)
+#ifdef __SH3E_VARG
#define __PASS_AS_FLOAT(TYPE_CLASS,SIZE) \
(TYPE_CLASS == __real_type_class && SIZE == 4)
are treated as named.
You need not define this macro if it always returns zero.
+
+@findex PRETEND_OUTGOING_VARARGS_NAMED
+@item PRETEND_OUTGOING_VARARGS_NAMED
+If you need to conditionally change ABIs so that one works with
+@code{SETUP_INCOMING_VARARGS}, but the other works like neither
+@code{SETUP_INCOMING_VARARGS} nor @code{STRICT_ARGUMENT_NAMING} was
+defined, then define this macro to return nonzero if
+@code{SETUP_INCOMING_VARARGS} is used, zero otherwise.
+Otherwise, you should not define this macro.
@end table
@node Trampolines