[PATCH] MC: Improve the .fill directive's compatibility with GAS

David Majnemer david.majnemer at gmail.com
Fri Jan 31 04:28:13 PST 2014


Hi rafael, grosbach,

Per the GAS documentation, .fill should permit pattern widths that
aren't a power of two.  While I was in the neighborhood, I added some
sanity checking.  This change was motivated by a use of this construct
in the Linux Kernel.

N.B. To make MCAsmStreamer::EmitValueImpl support emission of values
which aren't powers of two, I fall back upon MCStreamer::EmitIntValue
which is capable of handling them quite well.  There may be minor
differences in some assembly stream, see the modified test cases in this
commit for examples.

http://llvm-reviews.chandlerc.com/D2667

Files:
  lib/MC/MCAsmStreamer.cpp
  lib/MC/MCParser/AsmParser.cpp
  test/CodeGen/ARM/data-in-code-annotations.ll
  test/CodeGen/ARM/emit-big-cst.ll
  test/CodeGen/PowerPC/i128-and-beyond.ll
  test/CodeGen/Thumb2/aligned-constants.ll
  test/CodeGen/X86/global-sections.ll
  test/MC/AsmParser/directive_fill.s

Index: lib/MC/MCAsmStreamer.cpp
===================================================================
--- lib/MC/MCAsmStreamer.cpp
+++ lib/MC/MCAsmStreamer.cpp
@@ -673,28 +673,23 @@
 }
 
 void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) {
+  assert(Size <= 8 && "Invalid size");
   assert(getCurrentSection().first &&
          "Cannot emit contents before setting section!");
   const char *Directive = 0;
   switch (Size) {
   default: break;
   case 1: Directive = MAI->getData8bitsDirective();  break;
   case 2: Directive = MAI->getData16bitsDirective(); break;
   case 4: Directive = MAI->getData32bitsDirective(); break;
-  case 8:
-    Directive = MAI->getData64bitsDirective();
-    // If the target doesn't support 64-bit data, emit as two 32-bit halves.
-    if (Directive) break;
+  case 8: Directive = MAI->getData64bitsDirective(); break;
+  }
+
+  if (!Directive) {
     int64_t IntValue;
     if (!Value->EvaluateAsAbsolute(IntValue))
       report_fatal_error("Don't know how to emit this value.");
-    if (MAI->isLittleEndian()) {
-      EmitIntValue((uint32_t)(IntValue >> 0 ), 4);
-      EmitIntValue((uint32_t)(IntValue >> 32), 4);
-    } else {
-      EmitIntValue((uint32_t)(IntValue >> 32), 4);
-      EmitIntValue((uint32_t)(IntValue >> 0 ), 4);
-    }
+    MCStreamer::EmitIntValue(static_cast<uint64_t>(IntValue), Size);
     return;
   }
 
Index: lib/MC/MCParser/AsmParser.cpp
===================================================================
--- lib/MC/MCParser/AsmParser.cpp
+++ lib/MC/MCParser/AsmParser.cpp
@@ -2397,26 +2397,36 @@
 bool AsmParser::parseDirectiveFill() {
   checkForValidSection();
 
+  SMLoc RepeatLoc = getLexer().getLoc();
   int64_t NumValues;
   if (parseAbsoluteExpression(NumValues))
     return true;
 
+  if (NumValues < 0) {
+    Warning(RepeatLoc,
+            "'.fill' directive with negative repeat count has no effect");
+    NumValues = 0;
+  }
+
   int64_t FillSize = 1;
   int64_t FillExpr = 0;
 
+  SMLoc SizeLoc, ExprLoc;
   if (getLexer().isNot(AsmToken::EndOfStatement)) {
     if (getLexer().isNot(AsmToken::Comma))
       return TokError("unexpected token in '.fill' directive");
     Lex();
 
+    SizeLoc = getLexer().getLoc();
     if (parseAbsoluteExpression(FillSize))
       return true;
 
     if (getLexer().isNot(AsmToken::EndOfStatement)) {
       if (getLexer().isNot(AsmToken::Comma))
         return TokError("unexpected token in '.fill' directive");
       Lex();
 
+      ExprLoc = getLexer().getLoc();
       if (parseAbsoluteExpression(FillExpr))
         return true;
 
@@ -2427,8 +2437,19 @@
     }
   }
 
-  if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
-    return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
+  if (FillSize < 0) {
+    Warning(SizeLoc, "'.fill' directive with negative size has no effect");
+    NumValues = 0;
+  }
+  if (FillSize > 8) {
+    Warning(SizeLoc, "'.fill' directive with negative size has no effect");
+    NumValues = 8;
+  }
+
+  if (!isUInt<32>(FillExpr) && FillSize == 8) {
+    Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits");
+    FillExpr = Lo_32(FillExpr);
+  }
 
   for (uint64_t i = 0, e = NumValues; i != e; ++i)
     getStreamer().EmitIntValue(FillExpr, FillSize);
Index: test/CodeGen/ARM/data-in-code-annotations.ll
===================================================================
--- test/CodeGen/ARM/data-in-code-annotations.ll
+++ test/CodeGen/ARM/data-in-code-annotations.ll
@@ -3,8 +3,7 @@
 define double @f1() nounwind {
 ; CHECK-LABEL: f1:
 ; CHECK: .data_region
-; CHECK: .long 1413754129
-; CHECK: .long 1074340347
+; CHECK: .ascii "\021-DT\373!\t@"
 ; CHECK: .end_data_region
   ret double 0x400921FB54442D11
 }
Index: test/CodeGen/ARM/emit-big-cst.ll
===================================================================
--- test/CodeGen/ARM/emit-big-cst.ll
+++ test/CodeGen/ARM/emit-big-cst.ll
@@ -2,8 +2,7 @@
 ; Check assembly printing of odd constants.
 
 ; CHECK: bigCst:
-; CHECK-NEXT: .long 1694510592
-; CHECK-NEXT: .long 2960197
+; CHECK-NEXT: .asciz "\000.\000eE+-"
 ; CHECK-NEXT: .long 26220
 ; CHECK-NEXT: .size bigCst, 12
 
Index: test/CodeGen/PowerPC/i128-and-beyond.ll
===================================================================
--- test/CodeGen/PowerPC/i128-and-beyond.ll
+++ test/CodeGen/PowerPC/i128-and-beyond.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=ppc32 | grep 4294967295 | count 28
+; RUN: llc < %s -march=ppc32 | grep '\(\\377\)\{8\}' | count 14
 
 ; These static initializers are too big to hand off to assemblers
 ; as monolithic blobs.
Index: test/CodeGen/Thumb2/aligned-constants.ll
===================================================================
--- test/CodeGen/Thumb2/aligned-constants.ll
+++ test/CodeGen/Thumb2/aligned-constants.ll
@@ -10,8 +10,7 @@
 ; Constant pool with 8-byte entry before 4-byte entry:
 ; CHECK: .align 3
 ; CHECK: LCPI
-; CHECK:	.long	2370821947
-; CHECK:	.long	1080815255
+; CHECK:	.ascii  ";\337O\215\227\356k@"
 ; CHECK: LCPI
 ; CHECK:	.long	1123477881
 define void @func(float* nocapture %x, double* nocapture %y) nounwind ssp {
Index: test/CodeGen/X86/global-sections.ll
===================================================================
--- test/CodeGen/X86/global-sections.ll
+++ test/CodeGen/X86/global-sections.ll
@@ -45,7 +45,8 @@
 
 ; DARWIN: .section        __TEXT,__literal16,16byte_literals
 ; DARWIN: _G4:
-; DARWIN:     .long 34
+; DARWIN:     .asciz  "\"\000\000\000\000\000\000"
+; DARWIN:     .asciz  "\000\000\000\000\000\000\000"
 
 
 ; int G5 = 47;
Index: test/MC/AsmParser/directive_fill.s
===================================================================
--- test/MC/AsmParser/directive_fill.s
+++ test/MC/AsmParser/directive_fill.s
@@ -31,3 +31,11 @@
 # CHECK: .short 0
 TEST4:
 	.fill 4, 2
+
+# CHECK: TEST5
+# CHECK: .asciz "\002\000"
+# CHECK: .asciz "\002\000"
+# CHECK: .asciz "\002\000"
+# CHECK: .asciz "\002\000"
+TEST5:
+	.fill 1, 3, 2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2667.1.patch
Type: text/x-patch
Size: 5977 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140131/c0ed4490/attachment.bin>


More information about the llvm-commits mailing list