[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
This commit is contained in:
Chad Rosier 2012-10-01 23:45:51 +00:00
parent 3fc42fd77c
commit 22685876ed
6 changed files with 91 additions and 87 deletions

View File

@ -89,11 +89,11 @@ public:
/// On failure, the target parser is responsible for emitting a diagnostic /// On failure, the target parser is responsible for emitting a diagnostic
/// explaining the match failure. /// explaining the match failure.
virtual bool virtual bool
MatchInstruction(SMLoc IDLoc, unsigned &Kind, MatchInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands, SmallVectorImpl<MCParsedAsmOperand*> &Operands,
SmallVectorImpl<MCInst> &MCInsts, MCStreamer &Out, unsigned &Kind, unsigned &Opcode,
unsigned &OrigErrorInfo, SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints,
bool matchingInlineAsm = false) { unsigned &OrigErrorInfo, bool matchingInlineAsm = false) {
OrigErrorInfo = ~0x0; OrigErrorInfo = ~0x0;
return true; return true;
} }
@ -115,10 +115,9 @@ public:
return Match_Success; return Match_Success;
} }
virtual unsigned getMCInstOperandNum(unsigned Kind, virtual void convertToMapAndConstraints(unsigned Kind,
const SmallVectorImpl<MCParsedAsmOperand*> &Operands, const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
unsigned OperandNum, SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints) = 0;
unsigned &NumMCOperands) = 0;
}; };
} // End llvm namespace } // End llvm namespace

View File

