[llvm-commits] [llvm] r74478 - in /llvm/trunk: include/llvm/MC/MCStreamer.h lib/MC/MCAsmStreamer.cpp test/MC/AsmParser/directive_align.s tools/llvm-mc/AsmParser.cpp tools/llvm-mc/AsmParser.h
Daniel Dunbar
daniel at zuster.org
Mon Jun 29 16:47:00 PDT 2009
Author: ddunbar
Date: Mon Jun 29 18:46:59 2009
New Revision: 74478
URL: http://llvm.org/viewvc/llvm-project?rev=74478&view=rev
Log:
llvm-mc: Parse .{,b,p2}align{,w,l} directives.
Added:
llvm/trunk/test/MC/AsmParser/directive_align.s
Modified:
llvm/trunk/include/llvm/MC/MCStreamer.h
llvm/trunk/lib/MC/MCAsmStreamer.cpp
llvm/trunk/tools/llvm-mc/AsmParser.cpp
llvm/trunk/tools/llvm-mc/AsmParser.h
Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=74478&r1=74477&r2=74478&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Mon Jun 29 18:46:59 2009
@@ -135,7 +135,7 @@
/// This used to implement the .align assembler directive.
///
/// @param ByteAlignment - The alignment to reach. This must be a power of
- /// two.
+ /// two on some targets.
/// @param Value - The value to use when filling bytes.
/// @param Size - The size of the integer (in bytes) to emit for @param
/// Value. This must match a native machine width.
Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=74478&r1=74477&r2=74478&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Mon Jun 29 18:46:59 2009
@@ -105,6 +105,7 @@
OS << Symbol->getName() << ":\n";
Symbol->setSection(CurSection);
+ Symbol->setExternal(false);
}
void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCValue &Value,
@@ -164,20 +165,23 @@
void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
unsigned ValueSize,
unsigned MaxBytesToEmit) {
+ // Some assemblers don't support .balign, so we always emit as .p2align if
+ // this is a power of two. Otherwise we assume the client knows the target
+ // supports .balign and use that.
unsigned Pow2 = Log2_32(ByteAlignment);
- assert((1U << Pow2) == ByteAlignment && "Invalid alignment!");
+ bool IsPow2 = (1U << Pow2) == ByteAlignment;
switch (ValueSize) {
default:
assert(0 && "Invalid size for machine code value!");
case 8:
assert(0 && "Unsupported alignment size!");
- case 1: OS << ".p2align"; break;
- case 2: OS << ".p2alignw"; break;
- case 4: OS << ".p2alignl"; break;
+ case 1: OS << (IsPow2 ? ".p2align" : ".balign"); break;
+ case 2: OS << (IsPow2 ? ".p2alignw" : ".balignw"); break;
+ case 4: OS << (IsPow2 ? ".p2alignl" : ".balignl"); break;
}
- OS << ' ' << Pow2;
+ OS << ' ' << (IsPow2 ? Pow2 : ByteAlignment);
OS << ", " << truncateToSize(Value, ValueSize);
if (MaxBytesToEmit)
Added: llvm/trunk/test/MC/AsmParser/directive_align.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/directive_align.s?rev=74478&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/directive_align.s (added)
+++ llvm/trunk/test/MC/AsmParser/directive_align.s Mon Jun 29 18:46:59 2009
@@ -0,0 +1,16 @@
+# RUN: llvm-mc %s > %t
+
+# RUN: grep -A 2 TEST0 %t > %t2
+# RUN: grep ".p2align 1, 0" %t2 | count 1
+TEST0:
+ .align 1
+
+# RUN: grep -A 2 TEST1 %t > %t2
+# RUN: grep ".p2alignl 3, 0, 2" %t2 | count 1
+TEST1:
+ .align32 3,,2
+
+# RUN: grep -A 2 TEST2 %t > %t2
+# RUN: grep ".balign 3, 10" %t2 | count 1
+TEST2:
+ .balign 3,10
Modified: llvm/trunk/tools/llvm-mc/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/AsmParser.cpp?rev=74478&r1=74477&r2=74478&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mc/AsmParser.cpp (original)
+++ llvm/trunk/tools/llvm-mc/AsmParser.cpp Mon Jun 29 18:46:59 2009
@@ -429,10 +429,30 @@
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 @@
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;
+}
+
Modified: llvm/trunk/tools/llvm-mc/AsmParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/AsmParser.h?rev=74478&r1=74477&r2=74478&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mc/AsmParser.h (original)
+++ llvm/trunk/tools/llvm-mc/AsmParser.h Mon Jun 29 18:46:59 2009
@@ -79,6 +79,8 @@
bool ParseDirectiveSpace(); // ".space"
bool ParseDirectiveSet(); // ".set"
bool ParseDirectiveOrg(); // ".org"
+ // ".align{,32}", ".p2align{,w,l}"
+ bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
};
More information about the llvm-commits
mailing list