diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-06-29 23:46:59 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-06-29 23:46:59 +0000 |
commit | 631e12cf38a2250ff50c347239a919bcac4fe8da (patch) | |
tree | 65548bffd97a4d84a4d4e6ae133b9ffa211904dc /tools/llvm-mc/AsmParser.cpp | |
parent | 20683bf7d820c16f1d1b7b384a8fcd8cb5ca7884 (diff) | |
download | external_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.cpp | 98 |
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; +} + |