diff options
Diffstat (limited to 'tccgen.c')
| -rw-r--r-- | tccgen.c | 20 |
1 files changed, 12 insertions, 8 deletions
@@ -4153,7 +4153,7 @@ ST_FUNC void unary(void) } else if (tok == '(') { SValue ret; Sym *sa; - int nb_args, ret_nregs, ret_align, variadic; + int nb_args, ret_nregs, ret_align, regsize, variadic; /* function call */ if ((vtop->type.t & VT_BTYPE) != VT_FUNC) { @@ -4179,7 +4179,7 @@ ST_FUNC void unary(void) if ((s->type.t & VT_BTYPE) == VT_STRUCT) { variadic = (s->c == FUNC_ELLIPSIS); ret_nregs = gfunc_sret(&s->type, variadic, &ret.type, - &ret_align); + &ret_align, ®size); if (!ret_nregs) { /* get some space for the returned structure */ size = type_size(&s->type, &align); @@ -4259,6 +4259,10 @@ ST_FUNC void unary(void) int addr, offset; size = type_size(&s->type, &align); + /* We're writing whole regs often, make sure there's enough + space. Assume register size is power of 2. */ + if (regsize > align) + align = regsize; loc = (loc - size) & -align; addr = loc; offset = 0; @@ -4269,8 +4273,7 @@ ST_FUNC void unary(void) vtop--; if (--ret_nregs == 0) break; - /* XXX: compatible with arm only: ret_align == register_size */ - offset += ret_align; + offset += regsize; } vset(&s->type, VT_LOCAL | VT_LVAL, addr); } @@ -4850,9 +4853,9 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, #else if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { CType type, ret_type; - int ret_align, ret_nregs; + int ret_align, ret_nregs, regsize; ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type, - &ret_align); + &ret_align, ®size); if (0 == ret_nregs) { /* if returning structure, must copy it to implicit first pointer arg location */ @@ -4890,9 +4893,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, /* We assume that when a structure is returned in multiple registers, their classes are consecutive values of the suite s(n) = 2^n */ + /* XXX This seems confused, if r == 0, this never + changes r. */ r <<= 1; - /* XXX: compatible with arm only: ret_align == register_size */ - vtop->c.i += ret_align; + vtop->c.i += regsize; vtop->r = VT_LOCAL | VT_LVAL; } } |
