stdarg.h
3.84 KB
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
#ifndef __STDARG_H__
#define __STDARG_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Copyright (C) 1987,1989 Silicon Graphics, Inc. All rights reserved. */
/* ------------------------------------------------------------------ */
/* | Copyright Unpublished, MIPS Computer Systems, Inc. All Rights | */
/* | Reserved. This software contains proprietary and confidential | */
/* | information of MIPS and its suppliers. Use, disclosure or | */
/* | reproduction is prohibited without the prior express written | */
/* | consent of MIPS. | */
/* ------------------------------------------------------------------ */
/* #ident "$Revision: 1.1.1.1 $" */
/* ANSI C Notes:
*
* - THE IDENTIFIERS APPEARING OUTSIDE OF #ifdef __EXTENSIONS__ IN THIS
* standard header ARE SPECIFIED BY ANSI! CONFORMANCE WILL BE ALTERED
* IF ANY NEW IDENTIFIERS ARE ADDED TO THIS AREA UNLESS THEY ARE IN ANSI's
* RESERVED NAMESPACE. (i.e., unless they are prefixed by __[a-z] or
* _[A-Z]. For external objects, identifiers with the prefix _[a-z]
* are also reserved.)
*
* - At each call to a function with a variable number of arguments,
* either the function definition or prototype must be visible.
*/
#ifndef _VA_LIST_
#define _VA_LIST_
typedef char *va_list;
#endif /* !_VA_LIST_ */
#define va_end(__list)
#if defined(_CFE)
#if defined(__STDC__) && (__STDC__ != 0 )
/* va_start makes list point past the parmN */
#define va_start(list, parmN) (list = ((char *)&parmN + sizeof(parmN)))
#else
#define va_start(list, name) (void) (list = (void *)((char *)&...))
#endif
/* align p at least to 4-byte alignment, or a if a is larger */
#define _VA_ALIGN(p,a) (((unsigned int)(((char *)p)+((a)>4?(a-1):3))) & ~(unsigned int)((a)>4?(a-1):3))
/*
** "va_stack_arg" is the old MIPS va_arg, which we fall back
** on when we're dealing with arguments on the stack.
*/
#define __va_stack_arg(list,mode)\
(\
((list)=(char *)_VA_ALIGN(list,__builtin_alignof(mode))+ \
_VA_ALIGN(sizeof(mode),4)), \
(((char *)list) - (_VA_ALIGN(sizeof(mode),4) - sizeof(mode))) \
)
/*
** "_va_double_arg" checks the status in the lower-order 2 bits
** of the "list" pointer, and correctly extracts arguments with
** type double either from the arguements stack, or from the
** floating point argument register spill area.
*/
#define __va_double_arg(list,mode) (\
(((int)list & 0x1) /* 1 byte aligned? */ \
?(list = (char *)((int)list + 7),(char *)((int)list-6-_VA_FP_SAVE_AREA))\
:(((int)list & 0x2) /* 2 byte aligned? */ \
?(list = (char *)((int)list +10),(char *)((int)list-24-_VA_FP_SAVE_AREA)) :__va_stack_arg(list,mode) )))
/* +++++++++++++++++++++++++++++++++++++++++++
Because of parameter passing conventions in C:
use mode=int for char, and short types
use mode=double for float types
use a pointer for array types
+++++++++++++++++++++++++++++++++++++++++++ */
#define _INT 0
#define _FP 1
#define _STRUCT 2
#define va_arg(list,mode) ((mode*)(\
((__builtin_classof(mode)==_FP && \
__builtin_alignof(mode)==sizeof(double)) \
? __va_double_arg(list,mode)\
: __va_stack_arg(list,mode))))[-1]
#else /* !_CFE */
/* these with with both ANSI and traditional SGI C */
#define va_start(__list, __parmN) (__list = (char *) \
( \
(__builtin_alignof(__parmN) == 8) ? \
(((unsigned int)&__parmN + sizeof(__parmN) + 8 - 1) & (~0x7) ) : \
(((unsigned int)&__parmN + ((sizeof(__parmN) > 4)?sizeof(__parmN):4) + 4 - 1) & (~0x3)) \
) \
)
#define va_arg(__list, __mode) ((__mode *)(__list = (char *) \
( \
(__builtin_alignof(__mode) == 8) ? \
(((unsigned int)__list + sizeof(__mode) + 8 - 1) & (~0x7) ) : \
(((unsigned int)__list + ((sizeof(__mode) > 4)?sizeof(__mode):4) + 4 - 1) & (~0x3)) \
) \
)) [-1]
#endif /* !_CFE */
#ifdef __cplusplus
}
#endif
#endif /* !__STDARG_H__ */