MC: Fix Intel assembly parser for [global + offset]

We were dropping the displacement on the floor if we also had some
immediate offset.

Should fix PR19033.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202774 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Kleckner 2014-03-04 00:33:17 +00:00
parent 168a1af83c
commit 4e43e1e686
2 changed files with 36 additions and 15 deletions

View File

@ -936,17 +936,24 @@ X86AsmParser::CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp,
unsigned Scale, SMLoc Start, SMLoc End,
unsigned Size, StringRef Identifier,
InlineAsmIdentifierInfo &Info){
if (isa<MCSymbolRefExpr>(Disp)) {
// If this is not a VarDecl then assume it is a FuncDecl or some other label
// reference. We need an 'r' constraint here, so we need to create register
// operand to ensure proper matching. Just pick a GPR based on the size of
// a pointer.
if (!Info.IsVarDecl) {
unsigned RegNo =
is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true,
SMLoc(), Identifier, Info.OpDecl);
}
// If this is not a VarDecl then assume it is a FuncDecl or some other label
// reference. We need an 'r' constraint here, so we need to create register
// operand to ensure proper matching. Just pick a GPR based on the size of
// a pointer.
if (isa<MCSymbolRefExpr>(Disp) && !Info.IsVarDecl) {
unsigned RegNo =
is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true,
SMLoc(), Identifier, Info.OpDecl);
}
// We either have a direct symbol reference, or an offset from a symbol. The
// parser always puts the symbol on the LHS, so look there for size
// calculation purposes.
const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
bool IsSymRef =
isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
if (IsSymRef) {
if (!Size) {
Size = Info.Type * 8; // Size is in terms of bits in this context.
if (Size)
@ -1154,7 +1161,7 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
if (ParseIntelExpression(SM, End))
return 0;
const MCExpr *Disp;
const MCExpr *Disp = 0;
if (const MCExpr *Sym = SM.getSym()) {
// A symbolic displacement.
Disp = Sym;
@ -1162,9 +1169,14 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
ImmDisp, SM.getImm(), BracLoc, StartInBrac,
End);
} else {
// An immediate displacement only.
Disp = MCConstantExpr::Create(SM.getImm(), getContext());
}
if (SM.getImm() || !Disp) {
const MCExpr *Imm = MCConstantExpr::Create(SM.getImm(), getContext());
if (Disp)
Disp = MCBinaryExpr::CreateAdd(Disp, Imm, getContext());
else
Disp = Imm; // An immediate displacement only.
}
// Parse the dot operator (e.g., [ebx].foo.bar).

View File

@ -590,3 +590,12 @@ fdivr ST(1)
// CHECK: fxrstorq (%rax)
fxsave64 opaque ptr [rax]
fxrstor64 opaque ptr [rax]
.bss
.globl _g0
.text
// CHECK: movq _g0, %rbx
// CHECK: movq _g0+8, %rcx
mov rbx, qword ptr [_g0]
mov rcx, qword ptr [_g0 + 8]