[X86][inline asm] support even directive

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
This commit is contained in:
Michael Zuckerman 2015-12-13 17:07:23 +00:00
parent 778ee759f6
commit be7b5146ad
4 changed files with 76 additions and 1 deletions

View 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.
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.
@ -45,6 +46,7 @@ enum AsmRewriteKind {
const char AsmRewritePrecedence [] = {
0, // AOK_Delete
2, // AOK_Align
2, // AOK_EVEN
2, // AOK_DotOperator
2, // AOK_Emit
4, // AOK_Imm

View File

@ -1714,6 +1714,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &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.
@ -4863,6 +4865,9 @@ bool AsmParser::parseMSInlineAsm(
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();

View 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/MCSection.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);
bool parseDirectiveEven(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;
}
} else if (IDVal == ".even")
return parseDirectiveEven(DirectiveID.getLoc());
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) {

View File

@ -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: }