@ -7480,8 +7480,10 @@ MatchAndEmitInstruction(SMLoc IDLoc,
unsigned Kind; unsigned Kind;
unsigned ErrorInfo; unsigned ErrorInfo;
unsigned MatchResult; unsigned MatchResult;
SmallVector<std::pair< unsigned, std::string >, 4> MapAndConstraints;
MatchResult = MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo); MatchResult = MatchInstructionImpl(Operands, Kind, Inst,
MapAndConstraints, ErrorInfo,
/*matchingInlineAsm*/ false);
switch (MatchResult) { switch (MatchResult) {
default: break; default: break;
case Match_Success: case Match_Success:

View File

@ -318,8 +318,9 @@ MatchAndEmitInstruction(SMLoc IDLoc,
MCInst Inst; MCInst Inst;
unsigned Kind; unsigned Kind;
unsigned ErrorInfo; unsigned ErrorInfo;
SmallVector<std::pair< unsigned, std::string >, 4> MapAndConstraints;
switch (MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo)) { switch (MatchInstructionImpl(Operands, Kind, Inst, MapAndConstraints,
ErrorInfo, /*matchingInlineAsm*/ false)) {
default: break; default: break;
case Match_Success: case Match_Success:
Out.EmitInstruction(Inst); Out.EmitInstruction(Inst);

View File

@ -261,9 +261,12 @@ MatchAndEmitInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands, SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCStreamer &Out) { MCStreamer &Out) {
MCInst Inst; MCInst Inst;
unsigned ErrorInfo;
unsigned Kind; unsigned Kind;
unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo); unsigned ErrorInfo;
SmallVector<std::pair< unsigned, std::string >, 4> MapAndConstraints;
unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst,
MapAndConstraints, ErrorInfo,
/*matchingInlineAsm*/ false);
switch (MatchResult) { switch (MatchResult) {
default: break; default: break;

View File

@ -66,12 +66,11 @@ private:
bool MatchAndEmitInstruction(SMLoc IDLoc, bool MatchAndEmitInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands, SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCStreamer &Out); MCStreamer &Out);
bool MatchInstruction(SMLoc IDLoc,
bool MatchInstruction(SMLoc IDLoc, unsigned &Kind,
SmallVectorImpl<MCParsedAsmOperand*> &Operands, SmallVectorImpl<MCParsedAsmOperand*> &Operands,
SmallVectorImpl<MCInst> &MCInsts, MCStreamer &Out, unsigned &Kind, unsigned &Opcode,
unsigned &OrigErrorInfo, SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints,
bool matchingInlineAsm = false); unsigned &OrigErrorInfo, bool matchingInlineAsm = false);
/// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi) /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi)
/// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode. /// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode.
@ -1521,22 +1520,20 @@ MatchAndEmitInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands, SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCStreamer &Out) { MCStreamer &Out) {
unsigned Kind; unsigned Kind;
unsigned Opcode;
unsigned ErrorInfo; unsigned ErrorInfo;
SmallVector<MCInst, 2> Insts; SmallVector<std::pair< unsigned, std::string >, 4> MapAndConstraints;
bool Error = MatchInstruction(IDLoc, Operands, Out, Kind, Opcode,
bool Error = MatchInstruction(IDLoc, Kind, Operands, Insts, MapAndConstraints, ErrorInfo);
ErrorInfo);
if (!Error)
for (unsigned i = 0, e = Insts.size(); i != e; ++i)
Out.EmitInstruction(Insts[i]);
return Error; return Error;
} }
bool X86AsmParser:: bool X86AsmParser::
MatchInstruction(SMLoc IDLoc, unsigned &Kind, MatchInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands, SmallVectorImpl<MCParsedAsmOperand*> &Operands,
SmallVectorImpl<MCInst> &MCInsts, unsigned &OrigErrorInfo, MCStreamer &Out, unsigned &Kind, unsigned &Opcode,
bool matchingInlineAsm) { SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints,
unsigned &OrigErrorInfo, bool matchingInlineAsm) {
assert(!Operands.empty() && "Unexpect empty operand list!"); assert(!Operands.empty() && "Unexpect empty operand list!");
X86Operand *Op = static_cast<X86Operand*>(Operands[0]); X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
assert(Op->isToken() && "Leading operand should always be a mnemonic!"); assert(Op->isToken() && "Leading operand should always be a mnemonic!");
@ -1553,7 +1550,8 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind,
MCInst Inst; MCInst Inst;
Inst.setOpcode(X86::WAIT); Inst.setOpcode(X86::WAIT);
Inst.setLoc(IDLoc); Inst.setLoc(IDLoc);
MCInsts.push_back(Inst); if (!matchingInlineAsm)
Out.EmitInstruction(Inst);
const char *Repl = const char *Repl =
StringSwitch<const char*>(Op->getToken()) StringSwitch<const char*>(Op->getToken())
@ -1575,18 +1573,22 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind,
MCInst Inst; MCInst Inst;
// First, try a direct match. // First, try a direct match.
switch (MatchInstructionImpl(Operands, Kind, Inst, OrigErrorInfo, switch (MatchInstructionImpl(Operands, Kind, Inst, MapAndConstraints,
OrigErrorInfo, matchingInlineAsm,
isParsingIntelSyntax())) { isParsingIntelSyntax())) {
default: break; default: break;
case Match_Success: case Match_Success:
// Some instructions need post-processing to, for example, tweak which // Some instructions need post-processing to, for example, tweak which
// encoding is selected. Loop on it while changes happen so the // encoding is selected. Loop on it while changes happen so the
// individual transformations can chain off each other. // individual transformations can chain off each other.
if (!matchingInlineAsm)
while (processInstruction(Inst, Operands)) while (processInstruction(Inst, Operands))
; ;
Inst.setLoc(IDLoc); Inst.setLoc(IDLoc);
MCInsts.push_back(Inst); if (!matchingInlineAsm)
Out.EmitInstruction(Inst);
Opcode = Inst.getOpcode();
return false; return false;
case Match_MissingFeature: case Match_MissingFeature:
Error(IDLoc, "instruction requires a CPU feature not currently enabled", 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 Match1, Match2, Match3, Match4;
unsigned tKind; unsigned tKind;
Match1 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore, SmallVector<std::pair< unsigned, std::string >, 4> tMapAndConstraints[4];
isParsingIntelSyntax()); Match1 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[0],
ErrorInfoIgnore, isParsingIntelSyntax());
if (Match1 == Match_Success) Kind = tKind; if (Match1 == Match_Success) Kind = tKind;
Tmp[Base.size()] = Suffixes[1]; Tmp[Base.size()] = Suffixes[1];
Match2 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore, Match2 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[1],
isParsingIntelSyntax()); ErrorInfoIgnore, isParsingIntelSyntax());
if (Match2 == Match_Success) Kind = tKind; if (Match2 == Match_Success) Kind = tKind;
Tmp[Base.size()] = Suffixes[2]; Tmp[Base.size()] = Suffixes[2];
Match3 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore, Match3 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[2],
isParsingIntelSyntax()); ErrorInfoIgnore, isParsingIntelSyntax());
if (Match3 == Match_Success) Kind = tKind; if (Match3 == Match_Success) Kind = tKind;
Tmp[Base.size()] = Suffixes[3]; Tmp[Base.size()] = Suffixes[3];
Match4 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore, Match4 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[3],
isParsingIntelSyntax()); ErrorInfoIgnore, isParsingIntelSyntax());
if (Match4 == Match_Success) Kind = tKind; if (Match4 == Match_Success) Kind = tKind;
// Restore the old token. // Restore the old token.
@ -1652,7 +1655,10 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind,
(Match3 == Match_Success) + (Match4 == Match_Success); (Match3 == Match_Success) + (Match4 == Match_Success);
if (NumSuccessfulMatches == 1) { if (NumSuccessfulMatches == 1) {
Inst.setLoc(IDLoc); Inst.setLoc(IDLoc);
MCInsts.push_back(Inst); if (!matchingInlineAsm)
Out.EmitInstruction(Inst);
Opcode = Inst.getOpcode();
// FIXME: Handle the map and constraints.
return false; return false;
} }

