aboutsummaryrefslogtreecommitdiffstats
path: root/tools/llvm-mc/AsmParser.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-06-29 23:46:59 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-06-29 23:46:59 +0000
commit631e12cf38a2250ff50c347239a919bcac4fe8da (patch)
tree65548bffd97a4d84a4d4e6ae133b9ffa211904dc /tools/llvm-mc/AsmParser.cpp
parent20683bf7d820c16f1d1b7b384a8fcd8cb5ca7884 (diff)
downloadexternal_llvm-631e12cf38a2250ff50c347239a919bcac4fe8da.zip
external_llvm-631e12cf38a2250ff50c347239a919bcac4fe8da.tar.gz
external_llvm-631e12cf38a2250ff50c347239a919bcac4fe8da.tar.bz2
llvm-mc: Parse .{,b,p2}align{,w,l} directives.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74478 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-mc/AsmParser.cpp')
-rw-r--r--tools/llvm-mc/AsmParser.cpp98
1 files changed, 96 insertions, 2 deletions
diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp
index 4cb515b..29222d4 100644
--- a/tools/llvm-mc/AsmParser.cpp
+++ b/tools/llvm-mc/AsmParser.cpp
@@ -429,10 +429,30 @@ bool AsmParser::ParseStatement() {
return ParseDirectiveValue(4);
if (!strcmp(IDVal, ".quad"))
return ParseDirectiveValue(8);
- if (!strcmp(IDVal, ".fill"))
- return ParseDirectiveFill();
+
+ // FIXME: Target hooks for IsPow2.
+ if (!strcmp(IDVal, ".align"))
+ return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
+ if (!strcmp(IDVal, ".align32"))
+ return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
+ if (!strcmp(IDVal, ".balign"))
+ return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
+ if (!strcmp(IDVal, ".balignw"))
+ return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
+ if (!strcmp(IDVal, ".balignl"))
+ return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
+ if (!strcmp(IDVal, ".p2align"))
+ return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
+ if (!strcmp(IDVal, ".p2alignw"))
+ return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
+ if (!strcmp(IDVal, ".p2alignl"))
+ return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
+
if (!strcmp(IDVal, ".org"))
return ParseDirectiveOrg();
+
+ if (!strcmp(IDVal, ".fill"))
+ return ParseDirectiveFill();
if (!strcmp(IDVal, ".space"))
return ParseDirectiveSpace();
@@ -708,3 +728,77 @@ bool AsmParser::ParseDirectiveOrg() {
return false;
}
+
+/// ParseDirectiveAlign
+/// ::= {.align, ...} expression [ , expression [ , expression ]]
+bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
+ int64_t Alignment;
+ if (ParseAbsoluteExpression(Alignment))
+ return true;
+
+ SMLoc MaxBytesLoc;
+ bool HasFillExpr = false;
+ int64_t FillExpr = 0;
+ int64_t MaxBytesToFill = 0;
+ if (Lexer.isNot(asmtok::EndOfStatement)) {
+ if (Lexer.isNot(asmtok::Comma))
+ return TokError("unexpected token in directive");
+ Lexer.Lex();
+
+ // The fill expression can be omitted while specifying a maximum number of
+ // alignment bytes, e.g:
+ // .align 3,,4
+ if (Lexer.isNot(asmtok::Comma)) {
+ HasFillExpr = true;
+ if (ParseAbsoluteExpression(FillExpr))
+ return true;
+ }
+
+ if (Lexer.isNot(asmtok::EndOfStatement)) {
+ if (Lexer.isNot(asmtok::Comma))
+ return TokError("unexpected token in directive");
+ Lexer.Lex();
+
+ MaxBytesLoc = Lexer.getLoc();
+ if (ParseAbsoluteExpression(MaxBytesToFill))
+ return true;
+
+ if (Lexer.isNot(asmtok::EndOfStatement))
+ return TokError("unexpected token in directive");
+ }
+ }
+
+ Lexer.Lex();
+
+ if (!HasFillExpr) {
+ // FIXME: Sometimes fill with nop.
+ FillExpr = 0;
+ }
+
+ // Compute alignment in bytes.
+ if (IsPow2) {
+ // FIXME: Diagnose overflow.
+ Alignment = 1 << Alignment;
+ }
+
+ // Diagnose non-sensical max bytes to fill.
+ if (MaxBytesLoc.isValid()) {
+ if (MaxBytesToFill < 1) {
+ Lexer.PrintMessage(MaxBytesLoc, "warning: alignment directive can never "
+ "be satisfied in this many bytes, ignoring");
+ return false;
+ }
+
+ if (MaxBytesToFill >= Alignment) {
+ Lexer.PrintMessage(MaxBytesLoc, "warning: maximum bytes expression "
+ "exceeds alignment and has no effect");
+ MaxBytesToFill = 0;
+ }
+ }
+
+ // FIXME: Target specific behavior about how the "extra" bytes are filled.
+ Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
+
+ return false;
+}
+