History

Fix "Add support for struct > 4B returned via registers"

- avoid assumption "ret_align == register_size" which is false for non-arm targets - rename symbol "sret" to more descriptive "ret_nregs" This fixes commit dcec8673f21da86ae3dcf1ca3e9498127715b795

grischka committed 12 years ago

Commit fbc88101 parent 46dd2973 files · +31 −16Browse files

Unified · Split

3 files
  1. i386-gen.c +1 −1
  2. tccgen.c +28 −15
  3. win32/include/math.h +2 −0
i386-gen.c+1−1
@@ -392,7 +392,7 @@ ST_FUNC int gfunc_sret(CType *vt, CType *ret, int *ret_align) · 391 unmodified lines
392 } else {392 } else {
393 ret->ref = NULL;393 ret->ref = NULL;
394 ret->t = VT_INT;394 ret->t = VT_INT;
395 return 0;395 return 1;
396 }396 }
397#else397#else
398 *ret_align = 1; // Never have to re-align return values for x86398 *ret_align = 1; // Never have to re-align return values for x86
tccgen.c+28−15
@@ -3927,7 +3927,7 @@ ST_FUNC void unary(void) · 3926 unmodified lines
3927 } else if (tok == '(') {3927 } else if (tok == '(') {
3928 SValue ret;3928 SValue ret;
3929 Sym *sa;3929 Sym *sa;
3930 int nb_args, sret, ret_align;3930 int nb_args, ret_nregs, ret_align;
3931 3931
3932 /* function call */3932 /* function call */
3933 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {3933 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
@@ -3951,8 +3951,8 @@ ST_FUNC void unary(void) · 17 unmodified lines
3951 ret.r2 = VT_CONST;3951 ret.r2 = VT_CONST;
3952 /* compute first implicit argument if a structure is returned */3952 /* compute first implicit argument if a structure is returned */
3953 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {3953 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3954 sret = gfunc_sret(&s->type, &ret.type, &ret_align);3954 ret_nregs = gfunc_sret(&s->type, &ret.type, &ret_align);
3955 if (!sret) {3955 if (!ret_nregs) {
3956 /* get some space for the returned structure */3956 /* get some space for the returned structure */
3957 size = type_size(&s->type, &align);3957 size = type_size(&s->type, &align);
3958 loc = (loc - size) & -align;3958 loc = (loc - size) & -align;
@@ -3965,11 +3965,11 @@ ST_FUNC void unary(void) · 6 unmodified lines
3965 nb_args++;3965 nb_args++;
3966 }3966 }
3967 } else {3967 } else {
3968 sret = 1;3968 ret_nregs = 1;
3969 ret.type = s->type;3969 ret.type = s->type;
3970 }3970 }
3971 3971
3972 if (sret) {3972 if (ret_nregs) {
3973 /* return in register */3973 /* return in register */
3974 if (is_float(ret.type.t)) {3974 if (is_float(ret.type.t)) {
3975 ret.r = reg_fret(ret.type.t);3975 ret.r = reg_fret(ret.type.t);
@@ -4008,23 +4008,30 @@ ST_FUNC void unary(void) · 32 unmodified lines
4008 } else {4008 } else {
4009 vtop -= (nb_args + 1);4009 vtop -= (nb_args + 1);
4010 }4010 }
4011
4011 /* return value */4012 /* return value */
4012 for (r = ret.r + sret + !sret; r-- > ret.r;) {4013 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
4013 vsetc(&ret.type, r, &ret.c);4014 vsetc(&ret.type, r, &ret.c);
4014 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */4015 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
4015 }4016 }
4017
4016 /* handle packed struct return */4018 /* handle packed struct return */
4017 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && sret) {4019 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
4018 int addr, offset;4020 int addr, offset;
4019 4021
4020 size = type_size(&s->type, &align);4022 size = type_size(&s->type, &align);
4021 loc = (loc - size) & -align;4023 loc = (loc - size) & -align;
4022 addr = loc;4024 addr = loc;
4023 for(offset = 0; offset < size; offset += ret_align) {4025 offset = 0;
4026 for (;;) {
4024 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);4027 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
4025 vswap();4028 vswap();
4026 vstore();4029 vstore();
4027 vtop--;4030 vtop--;
4031 if (--ret_nregs == 0)
4032 break;
4033 /* XXX: compatible with arm only: ret_align == register_size */
4034 offset += ret_align;
4028 }4035 }
4029 vset(&s->type, VT_LOCAL | VT_LVAL, addr);4036 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4030 }4037 }
@@ -4596,8 +4603,9 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 565 unmodified lines
4596 gen_assign_cast(&func_vt);4603 gen_assign_cast(&func_vt);
4597 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {4604 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4598 CType type, ret_type;4605 CType type, ret_type;
4599 int ret_align;4606 int ret_align, ret_nregs;
4600 if (!gfunc_sret(&func_vt, &ret_type, &ret_align)) {4607 ret_nregs = gfunc_sret(&func_vt, &ret_type, &ret_align);
4608 if (0 == ret_nregs) {
4601 /* if returning structure, must copy it to implicit4609 /* if returning structure, must copy it to implicit
4602 first pointer arg location */4610 first pointer arg location */
4603 type = func_vt;4611 type = func_vt;
@@ -4609,7 +4617,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 5 unmodified lines
4609 vstore();4617 vstore();
4610 } else {4618 } else {
4611 /* returning structure packed into registers */4619 /* returning structure packed into registers */
4612 int r, size, addr, offset, align;4620 int r, size, addr, align;
4613 size = type_size(&func_vt,&align);4621 size = type_size(&func_vt,&align);
4614 if ((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & (ret_align-1)))4622 if ((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & (ret_align-1)))
4615 && (align & (ret_align-1))) {4623 && (align & (ret_align-1))) {
@@ -4626,11 +4634,16 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 10 unmodified lines
4626 r = rc_fret(ret_type.t);4634 r = rc_fret(ret_type.t);
4627 else4635 else
4628 r = RC_IRET;4636 r = RC_IRET;
4629 /* We assume that when a structure is returned in multiple4637
4630 registers, their classes are consecutive values of the4638 for (;;) {
4631 suite s(n) = 2^n */
4632 for (offset = 0; offset < size; offset += ret_align, r<<=1) {
4633 gv(r);4639 gv(r);
4640 if (--ret_nregs == 0)
4641 break;
4642 /* We assume that when a structure is returned in multiple
4643 registers, their classes are consecutive values of the
4644 suite s(n) = 2^n */
4645 r <<= 1;
4646 /* XXX: compatible with arm only: ret_align == register_size */
4634 vtop->c.i += ret_align;4647 vtop->c.i += ret_align;
4635 vtop->r = VT_LOCAL | VT_LVAL;4648 vtop->r = VT_LOCAL | VT_LVAL;
4636 }4649 }
win32/include/math.h+2−0
@@ -666,6 +666,7 @@ extern "C" { · 665 unmodified lines
666 extern long double __cdecl fmal (long double, long double, long double);666 extern long double __cdecl fmal (long double, long double, long double);
667 667
668 668
669#if 0 // gr: duplicate, see below
669 /* 7.12.14 */670 /* 7.12.14 */
670 /* 671 /*
671 * With these functions, comparisons involving quiet NaNs set the FP672 * With these functions, comparisons involving quiet NaNs set the FP
@@ -708,6 +709,7 @@ extern "C" { · 36 unmodified lines
708 & 0x4500) == 0x4500)709 & 0x4500) == 0x4500)
709 710
710#endif711#endif
712#endif //0
711 713
712 714
713#endif /* __STDC_VERSION__ >= 199901L */715#endif /* __STDC_VERSION__ >= 199901L */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t