From 4e04f67c94c97b4f28a4d73759a0ad38fb3a10f7 Mon Sep 17 00:00:00 2001 From: seyko Date: Thu, 14 May 2015 07:32:24 +0300 Subject: fix-mixed-struct (patch by Pip Cet) Jsut for testing. It works for me (don't break anything) Small fixes for x86_64-gen.c in "tccpp: fix issues, add tests" are dropped in flavor of this patch. Pip Cet: Okay, here's a first patch that fixes the problem (but I've found another bug, yet unfixed, in the process), though it's not particularly pretty code (I tried hard to keep the changes to the minimum necessary). If we decide to actually get rid of VT_QLONG and VT_QFLOAT (please, can we?), there are some further simplifications in tccgen.c that might offset some of the cost of this patch. The idea is that an integer is no longer enough to describe how an argument is stored in registers. There are a number of possibilities (none, integer register, two integer registers, float register, two float registers, integer register plus float register, float register plus integer register), and instead of enumerating them I've introduced a RegArgs type that stores the offsets for each of our registers (for the other architectures, it's simply an int specifying the number of registers). If someone strongly prefers an enum, we could do that instead, but I believe this is a place where keeping things general is worth it, because this way it should be doable to add SSE or AVX support. There is one line in the patch that looks suspicious: } else { addr = (addr + align - 1) & -align; param_addr = addr; addr += size; - sse_param_index += reg_count; } break; However, this actually fixes one half of a bug we have when calling a function with eight double arguments "interrupted" by a two-double structure after the seventh double argument: f(double,double,double,double,double,double,double,struct { double x,y; },double); In this case, the last argument should be passed in %xmm7. This patch fixes the problem in gfunc_prolog, but not the corresponding problem in gfunc_call, which I'll try tackling next. --- arm64-gen.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'arm64-gen.c') diff --git a/arm64-gen.c b/arm64-gen.c index 0c435d9..62447e7 100644 --- a/arm64-gen.c +++ b/arm64-gen.c @@ -14,6 +14,8 @@ // Number of registers available to allocator: #define NB_REGS 28 // x0-x18, x30, v0-v7 +typedef int RegArgs; + #define TREG_R(x) (x) // x = 0..18 #define TREG_R30 19 #define TREG_F(x) (x + 20) // x = 0..7 @@ -1196,8 +1198,15 @@ ST_FUNC void gen_va_arg(CType *t) } } -ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize) +ST_FUNC int regargs_nregs(RegArgs *args) { + return *args; +} + +ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize, RegArgs *args) +{ + *args = 0; + return 0; } -- cgit v1.3.1