diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2002-10-17 15:15:05 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2002-10-17 15:15:05 +0000 |
commit | 10e5c7a25b189eda13a48597e1cf90d65627d239 (patch) | |
tree | 236334e6a0475b804d9db9b4dca365cfdb45c6bf /sys/arch | |
parent | 33bd5168fe82ca217b7069f772a369261a086c71 (diff) |
sync with gcc version, fixes bug in sftp where it had a 64 bit parameter
which straddled the last register first stack parameter.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/powerpc/include/va-ppc.h | 256 |
1 files changed, 104 insertions, 152 deletions
diff --git a/sys/arch/powerpc/include/va-ppc.h b/sys/arch/powerpc/include/va-ppc.h index b8359bead00..c950186e9a8 100644 --- a/sys/arch/powerpc/include/va-ppc.h +++ b/sys/arch/powerpc/include/va-ppc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: va-ppc.h,v 1.8 2002/09/15 09:01:59 deraadt Exp $ */ +/* $OpenBSD: va-ppc.h,v 1.9 2002/10/17 15:15:04 drahn Exp $ */ /* GNU C varargs support for the PowerPC with either the V.4 or Windows NT calling sequences */ #ifndef _WIN32 @@ -18,10 +18,10 @@ /* Note that the names in this structure are in the user's namespace, but that the V.4 abi explicitly states that these names should be used. */ typedef struct __va_list_tag { - char gpr; /* index into the array of 8 GPRs stored in the + unsigned char gpr; /* index into the array of 8 GPRs stored in the register save area gpr=0 corresponds to r3, gpr=1 to r4, etc. */ - char fpr; /* index into the array of 8 FPRs stored in the + unsigned char fpr; /* index into the array of 8 FPRs stored in the register save area fpr=0 corresponds to f1, fpr=1 to f2, etc. */ char *overflow_arg_area; /* location on stack that holds the next @@ -52,61 +52,24 @@ typedef struct { /* Macros to access the register save area */ /* We cast to void * and then to TYPE * because this avoids a warning about increasing the alignment requirement. */ -#define __VA_FP_REGSAVE(AP,TYPE) \ +#define __VA_FP_REGSAVE(AP,OFS,TYPE) \ ((TYPE *) (void *) (&(((__va_regsave_t *) \ - (AP)->reg_save_area)->__fp_save[(int)(AP)->fpr]))) + (AP)->reg_save_area)->__fp_save[OFS]))) -#define __VA_GP_REGSAVE(AP,TYPE) \ +#define __VA_GP_REGSAVE(AP,OFS,TYPE) \ ((TYPE *) (void *) (&(((__va_regsave_t *) \ - (AP)->reg_save_area)->__gp_save[(int)(AP)->gpr]))) -#if __GNUC_MINOR__ > 8 -#define GCC29 -#endif - -#ifndef GCC29 -/* Common code for va_start for both varargs and stdarg. This depends - on the format of rs6000_args in rs6000.h. The fields used are: + (AP)->reg_save_area)->__gp_save[OFS]))) - #0 WORDS # words used for GP regs/stack values - #1 FREGNO next available FP register - #2 NARGS_PROTOTYPE # args left in the current prototype - #3 ORIG_NARGS original value of NARGS_PROTOTYPE - #4 VARARGS_OFFSET offset from frame pointer of varargs area */ -#else /* GCC29 */ /* Common code for va_start for both varargs and stdarg. We allow all the work to be done by __builtin_saveregs. It returns a pointer to a va_list that was constructed on the stack; we must simply copy it to the user's variable. */ -#endif /* GCC29 */ -#ifndef GCC29 -#define __va_words __builtin_args_info (0) -#define __va_fregno __builtin_args_info (1) -#define __va_nargs __builtin_args_info (2) -#define __va_orig_nargs __builtin_args_info (3) -#define __va_varargs_offset __builtin_args_info (4) - -#define __va_start_common(AP, FAKE) \ -__extension__ ({ \ - register int __words = __va_words - FAKE; \ - \ - (AP) = (struct __va_list_tag *)__builtin_alloca(sizeof(struct __va_list_tag)); \ - (AP)->gpr = (__words < 8) ? __words : 8; \ - (AP)->fpr = __va_fregno - 33; \ - (AP)->reg_save_area = (((char *) __builtin_frame_address (0)) \ - + __va_varargs_offset); \ - __va_overflow(AP) = ((char *)__builtin_saveregs () \ - + (((__words >= 8) ? __words - 8 : 0) \ - * sizeof (long))); \ - (void)0; \ -}) -#else /* GCC29 */ #define __va_start_common(AP, FAKE) \ __extension__ ({ \ (AP) = (struct __va_list_tag *)__builtin_alloca(sizeof(__gnuc_va_list)); \ __builtin_memcpy ((AP), __builtin_saveregs (), sizeof(__gnuc_va_list)); \ }) -#endif /* GCC29 */ #ifdef _STDARG_H /* stdarg.h support */ @@ -129,116 +92,107 @@ __extension__ ({ \ #define __va_float_p(TYPE) (__builtin_classify_type(*(TYPE *)0) == 8) #endif -#define __va_longlong_p(TYPE) \ - ((__builtin_classify_type(*(TYPE *)0) == 1) && (sizeof(TYPE) == 8)) - #define __va_aggregate_p(TYPE) (__builtin_classify_type(*(TYPE *)0) >= 12) #define __va_size(TYPE) ((sizeof(TYPE) + sizeof (long) - 1) / sizeof (long)) -#ifndef GCC29 -#define va_arg(AP,TYPE) \ -__extension__ (*({ \ - register TYPE *__ptr; \ - \ - if (__va_float_p (TYPE) && (AP)->fpr < 8) \ - { \ - __ptr = __VA_FP_REGSAVE (AP, TYPE); \ - (AP)->fpr++; \ - } \ - \ - else if (__va_aggregate_p (TYPE) && (AP)->gpr < 8) \ - { \ - __ptr = * __VA_GP_REGSAVE (AP, TYPE *); \ - (AP)->gpr++; \ - } \ - \ - else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE) \ - && (AP)->gpr + __va_size(TYPE) <= 8 \ - && (!__va_longlong_p(TYPE) \ - || (AP)->gpr + __va_size(TYPE) <= 7)) \ - { \ - if (__va_longlong_p(TYPE) && ((AP)->gpr & 1) != 0) \ - (AP)->gpr++; \ - \ - __ptr = __VA_GP_REGSAVE (AP, TYPE); \ - (AP)->gpr += __va_size (TYPE); \ - } \ - \ - else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE) \ - && (AP)->gpr < 8) \ - { \ - (AP)->gpr = 8; \ - __ptr = (TYPE *) (void *) (__va_overflow(AP)); \ - __va_overflow(AP) += __va_size (TYPE) * sizeof (long); \ - } \ - \ - else if (__va_aggregate_p (TYPE)) \ - { \ - __ptr = * (TYPE **) (void *) (__va_overflow(AP)); \ - __va_overflow(AP) += sizeof (TYPE *); \ - } \ - else \ - { \ - if (__va_longlong_p(TYPE) && ((long)__va_overflow(AP) & 4) != 0) \ - __va_overflow(AP) += 4; \ - \ - __ptr = (TYPE *) (void *) (__va_overflow(AP)); \ - __va_overflow(AP) += __va_size (TYPE) * sizeof (long); \ - } \ - \ - __ptr; \ -})) -#else /* GCC29 */ -#define va_arg(AP,TYPE) \ -__extension__ (*({ \ - register TYPE *__ptr; \ - \ - if (__va_float_p (TYPE) && (AP)->fpr < 8) \ - { \ - __ptr = __VA_FP_REGSAVE (AP, TYPE); \ - (AP)->fpr++; \ - } \ - \ - else if (__va_aggregate_p (TYPE) && (AP)->gpr < 8) \ - { \ - __ptr = * __VA_GP_REGSAVE (AP, TYPE *); \ - (AP)->gpr++; \ - } \ - \ - else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE) \ - && (AP)->gpr + __va_size(TYPE) <= 8 \ - && (!__va_longlong_p(TYPE) \ - || (AP)->gpr + __va_size(TYPE) <= 8)) \ - { \ - if (__va_longlong_p(TYPE) && ((AP)->gpr & 1) != 0) \ - (AP)->gpr++; \ - \ - __ptr = __VA_GP_REGSAVE (AP, TYPE); \ - (AP)->gpr += __va_size (TYPE); \ - } \ - \ - else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE) \ - && (AP)->gpr < 8) \ - { \ - (AP)->gpr = 8; \ - __ptr = (TYPE *) (void *) (__va_overflow(AP)); \ - __va_overflow(AP) += __va_size (TYPE) * sizeof (long); \ - } \ - \ - else if (__va_aggregate_p (TYPE)) \ - { \ - __ptr = * (TYPE **) (void *) (__va_overflow(AP)); \ - __va_overflow(AP) += sizeof (TYPE *); \ - } \ - else \ - { \ - __ptr = (TYPE *) (void *) (__va_overflow(AP)); \ - __va_overflow(AP) += __va_size (TYPE) * sizeof (long); \ - } \ - \ - __ptr; \ +/* This symbol isn't defined. It is used to flag type promotion violations + at link time. We can only do this when optimizing. Use __builtin_trap + instead of abort so that we don't require a prototype for abort. + + __builtin_trap stuff is not available on the gcc-2.95 branch, so we just + avoid calling it for now. */ + +#ifdef __OPTIMIZE__ +extern void __va_arg_type_violation(void) __attribute__((__noreturn__)); +#else +#define __va_arg_type_violation() +#endif + +#define va_arg(AP,TYPE) \ +__extension__ (*({ \ + register TYPE *__ptr; \ + \ + if (__va_float_p (TYPE) && sizeof (TYPE) < 16) \ + { \ + unsigned char __fpr = (AP)->fpr; \ + if (__fpr < 8) \ + { \ + __ptr = __VA_FP_REGSAVE (AP, __fpr, TYPE); \ + (AP)->fpr = __fpr + 1; \ + } \ + else if (sizeof (TYPE) == 8) \ + { \ + unsigned long __addr = (unsigned long) (__va_overflow (AP)); \ + __ptr = (TYPE *)((__addr + 7) & -8); \ + __va_overflow (AP) = (char *)(__ptr + 1); \ + } \ + else \ + { \ + /* float is promoted to double. */ \ + __va_arg_type_violation (); \ + } \ + } \ + \ + /* Aggregates and long doubles are passed by reference. */ \ + else if (__va_aggregate_p (TYPE) || __va_float_p (TYPE)) \ + { \ + unsigned char __gpr = (AP)->gpr; \ + if (__gpr < 8) \ + { \ + __ptr = * __VA_GP_REGSAVE (AP, __gpr, TYPE *); \ + (AP)->gpr = __gpr + 1; \ + } \ + else \ + { \ + TYPE **__pptr = (TYPE **) (__va_overflow (AP)); \ + __ptr = * __pptr; \ + __va_overflow (AP) = (char *) (__pptr + 1); \ + } \ + } \ + \ + /* Only integrals remaining. */ \ + else \ + { \ + /* longlong is aligned. */ \ + if (sizeof (TYPE) == 8) \ + { \ + unsigned char __gpr = (AP)->gpr; \ + if (__gpr < 7) \ + { \ + __gpr += __gpr & 1; \ + __ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE); \ + (AP)->gpr = __gpr + 2; \ + } \ + else \ + { \ + unsigned long __addr = (unsigned long) (__va_overflow (AP)); \ + __ptr = (TYPE *)((__addr + 7) & -8); \ + (AP)->gpr = 8; \ + __va_overflow (AP) = (char *)(__ptr + 1); \ + } \ + } \ + else if (sizeof (TYPE) == 4) \ + { \ + unsigned char __gpr = (AP)->gpr; \ + if (__gpr < 8) \ + { \ + __ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE); \ + (AP)->gpr = __gpr + 1; \ + } \ + else \ + { \ + __ptr = (TYPE *) __va_overflow (AP); \ + __va_overflow (AP) = (char *)(__ptr + 1); \ + } \ + } \ + else \ + { \ + /* Everything else was promoted to int. */ \ + __va_arg_type_violation (); \ + } \ + } \ + __ptr; \ })) -#endif /* not GCC29 */ #define va_end(AP) ((void)0) @@ -249,8 +203,6 @@ __extension__ ({ \ (struct __va_list_tag *)__builtin_alloca(sizeof(__gnuc_va_list)); \ *(dest) = *(src);\ }) - - #endif /* __VA_PPC_H__ */ #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */ |