1212793Sdim//===-- X86MCInstLower.cpp - Convert X86 MachineInstr to an MCInst --------===// 2212793Sdim// 3212793Sdim// The LLVM Compiler Infrastructure 4212793Sdim// 5212793Sdim// This file is distributed under the University of Illinois Open Source 6212793Sdim// License. See LICENSE.TXT for details. 7212793Sdim// 8212793Sdim//===----------------------------------------------------------------------===// 9212793Sdim// 10212793Sdim// This file contains code to lower X86 MachineInstrs to their corresponding 11212793Sdim// MCInst records. 12212793Sdim// 13212793Sdim//===----------------------------------------------------------------------===// 14212793Sdim 15212793Sdim#include "X86AsmPrinter.h" 16252723Sdim#include "InstPrinter/X86ATTInstPrinter.h" 17212793Sdim#include "X86COFFMachineModuleInfo.h" 18252723Sdim#include "llvm/ADT/SmallString.h" 19212793Sdim#include "llvm/CodeGen/MachineModuleInfoImpls.h" 20263509Sdim#include "llvm/CodeGen/StackMaps.h" 21252723Sdim#include "llvm/IR/Type.h" 22224145Sdim#include "llvm/MC/MCAsmInfo.h" 23212793Sdim#include "llvm/MC/MCContext.h" 24212793Sdim#include "llvm/MC/MCExpr.h" 25212793Sdim#include "llvm/MC/MCInst.h" 26252723Sdim#include "llvm/MC/MCInstBuilder.h" 27212793Sdim#include "llvm/MC/MCStreamer.h" 28212793Sdim#include "llvm/MC/MCSymbol.h" 29252723Sdim#include "llvm/Support/FormattedStream.h" 30212793Sdim#include "llvm/Target/Mangler.h" 31212793Sdimusing namespace llvm; 32212793Sdim 33245431Sdimnamespace { 34245431Sdim 35245431Sdim/// X86MCInstLower - This class is used to lower an MachineInstr into an MCInst. 36245431Sdimclass X86MCInstLower { 37245431Sdim MCContext &Ctx; 38245431Sdim const MachineFunction &MF; 39245431Sdim const TargetMachine &TM; 40245431Sdim const MCAsmInfo &MAI; 41245431Sdim X86AsmPrinter &AsmPrinter; 42245431Sdimpublic: 43263509Sdim X86MCInstLower(const MachineFunction &MF, X86AsmPrinter &asmprinter); 44245431Sdim 45245431Sdim void Lower(const MachineInstr *MI, MCInst &OutMI) const; 46245431Sdim 47245431Sdim MCSymbol *GetSymbolFromOperand(const MachineOperand &MO) const; 48245431Sdim MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const; 49245431Sdim 50245431Sdimprivate: 51245431Sdim MachineModuleInfoMachO &getMachOMMI() const; 52263509Sdim Mangler *getMang() const { 53263509Sdim return AsmPrinter.Mang; 54263509Sdim } 55245431Sdim}; 56245431Sdim 57245431Sdim} // end anonymous namespace 58245431Sdim 59263509SdimX86MCInstLower::X86MCInstLower(const MachineFunction &mf, 60212793Sdim X86AsmPrinter &asmprinter) 61263509Sdim: Ctx(mf.getContext()), MF(mf), TM(mf.getTarget()), 62212793Sdim MAI(*TM.getMCAsmInfo()), AsmPrinter(asmprinter) {} 63212793Sdim 64212793SdimMachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const { 65212793Sdim return MF.getMMI().getObjFileInfo<MachineModuleInfoMachO>(); 66212793Sdim} 67212793Sdim 68212793Sdim 69212793Sdim/// GetSymbolFromOperand - Lower an MO_GlobalAddress or MO_ExternalSymbol 70212793Sdim/// operand to an MCSymbol. 71212793SdimMCSymbol *X86MCInstLower:: 72212793SdimGetSymbolFromOperand(const MachineOperand &MO) const { 73245431Sdim assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) && "Isn't a symbol reference"); 74212793Sdim 75212793Sdim SmallString<128> Name; 76245431Sdim 77245431Sdim if (MO.isGlobal()) { 78212793Sdim const GlobalValue *GV = MO.getGlobal(); 79212793Sdim bool isImplicitlyPrivate = false; 80212793Sdim if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB || 81212793Sdim MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || 82212793Sdim MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE || 83212793Sdim MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE) 84212793Sdim isImplicitlyPrivate = true; 85245431Sdim 86263509Sdim getMang()->getNameWithPrefix(Name, GV, isImplicitlyPrivate); 87245431Sdim } else if (MO.isSymbol()) { 88245431Sdim Name += MAI.getGlobalPrefix(); 89245431Sdim Name += MO.getSymbolName(); 90245431Sdim } else if (MO.isMBB()) { 91245431Sdim Name += MO.getMBB()->getSymbol()->getName(); 92212793Sdim } 93212793Sdim 94212793Sdim // If the target flags on the operand changes the name of the symbol, do that 95212793Sdim // before we return the symbol. 96212793Sdim switch (MO.getTargetFlags()) { 97212793Sdim default: break; 98212793Sdim case X86II::MO_DLLIMPORT: { 99212793Sdim // Handle dllimport linkage. 100212793Sdim const char *Prefix = "__imp_"; 101212793Sdim Name.insert(Name.begin(), Prefix, Prefix+strlen(Prefix)); 102212793Sdim break; 103212793Sdim } 104212793Sdim case X86II::MO_DARWIN_NONLAZY: 105212793Sdim case X86II::MO_DARWIN_NONLAZY_PIC_BASE: { 106212793Sdim Name += "$non_lazy_ptr"; 107212793Sdim MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 108212793Sdim 109212793Sdim MachineModuleInfoImpl::StubValueTy &StubSym = 110212793Sdim getMachOMMI().getGVStubEntry(Sym); 111212793Sdim if (StubSym.getPointer() == 0) { 112212793Sdim assert(MO.isGlobal() && "Extern symbol not handled yet"); 113212793Sdim StubSym = 114212793Sdim MachineModuleInfoImpl:: 115263509Sdim StubValueTy(AsmPrinter.getSymbol(MO.getGlobal()), 116212793Sdim !MO.getGlobal()->hasInternalLinkage()); 117212793Sdim } 118212793Sdim return Sym; 119212793Sdim } 120212793Sdim case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: { 121212793Sdim Name += "$non_lazy_ptr"; 122212793Sdim MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 123212793Sdim MachineModuleInfoImpl::StubValueTy &StubSym = 124212793Sdim getMachOMMI().getHiddenGVStubEntry(Sym); 125212793Sdim if (StubSym.getPointer() == 0) { 126212793Sdim assert(MO.isGlobal() && "Extern symbol not handled yet"); 127212793Sdim StubSym = 128212793Sdim MachineModuleInfoImpl:: 129263509Sdim StubValueTy(AsmPrinter.getSymbol(MO.getGlobal()), 130212793Sdim !MO.getGlobal()->hasInternalLinkage()); 131212793Sdim } 132212793Sdim return Sym; 133212793Sdim } 134212793Sdim case X86II::MO_DARWIN_STUB: { 135212793Sdim Name += "$stub"; 136212793Sdim MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 137212793Sdim MachineModuleInfoImpl::StubValueTy &StubSym = 138212793Sdim getMachOMMI().getFnStubEntry(Sym); 139212793Sdim if (StubSym.getPointer()) 140212793Sdim return Sym; 141245431Sdim 142212793Sdim if (MO.isGlobal()) { 143212793Sdim StubSym = 144212793Sdim MachineModuleInfoImpl:: 145263509Sdim StubValueTy(AsmPrinter.getSymbol(MO.getGlobal()), 146212793Sdim !MO.getGlobal()->hasInternalLinkage()); 147212793Sdim } else { 148212793Sdim Name.erase(Name.end()-5, Name.end()); 149212793Sdim StubSym = 150212793Sdim MachineModuleInfoImpl:: 151212793Sdim StubValueTy(Ctx.GetOrCreateSymbol(Name.str()), false); 152212793Sdim } 153212793Sdim return Sym; 154212793Sdim } 155212793Sdim } 156212793Sdim 157212793Sdim return Ctx.GetOrCreateSymbol(Name.str()); 158212793Sdim} 159212793Sdim 160212793SdimMCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO, 161212793Sdim MCSymbol *Sym) const { 162212793Sdim // FIXME: We would like an efficient form for this, so we don't have to do a 163212793Sdim // lot of extra uniquing. 164212793Sdim const MCExpr *Expr = 0; 165212793Sdim MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; 166245431Sdim 167212793Sdim switch (MO.getTargetFlags()) { 168212793Sdim default: llvm_unreachable("Unknown target flag on GV operand"); 169212793Sdim case X86II::MO_NO_FLAG: // No flag. 170212793Sdim // These affect the name of the symbol, not any suffix. 171212793Sdim case X86II::MO_DARWIN_NONLAZY: 172212793Sdim case X86II::MO_DLLIMPORT: 173212793Sdim case X86II::MO_DARWIN_STUB: 174212793Sdim break; 175245431Sdim 176212793Sdim case X86II::MO_TLVP: RefKind = MCSymbolRefExpr::VK_TLVP; break; 177212793Sdim case X86II::MO_TLVP_PIC_BASE: 178212793Sdim Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx); 179212793Sdim // Subtract the pic base. 180212793Sdim Expr = MCBinaryExpr::CreateSub(Expr, 181218893Sdim MCSymbolRefExpr::Create(MF.getPICBaseSymbol(), 182212793Sdim Ctx), 183212793Sdim Ctx); 184212793Sdim break; 185235633Sdim case X86II::MO_SECREL: RefKind = MCSymbolRefExpr::VK_SECREL; break; 186212793Sdim case X86II::MO_TLSGD: RefKind = MCSymbolRefExpr::VK_TLSGD; break; 187245431Sdim case X86II::MO_TLSLD: RefKind = MCSymbolRefExpr::VK_TLSLD; break; 188245431Sdim case X86II::MO_TLSLDM: RefKind = MCSymbolRefExpr::VK_TLSLDM; break; 189212793Sdim case X86II::MO_GOTTPOFF: RefKind = MCSymbolRefExpr::VK_GOTTPOFF; break; 190212793Sdim case X86II::MO_INDNTPOFF: RefKind = MCSymbolRefExpr::VK_INDNTPOFF; break; 191212793Sdim case X86II::MO_TPOFF: RefKind = MCSymbolRefExpr::VK_TPOFF; break; 192245431Sdim case X86II::MO_DTPOFF: RefKind = MCSymbolRefExpr::VK_DTPOFF; break; 193212793Sdim case X86II::MO_NTPOFF: RefKind = MCSymbolRefExpr::VK_NTPOFF; break; 194245431Sdim case X86II::MO_GOTNTPOFF: RefKind = MCSymbolRefExpr::VK_GOTNTPOFF; break; 195212793Sdim case X86II::MO_GOTPCREL: RefKind = MCSymbolRefExpr::VK_GOTPCREL; break; 196212793Sdim case X86II::MO_GOT: RefKind = MCSymbolRefExpr::VK_GOT; break; 197212793Sdim case X86II::MO_GOTOFF: RefKind = MCSymbolRefExpr::VK_GOTOFF; break; 198212793Sdim case X86II::MO_PLT: RefKind = MCSymbolRefExpr::VK_PLT; break; 199212793Sdim case X86II::MO_PIC_BASE_OFFSET: 200212793Sdim case X86II::MO_DARWIN_NONLAZY_PIC_BASE: 201212793Sdim case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: 202212793Sdim Expr = MCSymbolRefExpr::Create(Sym, Ctx); 203212793Sdim // Subtract the pic base. 204245431Sdim Expr = MCBinaryExpr::CreateSub(Expr, 205218893Sdim MCSymbolRefExpr::Create(MF.getPICBaseSymbol(), Ctx), 206212793Sdim Ctx); 207212793Sdim if (MO.isJTI() && MAI.hasSetDirective()) { 208212793Sdim // If .set directive is supported, use it to reduce the number of 209212793Sdim // relocations the assembler will generate for differences between 210212793Sdim // local labels. This is only safe when the symbols are in the same 211212793Sdim // section so we are restricting it to jumptable references. 212212793Sdim MCSymbol *Label = Ctx.CreateTempSymbol(); 213212793Sdim AsmPrinter.OutStreamer.EmitAssignment(Label, Expr); 214212793Sdim Expr = MCSymbolRefExpr::Create(Label, Ctx); 215212793Sdim } 216212793Sdim break; 217212793Sdim } 218245431Sdim 219212793Sdim if (Expr == 0) 220212793Sdim Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx); 221245431Sdim 222245431Sdim if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) 223212793Sdim Expr = MCBinaryExpr::CreateAdd(Expr, 224212793Sdim MCConstantExpr::Create(MO.getOffset(), Ctx), 225212793Sdim Ctx); 226212793Sdim return MCOperand::CreateExpr(Expr); 227212793Sdim} 228212793Sdim 229212793Sdim 230212793Sdim/// LowerUnaryToTwoAddr - R = setb -> R = sbb R, R 231212793Sdimstatic void LowerUnaryToTwoAddr(MCInst &OutMI, unsigned NewOpc) { 232212793Sdim OutMI.setOpcode(NewOpc); 233212793Sdim OutMI.addOperand(OutMI.getOperand(0)); 234212793Sdim OutMI.addOperand(OutMI.getOperand(0)); 235212793Sdim} 236212793Sdim 237212793Sdim/// \brief Simplify FOO $imm, %{al,ax,eax,rax} to FOO $imm, for instruction with 238212793Sdim/// a short fixed-register form. 239212793Sdimstatic void SimplifyShortImmForm(MCInst &Inst, unsigned Opcode) { 240212793Sdim unsigned ImmOp = Inst.getNumOperands() - 1; 241235633Sdim assert(Inst.getOperand(0).isReg() && 242235633Sdim (Inst.getOperand(ImmOp).isImm() || Inst.getOperand(ImmOp).isExpr()) && 243212793Sdim ((Inst.getNumOperands() == 3 && Inst.getOperand(1).isReg() && 244212793Sdim Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) || 245212793Sdim Inst.getNumOperands() == 2) && "Unexpected instruction!"); 246212793Sdim 247212793Sdim // Check whether the destination register can be fixed. 248212793Sdim unsigned Reg = Inst.getOperand(0).getReg(); 249212793Sdim if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX) 250212793Sdim return; 251212793Sdim 252212793Sdim // If so, rewrite the instruction. 253212793Sdim MCOperand Saved = Inst.getOperand(ImmOp); 254212793Sdim Inst = MCInst(); 255212793Sdim Inst.setOpcode(Opcode); 256212793Sdim Inst.addOperand(Saved); 257212793Sdim} 258212793Sdim 259263509Sdim/// \brief If a movsx instruction has a shorter encoding for the used register 260263509Sdim/// simplify the instruction to use it instead. 261263509Sdimstatic void SimplifyMOVSX(MCInst &Inst) { 262263509Sdim unsigned NewOpcode = 0; 263263509Sdim unsigned Op0 = Inst.getOperand(0).getReg(), Op1 = Inst.getOperand(1).getReg(); 264263509Sdim switch (Inst.getOpcode()) { 265263509Sdim default: 266263509Sdim llvm_unreachable("Unexpected instruction!"); 267263509Sdim case X86::MOVSX16rr8: // movsbw %al, %ax --> cbtw 268263509Sdim if (Op0 == X86::AX && Op1 == X86::AL) 269263509Sdim NewOpcode = X86::CBW; 270263509Sdim break; 271263509Sdim case X86::MOVSX32rr16: // movswl %ax, %eax --> cwtl 272263509Sdim if (Op0 == X86::EAX && Op1 == X86::AX) 273263509Sdim NewOpcode = X86::CWDE; 274263509Sdim break; 275263509Sdim case X86::MOVSX64rr32: // movslq %eax, %rax --> cltq 276263509Sdim if (Op0 == X86::RAX && Op1 == X86::EAX) 277263509Sdim NewOpcode = X86::CDQE; 278263509Sdim break; 279263509Sdim } 280263509Sdim 281263509Sdim if (NewOpcode != 0) { 282263509Sdim Inst = MCInst(); 283263509Sdim Inst.setOpcode(NewOpcode); 284263509Sdim } 285263509Sdim} 286263509Sdim 287212793Sdim/// \brief Simplify things like MOV32rm to MOV32o32a. 288212793Sdimstatic void SimplifyShortMoveForm(X86AsmPrinter &Printer, MCInst &Inst, 289212793Sdim unsigned Opcode) { 290212793Sdim // Don't make these simplifications in 64-bit mode; other assemblers don't 291212793Sdim // perform them because they make the code larger. 292212793Sdim if (Printer.getSubtarget().is64Bit()) 293212793Sdim return; 294212793Sdim 295212793Sdim bool IsStore = Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg(); 296212793Sdim unsigned AddrBase = IsStore; 297212793Sdim unsigned RegOp = IsStore ? 0 : 5; 298212793Sdim unsigned AddrOp = AddrBase + 3; 299212793Sdim assert(Inst.getNumOperands() == 6 && Inst.getOperand(RegOp).isReg() && 300212793Sdim Inst.getOperand(AddrBase + 0).isReg() && // base 301212793Sdim Inst.getOperand(AddrBase + 1).isImm() && // scale 302212793Sdim Inst.getOperand(AddrBase + 2).isReg() && // index register 303212793Sdim (Inst.getOperand(AddrOp).isExpr() || // address 304212793Sdim Inst.getOperand(AddrOp).isImm())&& 305212793Sdim Inst.getOperand(AddrBase + 4).isReg() && // segment 306212793Sdim "Unexpected instruction!"); 307212793Sdim 308212793Sdim // Check whether the destination register can be fixed. 309212793Sdim unsigned Reg = Inst.getOperand(RegOp).getReg(); 310212793Sdim if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX) 311212793Sdim return; 312212793Sdim 313212793Sdim // Check whether this is an absolute address. 314245431Sdim // FIXME: We know TLVP symbol refs aren't, but there should be a better way 315212793Sdim // to do this here. 316212793Sdim bool Absolute = true; 317212793Sdim if (Inst.getOperand(AddrOp).isExpr()) { 318212793Sdim const MCExpr *MCE = Inst.getOperand(AddrOp).getExpr(); 319212793Sdim if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(MCE)) 320212793Sdim if (SRE->getKind() == MCSymbolRefExpr::VK_TLVP) 321212793Sdim Absolute = false; 322212793Sdim } 323245431Sdim 324212793Sdim if (Absolute && 325212793Sdim (Inst.getOperand(AddrBase + 0).getReg() != 0 || 326212793Sdim Inst.getOperand(AddrBase + 2).getReg() != 0 || 327212793Sdim Inst.getOperand(AddrBase + 4).getReg() != 0 || 328212793Sdim Inst.getOperand(AddrBase + 1).getImm() != 1)) 329212793Sdim return; 330212793Sdim 331212793Sdim // If so, rewrite the instruction. 332212793Sdim MCOperand Saved = Inst.getOperand(AddrOp); 333212793Sdim Inst = MCInst(); 334212793Sdim Inst.setOpcode(Opcode); 335212793Sdim Inst.addOperand(Saved); 336212793Sdim} 337212793Sdim 338212793Sdimvoid X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { 339212793Sdim OutMI.setOpcode(MI->getOpcode()); 340245431Sdim 341212793Sdim for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 342212793Sdim const MachineOperand &MO = MI->getOperand(i); 343245431Sdim 344212793Sdim MCOperand MCOp; 345212793Sdim switch (MO.getType()) { 346212793Sdim default: 347212793Sdim MI->dump(); 348212793Sdim llvm_unreachable("unknown operand type"); 349212793Sdim case MachineOperand::MO_Register: 350212793Sdim // Ignore all implicit register operands. 351212793Sdim if (MO.isImplicit()) continue; 352212793Sdim MCOp = MCOperand::CreateReg(MO.getReg()); 353212793Sdim break; 354212793Sdim case MachineOperand::MO_Immediate: 355212793Sdim MCOp = MCOperand::CreateImm(MO.getImm()); 356212793Sdim break; 357212793Sdim case MachineOperand::MO_MachineBasicBlock: 358212793Sdim case MachineOperand::MO_GlobalAddress: 359212793Sdim case MachineOperand::MO_ExternalSymbol: 360212793Sdim MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO)); 361212793Sdim break; 362212793Sdim case MachineOperand::MO_JumpTableIndex: 363212793Sdim MCOp = LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex())); 364212793Sdim break; 365212793Sdim case MachineOperand::MO_ConstantPoolIndex: 366212793Sdim MCOp = LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex())); 367212793Sdim break; 368212793Sdim case MachineOperand::MO_BlockAddress: 369212793Sdim MCOp = LowerSymbolOperand(MO, 370212793Sdim AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress())); 371212793Sdim break; 372235633Sdim case MachineOperand::MO_RegisterMask: 373235633Sdim // Ignore call clobbers. 374235633Sdim continue; 375212793Sdim } 376245431Sdim 377212793Sdim OutMI.addOperand(MCOp); 378212793Sdim } 379245431Sdim 380212793Sdim // Handle a few special cases to eliminate operand modifiers. 381218893SdimReSimplify: 382212793Sdim switch (OutMI.getOpcode()) { 383263509Sdim case X86::LEA64_32r: 384212793Sdim case X86::LEA64r: 385212793Sdim case X86::LEA16r: 386212793Sdim case X86::LEA32r: 387212793Sdim // LEA should have a segment register, but it must be empty. 388212793Sdim assert(OutMI.getNumOperands() == 1+X86::AddrNumOperands && 389212793Sdim "Unexpected # of LEA operands"); 390212793Sdim assert(OutMI.getOperand(1+X86::AddrSegmentReg).getReg() == 0 && 391212793Sdim "LEA has segment specified!"); 392212793Sdim break; 393212793Sdim case X86::MOV32r0: LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); break; 394212793Sdim 395263509Sdim case X86::MOV32ri64: 396263509Sdim OutMI.setOpcode(X86::MOV32ri); 397212793Sdim break; 398212793Sdim 399252723Sdim // Commute operands to get a smaller encoding by using VEX.R instead of VEX.B 400252723Sdim // if one of the registers is extended, but other isn't. 401252723Sdim case X86::VMOVAPDrr: 402252723Sdim case X86::VMOVAPDYrr: 403252723Sdim case X86::VMOVAPSrr: 404252723Sdim case X86::VMOVAPSYrr: 405252723Sdim case X86::VMOVDQArr: 406252723Sdim case X86::VMOVDQAYrr: 407252723Sdim case X86::VMOVDQUrr: 408252723Sdim case X86::VMOVDQUYrr: 409252723Sdim case X86::VMOVUPDrr: 410252723Sdim case X86::VMOVUPDYrr: 411252723Sdim case X86::VMOVUPSrr: 412252723Sdim case X86::VMOVUPSYrr: { 413252723Sdim if (!X86II::isX86_64ExtendedReg(OutMI.getOperand(0).getReg()) && 414252723Sdim X86II::isX86_64ExtendedReg(OutMI.getOperand(1).getReg())) { 415252723Sdim unsigned NewOpc; 416252723Sdim switch (OutMI.getOpcode()) { 417252723Sdim default: llvm_unreachable("Invalid opcode"); 418252723Sdim case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break; 419252723Sdim case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break; 420252723Sdim case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break; 421252723Sdim case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break; 422252723Sdim case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break; 423252723Sdim case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break; 424252723Sdim case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break; 425252723Sdim case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break; 426252723Sdim case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break; 427252723Sdim case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break; 428252723Sdim case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break; 429252723Sdim case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break; 430252723Sdim } 431252723Sdim OutMI.setOpcode(NewOpc); 432252723Sdim } 433252723Sdim break; 434252723Sdim } 435252723Sdim case X86::VMOVSDrr: 436252723Sdim case X86::VMOVSSrr: { 437252723Sdim if (!X86II::isX86_64ExtendedReg(OutMI.getOperand(0).getReg()) && 438252723Sdim X86II::isX86_64ExtendedReg(OutMI.getOperand(2).getReg())) { 439252723Sdim unsigned NewOpc; 440252723Sdim switch (OutMI.getOpcode()) { 441252723Sdim default: llvm_unreachable("Invalid opcode"); 442252723Sdim case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break; 443252723Sdim case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break; 444252723Sdim } 445252723Sdim OutMI.setOpcode(NewOpc); 446252723Sdim } 447252723Sdim break; 448252723Sdim } 449252723Sdim 450235633Sdim // TAILJMPr64, CALL64r, CALL64pcrel32 - These instructions have register 451235633Sdim // inputs modeled as normal uses instead of implicit uses. As such, truncate 452235633Sdim // off all but the first operand (the callee). FIXME: Change isel. 453212793Sdim case X86::TAILJMPr64: 454212793Sdim case X86::CALL64r: 455235633Sdim case X86::CALL64pcrel32: { 456212793Sdim unsigned Opcode = OutMI.getOpcode(); 457212793Sdim MCOperand Saved = OutMI.getOperand(0); 458212793Sdim OutMI = MCInst(); 459212793Sdim OutMI.setOpcode(Opcode); 460212793Sdim OutMI.addOperand(Saved); 461212793Sdim break; 462212793Sdim } 463212793Sdim 464218893Sdim case X86::EH_RETURN: 465218893Sdim case X86::EH_RETURN64: { 466218893Sdim OutMI = MCInst(); 467218893Sdim OutMI.setOpcode(X86::RET); 468218893Sdim break; 469218893Sdim } 470218893Sdim 471212793Sdim // TAILJMPd, TAILJMPd64 - Lower to the correct jump instructions. 472212793Sdim case X86::TAILJMPr: 473212793Sdim case X86::TAILJMPd: 474212793Sdim case X86::TAILJMPd64: { 475212793Sdim unsigned Opcode; 476212793Sdim switch (OutMI.getOpcode()) { 477235633Sdim default: llvm_unreachable("Invalid opcode"); 478212793Sdim case X86::TAILJMPr: Opcode = X86::JMP32r; break; 479212793Sdim case X86::TAILJMPd: 480212793Sdim case X86::TAILJMPd64: Opcode = X86::JMP_1; break; 481212793Sdim } 482245431Sdim 483212793Sdim MCOperand Saved = OutMI.getOperand(0); 484212793Sdim OutMI = MCInst(); 485212793Sdim OutMI.setOpcode(Opcode); 486212793Sdim OutMI.addOperand(Saved); 487212793Sdim break; 488212793Sdim } 489212793Sdim 490218893Sdim // These are pseudo-ops for OR to help with the OR->ADD transformation. We do 491218893Sdim // this with an ugly goto in case the resultant OR uses EAX and needs the 492218893Sdim // short form. 493218893Sdim case X86::ADD16rr_DB: OutMI.setOpcode(X86::OR16rr); goto ReSimplify; 494218893Sdim case X86::ADD32rr_DB: OutMI.setOpcode(X86::OR32rr); goto ReSimplify; 495218893Sdim case X86::ADD64rr_DB: OutMI.setOpcode(X86::OR64rr); goto ReSimplify; 496218893Sdim case X86::ADD16ri_DB: OutMI.setOpcode(X86::OR16ri); goto ReSimplify; 497218893Sdim case X86::ADD32ri_DB: OutMI.setOpcode(X86::OR32ri); goto ReSimplify; 498218893Sdim case X86::ADD64ri32_DB: OutMI.setOpcode(X86::OR64ri32); goto ReSimplify; 499218893Sdim case X86::ADD16ri8_DB: OutMI.setOpcode(X86::OR16ri8); goto ReSimplify; 500218893Sdim case X86::ADD32ri8_DB: OutMI.setOpcode(X86::OR32ri8); goto ReSimplify; 501218893Sdim case X86::ADD64ri8_DB: OutMI.setOpcode(X86::OR64ri8); goto ReSimplify; 502245431Sdim 503212793Sdim // The assembler backend wants to see branches in their small form and relax 504212793Sdim // them to their large form. The JIT can only handle the large form because 505212793Sdim // it does not do relaxation. For now, translate the large form to the 506212793Sdim // small one here. 507212793Sdim case X86::JMP_4: OutMI.setOpcode(X86::JMP_1); break; 508212793Sdim case X86::JO_4: OutMI.setOpcode(X86::JO_1); break; 509212793Sdim case X86::JNO_4: OutMI.setOpcode(X86::JNO_1); break; 510212793Sdim case X86::JB_4: OutMI.setOpcode(X86::JB_1); break; 511212793Sdim case X86::JAE_4: OutMI.setOpcode(X86::JAE_1); break; 512212793Sdim case X86::JE_4: OutMI.setOpcode(X86::JE_1); break; 513212793Sdim case X86::JNE_4: OutMI.setOpcode(X86::JNE_1); break; 514212793Sdim case X86::JBE_4: OutMI.setOpcode(X86::JBE_1); break; 515212793Sdim case X86::JA_4: OutMI.setOpcode(X86::JA_1); break; 516212793Sdim case X86::JS_4: OutMI.setOpcode(X86::JS_1); break; 517212793Sdim case X86::JNS_4: OutMI.setOpcode(X86::JNS_1); break; 518212793Sdim case X86::JP_4: OutMI.setOpcode(X86::JP_1); break; 519212793Sdim case X86::JNP_4: OutMI.setOpcode(X86::JNP_1); break; 520212793Sdim case X86::JL_4: OutMI.setOpcode(X86::JL_1); break; 521212793Sdim case X86::JGE_4: OutMI.setOpcode(X86::JGE_1); break; 522212793Sdim case X86::JLE_4: OutMI.setOpcode(X86::JLE_1); break; 523212793Sdim case X86::JG_4: OutMI.setOpcode(X86::JG_1); break; 524212793Sdim 525226890Sdim // Atomic load and store require a separate pseudo-inst because Acquire 526226890Sdim // implies mayStore and Release implies mayLoad; fix these to regular MOV 527226890Sdim // instructions here 528226890Sdim case X86::ACQUIRE_MOV8rm: OutMI.setOpcode(X86::MOV8rm); goto ReSimplify; 529226890Sdim case X86::ACQUIRE_MOV16rm: OutMI.setOpcode(X86::MOV16rm); goto ReSimplify; 530226890Sdim case X86::ACQUIRE_MOV32rm: OutMI.setOpcode(X86::MOV32rm); goto ReSimplify; 531226890Sdim case X86::ACQUIRE_MOV64rm: OutMI.setOpcode(X86::MOV64rm); goto ReSimplify; 532226890Sdim case X86::RELEASE_MOV8mr: OutMI.setOpcode(X86::MOV8mr); goto ReSimplify; 533226890Sdim case X86::RELEASE_MOV16mr: OutMI.setOpcode(X86::MOV16mr); goto ReSimplify; 534226890Sdim case X86::RELEASE_MOV32mr: OutMI.setOpcode(X86::MOV32mr); goto ReSimplify; 535226890Sdim case X86::RELEASE_MOV64mr: OutMI.setOpcode(X86::MOV64mr); goto ReSimplify; 536226890Sdim 537212793Sdim // We don't currently select the correct instruction form for instructions 538212793Sdim // which have a short %eax, etc. form. Handle this by custom lowering, for 539212793Sdim // now. 540212793Sdim // 541212793Sdim // Note, we are currently not handling the following instructions: 542212793Sdim // MOV64ao8, MOV64o8a 543212793Sdim // XCHG16ar, XCHG32ar, XCHG64ar 544212793Sdim case X86::MOV8mr_NOREX: 545212793Sdim case X86::MOV8mr: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV8ao8); break; 546212793Sdim case X86::MOV8rm_NOREX: 547212793Sdim case X86::MOV8rm: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV8o8a); break; 548212793Sdim case X86::MOV16mr: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV16ao16); break; 549212793Sdim case X86::MOV16rm: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV16o16a); break; 550212793Sdim case X86::MOV32mr: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV32ao32); break; 551212793Sdim case X86::MOV32rm: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV32o32a); break; 552212793Sdim 553212793Sdim case X86::ADC8ri: SimplifyShortImmForm(OutMI, X86::ADC8i8); break; 554212793Sdim case X86::ADC16ri: SimplifyShortImmForm(OutMI, X86::ADC16i16); break; 555212793Sdim case X86::ADC32ri: SimplifyShortImmForm(OutMI, X86::ADC32i32); break; 556212793Sdim case X86::ADC64ri32: SimplifyShortImmForm(OutMI, X86::ADC64i32); break; 557212793Sdim case X86::ADD8ri: SimplifyShortImmForm(OutMI, X86::ADD8i8); break; 558212793Sdim case X86::ADD16ri: SimplifyShortImmForm(OutMI, X86::ADD16i16); break; 559212793Sdim case X86::ADD32ri: SimplifyShortImmForm(OutMI, X86::ADD32i32); break; 560212793Sdim case X86::ADD64ri32: SimplifyShortImmForm(OutMI, X86::ADD64i32); break; 561212793Sdim case X86::AND8ri: SimplifyShortImmForm(OutMI, X86::AND8i8); break; 562212793Sdim case X86::AND16ri: SimplifyShortImmForm(OutMI, X86::AND16i16); break; 563212793Sdim case X86::AND32ri: SimplifyShortImmForm(OutMI, X86::AND32i32); break; 564212793Sdim case X86::AND64ri32: SimplifyShortImmForm(OutMI, X86::AND64i32); break; 565212793Sdim case X86::CMP8ri: SimplifyShortImmForm(OutMI, X86::CMP8i8); break; 566212793Sdim case X86::CMP16ri: SimplifyShortImmForm(OutMI, X86::CMP16i16); break; 567212793Sdim case X86::CMP32ri: SimplifyShortImmForm(OutMI, X86::CMP32i32); break; 568212793Sdim case X86::CMP64ri32: SimplifyShortImmForm(OutMI, X86::CMP64i32); break; 569212793Sdim case X86::OR8ri: SimplifyShortImmForm(OutMI, X86::OR8i8); break; 570212793Sdim case X86::OR16ri: SimplifyShortImmForm(OutMI, X86::OR16i16); break; 571212793Sdim case X86::OR32ri: SimplifyShortImmForm(OutMI, X86::OR32i32); break; 572212793Sdim case X86::OR64ri32: SimplifyShortImmForm(OutMI, X86::OR64i32); break; 573212793Sdim case X86::SBB8ri: SimplifyShortImmForm(OutMI, X86::SBB8i8); break; 574212793Sdim case X86::SBB16ri: SimplifyShortImmForm(OutMI, X86::SBB16i16); break; 575212793Sdim case X86::SBB32ri: SimplifyShortImmForm(OutMI, X86::SBB32i32); break; 576212793Sdim case X86::SBB64ri32: SimplifyShortImmForm(OutMI, X86::SBB64i32); break; 577212793Sdim case X86::SUB8ri: SimplifyShortImmForm(OutMI, X86::SUB8i8); break; 578212793Sdim case X86::SUB16ri: SimplifyShortImmForm(OutMI, X86::SUB16i16); break; 579212793Sdim case X86::SUB32ri: SimplifyShortImmForm(OutMI, X86::SUB32i32); break; 580212793Sdim case X86::SUB64ri32: SimplifyShortImmForm(OutMI, X86::SUB64i32); break; 581212793Sdim case X86::TEST8ri: SimplifyShortImmForm(OutMI, X86::TEST8i8); break; 582212793Sdim case X86::TEST16ri: SimplifyShortImmForm(OutMI, X86::TEST16i16); break; 583212793Sdim case X86::TEST32ri: SimplifyShortImmForm(OutMI, X86::TEST32i32); break; 584212793Sdim case X86::TEST64ri32: SimplifyShortImmForm(OutMI, X86::TEST64i32); break; 585212793Sdim case X86::XOR8ri: SimplifyShortImmForm(OutMI, X86::XOR8i8); break; 586212793Sdim case X86::XOR16ri: SimplifyShortImmForm(OutMI, X86::XOR16i16); break; 587212793Sdim case X86::XOR32ri: SimplifyShortImmForm(OutMI, X86::XOR32i32); break; 588212793Sdim case X86::XOR64ri32: SimplifyShortImmForm(OutMI, X86::XOR64i32); break; 589235633Sdim 590263509Sdim // Try to shrink some forms of movsx. 591263509Sdim case X86::MOVSX16rr8: 592263509Sdim case X86::MOVSX32rr16: 593263509Sdim case X86::MOVSX64rr32: 594263509Sdim SimplifyMOVSX(OutMI); 595235633Sdim break; 596212793Sdim } 597212793Sdim} 598212793Sdim 599218893Sdimstatic void LowerTlsAddr(MCStreamer &OutStreamer, 600218893Sdim X86MCInstLower &MCInstLowering, 601218893Sdim const MachineInstr &MI) { 602245431Sdim 603245431Sdim bool is64Bits = MI.getOpcode() == X86::TLS_addr64 || 604245431Sdim MI.getOpcode() == X86::TLS_base_addr64; 605245431Sdim 606245431Sdim bool needsPadding = MI.getOpcode() == X86::TLS_addr64; 607245431Sdim 608218893Sdim MCContext &context = OutStreamer.getContext(); 609212793Sdim 610252723Sdim if (needsPadding) 611252723Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX)); 612245431Sdim 613245431Sdim MCSymbolRefExpr::VariantKind SRVK; 614245431Sdim switch (MI.getOpcode()) { 615245431Sdim case X86::TLS_addr32: 616245431Sdim case X86::TLS_addr64: 617245431Sdim SRVK = MCSymbolRefExpr::VK_TLSGD; 618245431Sdim break; 619245431Sdim case X86::TLS_base_addr32: 620245431Sdim SRVK = MCSymbolRefExpr::VK_TLSLDM; 621245431Sdim break; 622245431Sdim case X86::TLS_base_addr64: 623245431Sdim SRVK = MCSymbolRefExpr::VK_TLSLD; 624245431Sdim break; 625245431Sdim default: 626245431Sdim llvm_unreachable("unexpected opcode"); 627245431Sdim } 628245431Sdim 629218893Sdim MCSymbol *sym = MCInstLowering.GetSymbolFromOperand(MI.getOperand(3)); 630245431Sdim const MCSymbolRefExpr *symRef = MCSymbolRefExpr::Create(sym, SRVK, context); 631218893Sdim 632218893Sdim MCInst LEA; 633218893Sdim if (is64Bits) { 634218893Sdim LEA.setOpcode(X86::LEA64r); 635218893Sdim LEA.addOperand(MCOperand::CreateReg(X86::RDI)); // dest 636218893Sdim LEA.addOperand(MCOperand::CreateReg(X86::RIP)); // base 637218893Sdim LEA.addOperand(MCOperand::CreateImm(1)); // scale 638218893Sdim LEA.addOperand(MCOperand::CreateReg(0)); // index 639218893Sdim LEA.addOperand(MCOperand::CreateExpr(symRef)); // disp 640218893Sdim LEA.addOperand(MCOperand::CreateReg(0)); // seg 641245431Sdim } else if (SRVK == MCSymbolRefExpr::VK_TLSLDM) { 642245431Sdim LEA.setOpcode(X86::LEA32r); 643245431Sdim LEA.addOperand(MCOperand::CreateReg(X86::EAX)); // dest 644245431Sdim LEA.addOperand(MCOperand::CreateReg(X86::EBX)); // base 645245431Sdim LEA.addOperand(MCOperand::CreateImm(1)); // scale 646245431Sdim LEA.addOperand(MCOperand::CreateReg(0)); // index 647245431Sdim LEA.addOperand(MCOperand::CreateExpr(symRef)); // disp 648245431Sdim LEA.addOperand(MCOperand::CreateReg(0)); // seg 649218893Sdim } else { 650218893Sdim LEA.setOpcode(X86::LEA32r); 651218893Sdim LEA.addOperand(MCOperand::CreateReg(X86::EAX)); // dest 652218893Sdim LEA.addOperand(MCOperand::CreateReg(0)); // base 653218893Sdim LEA.addOperand(MCOperand::CreateImm(1)); // scale 654218893Sdim LEA.addOperand(MCOperand::CreateReg(X86::EBX)); // index 655218893Sdim LEA.addOperand(MCOperand::CreateExpr(symRef)); // disp 656218893Sdim LEA.addOperand(MCOperand::CreateReg(0)); // seg 657218893Sdim } 658218893Sdim OutStreamer.EmitInstruction(LEA); 659218893Sdim 660245431Sdim if (needsPadding) { 661252723Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX)); 662252723Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX)); 663252723Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::REX64_PREFIX)); 664218893Sdim } 665218893Sdim 666218893Sdim StringRef name = is64Bits ? "__tls_get_addr" : "___tls_get_addr"; 667218893Sdim MCSymbol *tlsGetAddr = context.GetOrCreateSymbol(name); 668218893Sdim const MCSymbolRefExpr *tlsRef = 669218893Sdim MCSymbolRefExpr::Create(tlsGetAddr, 670218893Sdim MCSymbolRefExpr::VK_PLT, 671218893Sdim context); 672218893Sdim 673252723Sdim OutStreamer.EmitInstruction(MCInstBuilder(is64Bits ? X86::CALL64pcrel32 674252723Sdim : X86::CALLpcrel32) 675252723Sdim .addExpr(tlsRef)); 676218893Sdim} 677218893Sdim 678263509Sdimstatic std::pair<StackMaps::Location, MachineInstr::const_mop_iterator> 679263509SdimparseMemoryOperand(StackMaps::Location::LocationType LocTy, unsigned Size, 680263509Sdim MachineInstr::const_mop_iterator MOI, 681263509Sdim MachineInstr::const_mop_iterator MOE) { 682263509Sdim 683263509Sdim typedef StackMaps::Location Location; 684263509Sdim 685263509Sdim assert(std::distance(MOI, MOE) >= 5 && "Too few operands to encode mem op."); 686263509Sdim 687263509Sdim const MachineOperand &Base = *MOI; 688263509Sdim const MachineOperand &Scale = *(++MOI); 689263509Sdim const MachineOperand &Index = *(++MOI); 690263509Sdim const MachineOperand &Disp = *(++MOI); 691263509Sdim const MachineOperand &ZeroReg = *(++MOI); 692263509Sdim 693263509Sdim // Sanity check for supported operand format. 694263509Sdim assert(Base.isReg() && 695263509Sdim Scale.isImm() && Scale.getImm() == 1 && 696263509Sdim Index.isReg() && Index.getReg() == 0 && 697263509Sdim Disp.isImm() && ZeroReg.isReg() && (ZeroReg.getReg() == 0) && 698263509Sdim "Unsupported x86 memory operand sequence."); 699263509Sdim (void)Scale; 700263509Sdim (void)Index; 701263509Sdim (void)ZeroReg; 702263509Sdim 703263509Sdim return std::make_pair( 704263509Sdim Location(LocTy, Size, Base.getReg(), Disp.getImm()), ++MOI); 705263509Sdim} 706263509Sdim 707263509Sdimstd::pair<StackMaps::Location, MachineInstr::const_mop_iterator> 708263509SdimX86AsmPrinter::stackmapOperandParser(MachineInstr::const_mop_iterator MOI, 709263509Sdim MachineInstr::const_mop_iterator MOE, 710263509Sdim const TargetMachine &TM) { 711263509Sdim 712263509Sdim typedef StackMaps::Location Location; 713263509Sdim 714263509Sdim const MachineOperand &MOP = *MOI; 715263509Sdim assert(!MOP.isRegMask() && (!MOP.isReg() || !MOP.isImplicit()) && 716263509Sdim "Register mask and implicit operands should not be processed."); 717263509Sdim 718263509Sdim if (MOP.isImm()) { 719263509Sdim // Verify anyregcc 720263509Sdim // [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ... 721263509Sdim 722263509Sdim switch (MOP.getImm()) { 723263509Sdim default: llvm_unreachable("Unrecognized operand type."); 724263509Sdim case StackMaps::DirectMemRefOp: { 725263509Sdim unsigned Size = TM.getDataLayout()->getPointerSizeInBits(); 726263509Sdim assert((Size % 8) == 0 && "Need pointer size in bytes."); 727263509Sdim Size /= 8; 728263509Sdim return parseMemoryOperand(StackMaps::Location::Direct, Size, 729263509Sdim llvm::next(MOI), MOE); 730263509Sdim } 731263509Sdim case StackMaps::IndirectMemRefOp: { 732263509Sdim ++MOI; 733263509Sdim int64_t Size = MOI->getImm(); 734263509Sdim assert(Size > 0 && "Need a valid size for indirect memory locations."); 735263509Sdim return parseMemoryOperand(StackMaps::Location::Indirect, Size, 736263509Sdim llvm::next(MOI), MOE); 737263509Sdim } 738263509Sdim case StackMaps::ConstantOp: { 739263509Sdim ++MOI; 740263509Sdim assert(MOI->isImm() && "Expected constant operand."); 741263509Sdim int64_t Imm = MOI->getImm(); 742263509Sdim return std::make_pair( 743263509Sdim Location(Location::Constant, sizeof(int64_t), 0, Imm), ++MOI); 744263509Sdim } 745263509Sdim } 746263509Sdim } 747263509Sdim 748263509Sdim // Otherwise this is a reg operand. The physical register number will 749263509Sdim // ultimately be encoded as a DWARF regno. The stack map also records the size 750263509Sdim // of a spill slot that can hold the register content. (The runtime can 751263509Sdim // track the actual size of the data type if it needs to.) 752263509Sdim assert(MOP.isReg() && "Expected register operand here."); 753263509Sdim assert(TargetRegisterInfo::isPhysicalRegister(MOP.getReg()) && 754263509Sdim "Virtreg operands should have been rewritten before now."); 755263509Sdim const TargetRegisterClass *RC = 756263509Sdim TM.getRegisterInfo()->getMinimalPhysRegClass(MOP.getReg()); 757263509Sdim assert(!MOP.getSubReg() && "Physical subreg still around."); 758263509Sdim return std::make_pair( 759263509Sdim Location(Location::Register, RC->getSize(), MOP.getReg(), 0), ++MOI); 760263509Sdim} 761263509Sdim 762263509Sdim// Lower a stackmap of the form: 763263509Sdim// <id>, <shadowBytes>, ... 764263509Sdimstatic void LowerSTACKMAP(MCStreamer &OutStreamer, 765263509Sdim StackMaps &SM, 766263509Sdim const MachineInstr &MI) 767263509Sdim{ 768263509Sdim unsigned NumNOPBytes = MI.getOperand(1).getImm(); 769263509Sdim SM.recordStackMap(MI); 770263509Sdim // Emit padding. 771263509Sdim // FIXME: These nops ensure that the stackmap's shadow is covered by 772263509Sdim // instructions from the same basic block, but the nops should not be 773263509Sdim // necessary if instructions from the same block follow the stackmap. 774263509Sdim for (unsigned i = 0; i < NumNOPBytes; ++i) 775263509Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::NOOP)); 776263509Sdim} 777263509Sdim 778263509Sdim// Lower a patchpoint of the form: 779263509Sdim// [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ... 780263509Sdimstatic void LowerPATCHPOINT(MCStreamer &OutStreamer, 781263509Sdim StackMaps &SM, 782263509Sdim const MachineInstr &MI) { 783263509Sdim SM.recordPatchPoint(MI); 784263509Sdim 785263509Sdim PatchPointOpers opers(&MI); 786263509Sdim unsigned ScratchIdx = opers.getNextScratchIdx(); 787263509Sdim unsigned EncodedBytes = 0; 788263509Sdim int64_t CallTarget = opers.getMetaOper(PatchPointOpers::TargetPos).getImm(); 789263509Sdim if (CallTarget) { 790263509Sdim // Emit MOV to materialize the target address and the CALL to target. 791263509Sdim // This is encoded with 12-13 bytes, depending on which register is used. 792263509Sdim // We conservatively assume that it is 12 bytes and emit in worst case one 793263509Sdim // extra NOP byte. 794263509Sdim EncodedBytes = 12; 795263509Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::MOV64ri) 796263509Sdim .addReg(MI.getOperand(ScratchIdx).getReg()) 797263509Sdim .addImm(CallTarget)); 798263509Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::CALL64r) 799263509Sdim .addReg(MI.getOperand(ScratchIdx).getReg())); 800263509Sdim } 801263509Sdim // Emit padding. 802263509Sdim unsigned NumBytes = opers.getMetaOper(PatchPointOpers::NBytesPos).getImm(); 803263509Sdim assert(NumBytes >= EncodedBytes && 804263509Sdim "Patchpoint can't request size less than the length of a call."); 805263509Sdim 806263509Sdim for (unsigned i = EncodedBytes; i < NumBytes; ++i) 807263509Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::NOOP)); 808263509Sdim} 809263509Sdim 810212793Sdimvoid X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { 811263509Sdim X86MCInstLower MCInstLowering(*MF, *this); 812212793Sdim switch (MI->getOpcode()) { 813212793Sdim case TargetOpcode::DBG_VALUE: 814263509Sdim llvm_unreachable("Should be handled target independently"); 815212793Sdim 816212793Sdim // Emit nothing here but a comment if we can. 817212793Sdim case X86::Int_MemBarrier: 818212793Sdim if (OutStreamer.hasRawTextSupport()) 819212793Sdim OutStreamer.EmitRawText(StringRef("\t#MEMBARRIER")); 820212793Sdim return; 821218893Sdim 822226890Sdim 823218893Sdim case X86::EH_RETURN: 824218893Sdim case X86::EH_RETURN64: { 825218893Sdim // Lower these as normal, but add some comments. 826218893Sdim unsigned Reg = MI->getOperand(0).getReg(); 827218893Sdim OutStreamer.AddComment(StringRef("eh_return, addr: %") + 828218893Sdim X86ATTInstPrinter::getRegisterName(Reg)); 829218893Sdim break; 830218893Sdim } 831212793Sdim case X86::TAILJMPr: 832212793Sdim case X86::TAILJMPd: 833212793Sdim case X86::TAILJMPd64: 834212793Sdim // Lower these as normal, but add some comments. 835212793Sdim OutStreamer.AddComment("TAILCALL"); 836212793Sdim break; 837218893Sdim 838218893Sdim case X86::TLS_addr32: 839218893Sdim case X86::TLS_addr64: 840245431Sdim case X86::TLS_base_addr32: 841245431Sdim case X86::TLS_base_addr64: 842218893Sdim return LowerTlsAddr(OutStreamer, MCInstLowering, *MI); 843218893Sdim 844212793Sdim case X86::MOVPC32r: { 845212793Sdim // This is a pseudo op for a two instruction sequence with a label, which 846212793Sdim // looks like: 847212793Sdim // call "L1$pb" 848212793Sdim // "L1$pb": 849212793Sdim // popl %esi 850245431Sdim 851212793Sdim // Emit the call. 852218893Sdim MCSymbol *PICBase = MF->getPICBaseSymbol(); 853212793Sdim // FIXME: We would like an efficient form for this, so we don't have to do a 854212793Sdim // lot of extra uniquing. 855252723Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::CALLpcrel32) 856252723Sdim .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext))); 857245431Sdim 858212793Sdim // Emit the label. 859212793Sdim OutStreamer.EmitLabel(PICBase); 860245431Sdim 861212793Sdim // popl $reg 862252723Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::POP32r) 863252723Sdim .addReg(MI->getOperand(0).getReg())); 864212793Sdim return; 865212793Sdim } 866245431Sdim 867212793Sdim case X86::ADD32ri: { 868212793Sdim // Lower the MO_GOT_ABSOLUTE_ADDRESS form of ADD32ri. 869212793Sdim if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS) 870212793Sdim break; 871245431Sdim 872212793Sdim // Okay, we have something like: 873212793Sdim // EAX = ADD32ri EAX, MO_GOT_ABSOLUTE_ADDRESS(@MYGLOBAL) 874245431Sdim 875212793Sdim // For this, we want to print something like: 876212793Sdim // MYGLOBAL + (. - PICBASE) 877212793Sdim // However, we can't generate a ".", so just emit a new label here and refer 878212793Sdim // to it. 879212793Sdim MCSymbol *DotSym = OutContext.CreateTempSymbol(); 880212793Sdim OutStreamer.EmitLabel(DotSym); 881245431Sdim 882212793Sdim // Now that we have emitted the label, lower the complex operand expression. 883212793Sdim MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2)); 884245431Sdim 885212793Sdim const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 886212793Sdim const MCExpr *PICBase = 887218893Sdim MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), OutContext); 888212793Sdim DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, OutContext); 889245431Sdim 890245431Sdim DotExpr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(OpSym,OutContext), 891212793Sdim DotExpr, OutContext); 892245431Sdim 893252723Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::ADD32ri) 894252723Sdim .addReg(MI->getOperand(0).getReg()) 895252723Sdim .addReg(MI->getOperand(1).getReg()) 896252723Sdim .addExpr(DotExpr)); 897212793Sdim return; 898212793Sdim } 899263509Sdim 900263509Sdim case TargetOpcode::STACKMAP: 901263509Sdim return LowerSTACKMAP(OutStreamer, SM, *MI); 902263509Sdim 903263509Sdim case TargetOpcode::PATCHPOINT: 904263509Sdim return LowerPATCHPOINT(OutStreamer, SM, *MI); 905263509Sdim 906263509Sdim case X86::MORESTACK_RET: 907263509Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::RET)); 908263509Sdim return; 909263509Sdim 910263509Sdim case X86::MORESTACK_RET_RESTORE_R10: 911263509Sdim // Return, then restore R10. 912263509Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::RET)); 913263509Sdim OutStreamer.EmitInstruction(MCInstBuilder(X86::MOV64rr) 914263509Sdim .addReg(X86::R10) 915263509Sdim .addReg(X86::RAX)); 916263509Sdim return; 917212793Sdim } 918245431Sdim 919212793Sdim MCInst TmpInst; 920212793Sdim MCInstLowering.Lower(MI, TmpInst); 921212793Sdim OutStreamer.EmitInstruction(TmpInst); 922212793Sdim} 923