Index: lib/Target/Sparc/LeonFeatures.td =================================================================== --- lib/Target/Sparc/LeonFeatures.td +++ lib/Target/Sparc/LeonFeatures.td @@ -83,12 +83,3 @@ "LEON3 erratum fix: Insert NOPs between " "single-precision loads and the store, so the number of " "instructions between is 4">; - -def FillDataCache : SubtargetFeature<"filldatacache", "FillDataCache", "true", - "LEON2 erratum fix: Ensure data cache is " - "filled so that cache misses do not " - "happen later in program execution.">; - -def RestoreExecAddress - : SubtargetFeature<"restexecaddr", "RestoreExecAddress", "true", - "LEON2 erratum fix: Restore execution address.">; Index: lib/Target/Sparc/LeonPasses.cpp =================================================================== --- lib/Target/Sparc/LeonPasses.cpp +++ lib/Target/Sparc/LeonPasses.cpp @@ -745,189 +745,3 @@ 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(); - 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(); - 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; -} - Index: lib/Target/Sparc/Sparc.td =================================================================== --- lib/Target/Sparc/Sparc.td +++ lib/Target/Sparc/Sparc.td @@ -107,8 +107,7 @@ // AT697E: Provides full coverage of AT697E - covers all the erratum fixes for // LEON2 AT697E def : Processor<"at697e", LEON2Itineraries, [ - FeatureLeon, ReplaceSDIV, FixCALL, IgnoreZeroFlag, InsertNOPDoublePrecision, - FillDataCache, RestoreExecAddress + FeatureLeon, ReplaceSDIV, FixCALL, IgnoreZeroFlag, InsertNOPDoublePrecision ]>; // LEON 2 FT (AT697F) Index: lib/Target/Sparc/SparcSubtarget.h =================================================================== --- lib/Target/Sparc/SparcSubtarget.h +++ lib/Target/Sparc/SparcSubtarget.h @@ -55,8 +55,6 @@ bool InsertNOPDoublePrecision; bool PreventRoundChange; bool InsertNOPsLoadStore; - bool FillDataCache; - bool RestoreExecAddress; SparcInstrInfo InstrInfo; SparcTargetLowering TLInfo; @@ -107,8 +105,6 @@ bool fixAllFDIVSQRT() const { return FixAllFDIVSQRT; } bool insertNOPsLoadStore() const { return InsertNOPsLoadStore; } bool insertNOPLoad() const { return InsertNOPLoad; } - bool fillDataCache() const { return FillDataCache; } - bool restoreExecAddr() const { return RestoreExecAddress; } /// ParseSubtargetFeatures - Parses features string setting specified /// subtarget options. Definition of function is auto generated by tblgen. Index: lib/Target/Sparc/SparcSubtarget.cpp =================================================================== --- lib/Target/Sparc/SparcSubtarget.cpp +++ lib/Target/Sparc/SparcSubtarget.cpp @@ -49,9 +49,6 @@ FixAllFDIVSQRT = false; InsertNOPLoad = false; InsertNOPsLoadStore = false; - FillDataCache = false; - RestoreExecAddress = false; - // Determine default and user specified characteristics std::string CPUName = CPU; Index: lib/Target/Sparc/SparcTargetMachine.cpp =================================================================== --- lib/Target/Sparc/SparcTargetMachine.cpp +++ lib/Target/Sparc/SparcTargetMachine.cpp @@ -171,12 +171,6 @@ if (this->getSparcTargetMachine().getSubtargetImpl()->insertNOPLoad()) { addPass(new InsertNOPLoad(getSparcTargetMachine())); } - if (this->getSparcTargetMachine().getSubtargetImpl()->fillDataCache()) { - addPass(new FillDataCache(getSparcTargetMachine())); - } - if (this->getSparcTargetMachine().getSubtargetImpl()->restoreExecAddr()) { - addPass(new RestoreExecAddress(getSparcTargetMachine())); - } if (this->getSparcTargetMachine() .getSubtargetImpl() ->insertNOPDoublePrecision()) { Index: test/CodeGen/SPARC/LeonFillDataCachePassUT.ll =================================================================== --- test/CodeGen/SPARC/LeonFillDataCachePassUT.ll +++ test/CodeGen/SPARC/LeonFillDataCachePassUT.ll @@ -1,27 +0,0 @@ -; RUN: llc %s -O0 -march=sparc -mcpu=leon2 -mattr=+filldatacache -o - | FileCheck %s -; RUN: llc %s -O0 -march=sparc -mcpu=at697e -o - | FileCheck %s -; RUN: llc %s -O0 -march=sparc -mcpu=at697f -mattr=+filldatacache -o - | FileCheck %s - -; CHECK-LABEL: test_filldatacache_1 -; CHECK: or %g0, 1, %g1 -; CHECK: nop -; CHECK-NEXT: add %g1, 1, %g1 -; CHECK-NEXT: cmp %g1, 4096 -; CHECK-NEXT: ble {{.+}} -define zeroext i1@test_filldatacache_1(i1 zeroext %a, i1 zeroext %b) { - %1 = tail call zeroext i1 asm sideeffect "udivcc $0, $1, $2", "=r,r,r"(i1 zeroext %a, i1 zeroext %b) - - ret i1 %1 -} - - -; CHECK-LABEL: test_filldatacache_2 -; CHECK-NOT: or %g0, 1, %g1 -; CHECK-NOT: add %g1, 1, %g1 -; CHECK-NOT: cmp %g1, 4096 -; CHECK-NOT: ble {{.+}} -define zeroext i1@test_filldatacache_2(i1 zeroext %a, i1 zeroext %b) { - %1 = tail call zeroext i1 asm sideeffect "sdivcc $0, $1, $2", "=r,r,r"(i1 zeroext %a, i1 zeroext %b) - - ret i1 %1 -}