source: CLRX/CLRadeonExtender/trunk/CLRX/amdasm/AsmFormats.h @ 2581

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

CLRadeonExtender: Add ROCm format handler's first code.

File size: 14.6 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/*! \file AsmFormats.h
20 * \brief an assembler formats
21 */
22
23#ifndef __CLRX_ASMFORMATS_H__
24#define __CLRX_ASMFORMATS_H__
25
26#include <CLRX/Config.h>
27#include <cstdint>
28#include <string>
29#include <vector>
30#include <utility>
31#include <unordered_set>
32#include <unordered_map>
33#include <CLRX/amdbin/AmdBinaries.h>
34#include <CLRX/amdbin/GalliumBinaries.h>
35#include <CLRX/amdbin/AmdBinGen.h>
36#include <CLRX/amdbin/AmdCL2BinGen.h>
37#include <CLRX/amdbin/ROCmBinaries.h>
38#include <CLRX/utils/Utilities.h>
39#include <CLRX/amdasm/Commons.h>
40
41namespace CLRX
42{
43
44/// assembler section type
45enum class AsmSectionType: cxbyte
46{
47    DATA = 0,       ///< kernel or global data
48    CODE,           ///< code of program or kernel
49    CONFIG,         ///< configuration (global or for kernel)
50    LAST_COMMON = CONFIG,   ///< last common type
51   
52    AMD_HEADER = LAST_COMMON+1, ///< AMD Catalyst kernel's header
53    AMD_METADATA,       ///< AMD Catalyst kernel's metadata
54    AMD_CALNOTE,        ///< AMD CALNote
55   
56    AMDCL2_RWDATA = LAST_COMMON+1,
57    AMDCL2_BSS,
58    AMDCL2_SAMPLERINIT,
59    AMDCL2_SETUP,
60    AMDCL2_STUB,
61    AMDCL2_METADATA,
62    AMDCL2_ISAMETADATA,
63   
64    GALLIUM_COMMENT = LAST_COMMON+1,    ///< gallium comment section
65   
66    ROCM_COMMENT = LAST_COMMON+1,        ///< ROCm comment section
67   
68    EXTRA_FIRST = 0xfc,
69    EXTRA_PROGBITS = 0xfc,
70    EXTRA_NOBITS = 0xfd,
71    EXTRA_NOTE = 0xfe,
72    EXTRA_SECTION = 0xff
73};
74
75enum: cxuint
76{
77    ASMSECT_ABS = UINT_MAX,  ///< absolute section id
78    ASMSECT_NONE = UINT_MAX,  ///< none section id
79    ASMKERN_GLOBAL = UINT_MAX, ///< no kernel, global space
80    ASMKERN_INNER = UINT_MAX-1 ///< no kernel, inner global space
81};
82
83enum: Flags
84{
85    ASMSECT_WRITEABLE = 1,
86    ASMSECT_ADDRESSABLE = 2,
87    ASMSECT_ABS_ADDRESSABLE = 4,
88    ASMSECT_UNRESOLVABLE = 8,   ///< section is unresolvable
89   
90    ASMELFSECT_ALLOCATABLE = 0x10,
91    ASMELFSECT_WRITEABLE = 0x20,
92    ASMELFSECT_EXECUTABLE = 0x40
93};
94
95class Assembler;
96class AsmExpression;
97struct AsmRelocation;
98struct AsmSymbol;
99
100/// assembler format exception
101class AsmFormatException: public Exception
102{
103public:
104    /// default constructor
105    AsmFormatException() = default;
106    /// constructor from message
107    explicit AsmFormatException(const std::string& message);
108    /// destructor
109    virtual ~AsmFormatException() noexcept = default;
110};
111
112/// assdembler format handler
113class AsmFormatHandler: public NonCopyableAndNonMovable
114{
115public:
116    /// section information
117    struct SectionInfo
118    {
119        const char* name;   ///< section name
120        AsmSectionType type;    ///< section type
121        Flags flags;        ///< section flags
122    };
123protected:
124    Assembler& assembler;   ///< assembler reference
125   
126    /// constructor
127    explicit AsmFormatHandler(Assembler& assembler);
128public:
129    virtual ~AsmFormatHandler();
130   
131    /// add/set kernel
132    /** adds new kernel. throw AsmFormatException when addition failed.
133     * Method should handles any constraint that doesn't allow to add kernel except
134     * duplicate of name.
135     * \param kernelName kernel name
136     * \return kernel id
137     */
138    virtual cxuint addKernel(const char* kernelName) = 0;
139    /// add section
140    /** adds new section . throw AsmFormatException when addition failed.
141     * Method should handles any constraint that doesn't allow to add section except
142     * duplicate of name.
143     * \param sectionName section name
144     * \param kernelId kernel id (may ASMKERN_GLOBAL)
145     * \return section id
146     */
147    virtual cxuint addSection(const char* sectionName, cxuint kernelId) = 0;
148   
149    /// get section id if exists in current context, otherwise returns ASMSECT_NONE
150    virtual cxuint getSectionId(const char* sectionName) const = 0;
151   
152    /// set current kernel
153    virtual void setCurrentKernel(cxuint kernel) = 0;
154    /// set current section, this method can change current kernel if that required
155    virtual void setCurrentSection(cxuint sectionId) = 0;
156   
157    /// get current section flags and type
158    virtual SectionInfo getSectionInfo(cxuint sectionId) const = 0;
159    /// parse pseudo-op (return true if recognized pseudo-op)
160    virtual bool parsePseudoOp(const CString& firstName,
161           const char* stmtPlace, const char* linePtr) = 0;
162    /// handle labels
163    virtual void handleLabel(const CString& label);
164    /// resolve symbol if needed (for example that comes from unresolvable sections)
165    virtual bool resolveSymbol(const AsmSymbol& symbol,
166               uint64_t& value, cxuint& sectionId);
167    /// resolve relocation for specified expression
168    virtual bool resolveRelocation(const AsmExpression* expr,
169                uint64_t& value, cxuint& sectionId);
170    /// prepare binary for use
171    virtual bool prepareBinary() = 0;
172    /// write binary to output stream
173    virtual void writeBinary(std::ostream& os) const = 0;
174    /// write binary to array
175    virtual void writeBinary(Array<cxbyte>& array) const = 0;
176};
177
178/// handles raw code format
179class AsmRawCodeHandler: public AsmFormatHandler
180{
181public:
182    /// constructor
183    explicit AsmRawCodeHandler(Assembler& assembler);
184    /// destructor
185    ~AsmRawCodeHandler() = default;
186   
187    cxuint addKernel(const char* kernelName);
188    cxuint addSection(const char* sectionName, cxuint kernelId);
189
190    cxuint getSectionId(const char* sectionName) const;
191   
192    void setCurrentKernel(cxuint kernel);
193    void setCurrentSection(cxuint sectionId);
194   
195    SectionInfo getSectionInfo(cxuint sectionId) const;
196    bool parsePseudoOp(const CString& firstName,
197           const char* stmtPlace, const char* linePtr);
198   
199    bool prepareBinary();
200    void writeBinary(std::ostream& os) const;
201    void writeBinary(Array<cxbyte>& array) const;
202};
203
204/// handles AMD Catalyst format
205class AsmAmdHandler: public AsmFormatHandler
206{
207private:
208    typedef std::unordered_map<CString, cxuint> SectionMap;
209    friend struct AsmAmdPseudoOps;
210    AmdInput output;
211    struct Section
212    {
213        cxuint kernelId;
214        AsmSectionType type;
215        cxuint elfBinSectId;
216        const char* name;
217        uint32_t extraId; // for example CALNote id
218    };
219    struct Kernel
220    {
221        cxuint headerSection;
222        cxuint metadataSection;
223        cxuint configSection;
224        cxuint codeSection;
225        cxuint dataSection;
226        std::vector<cxuint> calNoteSections;
227        SectionMap extraSectionMap;
228        cxuint extraSectionCount;
229        cxuint savedSection;
230        std::unordered_set<CString> argNamesSet;
231        cxuint allocRegs[2];
232        Flags allocRegFlags;
233    };
234    std::vector<Section> sections;
235    // use pointer to prevents copying Kernel objects
236    std::vector<Kernel*> kernelStates;
237    SectionMap extraSectionMap;
238    cxuint dataSection; // global
239    cxuint savedSection;
240    cxuint extraSectionCount;
241   
242    void saveCurrentSection();
243    void restoreCurrentAllocRegs();
244    void saveCurrentAllocRegs();
245public:
246    /// constructor
247    explicit AsmAmdHandler(Assembler& assembler);
248    /// destructor
249    ~AsmAmdHandler();
250   
251    cxuint addKernel(const char* kernelName);
252    cxuint addSection(const char* sectionName, cxuint kernelId);
253   
254    cxuint getSectionId(const char* sectionName) const;
255    void setCurrentKernel(cxuint kernel);
256    void setCurrentSection(cxuint sectionId);
257   
258    SectionInfo getSectionInfo(cxuint sectionId) const;
259    bool parsePseudoOp(const CString& firstName,
260           const char* stmtPlace, const char* linePtr);
261   
262    bool prepareBinary();
263    void writeBinary(std::ostream& os) const;
264    void writeBinary(Array<cxbyte>& array) const;
265    /// get output structure pointer
266    const AmdInput* getOutput() const
267    { return &output; }
268};
269
270/// handles AMD OpenCL 2.0 binary format
271class AsmAmdCL2Handler: public AsmFormatHandler
272{
273private:
274    typedef std::unordered_map<CString, cxuint> SectionMap;
275    friend struct AsmAmdCL2PseudoOps;
276    AmdCL2Input output;
277    struct Section
278    {
279        cxuint kernelId;
280        AsmSectionType type;
281        cxuint elfBinSectId;
282        const char* name;
283        uint32_t extraId;
284    };
285    struct Relocation
286    {
287        RelocType type;
288        cxuint symbol;  // 0,1,2
289        size_t addend;
290    };
291    /* relocmap: key - symbol, value - relocation */
292    typedef std::unordered_map<CString, Relocation> RelocMap;
293    struct Kernel
294    {
295        cxuint stubSection;
296        cxuint setupSection;
297        cxuint metadataSection;
298        cxuint isaMetadataSection;
299        cxuint configSection;
300        cxuint codeSection;
301        cxuint savedSection;
302        std::unordered_set<CString> argNamesSet;
303        cxuint allocRegs[2];
304        Flags allocRegFlags;
305    };
306    std::vector<Section> sections;
307    // use pointer to prevents copying Kernel objects
308    std::vector<Kernel*> kernelStates;
309    RelocMap relocsMap;
310    SectionMap extraSectionMap;
311    SectionMap innerExtraSectionMap;
312    cxuint rodataSection; // global inner
313    cxuint dataSection; // global inner
314    cxuint bssSection; // global inner
315    cxuint samplerInitSection;
316    cxuint savedSection;
317    cxuint innerSavedSection;
318    cxuint extraSectionCount;
319    cxuint innerExtraSectionCount;
320   
321    void saveCurrentSection();
322    void restoreCurrentAllocRegs();
323    void saveCurrentAllocRegs();
324    cxuint getDriverVersion() const;
325public:
326    /// constructor
327    explicit AsmAmdCL2Handler(Assembler& assembler);
328    /// destructor
329    ~AsmAmdCL2Handler();
330   
331    cxuint addKernel(const char* kernelName);
332    cxuint addSection(const char* sectionName, cxuint kernelId);
333   
334    cxuint getSectionId(const char* sectionName) const;
335    void setCurrentKernel(cxuint kernel);
336    void setCurrentSection(cxuint sectionId);
337   
338    SectionInfo getSectionInfo(cxuint sectionId) const;
339    bool parsePseudoOp(const CString& firstName,
340           const char* stmtPlace, const char* linePtr);
341   
342    bool resolveSymbol(const AsmSymbol& symbol, uint64_t& value, cxuint& sectionId);
343    bool resolveRelocation(const AsmExpression* expr, uint64_t& value, cxuint& sectionId);
344    bool prepareBinary();
345    void writeBinary(std::ostream& os) const;
346    void writeBinary(Array<cxbyte>& array) const;
347    /// get output structure pointer
348    const AmdCL2Input* getOutput() const
349    { return &output; }
350};
351
352/// handles GalliumCompute format
353class AsmGalliumHandler: public AsmFormatHandler
354{
355private:
356    enum class Inside : cxbyte {
357        MAINLAYOUT, CONFIG, ARGS, PROGINFO
358    };
359   
360    typedef std::unordered_map<CString, cxuint> SectionMap;
361    friend struct AsmGalliumPseudoOps;
362    GalliumInput output;
363    struct Section
364    {
365        cxuint kernelId;
366        AsmSectionType type;
367        cxuint elfBinSectId;
368        const char* name;    // must be available by whole lifecycle
369    };
370    struct Kernel
371    {
372        cxuint defaultSection;
373        bool hasProgInfo;
374        cxbyte progInfoEntries;
375        cxuint allocRegs[2];
376        Flags allocRegFlags;
377    };
378    std::vector<Kernel> kernelStates;
379    std::vector<Section> sections;
380    std::vector<cxuint> kcodeSelection; // kcode
381    std::stack<std::vector<cxuint> > kcodeSelStack;
382    cxuint currentKcodeKernel;
383    SectionMap extraSectionMap;
384    cxuint codeSection;
385    cxuint dataSection;
386    cxuint commentSection;
387    cxuint savedSection;
388    Inside inside;
389    cxuint extraSectionCount;
390   
391    void restoreKcodeCurrentAllocRegs();
392    void saveKcodeCurrentAllocRegs();
393public:
394    /// construcror
395    explicit AsmGalliumHandler(Assembler& assembler);
396    /// destructor
397    ~AsmGalliumHandler() = default;
398   
399    cxuint addKernel(const char* kernelName);
400    cxuint addSection(const char* sectionName, cxuint kernelId);
401   
402    cxuint getSectionId(const char* sectionName) const;
403    void setCurrentKernel(cxuint kernel);
404    void setCurrentSection(cxuint sectionId);
405   
406    SectionInfo getSectionInfo(cxuint sectionId) const;
407    bool parsePseudoOp(const CString& firstName,
408           const char* stmtPlace, const char* linePtr);
409    void handleLabel(const CString& label);
410   
411    bool prepareBinary();
412    void writeBinary(std::ostream& os) const;
413    void writeBinary(Array<cxbyte>& array) const;
414    /// get output object (input for bingenerator)
415    const GalliumInput* getOutput() const
416    { return &output; }
417};
418
419/// handles ROCM binary format
420class AsmROCmHandler: public AsmFormatHandler
421{
422private:
423    typedef std::unordered_map<CString, cxuint> SectionMap;
424    friend struct AsmROCmPseudoOps;
425    ROCmInput output;
426    struct Section
427    {
428        cxuint kernelId;
429        AsmSectionType type;
430        cxuint elfBinSectId;
431        const char* name;    // must be available by whole lifecycle
432    };
433    struct Kernel
434    {
435        cxuint defaultSection;
436        cxuint allocRegs[2];
437        Flags allocRegFlags;
438    };
439    std::vector<Kernel> kernelStates;
440    std::vector<Section> sections;
441    std::vector<cxuint> kcodeSelection; // kcode
442    std::stack<std::vector<cxuint> > kcodeSelStack;
443    cxuint currentKcodeKernel;
444    SectionMap extraSectionMap;
445    cxuint codeSection;
446    cxuint commentSection;
447    cxuint savedSection;
448    cxuint extraSectionCount;
449   
450    void restoreKcodeCurrentAllocRegs();
451    void saveKcodeCurrentAllocRegs();
452public:
453    /// construcror
454    explicit AsmROCmHandler(Assembler& assembler);
455    /// destructor
456    ~AsmROCmHandler() = default;
457   
458    cxuint addKernel(const char* kernelName);
459    cxuint addSection(const char* sectionName, cxuint kernelId);
460   
461    cxuint getSectionId(const char* sectionName) const;
462    void setCurrentKernel(cxuint kernel);
463    void setCurrentSection(cxuint sectionId);
464   
465    SectionInfo getSectionInfo(cxuint sectionId) const;
466    bool parsePseudoOp(const CString& firstName,
467           const char* stmtPlace, const char* linePtr);
468    void handleLabel(const CString& label);
469   
470    bool prepareBinary();
471    void writeBinary(std::ostream& os) const;
472    void writeBinary(Array<cxbyte>& array) const;
473    /// get output object (input for bingenerator)
474    const ROCmInput* getOutput() const
475    { return &output; }
476};
477
478};
479
480#endif
Note: See TracBrowser for help on using the repository browser.