diff options
author | Chad Rosier <mcrosier@apple.com> | 2013-02-12 21:33:51 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@apple.com> | 2013-02-12 21:33:51 +0000 |
commit | 469b144f1ce7dc3984cda265bc23ed0b41c20584 (patch) | |
tree | 516213044f658d5c9a14063848d204e311295596 /lib/MC/MCParser | |
parent | dc08bfbd565ba6540be698bba551b2039661299d (diff) | |
download | external_llvm-469b144f1ce7dc3984cda265bc23ed0b41c20584.zip external_llvm-469b144f1ce7dc3984cda265bc23ed0b41c20584.tar.gz external_llvm-469b144f1ce7dc3984cda265bc23ed0b41c20584.tar.bz2 |
[ms-inline-asm] Implement align directive (which is roughly equivalent to .align).
Also, allow _EMIT and __EMIT for the emit directive. We already do the same
for TYPE, SIZE, and LENGTH.
rdar://13200215
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175008 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index bd2c65e..7aa3812 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -443,9 +443,12 @@ private: bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc" bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr" - // "_emit" - bool ParseDirectiveEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info, - size_t len); + // "_emit" or "__emit" + bool ParseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info, + size_t Len); + + // "align" + bool ParseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info); void initializeDirectiveKindMap(); }; @@ -1447,9 +1450,14 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) { return Error(IDLoc, "unknown directive"); } - // _emit or __emit - if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit")) - return ParseDirectiveEmit(IDLoc, Info, IDVal.size()); + // __asm _emit or __asm __emit + if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit" || + IDVal == "_EMIT" || IDVal == "__EMIT")) + return ParseDirectiveMSEmit(IDLoc, Info, IDVal.size()); + + // __asm align + if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN")) + return ParseDirectiveMSAlign(IDLoc, Info); CheckForValidSection(); @@ -3989,7 +3997,7 @@ bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) { return false; } -bool AsmParser::ParseDirectiveEmit(SMLoc IDLoc, ParseStatementInfo &Info, size_t len) { +bool AsmParser::ParseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info, size_t Len) { const MCExpr *Value; SMLoc ExprLoc = getLexer().getLoc(); if (ParseExpression(Value)) @@ -4001,7 +4009,23 @@ bool AsmParser::ParseDirectiveEmit(SMLoc IDLoc, ParseStatementInfo &Info, size_t 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, len)); + Info.AsmRewrites->push_back(AsmRewrite(AOK_Emit, IDLoc, Len)); + return false; +} + +bool AsmParser::ParseDirectiveMSAlign(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 align"); + uint64_t IntValue = MCE->getValue(); + if (!isPowerOf2_64(IntValue)) + return Error(ExprLoc, "literal value not a power of two greater then zero"); + + Info.AsmRewrites->push_back(AsmRewrite(AOK_Align, IDLoc, 5, Log2_64(IntValue))); return false; } @@ -4133,6 +4157,7 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, I = AsmStrRewrites.begin(), E = AsmStrRewrites.end(); I != E; ++I) { const char *Loc = (*I).Loc.getPointer(); + unsigned AdditionalSkip = 0; AsmRewriteKind Kind = (*I).Kind; // Emit everything up to the immediate/expression. If the previous rewrite @@ -4180,6 +4205,15 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, case AOK_Emit: OS << ".byte"; break; + case AOK_Align: { + unsigned Val = (*I).Val; + OS << ".align " << Val; + + // Skip the original immediate. + assert (Val < 10 && "Expected alignment less then 2^10."); + AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4; + break; + } case AOK_DotOperator: OS << (*I).Val; break; @@ -4187,7 +4221,7 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, // Skip the original expression. if (Kind != AOK_SizeDirective) - Start = Loc + (*I).Len; + Start = Loc + (*I).Len + AdditionalSkip; } // Emit the remainder of the asm string. |