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

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

CLRadeonExtender: Update.

File size: 5.9 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 <iostream>
22#include <cstdint>
23#include <cstdio>
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};
44
45static const AMDGPUArchValues amdGpuArchValuesTbl[] =
46{
47    { 0, 0, 0 }, // GPUDeviceType::CAPE_VERDE
48    { 0, 0, 0 }, // GPUDeviceType::PITCAIRN
49    { 0, 0, 0 }, // GPUDeviceType::TAHITI
50    { 0, 0, 0 }, // GPUDeviceType::OLAND
51    { 7, 0, 0 }, // GPUDeviceType::BONAIRE
52    { 7, 0, 0 }, // GPUDeviceType::SPECTRE
53    { 7, 0, 0 }, // GPUDeviceType::SPOOKY
54    { 7, 0, 0 }, // GPUDeviceType::KALINDI
55    { 0, 0, 0 }, // GPUDeviceType::HAINAN
56    { 7, 0, 1 }, // GPUDeviceType::HAWAII
57    { 8, 0, 0 }, // GPUDeviceType::ICELAND
58    { 8, 0, 0 }, // GPUDeviceType::TONGA
59    { 7, 0, 0 }, // GPUDeviceType::MULLINS
60    { 8, 0, 4 }, // GPUDeviceType::FIJI
61    { 8, 0, 1 }, // GPUDeviceType::CARRIZO
62    { 0, 0, 0 }, // GPUDeviceType::DUMMY
63    { 0, 0, 0 }, // GPUDeviceType::GOOSE
64    { 0, 0, 0 }, // GPUDeviceType::HORSE
65    { 8, 1, 0 }, // GPUDeviceType::STONEY
66    { 8, 0, 4 }, // GPUDeviceType::ELLESMERE
67    { 8, 0, 4 } // GPUDeviceType::BAFFIN
68};
69
70ROCmDisasmInput* CLRX::getROCmDisasmInputFromBinary(const ROCmBinary& binary)
71{
72    std::unique_ptr<ROCmDisasmInput> input(new ROCmDisasmInput);
73    uint32_t archMajor = 0;
74   
75    {
76        const cxbyte* noteContent = binary.getSectionContent(".note");
77        size_t notesSize = binary.getSectionHeader(".note").sh_size;
78        // find note about AMDGPU
79        for (size_t offset = 0; offset < notesSize; )
80        {
81            const Elf64_Nhdr* nhdr = (const Elf64_Nhdr*)(noteContent + offset);
82            size_t namesz = ULEV(nhdr->n_namesz);
83            size_t descsz = ULEV(nhdr->n_descsz);
84            if (usumGt(offset, namesz+descsz, notesSize))
85                throw Exception("Note offset+size out of range");
86            if (ULEV(nhdr->n_type) == 0x3 && namesz==4 && descsz>=0x1a &&
87                ::strcmp((const char*)noteContent+offset+sizeof(Elf64_Nhdr), "AMD")==0)
88            {    // AMDGPU type
89                const uint32_t* content = (const uint32_t*)
90                        (noteContent+offset+sizeof(Elf64_Nhdr) + 4);
91                archMajor = ULEV(content[1]);
92                input->archMinor = ULEV(content[2]);
93                input->archStepping = ULEV(content[3]);
94            }
95            size_t align = (((namesz+descsz)&3)!=0) ? 4-((namesz+descsz)&3) : 0;
96            offset += sizeof(Elf64_Nhdr) + namesz + descsz + align;
97        }
98    }
99    // determine device type
100    std::cout << "archmajor: " << archMajor << ", archminor: " << input->archMinor <<
101            ", archstepping: " << input->archStepping << "\n";
102    cxuint deviceNumber = 0;
103    for (deviceNumber = 0; deviceNumber <= cxuint(GPUDeviceType::GPUDEVICE_MAX);
104                 deviceNumber++)
105        if (amdGpuArchValuesTbl[deviceNumber].major==archMajor &&
106            amdGpuArchValuesTbl[deviceNumber].minor==input->archMinor &&
107            amdGpuArchValuesTbl[deviceNumber].stepping==input->archStepping)
108            break;
109    if (deviceNumber > cxuint(GPUDeviceType::GPUDEVICE_MAX))
110        throw Exception("Can't determine device type from arch values!");
111    input->deviceType = GPUDeviceType(deviceNumber);
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, region.size,
120            region.offset - codeOffset, region.isKernel };
121    }
122   
123    input->code = binary.getCode();
124    input->codeSize = binary.getCodeSize();
125    return input.release();
126}
127
128void CLRX::disassembleROCm(std::ostream& output, const ROCmDisasmInput* rocmInput,
129           ISADisassembler* isaDisassembler, size_t& sectionCount, Flags flags)
130{
131    const bool doDumpData = ((flags & DISASM_DUMPDATA) != 0);
132    const bool doMetadata = ((flags & (DISASM_METADATA|DISASM_CONFIG)) != 0);
133    const bool doDumpCode = ((flags & DISASM_DUMPCODE) != 0);
134    const bool doDumpConfig = ((flags & DISASM_CONFIG) != 0);
135   
136    const GPUArchitecture arch = getGPUArchitectureFromDeviceType(rocmInput->deviceType);
137    const cxuint maxSgprsNum = getGPUMaxRegistersNum(arch, REGTYPE_SGPR, 0);
138   
139    for (cxuint i = 0; i < rocmInput->regions.size(); i++)
140    {
141        const ROCmDisasmRegionInput& rinput = rocmInput->regions[i];
142        if (rinput.isKernel)
143        {
144            output.write(".kernel ", 8);
145            output.write(rinput.regionName.c_str(), rinput.regionName.size());
146            output.put('\n');
147        }
148    }
149    if (doDumpCode && rocmInput->code != nullptr && rocmInput->codeSize != 0)
150    {
151    }
152}
Note: See TracBrowser for help on using the repository browser.