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)
 |