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

Last change on this file since 2586 was 2586, checked in by matszpk, 4 years ago

CLRadeonExtender: DisasmROCm: replace '.use_grid_workgroup_count_?' by single '.use_grid_workgroup_count' with dimesions specification.
AsmRocm?: Adding specific pseudo-ops.

File size: 21.3 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   
268    if ((sgprFlags&(7U<<7)) != 0)
269    {
270        strcpy(buf, "        .use_grid_workgroup_count ");
271        bufSize = 34;
272        if ((sgprFlags&128) != 0)
273            buf[bufSize++] = 'x';
274        if ((sgprFlags&256) != 0)
275            buf[bufSize++] = 'y';
276        if ((sgprFlags&512) != 0)
277            buf[bufSize++] = 'z';
278        buf[bufSize++] = '\n';
279        output.write(buf, bufSize);
280    }
281   
282    const uint16_t featureFlags = enableFeatureFlags;
283    if ((featureFlags&1) != 0)
284        output.write("        .use_ordered_append_gds\n", 32);
285    bufSize = snprintf(buf, 100, "        .private_elem_size %u\n",
286                       2U<<((featureFlags>>1)&3));
287    output.write(buf, bufSize);
288    if ((featureFlags&8) != 0)
289        output.write("        .use_ptr64\n", 19);
290    if ((featureFlags&16) != 0)
291        output.write("        .use_dynamic_call_stack\n", 32);
292    if ((featureFlags&32) != 0)
293        output.write("        .use_debug_enabled\n", 27);
294    if ((featureFlags&64) != 0)
295        output.write("        .use_xnack_enabled\n", 27);
296   
297    if (workitemPrivateSegmentSize!=0)
298    {
299        bufSize = snprintf(buf, 100, "        .workitem_private_segment_size %u\n",
300                         workitemPrivateSegmentSize);
301        output.write(buf, bufSize);
302    }
303    if (workgroupGroupSegmentSize!=0)
304    {
305        bufSize = snprintf(buf, 100, "        .workgroup_group_segment_size %u\n",
306                         workgroupGroupSegmentSize);
307        output.write(buf, bufSize);
308    }
309    if (gdsSegmentSize!=0)
310    {
311        bufSize = snprintf(buf, 100, "        .gds_segment_size %u\n",
312                         gdsSegmentSize);
313        output.write(buf, bufSize);
314    }
315    if (kernargSegmentSize!=0)
316    {
317        bufSize = snprintf(buf, 100, "        .kernarg_segment_size %" PRIu64 "\n",
318                         kernargSegmentSize);
319        output.write(buf, bufSize);
320    }
321    if (workgroupFbarrierCount!=0)
322    {
323        bufSize = snprintf(buf, 100, "        .workgroup_fbarrier_count %u\n",
324                         workgroupFbarrierCount);
325        output.write(buf, bufSize);
326    }
327    if (wavefrontSgprCount!=0)
328    {
329        bufSize = snprintf(buf, 100, "        .wavefront_sgpr_count %hu\n",
330                         wavefrontSgprCount);
331        output.write(buf, bufSize);
332    }
333    if (workitemVgprCount!=0)
334    {
335        bufSize = snprintf(buf, 100, "        .workitem_vgpr_count %hu\n",
336                         workitemVgprCount);
337        output.write(buf, bufSize);
338    }
339    if (reservedVgprFirst!=0)
340    {
341        bufSize = snprintf(buf, 100, "        .reserved_vgpr_first %hu\n",
342                         reservedVgprFirst);
343        output.write(buf, bufSize);
344    }
345    if (reservedVgprCount!=0)
346    {
347        bufSize = snprintf(buf, 100, "        .reserved_vgpr_count %hu\n",
348                         reservedVgprCount);
349        output.write(buf, bufSize);
350    }
351    if (reservedSgprFirst!=0)
352    {
353        bufSize = snprintf(buf, 100, "        .reserved_sgpr_first %hu\n",
354                         reservedSgprFirst);
355        output.write(buf, bufSize);
356    }
357    if (reservedSgprCount!=0)
358    {
359        bufSize = snprintf(buf, 100, "        .reserved_sgpr_count %hu\n",
360                         reservedSgprCount);
361        output.write(buf, bufSize);
362    }
363    if (debugWavefrontPrivateSegmentOffsetSgpr!=0)
364    {
365        bufSize = snprintf(buf, 100, "        "
366                        ".debug_wavefront_private_segment_offset_sgpr %hu\n",
367                         debugWavefrontPrivateSegmentOffsetSgpr);
368        output.write(buf, bufSize);
369    }
370    if (debugPrivateSegmentBufferSgpr!=0)
371    {
372        bufSize = snprintf(buf, 100, "        .debug_private_segment_buffer_sgpr %hu\n",
373                         debugPrivateSegmentBufferSgpr);
374        output.write(buf, bufSize);
375    }
376    bufSize = snprintf(buf, 100, "        .kernarg_segment_align %u\n",
377                     1U<<(config.kernargSegmentAlignment));
378    output.write(buf, bufSize);
379    bufSize = snprintf(buf, 100, "        .group_segment_align %u\n",
380                     1U<<(config.groupSegmentAlignment));
381    output.write(buf, bufSize);
382    bufSize = snprintf(buf, 100, "        .private_segment_align %u\n",
383                     1U<<(config.privateSegmentAlignment));
384    output.write(buf, bufSize);
385    bufSize = snprintf(buf, 100, "        .wavefront_size %u\n",
386                     1U<<(config.wavefrontSize));
387    output.write(buf, bufSize);
388    bufSize = snprintf(buf, 100, "        .call_convention 0x%x\n",
389                     callConvention);
390    output.write(buf, bufSize);
391    if (runtimeLoaderKernelSymbol!=0)
392    {
393        bufSize = snprintf(buf, 100,
394                   "        .runtime_loader_kernel_symbol 0x%" PRIx64 "\n",
395                         runtimeLoaderKernelSymbol);
396        output.write(buf, bufSize);
397    }
398    // new section, control_directive, outside .config
399    output.write("    .control_directive\n", 23);
400    printDisasmData(sizeof config.controlDirective, config.controlDirective, output, true);
401}
402
403void CLRX::disassembleROCm(std::ostream& output, const ROCmDisasmInput* rocmInput,
404           ISADisassembler* isaDisassembler, size_t& sectionCount, Flags flags)
405{
406    const bool doDumpData = ((flags & DISASM_DUMPDATA) != 0);
407    const bool doMetadata = ((flags & (DISASM_METADATA|DISASM_CONFIG)) != 0);
408    const bool doDumpCode = ((flags & DISASM_DUMPCODE) != 0);
409    const bool doDumpConfig = ((flags & DISASM_CONFIG) != 0);
410   
411    const GPUArchitecture arch = getGPUArchitectureFromDeviceType(rocmInput->deviceType);
412    const cxuint maxSgprsNum = getGPUMaxRegistersNum(arch, REGTYPE_SGPR, 0);
413   
414    {
415        char buf[40];
416        size_t size = snprintf(buf, 40, ".arch_minor %u\n", rocmInput->archMinor);
417        output.write(buf, size);
418        size = snprintf(buf, 40, ".arch_stepping %u\n", rocmInput->archStepping);
419        output.write(buf, size);
420    }
421   
422    for (const ROCmDisasmRegionInput& rinput: rocmInput->regions)
423        if (rinput.isKernel)
424        {
425            output.write(".kernel ", 8);
426            output.write(rinput.regionName.c_str(), rinput.regionName.size());
427            output.put('\n');
428            if (doMetadata && doDumpConfig)
429                dumpKernelConfig(output, maxSgprsNum, arch,
430                     *reinterpret_cast<const ROCmKernelConfig*>(
431                             rocmInput->code + rinput.offset));
432        }
433   
434    const size_t regionsNum = rocmInput->regions.size();
435    typedef std::pair<size_t, size_t> SortEntry;
436    std::unique_ptr<SortEntry[]> sorted(new SortEntry[regionsNum]);
437    for (size_t i = 0; i < regionsNum; i++)
438        sorted[i] = std::make_pair(rocmInput->regions[i].offset, i);
439    mapSort(sorted.get(), sorted.get() + regionsNum);
440   
441    if (rocmInput->code != nullptr && rocmInput->codeSize != 0)
442    {
443        const cxbyte* code = rocmInput->code;
444        output.write(".text\n", 6);
445        // clear labels
446        isaDisassembler->clearNumberedLabels();
447       
448        /// analyze code with collecting labels
449        for (size_t i = 0; i < regionsNum; i++)
450        {
451            const ROCmDisasmRegionInput& region = rocmInput->regions[sorted[i].second];
452            if (region.isKernel && doDumpCode)
453            {
454                isaDisassembler->setInput(region.size-256, code + region.offset+256,
455                                    region.offset+256);
456                isaDisassembler->analyzeBeforeDisassemble();
457            }
458            isaDisassembler->addNamedLabel(region.offset, region.regionName);
459        }
460        isaDisassembler->prepareLabelsAndRelocations();
461       
462        ISADisassembler::LabelIter curLabel;
463        ISADisassembler::NamedLabelIter curNamedLabel;
464        const auto& labels = isaDisassembler->getLabels();
465        const auto& namedLabels = isaDisassembler->getNamedLabels();
466        // real disassemble
467        size_t prevRegionPos = 0;
468        for (size_t i = 0; i < regionsNum; i++)
469        {
470            const ROCmDisasmRegionInput& region = rocmInput->regions[sorted[i].second];
471            // set labelIters to previous position
472            isaDisassembler->setInput(prevRegionPos, code + region.offset,
473                                    region.offset, prevRegionPos);
474            curLabel = std::lower_bound(labels.begin(), labels.end(), prevRegionPos);
475            curNamedLabel = std::lower_bound(namedLabels.begin(), namedLabels.end(),
476                std::make_pair(prevRegionPos, CString()),
477                  [](const std::pair<size_t,CString>& a,
478                                 const std::pair<size_t, CString>& b)
479                  { return a.first < b.first; });
480            isaDisassembler->writeLabelsToPosition(0, curLabel, curNamedLabel);
481            isaDisassembler->flushOutput();
482           
483            size_t dataSize = rocmInput->codeSize - region.offset;
484            if (i+1<regionsNum)
485            {
486                const ROCmDisasmRegionInput& newRegion =
487                        rocmInput->regions[sorted[i+1].second];
488                dataSize = newRegion.offset - region.offset;
489            }
490            if (region.isKernel)
491            {
492                if (doMetadata)
493                {
494                    if (!doDumpConfig)
495                        printDisasmData(0x100, code + region.offset, output, true);
496                    else    // skip, config was dumped in kernel configuration
497                        output.write(".skip 256\n", 10);
498                }
499               
500                if (doDumpCode)
501                {
502                    isaDisassembler->setInput(dataSize-256, code + region.offset+256,
503                                    region.offset+256, region.offset+1);
504                    isaDisassembler->setDontPrintLabels(i+1<regionsNum);
505                    isaDisassembler->disassemble();
506                }
507                prevRegionPos = region.offset + dataSize + 1;
508            }
509            else if (doDumpData)
510            {
511                output.write(".global ", 8);
512                output.write(region.regionName.c_str(), region.regionName.size());
513                output.write("\n", 1);
514                printDisasmData(dataSize, code + region.offset, output, true);
515                prevRegionPos = region.offset + dataSize;
516            }
517        }
518       
519        if (regionsNum!=0 && !rocmInput->regions[sorted[regionsNum-1].second].isKernel)
520        {   // if last region is kernel, then print labels after last region
521            const ROCmDisasmRegionInput& region =
522                        rocmInput->regions[sorted[regionsNum-1].second];
523            isaDisassembler->writeLabelsToEnd(region.size, curLabel, curNamedLabel);
524            isaDisassembler->flushOutput();
525        }
526    }
527}
Note: See TracBrowser for help on using the repository browser.