source: CLRX/CLRadeonExtender/trunk/amdasm/GCNAsmInternals.h @ 3095

Last change on this file since 3095 was 3095, checked in by matszpk, 2 years ago

CLRadeonExtender: GCNAsm: update. remove bitfields from VOPExtraModifiers. Add negMod and absMod to VOPExtraModifiers.

File size: 14.9 KB
Line 
1/*
2 *  CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3 *  Copyright (C) 2014-2017 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_GCNASMINTERNALS_H__
21#define __CLRX_GCNASMINTERNALS_H__
22
23#include <CLRX/Config.h>
24#include <cstdint>
25#include <string>
26#include <memory>
27#include <utility>
28#include <CLRX/utils/Utilities.h>
29#include <CLRX/amdasm/Assembler.h>
30#include "AsmInternals.h"
31#include "GCNInternals.h"
32
33namespace CLRX
34{
35
36enum : Flags {
37    INSTROP_SREGS = 1,
38    INSTROP_SSOURCE = 2,
39    INSTROP_VREGS = 4,
40    INSTROP_LDS = 8,
41    INSTROP_VOP3MODS = 0x10,
42    // used internally by parseGCNOperand to continuing parsing with modifiers
43    INSTROP_PARSEWITHNEG = 0x20,
44    INSTROP_VOP3NEG = 0x40,
45   
46    INSTROP_ONLYINLINECONSTS = 0x80, /// accepts only inline constants
47    INSTROP_NOLITERALERROR = 0x100, /// accepts only inline constants
48    INSTROP_NOLITERALERRORMUBUF = 0x200, /// accepts only inline constants
49   
50    INSTROP_TYPE_MASK = 0x3000,
51    INSTROP_INT = 0x000,    // integer literal
52    INSTROP_FLOAT = 0x1000, // floating point literal
53    INSTROP_F16 = 0x2000,   // half floating point literal
54    INSTROP_V64BIT = 0x3000, // 64-bit value (specific for vector instructions)
55    INSTROP_UNALIGNED = 0x8000, // not aligned, use by parseRegisterRange
56   
57    INSTROP_READ = 0x10000,
58    INSTROP_WRITE = 0x20000,
59    INSTROP_ACCESS_MASK = 0x30000,
60   
61    // for parseSRregRange/parseVRegRange
62    INSTROP_SYMREGRANGE = 1
63};
64
65enum: cxbyte {
66    VOPOP_ABS = 1,
67    VOPOP_NEG = 2,
68    VOPOP_SEXT = 4
69};
70
71enum: cxbyte {
72    VOP3_MUL2 = 1,
73    VOP3_MUL4 = 2,
74    VOP3_DIV2 = 3,
75    VOP3_CLAMP = 16,
76    VOP3_VOP3 = 32,
77    VOP3_BOUNDCTRL = 64
78};
79
80struct CLRX_INTERNAL RegRange
81{
82    uint16_t start, end;
83    const AsmRegVar* regVar;
84   
85    RegRange(): start(0), end(0), regVar(nullptr)
86    { }
87    template<typename U1, typename U2>
88    RegRange(U1 t1, U2 t2 = 0, const AsmRegVar* rv = nullptr)
89            : start(t1), end(t2), regVar(rv)
90    { }
91   
92    bool operator!() const
93    { return start==0 && end==0; }
94    operator bool() const
95    { return start!=0 || end!=0; }
96   
97    uint16_t bstart() const
98    { return (regVar==nullptr) ? start : 0; }
99   
100    bool isRegVar() const
101    { return regVar!=nullptr; }
102   
103    bool isVal(uint16_t reg) const
104    { return (regVar==nullptr && start==reg); }
105   
106    bool isSGPR() const
107    { return (regVar==nullptr && start<108) || (regVar!=nullptr &&
108                regVar->type==REGTYPE_SGPR); }
109    bool isNonVGPR() const
110    { return (regVar==nullptr && start<256) || (regVar!=nullptr &&
111                regVar->type==REGTYPE_SGPR); }
112    bool isVGPR() const
113    { return (regVar==nullptr && start>=256) || (regVar!=nullptr &&
114                regVar->type==REGTYPE_VGPR); }
115};
116
117struct CLRX_INTERNAL GCNOperand
118{
119    RegRange range;
120    uint32_t value;
121    cxbyte vopMods;
122   
123    bool operator!() const
124    { return !range; }
125    operator bool() const
126    { return range; }
127};
128
129struct CLRX_INTERNAL VOPExtraModifiers
130{   // TODO: check that for MSVC 2015
131    cxbyte dstSel;
132    cxbyte dstUnused;
133    cxbyte src0Sel;
134    cxbyte src1Sel;
135    cxbyte bankMask;
136    cxbyte rowMask;
137    uint16_t dppCtrl;
138    bool needSDWA;
139    bool needDPP;
140    cxbyte absMod;
141    cxbyte negMod;
142};
143
144enum class GCNEncSize
145{
146    UNKNOWN,
147    BIT32,
148    BIT64
149};
150
151enum class GCNVOPEnc
152{
153    NORMAL,
154    DPP,
155    SDWA
156};
157
158struct CLRX_INTERNAL GCNAsmUtils: AsmParseUtils
159{
160    static bool printRegisterRangeExpected(Assembler& asmr, const char* linePtr,
161               const char* regPoolName, cxuint regsNum, bool required);
162   
163    static void printXRegistersRequired(Assembler& asmr, const char* linePtr,
164               const char* regPoolName, cxuint requiredRegsNum);
165   
166    static bool parseRegVarRange(Assembler& asmr, const char*& linePtr,
167                 RegRange& regPair, uint16_t arch, cxuint regsNum, AsmRegField regField,
168                 Flags flags, bool required = true);
169   
170    static bool parseSymRegRange(Assembler& asmr, const char*& linePtr, RegRange& regPair,
171                 uint16_t arch, cxuint regsNum, AsmRegField regField, Flags flags,
172                 bool required = true);
173    /* return true if no error */
174    static bool parseVRegRange(Assembler& asmr, const char*& linePtr, RegRange& regPair,
175                   cxuint regsNum, AsmRegField regField, bool required = true,
176                   Flags flags = INSTROP_SYMREGRANGE);
177    /* return true if no error */
178    static bool parseSRegRange(Assembler& asmr, const char*& linePtr, RegRange& regPair,
179                   uint16_t arch, cxuint regsNum, AsmRegField regField,
180                   bool required = true, Flags flags = INSTROP_SYMREGRANGE);
181   
182    // bits=UINT_MAX - no range checking
183    /* return true if no error */
184    static bool parseImmInt(Assembler& asmr, const char*& linePtr, uint32_t& value,
185            std::unique_ptr<AsmExpression>* outTargetExpr, cxuint bits = 0,
186            cxbyte signess = WS_BOTH);
187   
188    template<typename T>
189    static bool parseImm(Assembler& asmr, const char*& linePtr, T& value,
190            std::unique_ptr<AsmExpression>* outTargetExpr, cxuint bits = 0,
191            cxbyte signess = WS_BOTH)
192    {
193        uint32_t v32;
194        bool ret = parseImmInt(asmr, linePtr, v32, outTargetExpr,
195               (bits!=0?bits:(sizeof(T)<<3)), signess);
196        if ((outTargetExpr==nullptr || *outTargetExpr==nullptr) && ret)
197            value = v32;
198        return ret;
199    }
200   
201    static bool parseLiteralImm(Assembler& asmr, const char*& linePtr, uint32_t& value,
202            std::unique_ptr<AsmExpression>* outTargetExpr, Flags instropMask = 0);
203   
204    /* withSDWAOperands - number operand that will be handled by SDWA modifer parser,
205     * (includes destination at begin) */
206    static bool parseVOPModifiers(Assembler& asmr, const char*& linePtr, uint16_t arch,
207                       cxbyte& mods, VOPExtraModifiers* extraMods = nullptr,
208                       bool withClamp = true, cxuint withSDWAOperands = 3);
209   
210    static bool parseOperand(Assembler& asmr, const char*& linePtr, GCNOperand& operand,
211               std::unique_ptr<AsmExpression>* outTargetExpr, uint16_t arch,
212               cxuint regsNum, Flags instrOpMask, AsmRegField regField);
213   
214    template<typename T>
215    static bool parseModImm(Assembler& asmr, const char*& linePtr, T& value,
216            std::unique_ptr<AsmExpression>* outTargetExpr, const char* modName,
217            cxuint bits = 0, cxbyte signess = WS_BOTH)
218    {
219        if (outTargetExpr!=nullptr)
220            outTargetExpr->reset();
221        const char* end = asmr.line+asmr.lineSize;
222        skipSpacesToEnd(linePtr, end);
223        if (linePtr!=end && *linePtr==':')
224        {
225            skipCharAndSpacesToEnd(linePtr, end);
226            return parseImm(asmr, linePtr, value, outTargetExpr, bits, signess);
227        }
228        asmr.printError(linePtr, (std::string("Expected ':' before ")+modName).c_str());
229        return false;
230    }
231   
232    static bool parseModEnable(Assembler& asmr, const char*& linePtr, bool& value,
233            const char* modName)
234    {
235        cxbyte val = 0;
236        const char* end = asmr.line+asmr.lineSize;
237        skipSpacesToEnd(linePtr, end);
238        if (linePtr==end || *linePtr!=':')
239        {   // by default is enabled
240            value = true;
241            return true;
242        }
243       
244        bool ret = parseModImm(asmr, linePtr, val, nullptr, modName, 1, WS_UNSIGNED);
245        value = val!=0;
246        return ret;
247    }
248   
249    static bool parseVINTRP0P10P20(Assembler& asmr, const char*& linePtr, RegRange& reg);
250    static bool parseVINTRPAttr(Assembler& asmr, const char*& linePtr, cxbyte& attr);
251   
252    static bool getMUBUFFmtNameArg(Assembler& asmr, size_t maxOutStrSize, char* outStr,
253               const char*& linePtr, const char* objName);
254   
255    static bool checkGCNEncodingSize(Assembler& asmr, const char* insnPtr,
256                     GCNEncSize gcnEncSize, uint32_t wordsNum);
257    static bool checkGCNVOPEncoding(Assembler& asmr, const char* insnPtr,
258                     GCNVOPEnc vopEnc, const VOPExtraModifiers* modifiers);
259    static bool checkGCNVOPExtraModifers(Assembler& asmr, bool needImm, bool sextFlags,
260                 bool vop3, GCNVOPEnc gcnVOPEnc, const GCNOperand& src0Op,
261                 VOPExtraModifiers& extraMods, const char* instrPlace);
262   
263    static bool parseSOP2Encoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
264                      const char* instrPlace, const char* linePtr, uint16_t arch,
265                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
266                      GCNEncSize gcnEncSize);
267    static bool parseSOP1Encoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
268                      const char* instrPlace, const char* linePtr, uint16_t arch,
269                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
270                      GCNEncSize gcnEncSize);
271    static bool parseSOPKEncoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
272                      const char* instrPlace, const char* linePtr, uint16_t arch,
273                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
274                      GCNEncSize gcnEncSize);
275    static bool parseSOPCEncoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
276                      const char* instrPlace, const char* linePtr, uint16_t arch,
277                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
278                      GCNEncSize gcnEncSize);
279    static bool parseSOPPEncoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
280                      const char* instrPlace, const char* linePtr, uint16_t arch,
281                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
282                      GCNEncSize gcnEncSize);
283   
284    static bool parseSMRDEncoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
285                      const char* instrPlace, const char* linePtr, uint16_t arch,
286                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
287                      GCNEncSize gcnEncSize);
288    static bool parseSMEMEncoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
289                      const char* instrPlace, const char* linePtr, uint16_t arch,
290                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
291                      GCNEncSize gcnEncSize);
292   
293    static bool parseVOP2Encoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
294                      const char* instrPlace, const char* linePtr, uint16_t arch,
295                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
296                      GCNEncSize gcnEncSize, GCNVOPEnc gcnVOPEnc);
297    static bool parseVOP1Encoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
298                      const char* instrPlace, const char* linePtr, uint16_t arch,
299                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
300                      GCNEncSize gcnEncSize, GCNVOPEnc gcnVOPEnc);
301    static bool parseVOPCEncoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
302                      const char* instrPlace, const char* linePtr, uint16_t arch,
303                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
304                      GCNEncSize gcnEncSize, GCNVOPEnc gcnVOPEnc);
305    static bool parseVOP3Encoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
306                      const char* instrPlace, const char* linePtr, uint16_t arch,
307                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
308                      GCNEncSize gcnEncSize, GCNVOPEnc gcnVOPEnc);
309    static bool parseVINTRPEncoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
310                      const char* instrPlace, const char* linePtr, uint16_t arch,
311                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
312                      GCNEncSize gcnEncSize, GCNVOPEnc gcnVOPEnc);
313    static bool parseDSEncoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
314                      const char* instrPlace, const char* linePtr, uint16_t arch,
315                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
316                      GCNEncSize gcnEncSize);
317    static bool parseMUBUFEncoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
318                      const char* instrPlace, const char* linePtr, uint16_t arch,
319                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
320                      GCNEncSize gcnEncSize);
321    static bool parseMIMGEncoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
322                      const char* instrPlace, const char* linePtr, uint16_t arch,
323                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
324                      GCNEncSize gcnEncSize);
325    static bool parseEXPEncoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
326                      const char* instrPlace, const char* linePtr, uint16_t arch,
327                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
328                      GCNEncSize gcnEncSize);
329    static bool parseFLATEncoding(Assembler& asmr, const GCNAsmInstruction& gcnInsn,
330                      const char* instrPlace, const char* linePtr, uint16_t arch,
331                      std::vector<cxbyte>& output, GCNAssembler::Regs& gcnRegs,
332                      GCNEncSize gcnEncSize);
333};
334
335static inline bool isXRegRange(RegRange pair, cxuint regsNum = 1)
336{   // second==0 - we assume that first is inline constant, otherwise we check range
337    return (pair.end==0) || cxuint(pair.end-pair.start)==regsNum;
338}
339
340static inline void updateVGPRsNum(cxuint& vgprsNum, cxuint vgpr)
341{
342    vgprsNum = std::min(std::max(vgprsNum, vgpr+1), 256U);
343}
344
345static inline void updateSGPRsNum(cxuint& sgprsNum, cxuint sgpr, uint16_t arch)
346{
347    cxuint maxSGPRsNum = getGPUMaxRegsNumByArchMask(arch, REGTYPE_SGPR);
348    if (sgpr < maxSGPRsNum) /* sgpr=-1 does not change sgprsNum */
349        sgprsNum = std::min(std::max(sgprsNum, sgpr+1), maxSGPRsNum-2);
350}
351
352static inline void updateRegFlags(Flags& regFlags, cxuint reg, uint16_t arch)
353{
354    reg &= ~1;
355    if (reg==106)
356        regFlags |= GCN_VCC;
357    else if (((arch&ARCH_GCN_1_2_4)!=0 && reg==102) ||
358            ((arch&ARCH_GCN_1_2_4)==0 && reg==104))
359        regFlags |= GCN_FLAT;
360    else if ((arch&ARCH_GCN_1_2_4)!=0 && reg==104)
361        regFlags |= GCN_XNACK;
362}
363
364};
365
366#endif
Note: See TracBrowser for help on using the repository browser.