aboutsummaryrefslogtreecommitdiff
path: root/i386-gen.c
diff options
context:
space:
mode:
authorbellard <bellard>2005-09-03 22:21:22 +0000
committerbellard <bellard>2005-09-03 22:21:22 +0000
commite9c64e3f473a29324988169f7fcffeff49649a96 (patch)
tree9d1098f4de5f8f61646b5d43ad0f627181b2c0b4 /i386-gen.c
parent81f957ae09642e4b8425c830a3444b464fb4aae4 (diff)
downloadtinycc-e9c64e3f473a29324988169f7fcffeff49649a96.tar.gz
tinycc-e9c64e3f473a29324988169f7fcffeff49649a96.tar.bz2
windows style fastcall (Filip Navara)
Diffstat (limited to 'i386-gen.c')
-rw-r--r--i386-gen.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/i386-gen.c b/i386-gen.c
index 515c888..b1024a7 100644
--- a/i386-gen.c
+++ b/i386-gen.c
@@ -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;
- fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
+ 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;