|
|
1.1 root 1: /* Note: We must use the name __builtin_savregs. GCC attaches special
2: significance to that name. In particular, regardless of where in a
3: function __builtin_saveregs is called, GCC moves the call up to the
4: very start of the function. */
5:
6:
1.1.1.2 root 7: /* Define __gnuc_va_list. */
1.1 root 8:
1.1.1.2 root 9: #ifndef __GNUC_VA_LIST
10: #define __GNUC_VA_LIST
1.1 root 11:
12: typedef union {
13: float __freg[8];
14: double __dreg[4];
15: } __f_regs;
16:
17: typedef struct {
1.1.1.2 root 18: #if defined (__SVR4__) || defined (__svr4__) || defined (__alliant__)
1.1 root 19: __f_regs __float_regs; long __ireg[12];
20: #else /* pre-SVR4 */
21: long __ireg[12]; __f_regs __float_regs;
22: #endif
23: } __va_saved_regs;
24:
25: typedef struct {
1.1.1.3 ! root 26: #if defined(__SVR4__) || defined(__svr4__) || defined(__alliant__)
1.1 root 27: unsigned __ireg_used; /* How many int regs consumed 'til now? */
28: unsigned __freg_used; /* How many flt regs consumed 'til now? */
29: long *__reg_base; /* Address of where we stored the regs. */
30: long * __mem_ptr; /* Address of memory overflow args area. */
31: #else /* pre-SVR4 */
32: long *__reg_base; /* Address of where we stored the regs. */
33: long * __mem_ptr; /* Address of memory overflow args area. */
34: unsigned __ireg_used; /* How many int regs consumed 'til now? */
35: unsigned __freg_used; /* How many flt regs consumed 'til now? */
36: #endif
1.1.1.2 root 37: } __gnuc_va_list;
38: #endif /* not __GNUC_VA_LIST */
1.1 root 39:
1.1.1.2 root 40: /* If this is for internal libc use, don't define anything but
41: __gnuc_va_list. */
42: #if defined (_STDARG_H) || defined (_VARARGS_H)
1.1 root 43:
1.1.1.2 root 44: #if !defined(_STDARG_H)
45:
46: /* varargs support */
47: #define va_alist __builtin_va_alist
48: #define va_dcl
49: #define va_start(pvar) ((pvar) = * (__gnuc_va_list *) __builtin_saveregs ())
50:
51: #else /* STDARG.H */
52:
53: /* ANSI alternative. */
54: /* Note that CUMULATIVE_ARGS elements are measured in bytes on the i860,
55: so we divide by 4 to get # of registers. */
56: #define va_start(pvar, firstarg) \
57: ((pvar) = *(__gnuc_va_list *) __builtin_saveregs (), \
58: (pvar).__ireg_used = __builtin_args_info (0) / 4, \
59: (pvar).__freg_used = __builtin_args_info (1) / 4, \
60: (pvar).__mem_ptr = __builtin_next_arg ())
61:
62: #endif /* _STDARG_H */
1.1 root 63:
64: /* Values returned by __builtin_classify_type. */
65:
1.1.1.2 root 66: #ifndef va_end
1.1 root 67: enum {
68: __no_type_class = -1,
69: __void_type_class,
70: __integer_type_class,
71: __char_type_class,
72: __enumeral_type_class,
73: __boolean_type_class,
74: __pointer_type_class,
75: __reference_type_class,
76: __offset_type_class,
77: __real_type_class,
78: __complex_type_class,
79: __function_type_class,
80: __method_type_class,
81: __record_type_class,
82: __union_type_class,
83: __array_type_class,
84: __string_type_class,
85: __set_type_class,
86: __file_type_class,
87: __lang_type_class
88: };
89:
1.1.1.2 root 90: void va_end (__gnuc_va_list); /* Defined in libgcc.a */
91: #endif
92: #define va_end(__va)
93:
1.1 root 94: #define __NUM_PARM_FREGS 8
95: #define __NUM_PARM_IREGS 12
96:
1.1.1.2 root 97: #define __savereg(__va) ((__va_saved_regs *) ((__va).__reg_base))
1.1 root 98:
99: /* This macro works both for SVR4 and pre-SVR4 environments. */
100:
101: /* Note that parameters are always aligned at least to a word boundary
102: (when passed) regardless of what GCC's __alignof__ operator says. */
103:
104: /* Make allowances here for adding 128-bit (long double) floats someday. */
105:
1.1.1.2 root 106: #if 0 /* What was this for? */
1.1 root 107: #ifndef __GNU_VA_LIST
108: #define __ireg_used ireg_used
109: #define __freg_used freg_used
110: #define __mem_ptr mem_ptr
111: #define __reg_base reg_base
112: #endif
1.1.1.2 root 113: #endif /* 0 */
1.1 root 114:
115: /* Avoid errors if compiling GCC v2 with GCC v1. */
116: #if __GNUC__ == 1
117: #define __extension__
118: #endif
119:
120: #define va_arg(__va, __type) \
121: __extension__ \
122: (* (__type *) \
123: ({ \
124: register void *__rv; /* result value */ \
125: register unsigned __align; \
126: switch (__builtin_classify_type (* (__type *) 0)) \
127: { \
128: case __real_type_class: \
129: switch (sizeof (__type)) \
130: { \
131: case sizeof (float): \
132: case sizeof (double): \
1.1.1.2 root 133: if ((__va).__freg_used < __NUM_PARM_FREGS - 1) \
1.1 root 134: { \
1.1.1.2 root 135: if (((__va).__freg_used & 1) != 0) \
136: (__va).__freg_used++; /* skip odd */ \
137: __rv = &__savereg((__va))->__float_regs.__freg[(__va).__freg_used];\
138: (__va).__freg_used += 2; \
1.1 root 139: } \
140: else \
141: { \
1.1.1.2 root 142: if ((((unsigned) (__va).__mem_ptr) & (sizeof(double)-1)) != 0) \
143: (__va).__mem_ptr++; /* skip odd */ \
144: __rv = (__va).__mem_ptr; \
145: (__va).__mem_ptr += 2; \
1.1 root 146: } \
147: if (sizeof (__type) == sizeof (float)) \
148: { \
149: *((float *) __rv) = *((double *) __rv); \
150: *(((long *) __rv) + 1) = 0xfff00001; \
151: } \
152: break; \
153: default: \
154: abort (); \
155: } \
156: break; \
157: case __void_type_class: \
158: case __integer_type_class: \
159: case __char_type_class: \
160: case __enumeral_type_class: \
161: case __boolean_type_class: \
162: case __pointer_type_class: \
163: case __reference_type_class: \
164: case __offset_type_class: \
165: if (sizeof (__type) <= 4) \
166: { \
1.1.1.2 root 167: __rv = ((__va).__ireg_used < __NUM_PARM_IREGS \
168: ? (&__savereg((__va))->__ireg[(__va).__ireg_used++]) \
169: : (__va).__mem_ptr++); \
1.1 root 170: break; \
171: } \
1.1.1.2 root 172: else if ((__va).__ireg_used + sizeof (__type) / 4 <= __NUM_PARM_IREGS) \
1.1 root 173: { \
1.1.1.2 root 174: __rv = &__savereg((__va))->__ireg[(__va).__ireg_used]; \
175: (__va).__ireg_used += sizeof (__type) / 4; \
1.1 root 176: break; \
177: } \
178: /* Fall through to fetch from memory. */ \
179: case __record_type_class: \
180: case __union_type_class: \
181: __align = (__alignof__ (__type) < sizeof (long) \
182: ? sizeof (long) \
183: : __alignof__ (__type)); \
1.1.1.2 root 184: (__va).__mem_ptr \
1.1 root 185: = (long *) \
1.1.1.2 root 186: ((((unsigned) (__va).__mem_ptr) + (__align-1)) & ~(__align-1)); \
187: __rv = (__va).__mem_ptr; \
188: (__va).__mem_ptr \
1.1 root 189: += ((sizeof (__type) + sizeof (long) - 1) / sizeof (long)); \
190: break; \
191: case __complex_type_class: \
192: case __function_type_class: \
193: case __method_type_class: \
194: case __array_type_class: \
195: case __string_type_class: \
196: case __set_type_class: \
197: case __file_type_class: \
198: case __lang_type_class: \
199: case __no_type_class: \
200: default: \
201: abort (); \
202: } \
203: __rv; \
204: }))
205:
1.1.1.2 root 206: #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
207:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.