[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