aboutsummaryrefslogtreecommitdiff
path: root/gcc/ginclude/va-alpha.h
blob: 2a4ba60b53235b5e7bfa7380a7da19d12f521f1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* GNU C varargs and stdargs support for the DEC Alpha.  */

/* Note:  We must use the name __builtin_savregs.  GCC attaches special
   significance to that name.  In particular, regardless of where in a
   function __builtin_saveregs is called, GCC moves the call up to the
   very start of the function.  */

/* Define __gnuc_va_list.  */

#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST


/* In VMS, __gnuc_va_list is simply char *; on OSF, it's a structure.  */

#ifdef __VMS__
typedef char *__gnuc_va_list;
#else

typedef struct {
  char *__base;			/* Pointer to first integer register. */
  int __offset;			/* Byte offset of args so far. */
} __gnuc_va_list;
#endif

#endif /* not __GNUC_VA_LIST */

/* If this is for internal libc use, don't define anything but
   __gnuc_va_list.  */
#if defined (_STDARG_H) || defined (_VARARGS_H)

#define va_list __gnuc_va_list
#define _VA_LIST
#define _VA_LIST_

#if !defined(_STDARG_H)

/* varargs support */
#define va_alist __builtin_va_alist
#define va_dcl	 int __builtin_va_alist;...
#ifdef __VMS__
#define va_start(pvar) ((pvar) = __builtin_saveregs ())
#else
#define va_start(pvar) ((pvar) = * (__gnuc_va_list *) __builtin_saveregs ())
#endif

#else /* STDARG.H */

/* ANSI alternative.  */

/* Call __builtin_next_arg even though we aren't using its value, so that
   we can verify that firstarg is correct.  */

#ifdef __VMS__
#define va_start(pvar, firstarg)				\
  (__builtin_next_arg (firstarg),				\
   (pvar) = __builtin_saveregs ())
#else
#define va_start(pvar, firstarg)				\
  (__builtin_next_arg (firstarg),				\
   (pvar) = *(__gnuc_va_list *) __builtin_saveregs ())
#endif

#endif /* _STDARG_H */

#ifndef va_end

#define va_end(__va)	((void) 0)

/* Values returned by __builtin_classify_type.  */

enum {
  __no_type_class = -1,
  __void_type_class,
  __integer_type_class,
  __char_type_class,
  __enumeral_type_class,
  __boolean_type_class,
  __pointer_type_class,
  __reference_type_class,
  __offset_type_class,
  __real_type_class,
  __complex_type_class,
  __function_type_class,
  __method_type_class,
  __record_type_class,
  __union_type_class,
  __array_type_class,
  __string_type_class,
  __set_type_class,
  __file_type_class,
  __lang_type_class
};

#endif

/* Note that parameters are always aligned at least to a word boundary
   (when passed) regardless of what GCC's __alignof__ operator says.  */

/* Avoid errors if compiling GCC v2 with GCC v1.  */
#if __GNUC__ == 1
#define __extension__
#endif

/* Get the size of a type in bytes, rounded up to an integral number
   of words.  */

#define __va_tsize(__type)  \
  (((sizeof (__type) + __extension__ sizeof (long long) - 1)   \
    / __extension__ sizeof (long long)) * __extension__ sizeof (long long))

#ifdef __VMS__
#define va_arg(__va, __type)						\
(*(((__va) += __va_tsize (__type)),					\
   (__type *)(void *)((__va) - __va_tsize (__type))))

#else

#define va_arg(__va, __type)						\
(*(((__va).__offset += __va_tsize (__type)),				\
   (__type *)(void *)((__va).__base + (__va).__offset			\
	      - (((__builtin_classify_type (* (__type *) 0)		\
		   == __real_type_class) && (__va).__offset <= (6 * 8))	\
		 ? (6 * 8) + 8 : __va_tsize (__type)))))
#endif

/* Copy __gnuc_va_list into another variable of this type.  */
#define __va_copy(dest, src) (dest) = (src)

#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */