diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2004-05-19 21:40:31 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2004-05-19 21:40:31 +0000 |
commit | 5ddf48e85619d5b384378cb8d0be6a01b727c32d (patch) | |
tree | e0431462f94e704ffa91f625fa9e3286f4baad71 /sys/arch | |
parent | d0c55a70775d9efea2277f35dcf420425109680f (diff) |
Rewrite va_arg() for correctness. Not only is the new code easier to read,
it also expands to faster code!
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/m88k/include/va-m88k.h | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/sys/arch/m88k/include/va-m88k.h b/sys/arch/m88k/include/va-m88k.h index b6c0bcf21cb..e076b50299c 100644 --- a/sys/arch/m88k/include/va-m88k.h +++ b/sys/arch/m88k/include/va-m88k.h @@ -1,12 +1,4 @@ -/* $OpenBSD: va-m88k.h,v 1.1 2004/04/26 12:34:05 miod Exp $ */ - -/* This file has local changes by MOTOROLA -Thu Sep 9 09:06:29 CDT 1993 Dale Rahn (drahn@pacific) - * Due to C-Front's usage of __alignof__ builtin the - usage of it must be changed to have an object of that type - as the argument not just the type. - */ -/* GNU C varargs support for the Motorola 88100 */ +/* $OpenBSD: va-m88k.h,v 1.2 2004/05/19 21:40:30 miod Exp $ */ /* Define __gnuc_va_list. */ @@ -46,24 +38,39 @@ __extension__ ({ \ #endif /* _STDARG_H */ -#define __va_reg_p(TYPE) \ - (__builtin_classify_type(*(TYPE *)0) < 12 \ - ? sizeof(TYPE) <= 8 : sizeof(TYPE) == 4 && __alignof__(*(TYPE *)0) == 4) +#define __va_reg_p(TYPE) \ +__extension__({ \ + __builtin_classify_type(*(TYPE *)0) < 12 ? /* record, union */ \ + sizeof(TYPE) <= 8 : \ + sizeof(TYPE) == 4 && __alignof__(*(TYPE *)0) == 4; \ +}) #define __va_size(TYPE) ((sizeof(TYPE) + 3) >> 2) /* We cast to void * and then to TYPE * because this avoids a warning about increasing the alignment requirement. */ -#define va_arg(AP,TYPE) \ - ( (AP)->__va_arg = (((AP)->__va_arg + (1 << (__alignof__(*(TYPE *)0) >> 3)) - 1) \ - & ~((1 << (__alignof__(*(TYPE *)0) >> 3)) - 1)) \ - + __va_size(TYPE), \ - *((TYPE *) (void *) ((__va_reg_p(TYPE) \ - && (AP)->__va_arg < 8 + __va_size(TYPE) \ - ? (AP)->__va_reg : (AP)->__va_stk) \ - + ((AP)->__va_arg - __va_size(TYPE))))) - -#define va_end(AP) +#define va_arg(AP,TYPE) \ +__extension__(*({ \ + register TYPE *__ptr; \ + \ + if ((AP)->__va_arg <= 8 && __va_reg_p(TYPE)) { \ + /* might be in registers */ \ + if (((AP)->__va_arg & 1) != 0 && __alignof__(*(TYPE *)0) > 4) \ + (AP)->__va_arg++; \ + (AP)->__va_arg += __va_size(TYPE); \ + } \ + \ + if ((AP)->__va_arg <= 8 && __va_reg_p(TYPE)) { \ + __ptr = (TYPE *) (void *) ((AP)->__va_reg + \ + (AP)->__va_arg - __va_size(TYPE)); \ + } else { \ + __ptr = (TYPE *) (AP)->__va_stk; \ + (AP)->__va_stk += __va_size(TYPE); \ + } \ + __ptr; \ +})) + +#define va_end(AP) ((void)0) /* Copy __gnuc_va_list into another variable of this type. */ #define __va_copy(dest, src) \ |