summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorMarcin Koscielnicki <koriakin@0x04.net>2016-04-24 13:57:49 +0000
committerMarcin Koscielnicki <koriakin@0x04.net>2016-04-24 13:57:49 +0000
commitaef3b5b5e2d8bcb321832859464ff11100811609 (patch)
tree9d92031439572df7c0aa1f07b95d2f6b22345b4f /llvm/lib
parent7eedee938f839680aad4fcb831bd0c77b7025f76 (diff)
downloadbcm5719-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')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZISelLowering.h7
-rw-r--r--llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp35
-rw-r--r--llvm/lib/Target/SystemZ/SystemZInstrInfo.h1
-rw-r--r--llvm/lib/Target/SystemZ/SystemZRegisterInfo.h9
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;
OpenPOWER on IntegriCloud