aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2013-04-08 17:43:47 +0000
committerChad Rosier <mcrosier@apple.com>2013-04-08 17:43:47 +0000
commit6b369ceb582f2deba9c252af301667975456ff86 (patch)
tree9d60261d59ddd2796f340e949c2890d2177e28f5
parent5ee67e8e76dfcaffa5e776ef3d5eeb80807a627b (diff)
[ms-inline asm] Add support for ImmDisp [ Symbol ] memory operands.
rdar://13521249 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179030 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h14
-rw-r--r--lib/MC/MCParser/AsmParser.cpp20
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp18
3 files changed, 28 insertions, 24 deletions
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index 4c5b176125..2cdb983285 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -22,7 +22,7 @@ class MCInst;
template <typename T> class SmallVectorImpl;
enum AsmRewriteKind {
- AOK_Align, // Rewrite align as .align.
+ AOK_Align = 0, // Rewrite align as .align.
AOK_DotOperator, // Rewrite a dot operator expression as an immediate.
// E.g., [eax].foo.bar -> [eax].8
AOK_Emit, // Rewrite _emit as .byte.
@@ -34,6 +34,18 @@ enum AsmRewriteKind {
AOK_Skip // Skip emission (e.g., offset/type operators).
};
+const char AsmRewritePrecedence [] = {
+ 0, // AOK_Align
+ 0, // AOK_DotOperator
+ 0, // AOK_Emit
+ 2, // AOK_Imm
+ 2, // AOK_ImmPrefix
+ 1, // AOK_Input
+ 1, // AOK_Output
+ 3, // AOK_SizeDirective
+ 0 // AOK_Skip
+};
+
struct AsmRewrite {
AsmRewriteKind Kind;
SMLoc Loc;
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 804734cea9..275e748c70 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -4046,19 +4046,17 @@ static int RewritesSort(const void *A, const void *B) {
if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
return 1;
- // It's possible to have a SizeDirective rewrite and an Input/Output rewrite
- // to the same location. Make sure the SizeDirective rewrite is performed
- // first. This also ensure the sort algorithm is stable.
- if (AsmRewriteA->Kind == AOK_SizeDirective) {
- assert ((AsmRewriteB->Kind == AOK_Input || AsmRewriteB->Kind == AOK_Output) &&
- "Expected an Input/Output rewrite!");
+ // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
+ // rewrite to the same location. Make sure the SizeDirective rewrite is
+ // performed first, then the Imm/ImmPrefix and finally the Input/Output. This
+ // ensures the sort algorithm is stable.
+ if (AsmRewritePrecedence [AsmRewriteA->Kind] >
+ AsmRewritePrecedence [AsmRewriteB->Kind])
return -1;
- }
- if (AsmRewriteB->Kind == AOK_SizeDirective) {
- assert ((AsmRewriteA->Kind == AOK_Input || AsmRewriteA->Kind == AOK_Output) &&
- "Expected an Input/Output rewrite!");
+
+ if (AsmRewritePrecedence [AsmRewriteA->Kind] <
+ AsmRewritePrecedence [AsmRewriteB->Kind])
return 1;
- }
llvm_unreachable ("Unstable rewrite sort.");
}
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index e9fc0d7ed1..4f4fad9b9f 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -61,8 +61,8 @@ private:
X86Operand *ParseIntelOperator(SMLoc StartLoc, unsigned OpKind);
X86Operand *ParseIntelMemOperand(unsigned SegReg, uint64_t ImmDisp,
SMLoc StartLoc);
- X86Operand *ParseIntelBracExpression(unsigned SegReg, uint64_t ImmDisp,
- unsigned Size);
+ X86Operand *ParseIntelBracExpression(unsigned SegReg, SMLoc SizeDirLoc,
+ uint64_t ImmDisp, unsigned Size);
X86Operand *ParseIntelVarWithQualifier(const MCExpr *&Disp,
SMLoc &IdentStart);
X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
@@ -1100,6 +1100,7 @@ X86Operand *X86AsmParser::CreateMemForInlineAsm(const MCExpr *Disp, SMLoc Start,
}
X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
+ SMLoc SizeDirLoc,
uint64_t ImmDisp,
unsigned Size) {
const AsmToken &Tok = Parser.getTok();
@@ -1126,18 +1127,11 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
if (getLexer().isNot(AsmToken::RBrac))
return ErrorOperand(Parser.getTok().getLoc(), "Expected ']' token!");
- // FIXME: We don't handle 'ImmDisp' '[' 'Symbol' ']'.
- if (ImmDisp)
- return ErrorOperand(Start, "Unsupported immediate displacement!");
-
// Adjust the EndLoc due to the ']'.
End = SMLoc::getFromPointer(Parser.getTok().getEndLoc().getPointer()-1);
Parser.Lex();
if (!isParsingInlineAsm())
return X86Operand::CreateMem(Disp, Start, End, Size);
-
- // We want the size directive before the '['.
- SMLoc SizeDirLoc = SMLoc::getFromPointer(Start.getPointer()-1);
return CreateMemForInlineAsm(Disp, Start, End, SizeDirLoc, Size);
}
}
@@ -1302,11 +1296,11 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
Parser.Lex(); // Eat the integer.
if (getLexer().isNot(AsmToken::LBrac))
return ErrorOperand(Start, "Expected '[' token!");
- return ParseIntelBracExpression(SegReg, ImmDisp, Size);
+ return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
}
if (getLexer().is(AsmToken::LBrac))
- return ParseIntelBracExpression(SegReg, ImmDisp, Size);
+ return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
if (!ParseRegister(SegReg, Start, End)) {
// Handel SegReg : [ ... ]
@@ -1315,7 +1309,7 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
Parser.Lex(); // Eat :
if (getLexer().isNot(AsmToken::LBrac))
return ErrorOperand(Start, "Expected '[' token!");
- return ParseIntelBracExpression(SegReg, ImmDisp, Size);
+ return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
}
const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());