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

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

CLRadeonExtender: AsmROCm: Add '.newbinfmt' and '.globaldata' pseudo-ops. ROCmBinGen: small fixes.

File size: 16.9 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   
132    /// constructor
133    explicit AsmFormatHandler(Assembler& assembler);
134   
135    // resolve LO32BIT/HI32BIT relocations (partially, helper)
136    bool resolveLoHiRelocExpression(const AsmExpression* expr, RelocType& relType,
137                    cxuint& relSectionId, uint64_t& relValue);
138public:
139    virtual ~AsmFormatHandler();
140   
141    /// add/set kernel
142    /** adds new kernel. throw AsmFormatException when addition failed.
143     * Method should handles any constraint that doesn't allow to add kernel except
144     * duplicate of name.
145     * \param kernelName kernel name
146     * \return kernel id
147     */
148    virtual cxuint addKernel(const char* kernelName) = 0;
149    /// add section
150    /** adds new section . throw AsmFormatException when addition failed.
151     * Method should handles any constraint that doesn't allow to add section except
152     * duplicate of name.
153     * \param sectionName section name
154     * \param kernelId kernel id (may ASMKERN_GLOBAL)
155     * \return section id
156     */
157    virtual cxuint addSection(const char* sectionName, cxuint kernelId) = 0;
158   
159    /// get section id if exists in current context, otherwise returns ASMSECT_NONE
160    virtual cxuint getSectionId(const char* sectionName) const = 0;
161   
162    /// set current kernel
163    virtual void setCurrentKernel(cxuint kernel) = 0;
164    /// set current section, this method can change current kernel if that required
165    virtual void setCurrentSection(cxuint sectionId) = 0;
166   
167    /// get current section flags and type
168    virtual SectionInfo getSectionInfo(cxuint sectionId) const = 0;
169    /// parse pseudo-op (return true if recognized pseudo-op)
170    virtual bool parsePseudoOp(const CString& firstName,
171           const char* stmtPlace, const char* linePtr) = 0;
172    /// handle labels
173    virtual void handleLabel(const CString& label);
174    /// resolve symbol if needed (for example that comes from unresolvable sections)
175    virtual bool resolveSymbol(const AsmSymbol& symbol,
176               uint64_t& value, cxuint& sectionId);
177    /// resolve relocation for specified expression
178    virtual bool resolveRelocation(const AsmExpression* expr,
179                uint64_t& value, cxuint& sectionId);
180    /// prepare binary for use
181    virtual bool prepareBinary() = 0;
182    /// write binary to output stream
183    virtual void writeBinary(std::ostream& os) const = 0;
184    /// write binary to array
185    virtual void writeBinary(Array<cxbyte>& array) const = 0;
186};
187
188/// handles raw code format
189class AsmRawCodeHandler: public AsmFormatHandler
190{
191public:
192    /// constructor
193    explicit AsmRawCodeHandler(Assembler& assembler);
194    /// destructor
195    ~AsmRawCodeHandler() = default;
196   
197    cxuint addKernel(const char* kernelName);
198    cxuint addSection(const char* sectionName, cxuint kernelId);
199
200    cxuint getSectionId(const char* sectionName) const;
201   
202    void setCurrentKernel(cxuint kernel);
203    void setCurrentSection(cxuint sectionId);
204   
205    SectionInfo getSectionInfo(cxuint sectionId) const;
206    bool parsePseudoOp(const CString& firstName,
207           const char* stmtPlace, const char* linePtr);
208   
209    bool prepareBinary();
210    void writeBinary(std::ostream& os) const;
211    void writeBinary(Array<cxbyte>& array) const;
212};
213
214/// handles AMD Catalyst format
215class AsmAmdHandler: public AsmFormatHandler
216{
217private:
218    typedef std::unordered_map<CString, cxuint> SectionMap;
219    friend struct AsmAmdPseudoOps;
220    AmdInput output;
221    struct Section
222    {
223        cxuint kernelId;
224        AsmSectionType type;
225        cxuint elfBinSectId;
226        const char* name;
227        uint32_t extraId; // for example CALNote id
228    };
229    struct Kernel
230    {
231        cxuint headerSection;
232        cxuint metadataSection;
233        cxuint configSection;
234        cxuint codeSection;
235        cxuint dataSection;
236        std::vector<cxuint> calNoteSections;
237        SectionMap extraSectionMap;
238        cxuint extraSectionCount;
239        cxuint savedSection;
240        std::unordered_set<CString> argNamesSet;
241        cxuint allocRegs[MAX_REGTYPES_NUM];
242        Flags allocRegFlags;
243    };
244    std::vector<Section> sections;
245    // use pointer to prevents copying Kernel objects
246    std::vector<Kernel*> kernelStates;
247    SectionMap extraSectionMap;
248    cxuint dataSection; // global
249    cxuint savedSection;
250    cxuint extraSectionCount;
251   
252    cxuint detectedDriverVersion;
253   
254    void saveCurrentSection();
255    void restoreCurrentAllocRegs();
256    void saveCurrentAllocRegs();
257   
258    cxuint determineDriverVersion() const;
259public:
260    /// constructor
261    explicit AsmAmdHandler(Assembler& assembler);
262    /// destructor
263    ~AsmAmdHandler();
264   
265    cxuint addKernel(const char* kernelName);
266    cxuint addSection(const char* sectionName, cxuint kernelId);
267   
268    cxuint getSectionId(const char* sectionName) const;
269    void setCurrentKernel(cxuint kernel);
270    void setCurrentSection(cxuint sectionId);
271   
272    SectionInfo getSectionInfo(cxuint sectionId) const;
273    bool parsePseudoOp(const CString& firstName,
274           const char* stmtPlace, const char* linePtr);
275   
276    bool prepareBinary();
277    void writeBinary(std::ostream& os) const;
278    void writeBinary(Array<cxbyte>& array) const;
279    /// get output structure pointer
280    const AmdInput* getOutput() const
281    { return &output; }
282};
283
284/// Asm AMD HSA kernel configuration
285struct AsmAmdHsaKernelConfig: AmdHsaKernelConfig
286{
287    cxuint dimMask;    ///< mask of dimension (bits: 0 - X, 1 - Y, 2 - Z)
288    cxuint usedVGPRsNum;  ///< number of used VGPRs
289    cxuint usedSGPRsNum;  ///< number of used SGPRs
290    cxbyte userDataNum;   ///< number of user data
291    bool ieeeMode;  ///< IEEE mode
292    cxbyte floatMode; ///< float mode
293    cxbyte priority;    ///< priority
294    cxbyte exceptions;      ///< enabled exceptions
295    bool tgSize;        ///< enable TG_SIZE_EN bit
296    bool debugMode;     ///< debug mode
297    bool privilegedMode;   ///< prvileged mode
298    bool dx10Clamp;     ///< DX10 CLAMP mode
299   
300    void initialize();
301};
302
303/// handles AMD OpenCL 2.0 binary format
304class AsmAmdCL2Handler: public AsmFormatHandler
305{
306private:
307    typedef std::unordered_map<CString, cxuint> SectionMap;
308    friend struct AsmAmdCL2PseudoOps;
309    AmdCL2Input output;
310    struct Section
311    {
312        cxuint kernelId;
313        AsmSectionType type;
314        cxuint elfBinSectId;
315        const char* name;
316        uint32_t extraId;
317    };
318    struct Relocation
319    {
320        RelocType type;
321        cxuint symbol;  // 0,1,2
322        size_t addend;
323    };
324    /* relocmap: key - symbol, value - relocation */
325    typedef std::unordered_map<CString, Relocation> RelocMap;
326    struct Kernel
327    {
328        cxuint stubSection;
329        cxuint setupSection;
330        cxuint metadataSection;
331        cxuint isaMetadataSection;
332        cxuint configSection;
333        cxuint ctrlDirSection;
334        cxuint codeSection;
335        cxuint savedSection;
336        bool useHsaConfig; //
337        std::unique_ptr<AsmAmdHsaKernelConfig> hsaConfig; // hsaConfig
338        std::unordered_set<CString> argNamesSet;
339        cxuint allocRegs[MAX_REGTYPES_NUM];
340        Flags allocRegFlags;
341       
342        void initializeKernelConfig();
343    };
344    std::vector<Section> sections;
345    // use pointer to prevents copying Kernel objects
346    std::vector<Kernel*> kernelStates;
347    RelocMap relocsMap;
348    SectionMap extraSectionMap;
349    SectionMap innerExtraSectionMap;
350    cxuint rodataSection; // global inner
351    cxuint dataSection; // global inner
352    cxuint bssSection; // global inner
353    cxuint samplerInitSection;
354    cxuint savedSection;
355    cxuint innerSavedSection;
356    cxuint extraSectionCount;
357    cxuint innerExtraSectionCount;
358   
359    cxuint detectedDriverVersion;
360   
361    void saveCurrentSection();
362    void restoreCurrentAllocRegs();
363    void saveCurrentAllocRegs();
364    cxuint getDriverVersion() const;
365public:
366    /// constructor
367    explicit AsmAmdCL2Handler(Assembler& assembler);
368    /// destructor
369    ~AsmAmdCL2Handler();
370   
371    cxuint addKernel(const char* kernelName);
372    cxuint addSection(const char* sectionName, cxuint kernelId);
373   
374    cxuint getSectionId(const char* sectionName) const;
375    void setCurrentKernel(cxuint kernel);
376    void setCurrentSection(cxuint sectionId);
377   
378    SectionInfo getSectionInfo(cxuint sectionId) const;
379    bool parsePseudoOp(const CString& firstName,
380           const char* stmtPlace, const char* linePtr);
381   
382    bool resolveSymbol(const AsmSymbol& symbol, uint64_t& value, cxuint& sectionId);
383    bool resolveRelocation(const AsmExpression* expr, uint64_t& value, cxuint& sectionId);
384    bool prepareBinary();
385    void writeBinary(std::ostream& os) const;
386    void writeBinary(Array<cxbyte>& array) const;
387    /// get output structure pointer
388    const AmdCL2Input* getOutput() const
389    { return &output; }
390};
391
392/// handles GalliumCompute format
393class AsmGalliumHandler: public AsmFormatHandler
394{
395private:
396    enum class Inside : cxbyte {
397        MAINLAYOUT, CONFIG, ARGS, PROGINFO
398    };
399   
400    typedef std::unordered_map<CString, cxuint> SectionMap;
401    friend struct AsmGalliumPseudoOps;
402    GalliumInput output;
403    struct Section
404    {
405        cxuint kernelId;
406        AsmSectionType type;
407        cxuint elfBinSectId;
408        const char* name;    // must be available by whole lifecycle
409    };
410    struct Kernel
411    {
412        cxuint defaultSection;
413        std::unique_ptr<AsmAmdHsaKernelConfig> hsaConfig;
414        cxuint ctrlDirSection;
415        bool hasProgInfo;
416        cxbyte progInfoEntries;
417        cxuint allocRegs[MAX_REGTYPES_NUM];
418        Flags allocRegFlags;
419       
420        void initializeAmdHsaKernelConfig();
421    };
422    std::vector<Kernel*> kernelStates;
423    std::vector<Section> sections;
424    std::vector<cxuint> kcodeSelection; // kcode
425    std::stack<std::vector<cxuint> > kcodeSelStack;
426    cxuint currentKcodeKernel;
427    SectionMap extraSectionMap;
428    cxuint codeSection;
429    cxuint dataSection;
430    cxuint commentSection;
431    cxuint scratchSection;
432    cxuint savedSection;
433    Inside inside;
434    cxuint extraSectionCount;
435   
436    cxuint detectedDriverVersion;
437    cxuint detectedLLVMVersion;
438   
439    uint32_t archMinor;
440    uint32_t archStepping;
441   
442    void restoreKcodeCurrentAllocRegs();
443    void saveKcodeCurrentAllocRegs();
444   
445    cxuint determineDriverVersion() const;
446    cxuint determineLLVMVersion() const;
447public:
448    /// construcror
449    explicit AsmGalliumHandler(Assembler& assembler);
450    /// destructor
451    ~AsmGalliumHandler();
452   
453    cxuint addKernel(const char* kernelName);
454    cxuint addSection(const char* sectionName, cxuint kernelId);
455   
456    cxuint getSectionId(const char* sectionName) const;
457    void setCurrentKernel(cxuint kernel);
458    void setCurrentSection(cxuint sectionId);
459   
460    SectionInfo getSectionInfo(cxuint sectionId) const;
461    bool parsePseudoOp(const CString& firstName,
462           const char* stmtPlace, const char* linePtr);
463    void handleLabel(const CString& label);
464   
465    bool resolveSymbol(const AsmSymbol& symbol, uint64_t& value, cxuint& sectionId);
466    bool resolveRelocation(const AsmExpression* expr, uint64_t& value, cxuint& sectionId);
467    bool prepareBinary();
468    void writeBinary(std::ostream& os) const;
469    void writeBinary(Array<cxbyte>& array) const;
470    /// get output object (input for bingenerator)
471    const GalliumInput* getOutput() const
472    { return &output; }
473};
474
475typedef AsmAmdHsaKernelConfig AsmROCmKernelConfig;
476
477/// handles ROCM binary format
478class AsmROCmHandler: public AsmFormatHandler
479{
480private:
481    typedef std::unordered_map<CString, cxuint> SectionMap;
482    friend struct AsmROCmPseudoOps;
483    ROCmInput output;
484    struct Section
485    {
486        cxuint kernelId;
487        AsmSectionType type;
488        cxuint elfBinSectId;
489        const char* name;    // must be available by whole lifecycle
490    };
491    struct Kernel
492    {
493        cxuint configSection;
494        std::unique_ptr<AsmROCmKernelConfig> config;
495        bool isFKernel;
496        cxuint ctrlDirSection;
497        cxuint savedSection;
498        Flags allocRegFlags;
499        cxuint allocRegs[MAX_REGTYPES_NUM];
500       
501        void initializeKernelConfig();
502    };
503    std::vector<Kernel*> kernelStates;
504    std::vector<Section> sections;
505    std::vector<cxuint> kcodeSelection; // kcode
506    std::stack<std::vector<cxuint> > kcodeSelStack;
507    cxuint currentKcodeKernel;
508    SectionMap extraSectionMap;
509    cxuint codeSection;
510    cxuint commentSection;
511    cxuint metadataSection;
512    cxuint dataSection;
513    cxuint savedSection;
514    cxuint extraSectionCount;
515   
516    void restoreKcodeCurrentAllocRegs();
517    void saveKcodeCurrentAllocRegs();
518   
519public:
520    /// construcror
521    explicit AsmROCmHandler(Assembler& assembler);
522    /// destructor
523    ~AsmROCmHandler();
524   
525    cxuint addKernel(const char* kernelName);
526    cxuint addSection(const char* sectionName, cxuint kernelId);
527   
528    cxuint getSectionId(const char* sectionName) const;
529    void setCurrentKernel(cxuint kernel);
530    void setCurrentSection(cxuint sectionId);
531   
532    SectionInfo getSectionInfo(cxuint sectionId) const;
533    bool parsePseudoOp(const CString& firstName,
534           const char* stmtPlace, const char* linePtr);
535    void handleLabel(const CString& label);
536   
537    bool prepareBinary();
538    void writeBinary(std::ostream& os) const;
539    void writeBinary(Array<cxbyte>& array) const;
540    /// get output object (input for bingenerator)
541    const ROCmInput* getOutput() const
542    { return &output; }
543};
544
545};
546
547#endif
Note: See TracBrowser for help on using the repository browser.