llvm.org GIT mirror llvm / 2268587
[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 Chad Rosier 7 years ago
6 changed file(s) with 91 addition(s) and 87 deletion(s). Raw diff Collapse all Expand all
8888 /// On failure, the target parser is responsible for emitting a diagnostic
8989 /// explaining the match failure.
9090 virtual bool
91 MatchInstruction(SMLoc IDLoc, unsigned &Kind,
91 MatchInstruction(SMLoc IDLoc,
9292 SmallVectorImpl &Operands,
93 SmallVectorImpl &MCInsts,
94 unsigned &OrigErrorInfo,
95 bool matchingInlineAsm = false) {
93 MCStreamer &Out, unsigned &Kind, unsigned &Opcode,
94 SmallVectorImpl > &MapAndConstraints,
95 unsigned &OrigErrorInfo, bool matchingInlineAsm = false) {
9696 OrigErrorInfo = ~0x0;
9797 return true;
9898 }
114114 return Match_Success;
115115 }
116116
117 virtual unsigned getMCInstOperandNum(unsigned Kind,
117 virtual void convertToMapAndConstraints(unsigned Kind,
118118 const SmallVectorImpl &Operands,
119 unsigned OperandNum,
120 unsigned &NumMCOperands) = 0;
119 SmallVectorImpl > &MapAndConstraints) = 0;
121120 };
122121
123122 } // End llvm namespace
74797479 unsigned Kind;
74807480 unsigned ErrorInfo;
74817481 unsigned MatchResult;
7482
7483 MatchResult = MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo);
7482 SmallVector, 4> MapAndConstraints;
7483 MatchResult = MatchInstructionImpl(Operands, Kind, Inst,
7484 MapAndConstraints, ErrorInfo,
7485 /*matchingInlineAsm*/ false);
74847486 switch (MatchResult) {
74857487 default: break;
74867488 case Match_Success:
317317 MCInst Inst;
318318 unsigned Kind;
319319 unsigned ErrorInfo;
320
321 switch (MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo)) {
320 SmallVector, 4> MapAndConstraints;
321 switch (MatchInstructionImpl(Operands, Kind, Inst, MapAndConstraints,
322 ErrorInfo, /*matchingInlineAsm*/ false)) {
322323 default: break;
323324 case Match_Success:
324325 Out.EmitInstruction(Inst);
260260 SmallVectorImpl &Operands,
261261 MCStreamer &Out) {
262262 MCInst Inst;
263 unsigned Kind;
263264 unsigned ErrorInfo;
264 unsigned Kind;
265 unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo);
265 SmallVector, 4> MapAndConstraints;
266 unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst,
267 MapAndConstraints, ErrorInfo,
268 /*matchingInlineAsm*/ false);
266269
267270 switch (MatchResult) {
268271 default: break;
6565 bool MatchAndEmitInstruction(SMLoc IDLoc,
6666 SmallVectorImpl &Operands,
6767 MCStreamer &Out);
68
69 bool MatchInstruction(SMLoc IDLoc, unsigned &Kind,
68 bool MatchInstruction(SMLoc IDLoc,
7069 SmallVectorImpl &Operands,
71 SmallVectorImpl &MCInsts,
72 unsigned &OrigErrorInfo,
73 bool matchingInlineAsm = false);
70 MCStreamer &Out, unsigned &Kind, unsigned &Opcode,
71 SmallVectorImpl > &MapAndConstraints,
72 unsigned &OrigErrorInfo, bool matchingInlineAsm = false);
7473
7574 /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi)
7675 /// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode.
15201519 SmallVectorImpl &Operands,
15211520 MCStreamer &Out) {
15221521 unsigned Kind;
1522 unsigned Opcode;
15231523 unsigned ErrorInfo;
1524 SmallVector Insts;
1525
1526 bool Error = MatchInstruction(IDLoc, Kind, Operands, Insts,
1527 ErrorInfo);
1528 if (!Error)
1529 for (unsigned i = 0, e = Insts.size(); i != e; ++i)
1530 Out.EmitInstruction(Insts[i]);
1524 SmallVector, 4> MapAndConstraints;
1525 bool Error = MatchInstruction(IDLoc, Operands, Out, Kind, Opcode,
1526 MapAndConstraints, ErrorInfo);
15311527 return Error;
15321528 }
15331529
15341530 bool X86AsmParser::
1535 MatchInstruction(SMLoc IDLoc, unsigned &Kind,
1531 MatchInstruction(SMLoc IDLoc,
15361532 SmallVectorImpl &Operands,
1537 SmallVectorImpl &MCInsts, unsigned &OrigErrorInfo,
1538 bool matchingInlineAsm) {
1533 MCStreamer &Out, unsigned &Kind, unsigned &Opcode,
1534 SmallVectorImpl > &MapAndConstraints,
1535 unsigned &OrigErrorInfo, bool matchingInlineAsm) {
15391536 assert(!Operands.empty() && "Unexpect empty operand list!");
15401537 X86Operand *Op = static_cast(Operands[0]);
15411538 assert(Op->isToken() && "Leading operand should always be a mnemonic!");
15521549 MCInst Inst;
15531550 Inst.setOpcode(X86::WAIT);
15541551 Inst.setLoc(IDLoc);
1555 MCInsts.push_back(Inst);
1552 if (!matchingInlineAsm)
1553 Out.EmitInstruction(Inst);
15561554
15571555 const char *Repl =
15581556 StringSwitch(Op->getToken())
15741572 MCInst Inst;
15751573
15761574 // First, try a direct match.
1577 switch (MatchInstructionImpl(Operands, Kind, Inst, OrigErrorInfo,
1575 switch (MatchInstructionImpl(Operands, Kind, Inst, MapAndConstraints,
1576 OrigErrorInfo, matchingInlineAsm,
15781577 isParsingIntelSyntax())) {
15791578 default: break;
15801579 case Match_Success:
15811580 // Some instructions need post-processing to, for example, tweak which
15821581 // encoding is selected. Loop on it while changes happen so the
15831582 // individual transformations can chain off each other.
1584 while (processInstruction(Inst, Operands))
1585 ;
1583 if (!matchingInlineAsm)
1584 while (processInstruction(Inst, Operands))
1585 ;
15861586
15871587 Inst.setLoc(IDLoc);
1588 MCInsts.push_back(Inst);
1588 if (!matchingInlineAsm)
1589 Out.EmitInstruction(Inst);
1590 Opcode = Inst.getOpcode();
15891591 return false;
15901592 case Match_MissingFeature:
15911593 Error(IDLoc, "instruction requires a CPU feature not currently enabled",
16241626 unsigned Match1, Match2, Match3, Match4;
16251627 unsigned tKind;
16261628
1627 Match1 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore,
1628 isParsingIntelSyntax());
1629 SmallVector, 4> tMapAndConstraints[4];
1630 Match1 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[0],
1631 ErrorInfoIgnore, isParsingIntelSyntax());
16291632 if (Match1 == Match_Success) Kind = tKind;
16301633 Tmp[Base.size()] = Suffixes[1];
1631 Match2 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore,
1632 isParsingIntelSyntax());
1634 Match2 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[1],
1635 ErrorInfoIgnore, isParsingIntelSyntax());
16331636 if (Match2 == Match_Success) Kind = tKind;
16341637 Tmp[Base.size()] = Suffixes[2];
1635 Match3 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore,
1636 isParsingIntelSyntax());
1638 Match3 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[2],
1639 ErrorInfoIgnore, isParsingIntelSyntax());
16371640 if (Match3 == Match_Success) Kind = tKind;
16381641 Tmp[Base.size()] = Suffixes[3];
1639 Match4 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore,
1640 isParsingIntelSyntax());
1642 Match4 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[3],
1643 ErrorInfoIgnore, isParsingIntelSyntax());
16411644 if (Match4 == Match_Success) Kind = tKind;
16421645
16431646 // Restore the old token.
16511654 (Match3 == Match_Success) + (Match4 == Match_Success);
16521655 if (NumSuccessfulMatches == 1) {
16531656 Inst.setLoc(IDLoc);
1654 MCInsts.push_back(Inst);
1657 if (!matchingInlineAsm)
1658 Out.EmitInstruction(Inst);
1659 Opcode = Inst.getOpcode();
1660 // FIXME: Handle the map and constraints.
16551661 return false;
16561662 }
16571663
16731673 }
16741674
16751675
1676 static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
1677 std::vector &Infos,
1678 raw_ostream &OS) {
1676 static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
1677 std::vector &Infos,
1678 raw_ostream &OS) {
16791679 SetVector OperandConversionKinds;
16801680 SetVector InstructionConversionKinds;
16811681 std::vector > ConversionTable;
17121712 std::string OperandFnBody;
17131713 raw_string_ostream OpOS(OperandFnBody);
17141714 // Start the operand number lookup function.
1715 OpOS << "unsigned " << Target.getName() << ClassName << "::\n"
1716 << "getMCInstOperandNum(unsigned Kind,\n"
1717 << " const SmallVectorImpl "
1718 << "&Operands,\n unsigned OperandNum, unsigned "
1719 << "&NumMCOperands) {\n"
1715 OpOS << "void " << Target.getName() << ClassName << "::\n"
1716 << "convertToMapAndConstraints(unsigned Kind,\n";
1717 OpOS.indent(20);
1718 OpOS << "const SmallVectorImpl &Operands,\n"
1719 << "SmallVectorImpl >"
1720 << " &MapAndConstraints) {\n"
17201721 << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
1721 << " NumMCOperands = 0;\n"
1722 << " unsigned MCOperandNum = 0;\n"
1722 << " unsigned NumMCOperands = 0;\n"
17231723 << " const uint8_t *Converter = ConversionTable[Kind];\n"
17241724 << " for (const uint8_t *p = Converter; *p; p+= 2) {\n"
1725 << " if (*(p + 1) > OperandNum) continue;\n"
17261725 << " switch (*p) {\n"
17271726 << " default: llvm_unreachable(\"invalid conversion entry!\");\n"
17281727 << " case CVT_Reg:\n"
1729 << " if (*(p + 1) == OperandNum) {\n"
1730 << " NumMCOperands = 1;\n"
1731 << " break;\n"
1732 << " }\n"
1733 << " ++MCOperandNum;\n"
1734 << " break;\n"
17351728 << " case CVT_Tied:\n"
1736 << " // FIXME: Tied operand calculation not supported.\n"
1737 << " assert (0 && \"getMCInstOperandNumImpl() doesn't support tied operands, yet!\");\n"
1729 << " MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"r\"));\n"
1730 << " ++NumMCOperands;\n"
17381731 << " break;\n";
17391732
17401733 // Pre-populate the operand conversion kinds with the standard always
18301823
18311824 // Add a handler for the operand number lookup.
18321825 OpOS << " case " << Name << ":\n"
1833 << " if (*(p + 1) == OperandNum) {\n"
1834 << " NumMCOperands = " << OpInfo.MINumOperands << ";\n"
1835 << " break;\n"
1836 << " }\n"
1837 << " MCOperandNum += " << OpInfo.MINumOperands << ";\n"
1826 << " MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"r\"));\n"
1827 << " NumMCOperands += " << OpInfo.MINumOperands << ";\n"
18381828 << " break;\n";
18391829 break;
18401830 }
18711861 << " break;\n";
18721862
18731863 OpOS << " case " << Name << ":\n"
1874 << " if (*(p + 1) == OperandNum) {\n"
1875 << " NumMCOperands = 1;\n"
1876 << " break;\n"
1877 << " }\n"
1878 << " ++MCOperandNum;\n"
1864 << " MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"\"));\n"
1865 << " ++NumMCOperands;\n"
18791866 << " break;\n";
18801867 break;
18811868 }
19041891 << " break;\n";
19051892
19061893 OpOS << " case " << Name << ":\n"
1907 << " if (*(p + 1) == OperandNum) {\n"
1908 << " NumMCOperands = 1;\n"
1909 << " break;\n"
1910 << " }\n"
1911 << " ++MCOperandNum;\n"
1894 << " MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"r\"));\n"
1895 << " ++NumMCOperands;\n"
19121896 << " break;\n";
19131897 }
19141898 }
19331917 CvtOS << " }\n }\n}\n\n";
19341918
19351919 // Finish up the operand number lookup function.
1936 OpOS << " }\n }\n return MCOperandNum;\n}\n\n";
1920 OpOS << " }\n }\n}\n\n";
19371921
19381922 OS << "namespace {\n";
19391923
26162600 << "unsigned Opcode,\n"
26172601 << " const SmallVectorImpl "
26182602 << "&Operands);\n";
2619 OS << " unsigned getMCInstOperandNum(unsigned Kind,\n"
2620 << " const "
2621 << "SmallVectorImpl &Operands,\n "
2622 << " unsigned OperandNum, unsigned &NumMCOperands);\n";
2603 OS << " void convertToMapAndConstraints(unsigned Kind,\n";
2604 OS << "const SmallVectorImpl &Operands,\n"
2605 << "SmallVectorImpl >"
2606 << " &MapAndConstraints);\n";
26232607 OS << " bool mnemonicIsValid(StringRef Mnemonic);\n";
26242608 OS << " unsigned MatchInstructionImpl(\n"
26252609 << " const SmallVectorImpl &Operands,\n"
26262610 << " unsigned &Kind, MCInst &Inst, "
2627 << "unsigned &ErrorInfo,\n unsigned VariantID = 0);\n";
2611 << "SmallVectorImpl > &MapAndConstraints,\n"
2612 << "unsigned &ErrorInfo,\n bool matchingInlineAsm, unsigned VariantID = 0);\n";
26282613
26292614 if (Info.OperandMatchInfo.size()) {
26302615 OS << "\n enum OperandMatchResultTy {\n";
26772662 // Generate the function that remaps for mnemonic aliases.
26782663 bool HasMnemonicAliases = emitMnemonicAliases(OS, Info);
26792664
2680 // Generate the unified function to convert operands into an MCInst.
2681 emitConvertToMCInst(Target, ClassName, Info.Matchables, OS);
2665 // Generate the convertToMCInst function to convert operands into an MCInst.
2666 // Also, generate the convertToMapAndConstraints function for MS-style inline
2667 // assembly. The latter doesn't actually generate a MCInst.
2668 emitConvertFuncs(Target, ClassName, Info.Matchables, OS);
26822669
26832670 // Emit the enumeration for classes which participate in matching.
26842671 emitMatchClassEnumeration(Target, Info.Classes, OS);
28122799 << Target.getName() << ClassName << "::\n"
28132800 << "MatchInstructionImpl(const SmallVectorImpl"
28142801 << " &Operands,\n";
2815 OS << " unsigned &Kind, MCInst &Inst, unsigned ";
2816 OS << "&ErrorInfo,\n unsigned VariantID) {\n";
2802 OS << " unsigned &Kind, MCInst &Inst,\n"
2803 << "SmallVectorImpl > &MapAndConstraints,\n"
2804 << "unsigned &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n";
28172805
28182806 OS << " // Eliminate obvious mismatches.\n";
28192807 OS << " if (Operands.size() > " << (MaxNumOperands+1) << ") {\n";
29072895 OS << " continue;\n";
29082896 OS << " }\n";
29092897 OS << "\n";
2898 OS << " if (matchingInlineAsm) {\n";
2899 OS << " Kind = it->ConvertFn;\n";
2900 OS << " Inst.setOpcode(it->Opcode);\n";
2901 OS << " convertToMapAndConstraints(it->ConvertFn, Operands, MapAndConstraints);\n";
2902 OS << " return Match_Success;\n";
2903 OS << " }\n\n";
29102904 OS << " // We have selected a definite instruction, convert the parsed\n"
29112905 << " // operands into the appropriate MCInst.\n";
29122906 OS << " convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
29302924 if (!InsnCleanupFn.empty())
29312925 OS << " " << InsnCleanupFn << "(Inst);\n";
29322926
2933 OS << " Kind = it->ConvertFn;\n";
29342927 OS << " return Match_Success;\n";
29352928 OS << " }\n\n";
29362929