stdarg.h 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #ifndef _STDARG_H
  2. #define _STDARG_H
  3. #ifdef __x86_64__
  4. #include <stdlib.h>
  5. /* GCC compatible definition of va_list. */
  6. struct __va_list_struct {
  7. unsigned int gp_offset;
  8. unsigned int fp_offset;
  9. union {
  10. unsigned int overflow_offset;
  11. char *overflow_arg_area;
  12. };
  13. char *reg_save_area;
  14. };
  15. typedef struct __va_list_struct *va_list;
  16. /* we use __builtin_(malloc|free) to avoid #define malloc tcc_malloc */
  17. /* XXX: this lacks the support of aggregated types. */
  18. #define va_start(ap, last) \
  19. (ap = (va_list)__builtin_malloc(sizeof(struct __va_list_struct)), \
  20. *ap = *(struct __va_list_struct*)( \
  21. (char*)__builtin_frame_address(0) - 16), \
  22. ap->overflow_arg_area = ((char *)__builtin_frame_address(0) + \
  23. ap->overflow_offset), \
  24. ap->reg_save_area = (char *)__builtin_frame_address(0) - 176 - 16 \
  25. )
  26. #define va_arg(ap, type) \
  27. (*(type*)(__builtin_types_compatible_p(type, long double) \
  28. ? (ap->overflow_arg_area += 16, \
  29. ap->overflow_arg_area - 16) \
  30. : __builtin_types_compatible_p(type, double) \
  31. ? (ap->fp_offset < 128 + 48 \
  32. ? (ap->fp_offset += 16, \
  33. ap->reg_save_area + ap->fp_offset - 16) \
  34. : (ap->overflow_arg_area += 8, \
  35. ap->overflow_arg_area - 8)) \
  36. : (ap->gp_offset < 48 \
  37. ? (ap->gp_offset += 8, \
  38. ap->reg_save_area + ap->gp_offset - 8) \
  39. : (ap->overflow_arg_area += 8, \
  40. ap->overflow_arg_area - 8)) \
  41. ))
  42. #define va_copy(dest, src) \
  43. ((dest) = (va_list)malloc(sizeof(struct __va_list_struct)), \
  44. *(dest) = *(src))
  45. #define va_end(ap) __builtin_free(ap)
  46. #else
  47. typedef char *va_list;
  48. /* only correct for i386 */
  49. #define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)
  50. #define va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3)))
  51. #define va_copy(dest, src) (dest) = (src)
  52. #define va_end(ap)
  53. #endif
  54. /* fix a buggy dependency on GCC in libio.h */
  55. typedef va_list __gnuc_va_list;
  56. #define _VA_LIST_DEFINED
  57. #endif /* _STDARG_H */