diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-02-21 18:58:30 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-02-21 18:58:30 +0000 |
commit | 36970cc69149ef3a3f32d57663a14adedaebcbb9 (patch) | |
tree | a82e8df0bf9a6771c4b27f9f15c5a2844e8f81ea /include | |
parent | 93ccb0356b10af44f620ec035fb76fa8a1165c22 (diff) |
Add an SH port done by Jean-Yves Avenard of Hewlett-Packard - Embedded
and Personal Systems. Thanks!
-Erik
Diffstat (limited to 'include')
-rw-r--r-- | include/stdarg.h | 250 | ||||
-rw-r--r-- | include/sys/syslog.h | 2 | ||||
-rw-r--r-- | include/va-sh.h | 202 |
3 files changed, 407 insertions, 47 deletions
diff --git a/include/stdarg.h b/include/stdarg.h index 321e6646e..24f338319 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -1,47 +1,205 @@ - /* - * @(#) stdarg.h 1.2 91/11/30 21:10:39 - * - * Sample stdarg.h file for use with the unproto filter. - * - * This file serves two purposes. - * - * 1 - As an include file for use with ANSI-style C source that implements - * variadic functions. - * - * 2 - To configure the unproto filter itself. If the _VA_ALIST_ macro is - * defined, its value will appear in the place of the "..." in argument - * lists of variadic function *definitions* (not declarations). - * - * Compilers that pass arguments via the stack can use the default code at the - * end of this file (this usually applies for the VAX, MC68k and 80*86 - * architectures). - * - * RISC-based systems often need special tricks. An example of the latter is - * given for the SPARC architecture. Read your /usr/include/varargs.h for - * more information. - * - * You can use the varargs.c program provided with the unproto package to - * verify that the stdarg.h file has been set up correctly. - */ - -#ifndef __STDARG_H -#define __STDARG_H - -#ifdef sparc -# define _VA_ALIST_ "__builtin_va_alist" - typedef char *va_list; -# define va_start(ap, p) (ap = (char *) &__builtin_va_alist) -# define va_arg(ap, type) ((type *) __builtin_va_arg_incr((type *) ap))[0] -# define va_end(ap) -#else /* vax, mc68k, 80*86 */ - typedef char *va_list; -# define va_start(ap, p) (ap = (char *) (&(p)+1)) -# define va_arg(ap, type) ((type *) (ap += sizeof(type)))[-1] -# define va_end(ap) -#endif - -#endif /* __STDARG_H */ - -#if __FIRST_ARG_IN_AX__ -#error First arg is in a register, stdarg.h cannot take its address +/* stdarg.h for GNU. + Note that the type used in va_arg is supposed to match the + actual type **after default promotions**. + Thus, va_arg (..., short) is not valid. */ + +#ifndef _STDARG_H +#ifndef _ANSI_STDARG_H_ +#ifndef __need___va_list +#define _STDARG_H +#define _ANSI_STDARG_H_ +#endif /* not __need___va_list */ +#undef __need___va_list + +#ifdef __clipper__ +#include "va-clipper.h" +#else +#ifdef __m88k__ +#include "va-m88k.h" +#else +#ifdef __i860__ +#include "va-i860.h" +#else +#ifdef __hppa__ +#include "va-pa.h" +#else +#ifdef __mips__ +#include "va-mips.h" +#else +#ifdef __sparc__ +#include "va-sparc.h" +#else +#ifdef __i960__ +#include "va-i960.h" +#else +#ifdef __alpha__ +#include "va-alpha.h" +#else +#if defined (__H8300__) || defined (__H8300H__) || defined (__H8300S__) +#include "va-h8300.h" +#else +#if defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32)) +#include "va-ppc.h" +#else +#ifdef __arc__ +#include "va-arc.h" +#else +#ifdef __M32R__ +#include "va-m32r.h" +#else +#ifdef __sh__ +#include "va-sh.h" +#else +#ifdef __mn10300__ +#include "va-mn10300.h" +#else +#ifdef __mn10200__ +#include "va-mn10200.h" +#else +#ifdef __v850__ +#include "va-v850.h" +#else + +/* Define __gnuc_va_list. */ + +#ifndef __GNUC_VA_LIST +#define __GNUC_VA_LIST +#if defined(__svr4__) || defined(_AIX) || defined(_M_UNIX) || defined(__NetBSD__) +typedef char *__gnuc_va_list; +#else +typedef void *__gnuc_va_list; +#endif +#endif + +/* Define the standard macros for the user, + if this invocation was from the user program. */ +#ifdef _STDARG_H + +/* Amount of space required in an argument list for an arg of type TYPE. + TYPE may alternatively be an expression whose type is used. */ + +#if defined(sysV68) +#define __va_rounded_size(TYPE) \ + (((sizeof (TYPE) + sizeof (short) - 1) / sizeof (short)) * sizeof (short)) +#else +#define __va_rounded_size(TYPE) \ + (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) #endif + +#define va_start(AP, LASTARG) \ + (AP = ((__gnuc_va_list) __builtin_next_arg (LASTARG))) + +#undef va_end +void va_end (__gnuc_va_list); /* Defined in libgcc.a */ +#define va_end(AP) ((void)0) + +/* We cast to void * and then to TYPE * because this avoids + a warning about increasing the alignment requirement. */ + +#if (defined (__arm__) && ! defined (__ARMEB__)) || defined (__i386__) || defined (__i860__) || defined (__ns32000__) || defined (__vax__) +/* This is for little-endian machines; small args are padded upward. */ +#define va_arg(AP, TYPE) \ + (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \ + *((TYPE *) (void *) ((char *) (AP) - __va_rounded_size (TYPE)))) +#else /* big-endian */ +/* This is for big-endian machines; small args are padded downward. */ +#define va_arg(AP, TYPE) \ + (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \ + *((TYPE *) (void *) ((char *) (AP) \ + - ((sizeof (TYPE) < __va_rounded_size (char) \ + ? sizeof (TYPE) : __va_rounded_size (TYPE)))))) +#endif /* big-endian */ + +/* Copy __gnuc_va_list into another variable of this type. */ +#define __va_copy(dest, src) (dest) = (src) + +#endif /* _STDARG_H */ + +#endif /* not v850 */ +#endif /* not mn10200 */ +#endif /* not mn10300 */ +#endif /* not sh */ +#endif /* not m32r */ +#endif /* not arc */ +#endif /* not powerpc with V.4 calling sequence */ +#endif /* not h8300 */ +#endif /* not alpha */ +#endif /* not i960 */ +#endif /* not sparc */ +#endif /* not mips */ +#endif /* not hppa */ +#endif /* not i860 */ +#endif /* not m88k */ +#endif /* not clipper */ + +#ifdef _STDARG_H +/* Define va_list, if desired, from __gnuc_va_list. */ +/* We deliberately do not define va_list when called from + stdio.h, because ANSI C says that stdio.h is not supposed to define + va_list. stdio.h needs to have access to that data type, + but must not use that name. It should use the name __gnuc_va_list, + which is safe because it is reserved for the implementation. */ + +#ifdef _HIDDEN_VA_LIST /* On OSF1, this means varargs.h is "half-loaded". */ +#undef _VA_LIST +#endif + +#ifdef _BSD_VA_LIST +#undef _BSD_VA_LIST +#endif + +#if defined(__svr4__) || (defined(_SCO_DS) && !defined(__VA_LIST)) +/* SVR4.2 uses _VA_LIST for an internal alias for va_list, + so we must avoid testing it and setting it here. + SVR4 uses _VA_LIST as a flag in stdarg.h, but we should + have no conflict with that. */ +#ifndef _VA_LIST_ +#define _VA_LIST_ +#ifdef __i860__ +#ifndef _VA_LIST +#define _VA_LIST va_list +#endif +#endif /* __i860__ */ +typedef __gnuc_va_list va_list; +#ifdef _SCO_DS +#define __VA_LIST +#endif +#endif /* _VA_LIST_ */ +#else /* not __svr4__ || _SCO_DS */ + +/* The macro _VA_LIST_ is the same thing used by this file in Ultrix. + But on BSD NET2 we must not test or define or undef it. + (Note that the comments in NET 2's ansi.h + are incorrect for _VA_LIST_--see stdio.h!) */ +#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT) +/* The macro _VA_LIST_DEFINED is used in Windows NT 3.5 */ +#ifndef _VA_LIST_DEFINED +/* The macro _VA_LIST is used in SCO Unix 3.2. */ +#ifndef _VA_LIST +/* The macro _VA_LIST_T_H is used in the Bull dpx2 */ +#ifndef _VA_LIST_T_H +typedef __gnuc_va_list va_list; +#endif /* not _VA_LIST_T_H */ +#endif /* not _VA_LIST */ +#endif /* not _VA_LIST_DEFINED */ +#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__)) +#define _VA_LIST_ +#endif +#ifndef _VA_LIST +#define _VA_LIST +#endif +#ifndef _VA_LIST_DEFINED +#define _VA_LIST_DEFINED +#endif +#ifndef _VA_LIST_T_H +#define _VA_LIST_T_H +#endif + +#endif /* not _VA_LIST_, except on certain systems */ + +#endif /* not __svr4__ */ + +#endif /* _STDARG_H */ + +#endif /* not _ANSI_STDARG_H_ */ +#endif /* not _STDARG_H */ diff --git a/include/sys/syslog.h b/include/sys/syslog.h index bfef56bb5..ffdb39bc1 100644 --- a/include/sys/syslog.h +++ b/include/sys/syslog.h @@ -37,7 +37,7 @@ #define _SYS_SYSLOG_H 1 #include <features.h> -#define __need___va_list +// #define __need___va_list #include <stdarg.h> diff --git a/include/va-sh.h b/include/va-sh.h new file mode 100644 index 000000000..d891c171f --- /dev/null +++ b/include/va-sh.h @@ -0,0 +1,202 @@ +/* This is just like the default gvarargs.h + except for differences described below. */ + +/* Define __gnuc_va_list. */ + +#ifndef __GNUC_VA_LIST +#define __GNUC_VA_LIST + +#ifdef __SH3E__ + +typedef long __va_greg; +typedef double __va_freg; + +typedef struct { + __va_greg * __va_next_o; /* next available register */ + __va_greg * __va_next_o_limit; /* past last available register */ + __va_freg * __va_next_fp; /* next available fp register */ + __va_freg * __va_next_fp_limit; /* last available fp register */ + __va_greg * __va_next_stack; /* next extended word on stack */ +} __gnuc_va_list; + +#else /* ! SH3E */ + +typedef void *__gnuc_va_list; + +#endif /* ! SH3E */ + +#endif /* __GNUC_VA_LIST */ + +/* If this is for internal libc use, don't define anything but + __gnuc_va_list. */ +#if defined (_STDARG_H) || defined (_VARARGS_H) + +#ifdef _STDARG_H + +#ifdef __SH3E__ + +#define va_start(AP, LASTARG) \ +__extension__ \ + ({ \ + AP.__va_next_fp = (__va_freg *) __builtin_saveregs (); \ + AP.__va_next_fp_limit = (AP.__va_next_fp + \ + (__builtin_args_info (1) < 8 ? 8 - __builtin_args_info (1) : 0)); \ + AP.__va_next_o = (__va_greg *) AP.__va_next_fp_limit; \ + AP.__va_next_o_limit = (AP.__va_next_o + \ + (__builtin_args_info (0) < 4 ? 4 - __builtin_args_info (0) : 0)); \ + AP.__va_next_stack = (__va_greg *) __builtin_next_arg (LASTARG); \ + }) + +#else /* ! SH3E */ + +#define va_start(AP, LASTARG) \ +do { \ + __builtin_saveregs();\ + (AP = ((__gnuc_va_list) __builtin_next_arg (LASTARG))); \ +} while (0) + +#endif /* ! SH3E */ + +#else /* _VARARGS_H */ + +#define va_alist __builtin_va_alist +#define va_dcl int __builtin_va_alist;... + +#ifdef __SH3E__ + +#define va_start(AP) \ +__extension__ \ + ({ \ + AP.__va_next_fp = (__va_freg *) __builtin_saveregs (); \ + AP.__va_next_fp_limit = (AP.__va_next_fp + \ + (__builtin_args_info (1) < 8 ? 8 - __builtin_args_info (1) : 0)); \ + AP.__va_next_o = (__va_greg *) AP.__va_next_fp_limit; \ + AP.__va_next_o_limit = (AP.__va_next_o + \ + (__builtin_args_info (0) < 4 ? 4 - __builtin_args_info (0) : 0)); \ + AP.__va_next_stack = (__va_greg *) __builtin_next_arg (__builtin_va_alist) \ + - (__builtin_args_info (0) >= 4 || __builtin_args_info (1) >= 8 ? 1 : 0); \ + }) + +#else /* ! SH3E */ + +#define va_start(AP) AP=(char *) &__builtin_va_alist + +#endif /* ! SH3E */ + +#endif /* _STDARG */ + +#ifndef va_end +void va_end (__gnuc_va_list); /* Defined in libgcc.a */ + +/* Values returned by __builtin_classify_type. */ + +enum __va_type_classes { + __no_type_class = -1, + __void_type_class, + __integer_type_class, + __char_type_class, + __enumeral_type_class, + __boolean_type_class, + __pointer_type_class, + __reference_type_class, + __offset_type_class, + __real_type_class, + __complex_type_class, + __function_type_class, + __method_type_class, + __record_type_class, + __union_type_class, + __array_type_class, + __string_type_class, + __set_type_class, + __file_type_class, + __lang_type_class +}; + +#endif +#define va_end(pvar) ((void)0) + +#ifdef __LITTLE_ENDIAN__ +#define __LITTLE_ENDIAN_P 1 +#else +#define __LITTLE_ENDIAN_P 0 +#endif + +#define __SCALAR_TYPE(TYPE) \ + ((TYPE) == __integer_type_class \ + || (TYPE) == __char_type_class \ + || (TYPE) == __enumeral_type_class) + +/* RECORD_TYPE args passed using the C calling convention are + passed by invisible reference. ??? RECORD_TYPE args passed + in the stack are made to be word-aligned; for an aggregate that is + not word-aligned, we advance the pointer to the first non-reg slot. */ + + /* When this is a smaller-than-int integer, using + auto-increment in the promoted (SImode) is fastest; + however, there is no way to express that is C. Therefore, + we use an asm. + We want the MEM_IN_STRUCT_P bit set in the emitted RTL, therefore we + use unions even when it would otherwise be unnecessary. */ + +#define __va_arg_sh1(AP, TYPE) __extension__ \ +__extension__ \ +({(sizeof (TYPE) == 1 \ + ? ({union {TYPE t; char c;} __t; \ + __asm("" \ + : "=r" (__t.c) \ + : "0" ((((union { int i, j; } *) (AP))++)->i)); \ + __t.t;}) \ + : sizeof (TYPE) == 2 \ + ? ({union {TYPE t; short s;} __t; \ + __asm("" \ + : "=r" (__t.s) \ + : "0" ((((union { int i, j; } *) (AP))++)->i)); \ + __t.t;}) \ + : sizeof (TYPE) >= 4 || __LITTLE_ENDIAN_P \ + ? (((union { TYPE t; int i;} *) (AP))++)->t \ + : ((union {TYPE t;TYPE u;}*) ((char *)++(int *)(AP) - sizeof (TYPE)))->t);}) + +#ifdef __SH3E__ + +#define __PASS_AS_FLOAT(TYPE_CLASS,SIZE) \ + (TYPE_CLASS == __real_type_class && SIZE == 4) + +#define va_arg(pvar,TYPE) \ +__extension__ \ +({int __type = __builtin_classify_type (* (TYPE *) 0); \ + void * __result_p; \ + if (__PASS_AS_FLOAT (__type, sizeof(TYPE))) \ + { \ + if (pvar.__va_next_fp < pvar.__va_next_fp_limit) \ + { \ + __result_p = &pvar.__va_next_fp; \ + } \ + else \ + __result_p = &pvar.__va_next_stack; \ + } \ + else \ + { \ + if (pvar.__va_next_o + ((sizeof (TYPE) + 3) / 4) \ + <= pvar.__va_next_o_limit) \ + __result_p = &pvar.__va_next_o; \ + else \ + { \ + if (sizeof (TYPE) > 4) \ + pvar.__va_next_o = pvar.__va_next_o_limit; \ + \ + __result_p = &pvar.__va_next_stack; \ + } \ + } \ + __va_arg_sh1(*(void **)__result_p, TYPE);}) + +#else /* ! SH3E */ + +#define va_arg(AP, TYPE) __va_arg_sh1((AP), TYPE) + +#endif /* SH3E */ + +/* Copy __gnuc_va_list into another variable of this type. */ +#define __va_copy(dest, src) (dest) = (src) + +#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */ |