Adapt the -mfix-loongson2f-btb workaround from as(1) to LLVM/clang.

Index: llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
--- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp.orig
+++ llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -68,6 +68,7 @@ class MCInstrInfo;
 } // end namespace llvm
 
 extern cl::opt<bool> EmitJalrReloc;
+extern cl::opt<bool> FixLoongson2FBTB;
 
 namespace {
 
@@ -236,6 +237,9 @@ class MipsAsmParser : public MCTargetAsmParser {
 
   bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
 
+  bool emitLoongson2FBTBFlush(MCInst &Inst, MipsTargetStreamer &TOut,
+                              SMLoc IDLoc, const MCSubtargetInfo *STI);
+
   bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
                      MCStreamer &Out, const MCSubtargetInfo *STI);
 
@@ -2104,6 +2108,20 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, S
     Inst = BInst;
   }
 
+  if (FixLoongson2FBTB) {
+    switch (Inst.getOpcode()) {
+    case Mips::JALR:
+    case Mips::JR:
+    case Mips::JalOneReg:
+    case Mips::JalTwoReg:
+      if (emitLoongson2FBTBFlush(Inst, TOut, IDLoc, STI))
+        return true;
+      LLVM_FALLTHROUGH;
+    default:
+      break;
+    }
+  }
+
   // This expansion is not in a function called by tryExpandInstruction()
   // because the pseudo-instruction doesn't have a distinct opcode.
   if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
@@ -3334,6 +3352,39 @@ bool MipsAsmParser::emitPartialAddress(MipsTargetStrea
       TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
     }
   }
+  return false;
+}
+
+bool MipsAsmParser::emitLoongson2FBTBFlush(MCInst &Inst,
+                                           MipsTargetStreamer &TOut,
+                                           SMLoc IDLoc,
+                                           const MCSubtargetInfo *STI) {
+  unsigned SReg = Inst.getOperand(0).getReg();
+  if (SReg == Mips::ZERO || SReg == Mips::ZERO_64 ||
+      SReg == Mips::K0 || SReg == Mips::K0_64 ||
+      SReg == Mips::K1 || SReg == Mips::K1_64)
+    return false;
+
+  unsigned ATReg = getATReg(IDLoc);
+  if (ATReg == 0)
+    return true;
+
+  // Direct comparison of SReg and ATReg is not reliable because
+  // the register classes may differ.
+  unsigned ATRegIndex = AssemblerOptions.back()->getATRegIndex();
+  if (ATRegIndex == 0)
+    return true;
+  if (SReg == getReg(Mips::GPR32RegClassID, ATRegIndex) ||
+      SReg == getReg(Mips::GPR64RegClassID, ATRegIndex))
+    return false;
+
+  warnIfNoMacro(IDLoc);
+
+  // li $at, COP_0_BTB_CLEAR | COP_0_RAS_DISABLE
+  TOut.emitRRI(Mips::ORi, ATReg, Mips::ZERO, 3, IDLoc, STI);
+  // dmtc0 $at, COP_0_DIAG
+  TOut.emitRRI(Mips::DMTC0, Mips::COP022, ATReg, 0, IDLoc, STI);
+
   return false;
 }
 
