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

Last change on this file since 3761 was 3761, checked in by matszpk, 19 months ago

CLRadeonExtender: Asm: Preliminaries to section differences in expressions.

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