|
191 | 191 | #if defined __x86_64__ |
192 | 192 | #if !defined _WIN32 |
193 | 193 | /* GCC compatible definition of va_list. */ |
194 | | - /* This should be in sync with the declaration in our lib/libtcc1.c */ |
| 194 | + |
| 195 | + enum __va_arg_type { |
| 196 | + __va_gen_reg, __va_float_reg, __va_stack |
| 197 | + }; |
195 | 198 | typedef struct { |
196 | 199 | unsigned gp_offset, fp_offset; |
197 | 200 | union { |
|
201 | 204 | char *reg_save_area; |
202 | 205 | } __builtin_va_list[1]; |
203 | 206 |
|
204 | | - void *__va_arg(__builtin_va_list ap, int arg_type, int size, int align); |
| 207 | + static inline void *__va_arg(__builtin_va_list ap, int arg_type, |
| 208 | + int size, int align) |
| 209 | + { |
| 210 | + size = (size + 7) & ~7; |
| 211 | + align = (align + 7) & ~7; |
| 212 | + switch ((enum __va_arg_type)arg_type) { |
| 213 | + case __va_gen_reg: |
| 214 | + if (ap->gp_offset + size <= 48) { |
| 215 | + ap->gp_offset += size; |
| 216 | + return ap->reg_save_area + ap->gp_offset - size; |
| 217 | + } |
| 218 | + goto use_overflow_area; |
| 219 | + case __va_float_reg: |
| 220 | + if (ap->fp_offset < 128 + 48) { |
| 221 | + ap->fp_offset += 16; |
| 222 | + if (size == 8) |
| 223 | + return ap->reg_save_area + ap->fp_offset - 16; |
| 224 | + if (ap->fp_offset < 128 + 48) { |
| 225 | + double *p = (double *)(ap->reg_save_area + ap->fp_offset); |
| 226 | + p[-1] = p[0]; |
| 227 | + ap->fp_offset += 16; |
| 228 | + return ap->reg_save_area + ap->fp_offset - 32; |
| 229 | + } |
| 230 | + } |
| 231 | + goto use_overflow_area; |
| 232 | + case __va_stack: |
| 233 | + use_overflow_area: |
| 234 | + ap->overflow_arg_area += size; |
| 235 | + ap->overflow_arg_area = |
| 236 | + (char*)((long long)(ap->overflow_arg_area + align - 1) & -align); |
| 237 | + return ap->overflow_arg_area - size; |
| 238 | + default: /* should never happen */ |
| 239 | + char *a = (char *)0; *a = 0; // abort |
| 240 | + return 0; |
| 241 | + } |
| 242 | + } |
| 243 | + |
205 | 244 | #define __builtin_va_start(ap, last) \ |
206 | 245 | (*(ap) = *(__builtin_va_list)((char*)__builtin_frame_address(0) - 24)) |
207 | 246 | #define __builtin_va_arg(ap, t) \ |
|
0 commit comments