summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Sparc/LeonPasses.cpp
diff options
context:
space:
mode:
authorJames Y Knight <jyknight@google.com>2016-08-12 14:48:09 +0000
committerJames Y Knight <jyknight@google.com>2016-08-12 14:48:09 +0000
commit2cc9da9a654ca1f9f90d1eaaea889516074f975f (patch)
treeb322c45c79fc2e10d8aa6eb750b2ecc23ee71db1 /llvm/lib/Target/Sparc/LeonPasses.cpp
parent3785393def95f2b52ef28e9bcb3985066812d2db (diff)
downloadbcm5719-llvm-2cc9da9a654ca1f9f90d1eaaea889516074f975f.tar.gz
bcm5719-llvm-2cc9da9a654ca1f9f90d1eaaea889516074f975f.zip
Revert "[Sparc] Leon errata fix passes."
...and the two followup commits: Revert "[Sparc][Leon] Missed resetting option flags from check-in 278489." Revert "[Sparc][Leon] Errata fixes for various errata in different versions of the Leon variants of the Sparc 32 bit processor." This reverts commit r274856, r278489, and r278492. llvm-svn: 278511
Diffstat (limited to 'llvm/lib/Target/Sparc/LeonPasses.cpp')
-rw-r--r--llvm/lib/Target/Sparc/LeonPasses.cpp680
1 files changed, 76 insertions, 604 deletions
diff --git a/llvm/lib/Target/Sparc/LeonPasses.cpp b/llvm/lib/Target/Sparc/LeonPasses.cpp
index c0591faf30c..fe57ec7b677 100644
--- a/llvm/lib/Target/Sparc/LeonPasses.cpp
+++ b/llvm/lib/Target/Sparc/LeonPasses.cpp
@@ -16,7 +16,6 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -90,6 +89,15 @@ bool InsertNOPLoad::runOnMachineFunction(MachineFunction &MF) {
MachineBasicBlock::iterator NMBBI = std::next(MBBI);
BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
Modified = true;
+ } else if (MI.isInlineAsm()) {
+ // Look for an inline ld or ldf instruction.
+ StringRef AsmString =
+ MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName();
+ if (AsmString.startswith_lower("ld")) {
+ MachineBasicBlock::iterator NMBBI = std::next(MBBI);
+ BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
+ Modified = true;
+ }
}
}
}
@@ -139,6 +147,32 @@ bool FixFSMULD::runOnMachineFunction(MachineFunction &MF) {
Reg1Index = MI.getOperand(0).getReg();
Reg2Index = MI.getOperand(1).getReg();
Reg3Index = MI.getOperand(2).getReg();
+ } else if (MI.isInlineAsm()) {
+ std::string AsmString(
+ MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName());
+ std::string FMULSOpCoode("fsmuld");
+ std::transform(AsmString.begin(), AsmString.end(), AsmString.begin(),
+ ::tolower);
+ if (AsmString.find(FMULSOpCoode) ==
+ 0) { // this is an inline FSMULD instruction
+
+ unsigned StartOp = InlineAsm::MIOp_FirstOperand;
+
+ // extracts the registers from the inline assembly instruction
+ for (unsigned i = StartOp, e = MI.getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI.getOperand(i);
+ if (MO.isReg()) {
+ if (Reg1Index == UNASSIGNED_INDEX)
+ Reg1Index = MO.getReg();
+ else if (Reg2Index == UNASSIGNED_INDEX)
+ Reg2Index = MO.getReg();
+ else if (Reg3Index == UNASSIGNED_INDEX)
+ Reg3Index = MO.getReg();
+ }
+ if (Reg3Index != UNASSIGNED_INDEX)
+ break;
+ }
+ }
}
if (Reg1Index != UNASSIGNED_INDEX && Reg2Index != UNASSIGNED_INDEX &&
@@ -228,6 +262,31 @@ bool ReplaceFMULS::runOnMachineFunction(MachineFunction &MF) {
Reg1Index = MI.getOperand(0).getReg();
Reg2Index = MI.getOperand(1).getReg();
Reg3Index = MI.getOperand(2).getReg();
+ } else if (MI.isInlineAsm()) {
+ std::string AsmString(
+ MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName());
+ std::string FMULSOpCoode("fmuls");
+ std::transform(AsmString.begin(), AsmString.end(), AsmString.begin(),
+ ::tolower);
+ if (AsmString.find(FMULSOpCoode) ==
+ 0) { // this is an inline FMULS instruction
+ unsigned StartOp = InlineAsm::MIOp_FirstOperand;
+
+ // extracts the registers from the inline assembly instruction
+ for (unsigned i = StartOp, e = MI.getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI.getOperand(i);
+ if (MO.isReg()) {
+ if (Reg1Index == UNASSIGNED_INDEX)
+ Reg1Index = MO.getReg();
+ else if (Reg2Index == UNASSIGNED_INDEX)
+ Reg2Index = MO.getReg();
+ else if (Reg3Index == UNASSIGNED_INDEX)
+ Reg3Index = MO.getReg();
+ }
+ if (Reg3Index != UNASSIGNED_INDEX)
+ break;
+ }
+ }
}
if (Reg1Index != UNASSIGNED_INDEX && Reg2Index != UNASSIGNED_INDEX &&
@@ -309,17 +368,31 @@ bool FixAllFDIVSQRT::runOnMachineFunction(MachineFunction &MF) {
MachineInstr &MI = *MBBI;
unsigned Opcode = MI.getOpcode();
+ if (MI.isInlineAsm()) {
+ std::string AsmString(
+ MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName());
+ std::string FSQRTDOpCode("fsqrtd");
+ std::string FDIVDOpCode("fdivd");
+ std::transform(AsmString.begin(), AsmString.end(), AsmString.begin(),
+ ::tolower);
+ if (AsmString.find(FSQRTDOpCode) ==
+ 0) { // this is an inline fsqrts instruction
+ Opcode = SP::FSQRTD;
+ } else if (AsmString.find(FDIVDOpCode) ==
+ 0) { // this is an inline fsqrts instruction
+ Opcode = SP::FDIVD;
+ }
+ }
+
// Note: FDIVS and FSQRTS cannot be generated when this erratum fix is
// switched on so we don't need to check for them here. They will
// already have been converted to FSQRTD or FDIVD earlier in the
// pipeline.
if (Opcode == SP::FSQRTD || Opcode == SP::FDIVD) {
- // Insert 5 NOPs before FSQRTD,FDIVD.
for (int InsertedCount = 0; InsertedCount < 5; InsertedCount++)
BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
MachineBasicBlock::iterator NMBBI = std::next(MBBI);
- // ... and inserting 28 NOPs after FSQRTD,FDIVD.
for (int InsertedCount = 0; InsertedCount < 28; InsertedCount++)
BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
@@ -330,604 +403,3 @@ bool FixAllFDIVSQRT::runOnMachineFunction(MachineFunction &MF) {
return Modified;
}
-
-//*****************************************************************************
-//**** ReplaceSDIV pass
-//*****************************************************************************
-// This pass fixes the incorrectly working SDIV instruction that
-// exist for some earlier versions of the LEON processor line. The instruction
-// is replaced with an SDIVcc instruction instead, which is working.
-//
-char ReplaceSDIV::ID = 0;
-
-ReplaceSDIV::ReplaceSDIV() : LEONMachineFunctionPass(ID) {}
-
-ReplaceSDIV::ReplaceSDIV(TargetMachine &tm) : LEONMachineFunctionPass(tm, ID) {}
-
-bool ReplaceSDIV::runOnMachineFunction(MachineFunction &MF) {
- Subtarget = &MF.getSubtarget<SparcSubtarget>();
- const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
-
- 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::SDIVrr) {
- MI.setDesc(TII.get(SP::SDIVCCrr));
- Modified = true;
- } else if (Opcode == SP::SDIVri) {
- MI.setDesc(TII.get(SP::SDIVCCri));
- Modified = true;
- }
- }
- }
-
- return Modified;
-}
-
-static RegisterPass<ReplaceSDIV> X("replace-sdiv", "Replase SDIV Pass", false,
- false);
-
-//*****************************************************************************
-//**** FixCALL pass
-//*****************************************************************************
-// This pass restricts the size of the immediate operand of the CALL
-// instruction, which can cause problems on some earlier versions of the LEON
-// processor, which can interpret some of the call address bits incorrectly.
-//
-char FixCALL::ID = 0;
-
-FixCALL::FixCALL(TargetMachine &tm) : LEONMachineFunctionPass(tm, ID) {}
-
-bool FixCALL::runOnMachineFunction(MachineFunction &MF) {
- 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::CALL || Opcode == SP::CALLrr) {
- unsigned NumOperands = MI.getNumOperands();
- for (unsigned OperandIndex = 0; OperandIndex < NumOperands;
- OperandIndex++) {
- MachineOperand &MO = MI.getOperand(OperandIndex);
- if (MO.isImm()) {
- int64_t Value = MO.getImm();
- MO.setImm(Value & 0x000fffffL);
- Modified = true;
- break;
- }
- }
- }
- }
- }
-
- return Modified;
-}
-
-//*****************************************************************************
-//**** IgnoreZeroFlag pass
-//*****************************************************************************
-// This erratum fix fixes the overflow behavior of SDIVCC and UDIVCC
-// instructions that exists on some earlier LEON processors. Where these
-// instructions are detected, they are replaced by a sequence that will
-// explicitly write the overflow bit flag if this is required.
-//
-char IgnoreZeroFlag::ID = 0;
-
-IgnoreZeroFlag::IgnoreZeroFlag(TargetMachine &tm)
- : LEONMachineFunctionPass(tm, ID) {}
-
-bool IgnoreZeroFlag::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::SDIVCCrr || Opcode == SP::SDIVCCri ||
- Opcode == SP::UDIVCCrr || Opcode == SP::UDIVCCri) {
-
- // split the current machine basic block - just after the sdivcc/udivcc
- // instruction
- // create a label that help us skip the zero flag update (of PSR -
- // Processor Status Register)
- // if conditions are not met
- const BasicBlock *LLVM_BB = MBB.getBasicBlock();
- MachineFunction::iterator It =
- std::next(MachineFunction::iterator(MBB));
-
- MachineBasicBlock *dneBB = MF.CreateMachineBasicBlock(LLVM_BB);
- MF.insert(It, dneBB);
-
- // Transfer the remainder of MBB and its successor edges to dneBB.
- dneBB->splice(dneBB->begin(), &MBB,
- std::next(MachineBasicBlock::iterator(MI)), MBB.end());
- dneBB->transferSuccessorsAndUpdatePHIs(&MBB);
-
- MBB.addSuccessor(dneBB);
-
- MachineBasicBlock::iterator NextMBBI = std::next(MBBI);
-
- // bvc - branch if overflow flag not set
- BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND))
- .addMBB(dneBB)
- .addImm(SPCC::ICC_VS);
-
- // bnz - branch if not zero
- BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND))
- .addMBB(dneBB)
- .addImm(SPCC::ICC_NE);
-
- // use the WRPSR (Write Processor State Register) instruction to set the
- // zeo flag to 1
- // create wr %g0, 1, %psr
- BuildMI(MBB, NextMBBI, DL, TII.get(SP::WRPSRri))
- .addReg(SP::G0)
- .addImm(1);
-
- BuildMI(MBB, NextMBBI, DL, TII.get(SP::NOP));
-
- Modified = true;
- }
- }
- }
-
- return Modified;
-}
-
-//*****************************************************************************
-//**** InsertNOPDoublePrecision pass
-//*****************************************************************************
-// This erratum fix for some earlier LEON processors fixes a problem where a
-// double precision load will not yield the correct result if used in FMUL,
-// FDIV, FADD, FSUB or FSQRT instructions later. If this sequence is detected,
-// inserting a NOP between the two instructions will fix the erratum.
-// 1.scans the code after register allocation;
-// 2.checks for the problem conditions as described in the AT697E erratum
-// “Odd-Numbered FPU Register Dependency not Properly Checked in some
-// Double-Precision FPU Operations”;
-// 3.inserts NOPs if the problem exists.
-//
-char InsertNOPDoublePrecision::ID = 0;
-
-InsertNOPDoublePrecision::InsertNOPDoublePrecision(TargetMachine &tm)
- : LEONMachineFunctionPass(tm, ID) {}
-
-bool InsertNOPDoublePrecision::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::LDDFri || Opcode == SP::LDDFrr) {
- MachineBasicBlock::iterator NMBBI = std::next(MBBI);
- MachineInstr &NMI = *NMBBI;
-
- unsigned NextOpcode = NMI.getOpcode();
- if (NextOpcode == SP::FADDD || NextOpcode == SP::FSUBD ||
- NextOpcode == SP::FMULD || NextOpcode == SP::FDIVD) {
- int RegAIndex = GetRegIndexForOperand(MI, 0);
- int RegBIndex = GetRegIndexForOperand(NMI, 0);
- int RegCIndex =
- GetRegIndexForOperand(NMI, 2); // Second source operand is index 2
- int RegDIndex =
- GetRegIndexForOperand(NMI, 1); // Destination operand is index 1
-
- if ((RegAIndex == RegBIndex + 1 && RegBIndex == RegDIndex) ||
- (RegAIndex == RegCIndex + 1 && RegCIndex == RegDIndex) ||
- (RegAIndex == RegBIndex + 1 && RegCIndex == RegDIndex) ||
- (RegAIndex == RegCIndex + 1 && RegBIndex == RegDIndex)) {
- // Insert NOP between the two instructions.
- BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
- Modified = true;
- }
-
- // Check the errata patterns that only happen for FADDD and FMULD
- if (Modified == false &&
- (NextOpcode == SP::FADDD || NextOpcode == SP::FMULD)) {
- RegAIndex = GetRegIndexForOperand(MI, 1);
- if (RegAIndex == RegBIndex + 1 && RegBIndex == RegCIndex &&
- RegBIndex == RegDIndex) {
- // Insert NOP between the two instructions.
- BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
- Modified = true;
- }
- }
- } else if (NextOpcode == SP::FSQRTD) {
- int RegAIndex = GetRegIndexForOperand(MI, 1);
- int RegBIndex = GetRegIndexForOperand(NMI, 0);
- int RegCIndex = GetRegIndexForOperand(NMI, 1);
-
- if (RegAIndex == RegBIndex + 1 && RegBIndex == RegCIndex) {
- // Insert NOP between the two instructions.
- BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
- Modified = true;
- }
- }
- }
- }
- }
-
- return Modified;
-}
-
-//*****************************************************************************
-//**** PreventRoundChange pass
-//*****************************************************************************
-// To prevent any explicit change of the default rounding mode, this pass
-// detects any call of the fesetround function and removes this call from the
-// list of generated operations.
-//
-char PreventRoundChange::ID = 0;
-
-PreventRoundChange::PreventRoundChange(TargetMachine &tm)
- : LEONMachineFunctionPass(tm, ID) {}
-
-bool PreventRoundChange::runOnMachineFunction(MachineFunction &MF) {
- Subtarget = &MF.getSubtarget<SparcSubtarget>();
-
- 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::CALL && MI.getNumOperands() > 0) {
- MachineOperand &MO = MI.getOperand(0);
-
- if (MO.isGlobal()) {
- StringRef FuncName = MO.getGlobal()->getName();
- if (FuncName.compare_lower("fesetround") == 0) {
- MachineBasicBlock::iterator NMBBI = std::next(MBBI);
- emitOptimizationRemark(
- MF.getFunction()->getContext(), getPassName(), *MF.getFunction(),
- MI.getDebugLoc(), "Warning: You are using the prvntroundchange "
- "option to prevent rounding changes caused "
- "by LEON errata. A call to fesetround to be "
- "removed from the output.");
- MI.eraseFromParent();
- MBBI = NMBBI;
- Modified = true;
- }
- }
- }
- }
- }
-
- return Modified;
-}
-//*****************************************************************************
-//**** InsertNOPsLoadStore pass
-//*****************************************************************************
-// This pass shall insert NOPs between floating point loads and stores when the
-// following circumstances are present [5]:
-// Pattern 1:
-// 1. single-precision load or single-precision FPOP to register %fX, where X is
-// the same register as the store being checked;
-// 2. single-precision load or single-precision FPOP to register %fY , where Y
-// is the opposite register in the same double-precision pair;
-// 3. 0-3 instructions of any kind, except stores from %fX or %fY or operations
-// with %fX as destination;
-// 4. the store (from register %fX) being considered.
-// Pattern 2:
-// 1. double-precision FPOP;
-// 2. any number of operations on any kind, except no double-precision FPOP and
-// at most one (less than two) single-precision or single-to-double FPOPs;
-// 3. the store (from register %fX) being considered.
-//
-char InsertNOPsLoadStore::ID = 0;
-
-InsertNOPsLoadStore::InsertNOPsLoadStore(TargetMachine &tm)
- : LEONMachineFunctionPass(tm, ID) {}
-
-bool InsertNOPsLoadStore::runOnMachineFunction(MachineFunction &MF) {
- Subtarget = &MF.getSubtarget<SparcSubtarget>();
- const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
- DebugLoc DL = DebugLoc();
-
- MachineInstr *Pattern1FirstInstruction = NULL;
- MachineInstr *Pattern2FirstInstruction = NULL;
- unsigned int StoreInstructionsToCheck = 0;
- int FxRegIndex, FyRegIndex;
-
- 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;
-
- if (StoreInstructionsToCheck > 0) {
- if (((MI.getOpcode() == SP::STFrr || MI.getOpcode() == SP::STFri) &&
- (GetRegIndexForOperand(MI, LAST_OPERAND) == FxRegIndex ||
- GetRegIndexForOperand(MI, LAST_OPERAND) == FyRegIndex)) ||
- GetRegIndexForOperand(MI, 0) == FxRegIndex) {
- // Insert four NOPs
- for (unsigned InsertedCount = 0; InsertedCount < 4; InsertedCount++) {
- BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
- }
- Modified = true;
- }
- StoreInstructionsToCheck--;
- }
-
- switch (MI.getOpcode()) {
- // Watch for Pattern 1 FPop instructions
- case SP::LDrr:
- case SP::LDri:
- case SP::LDFrr:
- case SP::LDFri:
- case SP::FADDS:
- case SP::FSUBS:
- case SP::FMULS:
- case SP::FDIVS:
- case SP::FSQRTS:
- case SP::FCMPS:
- case SP::FMOVS:
- case SP::FNEGS:
- case SP::FABSS:
- case SP::FITOS:
- case SP::FSTOI:
- case SP::FITOD:
- case SP::FDTOI:
- case SP::FDTOS:
- if (Pattern1FirstInstruction != NULL) {
- FxRegIndex = GetRegIndexForOperand(*Pattern1FirstInstruction, 0);
- FyRegIndex = GetRegIndexForOperand(MI, 0);
-
- // Check to see if these registers are part of the same double
- // precision
- // register pair.
- int DoublePrecRegIndexForX = (FxRegIndex - SP::F0) / 2;
- int DoublePrecRegIndexForY = (FyRegIndex - SP::F0) / 2;
-
- if (DoublePrecRegIndexForX == DoublePrecRegIndexForY)
- StoreInstructionsToCheck = 4;
- }
-
- Pattern1FirstInstruction = &MI;
- break;
- // End of Pattern 1
-
- // Search for Pattern 2
- case SP::FADDD:
- case SP::FSUBD:
- case SP::FMULD:
- case SP::FDIVD:
- case SP::FSQRTD:
- case SP::FCMPD:
- Pattern2FirstInstruction = &MI;
- Pattern1FirstInstruction = NULL;
- break;
-
- case SP::STFrr:
- case SP::STFri:
- case SP::STDFrr:
- case SP::STDFri:
- if (Pattern2FirstInstruction != NULL) {
- if (GetRegIndexForOperand(MI, LAST_OPERAND) ==
- GetRegIndexForOperand(*Pattern2FirstInstruction, 0)) {
- // Insert four NOPs
- for (unsigned InsertedCount = 0; InsertedCount < 4;
- InsertedCount++) {
- BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
- }
-
- Pattern2FirstInstruction = NULL;
- }
- }
- Pattern1FirstInstruction = NULL;
- break;
- // End of Pattern 2
-
- default:
- // Ensure we don't count debug-only values while we're testing for the
- // patterns.
- if (!MI.isDebugValue())
- Pattern1FirstInstruction = NULL;
- break;
- }
- }
- }
-
- return Modified;
-}
-
-
-//****************************************************************************************************************
-//**** FillDataCache pass
-//****************************************************************************************************************
-// This erratum fix inserts after the first operand a loop performing 4096 NOP
-// instructions.
-//
-// mov 0, %l0
-// mov 4096, %l1
-// loop1:
-// inc %l0
-// cmp %l0, %l1
-// ble loop1
-
-char FillDataCache::ID = 0;
-bool FillDataCache::CacheFilled = false;
-
-FillDataCache::FillDataCache(TargetMachine &tm)
- : LEONMachineFunctionPass(tm, ID) {}
-
-bool FillDataCache::runOnMachineFunction(MachineFunction &MF) {
- Subtarget = &MF.getSubtarget<SparcSubtarget>();
- const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
- DebugLoc DL = DebugLoc();
-
- unsigned int CountInstr = 0;
-
- bool Modified = false;
- if (!CacheFilled) {
- for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
-
- if (CacheFilled)
- break;
-
- MachineBasicBlock &MBB = *MFI;
-
- for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
- MachineInstr &MI = *MBBI;
-
- CountInstr++;
- MachineBasicBlock::iterator NextMBBI = std::next(MBBI);
- MBBI = NextMBBI;
-
- // insert the following sequence right after the first instruction
- // initializing the stack pointer (sp register)
- // or %g0, 1, %g1
- // loop1:
- // nop
- // add %g1, 1, %g1
- // cmp %g1, 4096
- // ble .LBB0_1
- if (CountInstr == 1) {
- BuildMI(MBB, NextMBBI, DL, TII.get(SP::ORrr))
- .addReg(SP::G1)
- .addReg(SP::G0)
- .addImm(1);
- } else {
- const BasicBlock *LLVM_BB = MBB.getBasicBlock();
- MachineBasicBlock *dneBB = MF.CreateMachineBasicBlock(LLVM_BB);
-
- MachineFunction::iterator It =
- std::next(MachineFunction::iterator(MBB));
-
- MF.insert(It, dneBB);
-
- BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
-
- BuildMI(MBB, MBBI, DL, TII.get(SP::ADDri))
- .addReg(SP::G1)
- .addReg(SP::G1)
- .addImm(1);
-
- BuildMI(MBB, MBBI, DL, TII.get(SP::CMPri))
- .addReg(SP::G1)
- .addImm(4096);
-
- BuildMI(MBB, MBBI, DL, TII.get(SP::BCOND))
- .addMBB(dneBB)
- .addImm(SPCC::ICC_LE);
-
- dneBB->splice(dneBB->begin(), &MBB,
- std::next(MachineBasicBlock::iterator(MI)), MBB.end());
- dneBB->transferSuccessorsAndUpdatePHIs(&MBB);
-
- MBB.addSuccessor(dneBB);
-
- CacheFilled = true;
- Modified = true;
- break;
- }
- }
- }
- }
-
- return Modified;
-}
-
-
-//****************************************************************************************************************
-//**** RestoreExecAddress pass
-//****************************************************************************************************************
-// This erratum fix should handle user traps of FPU exceptions and restore the
-// execution address by skipping the trapped FPU instruction.
-// The algorithm:
-// find rett - return from trap
-// insert code before rett to:
-// 1. load the FSR register
-// 2. check if there is an FPU exception
-// 3. branch to old rett if there is no exception
-// 4. rett to a restored exec address
-char RestoreExecAddress::ID = 0;
-
-RestoreExecAddress::RestoreExecAddress(TargetMachine &tm)
- : LEONMachineFunctionPass(tm, ID) {}
-
-bool RestoreExecAddress::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;
- bool ExecAddressRestored = false;
- for (auto NMBBI = MBB.begin(), E = MBB.end(); NMBBI != E; ++NMBBI) {
-
- if (NMBBI != E && !ExecAddressRestored) {
- MachineBasicBlock::iterator MBBI = std::next(NMBBI);
- MachineInstr &MI = *MBBI;
- unsigned Opcode = MI.getOpcode();
-
- if (Opcode == SP::RETTrr || Opcode == SP::RETTri) {
-
- const BasicBlock *LLVM_BB = MBB.getBasicBlock();
-
- MachineBasicBlock *dneBB = MF.CreateMachineBasicBlock(LLVM_BB);
-
- // gets the FSR - floating point status register;
- // the firts 4 bits are *cexc* - current exception flags
- BuildMI(MBB, MBBI, DL, TII.get(SP::STFSRrr)).addReg(SP::L7).addImm(0);
-
- BuildMI(MBB, MBBI, DL, TII.get(SP::LDrr))
- .addReg(SP::L7)
- .addReg(SP::L7)
- .addImm(0);
-
- // performs a bitwise AND with b1111 to check the first 4 bits of FSR
- // (cexc)
- // if cexc is not zero, then it is an FPU exception
- BuildMI(MBB, MBBI, DL, TII.get(SP::ANDri))
- .addReg(SP::L7)
- .addReg(SP::L7)
- .addImm(15);
-
- BuildMI(MBB, MBBI, DL, TII.get(SP::CMPri)).addReg(SP::L7).addImm(0);
-
- BuildMI(MBB, MBBI, DL, TII.get(SP::BCOND))
- .addMBB(dneBB)
- .addImm(SPCC::ICC_E);
- // BuildMI(&MBB, DL,
- // TII.get(SP::BCOND)).addMBB(dneBB).addImm(SPCC::ICC_E);
-
- BuildMI(MBB, MBBI, DL, TII.get(SP::RETTri)).addReg(SP::L2).addImm(4);
-
- MachineFunction::iterator It =
- std::next(MachineFunction::iterator(MBB));
- MF.insert(It, dneBB);
-
- // Transfer the remainder of MBB and its successor edges to dneBB.
- dneBB->splice(dneBB->begin(), &MBB, MachineBasicBlock::iterator(MI),
- MBB.end());
- dneBB->transferSuccessorsAndUpdatePHIs(&MBB);
-
- MBB.addSuccessor(dneBB);
-
- ExecAddressRestored = true;
- Modified = true;
- }
- }
- }
- }
-
- return Modified;
-}
-
OpenPOWER on IntegriCloud