source: CLRX/CLRadeonExtender/trunk/CLRX/amdasm/AsmDefs.h @ 4102

Last change on this file since 4102 was 4102, checked in by matszpk, 12 months ago

CLRadeonExtender: Asm: Add enums (pseudo-ops '.enum').

File size: 25.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 AsmDefs.h
20 * \brief an assembler for Radeon GPU's
21 */
22
23#ifndef __CLRX_ASMDEFS_H__
24#define __CLRX_ASMDEFS_H__
25
26#include <CLRX/Config.h>
27#include <cstdint>
28#include <vector>
29#include <utility>
30#include <list>
31#include <unordered_map>
32#include <CLRX/utils/Utilities.h>
33#include <CLRX/amdasm/Commons.h>
34#include <CLRX/amdasm/AsmSource.h>
35#include <CLRX/amdasm/AsmFormats.h>
36
37/// main namespace
38namespace CLRX
39{
40
41/// Assembler exception class
42class AsmException: public Exception
43{
44public:
45    /// empty constructor
46    AsmException() = default;
47    /// constructor with messasge
48    explicit AsmException(const std::string& message);
49    /// destructor
50    virtual ~AsmException() noexcept = default;
51};
52
53enum: cxbyte {
54    WS_UNSIGNED = 0,  // only unsigned
55    WS_BOTH = 1,  // both signed and unsigned range checking
56};
57
58/// expression target type (one byte)
59typedef cxbyte AsmExprTargetType;
60
61enum : AsmExprTargetType
62{
63    ASMXTGT_SYMBOL = 0, ///< target is symbol
64    ASMXTGT_DATA8,      ///< target is byte
65    ASMXTGT_DATA16,     ///< target is 16-bit word
66    ASMXTGT_DATA32,     ///< target is 32-bit word
67    ASMXTGT_DATA64,     ///< target is 64-bit word
68    ASMXTGT_CODEFLOW,    ///< code flow entry
69   
70    GCNTGT_LITIMM = 16,
71    GCNTGT_SOPKSIMM16,
72    GCNTGT_SOPJMP,
73    GCNTGT_SMRDOFFSET,
74    GCNTGT_DSOFFSET16,
75    GCNTGT_DSOFFSET8_0,
76    GCNTGT_DSOFFSET8_1,
77    GCNTGT_MXBUFOFFSET,
78    GCNTGT_SMEMOFFSET,
79    GCNTGT_SOPCIMM8,
80    GCNTGT_SMEMIMM,
81    GCNTGT_SMEMOFFSETVEGA,
82    GCNTGT_INSTOFFSET,
83    GCNTGT_INSTOFFSET_S
84};
85
86/*
87 * assembler expressions
88 */
89
90/// assembler expression operator
91enum class AsmExprOp : cxbyte
92{
93    ARG_VALUE = 0,  ///< value
94    ARG_SYMBOL = 1,  ///< symbol without defined value
95    NEGATE = 2, ///< negation
96    BIT_NOT,    ///< binary negation
97    LOGICAL_NOT,    ///< logical negation
98    PLUS,   ///< plus (nothing)
99    ADDITION,   ///< addition
100    SUBTRACT,       ///< subtraction
101    MULTIPLY,       ///< multiplication
102    DIVISION,       ///< unsigned division
103    SIGNED_DIVISION,    ///< signed division
104    MODULO,         ///< unsigned modulo
105    SIGNED_MODULO,      ///< signed modulo
106    BIT_AND,        ///< bitwise AND
107    BIT_OR,         //< bitwise OR
108    BIT_XOR,        ///< bitwise XOR
109    BIT_ORNOT,      ///< bitwise OR-not
110    SHIFT_LEFT,     ///< shift left
111    SHIFT_RIGHT,    ///< logical shift irght
112    SIGNED_SHIFT_RIGHT, ///< signed (arithmetic) shift right
113    LOGICAL_AND,    ///< logical AND
114    LOGICAL_OR,     ///< logical OR
115    EQUAL,          ///< equality
116    NOT_EQUAL,      ///< unequality
117    LESS,           ///< less than
118    LESS_EQ,        ///< less or equal than
119    GREATER,        ///< greater than
120    GREATER_EQ,     ///< greater or equal than
121    BELOW, ///< unsigned less
122    BELOW_EQ, ///< unsigned less or equal
123    ABOVE, ///< unsigned less
124    ABOVE_EQ, ///< unsigned less or equal
125    CHOICE,  ///< a ? b : c
126    CHOICE_START,   ///< helper
127    FIRST_ARG = ARG_VALUE,
128    LAST_ARG = ARG_SYMBOL,
129    FIRST_UNARY = NEGATE,   ///< helper
130    LAST_UNARY = PLUS,  ///< helper
131    FIRST_BINARY = ADDITION,    ///< helper
132    LAST_BINARY = ABOVE_EQ, ///< helper
133    NONE = 0xff ///< none operation
134};
135
136struct AsmExprTarget;
137
138union AsmExprArg;
139
140class AsmExpression;
141
142/// assembler symbol occurrence in expression
143struct AsmExprSymbolOccurrence
144{
145    AsmExpression* expression;      ///< target expression pointer
146    size_t argIndex;        ///< argument index
147    size_t opIndex;         ///< operator index
148   
149    /// comparison operator
150    bool operator==(const AsmExprSymbolOccurrence& b) const
151    { return expression==b.expression && opIndex==b.opIndex && argIndex==b.argIndex; }
152};
153
154struct AsmRegVar;
155struct AsmScope;
156
157/// assembler symbol structure
158struct AsmSymbol
159{
160    cxuint refCount;    ///< reference counter (for internal use only)
161    cxuint sectionId;       ///< section id
162    cxbyte info;           ///< ELF symbol info
163    cxbyte other;           ///< ELF symbol other
164    cxuint hasValue:1;         ///< symbol is defined
165    cxuint onceDefined:1;       ///< symbol can be only once defined (likes labels)
166    cxuint resolving:1;         ///< helper
167    cxuint base:1;              ///< with base expression
168    cxuint snapshot:1;          ///< if symbol is snapshot
169    cxuint regRange:1;          ///< if symbol is register range
170    cxuint detached:1;
171    cxuint withUnevalExpr:1;
172    uint64_t value;         ///< value of symbol
173    uint64_t size;          ///< size of symbol
174    union {
175        AsmExpression* expression;      ///< expression of symbol (if not resolved)
176        const AsmRegVar* regVar;
177    };
178   
179    /** list of occurrences in expressions */
180    std::vector<AsmExprSymbolOccurrence> occurrencesInExprs;
181   
182    /// empty constructor
183    explicit AsmSymbol(bool _onceDefined = false) :
184            refCount(1), sectionId(ASMSECT_ABS), info(0), other(0), hasValue(false),
185            onceDefined(_onceDefined), resolving(false), base(false), snapshot(false),
186            regRange(false), detached(false), withUnevalExpr(false),
187            value(0), size(0), expression(nullptr)
188    { }
189    /// constructor with expression
190    explicit AsmSymbol(AsmExpression* expr, bool _onceDefined = false, bool _base = false) :
191            refCount(1), sectionId(ASMSECT_ABS), info(0), other(0), hasValue(false),
192            onceDefined(_onceDefined), resolving(false), base(_base),
193            snapshot(false), regRange(false), detached(false), withUnevalExpr(false),
194            value(0), size(0), expression(expr)
195    { }
196    /// constructor with value and section id
197    explicit AsmSymbol(cxuint _sectionId, uint64_t _value, bool _onceDefined = false) :
198            refCount(1), sectionId(_sectionId), info(0), other(0), hasValue(true),
199            onceDefined(_onceDefined), resolving(false), base(false), snapshot(false),
200            regRange(false), detached(false), withUnevalExpr(false),
201            value(_value), size(0), expression(nullptr)
202    { }
203    /// destructor
204    ~AsmSymbol();
205   
206    /// adds occurrence in expression
207    void addOccurrenceInExpr(AsmExpression* expr, size_t argIndex, size_t opIndex)
208    { occurrencesInExprs.push_back({expr, argIndex, opIndex}); }
209    /// remove occurrence in expression
210    void removeOccurrenceInExpr(AsmExpression* expr, size_t argIndex, size_t opIndex);
211    /// clear list of occurrences in expression
212    void clearOccurrencesInExpr();
213    /// make symbol as undefined
214    void undefine();
215    /// return true if symbol defined (have value or expression)
216    bool isDefined() const
217    { return hasValue || expression!=nullptr; }
218};
219
220/// assembler symbol map
221typedef std::unordered_map<CString, AsmSymbol> AsmSymbolMap;
222/// assembler symbol entry
223typedef AsmSymbolMap::value_type AsmSymbolEntry;
224
225/// target for assembler expression
226struct AsmExprTarget
227{
228    AsmExprTargetType type;    ///< type of target
229    union
230    {
231        AsmSymbolEntry* symbol; ///< symbol entry (if ASMXTGT_SYMBOL)
232        struct {
233            cxuint sectionId;   ///< section id of destination
234            union {
235                size_t offset;      ///< offset of destination
236                size_t cflowId;     ///< cflow index of destination
237            };
238        };
239    };
240    /// empty constructor
241    AsmExprTarget() { }
242   
243    /// constructor to create custom target
244    AsmExprTarget(AsmExprTargetType _type, cxuint _sectionId, size_t _offset)
245            : type(_type), sectionId(_sectionId), offset(_offset)
246    { }
247   
248    /// make symbol target for expression
249    static AsmExprTarget symbolTarget(AsmSymbolEntry* entry)
250    { 
251        AsmExprTarget target;
252        target.type = ASMXTGT_SYMBOL;
253        target.symbol = entry;
254        return target;
255    }
256    /// make code flow target for expression
257    static AsmExprTarget codeFlowTarget(cxuint sectionId, size_t cflowIndex)
258    {
259        AsmExprTarget target;
260        target.type = ASMXTGT_CODEFLOW;
261        target.sectionId = sectionId;
262        target.cflowId = cflowIndex;
263        return target;
264    }
265   
266    /// make n-bit word target for expression
267    template<typename T>
268    static AsmExprTarget dataTarget(cxuint sectionId, size_t offset)
269    {
270        AsmExprTarget target;
271        target.type = (sizeof(T)==1) ? ASMXTGT_DATA8 : (sizeof(T)==2) ? ASMXTGT_DATA16 :
272                (sizeof(T)==4) ? ASMXTGT_DATA32 : ASMXTGT_DATA64;
273        target.sectionId = sectionId;
274        target.offset = offset;
275        return target;
276    }
277};
278
279/// assembler relocation
280struct AsmRelocation
281{
282    cxuint sectionId;   ///< section id where relocation is present
283    size_t offset;  ///< offset of relocation
284    RelocType type; ///< relocation type
285    union {
286        AsmSymbolEntry* symbol; ///< symbol
287        cxuint relSectionId;    ///< section for which relocation is defined
288    };
289    uint64_t addend;    ///< addend
290};
291
292/// class of return value for a trying routines
293enum class AsmTryStatus
294{
295    FAILED = 0, ///< if failed now, no later trial
296    TRY_LATER,  ///< try later (after some)
297    SUCCESS     ///< succeed, no trial needed
298};
299
300/// assembler expression class
301class AsmExpression: public NonCopyableAndNonMovable
302{
303private:
304    class TempSymbolSnapshotMap;
305   
306    AsmExprTarget target;
307    AsmSourcePos sourcePos;
308    size_t symOccursNum;
309    bool relativeSymOccurs;
310    bool baseExpr;
311    Array<AsmExprOp> ops;
312    std::unique_ptr<LineCol[]> messagePositions;    ///< for every potential message
313    std::unique_ptr<AsmExprArg[]> args;
314   
315    AsmSourcePos getSourcePos(size_t msgPosIndex) const
316    {
317        AsmSourcePos pos = sourcePos;
318        pos.lineNo = messagePositions[msgPosIndex].lineNo;
319        pos.colNo = messagePositions[msgPosIndex].colNo;
320        return pos;
321    }
322   
323    static bool makeSymbolSnapshot(Assembler& assembler,
324               TempSymbolSnapshotMap* snapshotMap, const AsmSymbolEntry& symEntry,
325               AsmSymbolEntry*& outSymEntry, const AsmSourcePos* topParentSourcePos);
326   
327    AsmExpression();
328    void setParams(size_t symOccursNum, bool relativeSymOccurs,
329            size_t _opsNum, const AsmExprOp* ops, size_t opPosNum, const LineCol* opPos,
330            size_t argsNum, const AsmExprArg* args, bool baseExpr = false);
331public:
332    /// constructor of expression (helper)
333    AsmExpression(const AsmSourcePos& pos, size_t symOccursNum, bool relativeSymOccurs,
334            size_t opsNum, size_t opPosNum, size_t argsNum, bool baseExpr = false);
335    /// constructor of expression (helper)
336    AsmExpression(const AsmSourcePos& pos, size_t symOccursNum, bool relativeSymOccurs,
337              size_t opsNum, const AsmExprOp* ops, size_t opPosNum,
338              const LineCol* opPos, size_t argsNum, const AsmExprArg* args,
339              bool baseExpr = false);
340    /// destructor
341    ~AsmExpression();
342   
343    /// return true if expression is empty
344    bool isEmpty() const
345    { return ops.empty(); }
346   
347    /// helper to create symbol snapshot. Creates initial expression for symbol snapshot
348    AsmExpression* createForSnapshot(const AsmSourcePos* exprSourcePos) const;
349   
350    /// set target of expression
351    void setTarget(AsmExprTarget _target)
352    { target = _target; }
353   
354    /// try to evaluate expression with/without section differences
355    /**
356     * \param assembler assembler instace
357     * \param opStart start operand
358     * \param opEnd end operand
359     * \param value output value
360     * \param sectionId output section id
361     * \param withSectionDiffs evaluate including precalculated section differences
362     * \return operation status
363     */
364    AsmTryStatus tryEvaluate(Assembler& assembler, size_t opStart, size_t opEnd,
365                  uint64_t& value, cxuint& sectionId, bool withSectionDiffs = false) const;
366   
367    /// try to evaluate expression with/without section differences
368    /**
369     * \param assembler assembler instace
370     * \param value output value
371     * \param sectionId output section id
372     * \param withSectionDiffs evaluate including precalculated section differences
373     * \return operation status
374     */
375    AsmTryStatus tryEvaluate(Assembler& assembler, uint64_t& value, cxuint& sectionId,
376                    bool withSectionDiffs = false) const
377    { return tryEvaluate(assembler, 0, ops.size(), value, sectionId, withSectionDiffs); }
378   
379    /// try to evaluate expression
380    /**
381     * \param assembler assembler instace
382     * \param value output value
383     * \param sectionId output section id
384     * \return true if evaluated
385     */
386    bool evaluate(Assembler& assembler, uint64_t& value, cxuint& sectionId) const
387    { return tryEvaluate(assembler, 0, ops.size(), value, sectionId) !=
388                    AsmTryStatus::FAILED; }
389   
390    /// try to evaluate expression
391    /**
392     * \param assembler assembler instace
393     * \param value output value
394     * \param opStart start operand
395     * \param opEnd end operand
396     * \param sectionId output section id
397     * \return true if evaluated
398     */
399    bool evaluate(Assembler& assembler, size_t opStart, size_t opEnd,
400                  uint64_t& value, cxuint& sectionId) const
401    { return tryEvaluate(assembler, opStart, opEnd, value, sectionId) !=
402                    AsmTryStatus::FAILED; }
403   
404    /// parse expression. By default, also gets values of symbol or  creates them
405    /** parse expresion from assembler's line string. Accepts empty expression.
406     * \param assembler assembler
407     * \param linePos position in line and output position in line
408     * \param makeBase do not evaluate resolved symbols, put them to expression
409     * \param dontResolveSymbolsLater do not resolve symbols later
410     * \return expression pointer
411     */
412    static AsmExpression* parse(Assembler& assembler, size_t& linePos,
413                    bool makeBase = false, bool dontResolveSymbolsLater = false);
414   
415    /// parse expression. By default, also gets values of symbol or  creates them
416    /** parse expresion from assembler's line string. Accepts empty expression.
417     * \param assembler assembler
418     * \param linePtr string at position in line (returns output line pointer)
419     * \param makeBase do not evaluate resolved symbols, put them to expression
420     * \param dontResolveSymbolsLater do not resolve symbols later
421     * \return expression pointer
422     */
423    static AsmExpression* parse(Assembler& assembler, const char*& linePtr,
424              bool makeBase = false, bool dontResolveSymbolsLater = false);
425   
426    /// return true if is argument op
427    static bool isArg(AsmExprOp op)
428    { return (AsmExprOp::FIRST_ARG <= op && op <= AsmExprOp::LAST_ARG); }
429    /// return true if is unary op
430    static bool isUnaryOp(AsmExprOp op)
431    { return (AsmExprOp::FIRST_UNARY <= op && op <= AsmExprOp::LAST_UNARY); }
432    /// return true if is binary op
433    static bool isBinaryOp(AsmExprOp op)
434    { return (AsmExprOp::FIRST_BINARY <= op && op <= AsmExprOp::LAST_BINARY); }
435    /// get targer of expression
436    const AsmExprTarget& getTarget() const
437    { return target; }
438    /// get number of symbol occurrences in expression
439    size_t getSymOccursNum() const
440    { return symOccursNum; }
441    /// get number of symbol occurrences in expression
442    size_t hasRelativeSymOccurs() const
443    { return relativeSymOccurs; }
444    /// unreference symbol occurrences in expression (used internally)
445    bool unrefSymOccursNum()
446    { return --symOccursNum!=0; }
447   
448    /// substitute occurrence in expression by value
449    void substituteOccurrence(AsmExprSymbolOccurrence occurrence, uint64_t value,
450                  cxuint sectionId = ASMSECT_ABS);
451    /// replace symbol in expression
452    void replaceOccurrenceSymbol(AsmExprSymbolOccurrence occurrence,
453                    AsmSymbolEntry* newSymEntry);
454    /// get operators list
455    const Array<AsmExprOp>& getOps() const
456    { return ops; }
457    /// get argument list
458    const AsmExprArg* getArgs() const
459    { return args.get(); }
460    /// get source position
461    const AsmSourcePos& getSourcePos() const
462    { return sourcePos; }
463   
464    /// for internal usage
465    size_t toTop(size_t opIndex) const;
466   
467    /// create an expression to evaluate from base expression
468    AsmExpression* createExprToEvaluate(Assembler& assembler) const;
469   
470    /// make symbol snapshot (required to implement .eqv pseudo-op)   
471    static bool makeSymbolSnapshot(Assembler& assembler, const AsmSymbolEntry& symEntry,
472               AsmSymbolEntry*& outSymEntry, const AsmSourcePos* parentExprSourcePos);
473   
474    /// fast expression parse and evaluate
475    static bool fastExprEvaluate(Assembler& assembler, const char*& linePtr,
476                uint64_t& value);
477    static bool fastExprEvaluate(Assembler& assembler, size_t& linePos,
478                uint64_t& value);
479};
480
481inline AsmSymbol::~AsmSymbol()
482{
483    if (base) delete expression; // if symbol with base expresion
484    clearOccurrencesInExpr();
485}
486
487/// assembler expression argument
488union AsmExprArg
489{
490    AsmSymbolEntry* symbol; ///< if symbol
491    uint64_t value;         ///< value
492    struct {
493        uint64_t value;         ///< value
494        cxuint sectionId;       ///< sectionId
495    } relValue; ///< relative value (with section)
496};
497
498inline void AsmExpression::substituteOccurrence(AsmExprSymbolOccurrence occurrence,
499                        uint64_t value, cxuint sectionId)
500{
501    ops[occurrence.opIndex] = AsmExprOp::ARG_VALUE;
502    args[occurrence.argIndex].relValue.value = value;
503    args[occurrence.argIndex].relValue.sectionId = sectionId;
504    if (sectionId != ASMSECT_ABS)
505        relativeSymOccurs = true;
506}
507
508inline void AsmExpression::replaceOccurrenceSymbol(AsmExprSymbolOccurrence occurrence,
509                    AsmSymbolEntry* newSymEntry)
510{
511    args[occurrence.argIndex].symbol = newSymEntry;
512}
513
514/// type of register field
515typedef cxbyte AsmRegField;
516
517enum : AsmRegField
518{
519    ASMFIELD_NONE = 0,
520    GCNFIELD_SSRC0,
521    GCNFIELD_SSRC1,
522    GCNFIELD_SDST,
523    GCNFIELD_SMRD_SBASE,
524    GCNFIELD_SMRD_SDST,
525    GCNFIELD_SMRD_SDSTH,
526    GCNFIELD_SMRD_SOFFSET,
527    GCNFIELD_VOP_SRC0,
528    GCNFIELD_VOP_VSRC1,
529    GCNFIELD_VOP_SSRC1,
530    GCNFIELD_VOP_VDST,
531    GCNFIELD_VOP_SDST,
532    GCNFIELD_VOP3_SRC0,
533    GCNFIELD_VOP3_SRC1,
534    GCNFIELD_VOP3_SRC2,
535    GCNFIELD_VOP3_VDST,
536    GCNFIELD_VOP3_SDST0,
537    GCNFIELD_VOP3_SSRC,
538    GCNFIELD_VOP3_SDST1,
539    GCNFIELD_VINTRP_VSRC0,
540    GCNFIELD_VINTRP_VDST,
541    GCNFIELD_DS_ADDR,
542    GCNFIELD_DS_DATA0,
543    GCNFIELD_DS_DATA1,
544    GCNFIELD_DS_VDST,
545    GCNFIELD_M_VADDR,
546    GCNFIELD_M_VDATA,
547    GCNFIELD_M_VDATAH,
548    GCNFIELD_M_VDATALAST,
549    GCNFIELD_M_SRSRC,
550    GCNFIELD_MIMG_SSAMP,
551    GCNFIELD_M_SOFFSET,
552    GCNFIELD_EXP_VSRC0,
553    GCNFIELD_EXP_VSRC1,
554    GCNFIELD_EXP_VSRC2,
555    GCNFIELD_EXP_VSRC3,
556    GCNFIELD_FLAT_ADDR,
557    GCNFIELD_FLAT_DATA,
558    GCNFIELD_FLAT_VDST,
559    GCNFIELD_FLAT_VDSTLAST,
560    GCNFIELD_DPPSDWA_SRC0,
561    GCNFIELD_DPPSDWA_SSRC0,
562    GCNFIELD_FLAT_SADDR,
563    GCNFIELD_SDWAB_SDST
564};
565
566struct AsmScope;
567
568/// Regvar info structure
569struct AsmRegVar
570{
571    cxuint type;    ///< scalar/vector/other
572    uint16_t size;  ///< in regs
573};
574
575/// single regvar id
576struct AsmSingleVReg // key for regvar
577{
578    const AsmRegVar* regVar;    ///< regvar
579    uint16_t index; ///< index of regvar array
580   
581    /// equal operator
582    bool operator==(const AsmSingleVReg& r2) const
583    { return regVar == r2.regVar && index == r2.index; }
584    /// not equal operator
585    bool operator!=(const AsmSingleVReg& r2) const
586    { return regVar == r2.regVar && index == r2.index; }
587};
588
589/// regvar map
590typedef std::unordered_map<CString, AsmRegVar> AsmRegVarMap;
591/// regvar entry
592typedef AsmRegVarMap::value_type AsmRegVarEntry;
593
594enum : cxbyte {
595    ASMRVU_READ = 1,        ///< register will be read
596    ASMRVU_WRITE = 2,       ///< register will be written
597    ASMRVU_ACCESS_MASK = 3, ///< access mask
598    ASMRVU_REGTYPE_MASK = 4,    ///< for internal usage (regtype)
599    ASMRVU_REGSIZE_SHIFT = 3,   ///< for internal usage
600    ASMRVU_REGSIZE_MASK = 0x78  ///< for internal usage
601};
602
603/// regvar usage in code
604struct AsmRegVarUsage
605{
606    size_t offset;  ///< offset in section
607    const AsmRegVar* regVar;    ///< if null, then usage of called register
608    uint16_t rstart; ///< register start
609    uint16_t rend;  ///< register end
610    AsmRegField regField;   ///< place in instruction
611    cxbyte rwFlags;  ///< 1 - read, 2 - write
612    cxbyte align;   ///< register alignment
613    bool useRegMode; ///< if RVU from useReg pseudo-ops
614};
615
616/// regvar usage (internal)
617struct AsmRegVarUsageInt
618{
619    const AsmRegVar* regVar;    ///< if null, then usage of called register
620    uint16_t rstart;    ///< register start
621    uint16_t rend;      ///< register end
622    AsmRegField regField;   ///< place in instruction
623    cxbyte rwFlags;  ///< 1 - read, 2 - write
624    cxbyte align;   ///< register alignment
625};
626
627/// internal structure for regusage
628struct AsmRegUsageInt
629{
630    AsmRegField regField;   ///< place in instruction
631    cxbyte rwFlags;     ///< 1 - read, 2 - write, other flags
632};
633
634/// internal structure for regusage
635struct AsmRegUsage2Int
636{
637    uint16_t rstart;    ///< register start
638    uint16_t rend;      ///< register end
639    cxbyte rwFlags;     ///< rw flags and others
640};
641
642/// code flow type
643enum AsmCodeFlowType
644{
645    JUMP = 0,   ///< jump
646    CJUMP,   ///< conditional jump
647    CALL,   ///< call of procedure
648    RETURN, ///< return from procedure
649    START,  ///< code start
650    END     ///< code end
651};
652
653/// code flow entry
654struct AsmCodeFlowEntry
655{
656    size_t offset;      ///< offset where is this entry
657    size_t target;      ///< target jump addreses
658    AsmCodeFlowType type;   ///< type of code flow entry
659};
660
661/// assembler macro map
662typedef std::unordered_map<CString, RefPtr<const AsmMacro> > AsmMacroMap;
663
664struct AsmScope;
665
666/// type definition of scope's map
667typedef std::unordered_map<CString, AsmScope*> AsmScopeMap;
668
669/// assembler scope for symbol, macros, regvars
670struct AsmScope
671{
672    AsmScope* parent;   ///< parent scope
673    AsmSymbolMap symbolMap; ///< symbol map
674    AsmRegVarMap regVarMap; ///< regvar map
675    AsmScopeMap scopeMap;   ///< scope map
676    bool temporary; ///< true if temporary
677    std::list<AsmScope*> usedScopes;    ///< list of used scope in this scope
678    uint64_t enumCount;
679   
680    /// set of used scopes in this scope
681    std::unordered_map<AsmScope*, std::list<AsmScope*>::iterator> usedScopesSet;
682   
683    /// constructor
684    AsmScope(AsmScope* _parent, const AsmSymbolMap& _symbolMap,
685                     bool _temporary = false)
686            : parent(_parent), symbolMap(_symbolMap), temporary(_temporary), enumCount(0)
687    { }
688    /// constructor
689    AsmScope(AsmScope* _parent = nullptr, bool _temporary= false)
690            : parent(_parent), temporary(_temporary), enumCount(0)
691    { }
692    /// destructor
693    ~AsmScope();
694   
695    /// start using scope in this scope
696    void startUsingScope(AsmScope* scope);
697    /// stop using scope in this scope
698    void stopUsingScope(AsmScope* scope);
699    /// remove all usings
700    void stopUsingScopes()
701    {
702        usedScopes.clear();
703        usedScopesSet.clear();
704    }
705    /// delete symbols recursively
706    void deleteSymbolsRecursively();
707};
708
709class ISAUsageHandler;
710
711/// assembler section
712struct AsmSection
713{
714    const char* name;       ///< section name
715    cxuint kernelId;    ///< kernel id (optional)
716    AsmSectionType type;        ///< type of section
717    Flags flags;   ///< section flags
718    uint64_t alignment; ///< section alignment
719    uint64_t size;  ///< section size
720    cxuint relSpace;    ///< relative space where is section
721    uint64_t relAddress; ///< relative address
722    std::vector<cxbyte> content;    ///< content of section
723   
724    std::unique_ptr<ISAUsageHandler> usageHandler;  ///< usage handler
725    std::vector<AsmCodeFlowEntry> codeFlow;  ///< code flow info
726   
727    /// constructor
728    AsmSection();
729    /// constructor
730    AsmSection(const char* _name, cxuint _kernelId, AsmSectionType _type, Flags _flags,
731               uint64_t _alignment, uint64_t _size = 0, cxuint _relSpace = UINT_MAX,
732               uint64_t _relAddress = UINT64_MAX)
733            : name(_name), kernelId(_kernelId), type(_type), flags(_flags),
734              alignment(_alignment), size(_size), relSpace(_relSpace),
735              relAddress(_relAddress)
736    { }
737   
738    /// copy constructor
739    AsmSection(const AsmSection& section);
740    /// copy assignment
741    AsmSection& operator=(const AsmSection& section);
742   
743    /// add code flow entry to this section
744    void addCodeFlowEntry(const AsmCodeFlowEntry& entry)
745    { codeFlow.push_back(entry); }
746   
747    /// get section's size
748    size_t getSize() const
749    { return ((flags&ASMSECT_WRITEABLE) != 0) ? content.size() : size; }
750};
751
752/// kernel entry structure
753struct AsmKernel
754{
755    const char* name;   ///< name of kernel
756    AsmSourcePos sourcePos; ///< source position of definition
757    std::vector<std::pair<size_t, size_t> > codeRegions; ///< code regions
758   
759    /// open kernel region in code
760    void openCodeRegion(size_t offset);
761    /// close kernel region in code
762    void closeCodeRegion(size_t offset);
763};
764
765};
766
767namespace std
768{
769
770/// std::hash specialization for CLRX CString
771template<>
772struct hash<CLRX::AsmSingleVReg>
773{
774    typedef CLRX::AsmSingleVReg argument_type;    ///< argument type
775    typedef std::size_t result_type;    ///< result type
776   
777    /// a calling operator
778    size_t operator()(const CLRX::AsmSingleVReg& r1) const
779    {
780        std::hash<const CLRX::AsmRegVar*> h1;
781        std::hash<uint16_t> h2;
782        return h1(r1.regVar) ^ (h2(r1.index)<<1);
783    }
784};
785
786}
787
788#endif
Note: See TracBrowser for help on using the repository browser.