aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp')
-rw-r--r--contrib/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp29
1 files changed, 25 insertions, 4 deletions
diff --git a/contrib/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/contrib/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index 52432a5820fb..d6db354e0215 100644
--- a/contrib/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/contrib/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -251,7 +251,6 @@ namespace {
struct PPCOperand;
class PPCAsmParser : public MCTargetAsmParser {
- const MCInstrInfo &MII;
bool IsPPC64;
bool IsDarwin;
@@ -298,7 +297,7 @@ class PPCAsmParser : public MCTargetAsmParser {
public:
PPCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &,
const MCInstrInfo &MII, const MCTargetOptions &Options)
- : MCTargetAsmParser(Options, STI), MII(MII) {
+ : MCTargetAsmParser(Options, STI, MII) {
// Check for 64-bit vs. 32-bit pointer mode.
const Triple &TheTriple = STI.getTargetTriple();
IsPPC64 = (TheTriple.getArch() == Triple::ppc64 ||
@@ -394,6 +393,10 @@ public:
/// getEndLoc - Get the location of the last token of this operand.
SMLoc getEndLoc() const override { return EndLoc; }
+ /// getLocRange - Get the range between the first and last token of this
+ /// operand.
+ SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
+
/// isPPC64 - True if this operand is for an instruction in 64-bit mode.
bool isPPC64() const { return IsPPC64; }
@@ -1138,6 +1141,15 @@ void PPCAsmParser::ProcessInstruction(MCInst &Inst,
Inst = TmpInst;
break;
}
+ case PPC::SUBPCIS: {
+ MCInst TmpInst;
+ int64_t N = Inst.getOperand(1).getImm();
+ TmpInst.setOpcode(PPC::ADDPCIS);
+ TmpInst.addOperand(Inst.getOperand(0));
+ TmpInst.addOperand(MCOperand::createImm(-N));
+ Inst = TmpInst;
+ break;
+ }
case PPC::SRDI:
case PPC::SRDIo: {
MCInst TmpInst;
@@ -1260,6 +1272,9 @@ void PPCAsmParser::ProcessInstruction(MCInst &Inst,
}
}
+static std::string PPCMnemonicSpellCheck(StringRef S, uint64_t FBS,
+ unsigned VariantID = 0);
+
bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
OperandVector &Operands,
MCStreamer &Out, uint64_t &ErrorInfo,
@@ -1275,8 +1290,13 @@ bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return false;
case Match_MissingFeature:
return Error(IDLoc, "instruction use requires an option to be enabled");
- case Match_MnemonicFail:
- return Error(IDLoc, "unrecognized instruction mnemonic");
+ case Match_MnemonicFail: {
+ uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
+ std::string Suggestion = PPCMnemonicSpellCheck(
+ ((PPCOperand &)*Operands[0]).getToken(), FBS);
+ return Error(IDLoc, "invalid instruction" + Suggestion,
+ ((PPCOperand &)*Operands[0]).getLocRange());
+ }
case Match_InvalidOperand: {
SMLoc ErrorLoc = IDLoc;
if (ErrorInfo != ~0ULL) {
@@ -1912,6 +1932,7 @@ extern "C" void LLVMInitializePowerPCAsmParser() {
#define GET_REGISTER_MATCHER
#define GET_MATCHER_IMPLEMENTATION
+#define GET_MNEMONIC_SPELL_CHECKER
#include "PPCGenAsmMatcher.inc"
// Define this matcher function after the auto-generated include so we