diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-02-01 07:19:38 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-02-01 07:19:38 +0000 |
commit | 522d3db745068f38b8aad4639f28f052e620fdd4 (patch) | |
tree | 99d1d332133e8317719507ebecf40cab563abedc /llvm/lib/MC/MCParser/AsmParser.cpp | |
parent | ad141abd634bc23e3a74ab3bbb6ca2622a05195d (diff) | |
download | bcm5719-llvm-522d3db745068f38b8aad4639f28f052e620fdd4.tar.gz bcm5719-llvm-522d3db745068f38b8aad4639f28f052e620fdd4.zip |
MC: Improve the .fill directive's compatibility with GAS
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.
llvm-svn: 200606
Diffstat (limited to 'llvm/lib/MC/MCParser/AsmParser.cpp')
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 3f813a73cc1..9157ac4f67c 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -2397,18 +2397,27 @@ bool AsmParser::parseDirectiveZero() { 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; @@ -2417,6 +2426,7 @@ bool AsmParser::parseDirectiveFill() { return TokError("unexpected token in '.fill' directive"); Lex(); + ExprLoc = getLexer().getLoc(); if (parseAbsoluteExpression(FillExpr)) return true; @@ -2427,11 +2437,25 @@ bool AsmParser::parseDirectiveFill() { } } - 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 size greater than 8 has been truncated to 8"); + FillSize = 8; + } - for (uint64_t i = 0, e = NumValues; i != e; ++i) - getStreamer().EmitIntValue(FillExpr, FillSize); + if (!isUInt<32>(FillExpr) && FillSize > 4) + Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits"); + + int64_t NonZeroFillSize = FillSize > 4 ? 4 : FillSize; + FillExpr &= ~0ULL >> (64 - NonZeroFillSize * 8); + + for (uint64_t i = 0, e = NumValues; i != e; ++i) { + getStreamer().EmitIntValue(FillExpr, NonZeroFillSize); + getStreamer().EmitIntValue(0, FillSize - NonZeroFillSize); + } return false; } |