source: CLRX/CLRadeonExtender/trunk/amdasm/AsmInternals.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: 13.6 KB
Line 
1/*
2 *  CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3 *  Copyright (C) 2014-2018 Mateusz Szpakowski
4 *
5 *  This library is free software; you can redistribute it and/or
6 *  modify it under the terms of the GNU Lesser General Public
7 *  License as published by the Free Software Foundation; either
8 *  version 2.1 of the License, or (at your option) any later version.
9 *
10 *  This library is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 *  Lesser General Public License for more details.
14 *
15 *  You should have received a copy of the GNU Lesser General Public
16 *  License along with this library; if not, write to the Free Software
17 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20#ifndef __CLRX_ASMINTERNALS_H__
21#define __CLRX_ASMINTERNALS_H__
22
23#include <CLRX/Config.h>
24#include <cstdint>
25#include <string>
26#include <unordered_set>
27#include <utility>
28#include <memory>
29#include <CLRX/utils/Utilities.h>
30#include <CLRX/amdasm/Assembler.h>
31#include "GCNInternals.h"
32
33namespace CLRX
34{
35
36static inline void skipCharAndSpacesToEnd(const char*& string, const char* end)
37{
38    ++string;
39    while (string!=end && *string == ' ') string++;
40}
41
42static inline void skipSpacesToEnd(const char*& string, const char* end)
43{ while (string!=end && *string == ' ') string++; }
44
45// extract sybol name or argument name or other identifier
46CString extractSymName(const char*& string, const char* end, bool localLabelSymName);
47
48CString extractScopedSymName(const char*& string, const char* end,
49           bool localLabelSymName = false);
50
51// extract label name from string (must be at start)
52// (but not symbol of backward of forward labels)
53static inline CString extractLabelName(const char*& string, const char* end)
54{
55    if (string != end && isDigit(*string))
56    {
57        const char* startString = string;
58        while (string != end && isDigit(*string)) string++;
59        return CString(startString, string);
60    }
61    return extractScopedSymName(string, end, false);
62}
63
64void skipSpacesAndLabels(const char*& linePtr, const char* end);
65
66class Assembler;
67
68enum class IfIntComp
69{
70    EQUAL = 0,
71    NOT_EQUAL,
72    LESS,
73    LESS_EQUAL,
74    GREATER,
75    GREATER_EQUAL
76};
77
78struct CLRX_INTERNAL AsmParseUtils
79{
80    static bool checkGarbagesAtEnd(Assembler& asmr, const char* linePtr);
81    /* parsing helpers */
82    /* get absolute value arg resolved at this time.
83       if empty expression value is not set */
84    static bool getAbsoluteValueArg(Assembler& asmr, uint64_t& value, const char*& linePtr,
85                    bool requiredExpr = false);
86   
87    static bool getAnyValueArg(Assembler& asmr, uint64_t& value, cxuint& sectionId,
88                    const char*& linePtr);
89   
90    static bool getJumpValueArg(Assembler& asmr, uint64_t& value,
91            std::unique_ptr<AsmExpression>& outTargetExpr, const char*& linePtr);
92    // get name (not symbol name)
93    static bool getNameArg(Assembler& asmr, CString& outStr, const char*& linePtr,
94               const char* objName, bool requiredArg = true,
95               bool skipCommaAtError = false);
96   
97    // get name (not symbol name)
98    static bool getNameArg(Assembler& asmr, size_t maxOutStrSize, char* outStr,
99               const char*& linePtr, const char* objName, bool requiredArg = true,
100               bool ignoreLongerName = false, bool skipCommaAtError = false);
101   
102    // get name (not symbol name), skipping spaces at error by default
103    static bool getNameArgS(Assembler& asmr, CString& outStr, const char*& linePtr,
104               const char* objName, bool requiredArg = true)
105    { return getNameArg(asmr, outStr, linePtr, objName, requiredArg, true); }
106   
107    // get name (not symbol name), skipping spaces at error by default
108    static bool getNameArgS(Assembler& asmr, size_t maxOutStrSize, char* outStr,
109               const char*& linePtr, const char* objName, bool requiredArg = true,
110               bool ignoreLongerName = false)
111    {
112        return getNameArg(asmr, maxOutStrSize, outStr, linePtr, objName,
113                    requiredArg, ignoreLongerName, true);
114    }
115   
116    /* IMPORTANT NOTE: table must be sorted by name!!!
117     * the longest name in table must shorter than 72 */
118    static bool getEnumeration(Assembler& asmr, const char*& linePtr, const char* objName,
119          size_t tableSize, const std::pair<const char*, cxuint>* table, cxuint& value,
120          const char* prefix = nullptr);
121   
122    // skip comma
123    // errorWhenNoEnd - print error if not end and not comma
124    static bool skipComma(Assembler& asmr, bool& haveComma, const char*& linePtr,
125                    bool errorWhenNoEnd = true);
126    // skip required comma, (returns false if not found comma)
127    static bool skipRequiredComma(Assembler& asmr, const char*& linePtr);
128   
129    // skip comma for multiple argument pseudo-ops
130    static bool skipCommaForMultipleArgs(Assembler& asmr, const char*& linePtr);
131   
132    static bool parseDimensions(Assembler& asmr, const char*& linePtr, cxuint& dimMask);
133   
134    static void setSymbolValue(Assembler& asmr, const char* linePtr,
135                    uint64_t value, cxuint sectionId);
136};
137
138enum class AsmPredefined: cxbyte
139{
140    ARCH,
141    BIT64,
142    FORMAT,
143    GPU,
144    VERSION
145};
146
147struct CLRX_INTERNAL AsmPseudoOps: AsmParseUtils
148{
149    /*
150     * pseudo-ops logic
151     */
152    // set bitnesss
153    static void setBitness(Assembler& asmr, const char* linePtr, bool _64Bit);
154   
155    static bool parseFormat(Assembler& asmr, const char*& linePtr, BinaryFormat& format);
156    // set output format
157    static void setOutFormat(Assembler& asmr, const char* linePtr);
158    // set GPU architecture type
159    static void setGPUDevice(Assembler& asmr, const char* linePtr);
160    // set GPU architecture
161    static void setGPUArchitecture(Assembler& asmr, const char* linePtr);
162   
163    // change kernel
164    static void goToKernel(Assembler& asmr, const char* pseudoOpPlace,
165                   const char* linePtr);
166    // change section
167    static void goToSection(Assembler& asmr, const char* pseudoOpPlace,
168                   const char* linePtr, bool isPseudoOp = false);
169   
170    static void goToMain(Assembler& asmr, const char* pseudoOpPlace,
171                   const char* linePtr);
172   
173    /// include file
174    static void includeFile(Assembler& asmr, const char* pseudoOpPlace,
175                            const char* linePtr);
176    // include binary file
177    static void includeBinFile(Assembler& asmr, const char* pseudoOpPlace,
178                       const char* linePtr);
179   
180    // fail
181    static void doFail(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
182    // .error
183    static void doError(Assembler& asmr, const char* pseudoOpPlace,
184                           const char* linePtr);
185    // .warning
186    static void doWarning(Assembler& asmr, const char* pseudoOpPlace,
187                     const char* linePtr);
188   
189    // .byte, .short, .int, .word, .long, .quad
190    template<typename T>
191    static void putIntegers(Assembler& asmr, const char* pseudoOpPlace,
192                    const char* linePtr);
193   
194    // .half, .float, .double
195    template<typename UIntType>
196    static void putFloats(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
197   
198    /// .string, ascii
199    static void putStrings(Assembler& asmr, const char* pseudoOpPlace,
200                   const char* linePtr, bool addZero = false);
201    // .string16, .string32, .string64
202    template<typename T>
203    static void putStringsToInts(Assembler& asmr, const char* pseudoOpPlace,
204                   const char* linePtr);
205   
206    /// .octa
207    static void putUInt128s(Assembler& asmr, const char* pseudoOpPlace,
208                        const char* linePtr);
209   
210    /// .set, .equ, .eqv, .equiv
211    static void setSymbol(Assembler& asmr, const char* linePtr, bool reassign = true,
212                bool baseExpr = false);
213   
214    // .global, .local, .extern
215    static void setSymbolBind(Assembler& asmr, const char* linePtr, cxbyte elfInfo);
216   
217    static void setSymbolSize(Assembler& asmr, const char* linePtr);
218   
219    // ignore .extern
220    static void ignoreExtern(Assembler& asmr, const char* linePtr);
221   
222    // .fill
223    static void doFill(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
224               bool _64bit = false);
225    // .skip
226    static void doSkip(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
227   
228    // .align
229    static void doAlign(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
230                    bool powerOf2 = false);
231   
232    template<typename Word>
233    static void doAlignWord(Assembler& asmr, const char* pseudoOpPlace,
234                            const char* linePtr);
235    // .org
236    static void doOrganize(Assembler& asmr, const char* linePtr);
237   
238    // .print
239    static void doPrint(Assembler& asmr, const char* linePtr);
240   
241    // .ifXX for integers
242    static void doIfInt(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
243                IfIntComp compType, bool elseIfClause);
244    // .ifdef
245    static void doIfDef(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
246                bool negation, bool elseIfClause);
247   
248    // .ifb
249    static void doIfBlank(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
250                bool negation, bool elseIfClause);
251   
252    // .if64 and .if32
253    static void doIf64Bit(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
254                bool negation, bool elseIfClause);
255    // .ifarch
256    static void doIfArch(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
257                bool negation, bool elseIfClause);
258    // .ifgpu
259    static void doIfGpu(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
260                bool negation, bool elseIfClause);
261    // .iffmt
262    static void doIfFmt(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
263                bool negation, bool elseIfClause);
264    /// .ifc
265    static void doIfCmpStr(Assembler& asmr, const char* pseudoOpPlace,
266               const char* linePtr, bool negation, bool elseIfClause);
267    /// ifeqs, ifnes
268    static void doIfStrEqual(Assembler& asmr, const char* pseudoOpPlace,
269                     const char* linePtr, bool negation, bool elseIfClause);
270    // else
271    static void doElse(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
272    // endif
273    static void endIf(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
274    /// start repetition content
275    static void doRepeat(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
276    /// end repetition content
277    static void endRepeat(Assembler& asmr, const char* pseudoOpPlace,
278                          const char* linePtr);
279    /// start macro definition
280    static void doMacro(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
281    /// ends macro definition
282    static void endMacro(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
283    // immediately exit from macro
284    static void exitMacro(Assembler& asmr, const char* pseudoOpPlace,
285                      const char* linePtr);
286    // purge macro
287    static void purgeMacro(Assembler& asmr, const char* linePtr);
288    // do IRP
289    static void doIRP(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
290                      bool perChar = false);
291    // do 'for'
292    static void doFor(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
293    // do 'while'
294    static void doWhile(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
295    // do open scope (.scope)
296    static void openScope(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
297    // do close scope (.ends or .endscope)
298    static void closeScope(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
299    // start using scope (.using)
300    static void startUsing(Assembler& asmr, const char* linePtr);
301    // stop using scope (.unusing)
302    static void stopUsing(Assembler& asmr, const char* linePtr);
303    // .usereg ?
304    static void doUseReg(Assembler& asmr, const char* linePtr);
305    // .undef
306    static void undefSymbol(Assembler& asmr, const char* linePtr);
307    // .regvar
308    static void defRegVar(Assembler& asmr, const char* linePtr);
309    // .cf_ (code flow pseudo-ops)
310    static void addCodeFlowEntries(Assembler& asmr, const char* pseudoOpPlace,
311                     const char* linePtr, AsmCodeFlowType type);
312   
313    static void setAbsoluteOffset(Assembler& asmr, const char* linePtr);
314   
315    static void getPredefinedValue(Assembler& asmr, const char* linePtr,
316                        AsmPredefined predefined);
317   
318    // enumerate
319    static void doEnum(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
320   
321    static void ignoreString(Assembler& asmr, const char* linePtr);
322   
323    static bool checkPseudoOpName(const CString& string);
324};
325
326// macro helper to handle printing error
327
328#define PSEUDOOP_RETURN_BY_ERROR(STRING) \
329    { \
330        asmr.printError(pseudoOpPlace, STRING); \
331        return; \
332    }
333
334#define ASM_RETURN_BY_ERROR(PLACE, STRING) \
335    { \
336        asmr.printError(PLACE, STRING); \
337        return; \
338    }
339
340#define ASM_FAIL_BY_ERROR(PLACE, STRING) \
341    { \
342        asmr.printError(PLACE, STRING); \
343        return false; \
344    }
345
346#define ASM_NOTGOOD_BY_ERROR(PLACE, STRING) \
347    { \
348        asmr.printError(PLACE, STRING); \
349        good = false; \
350    }
351
352#define ASM_NOTGOOD_BY_ERROR1(GOOD, PLACE, STRING) \
353    { \
354        asmr.printError(PLACE, STRING); \
355        GOOD = false; \
356    }
357
358extern CLRX_INTERNAL cxbyte cstrtobyte(const char*& str, const char* end);
359
360extern const cxbyte tokenCharTable[96] CLRX_INTERNAL;
361
362};
363
364#endif
Note: See TracBrowser for help on using the repository browser.