From 3246176838a47fa088b98772d4899063a9b7f731 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Thu, 9 Aug 2012 22:04:55 +0000 Subject: [ms-inline asm] Extend the MC AsmParser API to match MCInsts (but not emit). This new API will be used by clang to parse ms-style inline asms. One goal of this project is to use this style of inline asm for targets other then x86. Therefore, this API needs to be implemented for non-x86 targets at some point in the future. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161624 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/AsmParser/X86AsmParser.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'lib/Target/X86/AsmParser/X86AsmParser.cpp') diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 95e83ec..fbbaa95 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -65,6 +65,10 @@ private: SmallVectorImpl &Operands, MCStreamer &Out); + bool MatchInstruction(SMLoc IDLoc, + SmallVectorImpl &Operands, + SmallVectorImpl &MCInsts); + /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi) /// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode. bool isSrcOp(X86Operand &Op); @@ -1508,6 +1512,18 @@ bool X86AsmParser:: MatchAndEmitInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, MCStreamer &Out) { + SmallVector Insts; + bool Error = MatchInstruction(IDLoc, Operands, Insts); + if (!Error) + for (unsigned i = 0, e = Insts.size(); i != e; ++i) + Out.EmitInstruction(Insts[i]); + return Error; +} + +bool X86AsmParser:: +MatchInstruction(SMLoc IDLoc, + SmallVectorImpl &Operands, + SmallVectorImpl &MCInsts) { assert(!Operands.empty() && "Unexpect empty operand list!"); X86Operand *Op = static_cast(Operands[0]); assert(Op->isToken() && "Leading operand should always be a mnemonic!"); @@ -1523,7 +1539,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, MCInst Inst; Inst.setOpcode(X86::WAIT); Inst.setLoc(IDLoc); - Out.EmitInstruction(Inst); + MCInsts.push_back(Inst); const char *Repl = StringSwitch(Op->getToken()) @@ -1557,7 +1573,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, ; Inst.setLoc(IDLoc); - Out.EmitInstruction(Inst); + MCInsts.push_back(Inst); return false; case Match_MissingFeature: Error(IDLoc, "instruction requires a CPU feature not currently enabled"); @@ -1615,7 +1631,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, (Match3 == Match_Success) + (Match4 == Match_Success); if (NumSuccessfulMatches == 1) { Inst.setLoc(IDLoc); - Out.EmitInstruction(Inst); + MCInsts.push_back(Inst); return false; } -- cgit v1.1 From 64bfcbbc58ad485db157190496f0f39156b5a516 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Tue, 21 Aug 2012 18:14:59 +0000 Subject: [ms-inline asm] Expose the ErrorInfo from the MatchInstructionImpl. In general, this is the index of the operand that failed to match. Note: This may cause a buildbot failure due to an API mismatch in clang. Should recover with my next commit to clang. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162295 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/AsmParser/X86AsmParser.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'lib/Target/X86/AsmParser/X86AsmParser.cpp') diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index fbbaa95..c139dbc 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -67,7 +67,8 @@ private: bool MatchInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, - SmallVectorImpl &MCInsts); + SmallVectorImpl &MCInsts, + unsigned &OrigErrorInfo); /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi) /// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode. @@ -1513,7 +1514,8 @@ MatchAndEmitInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, MCStreamer &Out) { SmallVector Insts; - bool Error = MatchInstruction(IDLoc, Operands, Insts); + unsigned ErrorInfo; + bool Error = MatchInstruction(IDLoc, Operands, Insts, ErrorInfo); if (!Error) for (unsigned i = 0, e = Insts.size(); i != e; ++i) Out.EmitInstruction(Insts[i]); @@ -1523,7 +1525,8 @@ MatchAndEmitInstruction(SMLoc IDLoc, bool X86AsmParser:: MatchInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, - SmallVectorImpl &MCInsts) { + SmallVectorImpl &MCInsts, + unsigned &OrigErrorInfo) { assert(!Operands.empty() && "Unexpect empty operand list!"); X86Operand *Op = static_cast(Operands[0]); assert(Op->isToken() && "Leading operand should always be a mnemonic!"); @@ -1558,7 +1561,6 @@ MatchInstruction(SMLoc IDLoc, } bool WasOriginallyInvalidOperand = false; - unsigned OrigErrorInfo; MCInst Inst; // First, try a direct match. -- cgit v1.1 From b4fdadef51ed254d9282356463c6b11ff8a102df Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Tue, 21 Aug 2012 19:36:59 +0000 Subject: [ms-inline asm] Do not report a Parser error when matching inline assembly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162306 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/AsmParser/X86AsmParser.cpp | 39 ++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 14 deletions(-) (limited to 'lib/Target/X86/AsmParser/X86AsmParser.cpp') diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index c139dbc..73a0095 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -39,7 +39,9 @@ private: MCAsmLexer &getLexer() const { return Parser.getLexer(); } bool Error(SMLoc L, const Twine &Msg, - ArrayRef Ranges = ArrayRef()) { + ArrayRef Ranges = ArrayRef(), + bool matchingInlineAsm = false) { + if (matchingInlineAsm) return true; return Parser.Error(L, Msg, Ranges); } @@ -68,7 +70,8 @@ private: bool MatchInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, SmallVectorImpl &MCInsts, - unsigned &OrigErrorInfo); + 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. @@ -1525,11 +1528,12 @@ MatchAndEmitInstruction(SMLoc IDLoc, bool X86AsmParser:: MatchInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, - SmallVectorImpl &MCInsts, - unsigned &OrigErrorInfo) { + SmallVectorImpl &MCInsts, 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!"); + ArrayRef EmptyRanges = ArrayRef(); // First, handle aliases that expand to multiple instructions. // FIXME: This should be replaced with a real .td file alias mechanism. @@ -1578,10 +1582,12 @@ MatchInstruction(SMLoc IDLoc, MCInsts.push_back(Inst); return false; case Match_MissingFeature: - Error(IDLoc, "instruction requires a CPU feature not currently enabled"); + Error(IDLoc, "instruction requires a CPU feature not currently enabled", + EmptyRanges, matchingInlineAsm); return true; case Match_ConversionFail: - return Error(IDLoc, "unable to convert operands to instruction"); + return Error(IDLoc, "unable to convert operands to instruction", + EmptyRanges, matchingInlineAsm); case Match_InvalidOperand: WasOriginallyInvalidOperand = true; break; @@ -1660,7 +1666,7 @@ MatchInstruction(SMLoc IDLoc, OS << "'" << Base << MatchChars[i] << "'"; } OS << ")"; - Error(IDLoc, OS.str()); + Error(IDLoc, OS.str(), EmptyRanges, matchingInlineAsm); return true; } @@ -1672,30 +1678,33 @@ MatchInstruction(SMLoc IDLoc, (Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) { if (!WasOriginallyInvalidOperand) { return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'", - Op->getLocRange()); + Op->getLocRange(), matchingInlineAsm); } // Recover location info for the operand if we know which was the problem. if (OrigErrorInfo != ~0U) { if (OrigErrorInfo >= Operands.size()) - return Error(IDLoc, "too few operands for instruction"); + return Error(IDLoc, "too few operands for instruction", + EmptyRanges, matchingInlineAsm); X86Operand *Operand = (X86Operand*)Operands[OrigErrorInfo]; if (Operand->getStartLoc().isValid()) { SMRange OperandRange = Operand->getLocRange(); return Error(Operand->getStartLoc(), "invalid operand for instruction", - OperandRange); + OperandRange, matchingInlineAsm); } } - return Error(IDLoc, "invalid operand for instruction"); + return Error(IDLoc, "invalid operand for instruction", EmptyRanges, + matchingInlineAsm); } // If one instruction matched with a missing feature, report this as a // missing feature. if ((Match1 == Match_MissingFeature) + (Match2 == Match_MissingFeature) + (Match3 == Match_MissingFeature) + (Match4 == Match_MissingFeature) == 1){ - Error(IDLoc, "instruction requires a CPU feature not currently enabled"); + Error(IDLoc, "instruction requires a CPU feature not currently enabled", + EmptyRanges, matchingInlineAsm); return true; } @@ -1703,12 +1712,14 @@ MatchInstruction(SMLoc IDLoc, // operand failure. if ((Match1 == Match_InvalidOperand) + (Match2 == Match_InvalidOperand) + (Match3 == Match_InvalidOperand) + (Match4 == Match_InvalidOperand) == 1){ - Error(IDLoc, "invalid operand for instruction"); + Error(IDLoc, "invalid operand for instruction", EmptyRanges, + matchingInlineAsm); return true; } // If all of these were an outright failure, report it in a useless way. - Error(IDLoc, "unknown use of instruction mnemonic without a size suffix"); + Error(IDLoc, "unknown use of instruction mnemonic without a size suffix", + EmptyRanges, matchingInlineAsm); return true; } -- cgit v1.1