@@ -1605,7 +1605,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
1605
1605
MBB.erase (I);
1606
1606
}
1607
1607
1608
- // Get minimum constant for ARM instruction set that is greator than
1608
+ // Get minimum constant for ARM instruction set that is greator than
1609
1609
// or equal to the argument.
1610
1610
// In ARM instruction, constant can have any value that can be
1611
1611
// produced by rotating an 8-bit value right by and even number
@@ -1629,29 +1629,28 @@ static uint32_t AlignToARMConstant(uint32_t Value) {
1629
1629
1630
1630
if (Shifted > 24 )
1631
1631
Value = Value >> (Shifted - 24 );
1632
- else
1632
+ else
1633
1633
Value = Value << (24 - Shifted);
1634
1634
1635
1635
return Value;
1636
1636
}
1637
1637
1638
- // The stack limit in the TCB is set to this manyu bytes above the actual
1638
+ // The stack limit in the TCB is set to this manyu bytes above the actual
1639
1639
// stack limit.
1640
1640
static const uint64_t kSplitStackAvailable = 256 ;
1641
1641
1642
1642
// Adjust function prologue to enable split stack.
1643
- // Only support android.
1644
- void
1643
+ // Only support android and linux .
1644
+ void
1645
1645
ARMFrameLowering::adjustForSegmentedStacks (MachineFunction &MF) const {
1646
1646
const ARMSubtarget *ST = &MF.getTarget ().getSubtarget <ARMSubtarget>();
1647
1647
1648
1648
// Doesn't support vararg function.
1649
1649
if (MF.getFunction ()->isVarArg ())
1650
1650
report_fatal_error (" Segmented stacks do not support vararg functions." );
1651
- // Doesn't support other than android.
1652
- if (!ST->isTargetAndroid ())
1653
- report_fatal_error (" Segmented statks not supported on this platfrom." );
1654
-
1651
+ if (!ST->isTargetAndroid () && !ST->isTargetLinux ())
1652
+ report_fatal_error (" Segmented stacks not supported on this platfrom." );
1653
+
1655
1654
MachineBasicBlock &prologueMBB = MF.front ();
1656
1655
MachineFrameInfo* MFI = MF.getFrameInfo ();
1657
1656
const ARMBaseInstrInfo &TII = *TM.getInstrInfo ();
@@ -1663,37 +1662,45 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
1663
1662
// leave the function.
1664
1663
unsigned ScratchReg0 = ARM::R4;
1665
1664
unsigned ScratchReg1 = ARM::R5;
1666
- // Use the last tls slot.
1667
- unsigned TlsOffset = 63 ;
1665
+ unsigned TlsOffset;
1668
1666
uint64_t AlignedStackSize;
1669
1667
1668
+ if (ST->isTargetAndroid ()) {
1669
+ // Use the last tls slot.
1670
+ TlsOffset = 63 ;
1671
+ } else if (ST->isTargetLinux ()) {
1672
+ // Use private field of the TCB
1673
+ TlsOffset = 1 ;
1674
+ }
1675
+
1670
1676
MachineBasicBlock* prevStackMBB = MF.CreateMachineBasicBlock ();
1671
1677
MachineBasicBlock* postStackMBB = MF.CreateMachineBasicBlock ();
1672
1678
MachineBasicBlock* allocMBB = MF.CreateMachineBasicBlock ();
1673
- MachineBasicBlock* checkMBB = MF.CreateMachineBasicBlock ();
1679
+ MachineBasicBlock* getMBB = MF.CreateMachineBasicBlock ();
1680
+ MachineBasicBlock* mcrMBB = MF.CreateMachineBasicBlock ();
1681
+ MachineBasicBlock* magicMBB = MF.CreateMachineBasicBlock ();
1674
1682
1675
1683
for (MachineBasicBlock::livein_iterator i = prologueMBB.livein_begin (),
1676
1684
e = prologueMBB.livein_end (); i != e; ++i) {
1677
1685
allocMBB->addLiveIn (*i);
1678
- checkMBB->addLiveIn (*i);
1686
+ getMBB->addLiveIn (*i);
1687
+ magicMBB->addLiveIn (*i);
1688
+ mcrMBB->addLiveIn (*i);
1679
1689
prevStackMBB->addLiveIn (*i);
1680
1690
postStackMBB->addLiveIn (*i);
1681
1691
}
1682
1692
1683
1693
MF.push_front (postStackMBB);
1684
1694
MF.push_front (allocMBB);
1685
- MF.push_front (checkMBB);
1695
+ MF.push_front (getMBB);
1696
+ MF.push_front (magicMBB);
1697
+ MF.push_front (mcrMBB);
1686
1698
MF.push_front (prevStackMBB);
1687
1699
1688
1700
// The required stack size that is aligend to ARM constant critarion.
1689
1701
uint64_t StackSize = MFI->getStackSize ();
1690
1702
1691
- // If the front-end requested a fixed stack segment size, use that.
1692
- if (MF.getFunction ()->hasFnAttribute (" fixedstacksegment" )) {
1693
- StackSize = MF.getTarget ().Options .FixedStackSegmentSize ;
1694
- }
1695
-
1696
- AlignedStackSize = AlignToARMConstant (StackSize)
1703
+ AlignedStackSize = AlignToARMConstant (StackSize);
1697
1704
1698
1705
// When the frame size is less than 256 we just compare the stack
1699
1706
// boundary directly to the value of the stack pointer, per gcc.
@@ -1714,41 +1721,63 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
1714
1721
1715
1722
if (CompareStackPointer) {
1716
1723
// mov SR1, sp
1717
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::MOVr), ScratchReg1)
1724
+ AddDefaultPred (BuildMI (mcrMBB , DL, TII.get (ARM::MOVr), ScratchReg1)
1718
1725
.addReg (ARM::SP)).addReg (0 );
1719
1726
} else {
1720
1727
// sub SR1, sp, #StackSize
1721
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::SUBri), ScratchReg1)
1728
+ AddDefaultPred (BuildMI (mcrMBB , DL, TII.get (ARM::SUBri), ScratchReg1)
1722
1729
.addReg (ARM::SP).addImm (AlignedStackSize)).addReg (0 );
1723
1730
}
1724
-
1731
+
1725
1732
// Get TLS base address.
1733
+ // First try to get it from the coprocessor
1726
1734
// mrc p15, #0, SR0, c13, c0, #3
1727
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::MRC), ScratchReg0)
1735
+ AddDefaultPred (BuildMI (mcrMBB , DL, TII.get (ARM::MRC), ScratchReg0)
1728
1736
.addImm (15 )
1729
1737
.addImm (0 )
1730
1738
.addImm (13 )
1731
1739
.addImm (0 )
1732
1740
.addImm (3 ));
1733
1741
1734
- // The last slot, assume that the last tls slot holds the stack limit
1735
- // add SR0, SR0, #252
1736
- AddDefaultPred (BuildMI (checkMBB, DL, TII.get (ARM::ADDri), ScratchReg0)
1742
+ // Success?
1743
+ // cmp SR0, #0
1744
+ AddDefaultPred (BuildMI (mcrMBB, DL, TII.get (ARM::CMPri))
1745
+ .addReg (ScratchReg0)
1746
+ .addImm (0 ));
1747
+
1748
+ // This jump is taken if SR0 is not null
1749
+ BuildMI (mcrMBB, DL, TII.get (ARM::Bcc)).addMBB (getMBB)
1750
+ .addImm (ARMCC::NE)
1751
+ .addReg (ARM::CPSR);
1752
+
1753
+ // Next, try to get it from the special address 0xFFFF0FF0
1754
+ // mvn SR0, #0xF000
1755
+ AddDefaultPred (BuildMI (magicMBB, DL, TII.get (ARM::MVNi), ScratchReg0)
1756
+ .addImm (0xF000 )).addReg (0 );
1757
+ // ldr SR0, [SR0, #-15]
1758
+ AddDefaultPred (BuildMI (magicMBB, DL, TII.get (ARM::LDRi12), ScratchReg0)
1759
+ .addReg (ScratchReg0)
1760
+ .addImm (-15 ));
1761
+
1762
+
1763
+ // Get the stack limit from the right offset
1764
+ // add SR0, SR0, offset*4
1765
+ AddDefaultPred (BuildMI (getMBB, DL, TII.get (ARM::ADDri), ScratchReg0)
1737
1766
.addReg (ScratchReg0).addImm (4 *TlsOffset)).addReg (0 );
1738
1767
1739
1768
// Get stack limit.
1740
1769
// ldr SR0, [sr0]
1741
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::LDRi12), ScratchReg0)
1770
+ AddDefaultPred (BuildMI (getMBB , DL, TII.get (ARM::LDRi12), ScratchReg0)
1742
1771
.addReg (ScratchReg0).addImm (0 ));
1743
1772
1744
1773
// Compare stack limit with stack size requested.
1745
1774
// cmp SR0, SR1
1746
- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::CMPrr))
1775
+ AddDefaultPred (BuildMI (getMBB , DL, TII.get (ARM::CMPrr))
1747
1776
.addReg (ScratchReg0)
1748
1777
.addReg (ScratchReg1));
1749
1778
1750
1779
// This jump is taken if StackLimit < SP - stack required.
1751
- BuildMI (checkMBB , DL, TII.get (ARM::Bcc)).addMBB (postStackMBB)
1780
+ BuildMI (getMBB , DL, TII.get (ARM::Bcc)).addMBB (postStackMBB)
1752
1781
.addImm (ARMCC::LO)
1753
1782
.addReg (ARM::CPSR);
1754
1783
@@ -1776,7 +1805,7 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
1776
1805
// Call __morestack().
1777
1806
BuildMI (allocMBB, DL, TII.get (ARM::BL))
1778
1807
.addExternalSymbol (" __morestack" );
1779
-
1808
+
1780
1809
// Restore return address of this original function.
1781
1810
// pop {lr}
1782
1811
AddDefaultPred (BuildMI (allocMBB, DL, TII.get (ARM::LDMIA_UPD))
@@ -1811,11 +1840,16 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
1811
1840
postStackMBB->addSuccessor (&prologueMBB);
1812
1841
1813
1842
allocMBB->addSuccessor (postStackMBB);
1814
-
1815
- checkMBB->addSuccessor (postStackMBB);
1816
- checkMBB->addSuccessor (allocMBB);
1817
-
1818
- prevStackMBB->addSuccessor (checkMBB);
1843
+
1844
+ getMBB->addSuccessor (postStackMBB);
1845
+ getMBB->addSuccessor (allocMBB);
1846
+
1847
+ magicMBB->addSuccessor (getMBB);
1848
+
1849
+ mcrMBB->addSuccessor (getMBB);
1850
+ mcrMBB->addSuccessor (magicMBB);
1851
+
1852
+ prevStackMBB->addSuccessor (mcrMBB);
1819
1853
1820
1854
#ifdef XDEBUG
1821
1855
MF.verify ();
0 commit comments