source: trunk/third/gcc/ginclude/va-ppc.h @ 8834

Revision 8834, 4.8 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, which included commits to RCS files with non-trunk default branches.
Line 
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.  */
10typedef 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 */
28typedef 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) */
Note: See TracBrowser for help on using the repository browser.