changeset 387:eaf3c68531af

[project @ 2005-09-03 22:21:22 by bellard] windows style fastcall (Filip Navara)
author bellard
date Sat, 03 Sep 2005 22:21:22 +0000
parents df250e9d55a8
children 25f4a44d713f
files i386-gen.c tcc.c
diffstat 2 files changed, 25 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/i386-gen.c	Sat Sep 03 22:18:51 2005 +0000
+++ b/i386-gen.c	Sat Sep 03 22:21:22 2005 +0000
@@ -321,6 +321,7 @@
 }
 
 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 @@
     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 @@
 {
     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 @@
     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 @@
             /* 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;
--- a/tcc.c	Sat Sep 03 22:18:51 2005 +0000
+++ b/tcc.c	Sat Sep 03 22:21:22 2005 +0000
@@ -249,6 +249,7 @@
 #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 @@
                 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;