source: CLRX/CLRadeonExtender/trunk/amdasm/AsmInternals.h @ 3632

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

CLRadeonExtender: Asm: Tentative implementation of '.while' pseudo-op (repetition).

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    static bool skipComma(Assembler& asmr, bool& haveComma, const char*& linePtr);
124    // skip required comma, (returns false if not found comma)
125    static bool skipRequiredComma(Assembler& asmr, const char*& linePtr);
126   
127    // skip comma for multiple argument pseudo-ops
128    static bool skipCommaForMultipleArgs(Assembler& asmr, const char*& linePtr);
129   
130    static bool parseDimensions(Assembler& asmr, const char*& linePtr, cxuint& dimMask);
131   
132    static void setSymbolValue(Assembler& asmr, const char* linePtr,
133                    uint64_t value, cxuint sectionId);
134};
135
136enum class AsmPredefined: cxbyte
137{
138    ARCH,
139    BIT64,
140    FORMAT,
141    GPU,
142    VERSION
143};
144
145struct CLRX_INTERNAL AsmPseudoOps: AsmParseUtils
146{
147    /*
148     * pseudo-ops logic
149     */
150    // set bitnesss
151    static void setBitness(Assembler& asmr, const char* linePtr, bool _64Bit);
152   
153    static bool parseFormat(Assembler& asmr, const char*& linePtr, BinaryFormat& format);
154    // set output format
155    static void setOutFormat(Assembler& asmr, const char* linePtr);
156    // set GPU architecture type
157    static void setGPUDevice(Assembler& asmr, const char* linePtr);
158    // set GPU architecture
159    static void setGPUArchitecture(Assembler& asmr, const char* linePtr);
160   
161    // change kernel
162    static void goToKernel(Assembler& asmr, const char* pseudoOpPlace,
163                   const char* linePtr);
164    // change section
165    static void goToSection(Assembler& asmr, const char* pseudoOpPlace,
166                   const char* linePtr, bool isPseudoOp = false);
167   
168    static void goToMain(Assembler& asmr, const char* pseudoOpPlace,
169                   const char* linePtr);
170   
171    /// include file
172    static void includeFile(Assembler& asmr, const char* pseudoOpPlace,
173                            const char* linePtr);
174    // include binary file
175    static void includeBinFile(Assembler& asmr, const char* pseudoOpPlace,
176                       const char* linePtr);
177   
178    // fail
179    static void doFail(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
180    // .error
181    static void doError(Assembler& asmr, const char* pseudoOpPlace,
182                           const char* linePtr);
183    // .warning
184    static void doWarning(Assembler& asmr, const char* pseudoOpPlace,
185                     const char* linePtr);
186   
187    // .byte, .short, .int, .word, .long, .quad
188    template<typename T>
189    static void putIntegers(Assembler& asmr, const char* pseudoOpPlace,
190                    const char* linePtr);
191   
192    // .half, .float, .double
193    template<typename UIntType>
194    static void putFloats(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
195   
196    /// .string, ascii
197    static void putStrings(Assembler& asmr, const char* pseudoOpPlace,
198                   const char* linePtr, bool addZero = false);
199    // .string16, .string32, .string64
200    template<typename T>
201    static void putStringsToInts(Assembler& asmr, const char* pseudoOpPlace,
202                   const char* linePtr);
203   
204    /// .octa
205    static void putUInt128s(Assembler& asmr, const char* pseudoOpPlace,
206                        const char* linePtr);
207   
208    /// .set, .equ, .eqv, .equiv
209    static void setSymbol(Assembler& asmr, const char* linePtr, bool reassign = true,
210                bool baseExpr = false);
211   
212    // .global, .local, .extern
213    static void setSymbolBind(Assembler& asmr, const char* linePtr, cxbyte elfInfo);
214   
215    static void setSymbolSize(Assembler& asmr, const char* linePtr);
216   
217    // ignore .extern
218    static void ignoreExtern(Assembler& asmr, const char* linePtr);
219   
220    // .fill
221    static void doFill(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
222               bool _64bit = false);
223    // .skip
224    static void doSkip(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
225   
226    // .align
227    static void doAlign(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
228                    bool powerOf2 = false);
229   
230    template<typename Word>
231    static void doAlignWord(Assembler& asmr, const char* pseudoOpPlace,
232                            const char* linePtr);
233    // .org
234    static void doOrganize(Assembler& asmr, const char* linePtr);
235   
236    // .print
237    static void doPrint(Assembler& asmr, const char* linePtr);
238   
239    // .ifXX for integers
240    static void doIfInt(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
241                IfIntComp compType, bool elseIfClause);
242    // .ifdef
243    static void doIfDef(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
244                bool negation, bool elseIfClause);
245   
246    // .ifb
247    static void doIfBlank(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
248                bool negation, bool elseIfClause);
249   
250    // .if64 and .if32
251    static void doIf64Bit(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
252                bool negation, bool elseIfClause);
253    // .ifarch
254    static void doIfArch(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
255                bool negation, bool elseIfClause);
256    // .ifgpu
257    static void doIfGpu(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
258                bool negation, bool elseIfClause);
259    // .iffmt
260    static void doIfFmt(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
261                bool negation, bool elseIfClause);
262    /// .ifc
263    static void doIfCmpStr(Assembler& asmr, const char* pseudoOpPlace,
264               const char* linePtr, bool negation, bool elseIfClause);
265    /// ifeqs, ifnes
266    static void doIfStrEqual(Assembler& asmr, const char* pseudoOpPlace,
267                     const char* linePtr, bool negation, bool elseIfClause);
268    // else
269    static void doElse(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
270    // endif
271    static void endIf(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
272    /// start repetition content
273    static void doRepeat(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
274    /// end repetition content
275    static void endRepeat(Assembler& asmr, const char* pseudoOpPlace,
276                          const char* linePtr);
277    /// start macro definition
278    static void doMacro(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
279    /// ends macro definition
280    static void endMacro(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
281    // immediately exit from macro
282    static void exitMacro(Assembler& asmr, const char* pseudoOpPlace,
283                      const char* linePtr);
284    // purge macro
285    static void purgeMacro(Assembler& asmr, const char* linePtr);
286    // do IRP
287    static void doIRP(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
288                      bool perChar = false);
289    // do 'for'
290    static void doFor(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
291    // do 'while'
292    static void doWhile(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
293    // do open scope (.scope)
294    static void openScope(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
295    // do close scope (.ends or .endscope)
296    static void closeScope(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
297    // start using scope (.using)
298    static void startUsing(Assembler& asmr, const char* pseudoOpPlace,
299                        const char* linePtr);
300    // stop using scope (.unusing)
301    static void stopUsing(Assembler& asmr, const char* pseudoOpPlace,
302                        const char* linePtr);
303    // .usereg ?
304    static void doUseReg(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
305    // .undef
306    static void undefSymbol(Assembler& asmr, const char* linePtr);
307    // .regvar
308    static void defRegVar(Assembler& asmr, const char* pseudoOpPlace, 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    static void ignoreString(Assembler& asmr, const char* linePtr);
319   
320    static bool checkPseudoOpName(const CString& string);
321};
322
323// macro helper to handle printing error
324
325#define PSEUDOOP_RETURN_BY_ERROR(STRING) \
326    { \
327        asmr.printError(pseudoOpPlace, STRING); \
328        return; \
329    }
330
331#define ASM_RETURN_BY_ERROR(PLACE, STRING) \
332    { \
333        asmr.printError(PLACE, STRING); \
334        return; \
335    }
336
337#define ASM_FAIL_BY_ERROR(PLACE, STRING) \
338    { \
339        asmr.printError(PLACE, STRING); \
340        return false; \
341    }
342
343#define ASM_NOTGOOD_BY_ERROR(PLACE, STRING) \
344    { \
345        asmr.printError(PLACE, STRING); \
346        good = false; \
347    }
348
349#define ASM_NOTGOOD_BY_ERROR1(GOOD, PLACE, STRING) \
350    { \
351        asmr.printError(PLACE, STRING); \
352        GOOD = false; \
353    }
354
355extern CLRX_INTERNAL cxbyte cstrtobyte(const char*& str, const char* end);
356
357extern const cxbyte tokenCharTable[96] CLRX_INTERNAL;
358
359};
360
361#endif
Note: See TracBrowser for help on using the repository browser.