@@ -1605,7 +1605,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
16051605 MBB.erase (I);
16061606}
16071607
1608- // Get minimum constant for ARM instruction set that is greator than
1608+ // Get minimum constant for ARM instruction set that is greator than
16091609// or equal to the argument.
16101610// In ARM instruction, constant can have any value that can be
16111611// produced by rotating an 8-bit value right by and even number
@@ -1629,29 +1629,28 @@ static uint32_t AlignToARMConstant(uint32_t Value) {
16291629
16301630 if (Shifted > 24 )
16311631 Value = Value >> (Shifted - 24 );
1632- else
1632+ else
16331633 Value = Value << (24 - Shifted);
16341634
16351635 return Value;
16361636}
16371637
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
16391639// stack limit.
16401640static const uint64_t kSplitStackAvailable = 256 ;
16411641
16421642// Adjust function prologue to enable split stack.
1643- // Only support android.
1644- void
1643+ // Only support android and linux .
1644+ void
16451645ARMFrameLowering::adjustForSegmentedStacks (MachineFunction &MF) const {
16461646 const ARMSubtarget *ST = &MF.getTarget ().getSubtarget <ARMSubtarget>();
16471647
16481648 // Doesn't support vararg function.
16491649 if (MF.getFunction ()->isVarArg ())
16501650 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+
16551654 MachineBasicBlock &prologueMBB = MF.front ();
16561655 MachineFrameInfo* MFI = MF.getFrameInfo ();
16571656 const ARMBaseInstrInfo &TII = *TM.getInstrInfo ();
@@ -1663,37 +1662,45 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
16631662 // leave the function.
16641663 unsigned ScratchReg0 = ARM::R4;
16651664 unsigned ScratchReg1 = ARM::R5;
1666- // Use the last tls slot.
1667- unsigned TlsOffset = 63 ;
1665+ unsigned TlsOffset;
16681666 uint64_t AlignedStackSize;
16691667
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+
16701676 MachineBasicBlock* prevStackMBB = MF.CreateMachineBasicBlock ();
16711677 MachineBasicBlock* postStackMBB = MF.CreateMachineBasicBlock ();
16721678 MachineBasicBlock* allocMBB = MF.CreateMachineBasicBlock ();
1673- MachineBasicBlock* checkMBB = MF.CreateMachineBasicBlock ();
1679+ MachineBasicBlock* getMBB = MF.CreateMachineBasicBlock ();
1680+ MachineBasicBlock* mcrMBB = MF.CreateMachineBasicBlock ();
1681+ MachineBasicBlock* magicMBB = MF.CreateMachineBasicBlock ();
16741682
16751683 for (MachineBasicBlock::livein_iterator i = prologueMBB.livein_begin (),
16761684 e = prologueMBB.livein_end (); i != e; ++i) {
16771685 allocMBB->addLiveIn (*i);
1678- checkMBB->addLiveIn (*i);
1686+ getMBB->addLiveIn (*i);
1687+ magicMBB->addLiveIn (*i);
1688+ mcrMBB->addLiveIn (*i);
16791689 prevStackMBB->addLiveIn (*i);
16801690 postStackMBB->addLiveIn (*i);
16811691 }
16821692
16831693 MF.push_front (postStackMBB);
16841694 MF.push_front (allocMBB);
1685- MF.push_front (checkMBB);
1695+ MF.push_front (getMBB);
1696+ MF.push_front (magicMBB);
1697+ MF.push_front (mcrMBB);
16861698 MF.push_front (prevStackMBB);
16871699
16881700 // The required stack size that is aligend to ARM constant critarion.
16891701 uint64_t StackSize = MFI->getStackSize ();
16901702
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);
16971704
16981705 // When the frame size is less than 256 we just compare the stack
16991706 // boundary directly to the value of the stack pointer, per gcc.
@@ -1714,41 +1721,63 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
17141721
17151722 if (CompareStackPointer) {
17161723 // mov SR1, sp
1717- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::MOVr), ScratchReg1)
1724+ AddDefaultPred (BuildMI (mcrMBB , DL, TII.get (ARM::MOVr), ScratchReg1)
17181725 .addReg (ARM::SP)).addReg (0 );
17191726 } else {
17201727 // sub SR1, sp, #StackSize
1721- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::SUBri), ScratchReg1)
1728+ AddDefaultPred (BuildMI (mcrMBB , DL, TII.get (ARM::SUBri), ScratchReg1)
17221729 .addReg (ARM::SP).addImm (AlignedStackSize)).addReg (0 );
17231730 }
1724-
1731+
17251732 // Get TLS base address.
1733+ // First try to get it from the coprocessor
17261734 // 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)
17281736 .addImm (15 )
17291737 .addImm (0 )
17301738 .addImm (13 )
17311739 .addImm (0 )
17321740 .addImm (3 ));
17331741
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)
17371766 .addReg (ScratchReg0).addImm (4 *TlsOffset)).addReg (0 );
17381767
17391768 // Get stack limit.
17401769 // ldr SR0, [sr0]
1741- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::LDRi12), ScratchReg0)
1770+ AddDefaultPred (BuildMI (getMBB , DL, TII.get (ARM::LDRi12), ScratchReg0)
17421771 .addReg (ScratchReg0).addImm (0 ));
17431772
17441773 // Compare stack limit with stack size requested.
17451774 // cmp SR0, SR1
1746- AddDefaultPred (BuildMI (checkMBB , DL, TII.get (ARM::CMPrr))
1775+ AddDefaultPred (BuildMI (getMBB , DL, TII.get (ARM::CMPrr))
17471776 .addReg (ScratchReg0)
17481777 .addReg (ScratchReg1));
17491778
17501779 // 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)
17521781 .addImm (ARMCC::LO)
17531782 .addReg (ARM::CPSR);
17541783
@@ -1776,7 +1805,7 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
17761805 // Call __morestack().
17771806 BuildMI (allocMBB, DL, TII.get (ARM::BL))
17781807 .addExternalSymbol (" __morestack" );
1779-
1808+
17801809 // Restore return address of this original function.
17811810 // pop {lr}
17821811 AddDefaultPred (BuildMI (allocMBB, DL, TII.get (ARM::LDMIA_UPD))
@@ -1811,11 +1840,16 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
18111840 postStackMBB->addSuccessor (&prologueMBB);
18121841
18131842 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);
18191853
18201854#ifdef XDEBUG
18211855 MF.verify ();
0 commit comments