@@ -1254,11 +1254,11 @@ void cdmemset(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
1254
1254
auto remainder = numbytes & (REGSIZE - 1 );
1255
1255
if (remainder >= 4 )
1256
1256
{
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
1258
1258
remainder -= 4 ;
1259
1259
}
1260
1260
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
1262
1262
fixresult(cdb,e,retregs,pretregs);
1263
1263
return ;
1264
1264
}
@@ -1424,8 +1424,8 @@ private void cdmemsetn(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pr
1424
1424
@trusted
1425
1425
void cdstreq (ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
1426
1426
{
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);
1429
1429
char need_DS = false ;
1430
1430
elem* e1 = e.E1 ;
1431
1431
elem* e2 = e.E2 ;
@@ -1467,101 +1467,136 @@ void cdstreq(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
1467
1467
1468
1468
regm_t regm = cg.allregs & ~ (srcregs | dstregs);
1469
1469
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);
1471
1474
1472
1475
getregs(cdb,srcregs | dstregs | regm);
1473
1476
if (numbytes <= REGSIZE * 7 )
1474
1477
{
1475
1478
code csrc;
1476
- csrc.base = findreg(srcregs) ;
1479
+ csrc.base = Rs ;
1477
1480
csrc.index = NOREG ;
1478
1481
csrc.reg = NOREG ;
1479
1482
1480
1483
code cdst;
1481
- cdst.base = findreg(dstregs) ;
1484
+ cdst.base = Rd ;
1482
1485
cdst.index = NOREG ;
1483
1486
cdst.reg = NOREG ;
1484
1487
1485
1488
ulong offset;
1486
1489
1487
1490
while (numbytes >= REGSIZE )
1488
1491
{
1489
- loadFromEA(csrc,reg ,8 ,8 );
1492
+ loadFromEA(csrc,Rv ,8 ,8 );
1490
1493
cdb.genc1(csrc.Iop,0 ,FL .offset,offset);
1491
- storeToEA(cdst,reg ,8 );
1494
+ storeToEA(cdst,Rv ,8 );
1492
1495
cdb.genc1(cdst.Iop,0 ,FL .offset,offset);
1493
1496
offset += REGSIZE ;
1494
1497
numbytes -= REGSIZE ;
1495
1498
}
1496
1499
1497
1500
while (numbytes >= 4 )
1498
1501
{
1499
- loadFromEA(csrc,reg ,4 ,4 );
1502
+ loadFromEA(csrc,Rv ,4 ,4 );
1500
1503
cdb.genc1(csrc.Iop,0 ,FL .offset,offset);
1501
- storeToEA(cdst,reg ,4 );
1504
+ storeToEA(cdst,Rv ,4 );
1502
1505
cdb.genc1(csrc.Iop,0 ,FL .offset,offset);
1503
1506
offset += 4 ;
1504
1507
numbytes -= 4 ;
1505
1508
}
1506
1509
1507
1510
while (numbytes >= 2 )
1508
1511
{
1509
- loadFromEA(csrc,reg ,4 ,2 );
1512
+ loadFromEA(csrc,Rv ,4 ,2 );
1510
1513
cdb.genc1(csrc.Iop,0 ,FL .offset,offset);
1511
- storeToEA(cdst,reg ,2 );
1514
+ storeToEA(cdst,Rv ,2 );
1512
1515
cdb.genc1(csrc.Iop,0 ,FL .offset,offset);
1513
1516
offset += 2 ;
1514
1517
numbytes -= 2 ;
1515
1518
}
1516
1519
1517
1520
if (numbytes)
1518
1521
{
1519
- loadFromEA(csrc,reg ,4 ,1 );
1522
+ loadFromEA(csrc,Rv ,4 ,1 );
1520
1523
cdb.genc1(csrc.Iop,0 ,FL .offset,offset);
1521
- storeToEA(cdst,reg ,1 );
1524
+ storeToEA(cdst,Rv ,1 );
1522
1525
cdb.genc1(csrc.Iop,0 ,FL .offset,offset);
1523
1526
}
1524
1527
}
1525
1528
else
1526
1529
{
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
+
1530
1540
uint remainder = numbytes & (REGSIZE - 1 );
1531
1541
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 )
1540
1576
{
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 ;
1543
1583
}
1544
- for (; remainder; remainder -- )
1584
+ if ( remainder & 2 )
1545
1585
{
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 ;
1547
1592
}
1548
- }
1549
- else
1550
- {
1551
- uint movs;
1552
- if (numbytes & (REGSIZE - 1 )) // if odd
1553
- movs = 0xA4 ; // MOVSB
1554
- else
1593
+ if (remainder & 1 )
1555
1594
{
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);
1558
1599
}
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
- }
1565
1600
}
1566
1601
assert (! (pretregs & mPSW));
1567
1602
if (pretregs)
@@ -1570,7 +1605,7 @@ else
1570
1605
// cdb.genc2(0x81,(rex << 16) | modregrm(3,5,DI), type_size(e.ET)); // SUB DI,numbytes
1571
1606
1572
1607
const tym = tybasic(e.Ety);
1573
- if (tym == TYucent && I64 )
1608
+ if (tym == TYucent)
1574
1609
{
1575
1610
/* https://issues.dlang.org/show_bug.cgi?id=22175
1576
1611
* The trouble happens when the struct size does not fit exactly into
@@ -1579,30 +1614,30 @@ else
1579
1614
*/
1580
1615
1581
1616
// 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 ;
1585
1620
allocreg(cdb,retregs,tym);
1586
1621
1587
1622
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 );
1592
1631
1593
1632
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
+
1598
1636
fixresult(cdb,e,retregs,pretregs);
1599
1637
return ;
1600
1638
}
1601
1639
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);
1606
1641
}
1607
1642
}
1608
1643
0 commit comments