diff options
| author | Daniel Glöckner <daniel-gl@gmx.net> | 2016-10-08 18:54:42 +0200 |
|---|---|---|
| committer | Daniel Glöckner <daniel-gl@gmx.net> | 2016-10-08 19:03:01 +0200 |
| commit | 6775c7cb3a6d87c2c048ce9d128e16b6aad42f7b (patch) | |
| tree | 2cc923a5cc42a96b738010530b1721e7288a4ea3 /tccgen.c | |
| parent | c09b6ce975190dfef22943ffeb0502f4d217e269 (diff) | |
| download | tinycc-6775c7cb3a6d87c2c048ce9d128e16b6aad42f7b.tar.gz tinycc-6775c7cb3a6d87c2c048ce9d128e16b6aad42f7b.tar.bz2 | |
tccgen.c: fix multi-register structure return when not on stack
We need to preserve the type of the pointer to the structure, f.ex.
when a global structure is returned.
This is not a perfect solution. Registers loaded in the first iteration
might be overwritten in a following iteration as the register is no
longer on vtop. This is not a problem for ARM32 as gfunc_sret returns
a maximum of 1 in the integer case.
Diffstat (limited to 'tccgen.c')
| -rw-r--r-- | tccgen.c | 23 |
1 files changed, 14 insertions, 9 deletions
@@ -5111,16 +5111,21 @@ static void block(int *bsym, int *csym, int is_expr) else r = RC_IRET; - for (;;) { + if (ret_nregs == 1) gv(r); - if (--ret_nregs == 0) - break; - /* We assume that when a structure is returned in multiple - registers, their classes are consecutive values of the - suite s(n) = 2^n */ - r <<= 1; - vtop->c.i += regsize; - vtop->r = VT_LOCAL | VT_LVAL; + else { + for (;;) { + vdup(); + gv(r); + vpop(); + if (--ret_nregs == 0) + break; + /* We assume that when a structure is returned in multiple + registers, their classes are consecutive values of the + suite s(n) = 2^n */ + r <<= 1; + vtop->c.i += regsize; + } } } } else if (is_float(func_vt.t)) { |
