X86MCInstLower.cpp revision b88b00ba2b7d7be2939c55193900cf4e465098c3
1//===-- X86MCInstLower.cpp - Convert X86 MachineInstr to an MCInst --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains code to lower X86 MachineInstrs to their corresponding 11// MCInst records. 12// 13//===----------------------------------------------------------------------===// 14 15#include "X86MCInstLower.h" 16#include "X86AsmPrinter.h" 17#include "X86COFFMachineModuleInfo.h" 18#include "X86MCAsmInfo.h" 19#include "llvm/CodeGen/MachineModuleInfoImpls.h" 20#include "llvm/MC/MCContext.h" 21#include "llvm/MC/MCExpr.h" 22#include "llvm/MC/MCInst.h" 23#include "llvm/MC/MCStreamer.h" 24#include "llvm/MC/MCSymbol.h" 25#include "llvm/Target/Mangler.h" 26#include "llvm/Support/FormattedStream.h" 27#include "llvm/ADT/SmallString.h" 28#include "llvm/Type.h" 29using namespace llvm; 30 31X86MCInstLower::X86MCInstLower(Mangler *mang, const MachineFunction &mf, 32 X86AsmPrinter &asmprinter) 33: Ctx(mf.getContext()), Mang(mang), MF(mf), TM(mf.getTarget()), 34 MAI(*TM.getMCAsmInfo()), AsmPrinter(asmprinter) {} 35 36MachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const { 37 return MF.getMMI().getObjFileInfo<MachineModuleInfoMachO>(); 38} 39 40 41MCSymbol *X86MCInstLower::GetPICBaseSymbol() const { 42 return static_cast<const X86TargetLowering*>(TM.getTargetLowering())-> 43 getPICBaseSymbol(&MF, Ctx); 44} 45 46/// GetSymbolFromOperand - Lower an MO_GlobalAddress or MO_ExternalSymbol 47/// operand to an MCSymbol. 48MCSymbol *X86MCInstLower:: 49GetSymbolFromOperand(const MachineOperand &MO) const { 50 assert((MO.isGlobal() || MO.isSymbol()) && "Isn't a symbol reference"); 51 52 SmallString<128> Name; 53 54 if (!MO.isGlobal()) { 55 assert(MO.isSymbol()); 56 Name += MAI.getGlobalPrefix(); 57 Name += MO.getSymbolName(); 58 } else { 59 const GlobalValue *GV = MO.getGlobal(); 60 bool isImplicitlyPrivate = false; 61 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB || 62 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || 63 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE || 64 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE) 65 isImplicitlyPrivate = true; 66 67 Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate); 68 } 69 70 // If the target flags on the operand changes the name of the symbol, do that 71 // before we return the symbol. 72 switch (MO.getTargetFlags()) { 73 default: break; 74 case X86II::MO_DLLIMPORT: { 75 // Handle dllimport linkage. 76 const char *Prefix = "__imp_"; 77 Name.insert(Name.begin(), Prefix, Prefix+strlen(Prefix)); 78 break; 79 } 80 case X86II::MO_DARWIN_NONLAZY: 81 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: { 82 Name += "$non_lazy_ptr"; 83 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 84 85 MachineModuleInfoImpl::StubValueTy &StubSym = 86 getMachOMMI().getGVStubEntry(Sym); 87 if (StubSym.getPointer() == 0) { 88 assert(MO.isGlobal() && "Extern symbol not handled yet"); 89 StubSym = 90 MachineModuleInfoImpl:: 91 StubValueTy(Mang->getSymbol(MO.getGlobal()), 92 !MO.getGlobal()->hasInternalLinkage()); 93 } 94 return Sym; 95 } 96 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: { 97 Name += "$non_lazy_ptr"; 98 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 99 MachineModuleInfoImpl::StubValueTy &StubSym = 100 getMachOMMI().getHiddenGVStubEntry(Sym); 101 if (StubSym.getPointer() == 0) { 102 assert(MO.isGlobal() && "Extern symbol not handled yet"); 103 StubSym = 104 MachineModuleInfoImpl:: 105 StubValueTy(Mang->getSymbol(MO.getGlobal()), 106 !MO.getGlobal()->hasInternalLinkage()); 107 } 108 return Sym; 109 } 110 case X86II::MO_DARWIN_STUB: { 111 Name += "$stub"; 112 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 113 MachineModuleInfoImpl::StubValueTy &StubSym = 114 getMachOMMI().getFnStubEntry(Sym); 115 if (StubSym.getPointer()) 116 return Sym; 117 118 if (MO.isGlobal()) { 119 StubSym = 120 MachineModuleInfoImpl:: 121 StubValueTy(Mang->getSymbol(MO.getGlobal()), 122 !MO.getGlobal()->hasInternalLinkage()); 123 } else { 124 Name.erase(Name.end()-5, Name.end()); 125 StubSym = 126 MachineModuleInfoImpl:: 127 StubValueTy(Ctx.GetOrCreateSymbol(Name.str()), false); 128 } 129 return Sym; 130 } 131 } 132 133 return Ctx.GetOrCreateSymbol(Name.str()); 134} 135 136MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO, 137 MCSymbol *Sym) const { 138 // FIXME: We would like an efficient form for this, so we don't have to do a 139 // lot of extra uniquing. 140 const MCExpr *Expr = 0; 141 MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; 142 143 switch (MO.getTargetFlags()) { 144 default: llvm_unreachable("Unknown target flag on GV operand"); 145 case X86II::MO_NO_FLAG: // No flag. 146 // These affect the name of the symbol, not any suffix. 147 case X86II::MO_DARWIN_NONLAZY: 148 case X86II::MO_DLLIMPORT: 149 case X86II::MO_DARWIN_STUB: 150 break; 151 152 case X86II::MO_TLVP: RefKind = MCSymbolRefExpr::VK_TLVP; break; 153 case X86II::MO_TLVP_PIC_BASE: 154 Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx); 155 // Subtract the pic base. 156 Expr = MCBinaryExpr::CreateSub(Expr, 157 MCSymbolRefExpr::Create(GetPICBaseSymbol(), 158 Ctx), 159 Ctx); 160 break; 161 case X86II::MO_TLSGD: RefKind = MCSymbolRefExpr::VK_TLSGD; break; 162 case X86II::MO_GOTTPOFF: RefKind = MCSymbolRefExpr::VK_GOTTPOFF; break; 163 case X86II::MO_INDNTPOFF: RefKind = MCSymbolRefExpr::VK_INDNTPOFF; break; 164 case X86II::MO_TPOFF: RefKind = MCSymbolRefExpr::VK_TPOFF; break; 165 case X86II::MO_NTPOFF: RefKind = MCSymbolRefExpr::VK_NTPOFF; break; 166 case X86II::MO_GOTPCREL: RefKind = MCSymbolRefExpr::VK_GOTPCREL; break; 167 case X86II::MO_GOT: RefKind = MCSymbolRefExpr::VK_GOT; break; 168 case X86II::MO_GOTOFF: RefKind = MCSymbolRefExpr::VK_GOTOFF; break; 169 case X86II::MO_PLT: RefKind = MCSymbolRefExpr::VK_PLT; break; 170 case X86II::MO_PIC_BASE_OFFSET: 171 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: 172 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: 173 Expr = MCSymbolRefExpr::Create(Sym, Ctx); 174 // Subtract the pic base. 175 Expr = MCBinaryExpr::CreateSub(Expr, 176 MCSymbolRefExpr::Create(GetPICBaseSymbol(), Ctx), 177 Ctx); 178 if (MO.isJTI() && MAI.hasSetDirective()) { 179 // If .set directive is supported, use it to reduce the number of 180 // relocations the assembler will generate for differences between 181 // local labels. This is only safe when the symbols are in the same 182 // section so we are restricting it to jumptable references. 183 MCSymbol *Label = Ctx.CreateTempSymbol(); 184 AsmPrinter.OutStreamer.EmitAssignment(Label, Expr); 185 Expr = MCSymbolRefExpr::Create(Label, Ctx); 186 } 187 break; 188 } 189 190 if (Expr == 0) 191 Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx); 192 193 if (!MO.isJTI() && MO.getOffset()) 194 Expr = MCBinaryExpr::CreateAdd(Expr, 195 MCConstantExpr::Create(MO.getOffset(), Ctx), 196 Ctx); 197 return MCOperand::CreateExpr(Expr); 198} 199 200 201 202static void lower_subreg32(MCInst *MI, unsigned OpNo) { 203 // Convert registers in the addr mode according to subreg32. 204 unsigned Reg = MI->getOperand(OpNo).getReg(); 205 if (Reg != 0) 206 MI->getOperand(OpNo).setReg(getX86SubSuperRegister(Reg, MVT::i32)); 207} 208 209static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) { 210 // Convert registers in the addr mode according to subreg64. 211 for (unsigned i = 0; i != 4; ++i) { 212 if (!MI->getOperand(OpNo+i).isReg()) continue; 213 214 unsigned Reg = MI->getOperand(OpNo+i).getReg(); 215 if (Reg == 0) continue; 216 217 MI->getOperand(OpNo+i).setReg(getX86SubSuperRegister(Reg, MVT::i64)); 218 } 219} 220 221/// LowerSubReg32_Op0 - Things like MOVZX16rr8 -> MOVZX32rr8. 222static void LowerSubReg32_Op0(MCInst &OutMI, unsigned NewOpc) { 223 OutMI.setOpcode(NewOpc); 224 lower_subreg32(&OutMI, 0); 225} 226/// LowerUnaryToTwoAddr - R = setb -> R = sbb R, R 227static void LowerUnaryToTwoAddr(MCInst &OutMI, unsigned NewOpc) { 228 OutMI.setOpcode(NewOpc); 229 OutMI.addOperand(OutMI.getOperand(0)); 230 OutMI.addOperand(OutMI.getOperand(0)); 231} 232 233/// \brief Simplify FOO $imm, %{al,ax,eax,rax} to FOO $imm, for instruction with 234/// a short fixed-register form. 235static void SimplifyShortImmForm(MCInst &Inst, unsigned Opcode) { 236 unsigned ImmOp = Inst.getNumOperands() - 1; 237 assert(Inst.getOperand(0).isReg() && Inst.getOperand(ImmOp).isImm() && 238 ((Inst.getNumOperands() == 3 && Inst.getOperand(1).isReg() && 239 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) || 240 Inst.getNumOperands() == 2) && "Unexpected instruction!"); 241 242 // Check whether the destination register can be fixed. 243 unsigned Reg = Inst.getOperand(0).getReg(); 244 if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX) 245 return; 246 247 // If so, rewrite the instruction. 248 MCOperand Saved = Inst.getOperand(ImmOp); 249 Inst = MCInst(); 250 Inst.setOpcode(Opcode); 251 Inst.addOperand(Saved); 252} 253 254/// \brief Simplify things like MOV32rm to MOV32o32a. 255static void SimplifyShortMoveForm(X86AsmPrinter &Printer, MCInst &Inst, 256 unsigned Opcode) { 257 // Don't make these simplifications in 64-bit mode; other assemblers don't 258 // perform them because they make the code larger. 259 if (Printer.getSubtarget().is64Bit()) 260 return; 261 262 bool IsStore = Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg(); 263 unsigned AddrBase = IsStore; 264 unsigned RegOp = IsStore ? 0 : 5; 265 unsigned AddrOp = AddrBase + 3; 266 assert(Inst.getNumOperands() == 6 && Inst.getOperand(RegOp).isReg() && 267 Inst.getOperand(AddrBase + 0).isReg() && // base 268 Inst.getOperand(AddrBase + 1).isImm() && // scale 269 Inst.getOperand(AddrBase + 2).isReg() && // index register 270 (Inst.getOperand(AddrOp).isExpr() || // address 271 Inst.getOperand(AddrOp).isImm())&& 272 Inst.getOperand(AddrBase + 4).isReg() && // segment 273 "Unexpected instruction!"); 274 275 // Check whether the destination register can be fixed. 276 unsigned Reg = Inst.getOperand(RegOp).getReg(); 277 if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX) 278 return; 279 280 // Check whether this is an absolute address. 281 // FIXME: We know TLVP symbol refs aren't, but there should be a better way 282 // to do this here. 283 bool Absolute = true; 284 if (Inst.getOperand(AddrOp).isExpr()) { 285 const MCExpr *MCE = Inst.getOperand(AddrOp).getExpr(); 286 if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(MCE)) 287 if (SRE->getKind() == MCSymbolRefExpr::VK_TLVP) 288 Absolute = false; 289 } 290 291 if (Absolute && 292 (Inst.getOperand(AddrBase + 0).getReg() != 0 || 293 Inst.getOperand(AddrBase + 2).getReg() != 0 || 294 Inst.getOperand(AddrBase + 4).getReg() != 0 || 295 Inst.getOperand(AddrBase + 1).getImm() != 1)) 296 return; 297 298 // If so, rewrite the instruction. 299 MCOperand Saved = Inst.getOperand(AddrOp); 300 Inst = MCInst(); 301 Inst.setOpcode(Opcode); 302 Inst.addOperand(Saved); 303} 304 305void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { 306 OutMI.setOpcode(MI->getOpcode()); 307 308 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 309 const MachineOperand &MO = MI->getOperand(i); 310 311 MCOperand MCOp; 312 switch (MO.getType()) { 313 default: 314 MI->dump(); 315 llvm_unreachable("unknown operand type"); 316 case MachineOperand::MO_Register: 317 // Ignore all implicit register operands. 318 if (MO.isImplicit()) continue; 319 MCOp = MCOperand::CreateReg(MO.getReg()); 320 break; 321 case MachineOperand::MO_Immediate: 322 MCOp = MCOperand::CreateImm(MO.getImm()); 323 break; 324 case MachineOperand::MO_MachineBasicBlock: 325 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 326 MO.getMBB()->getSymbol(), Ctx)); 327 break; 328 case MachineOperand::MO_GlobalAddress: 329 MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO)); 330 break; 331 case MachineOperand::MO_ExternalSymbol: 332 MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO)); 333 break; 334 case MachineOperand::MO_JumpTableIndex: 335 MCOp = LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex())); 336 break; 337 case MachineOperand::MO_ConstantPoolIndex: 338 MCOp = LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex())); 339 break; 340 case MachineOperand::MO_BlockAddress: 341 MCOp = LowerSymbolOperand(MO, 342 AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress())); 343 break; 344 } 345 346 OutMI.addOperand(MCOp); 347 } 348 349 // Handle a few special cases to eliminate operand modifiers. 350 switch (OutMI.getOpcode()) { 351 case X86::LEA64_32r: // Handle 'subreg rewriting' for the lea64_32mem operand. 352 lower_lea64_32mem(&OutMI, 1); 353 // FALL THROUGH. 354 case X86::LEA64r: 355 case X86::LEA16r: 356 case X86::LEA32r: 357 // LEA should have a segment register, but it must be empty. 358 assert(OutMI.getNumOperands() == 1+X86::AddrNumOperands && 359 "Unexpected # of LEA operands"); 360 assert(OutMI.getOperand(1+X86::AddrSegmentReg).getReg() == 0 && 361 "LEA has segment specified!"); 362 break; 363 case X86::MOVZX16rr8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr8); break; 364 case X86::MOVZX16rm8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm8); break; 365 case X86::MOVSX16rr8: LowerSubReg32_Op0(OutMI, X86::MOVSX32rr8); break; 366 case X86::MOVSX16rm8: LowerSubReg32_Op0(OutMI, X86::MOVSX32rm8); break; 367 case X86::MOVZX64rr32: LowerSubReg32_Op0(OutMI, X86::MOV32rr); break; 368 case X86::MOVZX64rm32: LowerSubReg32_Op0(OutMI, X86::MOV32rm); break; 369 case X86::MOV64ri64i32: LowerSubReg32_Op0(OutMI, X86::MOV32ri); break; 370 case X86::MOVZX64rr8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr8); break; 371 case X86::MOVZX64rm8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm8); break; 372 case X86::MOVZX64rr16: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr16); break; 373 case X86::MOVZX64rm16: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm16); break; 374 case X86::SETB_C8r: LowerUnaryToTwoAddr(OutMI, X86::SBB8rr); break; 375 case X86::SETB_C16r: LowerUnaryToTwoAddr(OutMI, X86::SBB16rr); break; 376 case X86::SETB_C32r: LowerUnaryToTwoAddr(OutMI, X86::SBB32rr); break; 377 case X86::SETB_C64r: LowerUnaryToTwoAddr(OutMI, X86::SBB64rr); break; 378 case X86::MOV8r0: LowerUnaryToTwoAddr(OutMI, X86::XOR8rr); break; 379 case X86::MOV32r0: LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); break; 380 case X86::FsFLD0SS: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break; 381 case X86::FsFLD0SD: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break; 382 case X86::V_SET0PS: LowerUnaryToTwoAddr(OutMI, X86::XORPSrr); break; 383 case X86::V_SET0PD: LowerUnaryToTwoAddr(OutMI, X86::XORPDrr); break; 384 case X86::V_SET0PI: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break; 385 case X86::V_SETALLONES: LowerUnaryToTwoAddr(OutMI, X86::PCMPEQDrr); break; 386 case X86::AVX_SET0PS: LowerUnaryToTwoAddr(OutMI, X86::VXORPSrr); break; 387 case X86::AVX_SET0PSY: LowerUnaryToTwoAddr(OutMI, X86::VXORPSYrr); break; 388 case X86::AVX_SET0PD: LowerUnaryToTwoAddr(OutMI, X86::VXORPDrr); break; 389 case X86::AVX_SET0PDY: LowerUnaryToTwoAddr(OutMI, X86::VXORPDYrr); break; 390 case X86::AVX_SET0PI: LowerUnaryToTwoAddr(OutMI, X86::VPXORrr); break; 391 392 case X86::MOV16r0: 393 LowerSubReg32_Op0(OutMI, X86::MOV32r0); // MOV16r0 -> MOV32r0 394 LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); // MOV32r0 -> XOR32rr 395 break; 396 case X86::MOV64r0: 397 LowerSubReg32_Op0(OutMI, X86::MOV32r0); // MOV64r0 -> MOV32r0 398 LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); // MOV32r0 -> XOR32rr 399 break; 400 401 // TAILJMPr64, [WIN]CALL64r, [WIN]CALL64pcrel32 - These instructions have 402 // register inputs modeled as normal uses instead of implicit uses. As such, 403 // truncate off all but the first operand (the callee). FIXME: Change isel. 404 case X86::TAILJMPr64: 405 case X86::CALL64r: 406 case X86::CALL64pcrel32: 407 case X86::WINCALL64r: 408 case X86::WINCALL64pcrel32: { 409 unsigned Opcode = OutMI.getOpcode(); 410 MCOperand Saved = OutMI.getOperand(0); 411 OutMI = MCInst(); 412 OutMI.setOpcode(Opcode); 413 OutMI.addOperand(Saved); 414 break; 415 } 416 417 // TAILJMPd, TAILJMPd64 - Lower to the correct jump instructions. 418 case X86::TAILJMPr: 419 case X86::TAILJMPd: 420 case X86::TAILJMPd64: { 421 unsigned Opcode; 422 switch (OutMI.getOpcode()) { 423 default: assert(0 && "Invalid opcode"); 424 case X86::TAILJMPr: Opcode = X86::JMP32r; break; 425 case X86::TAILJMPd: 426 case X86::TAILJMPd64: Opcode = X86::JMP_1; break; 427 } 428 429 MCOperand Saved = OutMI.getOperand(0); 430 OutMI = MCInst(); 431 OutMI.setOpcode(Opcode); 432 OutMI.addOperand(Saved); 433 break; 434 } 435 436 // The assembler backend wants to see branches in their small form and relax 437 // them to their large form. The JIT can only handle the large form because 438 // it does not do relaxation. For now, translate the large form to the 439 // small one here. 440 case X86::JMP_4: OutMI.setOpcode(X86::JMP_1); break; 441 case X86::JO_4: OutMI.setOpcode(X86::JO_1); break; 442 case X86::JNO_4: OutMI.setOpcode(X86::JNO_1); break; 443 case X86::JB_4: OutMI.setOpcode(X86::JB_1); break; 444 case X86::JAE_4: OutMI.setOpcode(X86::JAE_1); break; 445 case X86::JE_4: OutMI.setOpcode(X86::JE_1); break; 446 case X86::JNE_4: OutMI.setOpcode(X86::JNE_1); break; 447 case X86::JBE_4: OutMI.setOpcode(X86::JBE_1); break; 448 case X86::JA_4: OutMI.setOpcode(X86::JA_1); break; 449 case X86::JS_4: OutMI.setOpcode(X86::JS_1); break; 450 case X86::JNS_4: OutMI.setOpcode(X86::JNS_1); break; 451 case X86::JP_4: OutMI.setOpcode(X86::JP_1); break; 452 case X86::JNP_4: OutMI.setOpcode(X86::JNP_1); break; 453 case X86::JL_4: OutMI.setOpcode(X86::JL_1); break; 454 case X86::JGE_4: OutMI.setOpcode(X86::JGE_1); break; 455 case X86::JLE_4: OutMI.setOpcode(X86::JLE_1); break; 456 case X86::JG_4: OutMI.setOpcode(X86::JG_1); break; 457 458 // We don't currently select the correct instruction form for instructions 459 // which have a short %eax, etc. form. Handle this by custom lowering, for 460 // now. 461 // 462 // Note, we are currently not handling the following instructions: 463 // MOV64ao8, MOV64o8a 464 // XCHG16ar, XCHG32ar, XCHG64ar 465 case X86::MOV8mr_NOREX: 466 case X86::MOV8mr: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV8ao8); break; 467 case X86::MOV8rm_NOREX: 468 case X86::MOV8rm: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV8o8a); break; 469 case X86::MOV16mr: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV16ao16); break; 470 case X86::MOV16rm: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV16o16a); break; 471 case X86::MOV32mr: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV32ao32); break; 472 case X86::MOV32rm: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV32o32a); break; 473 474 case X86::ADC8ri: SimplifyShortImmForm(OutMI, X86::ADC8i8); break; 475 case X86::ADC16ri: SimplifyShortImmForm(OutMI, X86::ADC16i16); break; 476 case X86::ADC32ri: SimplifyShortImmForm(OutMI, X86::ADC32i32); break; 477 case X86::ADC64ri32: SimplifyShortImmForm(OutMI, X86::ADC64i32); break; 478 case X86::ADD8ri: SimplifyShortImmForm(OutMI, X86::ADD8i8); break; 479 case X86::ADD16ri: SimplifyShortImmForm(OutMI, X86::ADD16i16); break; 480 case X86::ADD32ri: SimplifyShortImmForm(OutMI, X86::ADD32i32); break; 481 case X86::ADD64ri32: SimplifyShortImmForm(OutMI, X86::ADD64i32); break; 482 case X86::AND8ri: SimplifyShortImmForm(OutMI, X86::AND8i8); break; 483 case X86::AND16ri: SimplifyShortImmForm(OutMI, X86::AND16i16); break; 484 case X86::AND32ri: SimplifyShortImmForm(OutMI, X86::AND32i32); break; 485 case X86::AND64ri32: SimplifyShortImmForm(OutMI, X86::AND64i32); break; 486 case X86::CMP8ri: SimplifyShortImmForm(OutMI, X86::CMP8i8); break; 487 case X86::CMP16ri: SimplifyShortImmForm(OutMI, X86::CMP16i16); break; 488 case X86::CMP32ri: SimplifyShortImmForm(OutMI, X86::CMP32i32); break; 489 case X86::CMP64ri32: SimplifyShortImmForm(OutMI, X86::CMP64i32); break; 490 case X86::OR8ri: SimplifyShortImmForm(OutMI, X86::OR8i8); break; 491 case X86::OR16ri: SimplifyShortImmForm(OutMI, X86::OR16i16); break; 492 case X86::OR32ri: SimplifyShortImmForm(OutMI, X86::OR32i32); break; 493 case X86::OR64ri32: SimplifyShortImmForm(OutMI, X86::OR64i32); break; 494 case X86::SBB8ri: SimplifyShortImmForm(OutMI, X86::SBB8i8); break; 495 case X86::SBB16ri: SimplifyShortImmForm(OutMI, X86::SBB16i16); break; 496 case X86::SBB32ri: SimplifyShortImmForm(OutMI, X86::SBB32i32); break; 497 case X86::SBB64ri32: SimplifyShortImmForm(OutMI, X86::SBB64i32); break; 498 case X86::SUB8ri: SimplifyShortImmForm(OutMI, X86::SUB8i8); break; 499 case X86::SUB16ri: SimplifyShortImmForm(OutMI, X86::SUB16i16); break; 500 case X86::SUB32ri: SimplifyShortImmForm(OutMI, X86::SUB32i32); break; 501 case X86::SUB64ri32: SimplifyShortImmForm(OutMI, X86::SUB64i32); break; 502 case X86::TEST8ri: SimplifyShortImmForm(OutMI, X86::TEST8i8); break; 503 case X86::TEST16ri: SimplifyShortImmForm(OutMI, X86::TEST16i16); break; 504 case X86::TEST32ri: SimplifyShortImmForm(OutMI, X86::TEST32i32); break; 505 case X86::TEST64ri32: SimplifyShortImmForm(OutMI, X86::TEST64i32); break; 506 case X86::XOR8ri: SimplifyShortImmForm(OutMI, X86::XOR8i8); break; 507 case X86::XOR16ri: SimplifyShortImmForm(OutMI, X86::XOR16i16); break; 508 case X86::XOR32ri: SimplifyShortImmForm(OutMI, X86::XOR32i32); break; 509 case X86::XOR64ri32: SimplifyShortImmForm(OutMI, X86::XOR64i32); break; 510 } 511} 512 513 514void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { 515 X86MCInstLower MCInstLowering(Mang, *MF, *this); 516 switch (MI->getOpcode()) { 517 case TargetOpcode::DBG_VALUE: 518 if (isVerbose() && OutStreamer.hasRawTextSupport()) { 519 std::string TmpStr; 520 raw_string_ostream OS(TmpStr); 521 PrintDebugValueComment(MI, OS); 522 OutStreamer.EmitRawText(StringRef(OS.str())); 523 } 524 return; 525 526 // Emit nothing here but a comment if we can. 527 case X86::Int_MemBarrier: 528 if (OutStreamer.hasRawTextSupport()) 529 OutStreamer.EmitRawText(StringRef("\t#MEMBARRIER")); 530 return; 531 532 case X86::TAILJMPr: 533 case X86::TAILJMPd: 534 case X86::TAILJMPd64: 535 // Lower these as normal, but add some comments. 536 OutStreamer.AddComment("TAILCALL"); 537 break; 538 539 case X86::MOVPC32r: { 540 MCInst TmpInst; 541 // This is a pseudo op for a two instruction sequence with a label, which 542 // looks like: 543 // call "L1$pb" 544 // "L1$pb": 545 // popl %esi 546 547 // Emit the call. 548 MCSymbol *PICBase = MCInstLowering.GetPICBaseSymbol(); 549 TmpInst.setOpcode(X86::CALLpcrel32); 550 // FIXME: We would like an efficient form for this, so we don't have to do a 551 // lot of extra uniquing. 552 TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(PICBase, 553 OutContext))); 554 OutStreamer.EmitInstruction(TmpInst); 555 556 // Emit the label. 557 OutStreamer.EmitLabel(PICBase); 558 559 // popl $reg 560 TmpInst.setOpcode(X86::POP32r); 561 TmpInst.getOperand(0) = MCOperand::CreateReg(MI->getOperand(0).getReg()); 562 OutStreamer.EmitInstruction(TmpInst); 563 return; 564 } 565 566 case X86::ADD32ri: { 567 // Lower the MO_GOT_ABSOLUTE_ADDRESS form of ADD32ri. 568 if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS) 569 break; 570 571 // Okay, we have something like: 572 // EAX = ADD32ri EAX, MO_GOT_ABSOLUTE_ADDRESS(@MYGLOBAL) 573 574 // For this, we want to print something like: 575 // MYGLOBAL + (. - PICBASE) 576 // However, we can't generate a ".", so just emit a new label here and refer 577 // to it. 578 MCSymbol *DotSym = OutContext.CreateTempSymbol(); 579 OutStreamer.EmitLabel(DotSym); 580 581 // Now that we have emitted the label, lower the complex operand expression. 582 MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2)); 583 584 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 585 const MCExpr *PICBase = 586 MCSymbolRefExpr::Create(MCInstLowering.GetPICBaseSymbol(), OutContext); 587 DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, OutContext); 588 589 DotExpr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(OpSym,OutContext), 590 DotExpr, OutContext); 591 592 MCInst TmpInst; 593 TmpInst.setOpcode(X86::ADD32ri); 594 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 595 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 596 TmpInst.addOperand(MCOperand::CreateExpr(DotExpr)); 597 OutStreamer.EmitInstruction(TmpInst); 598 return; 599 } 600 } 601 602 MCInst TmpInst; 603 MCInstLowering.Lower(MI, TmpInst); 604 OutStreamer.EmitInstruction(TmpInst); 605} 606 607