summaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2013-02-12 21:33:51 +0000
committerChad Rosier <mcrosier@apple.com>2013-02-12 21:33:51 +0000
commit469b144f1ce7dc3984cda265bc23ed0b41c20584 (patch)
tree516213044f658d5c9a14063848d204e311295596 /lib/MC
parentdc08bfbd565ba6540be698bba551b2039661299d (diff)
downloadllvm-469b144f1ce7dc3984cda265bc23ed0b41c20584.tar.gz
llvm-469b144f1ce7dc3984cda265bc23ed0b41c20584.tar.bz2
llvm-469b144f1ce7dc3984cda265bc23ed0b41c20584.tar.xz
[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')
-rw-r--r--lib/MC/MCParser/AsmParser.cpp52
1 files changed, 43 insertions, 9 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index bd2c65e646..7aa381242c 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.