Skip to content

Commit a13aba5

Browse files
authored
Merge branch 'dlang:master' into master
2 parents 7a81c97 + 27c5f80 commit a13aba5

File tree

22 files changed

+361
-102
lines changed

22 files changed

+361
-102
lines changed

compiler/src/dmd/backend/arm/cod2.d

Lines changed: 96 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,11 +1254,11 @@ void cdmemset(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
12541254
auto remainder = numbytes & (REGSIZE - 1);
12551255
if (remainder >= 4)
12561256
{
1257-
cdb.gen1(INSTR.ldst_immpost(3,0,0,4,dstreg,valuereg)); // STR valuereg,[dstreg],#4 // *dstreg++ = valuereg
1257+
cdb.gen1(INSTR.ldst_immpost(2,0,0,4,dstreg,valuereg)); // STR valuereg,[dstreg],#4 // *dstreg++ = valuereg
12581258
remainder -= 4;
12591259
}
12601260
for (; remainder; --remainder)
1261-
cdb.gen1(INSTR.ldst_immpost(3,0,0,1,dstreg,valuereg)); // STR valuereg,[dstreg],#0 // *dstreg++ = valuereg
1261+
cdb.gen1(INSTR.ldst_immpost(0,0,0,1,dstreg,valuereg)); // STRB valuereg,[dstreg],#1 // *dstreg++ = valuereg
12621262
fixresult(cdb,e,retregs,pretregs);
12631263
return;
12641264
}
@@ -1424,8 +1424,8 @@ private void cdmemsetn(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pr
14241424
@trusted
14251425
void cdstreq(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
14261426
{
1427-
//printf("cdstreq(e = %p, pretregs = %s)\n", e, regm_str(pretregs));
1428-
//elem_print(e);
1427+
printf("cdstreq(e = %p, pretregs = %s)\n", e, regm_str(pretregs));
1428+
elem_print(e);
14291429
char need_DS = false;
14301430
elem* e1 = e.E1;
14311431
elem* e2 = e.E2;
@@ -1467,101 +1467,136 @@ void cdstreq(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
14671467

14681468
regm_t regm = cg.allregs & ~(srcregs | dstregs);
14691469
allocreg(cdb, regm, TYint);
1470-
reg_t reg = findreg(regm);
1470+
reg_t Rv = findreg(regm);
1471+
1472+
reg_t Rs = findreg(srcregs);
1473+
reg_t Rd = findreg(dstregs);
14711474

14721475
getregs(cdb,srcregs | dstregs | regm);
14731476
if (numbytes <= REGSIZE * 7)
14741477
{
14751478
code csrc;
1476-
csrc.base = findreg(srcregs);
1479+
csrc.base = Rs;
14771480
csrc.index = NOREG;
14781481
csrc.reg = NOREG;
14791482

14801483
code cdst;
1481-
cdst.base = findreg(dstregs);
1484+
cdst.base = Rd;
14821485
cdst.index = NOREG;
14831486
cdst.reg = NOREG;
14841487

14851488
ulong offset;
14861489

14871490
while (numbytes >= REGSIZE)
14881491
{
1489-
loadFromEA(csrc,reg,8,8);
1492+
loadFromEA(csrc,Rv,8,8);
14901493
cdb.genc1(csrc.Iop,0,FL.offset,offset);
1491-
storeToEA(cdst,reg,8);
1494+
storeToEA(cdst,Rv,8);
14921495
cdb.genc1(cdst.Iop,0,FL.offset,offset);
14931496
offset += REGSIZE;
14941497
numbytes -= REGSIZE;
14951498
}
14961499

14971500
while (numbytes >= 4)
14981501
{
1499-
loadFromEA(csrc,reg,4,4);
1502+
loadFromEA(csrc,Rv,4,4);
15001503
cdb.genc1(csrc.Iop,0,FL.offset,offset);
1501-
storeToEA(cdst,reg,4);
1504+
storeToEA(cdst,Rv,4);
15021505
cdb.genc1(csrc.Iop,0,FL.offset,offset);
15031506
offset += 4;
15041507
numbytes -= 4;
15051508
}
15061509

15071510
while (numbytes >= 2)
15081511
{
1509-
loadFromEA(csrc,reg,4,2);
1512+
loadFromEA(csrc,Rv,4,2);
15101513
cdb.genc1(csrc.Iop,0,FL.offset,offset);
1511-
storeToEA(cdst,reg,2);
1514+
storeToEA(cdst,Rv,2);
15121515
cdb.genc1(csrc.Iop,0,FL.offset,offset);
15131516
offset += 2;
15141517
numbytes -= 2;
15151518
}
15161519

15171520
if (numbytes)
15181521
{
1519-
loadFromEA(csrc,reg,4,1);
1522+
loadFromEA(csrc,Rv,4,1);
15201523
cdb.genc1(csrc.Iop,0,FL.offset,offset);
1521-
storeToEA(cdst,reg,1);
1524+
storeToEA(cdst,Rv,1);
15221525
cdb.genc1(csrc.Iop,0,FL.offset,offset);
15231526
}
15241527
}
15251528
else
15261529
{
1527-
if (e1) assert(0); // TODO AArch64
1528-
static if (1)
1529-
{
1530+
/*
1531+
mov Rc, #count*8
1532+
mov Ri, #0x0
1533+
L2: ldr Rv, [Rs, Ri]
1534+
str Rv, [Rd, Ri]
1535+
add Ri, Ri, #8
1536+
cmp Ri, Rc
1537+
b.ne L2
1538+
*/
1539+
15301540
uint remainder = numbytes & (REGSIZE - 1);
15311541
numbytes /= REGSIZE; // number of words
1532-
getregs_imm(cdb,mCX);
1533-
movregconst(cdb,CX,numbytes,0); // # of bytes/words
1534-
cdb.gen1(0xF3); // REP
1535-
if (REGSIZE == 8)
1536-
cdb.gen1(REX | REX_W);
1537-
cdb.gen1(0xA5); // REP MOVSD
1538-
cgstate.regimmed_set(CX,0); // note that CX == 0
1539-
if (I64 && remainder >= 4)
1542+
1543+
regm_t iregs = cg.allregs & ~(srcregs | dstregs | regm);
1544+
reg_t Ri = allocreg(cdb,iregs,TYnptr);
1545+
1546+
regm_t cregs = cg.allregs & ~(srcregs | dstregs | regm | iregs);
1547+
reg_t Rc = allocreg(cdb,cregs,TYnptr);
1548+
1549+
code csrc;
1550+
csrc.base = Rs;
1551+
csrc.index = Ri;
1552+
csrc.reg = NOREG;
1553+
csrc.Sextend = 3; // LSL
1554+
1555+
code cdst;
1556+
cdst.base = Rd;
1557+
cdst.index = Ri;
1558+
cdst.reg = NOREG;
1559+
cdst.Sextend = 3; // LSL
1560+
1561+
movregconst(cdb,Rc,numbytes * 8,0); // mov Rc,#count * 8
1562+
movregconst(cdb,Ri,0,0); // mov Ri,0
1563+
1564+
loadFromEA(csrc,Rv,8,8); // L2: ldr Rv,[Rs,Ri]
1565+
cdb.genc1(csrc.Iop,0,FL.unde,0);
1566+
code* L2 = cdb.last();
1567+
storeToEA(cdst,Rv,8); // str Rv,[Rd,Ri]
1568+
cdb.genc1(cdst.Iop,0,FL.unde,0);
1569+
1570+
cdb.gen1(INSTR.add_addsub_imm(1,0,8,Ri,Ri)); // add Ri,Ri,#0x8 https://www.scs.stanford.edu/~zyedidia/arm64/add_addsub_imm.html
1571+
cdb.gen1(INSTR.cmp_shift(0,Rc,0,0,Ri)); // cmp Ri,Rc
1572+
genBranch(cdb,COND.ne,FL.code,cast(block*)L2); // b.ne L2
1573+
1574+
uint offset = 0;
1575+
if (remainder & 4)
15401576
{
1541-
cdb.gen1(0xA5); // MOVSD
1542-
remainder -= 4;
1577+
loadFromEA(csrc,Rv,4,4); // ldr Rv,[Rs,Ri]
1578+
cdb.genc1(csrc.Iop,0,FL.unde,offset);
1579+
storeToEA(cdst,Rv,4); // str Rv,[Rd,Ri]
1580+
cdb.genc1(cdst.Iop,0,FL.unde,offset);
1581+
cdb.gen1(INSTR.add_addsub_imm(1,0,4,Ri,Ri)); // add Ri,Ri,#0x4 https://www.scs.stanford.edu/~zyedidia/arm64/add_addsub_imm.html
1582+
offset += 4;
15431583
}
1544-
for (; remainder; remainder--)
1584+
if (remainder & 2)
15451585
{
1546-
cdb.gen1(0xA4); // MOVSB
1586+
loadFromEA(csrc,Rv,2,2); // ldrh Rv,[Rs,Ri]
1587+
cdb.genc1(csrc.Iop,0,FL.unde,offset);
1588+
storeToEA(cdst,Rv,2); // strh Rv,[Rd,Ri]
1589+
cdb.genc1(cdst.Iop,0,FL.unde,offset);
1590+
cdb.gen1(INSTR.add_addsub_imm(1,0,2,Ri,Ri)); // add Ri,Ri,#0x2 https://www.scs.stanford.edu/~zyedidia/arm64/add_addsub_imm.html
1591+
offset += 2;
15471592
}
1548-
}
1549-
else
1550-
{
1551-
uint movs;
1552-
if (numbytes & (REGSIZE - 1)) // if odd
1553-
movs = 0xA4; // MOVSB
1554-
else
1593+
if (remainder & 1)
15551594
{
1556-
movs = 0xA5; // MOVSW
1557-
numbytes /= REGSIZE; // # of words
1595+
loadFromEA(csrc,Rv,1,1); // ldrb Rv,[Rs,Ri]
1596+
cdb.genc1(csrc.Iop,0,FL.unde,offset);
1597+
storeToEA(cdst,Rv,1); // strb Rv,[Rd,Ri]
1598+
cdb.genc1(cdst.Iop,0,FL.unde,offset);
15581599
}
1559-
getregs_imm(cdb,mCX);
1560-
movregconst(cdb,CX,numbytes,0); // # of bytes/words
1561-
cdb.gen1(0xF3); // REP
1562-
cdb.gen1(movs);
1563-
cgstate.regimmed_set(CX,0); // note that CX == 0
1564-
}
15651600
}
15661601
assert(!(pretregs & mPSW));
15671602
if (pretregs)
@@ -1570,7 +1605,7 @@ else
15701605
//cdb.genc2(0x81,(rex << 16) | modregrm(3,5,DI), type_size(e.ET)); // SUB DI,numbytes
15711606

15721607
const tym = tybasic(e.Ety);
1573-
if (tym == TYucent && I64)
1608+
if (tym == TYucent)
15741609
{
15751610
/* https://issues.dlang.org/show_bug.cgi?id=22175
15761611
* The trouble happens when the struct size does not fit exactly into
@@ -1579,30 +1614,30 @@ else
15791614
*/
15801615

15811616
// dereference DI
1582-
code cs;
1583-
cs.Iop = 0x8B;
1584-
regm_t retregs = pretregs;
1617+
regm_t retregs = pretregs & ~srcregs;
1618+
if (!retregs)
1619+
retregs = cgstate.allregs & ~srcregs;
15851620
allocreg(cdb,retregs,tym);
15861621

15871622
reg_t msreg = findreg(retregs & INSTR.MSW);
1588-
buildEA(&cs,DI,-1,1,REGSIZE);
1589-
code_newreg(&cs,msreg);
1590-
cs.Irex |= REX_W;
1591-
cdb.gen(&cs); // MOV msreg,REGSIZE[DI] // msreg is never DI
1623+
1624+
code cs;
1625+
cs.base = Rs;
1626+
cs.index = NOREG;
1627+
cs.reg = NOREG;
1628+
1629+
loadFromEA(cs,msreg,8,8); // ldr msreg,[Rs,REGSIZE]
1630+
cdb.genc1(cs.Iop,0,FL.offset,REGSIZE);
15921631

15931632
reg_t lsreg = findreg(retregs & INSTR.LSW);
1594-
buildEA(&cs,DI,-1,1,0);
1595-
code_newreg(&cs,lsreg);
1596-
cs.Irex |= REX_W;
1597-
cdb.gen(&cs); // MOV lsreg,[DI];
1633+
loadFromEA(cs,lsreg,8,8); // ldr lsreg,[Rs]
1634+
cdb.genc1(cs.Iop,0,FL.offset,0);
1635+
15981636
fixresult(cdb,e,retregs,pretregs);
15991637
return;
16001638
}
16011639

1602-
regm_t retregs = mDI;
1603-
if (pretregs & INSTR.MSW && !(config.exe & EX_flat))
1604-
retregs |= mES;
1605-
fixresult(cdb,e,retregs,pretregs);
1640+
fixresult(cdb,e,dstregs,pretregs);
16061641
}
16071642
}
16081643

compiler/src/dmd/backend/arm/cod3.d

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,7 +1714,7 @@ void assignaddrc(code* c)
17141714
if (field(ins,28,23) == 0x22) // Add/subtract (immediate)
17151715
{
17161716
uint imm12 = field(ins,21,10); // unsigned 12 bits
1717-
//printf("imm12: %d offset: %llx\n", imm12, offset);
1717+
//printf("imm12: %x offset: %llx\n", imm12, offset);
17181718
imm12 += offset;
17191719
assert(imm12 < 0x1000);
17201720
ins = setField(ins,21,10,imm12);
@@ -1738,7 +1738,7 @@ void assignaddrc(code* c)
17381738
else
17391739
{
17401740
imm12 = cast(uint)(offset >> shift);
1741-
//printf("imm12: x%x\n", imm12);
1741+
//printf("offset: %llu x%llx shift: %d imm12: x%x\n", offset,offset,shift,imm12);
17421742
assert(imm12 < 0x1000);
17431743
ins = setField(ins,21,10,imm12);
17441744
}
@@ -1768,7 +1768,10 @@ void assignaddrc(code* c)
17681768
ins = setField(ins,20,12,imm9);
17691769
}
17701770
else
1771+
{
1772+
disassemble(ins);
17711773
assert(0);
1774+
}
17721775

17731776
Rn = cast(reg_t)field(ins,9,5);
17741777
Rt = cast(reg_t)field(ins,4,0);

0 commit comments

Comments
 (0)