[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