@@ -28,6 +28,7 @@ import core.stdc.stdlib;
2828import core.stdc.string ;
2929
3030import dmd.backend.cc;
31+ import dmd.backend.code;
3132import dmd.backend.cdef;
3233import dmd.backend.code_x86;
3334import dmd.backend.oper;
@@ -3484,14 +3485,6 @@ elem * elstruct(elem *e, goal_t goal)
34843485
34853486 uint sz = (e.Eoper == OPstrpar && type_zeroSize(t, global_tyf)) ? 0 : cast (uint )type_size(t);
34863487 // printf("\tsz = %d\n", (int)sz);
3487- if (sz == 16 )
3488- {
3489- while (ty == TYarray && t.Tdim == 1 )
3490- {
3491- t = t.Tnext;
3492- ty = tybasic(t.Tty);
3493- }
3494- }
34953488
34963489 type * targ1 = null ;
34973490 type * targ2 = null ;
@@ -3501,6 +3494,13 @@ elem * elstruct(elem *e, goal_t goal)
35013494 targ2 = t.Ttag.Sstruct.Sarg2type;
35023495 }
35033496
3497+ if (ty == TYarray && sz && config.exe != EX_WIN64 )
3498+ {
3499+ argtypes(t, targ1, targ2);
3500+ if (! targ1)
3501+ goto Ldefault;
3502+ goto L1 ;
3503+ }
35043504 // if (targ1) { printf("targ1\n"); type_print(targ1); }
35053505 // if (targ2) { printf("targ2\n"); type_print(targ2); }
35063506 switch (cast (int )sz)
@@ -3521,7 +3521,7 @@ elem * elstruct(elem *e, goal_t goal)
35213521 {
35223522 goto L1 ;
35233523 }
3524- if (e.Eoper == OPstrpar && I64 && ty == TYstruct )
3524+ if (I64 && config.exe != EX_WIN64 )
35253525 {
35263526 goto L1 ;
35273527 }
@@ -3542,7 +3542,7 @@ elem * elstruct(elem *e, goal_t goal)
35423542 case 13 :
35433543 case 14 :
35443544 case 15 :
3545- if (e.Eoper == OPstrpar && I64 && ty == TYstruct && config.exe != EX_WIN64 )
3545+ if (I64 && config.exe != EX_WIN64 )
35463546 {
35473547 goto L1 ;
35483548 }
@@ -3577,8 +3577,9 @@ elem * elstruct(elem *e, goal_t goal)
35773577 goto Ldefault;
35783578
35793579 L1 :
3580- if (ty == TYstruct)
3581- { // This needs to match what TypeFunction::retStyle() does
3580+ if (ty == TYstruct || ty == TYarray)
3581+ {
3582+ // This needs to match what TypeFunction::retStyle() does
35823583 if (config.exe == EX_WIN64 )
35833584 {
35843585 // if (t.Ttag.Sstruct.Sflags & STRnotpod)
@@ -3603,13 +3604,38 @@ elem * elstruct(elem *e, goal_t goal)
36033604 tym = TYcdouble;
36043605 else
36053606 tym = TYucent;
3607+ if ((0 == tyfloating(targ1.Tty)) ^ (0 == tyfloating(targ2.Tty)))
3608+ {
3609+ tym |= tyfloating(targ1.Tty) ? mTYxmmgpr : mTYgprxmm;
3610+ }
36063611 }
3612+ else if (I32 && targ1 && targ2)
3613+ tym = TYllong;
36073614 assert (tym != TYstruct);
36083615 }
36093616 assert (tym != ~ 0 );
36103617 switch (e.Eoper)
36113618 {
36123619 case OPstreq:
3620+ if (sz != tysize(tym))
3621+ {
3622+ // we can't optimize OPstreq in this case,
3623+ // there will be memory corruption in the assignment
3624+ elem * e2 = e.EV .E2 ;
3625+ if (e2.Eoper != OPvar && e2.Eoper != OPind)
3626+ {
3627+ // the source may come in registers. ex: returned from a function.
3628+ assert (tyaggregate(e2.Ety));
3629+ e2 = optelem(e2, GOALvalue);
3630+ e2 = elstruct(e2, GOALvalue);
3631+ e2 = exp2_copytotemp(e2); // (tmp = e2, tmp)
3632+ e2.EV .E2 .EV .Vsym.Sfl = FLauto;
3633+ e2.Ety = e2.EV .E2 .Ety = e.Ety;
3634+ e2.ET = e2.EV .E2 .ET = e.ET ;
3635+ e.EV .E2 = e2;
3636+ }
3637+ break ;
3638+ }
36133639 e.Eoper = OPeq;
36143640 e.Ety = (e.Ety & ~ mTYbasic) | tym;
36153641 elstructwalk(e.EV .E1 ,tym);
@@ -6141,6 +6167,8 @@ private elem *elToPair(elem *e)
61416167 */
61426168 tym_t ty0;
61436169 tym_t ty = e.Ety;
6170+ if (ty & (mTYxmmgpr | mTYgprxmm))
6171+ break ; // register allocation doesn't support it yet.
61446172 switch (tybasic(ty))
61456173 {
61466174 case TYcfloat: ty0 = TYfloat | (ty & ~ mTYbasic); goto L1 ;
@@ -6167,6 +6195,8 @@ private elem *elToPair(elem *e)
61676195 */
61686196 tym_t ty0;
61696197 tym_t ty = e.Ety;
6198+ if (ty & (mTYxmmgpr | mTYgprxmm))
6199+ break ; // register allocation doesn't support it yet.
61706200 switch (tybasic(ty))
61716201 {
61726202 case TYcfloat: ty0 = TYfloat | (ty & ~ mTYbasic); goto L2 ;
0 commit comments