home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / gnu / gcc-2.3.3-bin.lha / lib / gcc-lib / amigados / 2.3.3 / include / va-alpha.h < prev    next >
C/C++ Source or Header  |  1994-02-06  |  5KB  |  191 lines

  1. /* GNU C varargs and stdargs support for the DEC Alpha.  */
  2.  
  3. /* Note:  We must use the name __builtin_savregs.  GCC attaches special
  4.    significance to that name.  In particular, regardless of where in a
  5.    function __builtin_saveregs is called, GCC moves the call up to the
  6.    very start of the function.  */
  7.  
  8. /* Define __gnuc_va_list.  */
  9.  
  10. #ifndef __GNUC_VA_LIST
  11. #define __GNUC_VA_LIST
  12.  
  13. typedef struct {
  14.   long __va_arg;        /* Current argument number. */
  15.   long *__va_stack;        /* Start of arguments on stack */
  16.   long *__va_iregs;        /* Integer parameter registers ($16-$21) */
  17.   long *__va_fregs;        /* FP parameter registers ($f16-$f21) */
  18. } __gnuc_va_list;
  19. #endif /* not __GNUC_VA_LIST */
  20.  
  21. /* If this is for internal libc use, don't define anything but
  22.    __gnuc_va_list.  */
  23. #if defined (_STDARG_H) || defined (_VARARGS_H)
  24.  
  25. #define va_list __gnuc_va_list
  26. #define _VA_LIST
  27. #define _VA_LIST_
  28.  
  29. #if !defined(_STDARG_H)
  30.  
  31. /* varargs support */
  32. #define va_alist __builtin_va_alist
  33. #define va_dcl
  34. #define va_start(pvar) ((pvar) = * (__gnuc_va_list *) __builtin_saveregs ())
  35.  
  36. #else /* STDARG.H */
  37.  
  38. /* ANSI alternative.  */
  39.  
  40. #define va_start(pvar, firstarg)  \
  41.   ((pvar) = *(__gnuc_va_list *) __builtin_saveregs ())
  42.  
  43. #endif /* _STDARG_H */
  44.  
  45. #ifndef va_end
  46.  
  47. #define va_end(__va)
  48.  
  49. /* Values returned by __builtin_classify_type.  */
  50.  
  51. enum {
  52.   __no_type_class = -1,
  53.   __void_type_class,
  54.   __integer_type_class,
  55.   __char_type_class,
  56.   __enumeral_type_class,
  57.   __boolean_type_class,
  58.   __pointer_type_class,
  59.   __reference_type_class,
  60.   __offset_type_class,
  61.   __real_type_class,
  62.   __complex_type_class,
  63.   __function_type_class,
  64.   __method_type_class,
  65.   __record_type_class,
  66.   __union_type_class,
  67.   __array_type_class,
  68.   __string_type_class,
  69.   __set_type_class,
  70.   __file_type_class,
  71.   __lang_type_class
  72. };
  73.  
  74. #endif
  75.  
  76. /* Note that parameters are always aligned at least to a word boundary
  77.    (when passed) regardless of what GCC's __alignof__ operator says.  */
  78.  
  79. /* Avoid errors if compiling GCC v2 with GCC v1.  */
  80. #if __GNUC__ == 1
  81. #define __extension__
  82. #endif
  83.  
  84. /* Get the rounded number of words of a type.  */
  85.  
  86. #define __va_nwords(__type)  \
  87.   ((sizeof (__type) + sizeof (long) - 1) / sizeof (long))
  88.  
  89. #define va_arg(__va, __type)                        \
  90. __extension__                                \
  91. (* (__type *)                                \
  92.  ({                                    \
  93.   register void *__rv;  /* result value */                \
  94.   switch (__builtin_classify_type (* (__type *) 0))            \
  95.     {                                        \
  96.     case __real_type_class:                        \
  97.                                     \
  98.       /* Get a pointer to the value.  If we want a float instead of    \
  99.      a double, we have to make one and point to it instead.  */     \
  100.                                     \
  101.       __rv = (void *) & ((__va).__va_arg < 6                \
  102.              ? (__va).__va_fregs[(__va).__va_arg]        \
  103.              : (__va).__va_stack[(__va).__va_arg - 6]);    \
  104.                                     \
  105.       if (sizeof (__type) == sizeof (float))                \
  106.     {                                \
  107.       float __rf = * ((double *) __rv);                \
  108.                                     \
  109.       __rv = (void *) &__rf;                    \
  110.     }                                \
  111.                                     \
  112.       break;                                \
  113.                                           \
  114.     case __void_type_class:                        \
  115.     case __integer_type_class:                        \
  116.     case __char_type_class:                        \
  117.     case __enumeral_type_class:                        \
  118.     case __boolean_type_class:                        \
  119.     case __pointer_type_class:                        \
  120.     case __reference_type_class:                    \
  121.     case __offset_type_class:                        \
  122.     case __record_type_class:                        \
  123.     case __union_type_class:                        \
  124.                                     \
  125.       /* Force this on the stack if it's alignment isn't right.  */    \
  126.                                     \
  127.       if ((__va).__va_arg < 6)                        \
  128.     switch (sizeof (__type))                    \
  129.       {                                \
  130.       case sizeof (char):                        \
  131.         break;                            \
  132.       case sizeof (short):                        \
  133.         if (__alignof__ (__type) < sizeof (short))            \
  134.           (__va).__va_arg = 6;                    \
  135.         break;                            \
  136.       case 3:                            \
  137.       case sizeof (int):                        \
  138.         if (__alignof__ (__type) < sizeof (int))            \
  139.           (__va).__va_arg = 6;                    \
  140.         break;                            \
  141.       default:                            \
  142.         if (__alignof__ (__type) < sizeof (long))            \
  143.           (__va).__va_arg = 6;                    \
  144.         break;                            \
  145.       }                                \
  146.                                     \
  147.       /* If this object is only one word long, just get it.  If it is   \
  148.      longer, we need to worry about the possibility that it is    \
  149.      passed both in registers and in memory.  */            \
  150.                                     \
  151.       if (sizeof (__type) <= sizeof (long)                \
  152.       || (__va).__va_arg >= 6                    \
  153.       || (__va).__va_arg + __va_nwords (__type) < 6)        \
  154.     __rv = (void *) & ((__va).__va_arg < 6                \
  155.                ? (__va).__va_iregs[(__va).__va_arg]        \
  156.                : (__va).__va_stack[(__va).__va_arg - 6]);    \
  157.       else                                \
  158.     {                                \
  159.       long __obj[__va_nwords (__type)];                \
  160.       int __i;                            \
  161.                                     \
  162.       for (__i = 0; __i < __va_nwords (__type); __i++)        \
  163.         __obj[__i] = ((__va).__va_arg + __i < 6            \
  164.               ? (__va).__va_iregs[(__va).__va_arg + __i]    \
  165.               : (__va).__va_stack[(__va).__va_arg + __i - 6]); \
  166.                                     \
  167.       __rv = (void *) &__obj[0];                    \
  168.     }                                \
  169.       break;                                \
  170.                                     \
  171.     case __complex_type_class:                        \
  172.     case __function_type_class:                        \
  173.     case __method_type_class:                        \
  174.     case __array_type_class:                        \
  175.     case __string_type_class:                        \
  176.     case __set_type_class:                        \
  177.     case __file_type_class:                        \
  178.     case __lang_type_class:                        \
  179.     case __no_type_class:                        \
  180.     default:                                \
  181.     abort ();                            \
  182.     }                                    \
  183.                                     \
  184.   (__va).__va_arg += __va_nwords (__type);                \
  185.                                     \
  186.   __rv;                                    \
  187. }))
  188.  
  189. #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
  190.  
  191.