blob: fd0e182a14090e4fa73aa7187e831b17d4b552b5 (
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
|
typedef struct {
char gpr;
char fpr;
char reserved[2];
char* input_arg_area;
char* reg_save_area;
} va_list[1];
typedef enum {
ARGPOINTER,
WORD,
DOUBLEWORD,
REAL,
} _va_arg_type;
#define ALIGN(addr, amount) (((unsigned int)(addr) + ((amount)-1)) & ~((amount)-1))
void* __va_arg(va_list ap, _va_arg_type type) {
char* addr;
char* curGprPtr = &(ap->gpr);
int curGpr = ap->gpr;
int max = 8;
int size = 4;
int inc = 1;
int even = 0;
int fprOffset = 0;
int regSize = 4;
if (type == 3) {
curGprPtr = &(ap->fpr);
curGpr = ap->fpr;
size = 8;
fprOffset = 8 * 4;
regSize = 8;
}
if (type == 2) {
size = 8;
max = max - 1;
if (curGpr & 1)
even = 1;
inc = 2;
}
if (curGpr < max) {
curGpr += even;
addr = ap->reg_save_area + fprOffset + (curGpr * regSize);
*curGprPtr = curGpr + inc;
} else {
*curGprPtr = 8;
addr = ap->input_arg_area;
addr = (char*)ALIGN(addr, size);
ap->input_arg_area = addr + size;
}
if (type == ARGPOINTER)
addr = *((char**)addr);
return addr;
}
|