forked from OSchip/llvm-project
				
			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:
		
							parent
							
								
									70cb2311ab
								
							
						
					
					
						commit
						d84e70ea1b
					
				| 
						 | 
					@ -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).
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue