do not use TYucent for struct copies (#21175)

This commit is contained in:
Walter Bright 2025-04-08 00:41:31 -07:00 committed by GitHub
parent a52d7f0e36
commit c1eeb9b170
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 20 deletions

View file

@ -1144,6 +1144,7 @@ void cdind(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
void cdstreq(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
{
//printf("cdstreq(e = %p, pretregs = %s)\n", e, regm_str(pretregs));
//elem_print(e);
char need_DS = false;
elem* e1 = e.E1;
elem* e2 = e.E2;
@ -1194,45 +1195,44 @@ void cdstreq(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
cdst.index = NOREG;
cdst.reg = NOREG;
ulong offset;
while (numbytes >= REGSIZE)
{
loadFromEA(csrc,reg,8,8);
cdb.gen1(csrc.Iop);
cdb.genc1(csrc.Iop,0,FL.offset,offset);
storeToEA(cdst,reg,8);
cdb.gen1(cdst.Iop);
csrc.IEV1.Voffset += REGSIZE;
cdst.IEV1.Voffset += REGSIZE;
cdb.genc1(cdst.Iop,0,FL.offset,offset);
offset += REGSIZE;
numbytes -= REGSIZE;
}
while (numbytes >= 4)
{
loadFromEA(csrc,reg,4,4);
cdb.gen1(csrc.Iop);
cdb.genc1(csrc.Iop,0,FL.offset,offset);
storeToEA(cdst,reg,4);
cdb.gen1(cdst.Iop);
csrc.IEV1.Voffset += 4;
cdst.IEV1.Voffset += 4;
cdb.genc1(csrc.Iop,0,FL.offset,offset);
offset += 4;
numbytes -= 4;
}
while (numbytes >= 2)
{
loadFromEA(csrc,reg,4,2);
cdb.gen1(csrc.Iop);
cdb.genc1(csrc.Iop,0,FL.offset,offset);
storeToEA(cdst,reg,2);
csrc.IEV1.Voffset += 2;
cdb.gen1(cdst.Iop);
cdst.IEV1.Voffset += 2;
cdb.genc1(csrc.Iop,0,FL.offset,offset);
offset += 2;
numbytes -= 2;
}
if (numbytes)
{
loadFromEA(csrc,reg,4,1);
cdb.gen1(csrc.Iop);
cdb.genc1(csrc.Iop,0,FL.offset,offset);
storeToEA(cdst,reg,1);
cdb.gen1(cdst.Iop);
cdb.genc1(csrc.Iop,0,FL.offset,offset);
}
}
else

View file

@ -1523,14 +1523,15 @@ void assignaddrc(code* c)
L2:
offset = cast(int)offset; // sign extend
// Load/store register (unsigned immediate) https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#ldst_pos
uint opc = field(ins,23,22);
uint shift = field(ins,31,30); // 0:1 1:2 2:4 3:8 shift for imm12
uint op24 = field(ins,25,24);
//printf("offset: %lld localsize: %lld REGSIZE*2: %d\n", offset, localsize, REGSIZE*2);
if (cgstate.hasframe)
offset += REGSIZE * 2;
offset += localsize;
L3:
// Load/store register (unsigned immediate) https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#ldst_pos
uint opc = field(ins,23,22);
uint shift = field(ins,31,30); // 0:1 1:2 2:4 3:8 shift for imm12
uint op24 = field(ins,25,24);
if (field(ins,28,23) == 0x22) // Add/subtract (immediate)
{
uint imm12 = field(ins,21,10); // unsigned 12 bits
@ -1588,7 +1589,8 @@ void assignaddrc(code* c)
case FL.offset:
c.IFL1 = FL.const_;
break;
offset = c.IEV1.Voffset;
goto L3;
case FL.localsize: // used by inline assembler
c.IEV1.Vpointer += localsize;

View file

@ -3604,7 +3604,7 @@ elem* elstruct(elem* e, Goal goal)
goto Ldefault;
case 16:
if (I64 && (ty == TYstruct || (ty == TYarray && config.exe == EX_WIN64)))
if (I64 && (ty == TYstruct || (ty == TYarray && config.exe == EX_WIN64)) && !cgstate.AArch64)
{
tym = TYucent;
goto L1;
@ -3641,6 +3641,8 @@ elem* elstruct(elem* e, Goal goal)
{
if (tyfloating(tybasic(targ1.Tty)))
tym = TYcdouble;
else if (cgstate.AArch64)
goto Ldefault;
else
tym = TYucent;
if ((0 == tyfloating(targ1.Tty)) ^ (0 == tyfloating(targ2.Tty)))