home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gcc-2.7.2.1-base.tgz / gcc-2.7.2.1-base.tar / fsf / gcc / ginclude / va-ppc.h < prev    next >
C/C++ Source or Header  |  1995-10-09  |  5KB  |  145 lines

  1. /* GNU C varargs support for the PowerPC with V.4 calling sequence */
  2.  
  3. /* Define __gnuc_va_list.  */
  4.  
  5. #ifndef __GNUC_VA_LIST
  6. #define __GNUC_VA_LIST
  7.  
  8. /* Note that the names in this structure are in the user's namespace, but
  9.    that the V.4 abi explicitly states that these names should be used.  */
  10. typedef struct {
  11.   char gpr;            /* index into the array of 8 GPRs stored in the
  12.                    register save area gpr=0 corresponds to r3,
  13.                    gpr=1 to r4, etc. */
  14.   char fpr;            /* index into the array of 8 FPRs stored in the
  15.                    register save area fpr=0 corresponds to f1,
  16.                    fpr=1 to f2, etc. */
  17.   char *overflow_arg_area;    /* location on stack that holds the next
  18.                    overflow argument */
  19.   char *reg_save_area;        /* where r3:r10 and f1:f8, if saved are stored */
  20. } __gnuc_va_list[1];
  21. #endif /* not __GNUC_VA_LIST */
  22.  
  23. /* If this is for internal libc use, don't define anything but
  24.    __gnuc_va_list.  */
  25. #if defined (_STDARG_H) || defined (_VARARGS_H)
  26.  
  27. /* Register save area located below the frame pointer */
  28. typedef struct {
  29.   long   __gp_save[8];        /* save area for GP registers */
  30.   double __fp_save[8];        /* save area for FP registers */
  31. } __va_regsave_t;
  32.  
  33. /* Macros to access the register save area */
  34. /* We cast to void * and then to TYPE * because this avoids
  35.    a warning about increasing the alignment requirement.  */
  36. #define __VA_FP_REGSAVE(AP,TYPE)                    \
  37.   ((TYPE *) (void *) (&(((__va_regsave_t *)                \
  38.              (AP)->reg_save_area)->__fp_save[(int)(AP)->fpr])))
  39.  
  40. #define __VA_GP_REGSAVE(AP,TYPE)                    \
  41.   ((TYPE *) (void *) (&(((__va_regsave_t *)                \
  42.              (AP)->reg_save_area)->__gp_save[(int)(AP)->gpr])))
  43.  
  44. /* Common code for va_start for both varargs and stdarg.  This depends
  45.    on the format of rs6000_args in rs6000.h.  The fields used are:
  46.  
  47.    #0    WORDS            # words used for GP regs/stack values
  48.    #1    FREGNO            next available FP register
  49.    #2    NARGS_PROTOTYPE        # args left in the current prototype
  50.    #3    ORIG_NARGS        original value of NARGS_PROTOTYPE
  51.    #4    VARARGS_OFFSET        offset from frame pointer of varargs area */
  52.  
  53. #define __va_words        __builtin_args_info (0)
  54. #define __va_fregno        __builtin_args_info (1)
  55. #define    __va_nargs        __builtin_args_info (2)
  56. #define __va_orig_nargs        __builtin_args_info (3)
  57. #define __va_varargs_offset    __builtin_args_info (4)
  58.  
  59. #define __va_start_common(AP, FAKE)                    \
  60. __extension__ ({                            \
  61.    register int __words = __va_words - FAKE;                \
  62.                                     \
  63.    (AP)->gpr = (__words < 8) ? __words : 8;                \
  64.    (AP)->fpr = __va_fregno - 33;                    \
  65.    (AP)->reg_save_area = (((char *) __builtin_frame_address (0))    \
  66.               + __va_varargs_offset);            \
  67.    (AP)->overflow_arg_area = ((char *)__builtin_saveregs ()        \
  68.                   + (((__words >= 8) ? __words - 8 : 0)    \
  69.                  * sizeof (long)));            \
  70.    (void)0;                                \
  71. })
  72.  
  73. #ifdef _STDARG_H /* stdarg.h support */
  74.  
  75. /* Calling __builtin_next_arg gives the proper error message if LASTARG is
  76.    not indeed the last argument.  */
  77. #define va_start(AP,LASTARG) \
  78.   (__builtin_next_arg (LASTARG), __va_start_common (AP, 0))
  79.  
  80. #else /* varargs.h support */
  81.  
  82. #define va_start(AP) __va_start_common (AP, 1)
  83. #define va_alist __va_1st_arg
  84. #define va_dcl register int va_alist; ...
  85.  
  86. #endif /* _STDARG_H */
  87.  
  88. #ifdef _SOFT_FLOAT
  89. #define __va_float_p(TYPE)    0
  90. #else
  91. #define __va_float_p(TYPE)    (__builtin_classify_type(*(TYPE *)0) == 8)
  92. #endif
  93.  
  94. #define __va_aggregate_p(TYPE)    (__builtin_classify_type(*(TYPE *)0) >= 12)
  95. #define __va_size(TYPE)        ((sizeof(TYPE) + sizeof (long) - 1) / sizeof (long))
  96.  
  97. #define va_arg(AP,TYPE)                            \
  98. __extension__ (*({                            \
  99.   register TYPE *__ptr;                            \
  100.                                     \
  101.   if (__va_float_p (TYPE) && (AP)->fpr < 8)                \
  102.     {                                    \
  103.       __ptr = __VA_FP_REGSAVE (AP, TYPE);                \
  104.       (AP)->fpr++;                            \
  105.     }                                    \
  106.                                     \
  107.   else if (__va_aggregate_p (TYPE) && (AP)->gpr < 8)            \
  108.     {                                    \
  109.       __ptr = * __VA_GP_REGSAVE (AP, TYPE *);                \
  110.       (AP)->gpr++;                            \
  111.     }                                    \
  112.                                     \
  113.   else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE)        \
  114.        && (AP)->gpr + __va_size(TYPE) <= 8)                \
  115.     {                                    \
  116.       __ptr = __VA_GP_REGSAVE (AP, TYPE);                \
  117.       (AP)->gpr += __va_size (TYPE);                    \
  118.     }                                    \
  119.                                     \
  120.   else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE)        \
  121.        && (AP)->gpr < 8)                        \
  122.     {                                    \
  123.       (AP)->gpr = 8;                            \
  124.       __ptr = (TYPE *) (void *) ((AP)->overflow_arg_area);        \
  125.       (AP)->overflow_arg_area += __va_size (TYPE) * sizeof (long);    \
  126.     }                                    \
  127.                                     \
  128.   else if (__va_aggregate_p (TYPE))                    \
  129.     {                                    \
  130.       __ptr = * (TYPE **) (void *) ((AP)->overflow_arg_area);        \
  131.       (AP)->overflow_arg_area += sizeof (TYPE *);            \
  132.     }                                    \
  133.   else                                    \
  134.     {                                    \
  135.       __ptr = (TYPE *) (void *) ((AP)->overflow_arg_area);        \
  136.       (AP)->overflow_arg_area += __va_size (TYPE) * sizeof (long);    \
  137.     }                                    \
  138.                                     \
  139.   __ptr;                                \
  140. }))
  141.  
  142. #define va_end(AP)    ((void)0)
  143.  
  144. #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
  145.