aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/X86/AsmParser/X86AsmParser.cpp
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2012-10-24 22:21:50 +0000
committerChad Rosier <mcrosier@apple.com>2012-10-24 22:21:50 +0000
commit22f441afbac90b2dc1e4315a7a6c50dd034af2db (patch)
treed553338b6c8fe00e13c3cefc9bc631971d2151e9 /lib/Target/X86/AsmParser/X86AsmParser.cpp
parent4284e1795dd47d9638bb4fbd455ddb7e2e710e80 (diff)
[ms-inline asm] Add support for parsing the '.' operator. Given,
[register].field The operator returns the value at the location pointed to by register plus the offset of field within its structure or union. This patch only handles immediate fields (i.e., [eax].4). The original displacement has to be a MCConstantExpr as well. Part of rdar://12470415 and rdar://12470514 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166632 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/AsmParser/X86AsmParser.cpp')
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index c752d5962e..708951126f 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -60,6 +60,8 @@ private:
X86Operand *ParseIntelBracExpression(unsigned SegReg, unsigned Size);
X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
+ const MCExpr *ParseIntelDotOperator(const MCExpr *Disp);
+
bool ParseDirectiveWord(unsigned Size, SMLoc L);
bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
@@ -742,6 +744,11 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
Parser.Lex();
End = Tok.getLoc();
+ if (Tok.getString().startswith("."))
+ Disp = ParseIntelDotOperator(Disp);
+
+ End = Tok.getLoc();
+
// handle [-42]
if (!BaseReg && !IndexReg)
return X86Operand::CreateMem(Disp, Start, End, Size);
@@ -801,6 +808,33 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg, SMLoc Start) {
/*Scale*/1, Start, End, Size, NeedSizeDir);
}
+/// Parse the '.' operator.
+const MCExpr *X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp) {
+ AsmToken Tok = *&Parser.getTok();
+
+ // Drop the '.'.
+ StringRef DotDispStr = Tok.getString().drop_front(1);
+
+ Lex(); // Eat .field.
+
+ // .Imm gets lexed as a real.
+ if (Tok.is(AsmToken::Real)) {
+ APInt DotDisp;
+ DotDispStr.getAsInteger(10, DotDisp);
+ uint64_t DotDispVal = DotDisp.getZExtValue();
+
+ // Special case zero dot displacement.
+ if (!DotDispVal) return Disp;
+
+ // FIXME: Handle non-constant expressions.
+ if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp)) {
+ uint64_t OrigDispVal = OrigDisp->getValue();
+ return MCConstantExpr::Create(OrigDispVal + DotDispVal, getContext());
+ }
+ }
+ return Disp;
+}
+
/// Parse the 'offset' operator. This operator is used to specify the
/// location rather then the content of a variable.
X86Operand *X86AsmParser::ParseIntelOffsetOfOperator(SMLoc Start) {