[Top][All Lists]

[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)


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,
        struct S s)
  return s.x[3];

(with -DIN_REGS the address is passed in rcx, without it's passed on stack).

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, 
-            sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL | VT_REF, 
+            sym_push(sym->v & ~SYM_FIELD, type, VT_LVAL | VT_LLOCAL, addr);
         } else {
             if (reg_param_index < REGN) {
                 /* save arguments passed by register */

reply via email to

[Prev in Thread] Current Thread [Next in Thread]