openbsd-ports/devel/llvm/patches/patch-lib_Target_Mips_AsmParser_MipsAsmParser_cpp
2022-03-10 00:04:05 +00:00

84 lines
2.7 KiB
Plaintext

Adapt the -mfix-loongson2f-btb workaround from as(1) to LLVM/clang.
Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp
--- lib/Target/Mips/AsmParser/MipsAsmParser.cpp.orig
+++ 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,19 @@ 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;
+ 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 +3351,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;
}