home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 March / PCWorld_2001-03_cd.bin / Software / TemaCD / devc / _SETUP.6 / Group14 / va-mips.h < prev    next >
C/C++ Source or Header  |  2000-01-21  |  10KB  |  278 lines

  1. /* ---------------------------------------- */
  2. /*           VARARGS  for MIPS/GNU CC       */
  3. /*                                          */
  4. /*                                          */
  5. /*                                          */
  6. /*                                          */
  7. /* ---------------------------------------- */
  8.  
  9.  
  10. /* These macros implement varargs for GNU C--either traditional or ANSI.  */
  11.  
  12. /* Define __gnuc_va_list.  */
  13.  
  14. #ifndef __GNUC_VA_LIST
  15. #define __GNUC_VA_LIST
  16. #if defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)
  17.  
  18. typedef struct {
  19.   /* Pointer to FP regs.  */
  20.   char *__fp_regs;
  21.   /* Number of FP regs remaining.  */
  22.   int __fp_left;
  23.   /* Pointer to GP regs followed by stack parameters.  */
  24.   char *__gp_regs;
  25. } __gnuc_va_list;
  26.  
  27. #else /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
  28.  
  29. typedef char * __gnuc_va_list;
  30.  
  31. #endif /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
  32. #endif /* not __GNUC_VA_LIST */
  33.  
  34. /* If this is for internal libc use, don't define anything but
  35.    __gnuc_va_list.  */
  36. #if defined (_STDARG_H) || defined (_VARARGS_H)
  37.  
  38. #ifndef _VA_MIPS_H_ENUM
  39. #define _VA_MIPS_H_ENUM
  40. enum {
  41.   __no_type_class = -1,
  42.   __void_type_class,
  43.   __integer_type_class,
  44.   __char_type_class,
  45.   __enumeral_type_class,
  46.   __boolean_type_class,
  47.   __pointer_type_class,
  48.   __reference_type_class,
  49.   __offset_type_class,
  50.   __real_type_class,
  51.   __complex_type_class,
  52.   __function_type_class,
  53.   __method_type_class,
  54.   __record_type_class,
  55.   __union_type_class,
  56.   __array_type_class,
  57.   __string_type_class,
  58.   __set_type_class,
  59.   __file_type_class,
  60.   __lang_type_class
  61. };
  62. #endif
  63.  
  64. /* In GCC version 2, we want an ellipsis at the end of the declaration
  65.    of the argument list.  GCC version 1 can't parse it.  */
  66.  
  67. #if __GNUC__ > 1
  68. #define __va_ellipsis ...
  69. #else
  70. #define __va_ellipsis
  71. #endif
  72.  
  73. #ifdef __mips64
  74. #define __va_rounded_size(__TYPE)  \
  75.   (((sizeof (__TYPE) + 8 - 1) / 8) * 8)
  76. #else
  77. #define __va_rounded_size(__TYPE)  \
  78.   (((sizeof (__TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
  79. #endif
  80.  
  81. #ifdef __mips64
  82. #define __va_reg_size 8
  83. #else
  84. #define __va_reg_size 4
  85. #endif
  86.  
  87. /* Get definitions for _MIPS_SIM_ABI64 etc.  */
  88. #ifdef _MIPS_SIM
  89. #include <sgidefs.h>
  90. #endif
  91.  
  92. #ifdef _STDARG_H
  93. #if defined (__mips_eabi)
  94. #if ! defined (__mips_soft_float) && ! defined (__mips_single_float)
  95. #ifdef __mips64
  96. #define va_start(__AP, __LASTARG)                    \
  97.   (__AP.__gp_regs = ((char *) __builtin_next_arg (__LASTARG)        \
  98.              - (__builtin_args_info (2) < 8            \
  99.             ? (8 - __builtin_args_info (2)) * __va_reg_size    \
  100.             : 0)),                        \
  101.    __AP.__fp_left = 8 - __builtin_args_info (3),            \
  102.    __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * __va_reg_size)
  103. #else /* ! defined (__mips64) */
  104. #define va_start(__AP, __LASTARG)                    \
  105.   (__AP.__gp_regs = ((char *) __builtin_next_arg (__LASTARG)        \
  106.              - (__builtin_args_info (2) < 8            \
  107.             ? (8 - __builtin_args_info (2)) * __va_reg_size    \
  108.             : 0)),                        \
  109.    __AP.__fp_left = (8 - __builtin_args_info (3)) / 2,            \
  110.    __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * 8,        \
  111.    __AP.__fp_regs = (char *) ((int) __AP.__fp_regs & -8))
  112. #endif /* ! defined (__mips64) */
  113. #else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float) ) */
  114. #define va_start(__AP, __LASTARG)                    \
  115.   (__AP = ((__gnuc_va_list) __builtin_next_arg (__LASTARG)        \
  116.        - (__builtin_args_info (2) >= 8 ? 0                \
  117.           : (8 - __builtin_args_info (2)) * __va_reg_size)))
  118. #endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float) ) */
  119. #else /* ! defined (__mips_eabi) */
  120. #define va_start(__AP, __LASTARG) \
  121.   (__AP = (__gnuc_va_list) __builtin_next_arg (__LASTARG))
  122. #endif /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
  123. #else /* ! _STDARG_H */
  124. #define va_alist  __builtin_va_alist
  125. #ifdef __mips64
  126. /* This assumes that `long long int' is always a 64 bit type.  */
  127. #define va_dcl    long long int __builtin_va_alist; __va_ellipsis
  128. #else
  129. #define va_dcl    int __builtin_va_alist; __va_ellipsis
  130. #endif
  131. #if defined (__mips_eabi)
  132. #if ! defined (__mips_soft_float) && ! defined (__mips_single_float)
  133. #ifdef __mips64
  134. #define va_start(__AP)                            \
  135.   (__AP.__gp_regs = ((char *) __builtin_next_arg ()            \
  136.              - (__builtin_args_info (2) < 8            \
  137.             ? (8 - __builtin_args_info (2)) * __va_reg_size    \
  138.             : __va_reg_size)),                \
  139.    __AP.__fp_left = 8 - __builtin_args_info (3),            \
  140.    __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * __va_reg_size)
  141. #else /* ! defined (__mips64) */
  142. #define va_start(__AP)                            \
  143.   (__AP.__gp_regs = ((char *) __builtin_next_arg ()            \
  144.              - (__builtin_args_info (2) < 8            \
  145.             ? (8 - __builtin_args_info (2)) * __va_reg_size    \
  146.             : __va_reg_size)),                \
  147.    __AP.__fp_left = (8 - __builtin_args_info (3)) / 2,            \
  148.    __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * 8,        \
  149.    __AP.__fp_regs = (char *) ((int) __AP.__fp_regs & -8))
  150. #endif /* ! defined (__mips64) */
  151. #else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
  152. #define va_start(__AP)                            \
  153.   (__AP = ((__gnuc_va_list) __builtin_next_arg ()            \
  154.        - (__builtin_args_info (2) >= 8 ? __va_reg_size        \
  155.           : (8 - __builtin_args_info (2)) * __va_reg_size)))
  156. #endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
  157. /* Need alternate code for _MIPS_SIM_ABI64.  */
  158. #elif defined(_MIPS_SIM) && (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32)
  159. #define va_start(__AP)                            \
  160.   (__AP = (__gnuc_va_list) __builtin_next_arg ()            \
  161.    + (__builtin_args_info (2) >= 8 ? -8 : 0))
  162. #else
  163. #define va_start(__AP)  __AP = (char *) &__builtin_va_alist
  164. #endif
  165. #endif /* ! _STDARG_H */
  166.  
  167. #ifndef va_end
  168. void va_end (__gnuc_va_list);        /* Defined in libgcc.a */
  169. #endif
  170. #define va_end(__AP)    ((void)0)
  171.  
  172. #if defined (__mips_eabi)
  173.  
  174. #if ! defined (__mips_soft_float) && ! defined (__mips_single_float)
  175. #ifdef __mips64
  176. #define __va_next_addr(__AP, __type)                    \
  177.   ((__builtin_classify_type (*(__type *) 0) == __real_type_class    \
  178.     && __AP.__fp_left > 0)                        \
  179.    ? (--__AP.__fp_left, (__AP.__fp_regs += 8) - 8)            \
  180.    : (__AP.__gp_regs += __va_reg_size) - __va_reg_size)
  181. #else
  182. #define __va_next_addr(__AP, __type)                    \
  183.   ((__builtin_classify_type (*(__type *) 0) == __real_type_class    \
  184.     && __AP.__fp_left > 0)                        \
  185.    ? (--__AP.__fp_left, (__AP.__fp_regs += 8) - 8)            \
  186.    : (((__builtin_classify_type (* (__type *) 0) < __record_type_class    \
  187.     && __alignof__ (__type) > 4)                    \
  188.        ? __AP.__gp_regs = (char *) (((int) __AP.__gp_regs + 8 - 1) & -8) \
  189.        : (char *) 0),                            \
  190.       (__builtin_classify_type (* (__type *) 0) >= __record_type_class    \
  191.        ? (__AP.__gp_regs += __va_reg_size) - __va_reg_size        \
  192.        : ((__AP.__gp_regs += __va_rounded_size (__type))        \
  193.       - __va_rounded_size (__type)))))
  194. #endif
  195. #else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
  196. #ifdef __mips64
  197. #define __va_next_addr(__AP, __type)                    \
  198.   ((__AP += __va_reg_size) - __va_reg_size)
  199. #else
  200. #define __va_next_addr(__AP, __type)                    \
  201.   (((__builtin_classify_type (* (__type *) 0) < __record_type_class    \
  202.      && __alignof__ (__type) > 4)                    \
  203.     ? __AP = (char *) (((__PTRDIFF_TYPE__) __AP + 8 - 1) & -8)        \
  204.     : (char *) 0),                            \
  205.    (__builtin_classify_type (* (__type *) 0) >= __record_type_class    \
  206.     ? (__AP += __va_reg_size) - __va_reg_size                \
  207.     : ((__AP += __va_rounded_size (__type))                \
  208.        - __va_rounded_size (__type))))
  209. #endif
  210. #endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
  211.  
  212. #ifdef __MIPSEB__
  213. #define va_arg(__AP, __type)                        \
  214.   ((__va_rounded_size (__type) <= __va_reg_size)            \
  215.    ? *(__type *) (void *) (__va_next_addr (__AP, __type)        \
  216.                + __va_reg_size                \
  217.                - sizeof (__type))                \
  218.    : (__builtin_classify_type (*(__type *) 0) >= __record_type_class    \
  219.       ? **(__type **) (void *) (__va_next_addr (__AP, __type)        \
  220.                 + __va_reg_size                \
  221.                 - sizeof (char *))            \
  222.       : *(__type *) (void *) __va_next_addr (__AP, __type)))
  223. #else
  224. #define va_arg(__AP, __type)                        \
  225.   ((__va_rounded_size (__type) <= __va_reg_size)            \
  226.    ? *(__type *) (void *) __va_next_addr (__AP, __type)        \
  227.    : (__builtin_classify_type (* (__type *) 0) >= __record_type_class    \
  228.       ? **(__type **) (void *) __va_next_addr (__AP, __type)        \
  229.       : *(__type *) (void *) __va_next_addr (__AP, __type)))
  230. #endif
  231.  
  232. #else /* ! defined (__mips_eabi) */
  233.  
  234. /* We cast to void * and then to TYPE * because this avoids
  235.    a warning about increasing the alignment requirement.  */
  236. /* The __mips64 cases are reversed from the 32 bit cases, because the standard
  237.    32 bit calling convention left-aligns all parameters smaller than a word,
  238.    whereas the __mips64 calling convention does not (and hence they are
  239.    right aligned).  */
  240. #ifdef __mips64
  241. #ifdef __MIPSEB__
  242. #define va_arg(__AP, __type)                                    \
  243.   ((__type *) (void *) (__AP = (char *)                         \
  244.                        ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8) \
  245.                + __va_rounded_size (__type))))[-1]
  246. #else
  247. #define va_arg(__AP, __type)                                    \
  248.   ((__AP = (char *) ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8)    \
  249.              + __va_rounded_size (__type))),        \
  250.    *(__type *) (void *) (__AP - __va_rounded_size (__type)))
  251. #endif
  252.  
  253. #else /* not __mips64 */
  254.  
  255. #ifdef __MIPSEB__
  256. /* For big-endian machines.  */
  257. #define va_arg(__AP, __type)                    \
  258.   ((__AP = (char *) ((__alignof__ (__type) > 4            \
  259.               ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8    \
  260.               : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)    \
  261.              + __va_rounded_size (__type))),        \
  262.    *(__type *) (void *) (__AP - __va_rounded_size (__type)))
  263. #else
  264. /* For little-endian machines.  */
  265. #define va_arg(__AP, __type)                            \
  266.   ((__type *) (void *) (__AP = (char *) ((__alignof__(__type) > 4        \
  267.                 ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8        \
  268.                 : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)    \
  269.                      + __va_rounded_size(__type))))[-1]
  270. #endif
  271. #endif
  272. #endif /* ! defined (__mips_eabi)  */
  273.  
  274. /* Copy __gnuc_va_list into another variable of this type.  */
  275. #define __va_copy(dest, src) (dest) = (src)
  276.  
  277. #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
  278.