@@ -1447,7 +1447,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
1447
1447
MBB.erase (I);
1448
1448
}
1449
1449
1450
- // Get minimum constant for ARM instruction set that is greator than
1450
+ // Get minimum constant for ARM instruction set that is greator than
1451
1451
// or equal to the argument.
1452
1452
// In ARM instruction, constant can have any value that can be
1453
1453
// produced by rotating an 8-bit value right by and even number
@@ -1471,29 +1471,28 @@ static uint32_t AlignToARMConstant(uint32_t Value) {
1471
1471
1472
1472
if (Shifted > 24 )
1473
1473
Value = Value >> (Shifted - 24 );
1474
- else
1474
+ else
1475
1475
Value = Value << (24 - Shifted);
1476
1476
1477
1477
return Value;
1478
1478
}
1479
1479
1480
- // The stack limit in the TCB is set to this manyu bytes above the actual
1480
+ // The stack limit in the TCB is set to this manyu bytes above the actual
1481
1481
// stack limit.
1482
1482
static const uint64_t kSplitStackAvailable = 256 ;
1483
1483
1484
1484
// Adjust function prologue to enable split stack.
1485
- // Only support android.
1486
- void
1485
+ // Only support android and linux .
1486
+ void
1487
1487
ARMFrameLowering::adjustForSegmentedStacks (MachineFunction &MF) const {
1488
1488
const ARMSubtarget *ST = &MF.getTarget ().getSubtarget <ARMSubtarget>();
1489
1489
1490
1490
// Doesn't support vararg function.
1491
1491
if (MF.getFunction ()->isVarArg ())
1492
1492
report_fatal_error (" Segmented stacks do not support vararg functions." );
1493
- // Doesn't support other than android.
1494
- if (!ST->isTargetAndroid ())
1495
- report_fatal_error (" Segmented statks not supported on this platfrom." );
1496
-
1493
+ if (!ST->isTargetAndroid () && !ST->isTargetLinux ())
1494
+ report_fatal_error (" Segmented stacks not supported on this platfrom." );
1495
+
1497
1496
MachineBasicBlock &prologueMBB = MF.front ();
1498
1497
MachineFrameInfo* MFI = MF.getFrameInfo ();
1499
1498
const ARMBaseInstrInfo &TII = *TM.getInstrInfo ();
@@ -1505,37 +1504,45 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
1505
1504
// leave the function.
1506
1505
unsigned ScratchReg0 = ARM::R4;
1507
1506
unsigned ScratchReg1 = ARM::R5;
1508
- // Use the last tls slot.
1509
- unsigned TlsOffset = 63 ;
1507
+ unsigned TlsOffset;
1510
1508
uint64_t AlignedStackSize;
1511
1509
1510
+ if (ST->isTargetAndroid ()) {
1511
+ // Use the last tls slot.
1512
+ TlsOffset = 63 ;
1513
+ } else if (ST->isTargetLinux ()) {
1514
+ // Use private field of the TCB
1515
+ TlsOffset = 1 ;
1516
+ }
1517
+
1512
1518
MachineBasicBlock* prevStackMBB = MF.CreateMachineBasicBlock ();
1513
1519
MachineBasicBlock* postStackMBB = MF.CreateMachineBasicBlock ();
1514
1520
MachineBasicBlock* allocMBB = MF.CreateMachineBasicBlock ();
1515
- MachineBasicBlock* checkMBB = MF.CreateMachineBasicBlock ();
1521
+ MachineBasicBlock* getMBB = MF.CreateMachineBasicBlock ();
1522
+ MachineBasicBlock* mcrMBB = MF.CreateMachineBasicBlock ();
1523
+ MachineBasicBlock* magicMBB = MF.CreateMachineBasicBlock ();
1516
1524
1517
1525
for (MachineBasicBlock::livein_iterator i = prologueMBB.livein_begin (),
1518
1526
e = prologueMBB.livein_end (); i != e; ++i) {
1519
1527
allocMBB->addLiveIn (*i);
1520
- checkMBB->addLiveIn (*i);
1528
+ getMBB->addLiveIn (*i);
1529
+ magicMBB->addLiveIn (*i);
1530
+ mcrMBB->addLiveIn (*i);
1521
1531
prevStackMBB->addLiveIn (*i);
1522
1532
postStackMBB->addLiveIn (*i);
1523
1533
}
1524
1534
1525
1535
MF.push_front (postStackMBB);
1526
1536
MF.push_front (allocMBB);
1527
- MF.push_front (checkMBB);
1537
+ MF.push_front (getMBB);
1538
+ MF.push_front (magicMBB);
1539
+ MF.push_front (mcrMBB);
1528
1540
MF.push_front (prevStackMBB);
1529
1541
1530
1542
// The required stack size that is aligend to ARM constant critarion.
1531
1543
uint64_t StackSize = MFI->getStackSize ();
1532
1544
1533
- // If the front-end requested a fixed stack segment size, use that.
1534
- if (MF.getFunction ()->hasFnAttribute (" fixedstacksegment" )) {
1535
- StackSize = MF.getTarget ().Options .FixedStackSegmentSize ;
1536
- }
1537
-
1538
- AlignedStackSize = AlignToARMConstant (StackSize)
1545
+ AlignedStackSize = AlignToARMConstant (StackSize);
1539
1546
1540
1547
// When the frame size is less than 256 we just compare the stack
1541
1548
// boundary directly to the value of the stack pointer, per gcc.
@@ -1556,41 +1563,63 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
1556
1563
1557
1564
if (CompareStackPointer) {
1558
1565
// mov SR1, sp
1559
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::MOVr), ScratchReg1)
1566
+ AddDefaultPred (BuildMI (mcrMBB , DL, TII.get (ARM::MOVr), ScratchReg1)
1560
1567
.addReg (ARM::SP)).addReg (0 );
1561
1568
} else {
1562
1569
// sub SR1, sp, #StackSize
1563
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::SUBri), ScratchReg1)
1570
+ AddDefaultPred (BuildMI (mcrMBB , DL, TII.get (ARM::SUBri), ScratchReg1)
1564
1571
.addReg (ARM::SP).addImm (AlignedStackSize)).addReg (0 );
1565
1572
}
1566
-
1573
+
1567
1574
// Get TLS base address.
1575
+ // First try to get it from the coprocessor
1568
1576
// mrc p15, #0, SR0, c13, c0, #3
1569
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::MRC), ScratchReg0)
1577
+ AddDefaultPred (BuildMI (mcrMBB , DL, TII.get (ARM::MRC), ScratchReg0)
1570
1578
.addImm (15 )
1571
1579
.addImm (0 )
1572
1580
.addImm (13 )
1573
1581
.addImm (0 )
1574
1582
.addImm (3 ));
1575
1583
1576
- // The last slot, assume that the last tls slot holds the stack limit
1577
- // add SR0, SR0, #252
1578
- AddDefaultPred (BuildMI (checkMBB, DL, TII.get (ARM::ADDri), ScratchReg0)
1584
+ // Success?
1585
+ // cmp SR0, #0
1586
+ AddDefaultPred (BuildMI (mcrMBB, DL, TII.get (ARM::CMPri))
1587
+ .addReg (ScratchReg0)
1588
+ .addImm (0 ));
1589
+
1590
+ // This jump is taken if SR0 is not null
1591
+ BuildMI (mcrMBB, DL, TII.get (ARM::Bcc)).addMBB (getMBB)
1592
+ .addImm (ARMCC::NE)
1593
+ .addReg (ARM::CPSR);
1594
+
1595
+ // Next, try to get it from the special address 0xFFFF0FF0
1596
+ // mvn SR0, #0xF000
1597
+ AddDefaultPred (BuildMI (magicMBB, DL, TII.get (ARM::MVNi), ScratchReg0)
1598
+ .addImm (0xF000 )).addReg (0 );
1599
+ // ldr SR0, [SR0, #-15]
1600
+ AddDefaultPred (BuildMI (magicMBB, DL, TII.get (ARM::LDRi12), ScratchReg0)
1601
+ .addReg (ScratchReg0)
1602
+ .addImm (-15 ));
1603
+
1604
+
1605
+ // Get the stack limit from the right offset
1606
+ // add SR0, SR0, offset*4
1607
+ AddDefaultPred (BuildMI (getMBB, DL, TII.get (ARM::ADDri), ScratchReg0)
1579
1608
.addReg (ScratchReg0).addImm (4 *TlsOffset)).addReg (0 );
1580
1609
1581
1610
// Get stack limit.
1582
1611
// ldr SR0, [sr0]
1583
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::LDRi12), ScratchReg0)
1612
+ AddDefaultPred (BuildMI (getMBB , DL, TII.get (ARM::LDRi12), ScratchReg0)
1584
1613
.addReg (ScratchReg0).addImm (0 ));
1585
1614
1586
1615
// Compare stack limit with stack size requested.
1587
1616
// cmp SR0, SR1
1588
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::CMPrr))
1617
+ AddDefaultPred (BuildMI (getMBB , DL, TII.get (ARM::CMPrr))
1589
1618
.addReg (ScratchReg0)
1590
1619
.addReg (ScratchReg1));
1591
1620
1592
1621
// This jump is taken if StackLimit < SP - stack required.
1593
- BuildMI (checkMBB , DL, TII.get (ARM::Bcc)).addMBB (postStackMBB)
1622
+ BuildMI (getMBB , DL, TII.get (ARM::Bcc)).addMBB (postStackMBB)
1594
1623
.addImm (ARMCC::LO)
1595
1624
.addReg (ARM::CPSR);
1596
1625
@@ -1618,7 +1647,7 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
1618
1647
// Call __morestack().
1619
1648
BuildMI (allocMBB, DL, TII.get (ARM::BL))
1620
1649
.addExternalSymbol (" __morestack" );
1621
-
1650
+
1622
1651
// Restore return address of this original function.
1623
1652
// pop {lr}
1624
1653
AddDefaultPred (BuildMI (allocMBB, DL, TII.get (ARM::LDMIA_UPD))
@@ -1653,11 +1682,16 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
1653
1682
postStackMBB->addSuccessor (&prologueMBB);
1654
1683
1655
1684
allocMBB->addSuccessor (postStackMBB);
1656
-
1657
- checkMBB->addSuccessor (postStackMBB);
1658
- checkMBB->addSuccessor (allocMBB);
1659
-
1660
- prevStackMBB->addSuccessor (checkMBB);
1685
+
1686
+ getMBB->addSuccessor (postStackMBB);
1687
+ getMBB->addSuccessor (allocMBB);
1688
+
1689
+ magicMBB->addSuccessor (getMBB);
1690
+
1691
+ mcrMBB->addSuccessor (getMBB);
1692
+ mcrMBB->addSuccessor (magicMBB);
1693
+
1694
+ prevStackMBB->addSuccessor (mcrMBB);
1661
1695
1662
1696
#ifdef XDEBUG
1663
1697
MF.verify ();
0 commit comments