31 lines
1.2 KiB
C
31 lines
1.2 KiB
C
#ifndef _VA_LIST
|
|
#define _VA_LIST
|
|
typedef char *va_list;
|
|
#endif
|
|
|
|
// Function arguments are just words for now, because all goes through
|
|
// @pusha and our types are still 1 or 2 bytes long. Except structs, but
|
|
// LCC silently converts those to pointers before pushing on the stack
|
|
// (by virtue of gt1IR.want_argsb=0 in Utils/lcc/src/gt1.md).
|
|
// XXX This means that va_arg() gets it WRONG now for any passed structs!
|
|
// We can use our non-standard va_sarg() as a workaround.
|
|
|
|
#define _va_sizeof(var) ((sizeof(var) + 1U) & ~1U)
|
|
|
|
// Initialize an argument pointer
|
|
#define va_start(ap, last) (void) ((ap) = (va_list)&(last) +\
|
|
_va_sizeof(last))
|
|
|
|
// Fetch argument and advance argument pointer
|
|
#define va_arg(ap, type) * (type*) ( ((ap) += _va_sizeof(type))\
|
|
- _va_sizeof(type) )
|
|
|
|
// Use this macro (only) for struct types, for example as follows:
|
|
// struct xy p;
|
|
// p = va_sarg(ap, struct xy);
|
|
#define va_sarg(ap, stype) ** (stype**)( ((ap) += _va_sizeof(stype*))\
|
|
- _va_sizeof(stype*) )
|
|
|
|
// Optional cleanup up
|
|
#define va_end(ap) ((void) 0)
|