aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/calls.c11
-rw-r--r--gcc/config/sh/sh.c2
-rw-r--r--gcc/config/sh/sh.h12
-rw-r--r--gcc/expr.h11
-rw-r--r--gcc/function.c7
-rw-r--r--gcc/ginclude/va-sh.h15
-rw-r--r--gcc/tm.texi9
8 files changed, 65 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4df2950..83e85e3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+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
diff --git a/gcc/calls.c b/gcc/calls.c
index b7c4aa1..86a87ff 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1731,21 +1731,18 @@ expand_call (exp, target, ignore)
(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))
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 984fd6f..6ddf439 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -3717,7 +3717,7 @@ sh_expand_prologue ()
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++)
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index db07aae..2541660 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -46,7 +46,8 @@ extern int code_for_indirect_jump_scratch;
%{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)"
@@ -1004,7 +1005,9 @@ struct sh_args {
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 \
@@ -1037,13 +1040,16 @@ extern int current_function_varargs;
#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.
diff --git a/gcc/expr.h b/gcc/expr.h
index 5b32937..e4f709a 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -216,6 +216,17 @@ enum direction {none, upward, downward}; /* Value has this type. */
#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:
diff --git a/gcc/function.c b/gcc/function.c
index 03d1e75..75b47bd 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -4096,6 +4096,7 @@ assign_parms (fndecl, second_time)
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. */
@@ -4217,6 +4218,7 @@ assign_parms (fndecl, second_time)
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,
@@ -4224,12 +4226,11 @@ assign_parms (fndecl, second_time)
#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);
diff --git a/gcc/ginclude/va-sh.h b/gcc/ginclude/va-sh.h
index 0bfc84c..dc4e3ae 100644
--- a/gcc/ginclude/va-sh.h
+++ b/gcc/ginclude/va-sh.h
@@ -1,12 +1,15 @@
-/* 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;
@@ -33,7 +36,7 @@ typedef void *__gnuc_va_list;
#ifdef _STDARG_H
-#if defined (__SH3E__) || defined (__SH4_SINGLE__) || defined (__SH4__) || defined (__SH4_SINGLE_ONLY__)
+#ifdef __SH3E_VARG
#define va_start(AP, LASTARG) \
__extension__ \
@@ -59,7 +62,7 @@ __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__ \
@@ -164,7 +167,7 @@ enum __va_type_classes {
? (((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)
diff --git a/gcc/tm.texi b/gcc/tm.texi
index cd45f74..45e3dee 100644
--- a/gcc/tm.texi
+++ b/gcc/tm.texi
@@ -3789,6 +3789,15 @@ are treated as named. Otherwise, all named arguments except the last
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