Showing with 38 additions and 4 deletions.
  1. +38 −4 src/backend/cgelem.c
42 changes: 38 additions & 4 deletions src/backend/cgelem.c
Original file line number Diff line number Diff line change
Expand Up @@ -3303,7 +3303,6 @@ STATIC elem * eleq(elem *e, goal_t goal)
unsigned t,w,b;
unsigned sz;
elem *l,*l2,*r,*r2,*e1,*eres;
tym_t tyl;

#if SCPP
goal_t wantres = goal;
Expand Down Expand Up @@ -3332,7 +3331,7 @@ STATIC elem * eleq(elem *e, goal_t goal)
* so that garbage doesn't creep into the extra 2 bytes
* and throw off compares.
*/
tyl = tybasic(e1->Ety);
tym_t tyl = tybasic(e1->Ety);
if (e1->Eoper == OPvar && (tyl == TYldouble || tyl == TYildouble || tyl == TYcldouble))
{
#if 1
Expand Down Expand Up @@ -3516,8 +3515,43 @@ STATIC elem * eleq(elem *e, goal_t goal)
e2->E2 = es;
e2->Eoper = OPxor;
return optelem(e,GOALvalue);

L8: ;
}

// Replace (a=(r1 pair r2)) with (a1=r1), (a2=r2)
if (tysize(e1->Ety) == 2 * REGSIZE &&
e1->Eoper == OPvar &&
(e2->Eoper == OPpair || e2->Eoper == OPrpair) &&
goal == GOALnone
)
{
tym_t ty = (REGSIZE == 8) ? TYllong : TYint;
ty |= e1->Ety & ~mTYbasic;
e2->Ety = ty;
e->Ety = ty;
e1->Ety = ty;
elem *eb = el_copytree(e1);
eb->EV.sp.Voffset += REGSIZE;

if (e2->Eoper == OPpair)
{
e->E2 = e2->E1;
eb = el_bin(OPeq,ty,eb,e2->E2);
e2->E1 = eb;
e2->E2 = e;
}
else
{
e->E2 = e2->E2;
eb = el_bin(OPeq,ty,eb,e2->E1);
e2->E1 = eb;
e2->E2 = e;
}

e2->Eoper = OPcomma;
return optelem(e2,goal);
}
L8: ;
}

if (e1->Eoper == OPcomma)
Expand All @@ -3533,7 +3567,7 @@ STATIC elem * eleq(elem *e, goal_t goal)
t = e->Ety;
l = e1->E1; /* lvalue */
r = e->E2;
tyl = l->Ety;
tym_t tyl = l->Ety;
sz = tysize(tyl) * 8;
w = (e1->E2->EV.Vuns >> 8); /* width in bits of field */
m = ((targ_ullong)1 << w) - 1; // mask w bits wide
Expand Down