From 22685876ed7231f32f7d1698c00acab22825b74c Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Mon, 1 Oct 2012 23:45:51 +0000 Subject: [PATCH] [ms-inline asm] Add the convertToMapAndConstraints() function that is used to map constraints and MCInst operands to inline asm operands. This replaces the getMCInstOperandNum() function. The logic to determine the constraints are not in place, so we still default to a register constraint (i.e., "r"). Also, we no longer build the MCInst but rather return just the opcode to get the MCInstrDesc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164979 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCTargetAsmParser.h | 13 ++- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 6 +- .../MBlaze/AsmParser/MBlazeAsmParser.cpp | 5 +- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 7 +- lib/Target/X86/AsmParser/X86AsmParser.cpp | 64 +++++++------- utils/TableGen/AsmMatcherEmitter.cpp | 83 +++++++++---------- 6 files changed, 91 insertions(+), 87 deletions(-) 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";