diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h index 2b5a672d6d1..16cf6273a5a 100644 --- a/include/llvm/MC/MCTargetAsmParser.h +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -89,11 +89,11 @@ public: /// On failure, the target parser is responsible for emitting a diagnostic /// explaining the match failure. virtual bool - MatchInstruction(SMLoc IDLoc, unsigned &Kind, + MatchInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, - SmallVectorImpl &MCInsts, - unsigned &OrigErrorInfo, - bool matchingInlineAsm = false) { + MCStreamer &Out, unsigned &Kind, unsigned &Opcode, + SmallVectorImpl > &MapAndConstraints, + unsigned &OrigErrorInfo, bool matchingInlineAsm = false) { OrigErrorInfo = ~0x0; return true; } @@ -115,10 +115,9 @@ public: return Match_Success; } - virtual unsigned getMCInstOperandNum(unsigned Kind, + virtual void convertToMapAndConstraints(unsigned Kind, const SmallVectorImpl &Operands, - unsigned OperandNum, - unsigned &NumMCOperands) = 0; + SmallVectorImpl > &MapAndConstraints) = 0; }; } // End llvm namespace diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index aa5ba46ab21..9e926492179 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7480,8 +7480,10 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned Kind; unsigned ErrorInfo; unsigned MatchResult; - - MatchResult = MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo); + SmallVector, 4> MapAndConstraints; + MatchResult = MatchInstructionImpl(Operands, Kind, Inst, + MapAndConstraints, ErrorInfo, + /*matchingInlineAsm*/ false); switch (MatchResult) { default: break; case Match_Success: diff --git a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp index 9e22fd06d17..09eb4c8cabe 100644 --- a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp +++ b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp @@ -318,8 +318,9 @@ MatchAndEmitInstruction(SMLoc IDLoc, MCInst Inst; unsigned Kind; unsigned ErrorInfo; - - switch (MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo)) { + SmallVector, 4> MapAndConstraints; + switch (MatchInstructionImpl(Operands, Kind, Inst, MapAndConstraints, + ErrorInfo, /*matchingInlineAsm*/ false)) { default: break; case Match_Success: Out.EmitInstruction(Inst); diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index b1ada100f49..349abef16be 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -261,9 +261,12 @@ MatchAndEmitInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, MCStreamer &Out) { MCInst Inst; - unsigned ErrorInfo; unsigned Kind; - unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo); + unsigned ErrorInfo; + SmallVector, 4> MapAndConstraints; + unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst, + MapAndConstraints, ErrorInfo, + /*matchingInlineAsm*/ false); switch (MatchResult) { default: break; diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 9263bdde20d..704d5f94261 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -66,12 +66,11 @@ private: bool MatchAndEmitInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, MCStreamer &Out); - - bool MatchInstruction(SMLoc IDLoc, unsigned &Kind, + bool MatchInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, - SmallVectorImpl &MCInsts, - unsigned &OrigErrorInfo, - bool matchingInlineAsm = false); + MCStreamer &Out, unsigned &Kind, unsigned &Opcode, + SmallVectorImpl > &MapAndConstraints, + unsigned &OrigErrorInfo, bool matchingInlineAsm = false); /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi) /// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode. @@ -1521,22 +1520,20 @@ MatchAndEmitInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, MCStreamer &Out) { unsigned Kind; + unsigned Opcode; unsigned ErrorInfo; - SmallVector Insts; - - bool Error = MatchInstruction(IDLoc, Kind, Operands, Insts, - ErrorInfo); - if (!Error) - for (unsigned i = 0, e = Insts.size(); i != e; ++i) - Out.EmitInstruction(Insts[i]); + SmallVector, 4> MapAndConstraints; + bool Error = MatchInstruction(IDLoc, Operands, Out, Kind, Opcode, + MapAndConstraints, ErrorInfo); return Error; } bool X86AsmParser:: -MatchInstruction(SMLoc IDLoc, unsigned &Kind, +MatchInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, - SmallVectorImpl &MCInsts, unsigned &OrigErrorInfo, - bool matchingInlineAsm) { + MCStreamer &Out, unsigned &Kind, unsigned &Opcode, + SmallVectorImpl > &MapAndConstraints, + unsigned &OrigErrorInfo, bool matchingInlineAsm) { assert(!Operands.empty() && "Unexpect empty operand list!"); X86Operand *Op = static_cast(Operands[0]); assert(Op->isToken() && "Leading operand should always be a mnemonic!"); @@ -1553,7 +1550,8 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind, MCInst Inst; Inst.setOpcode(X86::WAIT); Inst.setLoc(IDLoc); - MCInsts.push_back(Inst); + if (!matchingInlineAsm) + Out.EmitInstruction(Inst); const char *Repl = StringSwitch(Op->getToken()) @@ -1575,18 +1573,22 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind, MCInst Inst; // First, try a direct match. - switch (MatchInstructionImpl(Operands, Kind, Inst, OrigErrorInfo, + switch (MatchInstructionImpl(Operands, Kind, Inst, MapAndConstraints, + OrigErrorInfo, matchingInlineAsm, isParsingIntelSyntax())) { default: break; case Match_Success: // Some instructions need post-processing to, for example, tweak which // encoding is selected. Loop on it while changes happen so the // individual transformations can chain off each other. - while (processInstruction(Inst, Operands)) - ; + if (!matchingInlineAsm) + while (processInstruction(Inst, Operands)) + ; Inst.setLoc(IDLoc); - MCInsts.push_back(Inst); + if (!matchingInlineAsm) + Out.EmitInstruction(Inst); + Opcode = Inst.getOpcode(); return false; case Match_MissingFeature: Error(IDLoc, "instruction requires a CPU feature not currently enabled", @@ -1625,20 +1627,21 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind, unsigned Match1, Match2, Match3, Match4; unsigned tKind; - Match1 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore, - isParsingIntelSyntax()); + SmallVector, 4> tMapAndConstraints[4]; + Match1 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[0], + ErrorInfoIgnore, isParsingIntelSyntax()); if (Match1 == Match_Success) Kind = tKind; Tmp[Base.size()] = Suffixes[1]; - Match2 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore, - isParsingIntelSyntax()); + Match2 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[1], + ErrorInfoIgnore, isParsingIntelSyntax()); if (Match2 == Match_Success) Kind = tKind; Tmp[Base.size()] = Suffixes[2]; - Match3 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore, - isParsingIntelSyntax()); + Match3 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[2], + ErrorInfoIgnore, isParsingIntelSyntax()); if (Match3 == Match_Success) Kind = tKind; Tmp[Base.size()] = Suffixes[3]; - Match4 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore, - isParsingIntelSyntax()); + Match4 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[3], + ErrorInfoIgnore, isParsingIntelSyntax()); if (Match4 == Match_Success) Kind = tKind; // Restore the old token. @@ -1652,7 +1655,10 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind, (Match3 == Match_Success) + (Match4 == Match_Success); if (NumSuccessfulMatches == 1) { Inst.setLoc(IDLoc); - MCInsts.push_back(Inst); + if (!matchingInlineAsm) + Out.EmitInstruction(Inst); + Opcode = Inst.getOpcode(); + // FIXME: Handle the map and constraints. return false; } diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 7b49723d215..7e040894f90 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -1674,9 +1674,9 @@ static unsigned getConverterOperandID(const std::string &Name, } -static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, - std::vector &Infos, - raw_ostream &OS) { +static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, + std::vector &Infos, + raw_ostream &OS) { SetVector OperandConversionKinds; SetVector InstructionConversionKinds; std::vector > ConversionTable; @@ -1713,29 +1713,22 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, std::string OperandFnBody; raw_string_ostream OpOS(OperandFnBody); // Start the operand number lookup function. - OpOS << "unsigned " << Target.getName() << ClassName << "::\n" - << "getMCInstOperandNum(unsigned Kind,\n" - << " const SmallVectorImpl " - << "&Operands,\n unsigned OperandNum, unsigned " - << "&NumMCOperands) {\n" + OpOS << "void " << Target.getName() << ClassName << "::\n" + << "convertToMapAndConstraints(unsigned Kind,\n"; + OpOS.indent(20); + OpOS << "const SmallVectorImpl &Operands,\n" + << "SmallVectorImpl >" + << " &MapAndConstraints) {\n" << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n" - << " NumMCOperands = 0;\n" - << " unsigned MCOperandNum = 0;\n" + << " unsigned NumMCOperands = 0;\n" << " const uint8_t *Converter = ConversionTable[Kind];\n" << " for (const uint8_t *p = Converter; *p; p+= 2) {\n" - << " if (*(p + 1) > OperandNum) continue;\n" << " switch (*p) {\n" << " default: llvm_unreachable(\"invalid conversion entry!\");\n" << " case CVT_Reg:\n" - << " if (*(p + 1) == OperandNum) {\n" - << " NumMCOperands = 1;\n" - << " break;\n" - << " }\n" - << " ++MCOperandNum;\n" - << " break;\n" << " case CVT_Tied:\n" - << " // FIXME: Tied operand calculation not supported.\n" - << " assert (0 && \"getMCInstOperandNumImpl() doesn't support tied operands, yet!\");\n" + << " MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"r\"));\n" + << " ++NumMCOperands;\n" << " break;\n"; // Pre-populate the operand conversion kinds with the standard always @@ -1831,11 +1824,8 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, // Add a handler for the operand number lookup. OpOS << " case " << Name << ":\n" - << " if (*(p + 1) == OperandNum) {\n" - << " NumMCOperands = " << OpInfo.MINumOperands << ";\n" - << " break;\n" - << " }\n" - << " MCOperandNum += " << OpInfo.MINumOperands << ";\n" + << " MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"r\"));\n" + << " NumMCOperands += " << OpInfo.MINumOperands << ";\n" << " break;\n"; break; } @@ -1872,11 +1862,8 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, << " break;\n"; OpOS << " case " << Name << ":\n" - << " if (*(p + 1) == OperandNum) {\n" - << " NumMCOperands = 1;\n" - << " break;\n" - << " }\n" - << " ++MCOperandNum;\n" + << " MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"\"));\n" + << " ++NumMCOperands;\n" << " break;\n"; break; } @@ -1905,11 +1892,8 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, << " break;\n"; OpOS << " case " << Name << ":\n" - << " if (*(p + 1) == OperandNum) {\n" - << " NumMCOperands = 1;\n" - << " break;\n" - << " }\n" - << " ++MCOperandNum;\n" + << " MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"r\"));\n" + << " ++NumMCOperands;\n" << " break;\n"; } } @@ -1934,7 +1918,7 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, CvtOS << " }\n }\n}\n\n"; // Finish up the operand number lookup function. - OpOS << " }\n }\n return MCOperandNum;\n}\n\n"; + OpOS << " }\n }\n}\n\n"; OS << "namespace {\n"; @@ -2617,15 +2601,16 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { << "unsigned Opcode,\n" << " const SmallVectorImpl " << "&Operands);\n"; - OS << " unsigned getMCInstOperandNum(unsigned Kind,\n" - << " const " - << "SmallVectorImpl &Operands,\n " - << " unsigned OperandNum, unsigned &NumMCOperands);\n"; + OS << " void convertToMapAndConstraints(unsigned Kind,\n"; + OS << "const SmallVectorImpl &Operands,\n" + << "SmallVectorImpl >" + << " &MapAndConstraints);\n"; OS << " bool mnemonicIsValid(StringRef Mnemonic);\n"; OS << " unsigned MatchInstructionImpl(\n" << " const SmallVectorImpl &Operands,\n" << " unsigned &Kind, MCInst &Inst, " - << "unsigned &ErrorInfo,\n unsigned VariantID = 0);\n"; + << "SmallVectorImpl > &MapAndConstraints,\n" + << "unsigned &ErrorInfo,\n bool matchingInlineAsm, unsigned VariantID = 0);\n"; if (Info.OperandMatchInfo.size()) { OS << "\n enum OperandMatchResultTy {\n"; @@ -2678,8 +2663,10 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { // Generate the function that remaps for mnemonic aliases. bool HasMnemonicAliases = emitMnemonicAliases(OS, Info); - // Generate the unified function to convert operands into an MCInst. - emitConvertToMCInst(Target, ClassName, Info.Matchables, OS); + // Generate the convertToMCInst function to convert operands into an MCInst. + // Also, generate the convertToMapAndConstraints function for MS-style inline + // assembly. The latter doesn't actually generate a MCInst. + emitConvertFuncs(Target, ClassName, Info.Matchables, OS); // Emit the enumeration for classes which participate in matching. emitMatchClassEnumeration(Target, Info.Classes, OS); @@ -2813,8 +2800,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { << Target.getName() << ClassName << "::\n" << "MatchInstructionImpl(const SmallVectorImpl" << " &Operands,\n"; - OS << " unsigned &Kind, MCInst &Inst, unsigned "; - OS << "&ErrorInfo,\n unsigned VariantID) {\n"; + OS << " unsigned &Kind, MCInst &Inst,\n" + << "SmallVectorImpl > &MapAndConstraints,\n" + << "unsigned &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n"; OS << " // Eliminate obvious mismatches.\n"; OS << " if (Operands.size() > " << (MaxNumOperands+1) << ") {\n"; @@ -2908,6 +2896,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " continue;\n"; OS << " }\n"; OS << "\n"; + OS << " if (matchingInlineAsm) {\n"; + OS << " Kind = it->ConvertFn;\n"; + OS << " Inst.setOpcode(it->Opcode);\n"; + OS << " convertToMapAndConstraints(it->ConvertFn, Operands, MapAndConstraints);\n"; + OS << " return Match_Success;\n"; + OS << " }\n\n"; OS << " // We have selected a definite instruction, convert the parsed\n" << " // operands into the appropriate MCInst.\n"; OS << " convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n"; @@ -2931,7 +2925,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { if (!InsnCleanupFn.empty()) OS << " " << InsnCleanupFn << "(Inst);\n"; - OS << " Kind = it->ConvertFn;\n"; OS << " return Match_Success;\n"; OS << " }\n\n";