100 lines
2.9 KiB
Plaintext
100 lines
2.9 KiB
Plaintext
$OpenBSD: patch-lib_Target_Mips_MipsLoongson2FBTBFix_cpp,v 1.1 2020/12/21 21:38:51 jca Exp $
|
|
|
|
Adapt the -mfix-loongson2f-btb workaround from as(1) to LLVM/clang.
|
|
|
|
Index: lib/Target/Mips/MipsLoongson2FBTBFix.cpp
|
|
--- lib/Target/Mips/MipsLoongson2FBTBFix.cpp.orig
|
|
+++ lib/Target/Mips/MipsLoongson2FBTBFix.cpp
|
|
@@ -0,0 +1,91 @@
|
|
+//===- MipsLoongson2FBTBFix.cpp -------------------------------------------===//
|
|
+//
|
|
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
+// See https://llvm.org/LICENSE.txt for license information.
|
|
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
+//
|
|
+//===----------------------------------------------------------------------===//
|
|
+
|
|
+#include "Mips.h"
|
|
+#include "MipsTargetMachine.h"
|
|
+#include "llvm/CodeGen/MachineFunctionPass.h"
|
|
+#include "llvm/CodeGen/Passes.h"
|
|
+
|
|
+using namespace llvm;
|
|
+
|
|
+namespace {
|
|
+
|
|
+class MipsLoongson2FBTBFix : public MachineFunctionPass {
|
|
+public:
|
|
+ static char ID;
|
|
+
|
|
+ MipsLoongson2FBTBFix() : MachineFunctionPass(ID) {
|
|
+ initializeMipsLoongson2FBTBFixPass(*PassRegistry::getPassRegistry());
|
|
+ }
|
|
+
|
|
+ bool runOnMachineFunction(MachineFunction &MF) override;
|
|
+
|
|
+ StringRef getPassName() const override {
|
|
+ return "Loongson 2F BTB erratum workaround pass";
|
|
+ }
|
|
+
|
|
+private:
|
|
+ bool runOnBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB);
|
|
+};
|
|
+
|
|
+} // end of anonymous namespace
|
|
+
|
|
+char MipsLoongson2FBTBFix::ID = 0;
|
|
+
|
|
+INITIALIZE_PASS(MipsLoongson2FBTBFix, "loongson2f-btb-fix-pass",
|
|
+ "Mips Loongson 2F BTB erratum workaround", false, false)
|
|
+
|
|
+FunctionPass *llvm::createMipsLoongson2FBTBFix() {
|
|
+ return new MipsLoongson2FBTBFix();
|
|
+}
|
|
+
|
|
+bool MipsLoongson2FBTBFix::runOnMachineFunction(MachineFunction &MF) {
|
|
+ bool Changed = false;
|
|
+
|
|
+ for (auto &MBB : MF) {
|
|
+ Changed |= runOnBasicBlock(MF, MBB);
|
|
+ }
|
|
+ return Changed;
|
|
+}
|
|
+
|
|
+bool MipsLoongson2FBTBFix::runOnBasicBlock(
|
|
+ MachineFunction &MF, MachineBasicBlock &MBB) {
|
|
+ MachineRegisterInfo &MRI = MF.getRegInfo();
|
|
+ const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
|
|
+ bool Changed = false;
|
|
+
|
|
+ for (auto &MI : MBB) {
|
|
+ if (!MI.isCall() && !MI.isIndirectBranch() && !MI.isReturn())
|
|
+ continue;
|
|
+
|
|
+ // Skip calls that are not through a register.
|
|
+ if (MI.isCall()) {
|
|
+ if (MI.getNumOperands() == 0)
|
|
+ continue;
|
|
+ const MachineOperand &MO = MI.getOperand(0);
|
|
+ if (!MO.isReg())
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ Changed = true;
|
|
+
|
|
+ DebugLoc MBBDL = MI.getDebugLoc();
|
|
+ Register TempReg = MRI.createVirtualRegister(&Mips::GPR64RegClass);
|
|
+
|
|
+ // li $TempReg, COP_0_BTB_CLEAR | COP_0_RAS_DISABLE
|
|
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::ORi), TempReg)
|
|
+ .addReg(Mips::ZERO)
|
|
+ .addImm(3);
|
|
+ // dmtc0 $TempReg, COP_0_DIAG
|
|
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::DMTC0))
|
|
+ .addReg(Mips::COP022)
|
|
+ .addReg(TempReg)
|
|
+ .addImm(0);
|
|
+ }
|
|
+ return Changed;
|
|
+}
|