[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
This commit is contained in:
Chad Rosier 2012-10-24 22:21:50 +00:00
parent 4284e1795d
commit 22f441afba

View File

@ -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) {