[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