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

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

CLRadeonExtender: Asm: First stuff to handle section differences (untested and not working).

File size: 24.7 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    uint64_t value;         ///< value of symbol
171    uint64_t size;          ///< size of symbol
172    union {
173        AsmExpression* expression;      ///< expression of symbol (if not resolved)
174        const AsmRegVar* regVar;
175    };
176   
177    /** list of occurrences in expressions */
178    std::vector<AsmExprSymbolOccurrence> occurrencesInExprs;
179   
180    /// empty constructor
181    explicit AsmSymbol(bool _onceDefined = false) :
182            refCount(1), sectionId(ASMSECT_ABS), info(0), other(0), hasValue(false),
183            onceDefined(_onceDefined), resolving(false), base(false), snapshot(false),
184            regRange(false), value(0), size(0), expression(nullptr)
185    { }
186    /// constructor with expression
187    explicit AsmSymbol(AsmExpression* expr, bool _onceDefined = false, bool _base = false) :
188            refCount(1), sectionId(ASMSECT_ABS), info(0), other(0), hasValue(false),
189            onceDefined(_onceDefined), resolving(false), base(_base),
190            snapshot(false), regRange(false), value(0), size(0), expression(expr)
191    { }
192    /// constructor with value and section id
193    explicit AsmSymbol(cxuint _sectionId, uint64_t _value, bool _onceDefined = false) :
194            refCount(1), sectionId(_sectionId), info(0), other(0), hasValue(true),
195            onceDefined(_onceDefined), resolving(false), base(false), snapshot(false),
196            regRange(false), value(_value), size(0), expression(nullptr)
197    { }
198    /// destructor
199    ~AsmSymbol();
200   
201    /// adds occurrence in expression
202    void addOccurrenceInExpr(AsmExpression* expr, size_t argIndex, size_t opIndex)
203    { occurrencesInExprs.push_back({expr, argIndex, opIndex}); }
204    /// remove occurrence in expression
205    void removeOccurrenceInExpr(AsmExpression* expr, size_t argIndex, size_t opIndex);
206    /// clear list of occurrences in expression
207    void clearOccurrencesInExpr();
208    /// make symbol as undefined
209    void undefine();
210    /// return true if symbol defined (have value or expression)
211    bool isDefined() const
212    { return hasValue || expression!=nullptr; }
213};
214
215/// assembler symbol map
216typedef std::unordered_map<CString, AsmSymbol> AsmSymbolMap;
217/// assembler symbol entry
218typedef AsmSymbolMap::value_type AsmSymbolEntry;
219
220/// target for assembler expression
221struct AsmExprTarget
222{
223    AsmExprTargetType type;    ///< type of target
224    union
225    {
226        AsmSymbolEntry* symbol; ///< symbol entry (if ASMXTGT_SYMBOL)
227        struct {
228            cxuint sectionId;   ///< section id of destination
229            union {
230                size_t offset;      ///< offset of destination
231                size_t cflowId;     ///< cflow index of destination
232            };
233        };
234    };
235    /// empty constructor
236    AsmExprTarget() { }
237   
238    /// constructor to create custom target
239    AsmExprTarget(AsmExprTargetType _type, cxuint _sectionId, size_t _offset)
240            : type(_type), sectionId(_sectionId), offset(_offset)
241    { }
242   
243    /// make symbol target for expression
244    static AsmExprTarget symbolTarget(AsmSymbolEntry* entry)
245    { 
246        AsmExprTarget target;
247        target.type = ASMXTGT_SYMBOL;
248        target.symbol = entry;
249        return target;
250    }
251    /// make code flow target for expression
252    static AsmExprTarget codeFlowTarget(cxuint sectionId, size_t cflowIndex)
253    {
254        AsmExprTarget target;
255        target.type = ASMXTGT_CODEFLOW;
256        target.sectionId = sectionId;
257        target.cflowId = cflowIndex;
258        return target;
259    }
260   
261    /// make n-bit word target for expression
262    template<typename T>
263    static AsmExprTarget dataTarget(cxuint sectionId, size_t offset)
264    {
265        AsmExprTarget target;
266        target.type = (sizeof(T)==1) ? ASMXTGT_DATA8 : (sizeof(T)==2) ? ASMXTGT_DATA16 :
267                (sizeof(T)==4) ? ASMXTGT_DATA32 : ASMXTGT_DATA64;
268        target.sectionId = sectionId;
269        target.offset = offset;
270        return target;
271    }
272};
273
274/// assembler relocation
275struct AsmRelocation
276{
277    cxuint sectionId;   ///< section id where relocation is present
278    size_t offset;  ///< offset of relocation
279    RelocType type; ///< relocation type
280    union {
281        AsmSymbolEntry* symbol; ///< symbol
282        cxuint relSectionId;    ///< section for which relocation is defined
283    };
284    uint64_t addend;    ///< addend
285};
286
287/// class of return value for a trying routines
288enum class AsmTryStatus
289{
290    FAILED = 0, ///< if failed now, no later trial
291    TRY_LATER,  ///< try later (after some)
292    SUCCESS     ///< succeed, no trial needed
293};
294
295/// assembler expression class
296class AsmExpression: public NonCopyableAndNonMovable
297{
298private:
299    class TempSymbolSnapshotMap;
300   
301    AsmExprTarget target;
302    AsmSourcePos sourcePos;
303    size_t symOccursNum;
304    bool relativeSymOccurs;
305    bool baseExpr;
306    Array<AsmExprOp> ops;
307    std::unique_ptr<LineCol[]> messagePositions;    ///< for every potential message
308    std::unique_ptr<AsmExprArg[]> args;
309   
310    AsmSourcePos getSourcePos(size_t msgPosIndex) const
311    {
312        AsmSourcePos pos = sourcePos;
313        pos.lineNo = messagePositions[msgPosIndex].lineNo;
314        pos.colNo = messagePositions[msgPosIndex].colNo;
315        return pos;
316    }
317   
318    static bool makeSymbolSnapshot(Assembler& assembler,
319               TempSymbolSnapshotMap* snapshotMap, const AsmSymbolEntry& symEntry,
320               AsmSymbolEntry*& outSymEntry, const AsmSourcePos* topParentSourcePos);
321   
322    AsmExpression();
323    void setParams(size_t symOccursNum, bool relativeSymOccurs,
324            size_t _opsNum, const AsmExprOp* ops, size_t opPosNum, const LineCol* opPos,
325            size_t argsNum, const AsmExprArg* args, bool baseExpr = false);
326public:
327    /// constructor of expression (helper)
328    AsmExpression(const AsmSourcePos& pos, size_t symOccursNum, bool relativeSymOccurs,
329            size_t opsNum, size_t opPosNum, size_t argsNum, bool baseExpr = false);
330    /// constructor of expression (helper)
331    AsmExpression(const AsmSourcePos& pos, size_t symOccursNum, bool relativeSymOccurs,
332              size_t opsNum, const AsmExprOp* ops, size_t opPosNum,
333              const LineCol* opPos, size_t argsNum, const AsmExprArg* args,
334              bool baseExpr = false);
335    /// destructor
336    ~AsmExpression();
337   
338    /// return true if expression is empty
339    bool isEmpty() const
340    { return ops.empty(); }
341   
342    /// helper to create symbol snapshot. Creates initial expression for symbol snapshot
343    AsmExpression* createForSnapshot(const AsmSourcePos* exprSourcePos) const;
344   
345    /// set target of expression
346    void setTarget(AsmExprTarget _target)
347    { target = _target; }
348   
349    /// try to evaluate expression with/without section differences
350    /**
351     * \param assembler assembler instace
352     * \param value output value
353     * \param sectionId output section id
354     * \param withSectionDiffs evaluate including precalculated section differences
355     * \return operation status
356     */
357    AsmTryStatus tryEvaluate(Assembler& assembler, size_t opStart, size_t opEnd,
358                  uint64_t& value, cxuint& sectionId, bool withSectionDiffs = false) const;
359   
360    /// try to evaluate expression
361    /**
362     * \param assembler assembler instace
363     * \param value output value
364     * \param sectionId output section id
365     * \return true if evaluated
366     */
367    bool evaluate(Assembler& assembler, uint64_t& value, cxuint& sectionId) const
368    { return tryEvaluate(assembler, 0, ops.size(), value, sectionId) !=
369                    AsmTryStatus::FAILED; }
370   
371    /// try to evaluate expression
372    /**
373     * \param assembler assembler instace
374     * \param value output value
375     * \param opStart start operand
376     * \param opEnd end operand
377     * \param sectionId output section id
378     * \return true if evaluated
379     */
380    bool evaluate(Assembler& assembler, size_t opStart, size_t opEnd,
381                  uint64_t& value, cxuint& sectionId) const
382    { return tryEvaluate(assembler, opStart, opEnd, value, sectionId) !=
383                    AsmTryStatus::FAILED; }
384   
385    /// parse expression. By default, also gets values of symbol or  creates them
386    /** parse expresion from assembler's line string. Accepts empty expression.
387     * \param assembler assembler
388     * \param linePos position in line and output position in line
389     * \param makeBase do not evaluate resolved symbols, put them to expression
390     * \param dontResolveSymbolsLater do not resolve symbols later
391     * \return expression pointer
392     */
393    static AsmExpression* parse(Assembler& assembler, size_t& linePos,
394                    bool makeBase = false, bool dontResolveSymbolsLater = false);
395   
396    /// parse expression. By default, also gets values of symbol or  creates them
397    /** parse expresion from assembler's line string. Accepts empty expression.
398     * \param assembler assembler
399     * \param linePtr string at position in line (returns output line pointer)
400     * \param makeBase do not evaluate resolved symbols, put them to expression
401     * \param dontResolveSymbolsLater do not resolve symbols later
402     * \return expression pointer
403     */
404    static AsmExpression* parse(Assembler& assembler, const char*& linePtr,
405              bool makeBase = false, bool dontResolveSymbolsLater = false);
406   
407    /// return true if is argument op
408    static bool isArg(AsmExprOp op)
409    { return (AsmExprOp::FIRST_ARG <= op && op <= AsmExprOp::LAST_ARG); }
410    /// return true if is unary op
411    static bool isUnaryOp(AsmExprOp op)
412    { return (AsmExprOp::FIRST_UNARY <= op && op <= AsmExprOp::LAST_UNARY); }
413    /// return true if is binary op
414    static bool isBinaryOp(AsmExprOp op)
415    { return (AsmExprOp::FIRST_BINARY <= op && op <= AsmExprOp::LAST_BINARY); }
416    /// get targer of expression
417    const AsmExprTarget& getTarget() const
418    { return target; }
419    /// get number of symbol occurrences in expression
420    size_t getSymOccursNum() const
421    { return symOccursNum; }
422    /// get number of symbol occurrences in expression
423    size_t hasRelativeSymOccurs() const
424    { return relativeSymOccurs; }
425    /// unreference symbol occurrences in expression (used internally)
426    bool unrefSymOccursNum()
427    { return --symOccursNum!=0; }
428   
429    /// substitute occurrence in expression by value
430    void substituteOccurrence(AsmExprSymbolOccurrence occurrence, uint64_t value,
431                  cxuint sectionId = ASMSECT_ABS);
432    /// get operators list
433    const Array<AsmExprOp>& getOps() const
434    { return ops; }
435    /// get argument list
436    const AsmExprArg* getArgs() const
437    { return args.get(); }
438    /// get source position
439    const AsmSourcePos& getSourcePos() const
440    { return sourcePos; }
441   
442    /// for internal usage
443    size_t toTop(size_t opIndex) const;
444   
445    /// create an expression to evaluate from base expression
446    AsmExpression* createExprToEvaluate(Assembler& assembler) const;
447   
448    /// make symbol snapshot (required to implement .eqv pseudo-op)   
449    static bool makeSymbolSnapshot(Assembler& assembler, const AsmSymbolEntry& symEntry,
450               AsmSymbolEntry*& outSymEntry, const AsmSourcePos* parentExprSourcePos);
451   
452    /// fast expression parse and evaluate
453    static bool fastExprEvaluate(Assembler& assembler, const char*& linePtr,
454                uint64_t& value);
455    static bool fastExprEvaluate(Assembler& assembler, size_t& linePos,
456                uint64_t& value);
457};
458
459inline AsmSymbol::~AsmSymbol()
460{
461    if (base) delete expression; // if symbol with base expresion
462    clearOccurrencesInExpr();
463}
464
465/// assembler expression argument
466union AsmExprArg
467{
468    AsmSymbolEntry* symbol; ///< if symbol
469    uint64_t value;         ///< value
470    struct {
471        uint64_t value;         ///< value
472        cxuint sectionId;       ///< sectionId
473    } relValue; ///< relative value (with section)
474};
475
476inline void AsmExpression::substituteOccurrence(AsmExprSymbolOccurrence occurrence,
477                        uint64_t value, cxuint sectionId)
478{
479    ops[occurrence.opIndex] = AsmExprOp::ARG_VALUE;
480    args[occurrence.argIndex].relValue.value = value;
481    args[occurrence.argIndex].relValue.sectionId = sectionId;
482    if (sectionId != ASMSECT_ABS)
483        relativeSymOccurs = true;
484}
485
486/// type of register field
487typedef cxbyte AsmRegField;
488
489enum : AsmRegField
490{
491    ASMFIELD_NONE = 0,
492    GCNFIELD_SSRC0,
493    GCNFIELD_SSRC1,
494    GCNFIELD_SDST,
495    GCNFIELD_SMRD_SBASE,
496    GCNFIELD_SMRD_SDST,
497    GCNFIELD_SMRD_SDSTH,
498    GCNFIELD_SMRD_SOFFSET,
499    GCNFIELD_VOP_SRC0,
500    GCNFIELD_VOP_VSRC1,
501    GCNFIELD_VOP_SSRC1,
502    GCNFIELD_VOP_VDST,
503    GCNFIELD_VOP_SDST,
504    GCNFIELD_VOP3_SRC0,
505    GCNFIELD_VOP3_SRC1,
506    GCNFIELD_VOP3_SRC2,
507    GCNFIELD_VOP3_VDST,
508    GCNFIELD_VOP3_SDST0,
509    GCNFIELD_VOP3_SSRC,
510    GCNFIELD_VOP3_SDST1,
511    GCNFIELD_VINTRP_VSRC0,
512    GCNFIELD_VINTRP_VDST,
513    GCNFIELD_DS_ADDR,
514    GCNFIELD_DS_DATA0,
515    GCNFIELD_DS_DATA1,
516    GCNFIELD_DS_VDST,
517    GCNFIELD_M_VADDR,
518    GCNFIELD_M_VDATA,
519    GCNFIELD_M_VDATAH,
520    GCNFIELD_M_VDATALAST,
521    GCNFIELD_M_SRSRC,
522    GCNFIELD_MIMG_SSAMP,
523    GCNFIELD_M_SOFFSET,
524    GCNFIELD_EXP_VSRC0,
525    GCNFIELD_EXP_VSRC1,
526    GCNFIELD_EXP_VSRC2,
527    GCNFIELD_EXP_VSRC3,
528    GCNFIELD_FLAT_ADDR,
529    GCNFIELD_FLAT_DATA,
530    GCNFIELD_FLAT_VDST,
531    GCNFIELD_FLAT_VDSTLAST,
532    GCNFIELD_DPPSDWA_SRC0,
533    GCNFIELD_DPPSDWA_SSRC0,
534    GCNFIELD_FLAT_SADDR,
535    GCNFIELD_SDWAB_SDST
536};
537
538struct AsmScope;
539
540/// Regvar info structure
541struct AsmRegVar
542{
543    cxuint type;    ///< scalar/vector/other
544    uint16_t size;  ///< in regs
545};
546
547/// single regvar id
548struct AsmSingleVReg // key for regvar
549{
550    const AsmRegVar* regVar;    ///< regvar
551    uint16_t index; ///< index of regvar array
552   
553    /// equal operator
554    bool operator==(const AsmSingleVReg& r2) const
555    { return regVar == r2.regVar && index == r2.index; }
556    /// not equal operator
557    bool operator!=(const AsmSingleVReg& r2) const
558    { return regVar == r2.regVar && index == r2.index; }
559};
560
561/// regvar map
562typedef std::unordered_map<CString, AsmRegVar> AsmRegVarMap;
563/// regvar entry
564typedef AsmRegVarMap::value_type AsmRegVarEntry;
565
566enum : cxbyte {
567    ASMRVU_READ = 1,        ///< register will be read
568    ASMRVU_WRITE = 2,       ///< register will be written
569    ASMRVU_ACCESS_MASK = 3, ///< access mask
570    ASMRVU_REGTYPE_MASK = 4,    ///< for internal usage (regtype)
571    ASMRVU_REGSIZE_SHIFT = 3,   ///< for internal usage
572    ASMRVU_REGSIZE_MASK = 0x78  ///< for internal usage
573};
574
575/// regvar usage in code
576struct AsmRegVarUsage
577{
578    size_t offset;  ///< offset in section
579    const AsmRegVar* regVar;    ///< if null, then usage of called register
580    uint16_t rstart; ///< register start
581    uint16_t rend;  ///< register end
582    AsmRegField regField;   ///< place in instruction
583    cxbyte rwFlags;  ///< 1 - read, 2 - write
584    cxbyte align;   ///< register alignment
585    bool useRegMode; ///< if RVU from useReg pseudo-ops
586};
587
588/// regvar usage (internal)
589struct AsmRegVarUsageInt
590{
591    const AsmRegVar* regVar;    ///< if null, then usage of called register
592    uint16_t rstart;    ///< register start
593    uint16_t rend;      ///< register end
594    AsmRegField regField;   ///< place in instruction
595    cxbyte rwFlags;  ///< 1 - read, 2 - write
596    cxbyte align;   ///< register alignment
597};
598
599/// internal structure for regusage
600struct AsmRegUsageInt
601{
602    AsmRegField regField;   ///< place in instruction
603    cxbyte rwFlags;     ///< 1 - read, 2 - write, other flags
604};
605
606/// internal structure for regusage
607struct AsmRegUsage2Int
608{
609    uint16_t rstart;    ///< register start
610    uint16_t rend;      ///< register end
611    cxbyte rwFlags;     ///< rw flags and others
612};
613
614/// code flow type
615enum AsmCodeFlowType
616{
617    JUMP = 0,   ///< jump
618    CJUMP,   ///< conditional jump
619    CALL,   ///< call of procedure
620    RETURN, ///< return from procedure
621    START,  ///< code start
622    END     ///< code end
623};
624
625/// code flow entry
626struct AsmCodeFlowEntry
627{
628    size_t offset;      ///< offset where is this entry
629    size_t target;      ///< target jump addreses
630    AsmCodeFlowType type;   ///< type of code flow entry
631};
632
633/// assembler macro map
634typedef std::unordered_map<CString, RefPtr<const AsmMacro> > AsmMacroMap;
635
636struct AsmScope;
637
638/// type definition of scope's map
639typedef std::unordered_map<CString, AsmScope*> AsmScopeMap;
640
641/// assembler scope for symbol, macros, regvars
642struct AsmScope
643{
644    AsmScope* parent;   ///< parent scope
645    AsmSymbolMap symbolMap; ///< symbol map
646    AsmRegVarMap regVarMap; ///< regvar map
647    AsmScopeMap scopeMap;   ///< scope map
648    bool temporary; ///< true if temporary
649    std::list<AsmScope*> usedScopes;    ///< list of used scope in this scope
650   
651    /// set of used scopes in this scope
652    std::unordered_map<AsmScope*, std::list<AsmScope*>::iterator> usedScopesSet;
653   
654    /// constructor
655    AsmScope(AsmScope* _parent, const AsmSymbolMap& _symbolMap,
656                     bool _temporary = false)
657            : parent(_parent), symbolMap(_symbolMap), temporary(_temporary)
658    { }
659    /// constructor
660    AsmScope(AsmScope* _parent = nullptr, bool _temporary= false)
661            : parent(_parent), temporary(_temporary)
662    { }
663    /// destructor
664    ~AsmScope();
665   
666    /// start using scope in this scope
667    void startUsingScope(AsmScope* scope);
668    /// stop using scope in this scope
669    void stopUsingScope(AsmScope* scope);
670    /// remove all usings
671    void stopUsingScopes()
672    {
673        usedScopes.clear();
674        usedScopesSet.clear();
675    }
676    /// delete symbols recursively
677    void deleteSymbolsRecursively();
678};
679
680class ISAUsageHandler;
681
682/// assembler section
683struct AsmSection
684{
685    const char* name;       ///< section name
686    cxuint kernelId;    ///< kernel id (optional)
687    AsmSectionType type;        ///< type of section
688    Flags flags;   ///< section flags
689    uint64_t alignment; ///< section alignment
690    uint64_t size;  ///< section size
691    cxuint relSpace;    ///< relative space where is section
692    uint64_t relAddress; ///< relative address
693    std::vector<cxbyte> content;    ///< content of section
694   
695    std::unique_ptr<ISAUsageHandler> usageHandler;  ///< usage handler
696    std::vector<AsmCodeFlowEntry> codeFlow;  ///< code flow info
697   
698    /// constructor
699    AsmSection();
700    /// constructor
701    AsmSection(const char* _name, cxuint _kernelId, AsmSectionType _type, Flags _flags,
702               uint64_t _alignment, uint64_t _size = 0, cxuint _relSpace = UINT_MAX,
703               uint64_t _relAddress = UINT64_MAX)
704            : name(_name), kernelId(_kernelId), type(_type), flags(_flags),
705              alignment(_alignment), size(_size), relSpace(_relSpace),
706              relAddress(_relAddress)
707    { }
708   
709    /// copy constructor
710    AsmSection(const AsmSection& section);
711    /// copy assignment
712    AsmSection& operator=(const AsmSection& section);
713   
714    /// add code flow entry to this section
715    void addCodeFlowEntry(const AsmCodeFlowEntry& entry)
716    { codeFlow.push_back(entry); }
717   
718    /// get section's size
719    size_t getSize() const
720    { return ((flags&ASMSECT_WRITEABLE) != 0) ? content.size() : size; }
721};
722
723/// kernel entry structure
724struct AsmKernel
725{
726    const char* name;   ///< name of kernel
727    AsmSourcePos sourcePos; ///< source position of definition
728    std::vector<std::pair<size_t, size_t> > codeRegions; ///< code regions
729   
730    /// open kernel region in code
731    void openCodeRegion(size_t offset);
732    /// close kernel region in code
733    void closeCodeRegion(size_t offset);
734};
735
736};
737
738namespace std
739{
740
741/// std::hash specialization for CLRX CString
742template<>
743struct hash<CLRX::AsmSingleVReg>
744{
745    typedef CLRX::AsmSingleVReg argument_type;    ///< argument type
746    typedef std::size_t result_type;    ///< result type
747   
748    /// a calling operator
749    size_t operator()(const CLRX::AsmSingleVReg& r1) const
750    {
751        std::hash<const CLRX::AsmRegVar*> h1;
752        std::hash<uint16_t> h2;
753        return h1(r1.regVar) ^ (h2(r1.index)<<1);
754    }
755};
756
757}
758
759#endif
Note: See TracBrowser for help on using the repository browser.