From: amylaar Date: Thu, 25 Feb 1999 14:02:32 +0000 (+0000) Subject: * sh.h (PASS_IN_REG_P): For TARGET_HITACHI, don't pass structures X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8b8232043f053ecbe1c8d70f0af39dc1b5f1b558;p=platform%2Fupstream%2Flinaro-gcc.git * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@25440 138bc75d-0d04-0410-961f-82ee72b054a4 --- 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 + + * 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 * 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