Skip to content

Commit c6fca39

Browse files
WalterBrightthewilsonator
authored andcommitted
implement cdstreq()
1 parent c933fdd commit c6fca39

3 files changed

Lines changed: 112 additions & 62 deletions

File tree

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

Lines changed: 90 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -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,132 @@ 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+
1554+
code cdst;
1555+
csrc.base = Rd;
1556+
csrc.index = Ri;
1557+
csrc.reg = NOREG;
1558+
1559+
movregconst(cdb,Rc,numbytes * 8,0); // mov Rc,#count * 8
1560+
movregconst(cdb,Ri,0,0); // mov Ri,0
1561+
1562+
loadFromEA(csrc,Rv,8,8); // L2: ldr Rv,[Rs,Ri]
1563+
cdb.genc1(csrc.Iop,0,FL.offset,0);
1564+
code* L2 = cdb.last();
1565+
storeToEA(cdst,Rv,8); // str Rv,[Rd,Ri]
1566+
cdb.genc1(cdst.Iop,0,FL.offset,0);
1567+
1568+
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
1569+
cdb.gen1(INSTR.cmp_shift(0,Rc,0,0,Ri)); // cmp Ri,Rc
1570+
genBranch(cdb,COND.ne,FL.code,cast(block*)L2); // b.ne L2
1571+
1572+
uint offset = 0;
1573+
if (remainder & 4)
15401574
{
1541-
cdb.gen1(0xA5); // MOVSD
1542-
remainder -= 4;
1575+
loadFromEA(csrc,Rv,4,4); // ldr Rv,[Rs,Ri]
1576+
cdb.genc1(csrc.Iop,0,FL.offset,offset);
1577+
storeToEA(cdst,Rv,4); // str Rv,[Rd,Ri]
1578+
cdb.genc1(cdst.Iop,0,FL.offset,offset);
1579+
offset += 4;
15431580
}
1544-
for (; remainder; remainder--)
1581+
if (remainder & 2)
15451582
{
1546-
cdb.gen1(0xA4); // MOVSB
1583+
loadFromEA(csrc,Rv,2,2); // ldr Rv,[Rs,Ri]
1584+
cdb.genc1(csrc.Iop,0,FL.offset,offset);
1585+
storeToEA(cdst,Rv,2); // str Rv,[Rd,Ri]
1586+
cdb.genc1(cdst.Iop,0,FL.offset,offset);
1587+
offset += 2;
15471588
}
1548-
}
1549-
else
1550-
{
1551-
uint movs;
1552-
if (numbytes & (REGSIZE - 1)) // if odd
1553-
movs = 0xA4; // MOVSB
1554-
else
1589+
if (remainder & 1)
15551590
{
1556-
movs = 0xA5; // MOVSW
1557-
numbytes /= REGSIZE; // # of words
1591+
loadFromEA(csrc,Rv,1,1); // ldr Rv,[Rs,Ri]
1592+
cdb.genc1(csrc.Iop,0,FL.offset,offset);
1593+
storeToEA(cdst,Rv,1); // str Rv,[Rd,Ri]
1594+
cdb.genc1(cdst.Iop,0,FL.offset,offset);
15581595
}
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-
}
15651596
}
15661597
assert(!(pretregs & mPSW));
15671598
if (pretregs)
@@ -1570,7 +1601,7 @@ else
15701601
//cdb.genc2(0x81,(rex << 16) | modregrm(3,5,DI), type_size(e.ET)); // SUB DI,numbytes
15711602

15721603
const tym = tybasic(e.Ety);
1573-
if (tym == TYucent && I64)
1604+
if (tym == TYucent)
15741605
{
15751606
/* https://issues.dlang.org/show_bug.cgi?id=22175
15761607
* The trouble happens when the struct size does not fit exactly into
@@ -1579,30 +1610,30 @@ else
15791610
*/
15801611

15811612
// dereference DI
1582-
code cs;
1583-
cs.Iop = 0x8B;
1584-
regm_t retregs = pretregs;
1613+
regm_t retregs = pretregs & ~srcregs;
1614+
if (!retregs)
1615+
retregs = cgstate.allregs & ~srcregs;
15851616
allocreg(cdb,retregs,tym);
15861617

15871618
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
1619+
1620+
code cs;
1621+
cs.base = Rs;
1622+
cs.index = NOREG;
1623+
cs.reg = NOREG;
1624+
1625+
loadFromEA(cs,msreg,8,8); // ldr msreg,[Rs,REGSIZE]
1626+
cdb.genc1(cs.Iop,0,FL.offset,REGSIZE);
15921627

15931628
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];
1629+
loadFromEA(cs,lsreg,8,8); // ldr lsreg,[Rs]
1630+
cdb.genc1(cs.Iop,0,FL.offset,0);
1631+
15981632
fixresult(cdb,e,retregs,pretregs);
15991633
return;
16001634
}
16011635

1602-
regm_t retregs = mDI;
1603-
if (pretregs & INSTR.MSW && !(config.exe & EX_flat))
1604-
retregs |= mES;
1605-
fixresult(cdb,e,retregs,pretregs);
1636+
fixresult(cdb,e,dstregs,pretregs);
16061637
}
16071638
}
16081639

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -669,8 +669,8 @@ void disassemble(uint c) @trusted
669669
else if (imms < immr)
670670
{
671671
p1 = "ubfiz"; // https://www.scs.stanford.edu/~zyedidia/arm64/ubfiz_ubfm.html
672-
p4 = wordtostring(-immr);
673-
p5 = wordtostring2(imms - 1);
672+
p4 = wordtostring(-immr & (((sf == 1) ? 64 : 32) - 1));
673+
p5 = wordtostring2(imms + 1);
674674
}
675675
else if (immr == 0 && imms == 7)
676676
{
@@ -3136,8 +3136,9 @@ unittest
31363136
unittest
31373137
{
31383138
int line64 = __LINE__;
3139-
string[86] cases64 = // 64 bit code gen
3139+
string[87] cases64 = // 64 bit code gen
31403140
[
3141+
"D3 7E 7C 43 ubfiz x3,x2,#2,#0x20",
31413142
"B8 00 93 E0 stur w0,[sp,#9]",
31423143
"F8 00 84 5F str xzr,[x2],#8",
31433144
"6F 00 E4 01 movi v1.2d,#0x0",

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,24 @@ struct INSTR
297297
return sbfm(1, 1, 0, 31, Rn, Rd);
298298
}
299299

300+
/* UBFM Rd,Rn,#immr,#imms
301+
* https://www.scs.stanford.edu/~zyedidia/arm64/ubfm.html
302+
*/
303+
static uint ubfm(uint sf, uint N, uint immr, uint imms, reg_t Rn, reg_t Rd)
304+
{
305+
return bitfield(sf, 2, N, immr, imms, Rn, Rd);
306+
}
307+
308+
/* UBFIZ Rd,Rn,#lsb,#width
309+
* https://www.scs.stanford.edu/~zyedidia/arm64/ubfiz_ubfm.html
310+
*/
311+
static uint ubfiz_ubfm(uint sf, uint N, uint lsb, uint width, reg_t Rn, reg_t Rd)
312+
{
313+
assert(sf == N);
314+
uint mask = ((sf == 1) ? 64 : 32) - 1;
315+
return ubfm(sf, N, -lsb & mask, width - 1, Rn, Rd);
316+
}
317+
300318
/* Extract
301319
* EXTR
302320
* https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#dpimm

0 commit comments

Comments
 (0)