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

Last change on this file since 3766 was 3766, checked in by matszpk, 2 years ago

CLRadeonExtender: Asm: Add relSpace to AsmFormatHandler::SectionInfo?. Set relSpace while adding new section.

File size: 17.6 KB
Line 
1/*
2 *  CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3 *  Copyright (C) 2014-2018 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 <memory>
32#include <unordered_set>
33#include <unordered_map>
34#include <CLRX/amdbin/AmdBinaries.h>
35#include <CLRX/amdbin/GalliumBinaries.h>
36#include <CLRX/amdbin/AmdBinGen.h>
37#include <CLRX/amdbin/AmdCL2BinGen.h>
38#include <CLRX/amdbin/ROCmBinaries.h>
39#include <CLRX/utils/Utilities.h>
40#include <CLRX/utils/GPUId.h>
41#include <CLRX/amdasm/Commons.h>
42
43namespace CLRX
44{
45
46/// assembler section type
47enum class AsmSectionType: cxbyte
48{
49    DATA = 0,       ///< kernel or global data
50    CODE,           ///< code of program or kernel
51    CONFIG,         ///< configuration (global or for kernel)
52    LAST_COMMON = CONFIG,   ///< last common type
53   
54    AMD_HEADER = LAST_COMMON+1, ///< AMD Catalyst kernel's header
55    AMD_METADATA,       ///< AMD Catalyst kernel's metadata
56    AMD_CALNOTE,        ///< AMD CALNote
57   
58    AMDCL2_RWDATA = LAST_COMMON+1,
59    AMDCL2_BSS,
60    AMDCL2_SAMPLERINIT,
61    AMDCL2_SETUP,
62    AMDCL2_STUB,
63    AMDCL2_METADATA,
64    AMDCL2_ISAMETADATA,
65    AMDCL2_CONFIG_CTRL_DIRECTIVE,
66   
67    GALLIUM_COMMENT = LAST_COMMON+1,    ///< gallium comment section
68    GALLIUM_CONFIG_CTRL_DIRECTIVE,
69    GALLIUM_SCRATCH,    ///< empty section for scratch symbol
70   
71    ROCM_COMMENT = LAST_COMMON+1,        ///< ROCm comment section
72    ROCM_CONFIG_CTRL_DIRECTIVE,
73    ROCM_METADATA,
74   
75    EXTRA_FIRST = 0xfc,
76    EXTRA_PROGBITS = 0xfc,
77    EXTRA_NOBITS = 0xfd,
78    EXTRA_NOTE = 0xfe,
79    EXTRA_SECTION = 0xff
80};
81
82enum: cxuint
83{
84    ASMSECT_ABS = UINT_MAX,  ///< absolute section id
85    ASMSECT_NONE = UINT_MAX,  ///< none section id
86    ASMKERN_GLOBAL = UINT_MAX, ///< no kernel, global space
87    ASMKERN_INNER = UINT_MAX-1 ///< no kernel, inner global space
88};
89
90enum: Flags
91{
92    ASMSECT_WRITEABLE = 1,
93    ASMSECT_ADDRESSABLE = 2,
94    ASMSECT_ABS_ADDRESSABLE = 4,
95    ASMSECT_UNRESOLVABLE = 8,   ///< section is unresolvable
96   
97    ASMELFSECT_ALLOCATABLE = 0x10,
98    ASMELFSECT_WRITEABLE = 0x20,
99    ASMELFSECT_EXECUTABLE = 0x40
100};
101
102class Assembler;
103class AsmExpression;
104struct AsmRelocation;
105struct AsmSymbol;
106
107/// assembler format exception
108class AsmFormatException: public Exception
109{
110public:
111    /// default constructor
112    AsmFormatException() = default;
113    /// constructor from message
114    explicit AsmFormatException(const std::string& message);
115    /// destructor
116    virtual ~AsmFormatException() noexcept = default;
117};
118
119/// assdembler format handler
120class AsmFormatHandler: public NonCopyableAndNonMovable
121{
122public:
123    /// section information
124    struct SectionInfo
125    {
126        const char* name;   ///< section name
127        AsmSectionType type;    ///< section type
128        Flags flags;        ///< section flags
129        cxuint relSpace;    ///< relative space
130       
131        SectionInfo() : name(nullptr), type(AsmSectionType::DATA), flags(0),
132                    relSpace(UINT_MAX)
133        { }
134        SectionInfo(const char* _name, AsmSectionType _type, Flags _flags = 0,
135                cxuint _relSpace = UINT_MAX) : name(_name), type(_type), flags(_flags),
136                    relSpace(_relSpace)
137        { }
138    };
139protected:
140    Assembler& assembler;   ///< assembler reference
141    bool sectionDiffsResolvable;
142   
143    /// constructor
144    explicit AsmFormatHandler(Assembler& assembler);
145   
146    // resolve LO32BIT/HI32BIT relocations (partially, helper)
147    bool resolveLoHiRelocExpression(const AsmExpression* expr, RelocType& relType,
148                    cxuint& relSectionId, uint64_t& relValue);
149public:
150    virtual ~AsmFormatHandler();
151   
152    /// return true if format handler can resolve differences between sections
153    bool isSectionDiffsResolvable() const
154    { return sectionDiffsResolvable; }
155   
156    /// add/set kernel
157    /** adds new kernel. throw AsmFormatException when addition failed.
158     * Method should handles any constraint that doesn't allow to add kernel except
159     * duplicate of name.
160     * \param kernelName kernel name
161     * \return kernel id
162     */
163    virtual cxuint addKernel(const char* kernelName) = 0;
164    /// add section
165    /** adds new section . throw AsmFormatException when addition failed.
166     * Method should handles any constraint that doesn't allow to add section except
167     * duplicate of name.
168     * \param sectionName section name
169     * \param kernelId kernel id (may ASMKERN_GLOBAL)
170     * \return section id
171     */
172    virtual cxuint addSection(const char* sectionName, cxuint kernelId) = 0;
173   
174    /// get section id if exists in current context, otherwise returns ASMSECT_NONE
175    virtual cxuint getSectionId(const char* sectionName) const = 0;
176   
177    /// set current kernel
178    virtual void setCurrentKernel(cxuint kernel) = 0;
179    /// set current section, this method can change current kernel if that required
180    virtual void setCurrentSection(cxuint sectionId) = 0;
181   
182    /// get current section flags and type
183    virtual SectionInfo getSectionInfo(cxuint sectionId) const = 0;
184    /// parse pseudo-op (return true if recognized pseudo-op)
185    virtual bool parsePseudoOp(const CString& firstName,
186           const char* stmtPlace, const char* linePtr) = 0;
187    /// handle labels
188    virtual void handleLabel(const CString& label);
189    /// resolve symbol if needed (for example that comes from unresolvable sections)
190    virtual bool resolveSymbol(const AsmSymbol& symbol,
191               uint64_t& value, cxuint& sectionId);
192    /// resolve relocation for specified expression
193    virtual bool resolveRelocation(const AsmExpression* expr,
194                uint64_t& value, cxuint& sectionId);
195    /// prepare binary for use
196    virtual bool prepareBinary() = 0;
197    /// write binary to output stream
198    virtual void writeBinary(std::ostream& os) const = 0;
199    /// write binary to array
200    virtual void writeBinary(Array<cxbyte>& array) const = 0;
201   
202    /// prepare before section diference resolving
203    virtual void prepareSectionDiffsResolving();
204};
205
206/// handles raw code format
207class AsmRawCodeHandler: public AsmFormatHandler
208{
209public:
210    /// constructor
211    explicit AsmRawCodeHandler(Assembler& assembler);
212    /// destructor
213    ~AsmRawCodeHandler() = default;
214   
215    cxuint addKernel(const char* kernelName);
216    cxuint addSection(const char* sectionName, cxuint kernelId);
217
218    cxuint getSectionId(const char* sectionName) const;
219   
220    void setCurrentKernel(cxuint kernel);
221    void setCurrentSection(cxuint sectionId);
222   
223    SectionInfo getSectionInfo(cxuint sectionId) const;
224    bool parsePseudoOp(const CString& firstName,
225           const char* stmtPlace, const char* linePtr);
226   
227    bool prepareBinary();
228    void writeBinary(std::ostream& os) const;
229    void writeBinary(Array<cxbyte>& array) const;
230};
231
232/// handles AMD Catalyst format
233class AsmAmdHandler: public AsmFormatHandler
234{
235private:
236    typedef std::unordered_map<CString, cxuint> SectionMap;
237    friend struct AsmAmdPseudoOps;
238    AmdInput output;
239    struct Section
240    {
241        cxuint kernelId;
242        AsmSectionType type;
243        cxuint elfBinSectId;
244        const char* name;
245        uint32_t extraId; // for example CALNote id
246    };
247    struct Kernel
248    {
249        cxuint headerSection;
250        cxuint metadataSection;
251        cxuint configSection;
252        cxuint codeSection;
253        cxuint dataSection;
254        std::vector<cxuint> calNoteSections;
255        SectionMap extraSectionMap;
256        cxuint extraSectionCount;
257        cxuint savedSection;
258        std::unordered_set<CString> argNamesSet;
259        cxuint allocRegs[MAX_REGTYPES_NUM];
260        Flags allocRegFlags;
261    };
262    std::vector<Section> sections;
263    // use pointer to prevents copying Kernel objects
264    std::vector<Kernel*> kernelStates;
265    SectionMap extraSectionMap;
266    cxuint dataSection; // global
267    cxuint savedSection;
268    cxuint extraSectionCount;
269   
270    cxuint detectedDriverVersion;
271   
272    void saveCurrentSection();
273    void restoreCurrentAllocRegs();
274    void saveCurrentAllocRegs();
275   
276    cxuint determineDriverVersion() const;
277public:
278    /// constructor
279    explicit AsmAmdHandler(Assembler& assembler);
280    /// destructor
281    ~AsmAmdHandler();
282   
283    cxuint addKernel(const char* kernelName);
284    cxuint addSection(const char* sectionName, cxuint kernelId);
285   
286    cxuint getSectionId(const char* sectionName) const;
287    void setCurrentKernel(cxuint kernel);
288    void setCurrentSection(cxuint sectionId);
289   
290    SectionInfo getSectionInfo(cxuint sectionId) const;
291    bool parsePseudoOp(const CString& firstName,
292           const char* stmtPlace, const char* linePtr);
293   
294    bool prepareBinary();
295    void writeBinary(std::ostream& os) const;
296    void writeBinary(Array<cxbyte>& array) const;
297    /// get output structure pointer
298    const AmdInput* getOutput() const
299    { return &output; }
300};
301
302/// Asm AMD HSA kernel configuration
303struct AsmAmdHsaKernelConfig: AmdHsaKernelConfig
304{
305    cxuint dimMask;    ///< mask of dimension (bits: 0 - X, 1 - Y, 2 - Z)
306    cxuint usedVGPRsNum;  ///< number of used VGPRs
307    cxuint usedSGPRsNum;  ///< number of used SGPRs
308    cxbyte userDataNum;   ///< number of user data
309    bool ieeeMode;  ///< IEEE mode
310    cxbyte floatMode; ///< float mode
311    cxbyte priority;    ///< priority
312    cxbyte exceptions;      ///< enabled exceptions
313    bool tgSize;        ///< enable TG_SIZE_EN bit
314    bool debugMode;     ///< debug mode
315    bool privilegedMode;   ///< prvileged mode
316    bool dx10Clamp;     ///< DX10 CLAMP mode
317   
318    void initialize();
319};
320
321/// handles AMD OpenCL 2.0 binary format
322class AsmAmdCL2Handler: public AsmFormatHandler
323{
324private:
325    typedef std::unordered_map<CString, cxuint> SectionMap;
326    friend struct AsmAmdCL2PseudoOps;
327    AmdCL2Input output;
328    struct Section
329    {
330        cxuint kernelId;
331        AsmSectionType type;
332        cxuint elfBinSectId;
333        const char* name;
334        uint32_t extraId;
335    };
336    struct Relocation
337    {
338        RelocType type;
339        cxuint symbol;  // 0,1,2
340        size_t addend;
341    };
342    /* relocmap: key - symbol, value - relocation */
343    typedef std::unordered_map<CString, Relocation> RelocMap;
344    struct Kernel
345    {
346        cxuint stubSection;
347        cxuint setupSection;
348        cxuint metadataSection;
349        cxuint isaMetadataSection;
350        cxuint configSection;
351        cxuint ctrlDirSection;
352        cxuint codeSection;
353        cxuint savedSection;
354        bool useHsaConfig; //
355        std::unique_ptr<AsmAmdHsaKernelConfig> hsaConfig; // hsaConfig
356        std::unordered_set<CString> argNamesSet;
357        cxuint allocRegs[MAX_REGTYPES_NUM];
358        Flags allocRegFlags;
359       
360        void initializeKernelConfig();
361    };
362    std::vector<Section> sections;
363    // use pointer to prevents copying Kernel objects
364    std::vector<Kernel*> kernelStates;
365    RelocMap relocsMap;
366    SectionMap extraSectionMap;
367    SectionMap innerExtraSectionMap;
368    cxuint rodataSection; // global inner
369    cxuint dataSection; // global inner
370    cxuint bssSection; // global inner
371    cxuint samplerInitSection;
372    cxuint savedSection;
373    cxuint innerSavedSection;
374    cxuint extraSectionCount;
375    cxuint innerExtraSectionCount;
376   
377    cxuint detectedDriverVersion;
378   
379    void saveCurrentSection();
380    void restoreCurrentAllocRegs();
381    void saveCurrentAllocRegs();
382    cxuint getDriverVersion() const;
383public:
384    /// constructor
385    explicit AsmAmdCL2Handler(Assembler& assembler);
386    /// destructor
387    ~AsmAmdCL2Handler();
388   
389    cxuint addKernel(const char* kernelName);
390    cxuint addSection(const char* sectionName, cxuint kernelId);
391   
392    cxuint getSectionId(const char* sectionName) const;
393    void setCurrentKernel(cxuint kernel);
394    void setCurrentSection(cxuint sectionId);
395   
396    SectionInfo getSectionInfo(cxuint sectionId) const;
397    bool parsePseudoOp(const CString& firstName,
398           const char* stmtPlace, const char* linePtr);
399   
400    bool resolveSymbol(const AsmSymbol& symbol, uint64_t& value, cxuint& sectionId);
401    bool resolveRelocation(const AsmExpression* expr, uint64_t& value, cxuint& sectionId);
402    bool prepareBinary();
403    void writeBinary(std::ostream& os) const;
404    void writeBinary(Array<cxbyte>& array) const;
405    /// get output structure pointer
406    const AmdCL2Input* getOutput() const
407    { return &output; }
408};
409
410/// handles GalliumCompute format
411class AsmGalliumHandler: public AsmFormatHandler
412{
413private:
414    enum class Inside : cxbyte {
415        MAINLAYOUT, CONFIG, ARGS, PROGINFO
416    };
417   
418    typedef std::unordered_map<CString, cxuint> SectionMap;
419    friend struct AsmGalliumPseudoOps;
420    GalliumInput output;
421    struct Section
422    {
423        cxuint kernelId;
424        AsmSectionType type;
425        cxuint elfBinSectId;
426        const char* name;    // must be available by whole lifecycle
427    };
428    struct Kernel
429    {
430        cxuint defaultSection;
431        std::unique_ptr<AsmAmdHsaKernelConfig> hsaConfig;
432        cxuint ctrlDirSection;
433        bool hasProgInfo;
434        cxbyte progInfoEntries;
435        cxuint allocRegs[MAX_REGTYPES_NUM];
436        Flags allocRegFlags;
437       
438        void initializeAmdHsaKernelConfig();
439    };
440    std::vector<Kernel*> kernelStates;
441    std::vector<Section> sections;
442    std::vector<cxuint> kcodeSelection; // kcode
443    std::stack<std::vector<cxuint> > kcodeSelStack;
444    cxuint currentKcodeKernel;
445    SectionMap extraSectionMap;
446    cxuint codeSection;
447    cxuint dataSection;
448    cxuint commentSection;
449    cxuint scratchSection;
450    cxuint savedSection;
451    Inside inside;
452    cxuint extraSectionCount;
453   
454    cxuint detectedDriverVersion;
455    cxuint detectedLLVMVersion;
456   
457    uint32_t archMinor;
458    uint32_t archStepping;
459   
460    void restoreKcodeCurrentAllocRegs();
461    void saveKcodeCurrentAllocRegs();
462   
463    cxuint determineDriverVersion() const;
464    cxuint determineLLVMVersion() const;
465public:
466    /// construcror
467    explicit AsmGalliumHandler(Assembler& assembler);
468    /// destructor
469    ~AsmGalliumHandler();
470   
471    cxuint addKernel(const char* kernelName);
472    cxuint addSection(const char* sectionName, cxuint kernelId);
473   
474    cxuint getSectionId(const char* sectionName) const;
475    void setCurrentKernel(cxuint kernel);
476    void setCurrentSection(cxuint sectionId);
477   
478    SectionInfo getSectionInfo(cxuint sectionId) const;
479    bool parsePseudoOp(const CString& firstName,
480           const char* stmtPlace, const char* linePtr);
481    void handleLabel(const CString& label);
482   
483    bool resolveSymbol(const AsmSymbol& symbol, uint64_t& value, cxuint& sectionId);
484    bool resolveRelocation(const AsmExpression* expr, uint64_t& value, cxuint& sectionId);
485    bool prepareBinary();
486    void writeBinary(std::ostream& os) const;
487    void writeBinary(Array<cxbyte>& array) const;
488    /// get output object (input for bingenerator)
489    const GalliumInput* getOutput() const
490    { return &output; }
491};
492
493typedef AsmAmdHsaKernelConfig AsmROCmKernelConfig;
494
495/// handles ROCM binary format
496class AsmROCmHandler: public AsmFormatHandler
497{
498private:
499    typedef std::unordered_map<CString, cxuint> SectionMap;
500    friend struct AsmROCmPseudoOps;
501    ROCmInput output;
502    std::unique_ptr<ROCmBinGenerator> binGen;
503    struct Section
504    {
505        cxuint kernelId;
506        AsmSectionType type;
507        cxuint elfBinSectId;
508        const char* name;    // must be available by whole lifecycle
509    };
510    struct Kernel
511    {
512        cxuint configSection;
513        std::unique_ptr<AsmROCmKernelConfig> config;
514        bool isFKernel;
515        cxuint ctrlDirSection;
516        cxuint savedSection;
517        Flags allocRegFlags;
518        cxuint allocRegs[MAX_REGTYPES_NUM];
519       
520        void initializeKernelConfig();
521    };
522    std::vector<Kernel*> kernelStates;
523    std::vector<Section> sections;
524    std::vector<cxuint> kcodeSelection; // kcode
525    std::stack<std::vector<cxuint> > kcodeSelStack;
526    cxuint currentKcodeKernel;
527    SectionMap extraSectionMap;
528    cxuint codeSection;
529    cxuint commentSection;
530    cxuint metadataSection;
531    cxuint dataSection;
532    cxuint savedSection;
533    cxuint extraSectionCount;
534   
535    void restoreKcodeCurrentAllocRegs();
536    void saveKcodeCurrentAllocRegs();
537   
538public:
539    /// construcror
540    explicit AsmROCmHandler(Assembler& assembler);
541    /// destructor
542    ~AsmROCmHandler();
543   
544    cxuint addKernel(const char* kernelName);
545    cxuint addSection(const char* sectionName, cxuint kernelId);
546   
547    cxuint getSectionId(const char* sectionName) const;
548    void setCurrentKernel(cxuint kernel);
549    void setCurrentSection(cxuint sectionId);
550   
551    SectionInfo getSectionInfo(cxuint sectionId) const;
552    bool parsePseudoOp(const CString& firstName,
553           const char* stmtPlace, const char* linePtr);
554    void handleLabel(const CString& label);
555   
556    bool prepareBinary();
557    void writeBinary(std::ostream& os) const;
558    void writeBinary(Array<cxbyte>& array) const;
559    /// get output object (input for bingenerator)
560    const ROCmInput* getOutput() const
561    { return &output; }
562};
563
564};
565
566#endif
Note: See TracBrowser for help on using the repository browser.