View File

@ -1674,7 +1674,7 @@ static unsigned getConverterOperandID(const std::string &Name,
} }
static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
std::vector<MatchableInfo*> &Infos, std::vector<MatchableInfo*> &Infos,
raw_ostream &OS) { raw_ostream &OS) {
SetVector<std::string> OperandConversionKinds; SetVector<std::string> OperandConversionKinds;
@ -1713,29 +1713,22 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
std::string OperandFnBody; std::string OperandFnBody;
raw_string_ostream OpOS(OperandFnBody); raw_string_ostream OpOS(OperandFnBody);
// Start the operand number lookup function. // Start the operand number lookup function.
OpOS << "unsigned " << Target.getName() << ClassName << "::\n" OpOS << "void " << Target.getName() << ClassName << "::\n"
<< "getMCInstOperandNum(unsigned Kind,\n" << "convertToMapAndConstraints(unsigned Kind,\n";
<< " const SmallVectorImpl<MCParsedAsmOperand*> " OpOS.indent(20);
<< "&Operands,\n unsigned OperandNum, unsigned " OpOS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
<< "&NumMCOperands) {\n" << "SmallVectorImpl<std::pair< unsigned, std::string > >"
<< " &MapAndConstraints) {\n"
<< " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n" << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
<< " NumMCOperands = 0;\n" << " unsigned NumMCOperands = 0;\n"
<< " unsigned MCOperandNum = 0;\n"
<< " const uint8_t *Converter = ConversionTable[Kind];\n" << " const uint8_t *Converter = ConversionTable[Kind];\n"
<< " for (const uint8_t *p = Converter; *p; p+= 2) {\n" << " for (const uint8_t *p = Converter; *p; p+= 2) {\n"
<< " if (*(p + 1) > OperandNum) continue;\n"
<< " switch (*p) {\n" << " switch (*p) {\n"
<< " default: llvm_unreachable(\"invalid conversion entry!\");\n" << " default: llvm_unreachable(\"invalid conversion entry!\");\n"
<< " case CVT_Reg:\n" << " case CVT_Reg:\n"
<< " if (*(p + 1) == OperandNum) {\n"
<< " NumMCOperands = 1;\n"
<< " break;\n"
<< " }\n"
<< " ++MCOperandNum;\n"
<< " break;\n"
<< " case CVT_Tied:\n" << " case CVT_Tied:\n"
<< " // FIXME: Tied operand calculation not supported.\n" << " MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"r\"));\n"
<< " assert (0 && \"getMCInstOperandNumImpl() doesn't support tied operands, yet!\");\n" << " ++NumMCOperands;\n"
<< " break;\n"; << " break;\n";
// Pre-populate the operand conversion kinds with the standard always // 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. // Add a handler for the operand number lookup.
OpOS << " case " << Name << ":\n" OpOS << " case " << Name << ":\n"
<< " if (*(p + 1) == OperandNum) {\n" << " MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"r\"));\n"
<< " NumMCOperands = " << OpInfo.MINumOperands << ";\n" << " NumMCOperands += " << OpInfo.MINumOperands << ";\n"
<< " break;\n"
<< " }\n"
<< " MCOperandNum += " << OpInfo.MINumOperands << ";\n"
<< " break;\n"; << " break;\n";
break; break;
} }
@ -1872,11 +1862,8 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
<< " break;\n"; << " break;\n";
OpOS << " case " << Name << ":\n" OpOS << " case " << Name << ":\n"
<< " if (*(p + 1) == OperandNum) {\n" << " MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"\"));\n"
<< " NumMCOperands = 1;\n" << " ++NumMCOperands;\n"
<< " break;\n"
<< " }\n"
<< " ++MCOperandNum;\n"
<< " break;\n"; << " break;\n";
break; break;
} }
@ -1905,11 +1892,8 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
<< " break;\n"; << " break;\n";
OpOS << " case " << Name << ":\n" OpOS << " case " << Name << ":\n"
<< " if (*(p + 1) == OperandNum) {\n" << " MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"r\"));\n"
<< " NumMCOperands = 1;\n" << " ++NumMCOperands;\n"
<< " break;\n"
<< " }\n"
<< " ++MCOperandNum;\n"
<< " break;\n"; << " break;\n";
} }
} }
@ -1934,7 +1918,7 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
CvtOS << " }\n }\n}\n\n"; CvtOS << " }\n }\n}\n\n";
// Finish up the operand number lookup function. // Finish up the operand number lookup function.
OpOS << " }\n }\n return MCOperandNum;\n}\n\n"; OpOS << " }\n }\n}\n\n";
OS << "namespace {\n"; OS << "namespace {\n";
@ -2617,15 +2601,16 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
<< "unsigned Opcode,\n" << "unsigned Opcode,\n"
<< " const SmallVectorImpl<MCParsedAsmOperand*> " << " const SmallVectorImpl<MCParsedAsmOperand*> "
<< "&Operands);\n"; << "&Operands);\n";
OS << " unsigned getMCInstOperandNum(unsigned Kind,\n" OS << " void convertToMapAndConstraints(unsigned Kind,\n";
<< " const " OS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
<< "SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n " << "SmallVectorImpl<std::pair< unsigned, std::string > >"
<< " unsigned OperandNum, unsigned &NumMCOperands);\n"; << " &MapAndConstraints);\n";
OS << " bool mnemonicIsValid(StringRef Mnemonic);\n"; OS << " bool mnemonicIsValid(StringRef Mnemonic);\n";
OS << " unsigned MatchInstructionImpl(\n" OS << " unsigned MatchInstructionImpl(\n"
<< " const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n" << " const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
<< " unsigned &Kind, MCInst &Inst, " << " unsigned &Kind, MCInst &Inst, "
<< "unsigned &ErrorInfo,\n unsigned VariantID = 0);\n"; << "SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints,\n"
<< "unsigned &ErrorInfo,\n bool matchingInlineAsm, unsigned VariantID = 0);\n";
if (Info.OperandMatchInfo.size()) { if (Info.OperandMatchInfo.size()) {
OS << "\n enum OperandMatchResultTy {\n"; OS << "\n enum OperandMatchResultTy {\n";
@ -2678,8 +2663,10 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
// Generate the function that remaps for mnemonic aliases. // Generate the function that remaps for mnemonic aliases.
bool HasMnemonicAliases = emitMnemonicAliases(OS, Info); bool HasMnemonicAliases = emitMnemonicAliases(OS, Info);
// Generate the unified function to convert operands into an MCInst. // Generate the convertToMCInst function to convert operands into an MCInst.
emitConvertToMCInst(Target, ClassName, Info.Matchables, OS); // 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. // Emit the enumeration for classes which participate in matching.
emitMatchClassEnumeration(Target, Info.Classes, OS); emitMatchClassEnumeration(Target, Info.Classes, OS);
@ -2813,8 +2800,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
<< Target.getName() << ClassName << "::\n" << Target.getName() << ClassName << "::\n"
<< "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>" << "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
<< " &Operands,\n"; << " &Operands,\n";
OS << " unsigned &Kind, MCInst &Inst, unsigned "; OS << " unsigned &Kind, MCInst &Inst,\n"
OS << "&ErrorInfo,\n unsigned VariantID) {\n"; << "SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints,\n"
<< "unsigned &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n";
OS << " // Eliminate obvious mismatches.\n"; OS << " // Eliminate obvious mismatches.\n";
OS << " if (Operands.size() > " << (MaxNumOperands+1) << ") {\n"; OS << " if (Operands.size() > " << (MaxNumOperands+1) << ") {\n";
@ -2908,6 +2896,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " continue;\n"; OS << " continue;\n";
OS << " }\n"; OS << " }\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" OS << " // We have selected a definite instruction, convert the parsed\n"
<< " // operands into the appropriate MCInst.\n"; << " // operands into the appropriate MCInst.\n";
OS << " convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n"; OS << " convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
@ -2931,7 +2925,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
if (!InsnCleanupFn.empty()) if (!InsnCleanupFn.empty())
OS << " " << InsnCleanupFn << "(Inst);\n"; OS << " " << InsnCleanupFn << "(Inst);\n";
OS << " Kind = it->ConvertFn;\n";
OS << " return Match_Success;\n"; OS << " return Match_Success;\n";
OS << " }\n\n"; OS << " }\n\n";