Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit b70c16c

Browse files
luqmanaalexcrichton
authored andcommitted
Splitstack support for arm/linux.
1 parent b24ba55 commit b70c16c

File tree

1 file changed

+70
-36
lines changed

1 file changed

+70
-36
lines changed

Diff for: lib/Target/ARM/ARMFrameLowering.cpp

+70-36
Original file line numberDiff line numberDiff line change
@@ -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.
16401640
static 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
16451645
ARMFrameLowering::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

Comments
 (0)