145bb48eaSTom Stellard //===- AMDGPUMCInstLower.cpp - Lower AMDGPU MachineInstr to an MCInst -----===// 245bb48eaSTom Stellard // 345bb48eaSTom Stellard // The LLVM Compiler Infrastructure 445bb48eaSTom Stellard // 545bb48eaSTom Stellard // This file is distributed under the University of Illinois Open Source 645bb48eaSTom Stellard // License. See LICENSE.TXT for details. 745bb48eaSTom Stellard // 845bb48eaSTom Stellard //===----------------------------------------------------------------------===// 945bb48eaSTom Stellard // 1045bb48eaSTom Stellard /// \file 115f8f34e4SAdrian Prantl /// Code to lower AMDGPU MachineInstrs to their corresponding MCInst. 1245bb48eaSTom Stellard // 1345bb48eaSTom Stellard //===----------------------------------------------------------------------===// 1445bb48eaSTom Stellard // 1545bb48eaSTom Stellard 1645bb48eaSTom Stellard #include "AMDGPUAsmPrinter.h" 1743e92fe3SMatt Arsenault #include "AMDGPUSubtarget.h" 1845bb48eaSTom Stellard #include "AMDGPUTargetMachine.h" 1945bb48eaSTom Stellard #include "InstPrinter/AMDGPUInstPrinter.h" 2044b30b45STom Stellard #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 21c5015010STom Stellard #include "R600AsmPrinter.h" 2245bb48eaSTom Stellard #include "SIInstrInfo.h" 2345bb48eaSTom Stellard #include "llvm/CodeGen/MachineBasicBlock.h" 2445bb48eaSTom Stellard #include "llvm/CodeGen/MachineInstr.h" 2545bb48eaSTom Stellard #include "llvm/IR/Constants.h" 2645bb48eaSTom Stellard #include "llvm/IR/Function.h" 2745bb48eaSTom Stellard #include "llvm/IR/GlobalVariable.h" 2845bb48eaSTom Stellard #include "llvm/MC/MCCodeEmitter.h" 2945bb48eaSTom Stellard #include "llvm/MC/MCContext.h" 3045bb48eaSTom Stellard #include "llvm/MC/MCExpr.h" 3145bb48eaSTom Stellard #include "llvm/MC/MCInst.h" 3245bb48eaSTom Stellard #include "llvm/MC/MCObjectStreamer.h" 3345bb48eaSTom Stellard #include "llvm/MC/MCStreamer.h" 3445bb48eaSTom Stellard #include "llvm/Support/ErrorHandling.h" 3545bb48eaSTom Stellard #include "llvm/Support/Format.h" 3645bb48eaSTom Stellard #include <algorithm> 3745bb48eaSTom Stellard 3845bb48eaSTom Stellard using namespace llvm; 3945bb48eaSTom Stellard 40*79fffe35STom Stellard namespace { 41*79fffe35STom Stellard 42*79fffe35STom Stellard class AMDGPUMCInstLower { 43*79fffe35STom Stellard MCContext &Ctx; 44*79fffe35STom Stellard const AMDGPUSubtarget &ST; 45*79fffe35STom Stellard const AsmPrinter &AP; 46*79fffe35STom Stellard 47*79fffe35STom Stellard const MCExpr *getLongBranchBlockExpr(const MachineBasicBlock &SrcBB, 48*79fffe35STom Stellard const MachineOperand &MO) const; 49*79fffe35STom Stellard 50*79fffe35STom Stellard public: 51*79fffe35STom Stellard AMDGPUMCInstLower(MCContext &ctx, const AMDGPUSubtarget &ST, 52*79fffe35STom Stellard const AsmPrinter &AP); 53*79fffe35STom Stellard 54*79fffe35STom Stellard bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const; 55*79fffe35STom Stellard 56*79fffe35STom Stellard /// Lower a MachineInstr to an MCInst 57*79fffe35STom Stellard void lower(const MachineInstr *MI, MCInst &OutMI) const; 58*79fffe35STom Stellard 59*79fffe35STom Stellard }; 60*79fffe35STom Stellard 61*79fffe35STom Stellard } // End anonymous namespace 62*79fffe35STom Stellard 6311f74020SMatt Arsenault #include "AMDGPUGenMCPseudoLowering.inc" 6411f74020SMatt Arsenault 651b9748c6STom Stellard AMDGPUMCInstLower::AMDGPUMCInstLower(MCContext &ctx, const AMDGPUSubtarget &st, 661b9748c6STom Stellard const AsmPrinter &ap): 671b9748c6STom Stellard Ctx(ctx), ST(st), AP(ap) { } 6845bb48eaSTom Stellard 69418beb76STom Stellard static MCSymbolRefExpr::VariantKind getVariantKind(unsigned MOFlags) { 70418beb76STom Stellard switch (MOFlags) { 71c96b5d70SKonstantin Zhuravlyov default: 72c96b5d70SKonstantin Zhuravlyov return MCSymbolRefExpr::VK_None; 73c96b5d70SKonstantin Zhuravlyov case SIInstrInfo::MO_GOTPCREL: 74c96b5d70SKonstantin Zhuravlyov return MCSymbolRefExpr::VK_GOTPCREL; 75c96b5d70SKonstantin Zhuravlyov case SIInstrInfo::MO_GOTPCREL32_LO: 76c96b5d70SKonstantin Zhuravlyov return MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_LO; 77c96b5d70SKonstantin Zhuravlyov case SIInstrInfo::MO_GOTPCREL32_HI: 78c96b5d70SKonstantin Zhuravlyov return MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_HI; 79c96b5d70SKonstantin Zhuravlyov case SIInstrInfo::MO_REL32_LO: 80c96b5d70SKonstantin Zhuravlyov return MCSymbolRefExpr::VK_AMDGPU_REL32_LO; 81c96b5d70SKonstantin Zhuravlyov case SIInstrInfo::MO_REL32_HI: 82c96b5d70SKonstantin Zhuravlyov return MCSymbolRefExpr::VK_AMDGPU_REL32_HI; 83418beb76STom Stellard } 84418beb76STom Stellard } 85418beb76STom Stellard 866bc43d86SMatt Arsenault const MCExpr *AMDGPUMCInstLower::getLongBranchBlockExpr( 876bc43d86SMatt Arsenault const MachineBasicBlock &SrcBB, 886bc43d86SMatt Arsenault const MachineOperand &MO) const { 896bc43d86SMatt Arsenault const MCExpr *DestBBSym 906bc43d86SMatt Arsenault = MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx); 916bc43d86SMatt Arsenault const MCExpr *SrcBBSym = MCSymbolRefExpr::create(SrcBB.getSymbol(), Ctx); 926bc43d86SMatt Arsenault 936bc43d86SMatt Arsenault assert(SrcBB.front().getOpcode() == AMDGPU::S_GETPC_B64 && 946bc43d86SMatt Arsenault ST.getInstrInfo()->get(AMDGPU::S_GETPC_B64).Size == 4); 956bc43d86SMatt Arsenault 966bc43d86SMatt Arsenault // s_getpc_b64 returns the address of next instruction. 976bc43d86SMatt Arsenault const MCConstantExpr *One = MCConstantExpr::create(4, Ctx); 986bc43d86SMatt Arsenault SrcBBSym = MCBinaryExpr::createAdd(SrcBBSym, One, Ctx); 996bc43d86SMatt Arsenault 1006bc43d86SMatt Arsenault if (MO.getTargetFlags() == AMDGPU::TF_LONG_BRANCH_FORWARD) 1016bc43d86SMatt Arsenault return MCBinaryExpr::createSub(DestBBSym, SrcBBSym, Ctx); 1026bc43d86SMatt Arsenault 1036bc43d86SMatt Arsenault assert(MO.getTargetFlags() == AMDGPU::TF_LONG_BRANCH_BACKWARD); 1046bc43d86SMatt Arsenault return MCBinaryExpr::createSub(SrcBBSym, DestBBSym, Ctx); 1056bc43d86SMatt Arsenault } 1066bc43d86SMatt Arsenault 10711f74020SMatt Arsenault bool AMDGPUMCInstLower::lowerOperand(const MachineOperand &MO, 10811f74020SMatt Arsenault MCOperand &MCOp) const { 10911f74020SMatt Arsenault switch (MO.getType()) { 11011f74020SMatt Arsenault default: 11111f74020SMatt Arsenault llvm_unreachable("unknown operand type"); 11211f74020SMatt Arsenault case MachineOperand::MO_Immediate: 11311f74020SMatt Arsenault MCOp = MCOperand::createImm(MO.getImm()); 11411f74020SMatt Arsenault return true; 11511f74020SMatt Arsenault case MachineOperand::MO_Register: 11611f74020SMatt Arsenault MCOp = MCOperand::createReg(AMDGPU::getMCReg(MO.getReg(), ST)); 11711f74020SMatt Arsenault return true; 11811f74020SMatt Arsenault case MachineOperand::MO_MachineBasicBlock: { 11911f74020SMatt Arsenault if (MO.getTargetFlags() != 0) { 12011f74020SMatt Arsenault MCOp = MCOperand::createExpr( 12111f74020SMatt Arsenault getLongBranchBlockExpr(*MO.getParent()->getParent(), MO)); 12211f74020SMatt Arsenault } else { 12311f74020SMatt Arsenault MCOp = MCOperand::createExpr( 12411f74020SMatt Arsenault MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); 12511f74020SMatt Arsenault } 12611f74020SMatt Arsenault 12711f74020SMatt Arsenault return true; 12811f74020SMatt Arsenault } 12911f74020SMatt Arsenault case MachineOperand::MO_GlobalAddress: { 13011f74020SMatt Arsenault const GlobalValue *GV = MO.getGlobal(); 13111f74020SMatt Arsenault SmallString<128> SymbolName; 13211f74020SMatt Arsenault AP.getNameWithPrefix(SymbolName, GV); 13311f74020SMatt Arsenault MCSymbol *Sym = Ctx.getOrCreateSymbol(SymbolName); 13411f74020SMatt Arsenault const MCExpr *SymExpr = 13511f74020SMatt Arsenault MCSymbolRefExpr::create(Sym, getVariantKind(MO.getTargetFlags()),Ctx); 13611f74020SMatt Arsenault const MCExpr *Expr = MCBinaryExpr::createAdd(SymExpr, 13711f74020SMatt Arsenault MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); 13811f74020SMatt Arsenault MCOp = MCOperand::createExpr(Expr); 13911f74020SMatt Arsenault return true; 14011f74020SMatt Arsenault } 14111f74020SMatt Arsenault case MachineOperand::MO_ExternalSymbol: { 14211f74020SMatt Arsenault MCSymbol *Sym = Ctx.getOrCreateSymbol(StringRef(MO.getSymbolName())); 14311f74020SMatt Arsenault Sym->setExternal(true); 14411f74020SMatt Arsenault const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx); 14511f74020SMatt Arsenault MCOp = MCOperand::createExpr(Expr); 14611f74020SMatt Arsenault return true; 14711f74020SMatt Arsenault } 148b62a4eb5SMatt Arsenault case MachineOperand::MO_RegisterMask: 149b62a4eb5SMatt Arsenault // Regmasks are like implicit defs. 150b62a4eb5SMatt Arsenault return false; 15111f74020SMatt Arsenault } 15211f74020SMatt Arsenault } 15311f74020SMatt Arsenault 15445bb48eaSTom Stellard void AMDGPUMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const { 1552b1f9aa5SMatt Arsenault unsigned Opcode = MI->getOpcode(); 1561d6317c3SMatt Arsenault const auto *TII = ST.getInstrInfo(); 15745bb48eaSTom Stellard 1582b1f9aa5SMatt Arsenault // FIXME: Should be able to handle this with emitPseudoExpansionLowering. We 1592b1f9aa5SMatt Arsenault // need to select it to the subtarget specific version, and there's no way to 1602b1f9aa5SMatt Arsenault // do that with a single pseudo source operation. 1612b1f9aa5SMatt Arsenault if (Opcode == AMDGPU::S_SETPC_B64_return) 1622b1f9aa5SMatt Arsenault Opcode = AMDGPU::S_SETPC_B64; 1636ed7b9bfSMatt Arsenault else if (Opcode == AMDGPU::SI_CALL) { 1646ed7b9bfSMatt Arsenault // SI_CALL is just S_SWAPPC_B64 with an additional operand to track the 1651d6317c3SMatt Arsenault // called function (which we need to remove here). 1661d6317c3SMatt Arsenault OutMI.setOpcode(TII->pseudoToMCOpcode(AMDGPU::S_SWAPPC_B64)); 1671d6317c3SMatt Arsenault MCOperand Dest, Src; 1681d6317c3SMatt Arsenault lowerOperand(MI->getOperand(0), Dest); 1691d6317c3SMatt Arsenault lowerOperand(MI->getOperand(1), Src); 1701d6317c3SMatt Arsenault OutMI.addOperand(Dest); 1711d6317c3SMatt Arsenault OutMI.addOperand(Src); 1721d6317c3SMatt Arsenault return; 17371bcbd45SMatt Arsenault } else if (Opcode == AMDGPU::SI_TCRETURN) { 17471bcbd45SMatt Arsenault // TODO: How to use branch immediate and avoid register+add? 17571bcbd45SMatt Arsenault Opcode = AMDGPU::S_SETPC_B64; 1766ed7b9bfSMatt Arsenault } 17745bb48eaSTom Stellard 1781d6317c3SMatt Arsenault int MCOpcode = TII->pseudoToMCOpcode(Opcode); 17945bb48eaSTom Stellard if (MCOpcode == -1) { 180f1caa283SMatthias Braun LLVMContext &C = MI->getParent()->getParent()->getFunction().getContext(); 18145bb48eaSTom Stellard C.emitError("AMDGPUMCInstLower::lower - Pseudo instruction doesn't have " 18245bb48eaSTom Stellard "a target-specific version: " + Twine(MI->getOpcode())); 18345bb48eaSTom Stellard } 18445bb48eaSTom Stellard 18545bb48eaSTom Stellard OutMI.setOpcode(MCOpcode); 18645bb48eaSTom Stellard 18745bb48eaSTom Stellard for (const MachineOperand &MO : MI->explicit_operands()) { 18845bb48eaSTom Stellard MCOperand MCOp; 18911f74020SMatt Arsenault lowerOperand(MO, MCOp); 19045bb48eaSTom Stellard OutMI.addOperand(MCOp); 19145bb48eaSTom Stellard } 19245bb48eaSTom Stellard } 19345bb48eaSTom Stellard 19411f74020SMatt Arsenault bool AMDGPUAsmPrinter::lowerOperand(const MachineOperand &MO, 19511f74020SMatt Arsenault MCOperand &MCOp) const { 19611f74020SMatt Arsenault const AMDGPUSubtarget &STI = MF->getSubtarget<AMDGPUSubtarget>(); 19711f74020SMatt Arsenault AMDGPUMCInstLower MCInstLowering(OutContext, STI, *this); 19811f74020SMatt Arsenault return MCInstLowering.lowerOperand(MO, MCOp); 19911f74020SMatt Arsenault } 20011f74020SMatt Arsenault 201c5015010STom Stellard static const MCExpr *lowerAddrSpaceCast(const TargetMachine &TM, 202c5015010STom Stellard const Constant *CV, 203c5015010STom Stellard MCContext &OutContext) { 2048f844f39SYaxun Liu // TargetMachine does not support llvm-style cast. Use C++-style cast. 2058f844f39SYaxun Liu // This is safe since TM is always of type AMDGPUTargetMachine or its 2068f844f39SYaxun Liu // derived class. 207c5015010STom Stellard auto &AT = static_cast<const AMDGPUTargetMachine&>(TM); 2088f844f39SYaxun Liu auto *CE = dyn_cast<ConstantExpr>(CV); 2098f844f39SYaxun Liu 2108f844f39SYaxun Liu // Lower null pointers in private and local address space. 2118f844f39SYaxun Liu // Clang generates addrspacecast for null pointers in private and local 2128f844f39SYaxun Liu // address space, which needs to be lowered. 2138f844f39SYaxun Liu if (CE && CE->getOpcode() == Instruction::AddrSpaceCast) { 2148f844f39SYaxun Liu auto Op = CE->getOperand(0); 2158f844f39SYaxun Liu auto SrcAddr = Op->getType()->getPointerAddressSpace(); 216c5015010STom Stellard if (Op->isNullValue() && AT.getNullPointerValue(SrcAddr) == 0) { 2178f844f39SYaxun Liu auto DstAddr = CE->getType()->getPointerAddressSpace(); 218c5015010STom Stellard return MCConstantExpr::create(AT.getNullPointerValue(DstAddr), 2198f844f39SYaxun Liu OutContext); 2208f844f39SYaxun Liu } 2218f844f39SYaxun Liu } 222c5015010STom Stellard return nullptr; 223c5015010STom Stellard } 224c5015010STom Stellard 225c5015010STom Stellard const MCExpr *AMDGPUAsmPrinter::lowerConstant(const Constant *CV) { 226c5015010STom Stellard if (const MCExpr *E = lowerAddrSpaceCast(TM, CV, OutContext)) 227c5015010STom Stellard return E; 2288f844f39SYaxun Liu return AsmPrinter::lowerConstant(CV); 2298f844f39SYaxun Liu } 2308f844f39SYaxun Liu 23145bb48eaSTom Stellard void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) { 23211f74020SMatt Arsenault if (emitPseudoExpansionLowering(*OutStreamer, MI)) 23311f74020SMatt Arsenault return; 23411f74020SMatt Arsenault 23545bb48eaSTom Stellard const AMDGPUSubtarget &STI = MF->getSubtarget<AMDGPUSubtarget>(); 2361b9748c6STom Stellard AMDGPUMCInstLower MCInstLowering(OutContext, STI, *this); 23745bb48eaSTom Stellard 23845bb48eaSTom Stellard StringRef Err; 2399cfc75c2SDuncan P. N. Exon Smith if (!STI.getInstrInfo()->verifyInstruction(*MI, Err)) { 240f1caa283SMatthias Braun LLVMContext &C = MI->getParent()->getParent()->getFunction().getContext(); 241302f83acSMichel Danzer C.emitError("Illegal instruction detected: " + Err); 2428c209aa8SMatthias Braun MI->print(errs()); 24345bb48eaSTom Stellard } 244302f83acSMichel Danzer 24545bb48eaSTom Stellard if (MI->isBundle()) { 24645bb48eaSTom Stellard const MachineBasicBlock *MBB = MI->getParent(); 247c5b668deSDuncan P. N. Exon Smith MachineBasicBlock::const_instr_iterator I = ++MI->getIterator(); 248a73371a9SDuncan P. N. Exon Smith while (I != MBB->instr_end() && I->isInsideBundle()) { 249a73371a9SDuncan P. N. Exon Smith EmitInstruction(&*I); 25045bb48eaSTom Stellard ++I; 25145bb48eaSTom Stellard } 25245bb48eaSTom Stellard } else { 2535b20fbb7SMatt Arsenault // We don't want SI_MASK_BRANCH/SI_RETURN_TO_EPILOG encoded. They are 2545b20fbb7SMatt Arsenault // placeholder terminator instructions and should only be printed as 2555b20fbb7SMatt Arsenault // comments. 2569babdf42SMatt Arsenault if (MI->getOpcode() == AMDGPU::SI_MASK_BRANCH) { 2579babdf42SMatt Arsenault if (isVerbose()) { 2589babdf42SMatt Arsenault SmallVector<char, 16> BBStr; 2599babdf42SMatt Arsenault raw_svector_ostream Str(BBStr); 2609babdf42SMatt Arsenault 261a74374a8SMatt Arsenault const MachineBasicBlock *MBB = MI->getOperand(0).getMBB(); 2629babdf42SMatt Arsenault const MCSymbolRefExpr *Expr 2639babdf42SMatt Arsenault = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext); 2649babdf42SMatt Arsenault Expr->print(Str, MAI); 265c18c12e3SReid Kleckner OutStreamer->emitRawComment(Twine(" mask branch ") + BBStr); 2669babdf42SMatt Arsenault } 2679babdf42SMatt Arsenault 2689babdf42SMatt Arsenault return; 2699babdf42SMatt Arsenault } 2709babdf42SMatt Arsenault 2715b20fbb7SMatt Arsenault if (MI->getOpcode() == AMDGPU::SI_RETURN_TO_EPILOG) { 2729babdf42SMatt Arsenault if (isVerbose()) 2735b20fbb7SMatt Arsenault OutStreamer->emitRawComment(" return to shader part epilog"); 2749babdf42SMatt Arsenault return; 2759babdf42SMatt Arsenault } 2769babdf42SMatt Arsenault 277ea91cca5SStanislav Mekhanoshin if (MI->getOpcode() == AMDGPU::WAVE_BARRIER) { 278ea91cca5SStanislav Mekhanoshin if (isVerbose()) 279ea91cca5SStanislav Mekhanoshin OutStreamer->emitRawComment(" wave barrier"); 280ea91cca5SStanislav Mekhanoshin return; 281ea91cca5SStanislav Mekhanoshin } 282ea91cca5SStanislav Mekhanoshin 28315a96b1dSYaxun Liu if (MI->getOpcode() == AMDGPU::SI_MASKED_UNREACHABLE) { 28415a96b1dSYaxun Liu if (isVerbose()) 28515a96b1dSYaxun Liu OutStreamer->emitRawComment(" divergent unreachable"); 28615a96b1dSYaxun Liu return; 28715a96b1dSYaxun Liu } 28815a96b1dSYaxun Liu 28945bb48eaSTom Stellard MCInst TmpInst; 29045bb48eaSTom Stellard MCInstLowering.lower(MI, TmpInst); 29145bb48eaSTom Stellard EmitToStreamer(*OutStreamer, TmpInst); 29245bb48eaSTom Stellard 29345bb48eaSTom Stellard if (STI.dumpCode()) { 29445bb48eaSTom Stellard // Disassemble instruction/operands to text. 29545bb48eaSTom Stellard DisasmLines.resize(DisasmLines.size() + 1); 29645bb48eaSTom Stellard std::string &DisasmLine = DisasmLines.back(); 29745bb48eaSTom Stellard raw_string_ostream DisasmStream(DisasmLine); 29845bb48eaSTom Stellard 29945bb48eaSTom Stellard AMDGPUInstPrinter InstPrinter(*TM.getMCAsmInfo(), 30043e92fe3SMatt Arsenault *STI.getInstrInfo(), 30143e92fe3SMatt Arsenault *STI.getRegisterInfo()); 30243e92fe3SMatt Arsenault InstPrinter.printInst(&TmpInst, DisasmStream, StringRef(), STI); 30345bb48eaSTom Stellard 30445bb48eaSTom Stellard // Disassemble instruction/operands to hex representation. 30545bb48eaSTom Stellard SmallVector<MCFixup, 4> Fixups; 30645bb48eaSTom Stellard SmallVector<char, 16> CodeBytes; 30745bb48eaSTom Stellard raw_svector_ostream CodeStream(CodeBytes); 30845bb48eaSTom Stellard 30945bb48eaSTom Stellard auto &ObjStreamer = static_cast<MCObjectStreamer&>(*OutStreamer); 31045bb48eaSTom Stellard MCCodeEmitter &InstEmitter = ObjStreamer.getAssembler().getEmitter(); 31145bb48eaSTom Stellard InstEmitter.encodeInstruction(TmpInst, CodeStream, Fixups, 31245bb48eaSTom Stellard MF->getSubtarget<MCSubtargetInfo>()); 31345bb48eaSTom Stellard HexLines.resize(HexLines.size() + 1); 31445bb48eaSTom Stellard std::string &HexLine = HexLines.back(); 31545bb48eaSTom Stellard raw_string_ostream HexStream(HexLine); 31645bb48eaSTom Stellard 31745bb48eaSTom Stellard for (size_t i = 0; i < CodeBytes.size(); i += 4) { 31845bb48eaSTom Stellard unsigned int CodeDWord = *(unsigned int *)&CodeBytes[i]; 31945bb48eaSTom Stellard HexStream << format("%s%08X", (i > 0 ? " " : ""), CodeDWord); 32045bb48eaSTom Stellard } 32145bb48eaSTom Stellard 32245bb48eaSTom Stellard DisasmStream.flush(); 32345bb48eaSTom Stellard DisasmLineMaxLen = std::max(DisasmLineMaxLen, DisasmLine.size()); 32445bb48eaSTom Stellard } 32545bb48eaSTom Stellard } 32645bb48eaSTom Stellard } 327c5015010STom Stellard 328c5015010STom Stellard void R600AsmPrinter::EmitInstruction(const MachineInstr *MI) { 329c5015010STom Stellard const R600Subtarget &STI = MF->getSubtarget<R600Subtarget>(); 330c5015010STom Stellard AMDGPUMCInstLower MCInstLowering(OutContext, STI, *this); 331c5015010STom Stellard 332c5015010STom Stellard StringRef Err; 333c5015010STom Stellard if (!STI.getInstrInfo()->verifyInstruction(*MI, Err)) { 334c5015010STom Stellard LLVMContext &C = MI->getParent()->getParent()->getFunction().getContext(); 335c5015010STom Stellard C.emitError("Illegal instruction detected: " + Err); 336c5015010STom Stellard MI->print(errs()); 337c5015010STom Stellard } 338c5015010STom Stellard 339c5015010STom Stellard if (MI->isBundle()) { 340c5015010STom Stellard const MachineBasicBlock *MBB = MI->getParent(); 341c5015010STom Stellard MachineBasicBlock::const_instr_iterator I = ++MI->getIterator(); 342c5015010STom Stellard while (I != MBB->instr_end() && I->isInsideBundle()) { 343c5015010STom Stellard EmitInstruction(&*I); 344c5015010STom Stellard ++I; 345c5015010STom Stellard } 346c5015010STom Stellard } else { 347c5015010STom Stellard MCInst TmpInst; 348c5015010STom Stellard MCInstLowering.lower(MI, TmpInst); 349c5015010STom Stellard EmitToStreamer(*OutStreamer, TmpInst); 350c5015010STom Stellard } 351c5015010STom Stellard } 352c5015010STom Stellard 353c5015010STom Stellard const MCExpr *R600AsmPrinter::lowerConstant(const Constant *CV) { 354c5015010STom Stellard if (const MCExpr *E = lowerAddrSpaceCast(TM, CV, OutContext)) 355c5015010STom Stellard return E; 356c5015010STom Stellard return AsmPrinter::lowerConstant(CV); 357c5015010STom Stellard } 358