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