[llvm] r282217 - [MC] Support skip and count for .incbin directive
Petr Hosek via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 22 17:41:07 PDT 2016
Author: phosek
Date: Thu Sep 22 19:41:06 2016
New Revision: 282217
URL: http://llvm.org/viewvc/llvm-project?rev=282217&view=rev
Log:
[MC] Support skip and count for .incbin directive
These optional arguments are supported by GNU assembler.
Differential Revision: https://reviews.llvm.org/D24714
Modified:
llvm/trunk/lib/MC/MCParser/AsmParser.cpp
llvm/trunk/test/MC/AsmParser/directive_incbin.s
Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=282217&r1=282216&r2=282217&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Thu Sep 22 19:41:06 2016
@@ -342,7 +342,8 @@ private:
/// \brief Process the specified file for the .incbin directive.
/// This returns true on failure.
- bool processIncbinFile(const std::string &Filename);
+ bool processIncbinFile(const std::string &Filename, int64_t Skip = 0,
+ const MCExpr *Count = nullptr, SMLoc Loc = SMLoc());
/// \brief Reset the current lexer position to that given by \p Loc. The
/// current token is not set; clients should ensure Lex() is called
@@ -643,7 +644,8 @@ bool AsmParser::enterIncludeFile(const s
/// Process the specified .incbin file by searching for it in the include paths
/// then just emitting the byte contents of the file to the streamer. This
/// returns true on failure.
-bool AsmParser::processIncbinFile(const std::string &Filename) {
+bool AsmParser::processIncbinFile(const std::string &Filename, int64_t Skip,
+ const MCExpr *Count, SMLoc Loc) {
std::string IncludedFile;
unsigned NewBuf =
SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
@@ -651,7 +653,17 @@ bool AsmParser::processIncbinFile(const
return true;
// Pick up the bytes from the file and emit them.
- getStreamer().EmitBytes(SrcMgr.getMemoryBuffer(NewBuf)->getBuffer());
+ StringRef Bytes = SrcMgr.getMemoryBuffer(NewBuf)->getBuffer();
+ Bytes = Bytes.drop_front(Skip);
+ if (Count) {
+ int64_t Res;
+ if (!Count->evaluateAsAbsolute(Res))
+ return Error(Loc, "expected absolute expression");
+ if (Res < 0)
+ return Warning(Loc, "negative count has no effect");
+ Bytes = Bytes.take_front(Res);
+ }
+ getStreamer().EmitBytes(Bytes);
return false;
}
@@ -4388,20 +4400,46 @@ bool AsmParser::parseDirectiveInclude()
}
/// parseDirectiveIncbin
-/// ::= .incbin "filename"
+/// ::= .incbin "filename" [ , skip [ , count ] ]
bool AsmParser::parseDirectiveIncbin() {
// Allow the strings to have escaped octal character sequence.
std::string Filename;
SMLoc IncbinLoc = getTok().getLoc();
if (check(getTok().isNot(AsmToken::String),
"expected string in '.incbin' directive") ||
- parseEscapedString(Filename) ||
- parseToken(AsmToken::EndOfStatement,
+ parseEscapedString(Filename))
+ return true;
+
+ int64_t Skip = 0;
+ const MCExpr *Count = nullptr;
+ SMLoc SkipLoc, CountLoc;
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (parseToken(AsmToken::Comma, "unexpected token in '.incbin' directive"))
+ return true;
+
+ // The skip expression can be omitted while specifying the count, e.g:
+ // .incbin "filename",,4
+ if (getTok().isNot(AsmToken::Comma)) {
+ if (parseTokenLoc(SkipLoc) || parseAbsoluteExpression(Skip))
+ return true;
+ }
+
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (parseToken(AsmToken::Comma, "unexpected token in '.incbin' directive") ||
+ parseTokenLoc(CountLoc) || parseExpression(Count))
+ return true;
+ }
+ }
+
+ if (parseToken(AsmToken::EndOfStatement,
"unexpected token in '.incbin' directive"))
return true;
+ if (check(Skip < 0, SkipLoc, "skip is negative"))
+ return true;
+
// Attempt to process the included file.
- if (processIncbinFile(Filename))
+ if (processIncbinFile(Filename, Skip, Count, CountLoc))
return Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
return false;
}
Modified: llvm/trunk/test/MC/AsmParser/directive_incbin.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/directive_incbin.s?rev=282217&r1=282216&r2=282217&view=diff
==============================================================================
--- llvm/trunk/test/MC/AsmParser/directive_incbin.s (original)
+++ llvm/trunk/test/MC/AsmParser/directive_incbin.s Thu Sep 22 19:41:06 2016
@@ -1,6 +1,47 @@
-# RUN: llvm-mc -triple i386-unknown-unknown %s -I %p | FileCheck %s
+# RUN: not llvm-mc -triple i386-unknown-unknown %s -I %p | FileCheck %s
+# RUN: not llvm-mc -triple i386-unknown-unknown %s -I %p 2>&1 > /dev/null| FileCheck %s --check-prefix=CHECK-ERROR
.data
.incbin "incbin\137abcd" # "\137" is underscore "_"
# CHECK: .ascii "abcd\n"
+
+.data
+.incbin "incbin\137abcd", 1
+
+# CHECK: .ascii "bcd\n"
+
+.data
+.incbin "incbin\137abcd", 1, 2
+
+# CHECK: .ascii "bc"
+
+.data
+.incbin "incbin\137abcd",, 2
+
+# CHECK: .ascii "ab"
+
+.data
+.incbin incbin\137abcd
+
+# CHECK-ERROR: error: expected string in '.incbin' directive
+
+.data
+.incbin "incbin\137abcd" 1
+
+# CHECK-ERROR: error: unexpected token in '.incbin' directive
+
+.data
+.incbin "incbin\137abcd", 1 2
+
+# CHECK-ERROR: error: unexpected token in '.incbin' directive
+
+.data
+.incbin "incbin\137abcd", -1
+
+# CHECK-ERROR: error: skip is negative
+
+.data
+.incbin "incbin\137abcd",, -1
+
+# CHECK-ERROR: warning: negative count has no effect
More information about the llvm-commits
mailing list