[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Tinycc-devel] [PATCH] deprecating VT_REF
From: |
Michael Matz |
Subject: |
Re: [Tinycc-devel] [PATCH] deprecating VT_REF |
Date: |
Sat, 21 Feb 2015 22:40:16 +0100 (CET) |
User-agent: |
Alpine 2.00 (LNX 1167 2008-08-23) |
Hi,
On Fri, 20 Feb 2015, Edmund Grimley Evans wrote:
VT_REF is not mentioned in the documentation and seems to be used only
for x86_64. Also, it seems to be the same thing as VT_LLOCAL, really.
This could be a first step towards removing it altogether.
Commit message:
Make it explicit that VT_REF is used only for TCC_TARGET_X86_64.
tcc.h: Make the definition conditional on TCC_TARGET_X86_64.
tccgen.c: Since the VT_REF bit is set only in x86_64-gen.c we
can make clearing it and testing for it conditional.
I don't like this. tccgen.c should become _less_ dependend on the TARGET
defines, not more. Hence either VT_REF has a purpose and it might make
sense to use it in more backends, or it hasn't and should be removed also
from x86_64. And _if_ it has a purpose only on x86-64 (which indeed seems
unlikely) then the common code should still handle it unconditionally.
FWIW it's currently only used when TCC_TARGET_PE, i.e. win64.
It was introduced by grischka in 2010 for some win64 va_arg handling of
structure types (8d107d9ff) and fixed a bit later with f115c123.
AFAIU VT_REF is added when an argument is passed in a caller allocated
buffer whose address itself is passed in a register (i.e.
by-reference-passing). So the register contains not the argument
itself, but the address of it. That's not a too unusual ABI (x86-64
linux, though, uses passing on stack, not by reference), as it can
sometimes avoid a memcpy when calling such functions. And yes, that seems
to be VT_LLOCAL.
grischka, can you try the below patch on win64? If it works we can remove
VT_REF altogether. I verified it generates the same code with a
cross-to-win64 tcc on functions where it should be active, like:
struct S {int x[7];};
int f (
#ifndef IN_REGS
int a, int b, int c, int d,
#endif
struct S s)
{
return s.x[3];
}
(with -DIN_REGS the address is passed in rcx, without it's passed on
stack).
Ciao,
Michael.
----------
diff --git a/x86_64-gen.c b/x86_64-gen.c
index c8fed85..463cf8d 100644
--- a/x86_64-gen.c
+++ b/x86_64-gen.c
@@ -855,7 +855,7 @@ void gfunc_prolog(CType *func_type)
if (reg_param_index < REGN) {
gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL,
addr);
}
- sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL | VT_REF,
addr);
+ sym_push(sym->v & ~SYM_FIELD, type, VT_LVAL | VT_LLOCAL, addr);
} else {
if (reg_param_index < REGN) {
/* save arguments passed by register */