@@ -1465,17 +1465,16 @@ static uint32_t AlignToARMConstant(uint32_t Value) {
1465
1465
static const uint64_t kSplitStackAvailable = 256 ;
1466
1466
1467
1467
// Adjust function prologue to enable split stack.
1468
- // Only support android.
1468
+ // Only support android and linux .
1469
1469
void
1470
1470
ARMFrameLowering::adjustForSegmentedStacks (MachineFunction &MF) const {
1471
1471
const ARMSubtarget *ST = &MF.getTarget ().getSubtarget <ARMSubtarget>();
1472
1472
1473
1473
// Doesn't support vararg function.
1474
1474
if (MF.getFunction ()->isVarArg ())
1475
1475
report_fatal_error (" Segmented stacks do not support vararg functions." );
1476
- // Doesn't support other than android.
1477
- if (!ST->isTargetAndroid ())
1478
- report_fatal_error (" Segmented statks not supported on this platfrom." );
1476
+ if (!ST->isTargetAndroid () && !ST->isTargetLinux ())
1477
+ report_fatal_error (" Segmented stacks not supported on this platfrom." );
1479
1478
1480
1479
MachineBasicBlock &prologueMBB = MF.front ();
1481
1480
MachineFrameInfo* MFI = MF.getFrameInfo ();
@@ -1488,26 +1487,39 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
1488
1487
// leave the function.
1489
1488
unsigned ScratchReg0 = ARM::R4;
1490
1489
unsigned ScratchReg1 = ARM::R5;
1491
- // Use the last tls slot.
1492
- unsigned TlsOffset = 63 ;
1490
+ unsigned TlsOffset;
1493
1491
uint64_t AlignedStackSize;
1494
1492
1493
+ if (ST->isTargetAndroid ()) {
1494
+ // Use the last tls slot.
1495
+ TlsOffset = 63 ;
1496
+ } else if (ST->isTargetLinux ()) {
1497
+ // Use private field of the TCB
1498
+ TlsOffset = 1 ;
1499
+ }
1500
+
1495
1501
MachineBasicBlock* prevStackMBB = MF.CreateMachineBasicBlock ();
1496
1502
MachineBasicBlock* postStackMBB = MF.CreateMachineBasicBlock ();
1497
1503
MachineBasicBlock* allocMBB = MF.CreateMachineBasicBlock ();
1498
- MachineBasicBlock* checkMBB = MF.CreateMachineBasicBlock ();
1504
+ MachineBasicBlock* getMBB = MF.CreateMachineBasicBlock ();
1505
+ MachineBasicBlock* mcrMBB = MF.CreateMachineBasicBlock ();
1506
+ MachineBasicBlock* magicMBB = MF.CreateMachineBasicBlock ();
1499
1507
1500
1508
for (MachineBasicBlock::livein_iterator i = prologueMBB.livein_begin (),
1501
1509
e = prologueMBB.livein_end (); i != e; ++i) {
1502
1510
allocMBB->addLiveIn (*i);
1503
- checkMBB->addLiveIn (*i);
1511
+ getMBB->addLiveIn (*i);
1512
+ magicMBB->addLiveIn (*i);
1513
+ mcrMBB->addLiveIn (*i);
1504
1514
prevStackMBB->addLiveIn (*i);
1505
1515
postStackMBB->addLiveIn (*i);
1506
1516
}
1507
1517
1508
1518
MF.push_front (postStackMBB);
1509
1519
MF.push_front (allocMBB);
1510
- MF.push_front (checkMBB);
1520
+ MF.push_front (getMBB);
1521
+ MF.push_front (magicMBB);
1522
+ MF.push_front (mcrMBB);
1511
1523
MF.push_front (prevStackMBB);
1512
1524
1513
1525
// The required stack size that is aligend to ARM constant critarion.
@@ -1541,41 +1553,63 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
1541
1553
1542
1554
if (CompareStackPointer) {
1543
1555
// mov SR1, sp
1544
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::MOVr), ScratchReg1)
1556
+ AddDefaultPred (BuildMI (mcrMBB , DL, TII.get (ARM::MOVr), ScratchReg1)
1545
1557
.addReg (ARM::SP)).addReg (0 );
1546
1558
} else {
1547
1559
// sub SR1, sp, #StackSize
1548
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::SUBri), ScratchReg1)
1560
+ AddDefaultPred (BuildMI (mcrMBB , DL, TII.get (ARM::SUBri), ScratchReg1)
1549
1561
.addReg (ARM::SP).addImm (AlignedStackSize)).addReg (0 );
1550
1562
}
1551
1563
1552
1564
// Get TLS base address.
1565
+ // First try to get it from the coprocessor
1553
1566
// mrc p15, #0, SR0, c13, c0, #3
1554
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::MRC), ScratchReg0)
1567
+ AddDefaultPred (BuildMI (mcrMBB , DL, TII.get (ARM::MRC), ScratchReg0)
1555
1568
.addImm (15 )
1556
1569
.addImm (0 )
1557
1570
.addImm (13 )
1558
1571
.addImm (0 )
1559
1572
.addImm (3 ));
1560
1573
1561
- // The last slot, assume that the last tls slot holds the stack limit
1562
- // add SR0, SR0, #252
1563
- AddDefaultPred (BuildMI (checkMBB, DL, TII.get (ARM::ADDri), ScratchReg0)
1574
+ // Success?
1575
+ // cmp SR0, #0
1576
+ AddDefaultPred (BuildMI (mcrMBB, DL, TII.get (ARM::CMPri))
1577
+ .addReg (ScratchReg0)
1578
+ .addImm (0 ));
1579
+
1580
+ // This jump is taken if SR0 is not null
1581
+ BuildMI (mcrMBB, DL, TII.get (ARM::Bcc)).addMBB (getMBB)
1582
+ .addImm (ARMCC::NE)
1583
+ .addReg (ARM::CPSR);
1584
+
1585
+ // Next, try to get it from the special address 0xFFFF0FF0
1586
+ // mvn SR0, #0xF000
1587
+ AddDefaultPred (BuildMI (magicMBB, DL, TII.get (ARM::MVNi), ScratchReg0)
1588
+ .addImm (0xF000 )).addReg (0 );
1589
+ // ldr SR0, [SR0, #-15]
1590
+ AddDefaultPred (BuildMI (magicMBB, DL, TII.get (ARM::LDRi12), ScratchReg0)
1591
+ .addReg (ScratchReg0)
1592
+ .addImm (-15 ));
1593
+
1594
+
1595
+ // Get the stack limit from the right offset
1596
+ // add SR0, SR0, offset*4
1597
+ AddDefaultPred (BuildMI (getMBB, DL, TII.get (ARM::ADDri), ScratchReg0)
1564
1598
.addReg (ScratchReg0).addImm (4 *TlsOffset)).addReg (0 );
1565
1599
1566
1600
// Get stack limit.
1567
1601
// ldr SR0, [sr0]
1568
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::LDRi12), ScratchReg0)
1602
+ AddDefaultPred (BuildMI (getMBB , DL, TII.get (ARM::LDRi12), ScratchReg0)
1569
1603
.addReg (ScratchReg0).addImm (0 ));
1570
1604
1571
1605
// Compare stack limit with stack size requested.
1572
1606
// cmp SR0, SR1
1573
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::CMPrr))
1607
+ AddDefaultPred (BuildMI (getMBB , DL, TII.get (ARM::CMPrr))
1574
1608
.addReg (ScratchReg0)
1575
1609
.addReg (ScratchReg1));
1576
1610
1577
1611
// This jump is taken if StackLimit < SP - stack required.
1578
- BuildMI (checkMBB , DL, TII.get (ARM::Bcc)).addMBB (postStackMBB)
1612
+ BuildMI (getMBB , DL, TII.get (ARM::Bcc)).addMBB (postStackMBB)
1579
1613
.addImm (ARMCC::LO)
1580
1614
.addReg (ARM::CPSR);
1581
1615
@@ -1638,11 +1672,16 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
1638
1672
postStackMBB->addSuccessor (&prologueMBB);
1639
1673
1640
1674
allocMBB->addSuccessor (postStackMBB);
1675
+
1676
+ getMBB->addSuccessor (postStackMBB);
1677
+ getMBB->addSuccessor (allocMBB);
1678
+
1679
+ magicMBB->addSuccessor (getMBB);
1680
+
1681
+ mcrMBB->addSuccessor (getMBB);
1682
+ mcrMBB->addSuccessor (magicMBB);
1641
1683
1642
- checkMBB->addSuccessor (postStackMBB);
1643
- checkMBB->addSuccessor (allocMBB);
1644
-
1645
- prevStackMBB->addSuccessor (checkMBB);
1684
+ prevStackMBB->addSuccessor (mcrMBB);
1646
1685
1647
1686
#ifdef XDEBUG
1648
1687
MF.verify ();
0 commit comments