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

Commit e1cfed4

Browse files
committed
Splitstack support for arm/linux.
1 parent 5c1ec69 commit e1cfed4

File tree

1 file changed

+70
-36
lines changed

1 file changed

+70
-36
lines changed

lib/Target/ARM/ARMFrameLowering.cpp

Lines changed: 70 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,7 +1447,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
14471447
MBB.erase(I);
14481448
}
14491449

1450-
// Get minimum constant for ARM instruction set that is greator than
1450+
// Get minimum constant for ARM instruction set that is greator than
14511451
// or equal to the argument.
14521452
// In ARM instruction, constant can have any value that can be
14531453
// produced by rotating an 8-bit value right by and even number
@@ -1471,29 +1471,28 @@ static uint32_t AlignToARMConstant(uint32_t Value) {
14711471

14721472
if (Shifted > 24)
14731473
Value = Value >> (Shifted - 24);
1474-
else
1474+
else
14751475
Value = Value << (24 - Shifted);
14761476

14771477
return Value;
14781478
}
14791479

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
14811481
// stack limit.
14821482
static const uint64_t kSplitStackAvailable = 256;
14831483

14841484
// Adjust function prologue to enable split stack.
1485-
// Only support android.
1486-
void
1485+
// Only support android and linux.
1486+
void
14871487
ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
14881488
const ARMSubtarget *ST = &MF.getTarget().getSubtarget<ARMSubtarget>();
14891489

14901490
// Doesn't support vararg function.
14911491
if (MF.getFunction()->isVarArg())
14921492
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+
14971496
MachineBasicBlock &prologueMBB = MF.front();
14981497
MachineFrameInfo* MFI = MF.getFrameInfo();
14991498
const ARMBaseInstrInfo &TII = *TM.getInstrInfo();
@@ -1505,37 +1504,45 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
15051504
// leave the function.
15061505
unsigned ScratchReg0 = ARM::R4;
15071506
unsigned ScratchReg1 = ARM::R5;
1508-
// Use the last tls slot.
1509-
unsigned TlsOffset = 63;
1507+
unsigned TlsOffset;
15101508
uint64_t AlignedStackSize;
15111509

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+
15121518
MachineBasicBlock* prevStackMBB = MF.CreateMachineBasicBlock();
15131519
MachineBasicBlock* postStackMBB = MF.CreateMachineBasicBlock();
15141520
MachineBasicBlock* allocMBB = MF.CreateMachineBasicBlock();
1515-
MachineBasicBlock* checkMBB = MF.CreateMachineBasicBlock();
1521+
MachineBasicBlock* getMBB = MF.CreateMachineBasicBlock();
1522+
MachineBasicBlock* mcrMBB = MF.CreateMachineBasicBlock();
1523+
MachineBasicBlock* magicMBB = MF.CreateMachineBasicBlock();
15161524

15171525
for (MachineBasicBlock::livein_iterator i = prologueMBB.livein_begin(),
15181526
e = prologueMBB.livein_end(); i != e; ++i) {
15191527
allocMBB->addLiveIn(*i);
1520-
checkMBB->addLiveIn(*i);
1528+
getMBB->addLiveIn(*i);
1529+
magicMBB->addLiveIn(*i);
1530+
mcrMBB->addLiveIn(*i);
15211531
prevStackMBB->addLiveIn(*i);
15221532
postStackMBB->addLiveIn(*i);
15231533
}
15241534

15251535
MF.push_front(postStackMBB);
15261536
MF.push_front(allocMBB);
1527-
MF.push_front(checkMBB);
1537+
MF.push_front(getMBB);
1538+
MF.push_front(magicMBB);
1539+
MF.push_front(mcrMBB);
15281540
MF.push_front(prevStackMBB);
15291541

15301542
// The required stack size that is aligend to ARM constant critarion.
15311543
uint64_t StackSize = MFI->getStackSize();
15321544

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);
15391546

15401547
// When the frame size is less than 256 we just compare the stack
15411548
// boundary directly to the value of the stack pointer, per gcc.
@@ -1556,41 +1563,63 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
15561563

15571564
if (CompareStackPointer) {
15581565
// mov SR1, sp
1559-
AddDefaultPred(BuildMI(checkMBB, DL, TII.get(ARM::MOVr), ScratchReg1)
1566+
AddDefaultPred(BuildMI(mcrMBB, DL, TII.get(ARM::MOVr), ScratchReg1)
15601567
.addReg(ARM::SP)).addReg(0);
15611568
} else {
15621569
// sub SR1, sp, #StackSize
1563-
AddDefaultPred(BuildMI(checkMBB, DL, TII.get(ARM::SUBri), ScratchReg1)
1570+
AddDefaultPred(BuildMI(mcrMBB, DL, TII.get(ARM::SUBri), ScratchReg1)
15641571
.addReg(ARM::SP).addImm(AlignedStackSize)).addReg(0);
15651572
}
1566-
1573+
15671574
// Get TLS base address.
1575+
// First try to get it from the coprocessor
15681576
// 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)
15701578
.addImm(15)
15711579
.addImm(0)
15721580
.addImm(13)
15731581
.addImm(0)
15741582
.addImm(3));
15751583

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)
15791608
.addReg(ScratchReg0).addImm(4*TlsOffset)).addReg(0);
15801609

15811610
// Get stack limit.
15821611
// ldr SR0, [sr0]
1583-
AddDefaultPred(BuildMI(checkMBB, DL, TII.get(ARM::LDRi12), ScratchReg0)
1612+
AddDefaultPred(BuildMI(getMBB, DL, TII.get(ARM::LDRi12), ScratchReg0)
15841613
.addReg(ScratchReg0).addImm(0));
15851614

15861615
// Compare stack limit with stack size requested.
15871616
// cmp SR0, SR1
1588-
AddDefaultPred(BuildMI(checkMBB, DL, TII.get(ARM::CMPrr))
1617+
AddDefaultPred(BuildMI(getMBB, DL, TII.get(ARM::CMPrr))
15891618
.addReg(ScratchReg0)
15901619
.addReg(ScratchReg1));
15911620

15921621
// 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)
15941623
.addImm(ARMCC::LO)
15951624
.addReg(ARM::CPSR);
15961625

@@ -1618,7 +1647,7 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
16181647
// Call __morestack().
16191648
BuildMI(allocMBB, DL, TII.get(ARM::BL))
16201649
.addExternalSymbol("__morestack");
1621-
1650+
16221651
// Restore return address of this original function.
16231652
// pop {lr}
16241653
AddDefaultPred(BuildMI(allocMBB, DL, TII.get(ARM::LDMIA_UPD))
@@ -1653,11 +1682,16 @@ ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
16531682
postStackMBB->addSuccessor(&prologueMBB);
16541683

16551684
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);
16611695

16621696
#ifdef XDEBUG
16631697
MF.verify();

0 commit comments

Comments
 (0)