xref: /openbsd-src/gnu/llvm/llvm/lib/Target/Mips/MipsLoongson2FBTBFix.cpp (revision e73ff4e669dda94395f3f3df1c98f51838c775d0)
1*e73ff4e6Svisa //===- MipsLoongson2FBTBFix.cpp -------------------------------------------===//
2*e73ff4e6Svisa //
3*e73ff4e6Svisa // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e73ff4e6Svisa // See https://llvm.org/LICENSE.txt for license information.
5*e73ff4e6Svisa // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e73ff4e6Svisa //
7*e73ff4e6Svisa //===----------------------------------------------------------------------===//
8*e73ff4e6Svisa 
9*e73ff4e6Svisa #include "Mips.h"
10*e73ff4e6Svisa #include "MipsTargetMachine.h"
11*e73ff4e6Svisa #include "llvm/CodeGen/MachineFunctionPass.h"
12*e73ff4e6Svisa #include "llvm/CodeGen/Passes.h"
13*e73ff4e6Svisa 
14*e73ff4e6Svisa using namespace llvm;
15*e73ff4e6Svisa 
16*e73ff4e6Svisa namespace {
17*e73ff4e6Svisa 
18*e73ff4e6Svisa class MipsLoongson2FBTBFix : public MachineFunctionPass {
19*e73ff4e6Svisa public:
20*e73ff4e6Svisa   static char ID;
21*e73ff4e6Svisa 
MipsLoongson2FBTBFix()22*e73ff4e6Svisa   MipsLoongson2FBTBFix() : MachineFunctionPass(ID) {
23*e73ff4e6Svisa     initializeMipsLoongson2FBTBFixPass(*PassRegistry::getPassRegistry());
24*e73ff4e6Svisa   }
25*e73ff4e6Svisa 
26*e73ff4e6Svisa   bool runOnMachineFunction(MachineFunction &MF) override;
27*e73ff4e6Svisa 
getPassName() const28*e73ff4e6Svisa   StringRef getPassName() const override {
29*e73ff4e6Svisa     return "Loongson 2F BTB erratum workaround pass";
30*e73ff4e6Svisa   }
31*e73ff4e6Svisa 
32*e73ff4e6Svisa private:
33*e73ff4e6Svisa   bool runOnBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB);
34*e73ff4e6Svisa };
35*e73ff4e6Svisa 
36*e73ff4e6Svisa } // end of anonymous namespace
37*e73ff4e6Svisa 
38*e73ff4e6Svisa char MipsLoongson2FBTBFix::ID = 0;
39*e73ff4e6Svisa 
40*e73ff4e6Svisa INITIALIZE_PASS(MipsLoongson2FBTBFix, "loongson2f-btb-fix-pass",
41*e73ff4e6Svisa                 "Mips Loongson 2F BTB erratum workaround", false, false)
42*e73ff4e6Svisa 
createMipsLoongson2FBTBFix()43*e73ff4e6Svisa FunctionPass *llvm::createMipsLoongson2FBTBFix() {
44*e73ff4e6Svisa   return new MipsLoongson2FBTBFix();
45*e73ff4e6Svisa }
46*e73ff4e6Svisa 
runOnMachineFunction(MachineFunction & MF)47*e73ff4e6Svisa bool MipsLoongson2FBTBFix::runOnMachineFunction(MachineFunction &MF) {
48*e73ff4e6Svisa   bool Changed = false;
49*e73ff4e6Svisa 
50*e73ff4e6Svisa   for (auto &MBB : MF) {
51*e73ff4e6Svisa     Changed |= runOnBasicBlock(MF, MBB);
52*e73ff4e6Svisa   }
53*e73ff4e6Svisa   return Changed;
54*e73ff4e6Svisa }
55*e73ff4e6Svisa 
runOnBasicBlock(MachineFunction & MF,MachineBasicBlock & MBB)56*e73ff4e6Svisa bool MipsLoongson2FBTBFix::runOnBasicBlock(
57*e73ff4e6Svisa     MachineFunction &MF, MachineBasicBlock &MBB) {
58*e73ff4e6Svisa   MachineRegisterInfo &MRI = MF.getRegInfo();
59*e73ff4e6Svisa   const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
60*e73ff4e6Svisa   bool Changed = false;
61*e73ff4e6Svisa 
62*e73ff4e6Svisa   for (auto &MI : MBB) {
63*e73ff4e6Svisa     if (!MI.isCall() && !MI.isIndirectBranch() && !MI.isReturn())
64*e73ff4e6Svisa       continue;
65*e73ff4e6Svisa 
66*e73ff4e6Svisa     // Skip calls that are not through a register.
67*e73ff4e6Svisa     if (MI.isCall()) {
68*e73ff4e6Svisa       if (MI.getNumOperands() == 0)
69*e73ff4e6Svisa         continue;
70*e73ff4e6Svisa       const MachineOperand &MO = MI.getOperand(0);
71*e73ff4e6Svisa       if (!MO.isReg())
72*e73ff4e6Svisa         continue;
73*e73ff4e6Svisa     }
74*e73ff4e6Svisa 
75*e73ff4e6Svisa     Changed = true;
76*e73ff4e6Svisa 
77*e73ff4e6Svisa     DebugLoc MBBDL = MI.getDebugLoc();
78*e73ff4e6Svisa     Register TempReg = MRI.createVirtualRegister(&Mips::GPR64RegClass);
79*e73ff4e6Svisa 
80*e73ff4e6Svisa     // li $TempReg, COP_0_BTB_CLEAR | COP_0_RAS_DISABLE
81*e73ff4e6Svisa     BuildMI(MBB, MI, MBBDL, TII->get(Mips::ORi), TempReg)
82*e73ff4e6Svisa         .addReg(Mips::ZERO)
83*e73ff4e6Svisa         .addImm(3);
84*e73ff4e6Svisa     // dmtc0 $TempReg, COP_0_DIAG
85*e73ff4e6Svisa     BuildMI(MBB, MI, MBBDL, TII->get(Mips::DMTC0))
86*e73ff4e6Svisa         .addReg(Mips::COP022)
87*e73ff4e6Svisa         .addReg(TempReg)
88*e73ff4e6Svisa         .addImm(0);
89*e73ff4e6Svisa   }
90*e73ff4e6Svisa   return Changed;
91*e73ff4e6Svisa }
92