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.
This commit is contained in:
8
tcc.h
8
tcc.h
@ -796,8 +796,8 @@ struct TCCState {
|
||||
#define VT_LLONG 12 /* 64 bit integer */
|
||||
#define VT_LONG 13 /* long integer (NEVER USED as type, only
|
||||
during parsing) */
|
||||
#define VT_QLONG 14 /* 128-bit integer. Only used for x86-64 ABI */
|
||||
#define VT_QFLOAT 15 /* 128-bit float. Only used for x86-64 ABI */
|
||||
#define VT_QLONG 14 /* 128-bit integer. No longer used. */
|
||||
#define VT_QFLOAT 15 /* 128-bit float. No longer used. */
|
||||
#define VT_UNSIGNED 0x0010 /* unsigned type */
|
||||
#define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
|
||||
#define VT_BITFIELD 0x0040 /* bitfield modifier */
|
||||
@ -1267,6 +1267,7 @@ ST_FUNC void save_regs(int n);
|
||||
ST_FUNC void gaddrof(void);
|
||||
ST_FUNC int gv(int rc);
|
||||
ST_FUNC void gv2(int rc1, int rc2);
|
||||
ST_FUNC void vdup(void);
|
||||
ST_FUNC void vpop(void);
|
||||
ST_FUNC void gen_op(int op);
|
||||
ST_FUNC int type_size(CType *type, int *a);
|
||||
@ -1355,7 +1356,8 @@ ST_FUNC void gsym_addr(int t, int a);
|
||||
ST_FUNC void gsym(int t);
|
||||
ST_FUNC void load(int r, SValue *sv);
|
||||
ST_FUNC void store(int r, SValue *v);
|
||||
ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize);
|
||||
ST_FUNC int regargs_nregs(RegArgs *args);
|
||||
ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize, RegArgs *args);
|
||||
ST_FUNC void gfunc_call(int nb_args);
|
||||
ST_FUNC void gfunc_prolog(CType *func_type);
|
||||
ST_FUNC void gfunc_epilog(void);
|
||||
|
||||
Reference in New Issue
Block a user