[llvm] [Sparc] Add errata workaround pass for GR712RC and UT700 (PR #103843)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 14 05:18:45 PDT 2024
================
@@ -19,6 +19,304 @@
using namespace llvm;
+char ErrataWorkaround::ID = 0;
+
+ErrataWorkaround::ErrataWorkaround() : MachineFunctionPass(ID) {
+ initializeErrataWorkaroundPass(*PassRegistry::getPassRegistry());
+}
+
+INITIALIZE_PASS(ErrataWorkaround, "errata-workaround", "Errata workaround pass",
+ false, false)
+
+bool ErrataWorkaround::moveNext(MachineBasicBlock::iterator &I) {
+
+ MachineBasicBlock *MBB = I->getParent();
+
+ do {
+ I++;
+
+ while (I == MBB->end()) {
+ if (MBB->getFallThrough() == nullptr)
+ return false;
+ MBB = MBB->getFallThrough();
+ I = MBB->begin();
+ }
+ } while (I->isMetaInstruction() || I->isInlineAsm());
+
+ return true;
+}
+
+void ErrataWorkaround::insertNop(MachineBasicBlock::iterator I) {
+ BuildMI(*I->getParent(), I, I->getDebugLoc(), TII->get(SP::NOP));
+}
+
+bool ErrataWorkaround::isFloat(MachineBasicBlock::iterator I) {
+ if (I->getNumOperands() == 0)
+ return false;
+
+ if (!I->getOperand(0).isReg())
+ return false;
+
+ unsigned reg = I->getOperand(0).getReg();
+
+ if (!SP::FPRegsRegClass.contains(reg) && !SP::DFPRegsRegClass.contains(reg))
+ return false;
+
+ return true;
+}
+
+bool ErrataWorkaround::isDivSqrt(MachineBasicBlock::iterator I) {
+ switch (I->getOpcode()) {
+ case SP::FDIVS:
+ case SP::FDIVD:
+ case SP::FSQRTS:
+ case SP::FSQRTD:
+ return true;
+ }
+ return false;
+}
+
+// Prevents the following code sequence from being generated:
+// (stb/sth/st/stf) -> (single non-store/load instruction) -> (any store)
+// If the sequence is detected a NOP instruction is inserted after
+// the first store instruction.
+bool ErrataWorkaround::checkSeqTN0009A(MachineBasicBlock::iterator I) {
+ switch (I->getOpcode()) {
+ case SP::STrr:
+ case SP::STri:
+ case SP::STBrr:
+ case SP::STBri:
+ case SP::STHrr:
+ case SP::STHri:
+ case SP::STFrr:
+ case SP::STFri:
+ break;
+ default:
+ return false;
+ }
+
+ MachineBasicBlock::iterator MI = I;
+ if (!moveNext(MI))
+ return false;
+
+ if (MI->mayStore() || MI->mayLoad())
+ return false;
+
+ MachineBasicBlock::iterator PatchHere = MI;
+
+ if (!moveNext(MI))
+ return false;
+
+ if (!MI->mayStore())
+ return false;
+
+ insertNop(PatchHere);
+ return true;
+}
+
+// Prevents the following code sequence from being generated:
+// (std/stdf) -> (any store)
+// If the sequence is detected a NOP instruction is inserted after
+// the first store instruction.
+bool ErrataWorkaround::checkSeqTN0009B(MachineBasicBlock::iterator I) {
+
+ switch (I->getOpcode()) {
+ case SP::STDrr:
+ case SP::STDri:
+ case SP::STDFrr:
+ case SP::STDFri:
+ break;
+ default:
+ return false;
+ }
+
+ MachineBasicBlock::iterator MI = I;
+
+ if (!moveNext(MI))
+ return false;
+
+ if (!MI->mayStore())
+ return false;
+
+ insertNop(MI);
+ return true;
+}
+
+bool ErrataWorkaround::checkSeqTN0010(MachineBasicBlock::iterator I) {
----------------
koachan wrote:
Probably need a description for this too?
https://github.com/llvm/llvm-project/pull/103843
More information about the llvm-commits
mailing list