diff options
| author | Chad Rosier <mcrosier@apple.com> | 2012-10-24 22:21:50 +0000 |
|---|---|---|
| committer | Chad Rosier <mcrosier@apple.com> | 2012-10-24 22:21:50 +0000 |
| commit | 5dcb4664f27630f88bdd12ca5dd6b7264998d749 (patch) | |
| tree | 2a0e1effe96846f0faecd723195ce12fb4d2ce55 | |
| parent | 2928d37096a5dc21020fbd452653370e8d294678 (diff) | |
| download | bcm5719-llvm-5dcb4664f27630f88bdd12ca5dd6b7264998d749.tar.gz bcm5719-llvm-5dcb4664f27630f88bdd12ca5dd6b7264998d749.zip | |
[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
llvm-svn: 166632
| -rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index c752d5962ea..708951126f5 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/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) { |

