source: CLRX/CLRadeonExtender/trunk/amdasm/DisasmROCm.cpp @ 2559

Last change on this file since 2559 was 2559, checked in by matszpk, 3 years ago

CLRadeonExtender: DisasmROCm: Fixed valgrind warning (invalid read).

File size: 21.5 KB
Line 
1/*
2 *  CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3 *  Copyright (C) 2014-2016 Mateusz Szpakowski
4 *
5 *  This library is free software; you can redistribute it and/or
6 *  modify it under the terms of the GNU Lesser General Public
7 *  License as published by the Free Software Foundation; either
8 *  version 2.1 of the License, or (at your option) any later version.
9 *
10 *  This library is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 *  Lesser General Public License for more details.
14 *
15 *  You should have received a copy of the GNU Lesser General Public
16 *  License along with this library; if not, write to the Free Software
17 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20#include <CLRX/Config.h>
21#include <cstdint>
22#include <cstdio>
23#include <inttypes.h>
24#include <string>
25#include <ostream>
26#include <memory>
27#include <vector>
28#include <utility>
29#include <CLRX/utils/Utilities.h>
30#include <CLRX/utils/MemAccess.h>
31#include <CLRX/amdbin/ROCmBinaries.h>
32#include <CLRX/amdasm/Disassembler.h>
33#include <CLRX/utils/GPUId.h>
34#include "DisasmInternals.h"
35
36using namespace CLRX;
37
38struct AMDGPUArchValues
39{
40    uint32_t major;
41    uint32_t minor;
42    uint32_t stepping;
43    GPUDeviceType deviceType;
44};
45
46static const AMDGPUArchValues amdGpuArchValuesTbl[] =
47{
48    { 0, 0, 0, GPUDeviceType::CAPE_VERDE },
49    { 7, 0, 0, GPUDeviceType::BONAIRE },
50    { 7, 0, 1, GPUDeviceType::HAWAII },
51    { 8, 0, 0, GPUDeviceType::ICELAND },
52    { 8, 0, 1, GPUDeviceType::CARRIZO },
53    { 8, 0, 2, GPUDeviceType::ICELAND },
54    { 8, 0, 3, GPUDeviceType::FIJI },
55    { 8, 0, 4, GPUDeviceType::FIJI },
56    { 8, 1, 0, GPUDeviceType::STONEY }
57};
58
59static const size_t amdGpuArchValuesNum = sizeof(amdGpuArchValuesTbl) /
60                sizeof(AMDGPUArchValues);
61
62ROCmDisasmInput* CLRX::getROCmDisasmInputFromBinary(const ROCmBinary& binary)
63{
64    std::unique_ptr<ROCmDisasmInput> input(new ROCmDisasmInput);
65    uint32_t archMajor = 0;
66    input->archMinor = 0;
67    input->archStepping = 0;
68   
69    {
70        const cxbyte* noteContent = (const cxbyte*)binary.getNotes();
71        if (noteContent==nullptr)
72            throw Exception("Missing notes in inner binary!");
73        size_t notesSize = binary.getNotesSize();
74        // find note about AMDGPU
75        for (size_t offset = 0; offset < notesSize; )
76        {
77            const Elf64_Nhdr* nhdr = (const Elf64_Nhdr*)(noteContent + offset);
78            size_t namesz = ULEV(nhdr->n_namesz);
79            size_t descsz = ULEV(nhdr->n_descsz);
80            if (usumGt(offset, namesz+descsz, notesSize))
81                throw Exception("Note offset+size out of range");
82            if (ULEV(nhdr->n_type) == 0x3 && namesz==4 && descsz>=0x1a &&
83                ::strcmp((const char*)noteContent+offset+sizeof(Elf64_Nhdr), "AMD")==0)
84            {    // AMDGPU type
85                const uint32_t* content = (const uint32_t*)
86                        (noteContent+offset+sizeof(Elf64_Nhdr) + 4);
87                archMajor = ULEV(content[1]);
88                input->archMinor = ULEV(content[2]);
89                input->archStepping = ULEV(content[3]);
90            }
91            size_t align = (((namesz+descsz)&3)!=0) ? 4-((namesz+descsz)&3) : 0;
92            offset += sizeof(Elf64_Nhdr) + namesz + descsz + align;
93        }
94    }
95    // determine device type
96    input->deviceType = GPUDeviceType::CAPE_VERDE;
97    if (archMajor==0)
98        input->deviceType = GPUDeviceType::CAPE_VERDE;
99    else if (archMajor==7)
100        input->deviceType = GPUDeviceType::BONAIRE;
101    else if (archMajor==8)
102        input->deviceType = GPUDeviceType::ICELAND;
103   
104    for (cxuint i = 0; i < amdGpuArchValuesNum; i++)
105        if (amdGpuArchValuesTbl[i].major==archMajor &&
106            amdGpuArchValuesTbl[i].minor==input->archMinor &&
107            amdGpuArchValuesTbl[i].stepping==input->archStepping)
108        {
109            input->deviceType = amdGpuArchValuesTbl[i].deviceType;
110            break;
111        }
112   
113    const size_t regionsNum = binary.getRegionsNum();
114    input->regions.resize(regionsNum);
115    size_t codeOffset = binary.getCode()-binary.getBinaryCode();
116    for (size_t i = 0; i < regionsNum; i++)
117    {
118        const ROCmRegion& region = binary.getRegion(i);
119        input->regions[i] = { region.regionName, size_t(region.size),
120            size_t(region.offset - codeOffset), region.isKernel };
121    }
122   
123    input->code = binary.getCode();
124    input->codeSize = binary.getCodeSize();
125    return input.release();
126}
127
128static void dumpKernelConfig(std::ostream& output, cxuint maxSgprsNum,
129             GPUArchitecture arch, const ROCmKernelConfig& config)
130{
131    output.write("    .config\n", 12);
132    // convert to native-endian
133    uint32_t amdCodeVersionMajor = ULEV(config.amdCodeVersionMajor);
134    uint32_t amdCodeVersionMinor = ULEV(config.amdCodeVersionMinor);
135    uint16_t amdMachineKind = ULEV(config.amdMachineKind);
136    uint16_t amdMachineMajor = ULEV(config.amdMachineMajor);
137    uint16_t amdMachineMinor = ULEV(config.amdMachineMinor);
138    uint16_t amdMachineStepping = ULEV(config.amdMachineStepping);
139    uint64_t kernelCodeEntryOffset = ULEV(config.kernelCodeEntryOffset);
140    uint64_t kernelCodePrefetchOffset = ULEV(config.kernelCodePrefetchOffset);
141    uint64_t kernelCodePrefetchSize = ULEV(config.kernelCodePrefetchSize);
142    uint64_t maxScrachBackingMemorySize = ULEV(config.maxScrachBackingMemorySize);
143    uint32_t computePgmRsrc1 = ULEV(config.computePgmRsrc1);
144    uint32_t computePgmRsrc2 = ULEV(config.computePgmRsrc2);
145    uint16_t enableSpgrRegisterFlags = ULEV(config.enableSpgrRegisterFlags);
146    uint16_t enableFeatureFlags = ULEV(config.enableFeatureFlags);
147    uint32_t workitemPrivateSegmentSize = ULEV(config.workitemPrivateSegmentSize);
148    uint32_t workgroupGroupSegmentSize = ULEV(config.workgroupGroupSegmentSize);
149    uint32_t gdsSegmentSize = ULEV(config.gdsSegmentSize);
150    uint64_t kernargSegmentSize = ULEV(config.kernargSegmentSize);
151    uint32_t workgroupFbarrierCount = ULEV(config.workgroupFbarrierCount);
152    uint16_t wavefrontSgprCount = ULEV(config.wavefrontSgprCount);
153    uint16_t workitemVgprCount = ULEV(config.workitemVgprCount);
154    uint16_t reservedVgprFirst = ULEV(config.reservedVgprFirst);
155    uint16_t reservedVgprCount = ULEV(config.reservedVgprCount);
156    uint16_t reservedSgprFirst = ULEV(config.reservedSgprFirst);
157    uint16_t reservedSgprCount = ULEV(config.reservedSgprCount);
158    uint16_t debugWavefrontPrivateSegmentOffsetSgpr =
159            ULEV(config.debugWavefrontPrivateSegmentOffsetSgpr);
160    uint16_t debugPrivateSegmentBufferSgpr = ULEV(config.debugPrivateSegmentBufferSgpr);
161    uint32_t callConvention = ULEV(config.callConvention);
162    uint64_t runtimeLoaderKernelSymbol = ULEV(config.runtimeLoaderKernelSymbol);
163   
164    size_t bufSize;
165    char buf[100];
166    const cxuint ldsShift = arch<GPUArchitecture::GCN1_1 ? 8 : 9;
167    const uint32_t pgmRsrc1 = computePgmRsrc1;
168    const uint32_t pgmRsrc2 = computePgmRsrc2;
169   
170    const cxuint dimMask = (pgmRsrc2 >> 7) & 7;
171    strcpy(buf, "        .dims ");
172    bufSize = 14;
173    if ((dimMask & 1) != 0)
174        buf[bufSize++] = 'x';
175    if ((dimMask & 2) != 0)
176        buf[bufSize++] = 'y';
177    if ((dimMask & 4) != 0)
178        buf[bufSize++] = 'z';
179    buf[bufSize++] = '\n';
180    output.write(buf, bufSize);
181   
182    bufSize = snprintf(buf, 100, "        .sgprsnum %u\n",
183              std::min((((pgmRsrc1>>6) & 0xf)<<3)+8, maxSgprsNum));
184    output.write(buf, bufSize);
185    bufSize = snprintf(buf, 100, "        .vgprsnum %u\n", ((pgmRsrc1 & 0x3f)<<2)+4);
186    output.write(buf, bufSize);
187    if ((pgmRsrc1 & (1U<<20)) != 0)
188        output.write("        .privmode\n", 18);
189    if ((pgmRsrc1 & (1U<<22)) != 0)
190        output.write("        .debugmode\n", 19);
191    if ((pgmRsrc1 & (1U<<21)) != 0)
192        output.write("        .dx10clamp\n", 19);
193    if ((pgmRsrc1 & (1U<<23)) != 0)
194        output.write("        .ieeemode\n", 18);
195    if ((pgmRsrc2 & 0x400) != 0)
196        output.write("        .tgsize\n", 16);
197   
198    bufSize = snprintf(buf, 100, "        .floatmode 0x%02x\n", (pgmRsrc1>>12) & 0xff);
199    output.write(buf, bufSize);
200    bufSize = snprintf(buf, 100, "        .priority %u\n", (pgmRsrc1>>10) & 3);
201    output.write(buf, bufSize);
202    if (((pgmRsrc1>>24) & 0x7f) != 0)
203    {
204        bufSize = snprintf(buf, 100, "        .exceptions 0x%02x\n",
205                   (pgmRsrc1>>24) & 0x7f);
206        output.write(buf, bufSize);
207    }
208    const cxuint localSize = ((pgmRsrc2>>15) & 0x1ff) << ldsShift;
209    if (localSize!=0)
210    {
211        bufSize = snprintf(buf, 100, "        .localsize %u\n", localSize);
212        output.write(buf, bufSize);
213    }
214    bufSize = snprintf(buf, 100, "        .userdatanum %u\n", (pgmRsrc2>>1) & 0x1f);
215    output.write(buf, bufSize);
216   
217    bufSize = snprintf(buf, 100, "        .pgmrsrc1 0x%08x\n", pgmRsrc1);
218    output.write(buf, bufSize);
219    bufSize = snprintf(buf, 100, "        .pgmrsrc2 0x%08x\n", pgmRsrc2);
220    output.write(buf, bufSize);
221   
222    bufSize = snprintf(buf, 100, "        .codeversion %u, %u\n",
223                   amdCodeVersionMajor, amdCodeVersionMinor);
224    output.write(buf, bufSize);
225    bufSize = snprintf(buf, 100, "        .machine %hu, %hu, %hu, %hu\n",
226                   amdMachineKind, amdMachineMajor,
227                   amdMachineMinor, amdMachineStepping);
228    output.write(buf, bufSize);
229    bufSize = snprintf(buf, 100, "        .kernel_code_entry_offset 0x%" PRIx64 "\n",
230                       kernelCodeEntryOffset);
231    output.write(buf, bufSize);
232    if (kernelCodePrefetchOffset!=0)
233    {
234        bufSize = snprintf(buf, 100,
235                   "        .kernel_code_prefetch_offset 0x%" PRIx64 "\n",
236                           kernelCodePrefetchOffset);
237        output.write(buf, bufSize);
238    }
239    if (kernelCodePrefetchSize!=0)
240    {
241        bufSize = snprintf(buf, 100, "        .kernel_code_prefetch_size %" PRIu64 "\n",
242                           kernelCodePrefetchSize);
243        output.write(buf, bufSize);
244    }
245    if (maxScrachBackingMemorySize!=0)
246    {
247        bufSize = snprintf(buf, 100, "        .max_scratch_backing_memory %" PRIu64 "\n",
248                           maxScrachBackingMemorySize);
249        output.write(buf, bufSize);
250    }
251   
252    const uint16_t sgprFlags = enableSpgrRegisterFlags;
253    if ((sgprFlags&1) != 0)
254        output.write("        .use_private_segment_buffer\n", 36);
255    if ((sgprFlags&2) != 0)
256        output.write("        .use_dispatch_ptr\n", 26);
257    if ((sgprFlags&4) != 0)
258        output.write("        .use_queue_ptr\n", 24);
259    if ((sgprFlags&8) != 0)
260        output.write("        .use_kernarg_segment_ptr\n", 33);
261    if ((sgprFlags&16) != 0)
262        output.write("        .use_dispatch_id\n", 25);
263    if ((sgprFlags&32) != 0)
264        output.write("        .use_flat_scratch_init\n", 31);
265    if ((sgprFlags&64) != 0)
266        output.write("        .use_private_segment_size\n", 34);
267    if ((sgprFlags&128) != 0)
268        output.write("        .use_grid_workgroup_count_x\n", 36);
269    if ((sgprFlags&256) != 0)
270        output.write("        .use_grid_workgroup_count_y\n", 36);
271    if ((sgprFlags&512) != 0)
272        output.write("        .use_grid_workgroup_count_z\n", 36);
273    const uint16_t featureFlags = enableFeatureFlags;
274    if ((featureFlags&1) != 0)
275        output.write("        .use_ordered_append_gds\n", 32);
276    bufSize = snprintf(buf, 100, "        .private_elem_size %u\n",
277                       2U<<((featureFlags>>1)&3));
278    output.write(buf, bufSize);
279    if ((featureFlags&8) != 0)
280        output.write("        .use_ptr64\n", 19);
281    if ((featureFlags&16) != 0)
282        output.write("        .use_dynamic_call_stack\n", 32);
283    if ((featureFlags&32) != 0)
284        output.write("        .use_debug_enabled\n", 27);
285    if ((featureFlags&64) != 0)
286        output.write("        .use_xnack_enabled\n", 27);
287   
288    if (workitemPrivateSegmentSize!=0)
289    {
290        bufSize = snprintf(buf, 100, "        .workitem_private_segment_size %u\n",
291                         workitemPrivateSegmentSize);
292        output.write(buf, bufSize);
293    }
294    if (workgroupGroupSegmentSize!=0)
295    {
296        bufSize = snprintf(buf, 100, "        .workgroup_group_segment_size %u\n",
297                         workgroupGroupSegmentSize);
298        output.write(buf, bufSize);
299    }
300    if (gdsSegmentSize!=0)
301    {
302        bufSize = snprintf(buf, 100, "        .gds_segment_size %u\n",
303                         gdsSegmentSize);
304        output.write(buf, bufSize);
305    }
306    if (kernargSegmentSize!=0)
307    {
308        bufSize = snprintf(buf, 100, "        .kernarg_segment_size %" PRIu64 "\n",
309                         kernargSegmentSize);
310        output.write(buf, bufSize);
311    }
312    if (workgroupFbarrierCount!=0)
313    {
314        bufSize = snprintf(buf, 100, "        .workgroup_fbarrier_count %u\n",
315                         workgroupFbarrierCount);
316        output.write(buf, bufSize);
317    }
318    if (wavefrontSgprCount!=0)
319    {
320        bufSize = snprintf(buf, 100, "        .wavefront_sgpr_count %hu\n",
321                         wavefrontSgprCount);
322        output.write(buf, bufSize);
323    }
324    if (workitemVgprCount!=0)
325    {
326        bufSize = snprintf(buf, 100, "        .workitem_vgpr_count %hu\n",
327                         workitemVgprCount);
328        output.write(buf, bufSize);
329    }
330    if (reservedVgprFirst!=0)
331    {
332        bufSize = snprintf(buf, 100, "        .reserved_vgpr_first %hu\n",
333                         reservedVgprFirst);
334        output.write(buf, bufSize);
335    }
336    if (reservedVgprCount!=0)
337    {
338        bufSize = snprintf(buf, 100, "        .reserved_vgpr_count %hu\n",
339                         reservedVgprCount);
340        output.write(buf, bufSize);
341    }
342    if (reservedSgprFirst!=0)
343    {
344        bufSize = snprintf(buf, 100, "        .reserved_sgpr_first %hu\n",
345                         reservedSgprFirst);
346        output.write(buf, bufSize);
347    }
348    if (reservedSgprCount!=0)
349    {
350        bufSize = snprintf(buf, 100, "        .reserved_sgpr_count %hu\n",
351                         reservedSgprCount);
352        output.write(buf, bufSize);
353    }
354    if (debugWavefrontPrivateSegmentOffsetSgpr!=0)
355    {
356        bufSize = snprintf(buf, 100, "        "
357                        ".debug_wavefront_private_segment_offset_sgpr %hu\n",
358                         debugWavefrontPrivateSegmentOffsetSgpr);
359        output.write(buf, bufSize);
360    }
361    if (debugPrivateSegmentBufferSgpr!=0)
362    {
363        bufSize = snprintf(buf, 100, "        .debug_private_segment_buffer_sgpr %hu\n",
364                         debugPrivateSegmentBufferSgpr);
365        output.write(buf, bufSize);
366    }
367    bufSize = snprintf(buf, 100, "        .kernarg_segment_align %u\n",
368                     1U<<(config.kernargSegmentAlignment));
369    output.write(buf, bufSize);
370    bufSize = snprintf(buf, 100, "        .group_segment_align %u\n",
371                     1U<<(config.groupSegmentAlignment));
372    output.write(buf, bufSize);
373    bufSize = snprintf(buf, 100, "        .private_segment_align %u\n",
374                     1U<<(config.privateSegmentAlignment));
375    output.write(buf, bufSize);
376    bufSize = snprintf(buf, 100, "        .wavefront_size %u\n",
377                     1U<<(config.wavefrontSize));
378    output.write(buf, bufSize);
379    bufSize = snprintf(buf, 100, "        .call_convention 0x%x\n",
380                     callConvention);
381    output.write(buf, bufSize);
382    if (runtimeLoaderKernelSymbol!=0)
383    {
384        bufSize = snprintf(buf, 100,
385                   "        .runtime_loader_kernel_symbol 0x%" PRIx64 "\n",
386                         runtimeLoaderKernelSymbol);
387        output.write(buf, bufSize);
388    }
389    // new section, control_directive, outside .config
390    output.write("    .control_directive\n", 23);
391    printDisasmData(sizeof config.controlDirective, config.controlDirective, output, true);
392}
393
394void CLRX::disassembleROCm(std::ostream& output, const ROCmDisasmInput* rocmInput,
395           ISADisassembler* isaDisassembler, size_t& sectionCount, Flags flags)
396{
397    const bool doDumpData = ((flags & DISASM_DUMPDATA) != 0);
398    const bool doMetadata = ((flags & (DISASM_METADATA|DISASM_CONFIG)) != 0);
399    const bool doDumpCode = ((flags & DISASM_DUMPCODE) != 0);
400    const bool doDumpConfig = ((flags & DISASM_CONFIG) != 0);
401   
402    const GPUArchitecture arch = getGPUArchitectureFromDeviceType(rocmInput->deviceType);
403    const cxuint maxSgprsNum = getGPUMaxRegistersNum(arch, REGTYPE_SGPR, 0);
404   
405    {
406        char buf[40];
407        size_t size = snprintf(buf, 40, ".arch_minor %u\n", rocmInput->archMinor);
408        output.write(buf, size);
409        size = snprintf(buf, 40, ".arch_stepping %u\n", rocmInput->archStepping);
410        output.write(buf, size);
411    }
412   
413    for (const ROCmDisasmRegionInput& rinput: rocmInput->regions)
414        if (rinput.isKernel)
415        {
416            output.write(".kernel ", 8);
417            output.write(rinput.regionName.c_str(), rinput.regionName.size());
418            output.put('\n');
419            if (doMetadata && doDumpConfig)
420                dumpKernelConfig(output, maxSgprsNum, arch,
421                     *reinterpret_cast<const ROCmKernelConfig*>(
422                             rocmInput->code + rinput.offset));
423        }
424   
425    const size_t regionsNum = rocmInput->regions.size();
426    typedef std::pair<size_t, size_t> SortEntry;
427    std::unique_ptr<SortEntry[]> sorted(new SortEntry[regionsNum]);
428    for (size_t i = 0; i < regionsNum; i++)
429        sorted[i] = std::make_pair(rocmInput->regions[i].offset, i);
430    mapSort(sorted.get(), sorted.get() + regionsNum);
431   
432    if (rocmInput->code != nullptr && rocmInput->codeSize != 0)
433    {
434        const cxbyte* code = rocmInput->code;
435        output.write(".text\n", 6);
436        // clear labels
437        isaDisassembler->clearNumberedLabels();
438       
439        /// analyze code with collecting labels
440        for (size_t i = 0; i < regionsNum; i++)
441        {
442            const ROCmDisasmRegionInput& region = rocmInput->regions[sorted[i].second];
443            if (region.isKernel && doDumpCode)
444            {
445                isaDisassembler->setInput(region.size-256, code + region.offset+256,
446                                    region.offset+256);
447                isaDisassembler->analyzeBeforeDisassemble();
448            }
449            isaDisassembler->addNamedLabel(region.offset, region.regionName);
450        }
451        isaDisassembler->prepareLabelsAndRelocations();
452       
453        ISADisassembler::LabelIter curLabel;
454        ISADisassembler::NamedLabelIter curNamedLabel;
455        const auto& labels = isaDisassembler->getLabels();
456        const auto& namedLabels = isaDisassembler->getNamedLabels();
457        // real disassemble
458        size_t prevRegionPos = 0;
459        for (size_t i = 0; i < regionsNum; i++)
460        {
461            const ROCmDisasmRegionInput& region = rocmInput->regions[sorted[i].second];
462            // set labelIters to previous position
463            isaDisassembler->setInput(prevRegionPos, code + region.offset,
464                                    region.offset, prevRegionPos);
465            curLabel = std::lower_bound(labels.begin(), labels.end(), prevRegionPos);
466            curNamedLabel = std::lower_bound(namedLabels.begin(), namedLabels.end(),
467                std::make_pair(prevRegionPos, CString()),
468                  [](const std::pair<size_t,CString>& a,
469                                 const std::pair<size_t, CString>& b)
470                  { return a.first < b.first; });
471            isaDisassembler->writeLabelsToPosition(0, curLabel, curNamedLabel);
472            isaDisassembler->flushOutput();
473           
474            if (region.isKernel)
475            {
476                if (doMetadata)
477                {
478                    if (!doDumpConfig)
479                        printDisasmData(0x100, code + region.offset, output, true);
480                    else    // skip, config was dumped in kernel configuration
481                        output.write(".skip 256\n", 10);
482                }
483               
484                size_t disasmSize = rocmInput->codeSize - region.offset-256;
485                if (i+1<regionsNum)
486                {
487                    const ROCmDisasmRegionInput& newRegion =
488                            rocmInput->regions[sorted[i+1].second];
489                    disasmSize = newRegion.offset - region.offset-256;
490                }
491               
492                if (doDumpCode)
493                {
494                    isaDisassembler->setInput(disasmSize, code + region.offset+256,
495                                    region.offset+256, region.offset+1);
496                    isaDisassembler->setDontPrintLabels(i+1<regionsNum);
497                    isaDisassembler->disassemble();
498                }
499                /* previous position 1 byte after kernel region
500                 * labels at end will be printed by 'disassemble' */
501                prevRegionPos = region.offset + disasmSize + 256 + 1;
502            }
503            else if (doDumpData)
504            {
505                output.write(".global ", 8);
506                output.write(region.regionName.c_str(), region.regionName.size());
507                output.write("\n", 1);
508                printDisasmData(region.size, code + region.offset, output, true);
509                prevRegionPos = region.offset+1; // previous position byte after region
510            }
511        }
512       
513        if (regionsNum!=0 && !rocmInput->regions[sorted[regionsNum-1].second].isKernel)
514        {   // if last region is kernel, then print labels after last region
515            const ROCmDisasmRegionInput& region =
516                        rocmInput->regions[sorted[regionsNum-1].second];
517            isaDisassembler->writeLabelsToEnd(region.size, curLabel, curNamedLabel);
518            isaDisassembler->flushOutput();
519        }
520    }
521}
Note: See TracBrowser for help on using the repository browser.