windows style fastcall (Filip Navara)

This commit is contained in:
bellard 2005-09-03 22:21:22 +00:00
parent 81f957ae09
commit e9c64e3f47
2 changed files with 25 additions and 4 deletions

View File

@ -321,6 +321,7 @@ static void gcall_or_jmp(int is_jmp)
}
static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX };
/* Generate function call. The function address is pushed first, then
all the parameters in call order. This functions pops all the
@ -381,13 +382,21 @@ void gfunc_call(int nb_args)
func_sym = vtop->type.ref;
func_call = func_sym->r;
/* fast call case */
if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
func_call == FUNC_FASTCALLW) {
int fastcall_nb_regs;
uint8_t *fastcall_regs_ptr;
if (func_call == FUNC_FASTCALLW) {
fastcall_regs_ptr = fastcallw_regs;
fastcall_nb_regs = 2;
} else {
fastcall_regs_ptr = fastcall_regs;
fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
}
for(i = 0;i < fastcall_nb_regs; i++) {
if (args_size <= 0)
break;
o(0x58 + fastcall_regs[i]); /* pop r */
o(0x58 + fastcall_regs_ptr[i]); /* pop r */
/* XXX: incorrect for struct/floats */
args_size -= 4;
}
@ -409,6 +418,7 @@ void gfunc_prolog(CType *func_type)
{
int addr, align, size, func_call, fastcall_nb_regs;
int param_index, param_addr;
uint8_t *fastcall_regs_ptr;
Sym *sym;
CType *type;
@ -418,8 +428,13 @@ void gfunc_prolog(CType *func_type)
loc = 0;
if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
fastcall_regs_ptr = fastcall_regs;
} else if (func_call == FUNC_FASTCALLW) {
fastcall_nb_regs = 2;
fastcall_regs_ptr = fastcallw_regs;
} else {
fastcall_nb_regs = 0;
fastcall_regs_ptr = NULL;
}
param_index = 0;
@ -449,7 +464,7 @@ void gfunc_prolog(CType *func_type)
/* save FASTCALL register */
loc -= 4;
o(0x89); /* movl */
gen_modrm(fastcall_regs[param_index], VT_LOCAL, NULL, loc);
gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc);
param_addr = loc;
} else {
param_addr = addr;

6
tcc.c
View File

@ -249,6 +249,7 @@ typedef struct AttributeDef {
#define FUNC_FASTCALL1 2 /* first param in %eax */
#define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
#define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
#define FUNC_FASTCALLW 5 /* first parameter in %ecx, %edx */
/* field 'Sym.t' for macros */
#define MACRO_OBJ 0 /* object like macro */
@ -6428,6 +6429,11 @@ static void parse_attribute(AttributeDef *ad)
ad->func_call = FUNC_FASTCALL1 + n - 1;
skip(')');
break;
case TOK_FASTCALL1:
case TOK_FASTCALL2:
case TOK_FASTCALL3:
ad->func_call = FUNC_FASTCALLW;
break;
#endif
case TOK_DLLEXPORT:
ad->dllexport = 1;