[BACK]Return to va-ppc.h CVS log [TXT][DIR] Up to [local] / sys / arch / powerpc / include

Annotation of sys/arch/powerpc/include/va-ppc.h, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: va-ppc.h,v 1.13 2006/04/09 03:07:53 deraadt Exp $     */
        !             2: /* GNU C varargs support for the PowerPC with either the V.4 or Windows NT calling sequences */
        !             3:
        !             4: #include <sys/cdefs.h>
        !             5:
        !             6: #ifndef _WIN32
        !             7: /* System V.4 support */
        !             8: /* Define __gnuc_va_list.  */
        !             9:
        !            10: #ifndef __GNUC_VA_LIST
        !            11: #define __GNUC_VA_LIST
        !            12:
        !            13: #ifndef _SYS_VA_LIST_H
        !            14: #define _SYS_VA_LIST_H         /* Solaris sys/va_list.h */
        !            15:
        !            16: /* Solaris decided to rename overflow_arg_area to input_arg_area,
        !            17:    so handle it via a macro.  */
        !            18: #define __va_overflow(AP) (AP)->overflow_arg_area
        !            19:
        !            20: /* Note that the names in this structure are in the user's namespace, but
        !            21:    that the V.4 abi explicitly states that these names should be used.  */
        !            22: typedef struct __va_list_tag {
        !            23:   unsigned char gpr;           /* index into the array of 8 GPRs stored in the
        !            24:                                   register save area gpr=0 corresponds to r3,
        !            25:                                   gpr=1 to r4, etc. */
        !            26:   unsigned char fpr;           /* index into the array of 8 FPRs stored in the
        !            27:                                   register save area fpr=0 corresponds to f1,
        !            28:                                   fpr=1 to f2, etc. */
        !            29:   char *overflow_arg_area;     /* location on stack that holds the next
        !            30:                                   overflow argument */
        !            31:   char *reg_save_area;         /* where r3:r10 and f1:f8, if saved are stored */
        !            32: } __gnuc_va_list[1];
        !            33:
        !            34: #else /* _SYS_VA_LIST */
        !            35:
        !            36: typedef __va_list __gnuc_va_list;
        !            37: #define __va_overflow(AP) (AP)->input_arg_area
        !            38:
        !            39: #endif /* not _SYS_VA_LIST */
        !            40: #endif /* not __GNUC_VA_LIST */
        !            41:
        !            42: /* If this is for internal libc use, don't define anything but
        !            43:    __gnuc_va_list.  */
        !            44: #if defined (_STDARG_H) || defined (_VARARGS_H)
        !            45:
        !            46: /* Register save area located below the frame pointer */
        !            47: #ifndef __VA_PPC_H__
        !            48: #define __VA_PPC_H__
        !            49: typedef struct {
        !            50:   long   __gp_save[8];         /* save area for GP registers */
        !            51:   double __fp_save[8];         /* save area for FP registers */
        !            52: } __va_regsave_t;
        !            53:
        !            54: /* Macros to access the register save area */
        !            55: /* We cast to void * and then to TYPE * because this avoids
        !            56:    a warning about increasing the alignment requirement.  */
        !            57: #define __VA_FP_REGSAVE(AP,OFS,TYPE)                                   \
        !            58:   ((TYPE *) (void *) (&(((__va_regsave_t *)                            \
        !            59:                         (AP)->reg_save_area)->__fp_save[OFS])))
        !            60:
        !            61: #define __VA_GP_REGSAVE(AP,OFS,TYPE)                                   \
        !            62:   ((TYPE *) (void *) (&(((__va_regsave_t *)                            \
        !            63:                         (AP)->reg_save_area)->__gp_save[OFS])))
        !            64:
        !            65: /* Common code for va_start for both varargs and stdarg.  We allow all
        !            66:    the work to be done by __builtin_saveregs.  It returns a pointer to
        !            67:    a va_list that was constructed on the stack; we must simply copy it
        !            68:    to the user's variable.  */
        !            69:
        !            70: #define __va_start_common(AP, FAKE) \
        !            71: __extension__ ({                                                       \
        !            72:    (AP) = (struct __va_list_tag *)__builtin_alloca(sizeof(__gnuc_va_list));   \
        !            73:   __builtin_memcpy ((AP), __builtin_saveregs (), sizeof(__gnuc_va_list)); \
        !            74:   })
        !            75:
        !            76: #ifdef _STDARG_H /* stdarg.h support */
        !            77:
        !            78: /* Calling __builtin_next_arg gives the proper error message if LASTARG is
        !            79:    not indeed the last argument.  */
        !            80: #ifdef lint
        !            81: #define va_start(AP,LASTARG)   ((AP) = (AP))
        !            82: #else
        !            83: #define va_start(AP,LASTARG) \
        !            84:   (__builtin_next_arg (LASTARG), __va_start_common (AP, 0))
        !            85: #endif /* lint */
        !            86:
        !            87: #else /* varargs.h support */
        !            88:
        !            89: #define va_start(AP) __va_start_common (AP, 1)
        !            90: #define va_alist __va_1st_arg
        !            91: #define va_dcl register int va_alist; ...
        !            92:
        !            93: #endif /* _STDARG_H */
        !            94:
        !            95: #ifdef _SOFT_FLOAT
        !            96: #define __va_float_p(TYPE)     0
        !            97: #else
        !            98: #define __va_float_p(TYPE)     (__builtin_classify_type(*(TYPE *)0) == 8)
        !            99: #endif
        !           100:
        !           101: #define __va_aggregate_p(TYPE) (__builtin_classify_type(*(TYPE *)0) >= 12)
        !           102: #define __va_size(TYPE)                ((sizeof(TYPE) + sizeof (long) - 1) / sizeof (long))
        !           103:
        !           104: /* This symbol isn't defined.  It is used to flag type promotion violations
        !           105:    at link time.  We can only do this when optimizing.  Use __builtin_trap
        !           106:    instead of abort so that we don't require a prototype for abort.
        !           107:
        !           108:    __builtin_trap stuff is not available on the gcc-2.95 branch, so we just
        !           109:    avoid calling it for now.  */
        !           110:
        !           111: #ifdef __OPTIMIZE__
        !           112: extern void __va_arg_type_violation(void) __attribute__((__noreturn__));
        !           113: #else
        !           114: #define __va_arg_type_violation()
        !           115: #endif
        !           116:
        !           117: #define va_arg(AP,TYPE)                                                           \
        !           118: __extension__ (*({                                                        \
        !           119:   register TYPE *__ptr;                                                           \
        !           120:                                                                           \
        !           121:   if (__va_float_p (TYPE) && sizeof (TYPE) < 16)                          \
        !           122:     {                                                                     \
        !           123:       unsigned char __fpr = (AP)->fpr;                                    \
        !           124:       if (__fpr < 8)                                                      \
        !           125:        {                                                                  \
        !           126:          __ptr = __VA_FP_REGSAVE (AP, __fpr, TYPE);                       \
        !           127:          (AP)->fpr = __fpr + 1;                                           \
        !           128:        }                                                                  \
        !           129:       else if (sizeof (TYPE) == 8)                                        \
        !           130:        {                                                                  \
        !           131:          unsigned long __addr = (unsigned long) (__va_overflow (AP));     \
        !           132:          __ptr = (TYPE *)((__addr + 7) & -8);                             \
        !           133:          __va_overflow (AP) = (char *)(__ptr + 1);                        \
        !           134:        }                                                                  \
        !           135:       else                                                                \
        !           136:        {                                                                  \
        !           137:          /* float is promoted to double.  */                              \
        !           138:          __va_arg_type_violation ();                                      \
        !           139:        }                                                                  \
        !           140:     }                                                                     \
        !           141:                                                                           \
        !           142:   /* Aggregates and long doubles are passed by reference.  */             \
        !           143:   else if (__va_aggregate_p (TYPE) || __va_float_p (TYPE))                \
        !           144:     {                                                                     \
        !           145:       unsigned char __gpr = (AP)->gpr;                                    \
        !           146:       if (__gpr < 8)                                                      \
        !           147:        {                                                                  \
        !           148:          __ptr = * __VA_GP_REGSAVE (AP, __gpr, TYPE *);                   \
        !           149:          (AP)->gpr = __gpr + 1;                                           \
        !           150:        }                                                                  \
        !           151:       else                                                                \
        !           152:        {                                                                  \
        !           153:          TYPE **__pptr = (TYPE **) (__va_overflow (AP));                  \
        !           154:          __ptr = * __pptr;                                                \
        !           155:          __va_overflow (AP) = (char *) (__pptr + 1);                      \
        !           156:        }                                                                  \
        !           157:     }                                                                     \
        !           158:                                                                           \
        !           159:   /* Only integrals remaining.  */                                        \
        !           160:   else                                                                    \
        !           161:     {                                                                     \
        !           162:       /* longlong is aligned.  */                                         \
        !           163:       if (sizeof (TYPE) == 8)                                             \
        !           164:        {                                                                  \
        !           165:          unsigned char __gpr = (AP)->gpr;                                 \
        !           166:          if (__gpr < 7)                                                   \
        !           167:            {                                                              \
        !           168:              __gpr += __gpr & 1;                                          \
        !           169:              __ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE);                   \
        !           170:              (AP)->gpr = __gpr + 2;                                       \
        !           171:            }                                                              \
        !           172:          else                                                             \
        !           173:            {                                                              \
        !           174:              unsigned long __addr = (unsigned long) (__va_overflow (AP)); \
        !           175:              __ptr = (TYPE *)((__addr + 7) & -8);                         \
        !           176:              (AP)->gpr = 8;                                               \
        !           177:              __va_overflow (AP) = (char *)(__ptr + 1);                    \
        !           178:            }                                                              \
        !           179:        }                                                                  \
        !           180:       else if (sizeof (TYPE) == 4)                                        \
        !           181:        {                                                                  \
        !           182:          unsigned char __gpr = (AP)->gpr;                                 \
        !           183:          if (__gpr < 8)                                                   \
        !           184:            {                                                              \
        !           185:              __ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE);                   \
        !           186:              (AP)->gpr = __gpr + 1;                                       \
        !           187:            }                                                              \
        !           188:          else                                                             \
        !           189:            {                                                              \
        !           190:              __ptr = (TYPE *) __va_overflow (AP);                         \
        !           191:              __va_overflow (AP) = (char *)(__ptr + 1);                    \
        !           192:            }                                                              \
        !           193:        }                                                                  \
        !           194:       else                                                                \
        !           195:        {                                                                  \
        !           196:          /* Everything else was promoted to int.  */                      \
        !           197:          __va_arg_type_violation ();                                      \
        !           198:        }                                                                  \
        !           199:     }                                                                     \
        !           200:   __ptr;                                                                  \
        !           201: }))
        !           202:
        !           203: #define va_end(AP)
        !           204:
        !           205: /* Copy __gnuc_va_list into another variable of this type.  */
        !           206: #define __va_copy(dest, src) \
        !           207: __extension__ ({ \
        !           208:         (dest) =  \
        !           209:            (struct __va_list_tag *)__builtin_alloca(sizeof(__gnuc_va_list)); \
        !           210:         *(dest) = *(src);\
        !           211:   })
        !           212:
        !           213: #if __ISO_C_VISIBLE >= 1999
        !           214: #define va_copy(dest, src)     __va_copy(dest, src)
        !           215: #endif
        !           216:
        !           217: #endif /* __VA_PPC_H__ */
        !           218: #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
        !           219:
        !           220: 
        !           221: #else
        !           222: /* Windows NT */
        !           223: /* Define __gnuc_va_list.  */
        !           224:
        !           225: #ifndef __GNUC_VA_LIST
        !           226: #define __GNUC_VA_LIST
        !           227: typedef char *__gnuc_va_list;
        !           228: #endif /* not __GNUC_VA_LIST */
        !           229:
        !           230: /* If this is for internal libc use, don't define anything but
        !           231:    __gnuc_va_list.  */
        !           232: #if defined (_STDARG_H) || defined (_VARARGS_H)
        !           233:
        !           234: #define __va_start_common(AP, LASTARG, FAKE)                           \
        !           235:   ((__builtin_saveregs ()), ((AP) = ((char *) &LASTARG) + __va_rounded_size (AP)), 0)
        !           236:
        !           237: #ifdef _STDARG_H /* stdarg.h support */
        !           238:
        !           239: /* Calling __builtin_next_arg gives the proper error message if LASTARG is
        !           240:    not indeed the last argument.  */
        !           241: #define va_start(AP,LASTARG)                                           \
        !           242:   (__builtin_saveregs (),                                              \
        !           243:    (AP) = __builtin_next_arg (LASTARG),                                        \
        !           244:    0)
        !           245:
        !           246: #else /* varargs.h support */
        !           247:
        !           248: #define va_start(AP)                                                   \
        !           249:   (__builtin_saveregs (),                                              \
        !           250:    (AP) = __builtin_next_arg (__va_1st_arg) - sizeof (int),            \
        !           251:    0)
        !           252:
        !           253: #define va_alist __va_1st_arg
        !           254: #define va_dcl register int __va_1st_arg; ...
        !           255:
        !           256: #endif /* _STDARG_H */
        !           257:
        !           258: #define __va_rounded_size(TYPE) ((sizeof (TYPE) + 3) & ~3)
        !           259: #define __va_align(AP, TYPE)                                           \
        !           260:      ((((unsigned long)(AP)) + ((sizeof (TYPE) >= 8) ? 7 : 3))         \
        !           261:       & ~((sizeof (TYPE) >= 8) ? 7 : 3))
        !           262:
        !           263: #define va_arg(AP,TYPE)                                                        \
        !           264: ( *(TYPE *)((AP = (char *) (__va_align(AP, TYPE)                       \
        !           265:                            + __va_rounded_size(TYPE)))                 \
        !           266:            - __va_rounded_size(TYPE)))
        !           267:
        !           268: #define va_end(AP)
        !           269:
        !           270: /* Copy __gnuc_va_list into another variable of this type.  */
        !           271: #define __va_copy(dest, src) (dest) = (src)
        !           272:
        !           273: #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
        !           274: #endif /* Windows NT */

CVSweb