llvm.org GIT mirror llvm / 9898671
Split the TargetAsmParser "ParseInstruction" interface in half: the new ParseInstruction method just parses and returns a list of target operands. A new MatchInstruction interface is used to turn the operand list into an MCInst. This requires new/deleting all the operands, but it also gives targets the ability to use polymorphic operands if they want to. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93469 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 10 years ago
6 changed file(s) with 86 addition(s) and 61 deletion(s). Raw diff Collapse all Expand all
1616 class Target;
1717 class SMLoc;
1818 class AsmToken;
19 class MCParsedAsmOperand;
20 template class SmallVectorImpl;
1921
2022 /// TargetAsmParser - Generic interface to target specific assembly parsers.
2123 class TargetAsmParser {
4244 //
4345 /// \param AP - The current parser object.
4446 /// \param Name - The instruction name.
45 /// \param Inst [out] - On success, the parsed instruction.
47 /// \param Operands [out] - The list of parsed operands, this returns
48 /// ownership of them to the caller.
4649 /// \return True on failure.
4750 virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
48 MCInst &Inst) = 0;
51 SmallVectorImpl &Operands) = 0;
4952
5053 /// ParseDirective - Parse a target specific assembler directive
5154 ///
5861 ///
5962 /// \param ID - the identifier token of the directive.
6063 virtual bool ParseDirective(AsmToken DirectiveID) = 0;
64
65 /// MatchInstruction - Recognize a series of operands of a parsed instruction
66 /// as an actual MCInst. This returns false and fills in Inst on success and
67 /// returns true on failure to match.
68 virtual bool
69 MatchInstruction(const SmallVectorImpl &Operands,
70 MCInst &Inst) = 0;
71
6172 };
6273
6374 } // End llvm namespace
7878
7979 /// @name Auto-generated Match Functions
8080 /// {
81 bool MatchInstruction(SmallVectorImpl> &Operands,
81 bool MatchInstruction(const SmallVectorImpl> &Operands,
8282 MCInst &Inst);
8383
8484 /// MatchRegisterName - Match the given string to a register name and return
9595 : TargetAsmParser(T), Parser(_Parser) {}
9696
9797 virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
98 MCInst &Inst);
98 SmallVectorImpl &Operands);
9999
100100 virtual bool ParseDirective(AsmToken DirectiveID);
101101 };
516516 }
517517
518518 /// A hack to allow some testing, to be replaced by a real table gen version.
519 bool ARMAsmParser::MatchInstruction(SmallVectorImpl &Operands,
520 MCInst &Inst) {
521 struct ARMOperand Op0 = Operands[0];
519 bool ARMAsmParser::
520 MatchInstruction(const SmallVectorImpl &Operands,
521 MCInst &Inst) {
522 ARMOperand &Op0 = *(ARMOperand*)Operands[0];
522523 assert(Op0.Kind == ARMOperand::Token && "First operand not a Token");
523524 const StringRef &Mnemonic = Op0.getToken();
524525 if (Mnemonic == "add" ||
580581
581582 /// Parse an arm instruction mnemonic followed by its operands.
582583 bool ARMAsmParser::ParseInstruction(const StringRef &Name, SMLoc NameLoc,
583 MCInst &Inst) {
584 SmallVector Operands;
585
586 Operands.push_back(ARMOperand::CreateToken(Name));
584 SmallVectorImpl &Operands) {
585 Operands.push_back(new ARMOperand(ARMOperand::CreateToken(Name)));
587586
588587 SMLoc Loc = getLexer().getTok().getLoc();
589588 if (getLexer().isNot(AsmToken::EndOfStatement)) {
590589
591590 // Read the first operand.
592 Operands.push_back(ARMOperand());
593 if (ParseOperand(Operands.back()))
594 return true;
591 ARMOperand Op;
592 if (ParseOperand(Op)) return true;
593 Operands.push_back(new ARMOperand(Op));
595594
596595 while (getLexer().is(AsmToken::Comma)) {
597596 getLexer().Lex(); // Eat the comma.
598597
599598 // Parse and remember the operand.
600 Operands.push_back(ARMOperand());
601 if (ParseOperand(Operands.back()))
602 return true;
599 if (ParseOperand(Op)) return true;
600 Operands.push_back(new ARMOperand(Op));
603601 }
604602 }
605 if (!MatchInstruction(Operands, Inst))
606 return false;
607
608 Error(Loc, "ARMAsmParser::ParseInstruction only partly implemented");
609 return true;
603 return false;
610604 }
611605
612606 /// ParseDirective parses the arm specific directives
66 //
77 //===----------------------------------------------------------------------===//
88
9 #include "llvm/Target/TargetAsmParser.h"
910 #include "X86.h"
1011 #include "llvm/ADT/SmallVector.h"
1112 #include "llvm/ADT/Twine.h"
4647 /// @name Auto-generated Match Functions
4748 /// {
4849
49 bool MatchInstruction(SmallVectorImpl> &Operands,
50 bool MatchInstruction(const SmallVectorImpl> &Operands,
5051 MCInst &Inst);
5152
5253 /// MatchRegisterName - Match the given string to a register name, or 0 if
6061 : TargetAsmParser(T), Parser(_Parser) {}
6162
6263 virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
63 MCInst &Inst);
64 SmallVectorImpl &Operands);
6465
6566 virtual bool ParseDirective(AsmToken DirectiveID);
6667 };
401402 return false;
402403 }
403404
404 bool X86ATTAsmParser::ParseInstruction(const StringRef &Name,
405 SMLoc NameLoc, MCInst &Inst) {
406 SmallVector Operands;
407
408 Operands.push_back(X86Operand::CreateToken(Name));
405 bool X86ATTAsmParser::
406 ParseInstruction(const StringRef &Name, SMLoc NameLoc,
407 SmallVectorImpl &Operands) {
408
409 Operands.push_back(new X86Operand(X86Operand::CreateToken(Name)));
409410
410411 SMLoc Loc = getLexer().getTok().getLoc();
411412 if (getLexer().isNot(AsmToken::EndOfStatement)) {
413414 // Parse '*' modifier.
414415 if (getLexer().is(AsmToken::Star)) {
415416 getLexer().Lex(); // Eat the star.
416 Operands.push_back(X86Operand::CreateToken("*"));
417 Operands.push_back(new X86Operand(X86Operand::CreateToken("*")));
417418 }
418419
419420 // Read the first operand.
420 Operands.push_back(X86Operand());
421 if (ParseOperand(Operands.back()))
421 X86Operand Op;
422 if (ParseOperand(Op))
422423 return true;
424
425 Operands.push_back(new X86Operand(Op));
423426
424427 while (getLexer().is(AsmToken::Comma)) {
425428 getLexer().Lex(); // Eat the comma.
426429
427430 // Parse and remember the operand.
428 Operands.push_back(X86Operand());
429 if (ParseOperand(Operands.back()))
431 if (ParseOperand(Op))
430432 return true;
431 }
432 }
433
434 if (!MatchInstruction(Operands, Inst))
435 return false;
436
437 // FIXME: We should give nicer diagnostics about the exact failure.
438
439 Error(Loc, "unrecognized instruction");
440 return true;
433 Operands.push_back(new X86Operand(Op));
434 }
435 }
436
437 return false;
441438 }
442439
443440 bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
4343 /// ReturnError - Set the error to the specified string at the specified
4444 /// location. This is defined to always return AsmToken::Error.
4545 AsmToken AsmLexer::ReturnError(const char *Loc, const std::string &Msg) {
46 SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), Msg, "error");
46 PrintMessage(SMLoc::getFromPointer(Loc), Msg, "error");
4747 return AsmToken(AsmToken::Error, StringRef(Loc, 0));
4848 }
4949
1717 #include "llvm/MC/MCContext.h"
1818 #include "llvm/MC/MCExpr.h"
1919 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCParsedAsmOperand.h"
2021 #include "llvm/MC/MCSectionMachO.h"
2122 #include "llvm/MC/MCStreamer.h"
2223 #include "llvm/MC/MCSymbol.h"
709710 return false;
710711 }
711712
713
714 SmallVector ParsedOperands;
715 if (getTargetParser().ParseInstruction(IDVal, IDLoc, ParsedOperands))
716 // FIXME: Leaking ParsedOperands on failure.
717 return true;
718
719 if (Lexer.isNot(AsmToken::EndOfStatement))
720 // FIXME: Leaking ParsedOperands on failure.
721 return TokError("unexpected token in argument list");
722
723 // Eat the end of statement marker.
724 Lexer.Lex();
725
726
712727 MCInst Inst;
713 if (getTargetParser().ParseInstruction(IDVal, IDLoc, Inst))
728
729 bool MatchFail = getTargetParser().MatchInstruction(ParsedOperands, Inst);
730
731 // Free any parsed operands.
732 for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
733 delete ParsedOperands[i];
734
735 if (MatchFail) {
736 // FIXME: We should give nicer diagnostics about the exact failure.
737 Error(IDLoc, "unrecognized instruction");
714738 return true;
715
716 if (Lexer.isNot(AsmToken::EndOfStatement))
717 return TokError("unexpected token in argument list");
718
719 // Eat the end of statement marker.
720 Lexer.Lex();
739 }
721740
722741 // Instruction is good, process it.
723742 Out.EmitInstruction(Inst);
960960
961961 CvtOS << "static bool ConvertToMCInst(ConversionKind Kind, MCInst &Inst, "
962962 << "unsigned Opcode,\n"
963 << " SmallVectorImpl<"
964 << Target.getName() << "Operand> &Operands) {\n";
963 << " const SmallVectorImpl
964 << "> &Operands) {\n";
965965 CvtOS << " Inst.setOpcode(Opcode);\n";
966966 CvtOS << " switch (Kind) {\n";
967967 CvtOS << " default:\n";
970970
971971 OS << "// Unified function for converting operants to MCInst instances.\n\n";
972972 OS << "enum ConversionKind {\n";
973
974 // TargetOperandClass - This is the target's operand class, like X86Operand.
975 std::string TargetOperandClass = Target.getName() + "Operand";
973976
974977 for (std::vector::const_iterator it = Infos.begin(),
975978 ie = Infos.end(); it != ie; ++it) {
10491052 for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex)
10501053 CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
10511054
1052 CvtOS << " Operands[" << MIOperandList[i].second
1053 << "]." << Op.Class->RenderMethod
1055 CvtOS << " ((" << TargetOperandClass << "*)Operands["
1056 << MIOperandList[i].second
1057 << "])->" << Op.Class->RenderMethod
10541058 << "(Inst, " << Op.OperandInfo->MINumOperands << ");\n";
10551059 CurIndex += Op.OperandInfo->MINumOperands;
10561060 }
11101114 static void EmitClassifyOperand(CodeGenTarget &Target,
11111115 AsmMatcherInfo &Info,
11121116 raw_ostream &OS) {
1113 OS << "static MatchClassKind ClassifyOperand("
1114 << Target.getName() << "Operand &Operand) {\n";
1117 OS << "static MatchClassKind ClassifyOperand(MCParsedAsmOperand *GOp) {\n"
1118 << " " << Target.getName() << "Operand &Operand = *("
1119 << Target.getName() << "Operand*)GOp;\n";
11151120
11161121 // Classify tokens.
11171122 OS << " if (Operand.isToken())\n";
14661471 MaxNumOperands = std::max(MaxNumOperands, (*it)->Operands.size());
14671472
14681473 OS << "bool " << Target.getName() << ClassName
1469 << "::MatchInstruction("
1470 << "SmallVectorImpl<" << Target.getName() << "Operand> &Operands, "
1471 << "MCInst &Inst) {\n";
1474 << "::\nMatchInstruction(const SmallVectorImpl "
1475 "&Operands,\n MCInst &Inst) {\n";
14721476
14731477 // Emit the static match table; unused classes get initalized to 0 which is
14741478 // guaranteed to be InvalidMatchClass.