[llvm-commits] [llvm] r166451 - in /llvm/trunk: include/llvm/MC/MCParser/MCAsmParser.h lib/MC/MCParser/AsmParser.cpp
Eli Friedman
eli.friedman at gmail.com
Mon Oct 22 16:58:19 PDT 2012
Author: efriedma
Date: Mon Oct 22 18:58:19 2012
New Revision: 166451
URL: http://llvm.org/viewvc/llvm-project?rev=166451&view=rev
Log:
[ms-inline-asm] Implement _emit directive (which is roughly equivalent to .byte).
<rdar://problem/12470345>.
Modified:
llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h
llvm/trunk/lib/MC/MCParser/AsmParser.cpp
Modified: llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h?rev=166451&r1=166450&r2=166451&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h (original)
+++ llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h Mon Oct 22 18:58:19 2012
@@ -97,9 +97,6 @@
const MCInstPrinter *IP,
MCAsmParserSemaCallback &SI) = 0;
- /// ParseStatement - Parse the next statement.
- virtual bool ParseStatement() = 0;
-
/// Warning - Emit a warning at the location \p L, with the message \p Msg.
///
/// \return The return value is true, if warnings are fatal.
Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=166451&r1=166450&r2=166451&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Mon Oct 22 18:58:19 2012
@@ -86,6 +86,28 @@
MemoryBuffer *I);
};
+struct AsmRewrite;
+struct ParseStatementInfo {
+ /// ParsedOperands - The parsed operands from the last parsed statement.
+ SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
+
+ /// Opcode - The opcode from the last parsed instruction.
+ unsigned Opcode;
+
+ SmallVectorImpl<AsmRewrite> *AsmRewrites;
+
+ ParseStatementInfo() : Opcode(~0U), AsmRewrites(0) {}
+ ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites)
+ : Opcode(~0), AsmRewrites(rewrites) {}
+
+ ~ParseStatementInfo() {
+ // Free any parsed operands.
+ for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
+ delete ParsedOperands[i];
+ ParsedOperands.clear();
+ }
+};
+
/// \brief The concrete assembly parser instance.
class AsmParser : public MCAsmParser {
friend class GenericAsmParser;
@@ -142,13 +164,6 @@
/// ParsingInlineAsm - Are we parsing ms-style inline assembly?
bool ParsingInlineAsm;
- /// ParsedOperands - The parsed operands from the last parsed statement.
- SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
-
- /// Opcode - The opcode from the last parsed instruction. This is MS-style
- /// inline asm specific.
- unsigned Opcode;
-
public:
AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI);
@@ -209,7 +224,7 @@
private:
void CheckForValidSection();
- bool ParseStatement();
+ bool ParseStatement(ParseStatementInfo &Info);
void EatToEndOfLine();
bool ParseCppHashLineFilenameComment(const SMLoc &L);
@@ -316,10 +331,8 @@
bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc"
bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr"
- // MS-style inline assembly parsing.
- bool isInstruction() { return Opcode != (unsigned)~0x0; }
- unsigned getOpcode() { return Opcode; }
- void setOpcode(unsigned Value) { Opcode = Value; }
+ // "_emit"
+ bool ParseDirectiveEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info);
};
/// \brief Generic implementations of directive handling, etc. which is shared
@@ -445,8 +458,7 @@
: Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
GenericParser(new GenericAsmParser), PlatformParser(0),
CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0),
- AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false),
- Opcode(~0x0) {
+ AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) {
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
SavedDiagContext = SrcMgr.getDiagContext();
@@ -585,7 +597,8 @@
// While we have input, parse each statement.
while (Lexer.isNot(AsmToken::Eof)) {
- if (!ParseStatement()) continue;
+ ParseStatementInfo Info;
+ if (!ParseStatement(Info)) continue;
// We had an error, validate that one was emitted and recover by skipping to
// the next line.
@@ -1068,7 +1081,7 @@
/// ::= EndOfStatement
/// ::= Label* Directive ...Operands... EndOfStatement
/// ::= Label* Identifier OperandList* EndOfStatement
-bool AsmParser::ParseStatement() {
+bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
if (Lexer.is(AsmToken::EndOfStatement)) {
Out.AddBlankLine();
Lex();
@@ -1187,7 +1200,7 @@
return false;
}
- return ParseStatement();
+ return false;
}
case AsmToken::Equal:
@@ -1341,6 +1354,10 @@
return Error(IDLoc, "unknown directive");
}
+ // _emit
+ if (ParsingInlineAsm && IDVal == "_emit")
+ return ParseDirectiveEmit(IDLoc, Info);
+
CheckForValidSection();
// Canonicalize the opcode to lower case.
@@ -1349,17 +1366,17 @@
OpcodeStr.push_back(tolower(IDVal[i]));
bool HadError = getTargetParser().ParseInstruction(OpcodeStr.str(), IDLoc,
- ParsedOperands);
+ Info.ParsedOperands);
// Dump the parsed representation, if requested.
if (getShowParsedOperands()) {
SmallString<256> Str;
raw_svector_ostream OS(Str);
OS << "parsed instruction: [";
- for (unsigned i = 0; i != ParsedOperands.size(); ++i) {
+ for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) {
if (i != 0)
OS << ", ";
- ParsedOperands[i]->print(OS);
+ Info.ParsedOperands[i]->print(OS);
}
OS << "]";
@@ -1381,20 +1398,12 @@
// If parsing succeeded, match the instruction.
if (!HadError) {
unsigned ErrorInfo;
- HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, Opcode,
- ParsedOperands, Out,
- ErrorInfo,
+ HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode,
+ Info.ParsedOperands,
+ Out, ErrorInfo,
ParsingInlineAsm);
}
- // Free any parsed operands. If parsing ms-style inline assembly the operands
- // will be freed by the ParseMSInlineAsm() function.
- if (!ParsingInlineAsm) {
- for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
- delete ParsedOperands[i];
- ParsedOperands.clear();
- }
-
// Don't skip the rest of the line, the instruction parser is responsible for
// that.
return false;
@@ -3579,7 +3588,8 @@
AOK_Imm,
AOK_Input,
AOK_Output,
- AOK_SizeDirective
+ AOK_SizeDirective,
+ AOK_Emit
};
struct AsmRewrite {
@@ -3593,6 +3603,22 @@
};
}
+bool AsmParser::ParseDirectiveEmit(SMLoc IDLoc, ParseStatementInfo &Info) {
+ const MCExpr *Value;
+ SMLoc ExprLoc = getLexer().getLoc();
+ if (ParseExpression(Value))
+ return true;
+ const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
+ if (!MCE)
+ return Error(ExprLoc, "unexpected expression in _emit");
+ uint64_t IntValue = MCE->getValue();
+ if (!isUIntN(8, IntValue) && !isIntN(8, IntValue))
+ return Error(ExprLoc, "literal value out of range for directive");
+
+ Info.AsmRewrites->push_back(AsmRewrite(AOK_Emit, IDLoc, 5));
+ return false;
+}
+
bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
unsigned &NumOutputs, unsigned &NumInputs,
SmallVectorImpl<void *> &OpDecls,
@@ -3616,18 +3642,16 @@
unsigned InputIdx = 0;
unsigned OutputIdx = 0;
while (getLexer().isNot(AsmToken::Eof)) {
- // Clear the opcode.
- setOpcode(~0x0);
-
- if (ParseStatement())
+ ParseStatementInfo Info(&AsmStrRewrites);
+ if (ParseStatement(Info))
return true;
- if (isInstruction()) {
- const MCInstrDesc &Desc = MII->get(getOpcode());
+ if (Info.Opcode != ~0U) {
+ const MCInstrDesc &Desc = MII->get(Info.Opcode);
// Build the list of clobbers, outputs and inputs.
- for (unsigned i = 1, e = ParsedOperands.size(); i != e; ++i) {
- MCParsedAsmOperand *Operand = ParsedOperands[i];
+ for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
+ MCParsedAsmOperand *Operand = Info.ParsedOperands[i];
// Immediate.
if (Operand->isImm()) {
@@ -3679,10 +3703,6 @@
}
}
}
- // Free any parsed operands.
- for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
- delete ParsedOperands[i];
- ParsedOperands.clear();
}
}
@@ -3751,6 +3771,10 @@
case 128: OS << "xmmword ptr "; break;
case 256: OS << "ymmword ptr "; break;
}
+ break;
+ case AOK_Emit:
+ OS << ".byte";
+ break;
}
// Skip the original expression.
More information about the llvm-commits
mailing list