mirror of
https://github.com/mirror/tinycc.git
synced 2025-01-15 05:20:06 +08:00
windows style fastcall (Filip Navara)
This commit is contained in:
parent
81f957ae09
commit
e9c64e3f47
23
i386-gen.c
23
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 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
|
/* Generate function call. The function address is pushed first, then
|
||||||
all the parameters in call order. This functions pops all the
|
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_sym = vtop->type.ref;
|
||||||
func_call = func_sym->r;
|
func_call = func_sym->r;
|
||||||
/* fast call case */
|
/* 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;
|
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++) {
|
for(i = 0;i < fastcall_nb_regs; i++) {
|
||||||
if (args_size <= 0)
|
if (args_size <= 0)
|
||||||
break;
|
break;
|
||||||
o(0x58 + fastcall_regs[i]); /* pop r */
|
o(0x58 + fastcall_regs_ptr[i]); /* pop r */
|
||||||
/* XXX: incorrect for struct/floats */
|
/* XXX: incorrect for struct/floats */
|
||||||
args_size -= 4;
|
args_size -= 4;
|
||||||
}
|
}
|
||||||
@ -409,6 +418,7 @@ void gfunc_prolog(CType *func_type)
|
|||||||
{
|
{
|
||||||
int addr, align, size, func_call, fastcall_nb_regs;
|
int addr, align, size, func_call, fastcall_nb_regs;
|
||||||
int param_index, param_addr;
|
int param_index, param_addr;
|
||||||
|
uint8_t *fastcall_regs_ptr;
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
CType *type;
|
CType *type;
|
||||||
|
|
||||||
@ -418,8 +428,13 @@ void gfunc_prolog(CType *func_type)
|
|||||||
loc = 0;
|
loc = 0;
|
||||||
if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
|
if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
|
||||||
fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
|
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 {
|
} else {
|
||||||
fastcall_nb_regs = 0;
|
fastcall_nb_regs = 0;
|
||||||
|
fastcall_regs_ptr = NULL;
|
||||||
}
|
}
|
||||||
param_index = 0;
|
param_index = 0;
|
||||||
|
|
||||||
@ -449,7 +464,7 @@ void gfunc_prolog(CType *func_type)
|
|||||||
/* save FASTCALL register */
|
/* save FASTCALL register */
|
||||||
loc -= 4;
|
loc -= 4;
|
||||||
o(0x89); /* movl */
|
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;
|
param_addr = loc;
|
||||||
} else {
|
} else {
|
||||||
param_addr = addr;
|
param_addr = addr;
|
||||||
|
6
tcc.c
6
tcc.c
@ -249,6 +249,7 @@ typedef struct AttributeDef {
|
|||||||
#define FUNC_FASTCALL1 2 /* first param in %eax */
|
#define FUNC_FASTCALL1 2 /* first param in %eax */
|
||||||
#define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
|
#define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
|
||||||
#define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
|
#define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
|
||||||
|
#define FUNC_FASTCALLW 5 /* first parameter in %ecx, %edx */
|
||||||
|
|
||||||
/* field 'Sym.t' for macros */
|
/* field 'Sym.t' for macros */
|
||||||
#define MACRO_OBJ 0 /* object like macro */
|
#define MACRO_OBJ 0 /* object like macro */
|
||||||
@ -6428,6 +6429,11 @@ static void parse_attribute(AttributeDef *ad)
|
|||||||
ad->func_call = FUNC_FASTCALL1 + n - 1;
|
ad->func_call = FUNC_FASTCALL1 + n - 1;
|
||||||
skip(')');
|
skip(')');
|
||||||
break;
|
break;
|
||||||
|
case TOK_FASTCALL1:
|
||||||
|
case TOK_FASTCALL2:
|
||||||
|
case TOK_FASTCALL3:
|
||||||
|
ad->func_call = FUNC_FASTCALLW;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case TOK_DLLEXPORT:
|
case TOK_DLLEXPORT:
|
||||||
ad->dllexport = 1;
|
ad->dllexport = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user