[X86][inline asm] support even directive
authorMichael Zuckerman <Michael.zuckerman@intel.com>
Sun, 13 Dec 2015 17:07:23 +0000 (17:07 +0000)
committerMichael Zuckerman <Michael.zuckerman@intel.com>
Sun, 13 Dec 2015 17:07:23 +0000 (17:07 +0000)
The .even directive aligns content to an evan-numbered address.

In at&t syntax .even
In Microsoft syntax even (without the dot).

Differential Revision: http://reviews.llvm.org/D15413

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255462 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCTargetAsmParser.h
lib/MC/MCParser/AsmParser.cpp
lib/Target/X86/AsmParser/X86AsmParser.cpp
test/MC/X86/x86-evenDirective.s [new file with mode: 0644]

index 126da39e70ff720999616f1f03f907c9d15f65db..f8bf4d09f5a14dd32b29e71fd1e27e2e21dd19a5 100644 (file)
@@ -30,6 +30,7 @@ typedef SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>> OperandVector;
 enum AsmRewriteKind {
   AOK_Delete = 0,     // Rewrite should be ignored.
   AOK_Align,          // Rewrite align as .align.
 enum AsmRewriteKind {
   AOK_Delete = 0,     // Rewrite should be ignored.
   AOK_Align,          // Rewrite align as .align.
+  AOK_EVEN,           // Rewrite even as .even.
   AOK_DotOperator,    // Rewrite a dot operator expression as an immediate.
                       // E.g., [eax].foo.bar -> [eax].8
   AOK_Emit,           // Rewrite _emit as .byte.
   AOK_DotOperator,    // Rewrite a dot operator expression as an immediate.
                       // E.g., [eax].foo.bar -> [eax].8
   AOK_Emit,           // Rewrite _emit as .byte.
@@ -45,6 +46,7 @@ enum AsmRewriteKind {
 const char AsmRewritePrecedence [] = {
   0, // AOK_Delete
   2, // AOK_Align
 const char AsmRewritePrecedence [] = {
   0, // AOK_Delete
   2, // AOK_Align
+  2, // AOK_EVEN
   2, // AOK_DotOperator
   2, // AOK_Emit
   4, // AOK_Imm
   2, // AOK_DotOperator
   2, // AOK_Emit
   4, // AOK_Imm
index 61f7d749b9688463222c3133fe72400eb0608ccd..646cbb43cae8a4a369395f433e961756663b562d 100644 (file)
@@ -1714,6 +1714,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
   if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
     return parseDirectiveMSAlign(IDLoc, Info);
 
   if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
     return parseDirectiveMSAlign(IDLoc, Info);
 
+  if (ParsingInlineAsm && (IDVal == "even"))
+    Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4);
   checkForValidSection();
 
   // Canonicalize the opcode to lower case.
   checkForValidSection();
 
   // Canonicalize the opcode to lower case.
@@ -4863,6 +4865,9 @@ bool AsmParser::parseMSInlineAsm(
       AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
       break;
     }
       AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
       break;
     }
+    case AOK_EVEN:
+      OS << ".even";
+      break;
     case AOK_DotOperator:
       // Insert the dot if the user omitted it.
       OS.flush();
     case AOK_DotOperator:
       // Insert the dot if the user omitted it.
       OS.flush();
index f2efefd35c52e715ab490fe5f82c77bd64500d16..4d36f1fd69cef0eba49049b4d8b6d500526457e8 100644 (file)
@@ -26,6 +26,7 @@
 #include "llvm/MC/MCParser/MCAsmParser.h"
 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCParser/MCAsmParser.h"
 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
 #include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSection.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/MC/MCSymbol.h"
@@ -714,6 +715,7 @@ private:
                         SMLoc End, unsigned Size, StringRef Identifier,
                         InlineAsmIdentifierInfo &Info);
 
                         SMLoc End, unsigned Size, StringRef Identifier,
                         InlineAsmIdentifierInfo &Info);
 
+  bool parseDirectiveEven(SMLoc L);
   bool ParseDirectiveWord(unsigned Size, SMLoc L);
   bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
 
   bool ParseDirectiveWord(unsigned Size, SMLoc L);
   bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
 
@@ -2844,10 +2846,29 @@ bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
                                            "a '%' prefix in .intel_syntax");
     }
     return false;
                                            "a '%' prefix in .intel_syntax");
     }
     return false;
-  }
+  } else if (IDVal == ".even")
+    return parseDirectiveEven(DirectiveID.getLoc());
   return true;
 }
 
   return true;
 }
 
+/// parseDirectiveEven
+///  ::= .even
+bool X86AsmParser::parseDirectiveEven(SMLoc L) {
+  const MCSection *Section = getStreamer().getCurrentSection().first;
+  if (getLexer().isNot(AsmToken::EndOfStatement)) {
+    TokError("unexpected token in directive");
+    return false;  
+  }
+  if (!Section) {
+    getStreamer().InitSections(false);
+    Section = getStreamer().getCurrentSection().first;
+  }
+  if (Section->UseCodeAlign())
+    getStreamer().EmitCodeAlignment(2, 0);
+  else
+    getStreamer().EmitValueToAlignment(2, 0, 1, 0);
+  return false;
+}
 /// ParseDirectiveWord
 ///  ::= .word [ expression (, expression)* ]
 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
 /// ParseDirectiveWord
 ///  ::= .word [ expression (, expression)* ]
 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
diff --git a/test/MC/X86/x86-evenDirective.s b/test/MC/X86/x86-evenDirective.s
new file mode 100644 (file)
index 0000000..4dcce28
--- /dev/null
@@ -0,0 +1,47 @@
+# RUN: llvm-mc -filetype obj -o - %s | llvm-readobj -s -sd \
+# RUN:   | FileCheck %s
+
+       .text
+       even_check:
+       .byte 0x00
+       .byte 0x01
+       .byte 0x02
+       .byte 0x03
+       .byte 0x04
+       .byte 0x05
+       .byte 0x06
+       .byte 0x07
+       .byte 0x08
+       .byte 0x09
+       .byte 0x10
+       .even
+       .byte 0x11
+       .byte 0x12
+       .even
+       .byte 0x13
+       .even
+       .byte 0x00
+       .byte 0x01
+       .byte 0x02
+       .byte 0x03
+       .byte 0x04
+       .byte 0x05
+       .byte 0x06
+       .byte 0x07
+       .byte 0x08
+       .byte 0x09
+       .byte 0x10
+       .byte 0x11
+       .byte 0x12
+       .byte 0x13
+       .byte 0x14
+       .byte 0x15
+
+# CHECK: Section {
+# CHECK:   Name: .text
+# CHECK:   SectionData (
+# CHECK:      0000: 00010203 04050607 08091090 11121390
+# CHECK:         0010: 00010203 04050607 08091011 12131415
+# CHECK:   )
+# CHECK: }
+