diff options
author | Marcin Koscielnicki <koriakin@0x04.net> | 2016-04-24 13:57:49 +0000 |
---|---|---|
committer | Marcin Koscielnicki <koriakin@0x04.net> | 2016-04-24 13:57:49 +0000 |
commit | aef3b5b5e2d8bcb321832859464ff11100811609 (patch) | |
tree | 9d92031439572df7c0aa1f07b95d2f6b22345b4f /llvm/lib/Target | |
parent | 7eedee938f839680aad4fcb831bd0c77b7025f76 (diff) | |
download | bcm5719-llvm-aef3b5b5e2d8bcb321832859464ff11100811609.tar.gz bcm5719-llvm-aef3b5b5e2d8bcb321832859464ff11100811609.zip |
[SystemZ] [SSP] Add support for LOAD_STACK_GUARD.
This fixes PR22248 on s390x. The previous attempt at this was D19101,
which was before LOAD_STACK_GUARD existed. Compared to the previous
version, this always emits a rather ugly block of 4 instructions, involving
a thread pointer load that can't be shared with other potential users.
However, this is necessary for SSP - spilling the guard value (or thread
pointer used to load it) is counter to the goal, since it could be
overwritten along with the frame it protects.
Differential Revision: http://reviews.llvm.org/D19363
llvm-svn: 267340
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZISelLowering.h | 7 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp | 35 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.h | 1 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZRegisterInfo.h | 9 |
4 files changed, 52 insertions, 0 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h index 02dd7afa887..ae761758b84 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h @@ -426,6 +426,13 @@ public: return SystemZ::R7D; } + /// Override to support customized stack guard loading. + bool useLoadStackGuardNode() const override { + return true; + } + void insertSSPDeclarations(Module &M) const override { + } + MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const override; diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp index 79bd0ef028d..11b88788875 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -160,6 +160,37 @@ void SystemZInstrInfo::expandZExtPseudo(MachineInstr *MI, unsigned LowOpcode, MI->eraseFromParent(); } +void SystemZInstrInfo::expandLoadStackGuard(MachineInstr *MI) const { + MachineBasicBlock *MBB = MI->getParent(); + MachineFunction &MF = *MBB->getParent(); + const unsigned Reg = MI->getOperand(0).getReg(); + + // Conveniently, all 4 instructions are cloned from LOAD_STACK_GUARD, + // so they already have operand 0 set to reg. + + // ear <reg>, %a0 + MachineInstr *Ear1MI = MF.CloneMachineInstr(MI); + MBB->insert(MI, Ear1MI); + Ear1MI->setDesc(get(SystemZ::EAR)); + MachineInstrBuilder(MF, Ear1MI).addImm(0); + + // sllg <reg>, <reg>, 32 + MachineInstr *SllgMI = MF.CloneMachineInstr(MI); + MBB->insert(MI, SllgMI); + SllgMI->setDesc(get(SystemZ::SLLG)); + MachineInstrBuilder(MF, SllgMI).addReg(Reg).addReg(0).addImm(32); + + // ear <reg>, %a1 + MachineInstr *Ear2MI = MF.CloneMachineInstr(MI); + MBB->insert(MI, Ear2MI); + Ear2MI->setDesc(get(SystemZ::EAR)); + MachineInstrBuilder(MF, Ear2MI).addImm(1); + + // lg <reg>, 40(<reg>) + MI->setDesc(get(SystemZ::LG)); + MachineInstrBuilder(MF, MI).addReg(Reg).addImm(40).addReg(0); +} + // Emit a zero-extending move from 32-bit GPR SrcReg to 32-bit GPR // DestReg before MBBI in MBB. Use LowLowOpcode when both DestReg and SrcReg // are low registers, otherwise use RISB[LH]G. Size is the number of bits @@ -1100,6 +1131,10 @@ SystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { splitAdjDynAlloc(MI); return true; + case TargetOpcode::LOAD_STACK_GUARD: + expandLoadStackGuard(MI); + return true; + default: return false; } diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h index 3cb73ed5fb8..e995ff10ddc 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h @@ -141,6 +141,7 @@ class SystemZInstrInfo : public SystemZGenInstrInfo { unsigned HighOpcode) const; void expandZExtPseudo(MachineInstr *MI, unsigned LowOpcode, unsigned Size) const; + void expandLoadStackGuard(MachineInstr *MI) const; void emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc DL, unsigned DestReg, unsigned SrcReg, unsigned LowLowOpcode, unsigned Size, bool KillSrc) const; diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h index a0db5a9c188..e41c06c98af 100644 --- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h +++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h @@ -33,6 +33,15 @@ struct SystemZRegisterInfo : public SystemZGenRegisterInfo { public: SystemZRegisterInfo(); + /// getPointerRegClass - Return the register class to use to hold pointers. + /// This is currently only used by LOAD_STACK_GUARD, which requires a non-%r0 + /// register, hence ADDR64. + const TargetRegisterClass * + getPointerRegClass(const MachineFunction &MF, + unsigned Kind=0) const override { + return &SystemZ::ADDR64BitRegClass; + } + // Override TargetRegisterInfo.h. bool requiresRegisterScavenging(const MachineFunction &MF) const override { return true; |