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.

llvm-svn: 202774
This commit is contained in:
Reid Kleckner 2014-03-04 00:33:17 +00:00
parent 70cb2311ab
commit d84e70ea1b
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 Scale, SMLoc Start, SMLoc End,
unsigned Size, StringRef Identifier, unsigned Size, StringRef Identifier,
InlineAsmIdentifierInfo &Info){ InlineAsmIdentifierInfo &Info){
if (isa<MCSymbolRefExpr>(Disp)) { // If this is not a VarDecl then assume it is a FuncDecl or some other label
// 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
// 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
// operand to ensure proper matching. Just pick a GPR based on the size of // a pointer.
// a pointer. if (isa<MCSymbolRefExpr>(Disp) && !Info.IsVarDecl) {
if (!Info.IsVarDecl) { unsigned RegNo =
unsigned RegNo = is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX); return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true,
return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true, SMLoc(), Identifier, Info.OpDecl);
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) { if (!Size) {
Size = Info.Type * 8; // Size is in terms of bits in this context. Size = Info.Type * 8; // Size is in terms of bits in this context.
if (Size) if (Size)
@ -1154,7 +1161,7 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
if (ParseIntelExpression(SM, End)) if (ParseIntelExpression(SM, End))
return 0; return 0;
const MCExpr *Disp; const MCExpr *Disp = 0;
if (const MCExpr *Sym = SM.getSym()) { if (const MCExpr *Sym = SM.getSym()) {
// A symbolic displacement. // A symbolic displacement.
Disp = Sym; Disp = Sym;
@ -1162,9 +1169,14 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(), RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
ImmDisp, SM.getImm(), BracLoc, StartInBrac, ImmDisp, SM.getImm(), BracLoc, StartInBrac,
End); 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). // Parse the dot operator (e.g., [ebx].foo.bar).

View File

@ -590,3 +590,12 @@ fdivr ST(1)
// CHECK: fxrstorq (%rax) // CHECK: fxrstorq (%rax)
fxsave64 opaque ptr [rax] fxsave64 opaque ptr [rax]
fxrstor64 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]