summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Sparc
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Sparc')
-rw-r--r--llvm/lib/Target/Sparc/CMakeLists.txt1
-rwxr-xr-xllvm/lib/Target/Sparc/LeonFeatures.td8
-rwxr-xr-xllvm/lib/Target/Sparc/LeonPasses.cpp79
-rwxr-xr-xllvm/lib/Target/Sparc/LeonPasses.h46
-rw-r--r--llvm/lib/Target/Sparc/Sparc.td8
-rw-r--r--llvm/lib/Target/Sparc/SparcISelLowering.cpp4
-rw-r--r--llvm/lib/Target/Sparc/SparcSubtarget.cpp1
-rw-r--r--llvm/lib/Target/Sparc/SparcSubtarget.h2
-rw-r--r--llvm/lib/Target/Sparc/SparcTargetMachine.cpp10
-rw-r--r--llvm/lib/Target/Sparc/SparcTargetMachine.h2
10 files changed, 152 insertions, 9 deletions
diff --git a/llvm/lib/Target/Sparc/CMakeLists.txt b/llvm/lib/Target/Sparc/CMakeLists.txt
index 5b7bfdd2802..312215cf6cd 100644
--- a/llvm/lib/Target/Sparc/CMakeLists.txt
+++ b/llvm/lib/Target/Sparc/CMakeLists.txt
@@ -13,6 +13,7 @@ add_public_tablegen_target(SparcCommonTableGen)
add_llvm_target(SparcCodeGen
DelaySlotFiller.cpp
+ LeonPasses.cpp
SparcAsmPrinter.cpp
SparcInstrInfo.cpp
SparcISelDAGToDAG.cpp
diff --git a/llvm/lib/Target/Sparc/LeonFeatures.td b/llvm/lib/Target/Sparc/LeonFeatures.td
index 5e62891c3ff..7de98407dac 100755
--- a/llvm/lib/Target/Sparc/LeonFeatures.td
+++ b/llvm/lib/Target/Sparc/LeonFeatures.td
@@ -36,4 +36,10 @@ def LeonCASA : SubtargetFeature<
"true",
"Enable CASA instruction for LEON3 and LEON4 processors"
>;
- \ No newline at end of file
+
+def InsertNOPLoad: SubtargetFeature<
+ "insertnopload",
+ "InsertNOPLoad",
+ "true",
+ "LEON3 erratum fix: Insert a NOP instruction after every single-cycle load instruction when the next instruction is another load/store instruction"
+>;
diff --git a/llvm/lib/Target/Sparc/LeonPasses.cpp b/llvm/lib/Target/Sparc/LeonPasses.cpp
new file mode 100755
index 00000000000..0a99a9825f1
--- /dev/null
+++ b/llvm/lib/Target/Sparc/LeonPasses.cpp
@@ -0,0 +1,79 @@
+//===------ LeonPasses.cpp - Define passes specific to LEON ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+#include "LeonPasses.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+
+LEONMachineFunctionPass::LEONMachineFunctionPass(TargetMachine &tm, char& ID) :
+ MachineFunctionPass(ID)
+{
+}
+
+LEONMachineFunctionPass::LEONMachineFunctionPass(char& ID) :
+ MachineFunctionPass(ID)
+{
+}
+
+//*****************************************************************************
+//**** InsertNOPLoad pass
+//*****************************************************************************
+//This pass inserts a NOP after any LD or LDF instruction.
+//
+char InsertNOPLoad::ID = 0;
+
+InsertNOPLoad::InsertNOPLoad(TargetMachine &tm) :
+ LEONMachineFunctionPass(tm, ID)
+{
+}
+
+bool InsertNOPLoad::runOnMachineFunction(MachineFunction& MF)
+{
+ Subtarget = &MF.getSubtarget<SparcSubtarget>();
+ const TargetInstrInfo& TII = *Subtarget->getInstrInfo();
+ DebugLoc DL = DebugLoc();
+
+ bool Modified = false;
+ for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
+ MachineBasicBlock &MBB = *MFI;
+ for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++ MBBI) {
+ MachineInstr &MI = *MBBI;
+ unsigned Opcode = MI.getOpcode();
+ if (Opcode >= SP::LDDArr && Opcode <= SP::LDrr) {
+ //errs() << "Inserting NOP after LD instruction\n";
+ MachineBasicBlock::iterator NMBBI = std::next(MBBI);
+ BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
+ Modified = true;
+ }
+ else if (MI.isInlineAsm()) {
+ std::string AsmString (MI.getOperand(InlineAsm::MIOp_AsmString)
+ .getSymbolName());
+ std::string LDOpCoode ("ld");
+ std::transform(AsmString.begin(), AsmString.end(), AsmString.begin(),
+ ::tolower);
+ if (AsmString.find(LDOpCoode) == 0) { // an inline ld or ldf instruction
+ //errs() << "Inserting NOP after LD instruction\n";
+ MachineBasicBlock::iterator NMBBI = std::next(MBBI);
+ BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
+ Modified = true;
+ }
+ }
+ }
+ }
+
+ return Modified;
+}
diff --git a/llvm/lib/Target/Sparc/LeonPasses.h b/llvm/lib/Target/Sparc/LeonPasses.h
new file mode 100755
index 00000000000..ea17b55bef3
--- /dev/null
+++ b/llvm/lib/Target/Sparc/LeonPasses.h
@@ -0,0 +1,46 @@
+//===------- LeonPasses.h - Define passes specific to LEON ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_SPARC_LEON_PASSES_H
+#define LLVM_LIB_TARGET_SPARC_LEON_PASSES_H
+
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+
+#include "Sparc.h"
+#include "SparcSubtarget.h"
+
+using namespace llvm;
+
+class LEONMachineFunctionPass : public MachineFunctionPass {
+protected:
+ const SparcSubtarget *Subtarget;
+
+protected:
+ LEONMachineFunctionPass(TargetMachine &tm, char& ID);
+ LEONMachineFunctionPass(char& ID);
+};
+
+class InsertNOPLoad : public LEONMachineFunctionPass {
+public:
+ static char ID;
+
+ InsertNOPLoad(TargetMachine &tm);
+ bool runOnMachineFunction(MachineFunction& MF) override;
+
+ const char *getPassName() const override {
+ return "InsertNOPLoad: Erratum Fix LBR35: insert a NOP instruction after every single-cycle load instruction when the next instruction is another load/store instruction";
+ }
+};
+
+#endif
diff --git a/llvm/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td
index 51e0b9acdb0..4fb82ff5c74 100644
--- a/llvm/lib/Target/Sparc/Sparc.td
+++ b/llvm/lib/Target/Sparc/Sparc.td
@@ -107,12 +107,12 @@ def : Processor<"leon2", LEON2Itineraries,
// LEON 2 FT (AT697E)
// TO DO: Place-holder: Processor specific features will be added *very* soon here.
def : Processor<"at697e", LEON2Itineraries,
- [FeatureLeon]>;
+ [FeatureLeon, InsertNOPLoad]>;
// LEON 2 FT (AT697F)
// TO DO: Place-holder: Processor specific features will be added *very* soon here.
def : Processor<"at697f", LEON2Itineraries,
- [FeatureLeon]>;
+ [FeatureLeon, InsertNOPLoad]>;
// LEON 3 FT generic
@@ -122,12 +122,12 @@ def : Processor<"leon3", LEON3Itineraries,
// LEON 3 FT (UT699). Provides features for the UT699 processor
// - covers all the erratum fixes for LEON3, but does not support the CASA instruction.
def : Processor<"ut699", LEON3Itineraries,
- [FeatureLeon, UMACSMACSupport]>;
+ [FeatureLeon, InsertNOPLoad]>;
// LEON3 FT (GR712RC). Provides features for the GR712RC processor.
// - covers all the erratum fixed for LEON3 and support for the CASA instruction.
def : Processor<"gr712rc", LEON3Itineraries,
- [FeatureLeon, UMACSMACSupport, LeonCASA]>;
+ [FeatureLeon, LeonCASA]>;
// LEON 4 FT generic
def : Processor<"leon4", LEON4Itineraries,
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index e5fbc477c06..23385a92579 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -1642,8 +1642,8 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
if (Subtarget->isV9())
setMaxAtomicSizeInBitsSupported(64);
else if (false && Subtarget->hasLeonCasa())
- // Test made to fail pending completion of AtomicExpandPass,
- // as this will cause a regression until that work is completed.
+ // Test made to fail pending completion of AtomicExpandPass,
+ // as this will cause a regression until that work is completed.
setMaxAtomicSizeInBitsSupported(32);
else
setMaxAtomicSizeInBitsSupported(0);
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
index f3b50d40323..3dd8a84ba47 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.cpp
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
@@ -39,6 +39,7 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(StringRef CPU,
// Leon features
HasLeonCasa = false;
HasUmacSmac = false;
+ InsertNOPLoad = false;
// Determine default and user specified characteristics
std::string CPUName = CPU;
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.h b/llvm/lib/Target/Sparc/SparcSubtarget.h
index 4ad963e31d8..a69c2efd913 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.h
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.h
@@ -44,6 +44,7 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
// LEON features
bool HasUmacSmac;
bool HasLeonCasa;
+ bool InsertNOPLoad;
SparcInstrInfo InstrInfo;
SparcTargetLowering TLInfo;
@@ -83,6 +84,7 @@ public:
// Leon options
bool hasUmacSmac() const { return HasUmacSmac; }
bool hasLeonCasa() const { return HasLeonCasa; }
+ bool insertNOPLoad() const { return InsertNOPLoad; }
/// ParseSubtargetFeatures - Parses features string setting specified
/// subtarget options. Definition of function is auto generated by tblgen.
diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
index 80c78514831..cc2be3a9ef0 100644
--- a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
+++ b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
@@ -13,6 +13,7 @@
#include "SparcTargetMachine.h"
#include "SparcTargetObjectFile.h"
#include "Sparc.h"
+#include "LeonPasses.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/LegacyPassManager.h"
@@ -68,9 +69,9 @@ SparcTargetMachine::SparcTargetMachine(const Target &T, const Triple &TT,
CodeGenOpt::Level OL, bool is64bit)
: LLVMTargetMachine(T, computeDataLayout(TT, is64bit), TT, CPU, FS, Options,
getEffectiveRelocModel(RM), CM, OL),
- TLOF(make_unique<SparcELFTargetObjectFile>()) {
+ TLOF(make_unique<SparcELFTargetObjectFile>()),
+ Subtarget(TT, CPU, FS, *this, is64bit), is64Bit(is64bit) {
initAsmInfo();
- this->is64Bit = is64bit;
}
SparcTargetMachine::~SparcTargetMachine() {}
@@ -143,6 +144,11 @@ bool SparcPassConfig::addInstSelector() {
void SparcPassConfig::addPreEmitPass(){
addPass(createSparcDelaySlotFillerPass(getSparcTargetMachine()));
+
+ if (this->getSparcTargetMachine().getSubtargetImpl()->insertNOPLoad())
+ {
+ addPass(new InsertNOPLoad(getSparcTargetMachine()));
+ }
}
void SparcV8TargetMachine::anchor() { }
diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.h b/llvm/lib/Target/Sparc/SparcTargetMachine.h
index 8c056b3c361..48193fe095b 100644
--- a/llvm/lib/Target/Sparc/SparcTargetMachine.h
+++ b/llvm/lib/Target/Sparc/SparcTargetMachine.h
@@ -22,6 +22,7 @@ namespace llvm {
class SparcTargetMachine : public LLVMTargetMachine {
std::unique_ptr<TargetLoweringObjectFile> TLOF;
+ SparcSubtarget Subtarget;
bool is64Bit;
mutable StringMap<std::unique_ptr<SparcSubtarget>> SubtargetMap;
public:
@@ -31,6 +32,7 @@ public:
CodeGenOpt::Level OL, bool is64bit);
~SparcTargetMachine() override;
+ const SparcSubtarget *getSubtargetImpl() const { return &Subtarget; }
const SparcSubtarget *getSubtargetImpl(const Function &) const override;
// Pass Pipeline Configuration
OpenPOWER on IntegriCloud