14a16efa3SDimitry Andric //===- AMDGPUMCInstLower.cpp - Lower AMDGPU MachineInstr to an MCInst -----===//
24a16efa3SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64a16efa3SDimitry Andric //
74a16efa3SDimitry Andric //===----------------------------------------------------------------------===//
84a16efa3SDimitry Andric //
94a16efa3SDimitry Andric /// \file
10eb11fae6SDimitry Andric /// Code to lower AMDGPU MachineInstrs to their corresponding MCInst.
114a16efa3SDimitry Andric //
124a16efa3SDimitry Andric //===----------------------------------------------------------------------===//
134a16efa3SDimitry Andric //
144a16efa3SDimitry Andric
15c0981da4SDimitry Andric #include "AMDGPUMCInstLower.h"
167fa27ce4SDimitry Andric #include "AMDGPU.h"
174a16efa3SDimitry Andric #include "AMDGPUAsmPrinter.h"
18e3b55780SDimitry Andric #include "AMDGPUMachineFunction.h"
195ca98fd9SDimitry Andric #include "AMDGPUTargetMachine.h"
20e6d15924SDimitry Andric #include "MCTargetDesc/AMDGPUInstPrinter.h"
21eb11fae6SDimitry Andric #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
224a16efa3SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
234a16efa3SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
244a16efa3SDimitry Andric #include "llvm/IR/Constants.h"
25ec304151SDimitry Andric #include "llvm/IR/Function.h"
265ca98fd9SDimitry Andric #include "llvm/IR/GlobalVariable.h"
27f8af5cf6SDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
285ca98fd9SDimitry Andric #include "llvm/MC/MCContext.h"
294a16efa3SDimitry Andric #include "llvm/MC/MCExpr.h"
304a16efa3SDimitry Andric #include "llvm/MC/MCInst.h"
31f8af5cf6SDimitry Andric #include "llvm/MC/MCObjectStreamer.h"
324a16efa3SDimitry Andric #include "llvm/MC/MCStreamer.h"
334a16efa3SDimitry Andric #include "llvm/Support/ErrorHandling.h"
34f8af5cf6SDimitry Andric #include "llvm/Support/Format.h"
35f8af5cf6SDimitry Andric #include <algorithm>
364a16efa3SDimitry Andric
374a16efa3SDimitry Andric using namespace llvm;
384a16efa3SDimitry Andric
39b915e9e0SDimitry Andric #include "AMDGPUGenMCPseudoLowering.inc"
40b915e9e0SDimitry Andric
AMDGPUMCInstLower(MCContext & ctx,const TargetSubtargetInfo & st,const AsmPrinter & ap)41eb11fae6SDimitry Andric AMDGPUMCInstLower::AMDGPUMCInstLower(MCContext &ctx,
42eb11fae6SDimitry Andric const TargetSubtargetInfo &st,
43b915e9e0SDimitry Andric const AsmPrinter &ap):
44b915e9e0SDimitry Andric Ctx(ctx), ST(st), AP(ap) { }
4501095a5dSDimitry Andric
getVariantKind(unsigned MOFlags)4601095a5dSDimitry Andric static MCSymbolRefExpr::VariantKind getVariantKind(unsigned MOFlags) {
4701095a5dSDimitry Andric switch (MOFlags) {
48b915e9e0SDimitry Andric default:
49b915e9e0SDimitry Andric return MCSymbolRefExpr::VK_None;
50b915e9e0SDimitry Andric case SIInstrInfo::MO_GOTPCREL:
51b915e9e0SDimitry Andric return MCSymbolRefExpr::VK_GOTPCREL;
52b915e9e0SDimitry Andric case SIInstrInfo::MO_GOTPCREL32_LO:
53b915e9e0SDimitry Andric return MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_LO;
54b915e9e0SDimitry Andric case SIInstrInfo::MO_GOTPCREL32_HI:
55b915e9e0SDimitry Andric return MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_HI;
56b915e9e0SDimitry Andric case SIInstrInfo::MO_REL32_LO:
57b915e9e0SDimitry Andric return MCSymbolRefExpr::VK_AMDGPU_REL32_LO;
58b915e9e0SDimitry Andric case SIInstrInfo::MO_REL32_HI:
59b915e9e0SDimitry Andric return MCSymbolRefExpr::VK_AMDGPU_REL32_HI;
60e6d15924SDimitry Andric case SIInstrInfo::MO_ABS32_LO:
61e6d15924SDimitry Andric return MCSymbolRefExpr::VK_AMDGPU_ABS32_LO;
62e6d15924SDimitry Andric case SIInstrInfo::MO_ABS32_HI:
63e6d15924SDimitry Andric return MCSymbolRefExpr::VK_AMDGPU_ABS32_HI;
64b915e9e0SDimitry Andric }
65b915e9e0SDimitry Andric }
66b915e9e0SDimitry Andric
lowerOperand(const MachineOperand & MO,MCOperand & MCOp) const67b915e9e0SDimitry Andric bool AMDGPUMCInstLower::lowerOperand(const MachineOperand &MO,
68b915e9e0SDimitry Andric MCOperand &MCOp) const {
69b915e9e0SDimitry Andric switch (MO.getType()) {
70b915e9e0SDimitry Andric default:
71344a3780SDimitry Andric break;
72b915e9e0SDimitry Andric case MachineOperand::MO_Immediate:
73b915e9e0SDimitry Andric MCOp = MCOperand::createImm(MO.getImm());
74b915e9e0SDimitry Andric return true;
75b915e9e0SDimitry Andric case MachineOperand::MO_Register:
76b915e9e0SDimitry Andric MCOp = MCOperand::createReg(AMDGPU::getMCReg(MO.getReg(), ST));
77b915e9e0SDimitry Andric return true;
78344a3780SDimitry Andric case MachineOperand::MO_MachineBasicBlock:
79b915e9e0SDimitry Andric MCOp = MCOperand::createExpr(
80b915e9e0SDimitry Andric MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx));
81b915e9e0SDimitry Andric return true;
82b915e9e0SDimitry Andric case MachineOperand::MO_GlobalAddress: {
83b915e9e0SDimitry Andric const GlobalValue *GV = MO.getGlobal();
84b915e9e0SDimitry Andric SmallString<128> SymbolName;
85b915e9e0SDimitry Andric AP.getNameWithPrefix(SymbolName, GV);
86b915e9e0SDimitry Andric MCSymbol *Sym = Ctx.getOrCreateSymbol(SymbolName);
87e6d15924SDimitry Andric const MCExpr *Expr =
88b915e9e0SDimitry Andric MCSymbolRefExpr::create(Sym, getVariantKind(MO.getTargetFlags()),Ctx);
89e6d15924SDimitry Andric int64_t Offset = MO.getOffset();
90e6d15924SDimitry Andric if (Offset != 0) {
91e6d15924SDimitry Andric Expr = MCBinaryExpr::createAdd(Expr,
92e6d15924SDimitry Andric MCConstantExpr::create(Offset, Ctx), Ctx);
93e6d15924SDimitry Andric }
94b915e9e0SDimitry Andric MCOp = MCOperand::createExpr(Expr);
95b915e9e0SDimitry Andric return true;
96b915e9e0SDimitry Andric }
97b915e9e0SDimitry Andric case MachineOperand::MO_ExternalSymbol: {
98b915e9e0SDimitry Andric MCSymbol *Sym = Ctx.getOrCreateSymbol(StringRef(MO.getSymbolName()));
99b915e9e0SDimitry Andric const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
100b915e9e0SDimitry Andric MCOp = MCOperand::createExpr(Expr);
101b915e9e0SDimitry Andric return true;
102b915e9e0SDimitry Andric }
103044eb2f6SDimitry Andric case MachineOperand::MO_RegisterMask:
104044eb2f6SDimitry Andric // Regmasks are like implicit defs.
105044eb2f6SDimitry Andric return false;
106344a3780SDimitry Andric case MachineOperand::MO_MCSymbol:
107344a3780SDimitry Andric if (MO.getTargetFlags() == SIInstrInfo::MO_FAR_BRANCH_OFFSET) {
108344a3780SDimitry Andric MCSymbol *Sym = MO.getMCSymbol();
109344a3780SDimitry Andric MCOp = MCOperand::createExpr(Sym->getVariableValue());
110344a3780SDimitry Andric return true;
11101095a5dSDimitry Andric }
112344a3780SDimitry Andric break;
113344a3780SDimitry Andric }
114344a3780SDimitry Andric llvm_unreachable("unknown operand type");
11501095a5dSDimitry Andric }
1164a16efa3SDimitry Andric
lower(const MachineInstr * MI,MCInst & OutMI) const1174a16efa3SDimitry Andric void AMDGPUMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
118b5630dbaSDimitry Andric unsigned Opcode = MI->getOpcode();
119eb11fae6SDimitry Andric const auto *TII = static_cast<const SIInstrInfo*>(ST.getInstrInfo());
1204a16efa3SDimitry Andric
121b5630dbaSDimitry Andric // FIXME: Should be able to handle this with emitPseudoExpansionLowering. We
122b5630dbaSDimitry Andric // need to select it to the subtarget specific version, and there's no way to
123b5630dbaSDimitry Andric // do that with a single pseudo source operation.
124145449b1SDimitry Andric if (Opcode == AMDGPU::S_SETPC_B64_return)
125b5630dbaSDimitry Andric Opcode = AMDGPU::S_SETPC_B64;
126044eb2f6SDimitry Andric else if (Opcode == AMDGPU::SI_CALL) {
127044eb2f6SDimitry Andric // SI_CALL is just S_SWAPPC_B64 with an additional operand to track the
128044eb2f6SDimitry Andric // called function (which we need to remove here).
129044eb2f6SDimitry Andric OutMI.setOpcode(TII->pseudoToMCOpcode(AMDGPU::S_SWAPPC_B64));
130044eb2f6SDimitry Andric MCOperand Dest, Src;
131044eb2f6SDimitry Andric lowerOperand(MI->getOperand(0), Dest);
132044eb2f6SDimitry Andric lowerOperand(MI->getOperand(1), Src);
133044eb2f6SDimitry Andric OutMI.addOperand(Dest);
134044eb2f6SDimitry Andric OutMI.addOperand(Src);
135044eb2f6SDimitry Andric return;
1367fa27ce4SDimitry Andric } else if (Opcode == AMDGPU::SI_TCRETURN ||
1377fa27ce4SDimitry Andric Opcode == AMDGPU::SI_TCRETURN_GFX) {
138044eb2f6SDimitry Andric // TODO: How to use branch immediate and avoid register+add?
139044eb2f6SDimitry Andric Opcode = AMDGPU::S_SETPC_B64;
140044eb2f6SDimitry Andric }
141ec304151SDimitry Andric
142044eb2f6SDimitry Andric int MCOpcode = TII->pseudoToMCOpcode(Opcode);
143ec304151SDimitry Andric if (MCOpcode == -1) {
144044eb2f6SDimitry Andric LLVMContext &C = MI->getParent()->getParent()->getFunction().getContext();
145ec304151SDimitry Andric C.emitError("AMDGPUMCInstLower::lower - Pseudo instruction doesn't have "
146ec304151SDimitry Andric "a target-specific version: " + Twine(MI->getOpcode()));
147ec304151SDimitry Andric }
148ec304151SDimitry Andric
149ec304151SDimitry Andric OutMI.setOpcode(MCOpcode);
1504a16efa3SDimitry Andric
1515ca98fd9SDimitry Andric for (const MachineOperand &MO : MI->explicit_operands()) {
1524a16efa3SDimitry Andric MCOperand MCOp;
153b915e9e0SDimitry Andric lowerOperand(MO, MCOp);
1544a16efa3SDimitry Andric OutMI.addOperand(MCOp);
1554a16efa3SDimitry Andric }
1561d5ae102SDimitry Andric
1571d5ae102SDimitry Andric int FIIdx = AMDGPU::getNamedOperandIdx(MCOpcode, AMDGPU::OpName::fi);
1581d5ae102SDimitry Andric if (FIIdx >= (int)OutMI.getNumOperands())
1591d5ae102SDimitry Andric OutMI.addOperand(MCOperand::createImm(0));
1604a16efa3SDimitry Andric }
1614a16efa3SDimitry Andric
lowerOperand(const MachineOperand & MO,MCOperand & MCOp) const162b915e9e0SDimitry Andric bool AMDGPUAsmPrinter::lowerOperand(const MachineOperand &MO,
163b915e9e0SDimitry Andric MCOperand &MCOp) const {
164eb11fae6SDimitry Andric const GCNSubtarget &STI = MF->getSubtarget<GCNSubtarget>();
165b915e9e0SDimitry Andric AMDGPUMCInstLower MCInstLowering(OutContext, STI, *this);
166b915e9e0SDimitry Andric return MCInstLowering.lowerOperand(MO, MCOp);
167b915e9e0SDimitry Andric }
168b915e9e0SDimitry Andric
lowerConstant(const Constant * CV)169eb11fae6SDimitry Andric const MCExpr *AMDGPUAsmPrinter::lowerConstant(const Constant *CV) {
170e3b55780SDimitry Andric
171e3b55780SDimitry Andric // Intercept LDS variables with known addresses
1727fa27ce4SDimitry Andric if (const GlobalVariable *GV = dyn_cast<const GlobalVariable>(CV)) {
1737fa27ce4SDimitry Andric if (std::optional<uint32_t> Address =
1747fa27ce4SDimitry Andric AMDGPUMachineFunction::getLDSAbsoluteAddress(*GV)) {
1757fa27ce4SDimitry Andric auto *IntTy = Type::getInt32Ty(CV->getContext());
1767fa27ce4SDimitry Andric return AsmPrinter::lowerConstant(ConstantInt::get(IntTy, *Address));
177e3b55780SDimitry Andric }
178e3b55780SDimitry Andric }
179e3b55780SDimitry Andric
180eb11fae6SDimitry Andric if (const MCExpr *E = lowerAddrSpaceCast(TM, CV, OutContext))
181eb11fae6SDimitry Andric return E;
18271d5a254SDimitry Andric return AsmPrinter::lowerConstant(CV);
18371d5a254SDimitry Andric }
18471d5a254SDimitry Andric
emitInstruction(const MachineInstr * MI)185cfca06d7SDimitry Andric void AMDGPUAsmPrinter::emitInstruction(const MachineInstr *MI) {
1861f917f69SDimitry Andric // FIXME: Enable feature predicate checks once all the test pass.
1871f917f69SDimitry Andric // AMDGPU_MC::verifyInstructionPredicates(MI->getOpcode(),
1881f917f69SDimitry Andric // getSubtargetInfo().getFeatureBits());
1891f917f69SDimitry Andric
190b915e9e0SDimitry Andric if (emitPseudoExpansionLowering(*OutStreamer, MI))
191b915e9e0SDimitry Andric return;
192b915e9e0SDimitry Andric
193eb11fae6SDimitry Andric const GCNSubtarget &STI = MF->getSubtarget<GCNSubtarget>();
194b915e9e0SDimitry Andric AMDGPUMCInstLower MCInstLowering(OutContext, STI, *this);
1954a16efa3SDimitry Andric
1965ca98fd9SDimitry Andric StringRef Err;
19701095a5dSDimitry Andric if (!STI.getInstrInfo()->verifyInstruction(*MI, Err)) {
198044eb2f6SDimitry Andric LLVMContext &C = MI->getParent()->getParent()->getFunction().getContext();
19901095a5dSDimitry Andric C.emitError("Illegal instruction detected: " + Err);
20071d5a254SDimitry Andric MI->print(errs());
2015ca98fd9SDimitry Andric }
20201095a5dSDimitry Andric
2034a16efa3SDimitry Andric if (MI->isBundle()) {
2044a16efa3SDimitry Andric const MachineBasicBlock *MBB = MI->getParent();
205dd58ef01SDimitry Andric MachineBasicBlock::const_instr_iterator I = ++MI->getIterator();
206dd58ef01SDimitry Andric while (I != MBB->instr_end() && I->isInsideBundle()) {
207cfca06d7SDimitry Andric emitInstruction(&*I);
2084a16efa3SDimitry Andric ++I;
2094a16efa3SDimitry Andric }
2104a16efa3SDimitry Andric } else {
211344a3780SDimitry Andric // We don't want these pseudo instructions encoded. They are
21271d5a254SDimitry Andric // placeholder terminator instructions and should only be printed as
21371d5a254SDimitry Andric // comments.
21471d5a254SDimitry Andric if (MI->getOpcode() == AMDGPU::SI_RETURN_TO_EPILOG) {
21501095a5dSDimitry Andric if (isVerbose())
21671d5a254SDimitry Andric OutStreamer->emitRawComment(" return to shader part epilog");
21701095a5dSDimitry Andric return;
21801095a5dSDimitry Andric }
21901095a5dSDimitry Andric
220b915e9e0SDimitry Andric if (MI->getOpcode() == AMDGPU::WAVE_BARRIER) {
221b915e9e0SDimitry Andric if (isVerbose())
222b915e9e0SDimitry Andric OutStreamer->emitRawComment(" wave barrier");
223b915e9e0SDimitry Andric return;
224b915e9e0SDimitry Andric }
225b915e9e0SDimitry Andric
226145449b1SDimitry Andric if (MI->getOpcode() == AMDGPU::SCHED_BARRIER) {
227145449b1SDimitry Andric if (isVerbose()) {
228145449b1SDimitry Andric std::string HexString;
229145449b1SDimitry Andric raw_string_ostream HexStream(HexString);
230145449b1SDimitry Andric HexStream << format_hex(MI->getOperand(0).getImm(), 10, true);
231145449b1SDimitry Andric OutStreamer->emitRawComment(" sched_barrier mask(" + HexString + ")");
232145449b1SDimitry Andric }
233145449b1SDimitry Andric return;
234145449b1SDimitry Andric }
235145449b1SDimitry Andric
236e3b55780SDimitry Andric if (MI->getOpcode() == AMDGPU::SCHED_GROUP_BARRIER) {
237e3b55780SDimitry Andric if (isVerbose()) {
238e3b55780SDimitry Andric std::string HexString;
239e3b55780SDimitry Andric raw_string_ostream HexStream(HexString);
240e3b55780SDimitry Andric HexStream << format_hex(MI->getOperand(0).getImm(), 10, true);
241e3b55780SDimitry Andric OutStreamer->emitRawComment(
242e3b55780SDimitry Andric " sched_group_barrier mask(" + HexString + ") size(" +
243e3b55780SDimitry Andric Twine(MI->getOperand(1).getImm()) + ") SyncID(" +
244e3b55780SDimitry Andric Twine(MI->getOperand(2).getImm()) + ")");
245e3b55780SDimitry Andric }
246e3b55780SDimitry Andric return;
247e3b55780SDimitry Andric }
248e3b55780SDimitry Andric
249e3b55780SDimitry Andric if (MI->getOpcode() == AMDGPU::IGLP_OPT) {
250e3b55780SDimitry Andric if (isVerbose()) {
251e3b55780SDimitry Andric std::string HexString;
252e3b55780SDimitry Andric raw_string_ostream HexStream(HexString);
253e3b55780SDimitry Andric HexStream << format_hex(MI->getOperand(0).getImm(), 10, true);
254e3b55780SDimitry Andric OutStreamer->emitRawComment(" iglp_opt mask(" + HexString + ")");
255e3b55780SDimitry Andric }
256e3b55780SDimitry Andric return;
257e3b55780SDimitry Andric }
258e3b55780SDimitry Andric
25912f3ca4cSDimitry Andric if (MI->getOpcode() == AMDGPU::SI_MASKED_UNREACHABLE) {
26012f3ca4cSDimitry Andric if (isVerbose())
26112f3ca4cSDimitry Andric OutStreamer->emitRawComment(" divergent unreachable");
26212f3ca4cSDimitry Andric return;
26312f3ca4cSDimitry Andric }
26412f3ca4cSDimitry Andric
265c0981da4SDimitry Andric if (MI->isMetaInstruction()) {
266c0981da4SDimitry Andric if (isVerbose())
267c0981da4SDimitry Andric OutStreamer->emitRawComment(" meta instruction");
268c0981da4SDimitry Andric return;
269c0981da4SDimitry Andric }
270c0981da4SDimitry Andric
2714a16efa3SDimitry Andric MCInst TmpInst;
2724a16efa3SDimitry Andric MCInstLowering.lower(MI, TmpInst);
2735a5ac124SDimitry Andric EmitToStreamer(*OutStreamer, TmpInst);
274f8af5cf6SDimitry Andric
275d8e91e46SDimitry Andric #ifdef EXPENSIVE_CHECKS
276c0981da4SDimitry Andric // Check getInstSizeInBytes on explicitly specified CPUs (it cannot
277d8e91e46SDimitry Andric // work correctly for the generic CPU).
278d8e91e46SDimitry Andric //
279d8e91e46SDimitry Andric // The isPseudo check really shouldn't be here, but unfortunately there are
280d8e91e46SDimitry Andric // some negative lit tests that depend on being able to continue through
281d8e91e46SDimitry Andric // here even when pseudo instructions haven't been lowered.
282b60736ecSDimitry Andric //
283b60736ecSDimitry Andric // We also overestimate branch sizes with the offset bug.
284b60736ecSDimitry Andric if (!MI->isPseudo() && STI.isCPUStringValid(STI.getCPU()) &&
285b60736ecSDimitry Andric (!STI.hasOffset3fBug() || !MI->isBranch())) {
286d8e91e46SDimitry Andric SmallVector<MCFixup, 4> Fixups;
287d8e91e46SDimitry Andric SmallVector<char, 16> CodeBytes;
288d8e91e46SDimitry Andric
2897fa27ce4SDimitry Andric std::unique_ptr<MCCodeEmitter> InstEmitter(createAMDGPUMCCodeEmitter(
290145449b1SDimitry Andric *STI.getInstrInfo(), OutContext));
2917fa27ce4SDimitry Andric InstEmitter->encodeInstruction(TmpInst, CodeBytes, Fixups, STI);
292d8e91e46SDimitry Andric
293d8e91e46SDimitry Andric assert(CodeBytes.size() == STI.getInstrInfo()->getInstSizeInBytes(*MI));
294d8e91e46SDimitry Andric }
295d8e91e46SDimitry Andric #endif
296d8e91e46SDimitry Andric
297e6d15924SDimitry Andric if (DumpCodeInstEmitter) {
298e6d15924SDimitry Andric // Disassemble instruction/operands to text
299f8af5cf6SDimitry Andric DisasmLines.resize(DisasmLines.size() + 1);
300f8af5cf6SDimitry Andric std::string &DisasmLine = DisasmLines.back();
301f8af5cf6SDimitry Andric raw_string_ostream DisasmStream(DisasmLine);
302f8af5cf6SDimitry Andric
303e6d15924SDimitry Andric AMDGPUInstPrinter InstPrinter(*TM.getMCAsmInfo(), *STI.getInstrInfo(),
30401095a5dSDimitry Andric *STI.getRegisterInfo());
305706b4fc4SDimitry Andric InstPrinter.printInst(&TmpInst, 0, StringRef(), STI, DisasmStream);
306f8af5cf6SDimitry Andric
307f8af5cf6SDimitry Andric // Disassemble instruction/operands to hex representation.
308f8af5cf6SDimitry Andric SmallVector<MCFixup, 4> Fixups;
309f8af5cf6SDimitry Andric SmallVector<char, 16> CodeBytes;
310f8af5cf6SDimitry Andric
311e6d15924SDimitry Andric DumpCodeInstEmitter->encodeInstruction(
3127fa27ce4SDimitry Andric TmpInst, CodeBytes, Fixups, MF->getSubtarget<MCSubtargetInfo>());
313f8af5cf6SDimitry Andric HexLines.resize(HexLines.size() + 1);
314f8af5cf6SDimitry Andric std::string &HexLine = HexLines.back();
315f8af5cf6SDimitry Andric raw_string_ostream HexStream(HexLine);
316f8af5cf6SDimitry Andric
317f8af5cf6SDimitry Andric for (size_t i = 0; i < CodeBytes.size(); i += 4) {
318f8af5cf6SDimitry Andric unsigned int CodeDWord = *(unsigned int *)&CodeBytes[i];
319f8af5cf6SDimitry Andric HexStream << format("%s%08X", (i > 0 ? " " : ""), CodeDWord);
320f8af5cf6SDimitry Andric }
321f8af5cf6SDimitry Andric
322f8af5cf6SDimitry Andric DisasmStream.flush();
323f8af5cf6SDimitry Andric DisasmLineMaxLen = std::max(DisasmLineMaxLen, DisasmLine.size());
324f8af5cf6SDimitry Andric }
3254a16efa3SDimitry Andric }
3264a16efa3SDimitry Andric }
327