1*9880d681SAndroid Build Coastguard Worker //===-- AMDGPUAsmParser.cpp - Parse SI asm to MCInst instructions ---------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "AMDKernelCodeT.h"
11*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
12*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/AMDGPUTargetStreamer.h"
13*9880d681SAndroid Build Coastguard Worker #include "SIDefines.h"
14*9880d681SAndroid Build Coastguard Worker #include "Utils/AMDGPUBaseInfo.h"
15*9880d681SAndroid Build Coastguard Worker #include "Utils/AMDKernelCodeTUtils.h"
16*9880d681SAndroid Build Coastguard Worker #include "Utils/AMDGPUAsmUtils.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/APFloat.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallBitVector.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallString.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringSwitch.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Twine.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrInfo.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCParser/MCAsmLexer.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCParser/MCAsmParser.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCParser/MCTargetAsmParser.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbolELF.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ELF.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SourceMgr.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h"
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker using namespace llvm;
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker namespace {
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker struct OptionalOperand;
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker enum RegisterKind { IS_UNKNOWN, IS_VGPR, IS_SGPR, IS_TTMP, IS_SPECIAL };
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker class AMDGPUOperand : public MCParsedAsmOperand {
51*9880d681SAndroid Build Coastguard Worker enum KindTy {
52*9880d681SAndroid Build Coastguard Worker Token,
53*9880d681SAndroid Build Coastguard Worker Immediate,
54*9880d681SAndroid Build Coastguard Worker Register,
55*9880d681SAndroid Build Coastguard Worker Expression
56*9880d681SAndroid Build Coastguard Worker } Kind;
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker SMLoc StartLoc, EndLoc;
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker public:
AMDGPUOperand(enum KindTy K)61*9880d681SAndroid Build Coastguard Worker AMDGPUOperand(enum KindTy K) : MCParsedAsmOperand(), Kind(K) {}
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker typedef std::unique_ptr<AMDGPUOperand> Ptr;
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker struct Modifiers {
66*9880d681SAndroid Build Coastguard Worker bool Abs;
67*9880d681SAndroid Build Coastguard Worker bool Neg;
68*9880d681SAndroid Build Coastguard Worker bool Sext;
69*9880d681SAndroid Build Coastguard Worker
hasFPModifiers__anon66474c340111::AMDGPUOperand::Modifiers70*9880d681SAndroid Build Coastguard Worker bool hasFPModifiers() const { return Abs || Neg; }
hasIntModifiers__anon66474c340111::AMDGPUOperand::Modifiers71*9880d681SAndroid Build Coastguard Worker bool hasIntModifiers() const { return Sext; }
hasModifiers__anon66474c340111::AMDGPUOperand::Modifiers72*9880d681SAndroid Build Coastguard Worker bool hasModifiers() const { return hasFPModifiers() || hasIntModifiers(); }
73*9880d681SAndroid Build Coastguard Worker
getFPModifiersOperand__anon66474c340111::AMDGPUOperand::Modifiers74*9880d681SAndroid Build Coastguard Worker int64_t getFPModifiersOperand() const {
75*9880d681SAndroid Build Coastguard Worker int64_t Operand = 0;
76*9880d681SAndroid Build Coastguard Worker Operand |= Abs ? SISrcMods::ABS : 0;
77*9880d681SAndroid Build Coastguard Worker Operand |= Neg ? SISrcMods::NEG : 0;
78*9880d681SAndroid Build Coastguard Worker return Operand;
79*9880d681SAndroid Build Coastguard Worker }
80*9880d681SAndroid Build Coastguard Worker
getIntModifiersOperand__anon66474c340111::AMDGPUOperand::Modifiers81*9880d681SAndroid Build Coastguard Worker int64_t getIntModifiersOperand() const {
82*9880d681SAndroid Build Coastguard Worker int64_t Operand = 0;
83*9880d681SAndroid Build Coastguard Worker Operand |= Sext ? SISrcMods::SEXT : 0;
84*9880d681SAndroid Build Coastguard Worker return Operand;
85*9880d681SAndroid Build Coastguard Worker }
86*9880d681SAndroid Build Coastguard Worker
getModifiersOperand__anon66474c340111::AMDGPUOperand::Modifiers87*9880d681SAndroid Build Coastguard Worker int64_t getModifiersOperand() const {
88*9880d681SAndroid Build Coastguard Worker assert(!(hasFPModifiers() && hasIntModifiers())
89*9880d681SAndroid Build Coastguard Worker && "fp and int modifiers should not be used simultaneously");
90*9880d681SAndroid Build Coastguard Worker if (hasFPModifiers()) {
91*9880d681SAndroid Build Coastguard Worker return getFPModifiersOperand();
92*9880d681SAndroid Build Coastguard Worker } else if (hasIntModifiers()) {
93*9880d681SAndroid Build Coastguard Worker return getIntModifiersOperand();
94*9880d681SAndroid Build Coastguard Worker } else {
95*9880d681SAndroid Build Coastguard Worker return 0;
96*9880d681SAndroid Build Coastguard Worker }
97*9880d681SAndroid Build Coastguard Worker }
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker friend raw_ostream &operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
100*9880d681SAndroid Build Coastguard Worker };
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker enum ImmTy {
103*9880d681SAndroid Build Coastguard Worker ImmTyNone,
104*9880d681SAndroid Build Coastguard Worker ImmTyGDS,
105*9880d681SAndroid Build Coastguard Worker ImmTyOffen,
106*9880d681SAndroid Build Coastguard Worker ImmTyIdxen,
107*9880d681SAndroid Build Coastguard Worker ImmTyAddr64,
108*9880d681SAndroid Build Coastguard Worker ImmTyOffset,
109*9880d681SAndroid Build Coastguard Worker ImmTyOffset0,
110*9880d681SAndroid Build Coastguard Worker ImmTyOffset1,
111*9880d681SAndroid Build Coastguard Worker ImmTyGLC,
112*9880d681SAndroid Build Coastguard Worker ImmTySLC,
113*9880d681SAndroid Build Coastguard Worker ImmTyTFE,
114*9880d681SAndroid Build Coastguard Worker ImmTyClampSI,
115*9880d681SAndroid Build Coastguard Worker ImmTyOModSI,
116*9880d681SAndroid Build Coastguard Worker ImmTyDppCtrl,
117*9880d681SAndroid Build Coastguard Worker ImmTyDppRowMask,
118*9880d681SAndroid Build Coastguard Worker ImmTyDppBankMask,
119*9880d681SAndroid Build Coastguard Worker ImmTyDppBoundCtrl,
120*9880d681SAndroid Build Coastguard Worker ImmTySdwaDstSel,
121*9880d681SAndroid Build Coastguard Worker ImmTySdwaSrc0Sel,
122*9880d681SAndroid Build Coastguard Worker ImmTySdwaSrc1Sel,
123*9880d681SAndroid Build Coastguard Worker ImmTySdwaDstUnused,
124*9880d681SAndroid Build Coastguard Worker ImmTyDMask,
125*9880d681SAndroid Build Coastguard Worker ImmTyUNorm,
126*9880d681SAndroid Build Coastguard Worker ImmTyDA,
127*9880d681SAndroid Build Coastguard Worker ImmTyR128,
128*9880d681SAndroid Build Coastguard Worker ImmTyLWE,
129*9880d681SAndroid Build Coastguard Worker ImmTyHwreg,
130*9880d681SAndroid Build Coastguard Worker ImmTySendMsg,
131*9880d681SAndroid Build Coastguard Worker };
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker struct TokOp {
134*9880d681SAndroid Build Coastguard Worker const char *Data;
135*9880d681SAndroid Build Coastguard Worker unsigned Length;
136*9880d681SAndroid Build Coastguard Worker };
137*9880d681SAndroid Build Coastguard Worker
138*9880d681SAndroid Build Coastguard Worker struct ImmOp {
139*9880d681SAndroid Build Coastguard Worker bool IsFPImm;
140*9880d681SAndroid Build Coastguard Worker ImmTy Type;
141*9880d681SAndroid Build Coastguard Worker int64_t Val;
142*9880d681SAndroid Build Coastguard Worker Modifiers Mods;
143*9880d681SAndroid Build Coastguard Worker };
144*9880d681SAndroid Build Coastguard Worker
145*9880d681SAndroid Build Coastguard Worker struct RegOp {
146*9880d681SAndroid Build Coastguard Worker unsigned RegNo;
147*9880d681SAndroid Build Coastguard Worker Modifiers Mods;
148*9880d681SAndroid Build Coastguard Worker const MCRegisterInfo *TRI;
149*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI;
150*9880d681SAndroid Build Coastguard Worker bool IsForcedVOP3;
151*9880d681SAndroid Build Coastguard Worker };
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker union {
154*9880d681SAndroid Build Coastguard Worker TokOp Tok;
155*9880d681SAndroid Build Coastguard Worker ImmOp Imm;
156*9880d681SAndroid Build Coastguard Worker RegOp Reg;
157*9880d681SAndroid Build Coastguard Worker const MCExpr *Expr;
158*9880d681SAndroid Build Coastguard Worker };
159*9880d681SAndroid Build Coastguard Worker
isToken() const160*9880d681SAndroid Build Coastguard Worker bool isToken() const override {
161*9880d681SAndroid Build Coastguard Worker if (Kind == Token)
162*9880d681SAndroid Build Coastguard Worker return true;
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker if (Kind != Expression || !Expr)
165*9880d681SAndroid Build Coastguard Worker return false;
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Worker // When parsing operands, we can't always tell if something was meant to be
168*9880d681SAndroid Build Coastguard Worker // a token, like 'gds', or an expression that references a global variable.
169*9880d681SAndroid Build Coastguard Worker // In this case, we assume the string is an expression, and if we need to
170*9880d681SAndroid Build Coastguard Worker // interpret is a token, then we treat the symbol name as the token.
171*9880d681SAndroid Build Coastguard Worker return isa<MCSymbolRefExpr>(Expr);
172*9880d681SAndroid Build Coastguard Worker }
173*9880d681SAndroid Build Coastguard Worker
isImm() const174*9880d681SAndroid Build Coastguard Worker bool isImm() const override {
175*9880d681SAndroid Build Coastguard Worker return Kind == Immediate;
176*9880d681SAndroid Build Coastguard Worker }
177*9880d681SAndroid Build Coastguard Worker
isInlinableImm() const178*9880d681SAndroid Build Coastguard Worker bool isInlinableImm() const {
179*9880d681SAndroid Build Coastguard Worker if (!isImmTy(ImmTyNone)) {
180*9880d681SAndroid Build Coastguard Worker // Only plain immediates are inlinable (e.g. "clamp" attribute is not)
181*9880d681SAndroid Build Coastguard Worker return false;
182*9880d681SAndroid Build Coastguard Worker }
183*9880d681SAndroid Build Coastguard Worker // TODO: We should avoid using host float here. It would be better to
184*9880d681SAndroid Build Coastguard Worker // check the float bit values which is what a few other places do.
185*9880d681SAndroid Build Coastguard Worker // We've had bot failures before due to weird NaN support on mips hosts.
186*9880d681SAndroid Build Coastguard Worker const float F = BitsToFloat(Imm.Val);
187*9880d681SAndroid Build Coastguard Worker // TODO: Add 1/(2*pi) for VI
188*9880d681SAndroid Build Coastguard Worker return (Imm.Val <= 64 && Imm.Val >= -16) ||
189*9880d681SAndroid Build Coastguard Worker (F == 0.0 || F == 0.5 || F == -0.5 || F == 1.0 || F == -1.0 ||
190*9880d681SAndroid Build Coastguard Worker F == 2.0 || F == -2.0 || F == 4.0 || F == -4.0);
191*9880d681SAndroid Build Coastguard Worker }
192*9880d681SAndroid Build Coastguard Worker
isRegKind() const193*9880d681SAndroid Build Coastguard Worker bool isRegKind() const {
194*9880d681SAndroid Build Coastguard Worker return Kind == Register;
195*9880d681SAndroid Build Coastguard Worker }
196*9880d681SAndroid Build Coastguard Worker
isReg() const197*9880d681SAndroid Build Coastguard Worker bool isReg() const override {
198*9880d681SAndroid Build Coastguard Worker return isRegKind() && !Reg.Mods.hasModifiers();
199*9880d681SAndroid Build Coastguard Worker }
200*9880d681SAndroid Build Coastguard Worker
isRegOrImmWithInputMods() const201*9880d681SAndroid Build Coastguard Worker bool isRegOrImmWithInputMods() const {
202*9880d681SAndroid Build Coastguard Worker return isRegKind() || isInlinableImm();
203*9880d681SAndroid Build Coastguard Worker }
204*9880d681SAndroid Build Coastguard Worker
isImmTy(ImmTy ImmT) const205*9880d681SAndroid Build Coastguard Worker bool isImmTy(ImmTy ImmT) const {
206*9880d681SAndroid Build Coastguard Worker return isImm() && Imm.Type == ImmT;
207*9880d681SAndroid Build Coastguard Worker }
208*9880d681SAndroid Build Coastguard Worker
isImmModifier() const209*9880d681SAndroid Build Coastguard Worker bool isImmModifier() const {
210*9880d681SAndroid Build Coastguard Worker return isImm() && Imm.Type != ImmTyNone;
211*9880d681SAndroid Build Coastguard Worker }
212*9880d681SAndroid Build Coastguard Worker
isClampSI() const213*9880d681SAndroid Build Coastguard Worker bool isClampSI() const { return isImmTy(ImmTyClampSI); }
isOModSI() const214*9880d681SAndroid Build Coastguard Worker bool isOModSI() const { return isImmTy(ImmTyOModSI); }
isDMask() const215*9880d681SAndroid Build Coastguard Worker bool isDMask() const { return isImmTy(ImmTyDMask); }
isUNorm() const216*9880d681SAndroid Build Coastguard Worker bool isUNorm() const { return isImmTy(ImmTyUNorm); }
isDA() const217*9880d681SAndroid Build Coastguard Worker bool isDA() const { return isImmTy(ImmTyDA); }
isR128() const218*9880d681SAndroid Build Coastguard Worker bool isR128() const { return isImmTy(ImmTyUNorm); }
isLWE() const219*9880d681SAndroid Build Coastguard Worker bool isLWE() const { return isImmTy(ImmTyLWE); }
isOffen() const220*9880d681SAndroid Build Coastguard Worker bool isOffen() const { return isImmTy(ImmTyOffen); }
isIdxen() const221*9880d681SAndroid Build Coastguard Worker bool isIdxen() const { return isImmTy(ImmTyIdxen); }
isAddr64() const222*9880d681SAndroid Build Coastguard Worker bool isAddr64() const { return isImmTy(ImmTyAddr64); }
isOffset() const223*9880d681SAndroid Build Coastguard Worker bool isOffset() const { return isImmTy(ImmTyOffset) && isUInt<16>(getImm()); }
isOffset0() const224*9880d681SAndroid Build Coastguard Worker bool isOffset0() const { return isImmTy(ImmTyOffset0) && isUInt<16>(getImm()); }
isOffset1() const225*9880d681SAndroid Build Coastguard Worker bool isOffset1() const { return isImmTy(ImmTyOffset1) && isUInt<8>(getImm()); }
isGDS() const226*9880d681SAndroid Build Coastguard Worker bool isGDS() const { return isImmTy(ImmTyGDS); }
isGLC() const227*9880d681SAndroid Build Coastguard Worker bool isGLC() const { return isImmTy(ImmTyGLC); }
isSLC() const228*9880d681SAndroid Build Coastguard Worker bool isSLC() const { return isImmTy(ImmTySLC); }
isTFE() const229*9880d681SAndroid Build Coastguard Worker bool isTFE() const { return isImmTy(ImmTyTFE); }
isBankMask() const230*9880d681SAndroid Build Coastguard Worker bool isBankMask() const { return isImmTy(ImmTyDppBankMask); }
isRowMask() const231*9880d681SAndroid Build Coastguard Worker bool isRowMask() const { return isImmTy(ImmTyDppRowMask); }
isBoundCtrl() const232*9880d681SAndroid Build Coastguard Worker bool isBoundCtrl() const { return isImmTy(ImmTyDppBoundCtrl); }
isSDWADstSel() const233*9880d681SAndroid Build Coastguard Worker bool isSDWADstSel() const { return isImmTy(ImmTySdwaDstSel); }
isSDWASrc0Sel() const234*9880d681SAndroid Build Coastguard Worker bool isSDWASrc0Sel() const { return isImmTy(ImmTySdwaSrc0Sel); }
isSDWASrc1Sel() const235*9880d681SAndroid Build Coastguard Worker bool isSDWASrc1Sel() const { return isImmTy(ImmTySdwaSrc1Sel); }
isSDWADstUnused() const236*9880d681SAndroid Build Coastguard Worker bool isSDWADstUnused() const { return isImmTy(ImmTySdwaDstUnused); }
237*9880d681SAndroid Build Coastguard Worker
isMod() const238*9880d681SAndroid Build Coastguard Worker bool isMod() const {
239*9880d681SAndroid Build Coastguard Worker return isClampSI() || isOModSI();
240*9880d681SAndroid Build Coastguard Worker }
241*9880d681SAndroid Build Coastguard Worker
isRegOrImm() const242*9880d681SAndroid Build Coastguard Worker bool isRegOrImm() const {
243*9880d681SAndroid Build Coastguard Worker return isReg() || isImm();
244*9880d681SAndroid Build Coastguard Worker }
245*9880d681SAndroid Build Coastguard Worker
isRegClass(unsigned RCID) const246*9880d681SAndroid Build Coastguard Worker bool isRegClass(unsigned RCID) const {
247*9880d681SAndroid Build Coastguard Worker return isReg() && Reg.TRI->getRegClass(RCID).contains(getReg());
248*9880d681SAndroid Build Coastguard Worker }
249*9880d681SAndroid Build Coastguard Worker
isSCSrc32() const250*9880d681SAndroid Build Coastguard Worker bool isSCSrc32() const {
251*9880d681SAndroid Build Coastguard Worker return isInlinableImm() || isRegClass(AMDGPU::SReg_32RegClassID);
252*9880d681SAndroid Build Coastguard Worker }
253*9880d681SAndroid Build Coastguard Worker
isSCSrc64() const254*9880d681SAndroid Build Coastguard Worker bool isSCSrc64() const {
255*9880d681SAndroid Build Coastguard Worker return isInlinableImm() || isRegClass(AMDGPU::SReg_64RegClassID);
256*9880d681SAndroid Build Coastguard Worker }
257*9880d681SAndroid Build Coastguard Worker
isSSrc32() const258*9880d681SAndroid Build Coastguard Worker bool isSSrc32() const {
259*9880d681SAndroid Build Coastguard Worker return isImm() || isSCSrc32() || isExpr();
260*9880d681SAndroid Build Coastguard Worker }
261*9880d681SAndroid Build Coastguard Worker
isSSrc64() const262*9880d681SAndroid Build Coastguard Worker bool isSSrc64() const {
263*9880d681SAndroid Build Coastguard Worker // TODO: Find out how SALU supports extension of 32-bit literals to 64 bits.
264*9880d681SAndroid Build Coastguard Worker // See isVSrc64().
265*9880d681SAndroid Build Coastguard Worker return isImm() || isSCSrc64();
266*9880d681SAndroid Build Coastguard Worker }
267*9880d681SAndroid Build Coastguard Worker
isVCSrc32() const268*9880d681SAndroid Build Coastguard Worker bool isVCSrc32() const {
269*9880d681SAndroid Build Coastguard Worker return isInlinableImm() || isRegClass(AMDGPU::VS_32RegClassID);
270*9880d681SAndroid Build Coastguard Worker }
271*9880d681SAndroid Build Coastguard Worker
isVCSrc64() const272*9880d681SAndroid Build Coastguard Worker bool isVCSrc64() const {
273*9880d681SAndroid Build Coastguard Worker return isInlinableImm() || isRegClass(AMDGPU::VS_64RegClassID);
274*9880d681SAndroid Build Coastguard Worker }
275*9880d681SAndroid Build Coastguard Worker
isVSrc32() const276*9880d681SAndroid Build Coastguard Worker bool isVSrc32() const {
277*9880d681SAndroid Build Coastguard Worker return isImm() || isVCSrc32();
278*9880d681SAndroid Build Coastguard Worker }
279*9880d681SAndroid Build Coastguard Worker
isVSrc64() const280*9880d681SAndroid Build Coastguard Worker bool isVSrc64() const {
281*9880d681SAndroid Build Coastguard Worker // TODO: Check if the 64-bit value (coming from assembly source) can be
282*9880d681SAndroid Build Coastguard Worker // narrowed to 32 bits (in the instruction stream). That require knowledge
283*9880d681SAndroid Build Coastguard Worker // of instruction type (unsigned/signed, floating or "untyped"/B64),
284*9880d681SAndroid Build Coastguard Worker // see [AMD GCN3 ISA 6.3.1].
285*9880d681SAndroid Build Coastguard Worker // TODO: How 64-bit values are formed from 32-bit literals in _B64 insns?
286*9880d681SAndroid Build Coastguard Worker return isImm() || isVCSrc64();
287*9880d681SAndroid Build Coastguard Worker }
288*9880d681SAndroid Build Coastguard Worker
isMem() const289*9880d681SAndroid Build Coastguard Worker bool isMem() const override {
290*9880d681SAndroid Build Coastguard Worker return false;
291*9880d681SAndroid Build Coastguard Worker }
292*9880d681SAndroid Build Coastguard Worker
isExpr() const293*9880d681SAndroid Build Coastguard Worker bool isExpr() const {
294*9880d681SAndroid Build Coastguard Worker return Kind == Expression;
295*9880d681SAndroid Build Coastguard Worker }
296*9880d681SAndroid Build Coastguard Worker
isSoppBrTarget() const297*9880d681SAndroid Build Coastguard Worker bool isSoppBrTarget() const {
298*9880d681SAndroid Build Coastguard Worker return isExpr() || isImm();
299*9880d681SAndroid Build Coastguard Worker }
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker bool isSWaitCnt() const;
302*9880d681SAndroid Build Coastguard Worker bool isHwreg() const;
303*9880d681SAndroid Build Coastguard Worker bool isSendMsg() const;
304*9880d681SAndroid Build Coastguard Worker bool isSMRDOffset() const;
305*9880d681SAndroid Build Coastguard Worker bool isSMRDLiteralOffset() const;
306*9880d681SAndroid Build Coastguard Worker bool isDPPCtrl() const;
307*9880d681SAndroid Build Coastguard Worker
getExpressionAsToken() const308*9880d681SAndroid Build Coastguard Worker StringRef getExpressionAsToken() const {
309*9880d681SAndroid Build Coastguard Worker assert(isExpr());
310*9880d681SAndroid Build Coastguard Worker const MCSymbolRefExpr *S = cast<MCSymbolRefExpr>(Expr);
311*9880d681SAndroid Build Coastguard Worker return S->getSymbol().getName();
312*9880d681SAndroid Build Coastguard Worker }
313*9880d681SAndroid Build Coastguard Worker
314*9880d681SAndroid Build Coastguard Worker
getToken() const315*9880d681SAndroid Build Coastguard Worker StringRef getToken() const {
316*9880d681SAndroid Build Coastguard Worker assert(isToken());
317*9880d681SAndroid Build Coastguard Worker
318*9880d681SAndroid Build Coastguard Worker if (Kind == Expression)
319*9880d681SAndroid Build Coastguard Worker return getExpressionAsToken();
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker return StringRef(Tok.Data, Tok.Length);
322*9880d681SAndroid Build Coastguard Worker }
323*9880d681SAndroid Build Coastguard Worker
getImm() const324*9880d681SAndroid Build Coastguard Worker int64_t getImm() const {
325*9880d681SAndroid Build Coastguard Worker assert(isImm());
326*9880d681SAndroid Build Coastguard Worker return Imm.Val;
327*9880d681SAndroid Build Coastguard Worker }
328*9880d681SAndroid Build Coastguard Worker
getImmTy() const329*9880d681SAndroid Build Coastguard Worker enum ImmTy getImmTy() const {
330*9880d681SAndroid Build Coastguard Worker assert(isImm());
331*9880d681SAndroid Build Coastguard Worker return Imm.Type;
332*9880d681SAndroid Build Coastguard Worker }
333*9880d681SAndroid Build Coastguard Worker
getReg() const334*9880d681SAndroid Build Coastguard Worker unsigned getReg() const override {
335*9880d681SAndroid Build Coastguard Worker return Reg.RegNo;
336*9880d681SAndroid Build Coastguard Worker }
337*9880d681SAndroid Build Coastguard Worker
getStartLoc() const338*9880d681SAndroid Build Coastguard Worker SMLoc getStartLoc() const override {
339*9880d681SAndroid Build Coastguard Worker return StartLoc;
340*9880d681SAndroid Build Coastguard Worker }
341*9880d681SAndroid Build Coastguard Worker
getEndLoc() const342*9880d681SAndroid Build Coastguard Worker SMLoc getEndLoc() const override {
343*9880d681SAndroid Build Coastguard Worker return EndLoc;
344*9880d681SAndroid Build Coastguard Worker }
345*9880d681SAndroid Build Coastguard Worker
getModifiers() const346*9880d681SAndroid Build Coastguard Worker Modifiers getModifiers() const {
347*9880d681SAndroid Build Coastguard Worker assert(isRegKind() || isImmTy(ImmTyNone));
348*9880d681SAndroid Build Coastguard Worker return isRegKind() ? Reg.Mods : Imm.Mods;
349*9880d681SAndroid Build Coastguard Worker }
350*9880d681SAndroid Build Coastguard Worker
setModifiers(Modifiers Mods)351*9880d681SAndroid Build Coastguard Worker void setModifiers(Modifiers Mods) {
352*9880d681SAndroid Build Coastguard Worker assert(isRegKind() || isImmTy(ImmTyNone));
353*9880d681SAndroid Build Coastguard Worker if (isRegKind())
354*9880d681SAndroid Build Coastguard Worker Reg.Mods = Mods;
355*9880d681SAndroid Build Coastguard Worker else
356*9880d681SAndroid Build Coastguard Worker Imm.Mods = Mods;
357*9880d681SAndroid Build Coastguard Worker }
358*9880d681SAndroid Build Coastguard Worker
hasModifiers() const359*9880d681SAndroid Build Coastguard Worker bool hasModifiers() const {
360*9880d681SAndroid Build Coastguard Worker return getModifiers().hasModifiers();
361*9880d681SAndroid Build Coastguard Worker }
362*9880d681SAndroid Build Coastguard Worker
hasFPModifiers() const363*9880d681SAndroid Build Coastguard Worker bool hasFPModifiers() const {
364*9880d681SAndroid Build Coastguard Worker return getModifiers().hasFPModifiers();
365*9880d681SAndroid Build Coastguard Worker }
366*9880d681SAndroid Build Coastguard Worker
hasIntModifiers() const367*9880d681SAndroid Build Coastguard Worker bool hasIntModifiers() const {
368*9880d681SAndroid Build Coastguard Worker return getModifiers().hasIntModifiers();
369*9880d681SAndroid Build Coastguard Worker }
370*9880d681SAndroid Build Coastguard Worker
addImmOperands(MCInst & Inst,unsigned N,bool ApplyModifiers=true) const371*9880d681SAndroid Build Coastguard Worker void addImmOperands(MCInst &Inst, unsigned N, bool ApplyModifiers = true) const {
372*9880d681SAndroid Build Coastguard Worker if (isImmTy(ImmTyNone) && ApplyModifiers && Imm.Mods.hasFPModifiers()) {
373*9880d681SAndroid Build Coastguard Worker // Apply modifiers to immediate value
374*9880d681SAndroid Build Coastguard Worker int64_t Val = Imm.Val;
375*9880d681SAndroid Build Coastguard Worker bool Negate = Imm.Mods.Neg; // Only negate can get here
376*9880d681SAndroid Build Coastguard Worker if (Imm.IsFPImm) {
377*9880d681SAndroid Build Coastguard Worker APFloat F(BitsToFloat(Val));
378*9880d681SAndroid Build Coastguard Worker if (Negate) {
379*9880d681SAndroid Build Coastguard Worker F.changeSign();
380*9880d681SAndroid Build Coastguard Worker }
381*9880d681SAndroid Build Coastguard Worker Val = F.bitcastToAPInt().getZExtValue();
382*9880d681SAndroid Build Coastguard Worker } else {
383*9880d681SAndroid Build Coastguard Worker Val = Negate ? -Val : Val;
384*9880d681SAndroid Build Coastguard Worker }
385*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(Val));
386*9880d681SAndroid Build Coastguard Worker } else {
387*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(getImm()));
388*9880d681SAndroid Build Coastguard Worker }
389*9880d681SAndroid Build Coastguard Worker }
390*9880d681SAndroid Build Coastguard Worker
addRegOperands(MCInst & Inst,unsigned N) const391*9880d681SAndroid Build Coastguard Worker void addRegOperands(MCInst &Inst, unsigned N) const {
392*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(AMDGPU::getMCReg(getReg(), *Reg.STI)));
393*9880d681SAndroid Build Coastguard Worker }
394*9880d681SAndroid Build Coastguard Worker
addRegOrImmOperands(MCInst & Inst,unsigned N) const395*9880d681SAndroid Build Coastguard Worker void addRegOrImmOperands(MCInst &Inst, unsigned N) const {
396*9880d681SAndroid Build Coastguard Worker if (isRegKind())
397*9880d681SAndroid Build Coastguard Worker addRegOperands(Inst, N);
398*9880d681SAndroid Build Coastguard Worker else if (isExpr())
399*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createExpr(Expr));
400*9880d681SAndroid Build Coastguard Worker else
401*9880d681SAndroid Build Coastguard Worker addImmOperands(Inst, N);
402*9880d681SAndroid Build Coastguard Worker }
403*9880d681SAndroid Build Coastguard Worker
addRegOrImmWithInputModsOperands(MCInst & Inst,unsigned N) const404*9880d681SAndroid Build Coastguard Worker void addRegOrImmWithInputModsOperands(MCInst &Inst, unsigned N) const {
405*9880d681SAndroid Build Coastguard Worker Modifiers Mods = getModifiers();
406*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(Mods.getModifiersOperand()));
407*9880d681SAndroid Build Coastguard Worker if (isRegKind()) {
408*9880d681SAndroid Build Coastguard Worker addRegOperands(Inst, N);
409*9880d681SAndroid Build Coastguard Worker } else {
410*9880d681SAndroid Build Coastguard Worker addImmOperands(Inst, N, false);
411*9880d681SAndroid Build Coastguard Worker }
412*9880d681SAndroid Build Coastguard Worker }
413*9880d681SAndroid Build Coastguard Worker
addRegOrImmWithFPInputModsOperands(MCInst & Inst,unsigned N) const414*9880d681SAndroid Build Coastguard Worker void addRegOrImmWithFPInputModsOperands(MCInst &Inst, unsigned N) const {
415*9880d681SAndroid Build Coastguard Worker assert(!hasIntModifiers());
416*9880d681SAndroid Build Coastguard Worker addRegOrImmWithInputModsOperands(Inst, N);
417*9880d681SAndroid Build Coastguard Worker }
418*9880d681SAndroid Build Coastguard Worker
addRegOrImmWithIntInputModsOperands(MCInst & Inst,unsigned N) const419*9880d681SAndroid Build Coastguard Worker void addRegOrImmWithIntInputModsOperands(MCInst &Inst, unsigned N) const {
420*9880d681SAndroid Build Coastguard Worker assert(!hasFPModifiers());
421*9880d681SAndroid Build Coastguard Worker addRegOrImmWithInputModsOperands(Inst, N);
422*9880d681SAndroid Build Coastguard Worker }
423*9880d681SAndroid Build Coastguard Worker
addSoppBrTargetOperands(MCInst & Inst,unsigned N) const424*9880d681SAndroid Build Coastguard Worker void addSoppBrTargetOperands(MCInst &Inst, unsigned N) const {
425*9880d681SAndroid Build Coastguard Worker if (isImm())
426*9880d681SAndroid Build Coastguard Worker addImmOperands(Inst, N);
427*9880d681SAndroid Build Coastguard Worker else {
428*9880d681SAndroid Build Coastguard Worker assert(isExpr());
429*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createExpr(Expr));
430*9880d681SAndroid Build Coastguard Worker }
431*9880d681SAndroid Build Coastguard Worker }
432*9880d681SAndroid Build Coastguard Worker
printImmTy(raw_ostream & OS,ImmTy Type) const433*9880d681SAndroid Build Coastguard Worker void printImmTy(raw_ostream& OS, ImmTy Type) const {
434*9880d681SAndroid Build Coastguard Worker switch (Type) {
435*9880d681SAndroid Build Coastguard Worker case ImmTyNone: OS << "None"; break;
436*9880d681SAndroid Build Coastguard Worker case ImmTyGDS: OS << "GDS"; break;
437*9880d681SAndroid Build Coastguard Worker case ImmTyOffen: OS << "Offen"; break;
438*9880d681SAndroid Build Coastguard Worker case ImmTyIdxen: OS << "Idxen"; break;
439*9880d681SAndroid Build Coastguard Worker case ImmTyAddr64: OS << "Addr64"; break;
440*9880d681SAndroid Build Coastguard Worker case ImmTyOffset: OS << "Offset"; break;
441*9880d681SAndroid Build Coastguard Worker case ImmTyOffset0: OS << "Offset0"; break;
442*9880d681SAndroid Build Coastguard Worker case ImmTyOffset1: OS << "Offset1"; break;
443*9880d681SAndroid Build Coastguard Worker case ImmTyGLC: OS << "GLC"; break;
444*9880d681SAndroid Build Coastguard Worker case ImmTySLC: OS << "SLC"; break;
445*9880d681SAndroid Build Coastguard Worker case ImmTyTFE: OS << "TFE"; break;
446*9880d681SAndroid Build Coastguard Worker case ImmTyClampSI: OS << "ClampSI"; break;
447*9880d681SAndroid Build Coastguard Worker case ImmTyOModSI: OS << "OModSI"; break;
448*9880d681SAndroid Build Coastguard Worker case ImmTyDppCtrl: OS << "DppCtrl"; break;
449*9880d681SAndroid Build Coastguard Worker case ImmTyDppRowMask: OS << "DppRowMask"; break;
450*9880d681SAndroid Build Coastguard Worker case ImmTyDppBankMask: OS << "DppBankMask"; break;
451*9880d681SAndroid Build Coastguard Worker case ImmTyDppBoundCtrl: OS << "DppBoundCtrl"; break;
452*9880d681SAndroid Build Coastguard Worker case ImmTySdwaDstSel: OS << "SdwaDstSel"; break;
453*9880d681SAndroid Build Coastguard Worker case ImmTySdwaSrc0Sel: OS << "SdwaSrc0Sel"; break;
454*9880d681SAndroid Build Coastguard Worker case ImmTySdwaSrc1Sel: OS << "SdwaSrc1Sel"; break;
455*9880d681SAndroid Build Coastguard Worker case ImmTySdwaDstUnused: OS << "SdwaDstUnused"; break;
456*9880d681SAndroid Build Coastguard Worker case ImmTyDMask: OS << "DMask"; break;
457*9880d681SAndroid Build Coastguard Worker case ImmTyUNorm: OS << "UNorm"; break;
458*9880d681SAndroid Build Coastguard Worker case ImmTyDA: OS << "DA"; break;
459*9880d681SAndroid Build Coastguard Worker case ImmTyR128: OS << "R128"; break;
460*9880d681SAndroid Build Coastguard Worker case ImmTyLWE: OS << "LWE"; break;
461*9880d681SAndroid Build Coastguard Worker case ImmTyHwreg: OS << "Hwreg"; break;
462*9880d681SAndroid Build Coastguard Worker case ImmTySendMsg: OS << "SendMsg"; break;
463*9880d681SAndroid Build Coastguard Worker }
464*9880d681SAndroid Build Coastguard Worker }
465*9880d681SAndroid Build Coastguard Worker
print(raw_ostream & OS) const466*9880d681SAndroid Build Coastguard Worker void print(raw_ostream &OS) const override {
467*9880d681SAndroid Build Coastguard Worker switch (Kind) {
468*9880d681SAndroid Build Coastguard Worker case Register:
469*9880d681SAndroid Build Coastguard Worker OS << "<register " << getReg() << " mods: " << Reg.Mods << '>';
470*9880d681SAndroid Build Coastguard Worker break;
471*9880d681SAndroid Build Coastguard Worker case Immediate:
472*9880d681SAndroid Build Coastguard Worker OS << '<' << getImm();
473*9880d681SAndroid Build Coastguard Worker if (getImmTy() != ImmTyNone) {
474*9880d681SAndroid Build Coastguard Worker OS << " type: "; printImmTy(OS, getImmTy());
475*9880d681SAndroid Build Coastguard Worker }
476*9880d681SAndroid Build Coastguard Worker OS << " mods: " << Imm.Mods << '>';
477*9880d681SAndroid Build Coastguard Worker break;
478*9880d681SAndroid Build Coastguard Worker case Token:
479*9880d681SAndroid Build Coastguard Worker OS << '\'' << getToken() << '\'';
480*9880d681SAndroid Build Coastguard Worker break;
481*9880d681SAndroid Build Coastguard Worker case Expression:
482*9880d681SAndroid Build Coastguard Worker OS << "<expr " << *Expr << '>';
483*9880d681SAndroid Build Coastguard Worker break;
484*9880d681SAndroid Build Coastguard Worker }
485*9880d681SAndroid Build Coastguard Worker }
486*9880d681SAndroid Build Coastguard Worker
CreateImm(int64_t Val,SMLoc Loc,enum ImmTy Type=ImmTyNone,bool IsFPImm=false)487*9880d681SAndroid Build Coastguard Worker static AMDGPUOperand::Ptr CreateImm(int64_t Val, SMLoc Loc,
488*9880d681SAndroid Build Coastguard Worker enum ImmTy Type = ImmTyNone,
489*9880d681SAndroid Build Coastguard Worker bool IsFPImm = false) {
490*9880d681SAndroid Build Coastguard Worker auto Op = llvm::make_unique<AMDGPUOperand>(Immediate);
491*9880d681SAndroid Build Coastguard Worker Op->Imm.Val = Val;
492*9880d681SAndroid Build Coastguard Worker Op->Imm.IsFPImm = IsFPImm;
493*9880d681SAndroid Build Coastguard Worker Op->Imm.Type = Type;
494*9880d681SAndroid Build Coastguard Worker Op->Imm.Mods = {false, false, false};
495*9880d681SAndroid Build Coastguard Worker Op->StartLoc = Loc;
496*9880d681SAndroid Build Coastguard Worker Op->EndLoc = Loc;
497*9880d681SAndroid Build Coastguard Worker return Op;
498*9880d681SAndroid Build Coastguard Worker }
499*9880d681SAndroid Build Coastguard Worker
CreateToken(StringRef Str,SMLoc Loc,bool HasExplicitEncodingSize=true)500*9880d681SAndroid Build Coastguard Worker static AMDGPUOperand::Ptr CreateToken(StringRef Str, SMLoc Loc,
501*9880d681SAndroid Build Coastguard Worker bool HasExplicitEncodingSize = true) {
502*9880d681SAndroid Build Coastguard Worker auto Res = llvm::make_unique<AMDGPUOperand>(Token);
503*9880d681SAndroid Build Coastguard Worker Res->Tok.Data = Str.data();
504*9880d681SAndroid Build Coastguard Worker Res->Tok.Length = Str.size();
505*9880d681SAndroid Build Coastguard Worker Res->StartLoc = Loc;
506*9880d681SAndroid Build Coastguard Worker Res->EndLoc = Loc;
507*9880d681SAndroid Build Coastguard Worker return Res;
508*9880d681SAndroid Build Coastguard Worker }
509*9880d681SAndroid Build Coastguard Worker
CreateReg(unsigned RegNo,SMLoc S,SMLoc E,const MCRegisterInfo * TRI,const MCSubtargetInfo * STI,bool ForceVOP3)510*9880d681SAndroid Build Coastguard Worker static AMDGPUOperand::Ptr CreateReg(unsigned RegNo, SMLoc S,
511*9880d681SAndroid Build Coastguard Worker SMLoc E,
512*9880d681SAndroid Build Coastguard Worker const MCRegisterInfo *TRI,
513*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI,
514*9880d681SAndroid Build Coastguard Worker bool ForceVOP3) {
515*9880d681SAndroid Build Coastguard Worker auto Op = llvm::make_unique<AMDGPUOperand>(Register);
516*9880d681SAndroid Build Coastguard Worker Op->Reg.RegNo = RegNo;
517*9880d681SAndroid Build Coastguard Worker Op->Reg.TRI = TRI;
518*9880d681SAndroid Build Coastguard Worker Op->Reg.STI = STI;
519*9880d681SAndroid Build Coastguard Worker Op->Reg.Mods = {false, false, false};
520*9880d681SAndroid Build Coastguard Worker Op->Reg.IsForcedVOP3 = ForceVOP3;
521*9880d681SAndroid Build Coastguard Worker Op->StartLoc = S;
522*9880d681SAndroid Build Coastguard Worker Op->EndLoc = E;
523*9880d681SAndroid Build Coastguard Worker return Op;
524*9880d681SAndroid Build Coastguard Worker }
525*9880d681SAndroid Build Coastguard Worker
CreateExpr(const class MCExpr * Expr,SMLoc S)526*9880d681SAndroid Build Coastguard Worker static AMDGPUOperand::Ptr CreateExpr(const class MCExpr *Expr, SMLoc S) {
527*9880d681SAndroid Build Coastguard Worker auto Op = llvm::make_unique<AMDGPUOperand>(Expression);
528*9880d681SAndroid Build Coastguard Worker Op->Expr = Expr;
529*9880d681SAndroid Build Coastguard Worker Op->StartLoc = S;
530*9880d681SAndroid Build Coastguard Worker Op->EndLoc = S;
531*9880d681SAndroid Build Coastguard Worker return Op;
532*9880d681SAndroid Build Coastguard Worker }
533*9880d681SAndroid Build Coastguard Worker };
534*9880d681SAndroid Build Coastguard Worker
operator <<(raw_ostream & OS,AMDGPUOperand::Modifiers Mods)535*9880d681SAndroid Build Coastguard Worker raw_ostream &operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods) {
536*9880d681SAndroid Build Coastguard Worker OS << "abs:" << Mods.Abs << " neg: " << Mods.Neg << " sext:" << Mods.Sext;
537*9880d681SAndroid Build Coastguard Worker return OS;
538*9880d681SAndroid Build Coastguard Worker }
539*9880d681SAndroid Build Coastguard Worker
540*9880d681SAndroid Build Coastguard Worker class AMDGPUAsmParser : public MCTargetAsmParser {
541*9880d681SAndroid Build Coastguard Worker const MCInstrInfo &MII;
542*9880d681SAndroid Build Coastguard Worker MCAsmParser &Parser;
543*9880d681SAndroid Build Coastguard Worker
544*9880d681SAndroid Build Coastguard Worker unsigned ForcedEncodingSize;
545*9880d681SAndroid Build Coastguard Worker bool ForcedDPP;
546*9880d681SAndroid Build Coastguard Worker bool ForcedSDWA;
547*9880d681SAndroid Build Coastguard Worker
isSI() const548*9880d681SAndroid Build Coastguard Worker bool isSI() const {
549*9880d681SAndroid Build Coastguard Worker return AMDGPU::isSI(getSTI());
550*9880d681SAndroid Build Coastguard Worker }
551*9880d681SAndroid Build Coastguard Worker
isCI() const552*9880d681SAndroid Build Coastguard Worker bool isCI() const {
553*9880d681SAndroid Build Coastguard Worker return AMDGPU::isCI(getSTI());
554*9880d681SAndroid Build Coastguard Worker }
555*9880d681SAndroid Build Coastguard Worker
isVI() const556*9880d681SAndroid Build Coastguard Worker bool isVI() const {
557*9880d681SAndroid Build Coastguard Worker return AMDGPU::isVI(getSTI());
558*9880d681SAndroid Build Coastguard Worker }
559*9880d681SAndroid Build Coastguard Worker
hasSGPR102_SGPR103() const560*9880d681SAndroid Build Coastguard Worker bool hasSGPR102_SGPR103() const {
561*9880d681SAndroid Build Coastguard Worker return !isVI();
562*9880d681SAndroid Build Coastguard Worker }
563*9880d681SAndroid Build Coastguard Worker
564*9880d681SAndroid Build Coastguard Worker /// @name Auto-generated Match Functions
565*9880d681SAndroid Build Coastguard Worker /// {
566*9880d681SAndroid Build Coastguard Worker
567*9880d681SAndroid Build Coastguard Worker #define GET_ASSEMBLER_HEADER
568*9880d681SAndroid Build Coastguard Worker #include "AMDGPUGenAsmMatcher.inc"
569*9880d681SAndroid Build Coastguard Worker
570*9880d681SAndroid Build Coastguard Worker /// }
571*9880d681SAndroid Build Coastguard Worker
572*9880d681SAndroid Build Coastguard Worker private:
573*9880d681SAndroid Build Coastguard Worker bool ParseDirectiveMajorMinor(uint32_t &Major, uint32_t &Minor);
574*9880d681SAndroid Build Coastguard Worker bool ParseDirectiveHSACodeObjectVersion();
575*9880d681SAndroid Build Coastguard Worker bool ParseDirectiveHSACodeObjectISA();
576*9880d681SAndroid Build Coastguard Worker bool ParseAMDKernelCodeTValue(StringRef ID, amd_kernel_code_t &Header);
577*9880d681SAndroid Build Coastguard Worker bool ParseDirectiveAMDKernelCodeT();
578*9880d681SAndroid Build Coastguard Worker bool ParseSectionDirectiveHSAText();
579*9880d681SAndroid Build Coastguard Worker bool subtargetHasRegister(const MCRegisterInfo &MRI, unsigned RegNo) const;
580*9880d681SAndroid Build Coastguard Worker bool ParseDirectiveAMDGPUHsaKernel();
581*9880d681SAndroid Build Coastguard Worker bool ParseDirectiveAMDGPUHsaModuleGlobal();
582*9880d681SAndroid Build Coastguard Worker bool ParseDirectiveAMDGPUHsaProgramGlobal();
583*9880d681SAndroid Build Coastguard Worker bool ParseSectionDirectiveHSADataGlobalAgent();
584*9880d681SAndroid Build Coastguard Worker bool ParseSectionDirectiveHSADataGlobalProgram();
585*9880d681SAndroid Build Coastguard Worker bool ParseSectionDirectiveHSARodataReadonlyAgent();
586*9880d681SAndroid Build Coastguard Worker bool AddNextRegisterToList(unsigned& Reg, unsigned& RegWidth, RegisterKind RegKind, unsigned Reg1, unsigned RegNum);
587*9880d681SAndroid Build Coastguard Worker bool ParseAMDGPURegister(RegisterKind& RegKind, unsigned& Reg, unsigned& RegNum, unsigned& RegWidth);
588*9880d681SAndroid Build Coastguard Worker void cvtMubufImpl(MCInst &Inst, const OperandVector &Operands, bool IsAtomic, bool IsAtomicReturn);
589*9880d681SAndroid Build Coastguard Worker
590*9880d681SAndroid Build Coastguard Worker public:
591*9880d681SAndroid Build Coastguard Worker enum AMDGPUMatchResultTy {
592*9880d681SAndroid Build Coastguard Worker Match_PreferE32 = FIRST_TARGET_MATCH_RESULT_TY
593*9880d681SAndroid Build Coastguard Worker };
594*9880d681SAndroid Build Coastguard Worker
AMDGPUAsmParser(const MCSubtargetInfo & STI,MCAsmParser & _Parser,const MCInstrInfo & MII,const MCTargetOptions & Options)595*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser(const MCSubtargetInfo &STI, MCAsmParser &_Parser,
596*9880d681SAndroid Build Coastguard Worker const MCInstrInfo &MII,
597*9880d681SAndroid Build Coastguard Worker const MCTargetOptions &Options)
598*9880d681SAndroid Build Coastguard Worker : MCTargetAsmParser(Options, STI), MII(MII), Parser(_Parser),
599*9880d681SAndroid Build Coastguard Worker ForcedEncodingSize(0),
600*9880d681SAndroid Build Coastguard Worker ForcedDPP(false),
601*9880d681SAndroid Build Coastguard Worker ForcedSDWA(false) {
602*9880d681SAndroid Build Coastguard Worker MCAsmParserExtension::Initialize(Parser);
603*9880d681SAndroid Build Coastguard Worker
604*9880d681SAndroid Build Coastguard Worker if (getSTI().getFeatureBits().none()) {
605*9880d681SAndroid Build Coastguard Worker // Set default features.
606*9880d681SAndroid Build Coastguard Worker copySTI().ToggleFeature("SOUTHERN_ISLANDS");
607*9880d681SAndroid Build Coastguard Worker }
608*9880d681SAndroid Build Coastguard Worker
609*9880d681SAndroid Build Coastguard Worker setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
610*9880d681SAndroid Build Coastguard Worker
611*9880d681SAndroid Build Coastguard Worker {
612*9880d681SAndroid Build Coastguard Worker // TODO: make those pre-defined variables read-only.
613*9880d681SAndroid Build Coastguard Worker // Currently there is none suitable machinery in the core llvm-mc for this.
614*9880d681SAndroid Build Coastguard Worker // MCSymbol::isRedefinable is intended for another purpose, and
615*9880d681SAndroid Build Coastguard Worker // AsmParser::parseDirectiveSet() cannot be specialized for specific target.
616*9880d681SAndroid Build Coastguard Worker AMDGPU::IsaVersion Isa = AMDGPU::getIsaVersion(getSTI().getFeatureBits());
617*9880d681SAndroid Build Coastguard Worker MCContext &Ctx = getContext();
618*9880d681SAndroid Build Coastguard Worker MCSymbol *Sym = Ctx.getOrCreateSymbol(Twine(".option.machine_version_major"));
619*9880d681SAndroid Build Coastguard Worker Sym->setVariableValue(MCConstantExpr::create(Isa.Major, Ctx));
620*9880d681SAndroid Build Coastguard Worker Sym = Ctx.getOrCreateSymbol(Twine(".option.machine_version_minor"));
621*9880d681SAndroid Build Coastguard Worker Sym->setVariableValue(MCConstantExpr::create(Isa.Minor, Ctx));
622*9880d681SAndroid Build Coastguard Worker Sym = Ctx.getOrCreateSymbol(Twine(".option.machine_version_stepping"));
623*9880d681SAndroid Build Coastguard Worker Sym->setVariableValue(MCConstantExpr::create(Isa.Stepping, Ctx));
624*9880d681SAndroid Build Coastguard Worker }
625*9880d681SAndroid Build Coastguard Worker }
626*9880d681SAndroid Build Coastguard Worker
getTargetStreamer()627*9880d681SAndroid Build Coastguard Worker AMDGPUTargetStreamer &getTargetStreamer() {
628*9880d681SAndroid Build Coastguard Worker MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
629*9880d681SAndroid Build Coastguard Worker return static_cast<AMDGPUTargetStreamer &>(TS);
630*9880d681SAndroid Build Coastguard Worker }
631*9880d681SAndroid Build Coastguard Worker
setForcedEncodingSize(unsigned Size)632*9880d681SAndroid Build Coastguard Worker void setForcedEncodingSize(unsigned Size) { ForcedEncodingSize = Size; }
setForcedDPP(bool ForceDPP_)633*9880d681SAndroid Build Coastguard Worker void setForcedDPP(bool ForceDPP_) { ForcedDPP = ForceDPP_; }
setForcedSDWA(bool ForceSDWA_)634*9880d681SAndroid Build Coastguard Worker void setForcedSDWA(bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
635*9880d681SAndroid Build Coastguard Worker
getForcedEncodingSize() const636*9880d681SAndroid Build Coastguard Worker unsigned getForcedEncodingSize() const { return ForcedEncodingSize; }
isForcedVOP3() const637*9880d681SAndroid Build Coastguard Worker bool isForcedVOP3() const { return ForcedEncodingSize == 64; }
isForcedDPP() const638*9880d681SAndroid Build Coastguard Worker bool isForcedDPP() const { return ForcedDPP; }
isForcedSDWA() const639*9880d681SAndroid Build Coastguard Worker bool isForcedSDWA() const { return ForcedSDWA; }
640*9880d681SAndroid Build Coastguard Worker
641*9880d681SAndroid Build Coastguard Worker std::unique_ptr<AMDGPUOperand> parseRegister();
642*9880d681SAndroid Build Coastguard Worker bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
643*9880d681SAndroid Build Coastguard Worker unsigned checkTargetMatchPredicate(MCInst &Inst) override;
644*9880d681SAndroid Build Coastguard Worker unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
645*9880d681SAndroid Build Coastguard Worker unsigned Kind) override;
646*9880d681SAndroid Build Coastguard Worker bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
647*9880d681SAndroid Build Coastguard Worker OperandVector &Operands, MCStreamer &Out,
648*9880d681SAndroid Build Coastguard Worker uint64_t &ErrorInfo,
649*9880d681SAndroid Build Coastguard Worker bool MatchingInlineAsm) override;
650*9880d681SAndroid Build Coastguard Worker bool ParseDirective(AsmToken DirectiveID) override;
651*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Mnemonic);
652*9880d681SAndroid Build Coastguard Worker StringRef parseMnemonicSuffix(StringRef Name);
653*9880d681SAndroid Build Coastguard Worker bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
654*9880d681SAndroid Build Coastguard Worker SMLoc NameLoc, OperandVector &Operands) override;
655*9880d681SAndroid Build Coastguard Worker
656*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseIntWithPrefix(const char *Prefix, int64_t &Int);
657*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseIntWithPrefix(const char *Prefix,
658*9880d681SAndroid Build Coastguard Worker OperandVector &Operands,
659*9880d681SAndroid Build Coastguard Worker enum AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
660*9880d681SAndroid Build Coastguard Worker bool (*ConvertResult)(int64_t&) = 0);
661*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseNamedBit(const char *Name, OperandVector &Operands,
662*9880d681SAndroid Build Coastguard Worker enum AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
663*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseStringWithPrefix(StringRef Prefix, StringRef &Value);
664*9880d681SAndroid Build Coastguard Worker
665*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseImm(OperandVector &Operands);
666*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseRegOrImm(OperandVector &Operands);
667*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseRegOrImmWithFPInputMods(OperandVector &Operands);
668*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseRegOrImmWithIntInputMods(OperandVector &Operands);
669*9880d681SAndroid Build Coastguard Worker
670*9880d681SAndroid Build Coastguard Worker void cvtDSOffset01(MCInst &Inst, const OperandVector &Operands);
671*9880d681SAndroid Build Coastguard Worker void cvtDS(MCInst &Inst, const OperandVector &Operands);
672*9880d681SAndroid Build Coastguard Worker
673*9880d681SAndroid Build Coastguard Worker bool parseCnt(int64_t &IntVal);
674*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseSWaitCntOps(OperandVector &Operands);
675*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseHwreg(OperandVector &Operands);
676*9880d681SAndroid Build Coastguard Worker
677*9880d681SAndroid Build Coastguard Worker private:
678*9880d681SAndroid Build Coastguard Worker struct OperandInfoTy {
679*9880d681SAndroid Build Coastguard Worker int64_t Id;
680*9880d681SAndroid Build Coastguard Worker bool IsSymbolic;
OperandInfoTy__anon66474c340111::AMDGPUAsmParser::OperandInfoTy681*9880d681SAndroid Build Coastguard Worker OperandInfoTy(int64_t Id_) : Id(Id_), IsSymbolic(false) { }
682*9880d681SAndroid Build Coastguard Worker };
683*9880d681SAndroid Build Coastguard Worker
684*9880d681SAndroid Build Coastguard Worker bool parseSendMsgConstruct(OperandInfoTy &Msg, OperandInfoTy &Operation, int64_t &StreamId);
685*9880d681SAndroid Build Coastguard Worker bool parseHwregConstruct(OperandInfoTy &HwReg, int64_t &Offset, int64_t &Width);
686*9880d681SAndroid Build Coastguard Worker public:
687*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseOptionalOperand(OperandVector &Operands);
688*9880d681SAndroid Build Coastguard Worker
689*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseSendMsgOp(OperandVector &Operands);
690*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseSOppBrTarget(OperandVector &Operands);
691*9880d681SAndroid Build Coastguard Worker
cvtMubuf(MCInst & Inst,const OperandVector & Operands)692*9880d681SAndroid Build Coastguard Worker void cvtMubuf(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, false, false); }
cvtMubufAtomic(MCInst & Inst,const OperandVector & Operands)693*9880d681SAndroid Build Coastguard Worker void cvtMubufAtomic(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, false); }
cvtMubufAtomicReturn(MCInst & Inst,const OperandVector & Operands)694*9880d681SAndroid Build Coastguard Worker void cvtMubufAtomicReturn(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, true); }
695*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr defaultGLC() const;
696*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr defaultSLC() const;
697*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr defaultTFE() const;
698*9880d681SAndroid Build Coastguard Worker
699*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr defaultDMask() const;
700*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr defaultUNorm() const;
701*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr defaultDA() const;
702*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr defaultR128() const;
703*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr defaultLWE() const;
704*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr defaultSMRDOffset() const;
705*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr defaultSMRDLiteralOffset() const;
706*9880d681SAndroid Build Coastguard Worker
707*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseOModOperand(OperandVector &Operands);
708*9880d681SAndroid Build Coastguard Worker
709*9880d681SAndroid Build Coastguard Worker void cvtId(MCInst &Inst, const OperandVector &Operands);
710*9880d681SAndroid Build Coastguard Worker void cvtVOP3_2_mod(MCInst &Inst, const OperandVector &Operands);
711*9880d681SAndroid Build Coastguard Worker void cvtVOP3(MCInst &Inst, const OperandVector &Operands);
712*9880d681SAndroid Build Coastguard Worker
713*9880d681SAndroid Build Coastguard Worker void cvtMIMG(MCInst &Inst, const OperandVector &Operands);
714*9880d681SAndroid Build Coastguard Worker void cvtMIMGAtomic(MCInst &Inst, const OperandVector &Operands);
715*9880d681SAndroid Build Coastguard Worker
716*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseDPPCtrl(OperandVector &Operands);
717*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr defaultRowMask() const;
718*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr defaultBankMask() const;
719*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr defaultBoundCtrl() const;
720*9880d681SAndroid Build Coastguard Worker void cvtDPP(MCInst &Inst, const OperandVector &Operands);
721*9880d681SAndroid Build Coastguard Worker
722*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseSDWASel(OperandVector &Operands, StringRef Prefix,
723*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::ImmTy Type);
724*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy parseSDWADstUnused(OperandVector &Operands);
725*9880d681SAndroid Build Coastguard Worker void cvtSdwaVOP1(MCInst &Inst, const OperandVector &Operands);
726*9880d681SAndroid Build Coastguard Worker void cvtSdwaVOP2(MCInst &Inst, const OperandVector &Operands);
727*9880d681SAndroid Build Coastguard Worker void cvtSdwaVOPC(MCInst &Inst, const OperandVector &Operands);
728*9880d681SAndroid Build Coastguard Worker void cvtSDWA(MCInst &Inst, const OperandVector &Operands,
729*9880d681SAndroid Build Coastguard Worker uint64_t BasicInstType);
730*9880d681SAndroid Build Coastguard Worker };
731*9880d681SAndroid Build Coastguard Worker
732*9880d681SAndroid Build Coastguard Worker struct OptionalOperand {
733*9880d681SAndroid Build Coastguard Worker const char *Name;
734*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::ImmTy Type;
735*9880d681SAndroid Build Coastguard Worker bool IsBit;
736*9880d681SAndroid Build Coastguard Worker bool (*ConvertResult)(int64_t&);
737*9880d681SAndroid Build Coastguard Worker };
738*9880d681SAndroid Build Coastguard Worker
739*9880d681SAndroid Build Coastguard Worker }
740*9880d681SAndroid Build Coastguard Worker
getRegClass(RegisterKind Is,unsigned RegWidth)741*9880d681SAndroid Build Coastguard Worker static int getRegClass(RegisterKind Is, unsigned RegWidth) {
742*9880d681SAndroid Build Coastguard Worker if (Is == IS_VGPR) {
743*9880d681SAndroid Build Coastguard Worker switch (RegWidth) {
744*9880d681SAndroid Build Coastguard Worker default: return -1;
745*9880d681SAndroid Build Coastguard Worker case 1: return AMDGPU::VGPR_32RegClassID;
746*9880d681SAndroid Build Coastguard Worker case 2: return AMDGPU::VReg_64RegClassID;
747*9880d681SAndroid Build Coastguard Worker case 3: return AMDGPU::VReg_96RegClassID;
748*9880d681SAndroid Build Coastguard Worker case 4: return AMDGPU::VReg_128RegClassID;
749*9880d681SAndroid Build Coastguard Worker case 8: return AMDGPU::VReg_256RegClassID;
750*9880d681SAndroid Build Coastguard Worker case 16: return AMDGPU::VReg_512RegClassID;
751*9880d681SAndroid Build Coastguard Worker }
752*9880d681SAndroid Build Coastguard Worker } else if (Is == IS_TTMP) {
753*9880d681SAndroid Build Coastguard Worker switch (RegWidth) {
754*9880d681SAndroid Build Coastguard Worker default: return -1;
755*9880d681SAndroid Build Coastguard Worker case 1: return AMDGPU::TTMP_32RegClassID;
756*9880d681SAndroid Build Coastguard Worker case 2: return AMDGPU::TTMP_64RegClassID;
757*9880d681SAndroid Build Coastguard Worker case 4: return AMDGPU::TTMP_128RegClassID;
758*9880d681SAndroid Build Coastguard Worker }
759*9880d681SAndroid Build Coastguard Worker } else if (Is == IS_SGPR) {
760*9880d681SAndroid Build Coastguard Worker switch (RegWidth) {
761*9880d681SAndroid Build Coastguard Worker default: return -1;
762*9880d681SAndroid Build Coastguard Worker case 1: return AMDGPU::SGPR_32RegClassID;
763*9880d681SAndroid Build Coastguard Worker case 2: return AMDGPU::SGPR_64RegClassID;
764*9880d681SAndroid Build Coastguard Worker case 4: return AMDGPU::SGPR_128RegClassID;
765*9880d681SAndroid Build Coastguard Worker case 8: return AMDGPU::SReg_256RegClassID;
766*9880d681SAndroid Build Coastguard Worker case 16: return AMDGPU::SReg_512RegClassID;
767*9880d681SAndroid Build Coastguard Worker }
768*9880d681SAndroid Build Coastguard Worker }
769*9880d681SAndroid Build Coastguard Worker return -1;
770*9880d681SAndroid Build Coastguard Worker }
771*9880d681SAndroid Build Coastguard Worker
getSpecialRegForName(StringRef RegName)772*9880d681SAndroid Build Coastguard Worker static unsigned getSpecialRegForName(StringRef RegName) {
773*9880d681SAndroid Build Coastguard Worker return StringSwitch<unsigned>(RegName)
774*9880d681SAndroid Build Coastguard Worker .Case("exec", AMDGPU::EXEC)
775*9880d681SAndroid Build Coastguard Worker .Case("vcc", AMDGPU::VCC)
776*9880d681SAndroid Build Coastguard Worker .Case("flat_scratch", AMDGPU::FLAT_SCR)
777*9880d681SAndroid Build Coastguard Worker .Case("m0", AMDGPU::M0)
778*9880d681SAndroid Build Coastguard Worker .Case("scc", AMDGPU::SCC)
779*9880d681SAndroid Build Coastguard Worker .Case("tba", AMDGPU::TBA)
780*9880d681SAndroid Build Coastguard Worker .Case("tma", AMDGPU::TMA)
781*9880d681SAndroid Build Coastguard Worker .Case("flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
782*9880d681SAndroid Build Coastguard Worker .Case("flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
783*9880d681SAndroid Build Coastguard Worker .Case("vcc_lo", AMDGPU::VCC_LO)
784*9880d681SAndroid Build Coastguard Worker .Case("vcc_hi", AMDGPU::VCC_HI)
785*9880d681SAndroid Build Coastguard Worker .Case("exec_lo", AMDGPU::EXEC_LO)
786*9880d681SAndroid Build Coastguard Worker .Case("exec_hi", AMDGPU::EXEC_HI)
787*9880d681SAndroid Build Coastguard Worker .Case("tma_lo", AMDGPU::TMA_LO)
788*9880d681SAndroid Build Coastguard Worker .Case("tma_hi", AMDGPU::TMA_HI)
789*9880d681SAndroid Build Coastguard Worker .Case("tba_lo", AMDGPU::TBA_LO)
790*9880d681SAndroid Build Coastguard Worker .Case("tba_hi", AMDGPU::TBA_HI)
791*9880d681SAndroid Build Coastguard Worker .Default(0);
792*9880d681SAndroid Build Coastguard Worker }
793*9880d681SAndroid Build Coastguard Worker
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)794*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
795*9880d681SAndroid Build Coastguard Worker auto R = parseRegister();
796*9880d681SAndroid Build Coastguard Worker if (!R) return true;
797*9880d681SAndroid Build Coastguard Worker assert(R->isReg());
798*9880d681SAndroid Build Coastguard Worker RegNo = R->getReg();
799*9880d681SAndroid Build Coastguard Worker StartLoc = R->getStartLoc();
800*9880d681SAndroid Build Coastguard Worker EndLoc = R->getEndLoc();
801*9880d681SAndroid Build Coastguard Worker return false;
802*9880d681SAndroid Build Coastguard Worker }
803*9880d681SAndroid Build Coastguard Worker
AddNextRegisterToList(unsigned & Reg,unsigned & RegWidth,RegisterKind RegKind,unsigned Reg1,unsigned RegNum)804*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::AddNextRegisterToList(unsigned& Reg, unsigned& RegWidth, RegisterKind RegKind, unsigned Reg1, unsigned RegNum)
805*9880d681SAndroid Build Coastguard Worker {
806*9880d681SAndroid Build Coastguard Worker switch (RegKind) {
807*9880d681SAndroid Build Coastguard Worker case IS_SPECIAL:
808*9880d681SAndroid Build Coastguard Worker if (Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) { Reg = AMDGPU::EXEC; RegWidth = 2; return true; }
809*9880d681SAndroid Build Coastguard Worker if (Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) { Reg = AMDGPU::FLAT_SCR; RegWidth = 2; return true; }
810*9880d681SAndroid Build Coastguard Worker if (Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) { Reg = AMDGPU::VCC; RegWidth = 2; return true; }
811*9880d681SAndroid Build Coastguard Worker if (Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) { Reg = AMDGPU::TBA; RegWidth = 2; return true; }
812*9880d681SAndroid Build Coastguard Worker if (Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) { Reg = AMDGPU::TMA; RegWidth = 2; return true; }
813*9880d681SAndroid Build Coastguard Worker return false;
814*9880d681SAndroid Build Coastguard Worker case IS_VGPR:
815*9880d681SAndroid Build Coastguard Worker case IS_SGPR:
816*9880d681SAndroid Build Coastguard Worker case IS_TTMP:
817*9880d681SAndroid Build Coastguard Worker if (Reg1 != Reg + RegWidth) { return false; }
818*9880d681SAndroid Build Coastguard Worker RegWidth++;
819*9880d681SAndroid Build Coastguard Worker return true;
820*9880d681SAndroid Build Coastguard Worker default:
821*9880d681SAndroid Build Coastguard Worker assert(false); return false;
822*9880d681SAndroid Build Coastguard Worker }
823*9880d681SAndroid Build Coastguard Worker }
824*9880d681SAndroid Build Coastguard Worker
ParseAMDGPURegister(RegisterKind & RegKind,unsigned & Reg,unsigned & RegNum,unsigned & RegWidth)825*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind& RegKind, unsigned& Reg, unsigned& RegNum, unsigned& RegWidth)
826*9880d681SAndroid Build Coastguard Worker {
827*9880d681SAndroid Build Coastguard Worker const MCRegisterInfo *TRI = getContext().getRegisterInfo();
828*9880d681SAndroid Build Coastguard Worker if (getLexer().is(AsmToken::Identifier)) {
829*9880d681SAndroid Build Coastguard Worker StringRef RegName = Parser.getTok().getString();
830*9880d681SAndroid Build Coastguard Worker if ((Reg = getSpecialRegForName(RegName))) {
831*9880d681SAndroid Build Coastguard Worker Parser.Lex();
832*9880d681SAndroid Build Coastguard Worker RegKind = IS_SPECIAL;
833*9880d681SAndroid Build Coastguard Worker } else {
834*9880d681SAndroid Build Coastguard Worker unsigned RegNumIndex = 0;
835*9880d681SAndroid Build Coastguard Worker if (RegName[0] == 'v') {
836*9880d681SAndroid Build Coastguard Worker RegNumIndex = 1;
837*9880d681SAndroid Build Coastguard Worker RegKind = IS_VGPR;
838*9880d681SAndroid Build Coastguard Worker } else if (RegName[0] == 's') {
839*9880d681SAndroid Build Coastguard Worker RegNumIndex = 1;
840*9880d681SAndroid Build Coastguard Worker RegKind = IS_SGPR;
841*9880d681SAndroid Build Coastguard Worker } else if (RegName.startswith("ttmp")) {
842*9880d681SAndroid Build Coastguard Worker RegNumIndex = strlen("ttmp");
843*9880d681SAndroid Build Coastguard Worker RegKind = IS_TTMP;
844*9880d681SAndroid Build Coastguard Worker } else {
845*9880d681SAndroid Build Coastguard Worker return false;
846*9880d681SAndroid Build Coastguard Worker }
847*9880d681SAndroid Build Coastguard Worker if (RegName.size() > RegNumIndex) {
848*9880d681SAndroid Build Coastguard Worker // Single 32-bit register: vXX.
849*9880d681SAndroid Build Coastguard Worker if (RegName.substr(RegNumIndex).getAsInteger(10, RegNum))
850*9880d681SAndroid Build Coastguard Worker return false;
851*9880d681SAndroid Build Coastguard Worker Parser.Lex();
852*9880d681SAndroid Build Coastguard Worker RegWidth = 1;
853*9880d681SAndroid Build Coastguard Worker } else {
854*9880d681SAndroid Build Coastguard Worker // Range of registers: v[XX:YY]. ":YY" is optional.
855*9880d681SAndroid Build Coastguard Worker Parser.Lex();
856*9880d681SAndroid Build Coastguard Worker int64_t RegLo, RegHi;
857*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::LBrac))
858*9880d681SAndroid Build Coastguard Worker return false;
859*9880d681SAndroid Build Coastguard Worker Parser.Lex();
860*9880d681SAndroid Build Coastguard Worker
861*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(RegLo))
862*9880d681SAndroid Build Coastguard Worker return false;
863*9880d681SAndroid Build Coastguard Worker
864*9880d681SAndroid Build Coastguard Worker const bool isRBrace = getLexer().is(AsmToken::RBrac);
865*9880d681SAndroid Build Coastguard Worker if (!isRBrace && getLexer().isNot(AsmToken::Colon))
866*9880d681SAndroid Build Coastguard Worker return false;
867*9880d681SAndroid Build Coastguard Worker Parser.Lex();
868*9880d681SAndroid Build Coastguard Worker
869*9880d681SAndroid Build Coastguard Worker if (isRBrace) {
870*9880d681SAndroid Build Coastguard Worker RegHi = RegLo;
871*9880d681SAndroid Build Coastguard Worker } else {
872*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(RegHi))
873*9880d681SAndroid Build Coastguard Worker return false;
874*9880d681SAndroid Build Coastguard Worker
875*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::RBrac))
876*9880d681SAndroid Build Coastguard Worker return false;
877*9880d681SAndroid Build Coastguard Worker Parser.Lex();
878*9880d681SAndroid Build Coastguard Worker }
879*9880d681SAndroid Build Coastguard Worker RegNum = (unsigned) RegLo;
880*9880d681SAndroid Build Coastguard Worker RegWidth = (RegHi - RegLo) + 1;
881*9880d681SAndroid Build Coastguard Worker }
882*9880d681SAndroid Build Coastguard Worker }
883*9880d681SAndroid Build Coastguard Worker } else if (getLexer().is(AsmToken::LBrac)) {
884*9880d681SAndroid Build Coastguard Worker // List of consecutive registers: [s0,s1,s2,s3]
885*9880d681SAndroid Build Coastguard Worker Parser.Lex();
886*9880d681SAndroid Build Coastguard Worker if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth))
887*9880d681SAndroid Build Coastguard Worker return false;
888*9880d681SAndroid Build Coastguard Worker if (RegWidth != 1)
889*9880d681SAndroid Build Coastguard Worker return false;
890*9880d681SAndroid Build Coastguard Worker RegisterKind RegKind1;
891*9880d681SAndroid Build Coastguard Worker unsigned Reg1, RegNum1, RegWidth1;
892*9880d681SAndroid Build Coastguard Worker do {
893*9880d681SAndroid Build Coastguard Worker if (getLexer().is(AsmToken::Comma)) {
894*9880d681SAndroid Build Coastguard Worker Parser.Lex();
895*9880d681SAndroid Build Coastguard Worker } else if (getLexer().is(AsmToken::RBrac)) {
896*9880d681SAndroid Build Coastguard Worker Parser.Lex();
897*9880d681SAndroid Build Coastguard Worker break;
898*9880d681SAndroid Build Coastguard Worker } else if (ParseAMDGPURegister(RegKind1, Reg1, RegNum1, RegWidth1)) {
899*9880d681SAndroid Build Coastguard Worker if (RegWidth1 != 1) {
900*9880d681SAndroid Build Coastguard Worker return false;
901*9880d681SAndroid Build Coastguard Worker }
902*9880d681SAndroid Build Coastguard Worker if (RegKind1 != RegKind) {
903*9880d681SAndroid Build Coastguard Worker return false;
904*9880d681SAndroid Build Coastguard Worker }
905*9880d681SAndroid Build Coastguard Worker if (!AddNextRegisterToList(Reg, RegWidth, RegKind1, Reg1, RegNum1)) {
906*9880d681SAndroid Build Coastguard Worker return false;
907*9880d681SAndroid Build Coastguard Worker }
908*9880d681SAndroid Build Coastguard Worker } else {
909*9880d681SAndroid Build Coastguard Worker return false;
910*9880d681SAndroid Build Coastguard Worker }
911*9880d681SAndroid Build Coastguard Worker } while (true);
912*9880d681SAndroid Build Coastguard Worker } else {
913*9880d681SAndroid Build Coastguard Worker return false;
914*9880d681SAndroid Build Coastguard Worker }
915*9880d681SAndroid Build Coastguard Worker switch (RegKind) {
916*9880d681SAndroid Build Coastguard Worker case IS_SPECIAL:
917*9880d681SAndroid Build Coastguard Worker RegNum = 0;
918*9880d681SAndroid Build Coastguard Worker RegWidth = 1;
919*9880d681SAndroid Build Coastguard Worker break;
920*9880d681SAndroid Build Coastguard Worker case IS_VGPR:
921*9880d681SAndroid Build Coastguard Worker case IS_SGPR:
922*9880d681SAndroid Build Coastguard Worker case IS_TTMP:
923*9880d681SAndroid Build Coastguard Worker {
924*9880d681SAndroid Build Coastguard Worker unsigned Size = 1;
925*9880d681SAndroid Build Coastguard Worker if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
926*9880d681SAndroid Build Coastguard Worker // SGPR and TTMP registers must be are aligned. Max required alignment is 4 dwords.
927*9880d681SAndroid Build Coastguard Worker Size = std::min(RegWidth, 4u);
928*9880d681SAndroid Build Coastguard Worker }
929*9880d681SAndroid Build Coastguard Worker if (RegNum % Size != 0)
930*9880d681SAndroid Build Coastguard Worker return false;
931*9880d681SAndroid Build Coastguard Worker RegNum = RegNum / Size;
932*9880d681SAndroid Build Coastguard Worker int RCID = getRegClass(RegKind, RegWidth);
933*9880d681SAndroid Build Coastguard Worker if (RCID == -1)
934*9880d681SAndroid Build Coastguard Worker return false;
935*9880d681SAndroid Build Coastguard Worker const MCRegisterClass RC = TRI->getRegClass(RCID);
936*9880d681SAndroid Build Coastguard Worker if (RegNum >= RC.getNumRegs())
937*9880d681SAndroid Build Coastguard Worker return false;
938*9880d681SAndroid Build Coastguard Worker Reg = RC.getRegister(RegNum);
939*9880d681SAndroid Build Coastguard Worker break;
940*9880d681SAndroid Build Coastguard Worker }
941*9880d681SAndroid Build Coastguard Worker
942*9880d681SAndroid Build Coastguard Worker default:
943*9880d681SAndroid Build Coastguard Worker assert(false); return false;
944*9880d681SAndroid Build Coastguard Worker }
945*9880d681SAndroid Build Coastguard Worker
946*9880d681SAndroid Build Coastguard Worker if (!subtargetHasRegister(*TRI, Reg))
947*9880d681SAndroid Build Coastguard Worker return false;
948*9880d681SAndroid Build Coastguard Worker return true;
949*9880d681SAndroid Build Coastguard Worker }
950*9880d681SAndroid Build Coastguard Worker
parseRegister()951*9880d681SAndroid Build Coastguard Worker std::unique_ptr<AMDGPUOperand> AMDGPUAsmParser::parseRegister() {
952*9880d681SAndroid Build Coastguard Worker const auto &Tok = Parser.getTok();
953*9880d681SAndroid Build Coastguard Worker SMLoc StartLoc = Tok.getLoc();
954*9880d681SAndroid Build Coastguard Worker SMLoc EndLoc = Tok.getEndLoc();
955*9880d681SAndroid Build Coastguard Worker const MCRegisterInfo *TRI = getContext().getRegisterInfo();
956*9880d681SAndroid Build Coastguard Worker
957*9880d681SAndroid Build Coastguard Worker RegisterKind RegKind;
958*9880d681SAndroid Build Coastguard Worker unsigned Reg, RegNum, RegWidth;
959*9880d681SAndroid Build Coastguard Worker
960*9880d681SAndroid Build Coastguard Worker if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth)) {
961*9880d681SAndroid Build Coastguard Worker return nullptr;
962*9880d681SAndroid Build Coastguard Worker }
963*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateReg(Reg, StartLoc, EndLoc,
964*9880d681SAndroid Build Coastguard Worker TRI, &getSTI(), false);
965*9880d681SAndroid Build Coastguard Worker }
966*9880d681SAndroid Build Coastguard Worker
967*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseImm(OperandVector & Operands)968*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseImm(OperandVector &Operands) {
969*9880d681SAndroid Build Coastguard Worker bool Minus = false;
970*9880d681SAndroid Build Coastguard Worker if (getLexer().getKind() == AsmToken::Minus) {
971*9880d681SAndroid Build Coastguard Worker Minus = true;
972*9880d681SAndroid Build Coastguard Worker Parser.Lex();
973*9880d681SAndroid Build Coastguard Worker }
974*9880d681SAndroid Build Coastguard Worker
975*9880d681SAndroid Build Coastguard Worker SMLoc S = Parser.getTok().getLoc();
976*9880d681SAndroid Build Coastguard Worker switch(getLexer().getKind()) {
977*9880d681SAndroid Build Coastguard Worker case AsmToken::Integer: {
978*9880d681SAndroid Build Coastguard Worker int64_t IntVal;
979*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(IntVal))
980*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
981*9880d681SAndroid Build Coastguard Worker if (!isInt<32>(IntVal) && !isUInt<32>(IntVal)) {
982*9880d681SAndroid Build Coastguard Worker Error(S, "invalid immediate: only 32-bit values are legal");
983*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
984*9880d681SAndroid Build Coastguard Worker }
985*9880d681SAndroid Build Coastguard Worker
986*9880d681SAndroid Build Coastguard Worker if (Minus)
987*9880d681SAndroid Build Coastguard Worker IntVal *= -1;
988*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateImm(IntVal, S));
989*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
990*9880d681SAndroid Build Coastguard Worker }
991*9880d681SAndroid Build Coastguard Worker case AsmToken::Real: {
992*9880d681SAndroid Build Coastguard Worker // FIXME: We should emit an error if a double precisions floating-point
993*9880d681SAndroid Build Coastguard Worker // value is used. I'm not sure the best way to detect this.
994*9880d681SAndroid Build Coastguard Worker int64_t IntVal;
995*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(IntVal))
996*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
997*9880d681SAndroid Build Coastguard Worker
998*9880d681SAndroid Build Coastguard Worker APFloat F((float)BitsToDouble(IntVal));
999*9880d681SAndroid Build Coastguard Worker if (Minus)
1000*9880d681SAndroid Build Coastguard Worker F.changeSign();
1001*9880d681SAndroid Build Coastguard Worker Operands.push_back(
1002*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::CreateImm(F.bitcastToAPInt().getZExtValue(), S,
1003*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::ImmTyNone, true));
1004*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
1005*9880d681SAndroid Build Coastguard Worker }
1006*9880d681SAndroid Build Coastguard Worker default:
1007*9880d681SAndroid Build Coastguard Worker return Minus ? MatchOperand_ParseFail : MatchOperand_NoMatch;
1008*9880d681SAndroid Build Coastguard Worker }
1009*9880d681SAndroid Build Coastguard Worker }
1010*9880d681SAndroid Build Coastguard Worker
1011*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseRegOrImm(OperandVector & Operands)1012*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseRegOrImm(OperandVector &Operands) {
1013*9880d681SAndroid Build Coastguard Worker auto res = parseImm(Operands);
1014*9880d681SAndroid Build Coastguard Worker if (res != MatchOperand_NoMatch) {
1015*9880d681SAndroid Build Coastguard Worker return res;
1016*9880d681SAndroid Build Coastguard Worker }
1017*9880d681SAndroid Build Coastguard Worker
1018*9880d681SAndroid Build Coastguard Worker if (auto R = parseRegister()) {
1019*9880d681SAndroid Build Coastguard Worker assert(R->isReg());
1020*9880d681SAndroid Build Coastguard Worker R->Reg.IsForcedVOP3 = isForcedVOP3();
1021*9880d681SAndroid Build Coastguard Worker Operands.push_back(std::move(R));
1022*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
1023*9880d681SAndroid Build Coastguard Worker }
1024*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1025*9880d681SAndroid Build Coastguard Worker }
1026*9880d681SAndroid Build Coastguard Worker
1027*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseRegOrImmWithFPInputMods(OperandVector & Operands)1028*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands) {
1029*9880d681SAndroid Build Coastguard Worker // XXX: During parsing we can't determine if minus sign means
1030*9880d681SAndroid Build Coastguard Worker // negate-modifier or negative immediate value.
1031*9880d681SAndroid Build Coastguard Worker // By default we suppose it is modifier.
1032*9880d681SAndroid Build Coastguard Worker bool Negate = false, Abs = false, Abs2 = false;
1033*9880d681SAndroid Build Coastguard Worker
1034*9880d681SAndroid Build Coastguard Worker if (getLexer().getKind()== AsmToken::Minus) {
1035*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1036*9880d681SAndroid Build Coastguard Worker Negate = true;
1037*9880d681SAndroid Build Coastguard Worker }
1038*9880d681SAndroid Build Coastguard Worker
1039*9880d681SAndroid Build Coastguard Worker if (getLexer().getKind() == AsmToken::Identifier && Parser.getTok().getString() == "abs") {
1040*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1041*9880d681SAndroid Build Coastguard Worker Abs2 = true;
1042*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::LParen)) {
1043*9880d681SAndroid Build Coastguard Worker Error(Parser.getTok().getLoc(), "expected left paren after abs");
1044*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1045*9880d681SAndroid Build Coastguard Worker }
1046*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1047*9880d681SAndroid Build Coastguard Worker }
1048*9880d681SAndroid Build Coastguard Worker
1049*9880d681SAndroid Build Coastguard Worker if (getLexer().getKind() == AsmToken::Pipe) {
1050*9880d681SAndroid Build Coastguard Worker if (Abs2) {
1051*9880d681SAndroid Build Coastguard Worker Error(Parser.getTok().getLoc(), "expected register or immediate");
1052*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1053*9880d681SAndroid Build Coastguard Worker }
1054*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1055*9880d681SAndroid Build Coastguard Worker Abs = true;
1056*9880d681SAndroid Build Coastguard Worker }
1057*9880d681SAndroid Build Coastguard Worker
1058*9880d681SAndroid Build Coastguard Worker auto Res = parseRegOrImm(Operands);
1059*9880d681SAndroid Build Coastguard Worker if (Res != MatchOperand_Success) {
1060*9880d681SAndroid Build Coastguard Worker return Res;
1061*9880d681SAndroid Build Coastguard Worker }
1062*9880d681SAndroid Build Coastguard Worker
1063*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Modifiers Mods = {false, false, false};
1064*9880d681SAndroid Build Coastguard Worker if (Negate) {
1065*9880d681SAndroid Build Coastguard Worker Mods.Neg = true;
1066*9880d681SAndroid Build Coastguard Worker }
1067*9880d681SAndroid Build Coastguard Worker if (Abs) {
1068*9880d681SAndroid Build Coastguard Worker if (getLexer().getKind() != AsmToken::Pipe) {
1069*9880d681SAndroid Build Coastguard Worker Error(Parser.getTok().getLoc(), "expected vertical bar");
1070*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1071*9880d681SAndroid Build Coastguard Worker }
1072*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1073*9880d681SAndroid Build Coastguard Worker Mods.Abs = true;
1074*9880d681SAndroid Build Coastguard Worker }
1075*9880d681SAndroid Build Coastguard Worker if (Abs2) {
1076*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::RParen)) {
1077*9880d681SAndroid Build Coastguard Worker Error(Parser.getTok().getLoc(), "expected closing parentheses");
1078*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1079*9880d681SAndroid Build Coastguard Worker }
1080*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1081*9880d681SAndroid Build Coastguard Worker Mods.Abs = true;
1082*9880d681SAndroid Build Coastguard Worker }
1083*9880d681SAndroid Build Coastguard Worker
1084*9880d681SAndroid Build Coastguard Worker if (Mods.hasFPModifiers()) {
1085*9880d681SAndroid Build Coastguard Worker AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands.back());
1086*9880d681SAndroid Build Coastguard Worker Op.setModifiers(Mods);
1087*9880d681SAndroid Build Coastguard Worker }
1088*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
1089*9880d681SAndroid Build Coastguard Worker }
1090*9880d681SAndroid Build Coastguard Worker
1091*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseRegOrImmWithIntInputMods(OperandVector & Operands)1092*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseRegOrImmWithIntInputMods(OperandVector &Operands) {
1093*9880d681SAndroid Build Coastguard Worker bool Sext = false;
1094*9880d681SAndroid Build Coastguard Worker
1095*9880d681SAndroid Build Coastguard Worker if (getLexer().getKind() == AsmToken::Identifier && Parser.getTok().getString() == "sext") {
1096*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1097*9880d681SAndroid Build Coastguard Worker Sext = true;
1098*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::LParen)) {
1099*9880d681SAndroid Build Coastguard Worker Error(Parser.getTok().getLoc(), "expected left paren after sext");
1100*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1101*9880d681SAndroid Build Coastguard Worker }
1102*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1103*9880d681SAndroid Build Coastguard Worker }
1104*9880d681SAndroid Build Coastguard Worker
1105*9880d681SAndroid Build Coastguard Worker auto Res = parseRegOrImm(Operands);
1106*9880d681SAndroid Build Coastguard Worker if (Res != MatchOperand_Success) {
1107*9880d681SAndroid Build Coastguard Worker return Res;
1108*9880d681SAndroid Build Coastguard Worker }
1109*9880d681SAndroid Build Coastguard Worker
1110*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Modifiers Mods = {false, false, false};
1111*9880d681SAndroid Build Coastguard Worker if (Sext) {
1112*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::RParen)) {
1113*9880d681SAndroid Build Coastguard Worker Error(Parser.getTok().getLoc(), "expected closing parentheses");
1114*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1115*9880d681SAndroid Build Coastguard Worker }
1116*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1117*9880d681SAndroid Build Coastguard Worker Mods.Sext = true;
1118*9880d681SAndroid Build Coastguard Worker }
1119*9880d681SAndroid Build Coastguard Worker
1120*9880d681SAndroid Build Coastguard Worker if (Mods.hasIntModifiers()) {
1121*9880d681SAndroid Build Coastguard Worker AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands.back());
1122*9880d681SAndroid Build Coastguard Worker Op.setModifiers(Mods);
1123*9880d681SAndroid Build Coastguard Worker }
1124*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
1125*9880d681SAndroid Build Coastguard Worker }
1126*9880d681SAndroid Build Coastguard Worker
checkTargetMatchPredicate(MCInst & Inst)1127*9880d681SAndroid Build Coastguard Worker unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1128*9880d681SAndroid Build Coastguard Worker
1129*9880d681SAndroid Build Coastguard Worker uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
1130*9880d681SAndroid Build Coastguard Worker
1131*9880d681SAndroid Build Coastguard Worker if ((getForcedEncodingSize() == 32 && (TSFlags & SIInstrFlags::VOP3)) ||
1132*9880d681SAndroid Build Coastguard Worker (getForcedEncodingSize() == 64 && !(TSFlags & SIInstrFlags::VOP3)) ||
1133*9880d681SAndroid Build Coastguard Worker (isForcedDPP() && !(TSFlags & SIInstrFlags::DPP)) ||
1134*9880d681SAndroid Build Coastguard Worker (isForcedSDWA() && !(TSFlags & SIInstrFlags::SDWA)) )
1135*9880d681SAndroid Build Coastguard Worker return Match_InvalidOperand;
1136*9880d681SAndroid Build Coastguard Worker
1137*9880d681SAndroid Build Coastguard Worker if ((TSFlags & SIInstrFlags::VOP3) &&
1138*9880d681SAndroid Build Coastguard Worker (TSFlags & SIInstrFlags::VOPAsmPrefer32Bit) &&
1139*9880d681SAndroid Build Coastguard Worker getForcedEncodingSize() != 64)
1140*9880d681SAndroid Build Coastguard Worker return Match_PreferE32;
1141*9880d681SAndroid Build Coastguard Worker
1142*9880d681SAndroid Build Coastguard Worker return Match_Success;
1143*9880d681SAndroid Build Coastguard Worker }
1144*9880d681SAndroid Build Coastguard Worker
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)1145*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1146*9880d681SAndroid Build Coastguard Worker OperandVector &Operands,
1147*9880d681SAndroid Build Coastguard Worker MCStreamer &Out,
1148*9880d681SAndroid Build Coastguard Worker uint64_t &ErrorInfo,
1149*9880d681SAndroid Build Coastguard Worker bool MatchingInlineAsm) {
1150*9880d681SAndroid Build Coastguard Worker MCInst Inst;
1151*9880d681SAndroid Build Coastguard Worker
1152*9880d681SAndroid Build Coastguard Worker switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
1153*9880d681SAndroid Build Coastguard Worker default: break;
1154*9880d681SAndroid Build Coastguard Worker case Match_Success:
1155*9880d681SAndroid Build Coastguard Worker Inst.setLoc(IDLoc);
1156*9880d681SAndroid Build Coastguard Worker Out.EmitInstruction(Inst, getSTI());
1157*9880d681SAndroid Build Coastguard Worker return false;
1158*9880d681SAndroid Build Coastguard Worker case Match_MissingFeature:
1159*9880d681SAndroid Build Coastguard Worker return Error(IDLoc, "instruction not supported on this GPU");
1160*9880d681SAndroid Build Coastguard Worker
1161*9880d681SAndroid Build Coastguard Worker case Match_MnemonicFail:
1162*9880d681SAndroid Build Coastguard Worker return Error(IDLoc, "unrecognized instruction mnemonic");
1163*9880d681SAndroid Build Coastguard Worker
1164*9880d681SAndroid Build Coastguard Worker case Match_InvalidOperand: {
1165*9880d681SAndroid Build Coastguard Worker SMLoc ErrorLoc = IDLoc;
1166*9880d681SAndroid Build Coastguard Worker if (ErrorInfo != ~0ULL) {
1167*9880d681SAndroid Build Coastguard Worker if (ErrorInfo >= Operands.size()) {
1168*9880d681SAndroid Build Coastguard Worker return Error(IDLoc, "too few operands for instruction");
1169*9880d681SAndroid Build Coastguard Worker }
1170*9880d681SAndroid Build Coastguard Worker ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
1171*9880d681SAndroid Build Coastguard Worker if (ErrorLoc == SMLoc())
1172*9880d681SAndroid Build Coastguard Worker ErrorLoc = IDLoc;
1173*9880d681SAndroid Build Coastguard Worker }
1174*9880d681SAndroid Build Coastguard Worker return Error(ErrorLoc, "invalid operand for instruction");
1175*9880d681SAndroid Build Coastguard Worker }
1176*9880d681SAndroid Build Coastguard Worker case Match_PreferE32:
1177*9880d681SAndroid Build Coastguard Worker return Error(IDLoc, "internal error: instruction without _e64 suffix "
1178*9880d681SAndroid Build Coastguard Worker "should be encoded as e32");
1179*9880d681SAndroid Build Coastguard Worker }
1180*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Implement any new match types added!");
1181*9880d681SAndroid Build Coastguard Worker }
1182*9880d681SAndroid Build Coastguard Worker
ParseDirectiveMajorMinor(uint32_t & Major,uint32_t & Minor)1183*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseDirectiveMajorMinor(uint32_t &Major,
1184*9880d681SAndroid Build Coastguard Worker uint32_t &Minor) {
1185*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
1186*9880d681SAndroid Build Coastguard Worker return TokError("invalid major version");
1187*9880d681SAndroid Build Coastguard Worker
1188*9880d681SAndroid Build Coastguard Worker Major = getLexer().getTok().getIntVal();
1189*9880d681SAndroid Build Coastguard Worker Lex();
1190*9880d681SAndroid Build Coastguard Worker
1191*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Comma))
1192*9880d681SAndroid Build Coastguard Worker return TokError("minor version number required, comma expected");
1193*9880d681SAndroid Build Coastguard Worker Lex();
1194*9880d681SAndroid Build Coastguard Worker
1195*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
1196*9880d681SAndroid Build Coastguard Worker return TokError("invalid minor version");
1197*9880d681SAndroid Build Coastguard Worker
1198*9880d681SAndroid Build Coastguard Worker Minor = getLexer().getTok().getIntVal();
1199*9880d681SAndroid Build Coastguard Worker Lex();
1200*9880d681SAndroid Build Coastguard Worker
1201*9880d681SAndroid Build Coastguard Worker return false;
1202*9880d681SAndroid Build Coastguard Worker }
1203*9880d681SAndroid Build Coastguard Worker
ParseDirectiveHSACodeObjectVersion()1204*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectVersion() {
1205*9880d681SAndroid Build Coastguard Worker
1206*9880d681SAndroid Build Coastguard Worker uint32_t Major;
1207*9880d681SAndroid Build Coastguard Worker uint32_t Minor;
1208*9880d681SAndroid Build Coastguard Worker
1209*9880d681SAndroid Build Coastguard Worker if (ParseDirectiveMajorMinor(Major, Minor))
1210*9880d681SAndroid Build Coastguard Worker return true;
1211*9880d681SAndroid Build Coastguard Worker
1212*9880d681SAndroid Build Coastguard Worker getTargetStreamer().EmitDirectiveHSACodeObjectVersion(Major, Minor);
1213*9880d681SAndroid Build Coastguard Worker return false;
1214*9880d681SAndroid Build Coastguard Worker }
1215*9880d681SAndroid Build Coastguard Worker
ParseDirectiveHSACodeObjectISA()1216*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectISA() {
1217*9880d681SAndroid Build Coastguard Worker
1218*9880d681SAndroid Build Coastguard Worker uint32_t Major;
1219*9880d681SAndroid Build Coastguard Worker uint32_t Minor;
1220*9880d681SAndroid Build Coastguard Worker uint32_t Stepping;
1221*9880d681SAndroid Build Coastguard Worker StringRef VendorName;
1222*9880d681SAndroid Build Coastguard Worker StringRef ArchName;
1223*9880d681SAndroid Build Coastguard Worker
1224*9880d681SAndroid Build Coastguard Worker // If this directive has no arguments, then use the ISA version for the
1225*9880d681SAndroid Build Coastguard Worker // targeted GPU.
1226*9880d681SAndroid Build Coastguard Worker if (getLexer().is(AsmToken::EndOfStatement)) {
1227*9880d681SAndroid Build Coastguard Worker AMDGPU::IsaVersion Isa = AMDGPU::getIsaVersion(getSTI().getFeatureBits());
1228*9880d681SAndroid Build Coastguard Worker getTargetStreamer().EmitDirectiveHSACodeObjectISA(Isa.Major, Isa.Minor,
1229*9880d681SAndroid Build Coastguard Worker Isa.Stepping,
1230*9880d681SAndroid Build Coastguard Worker "AMD", "AMDGPU");
1231*9880d681SAndroid Build Coastguard Worker return false;
1232*9880d681SAndroid Build Coastguard Worker }
1233*9880d681SAndroid Build Coastguard Worker
1234*9880d681SAndroid Build Coastguard Worker
1235*9880d681SAndroid Build Coastguard Worker if (ParseDirectiveMajorMinor(Major, Minor))
1236*9880d681SAndroid Build Coastguard Worker return true;
1237*9880d681SAndroid Build Coastguard Worker
1238*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Comma))
1239*9880d681SAndroid Build Coastguard Worker return TokError("stepping version number required, comma expected");
1240*9880d681SAndroid Build Coastguard Worker Lex();
1241*9880d681SAndroid Build Coastguard Worker
1242*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
1243*9880d681SAndroid Build Coastguard Worker return TokError("invalid stepping version");
1244*9880d681SAndroid Build Coastguard Worker
1245*9880d681SAndroid Build Coastguard Worker Stepping = getLexer().getTok().getIntVal();
1246*9880d681SAndroid Build Coastguard Worker Lex();
1247*9880d681SAndroid Build Coastguard Worker
1248*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Comma))
1249*9880d681SAndroid Build Coastguard Worker return TokError("vendor name required, comma expected");
1250*9880d681SAndroid Build Coastguard Worker Lex();
1251*9880d681SAndroid Build Coastguard Worker
1252*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::String))
1253*9880d681SAndroid Build Coastguard Worker return TokError("invalid vendor name");
1254*9880d681SAndroid Build Coastguard Worker
1255*9880d681SAndroid Build Coastguard Worker VendorName = getLexer().getTok().getStringContents();
1256*9880d681SAndroid Build Coastguard Worker Lex();
1257*9880d681SAndroid Build Coastguard Worker
1258*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Comma))
1259*9880d681SAndroid Build Coastguard Worker return TokError("arch name required, comma expected");
1260*9880d681SAndroid Build Coastguard Worker Lex();
1261*9880d681SAndroid Build Coastguard Worker
1262*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::String))
1263*9880d681SAndroid Build Coastguard Worker return TokError("invalid arch name");
1264*9880d681SAndroid Build Coastguard Worker
1265*9880d681SAndroid Build Coastguard Worker ArchName = getLexer().getTok().getStringContents();
1266*9880d681SAndroid Build Coastguard Worker Lex();
1267*9880d681SAndroid Build Coastguard Worker
1268*9880d681SAndroid Build Coastguard Worker getTargetStreamer().EmitDirectiveHSACodeObjectISA(Major, Minor, Stepping,
1269*9880d681SAndroid Build Coastguard Worker VendorName, ArchName);
1270*9880d681SAndroid Build Coastguard Worker return false;
1271*9880d681SAndroid Build Coastguard Worker }
1272*9880d681SAndroid Build Coastguard Worker
ParseAMDKernelCodeTValue(StringRef ID,amd_kernel_code_t & Header)1273*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef ID,
1274*9880d681SAndroid Build Coastguard Worker amd_kernel_code_t &Header) {
1275*9880d681SAndroid Build Coastguard Worker SmallString<40> ErrStr;
1276*9880d681SAndroid Build Coastguard Worker raw_svector_ostream Err(ErrStr);
1277*9880d681SAndroid Build Coastguard Worker if (!parseAmdKernelCodeField(ID, getParser(), Header, Err)) {
1278*9880d681SAndroid Build Coastguard Worker return TokError(Err.str());
1279*9880d681SAndroid Build Coastguard Worker }
1280*9880d681SAndroid Build Coastguard Worker Lex();
1281*9880d681SAndroid Build Coastguard Worker return false;
1282*9880d681SAndroid Build Coastguard Worker }
1283*9880d681SAndroid Build Coastguard Worker
ParseDirectiveAMDKernelCodeT()1284*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
1285*9880d681SAndroid Build Coastguard Worker
1286*9880d681SAndroid Build Coastguard Worker amd_kernel_code_t Header;
1287*9880d681SAndroid Build Coastguard Worker AMDGPU::initDefaultAMDKernelCodeT(Header, getSTI().getFeatureBits());
1288*9880d681SAndroid Build Coastguard Worker
1289*9880d681SAndroid Build Coastguard Worker while (true) {
1290*9880d681SAndroid Build Coastguard Worker
1291*9880d681SAndroid Build Coastguard Worker // Lex EndOfStatement. This is in a while loop, because lexing a comment
1292*9880d681SAndroid Build Coastguard Worker // will set the current token to EndOfStatement.
1293*9880d681SAndroid Build Coastguard Worker while(getLexer().is(AsmToken::EndOfStatement))
1294*9880d681SAndroid Build Coastguard Worker Lex();
1295*9880d681SAndroid Build Coastguard Worker
1296*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Identifier))
1297*9880d681SAndroid Build Coastguard Worker return TokError("expected value identifier or .end_amd_kernel_code_t");
1298*9880d681SAndroid Build Coastguard Worker
1299*9880d681SAndroid Build Coastguard Worker StringRef ID = getLexer().getTok().getIdentifier();
1300*9880d681SAndroid Build Coastguard Worker Lex();
1301*9880d681SAndroid Build Coastguard Worker
1302*9880d681SAndroid Build Coastguard Worker if (ID == ".end_amd_kernel_code_t")
1303*9880d681SAndroid Build Coastguard Worker break;
1304*9880d681SAndroid Build Coastguard Worker
1305*9880d681SAndroid Build Coastguard Worker if (ParseAMDKernelCodeTValue(ID, Header))
1306*9880d681SAndroid Build Coastguard Worker return true;
1307*9880d681SAndroid Build Coastguard Worker }
1308*9880d681SAndroid Build Coastguard Worker
1309*9880d681SAndroid Build Coastguard Worker getTargetStreamer().EmitAMDKernelCodeT(Header);
1310*9880d681SAndroid Build Coastguard Worker
1311*9880d681SAndroid Build Coastguard Worker return false;
1312*9880d681SAndroid Build Coastguard Worker }
1313*9880d681SAndroid Build Coastguard Worker
ParseSectionDirectiveHSAText()1314*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseSectionDirectiveHSAText() {
1315*9880d681SAndroid Build Coastguard Worker getParser().getStreamer().SwitchSection(
1316*9880d681SAndroid Build Coastguard Worker AMDGPU::getHSATextSection(getContext()));
1317*9880d681SAndroid Build Coastguard Worker return false;
1318*9880d681SAndroid Build Coastguard Worker }
1319*9880d681SAndroid Build Coastguard Worker
ParseDirectiveAMDGPUHsaKernel()1320*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
1321*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Identifier))
1322*9880d681SAndroid Build Coastguard Worker return TokError("expected symbol name");
1323*9880d681SAndroid Build Coastguard Worker
1324*9880d681SAndroid Build Coastguard Worker StringRef KernelName = Parser.getTok().getString();
1325*9880d681SAndroid Build Coastguard Worker
1326*9880d681SAndroid Build Coastguard Worker getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
1327*9880d681SAndroid Build Coastguard Worker ELF::STT_AMDGPU_HSA_KERNEL);
1328*9880d681SAndroid Build Coastguard Worker Lex();
1329*9880d681SAndroid Build Coastguard Worker return false;
1330*9880d681SAndroid Build Coastguard Worker }
1331*9880d681SAndroid Build Coastguard Worker
ParseDirectiveAMDGPUHsaModuleGlobal()1332*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaModuleGlobal() {
1333*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Identifier))
1334*9880d681SAndroid Build Coastguard Worker return TokError("expected symbol name");
1335*9880d681SAndroid Build Coastguard Worker
1336*9880d681SAndroid Build Coastguard Worker StringRef GlobalName = Parser.getTok().getIdentifier();
1337*9880d681SAndroid Build Coastguard Worker
1338*9880d681SAndroid Build Coastguard Worker getTargetStreamer().EmitAMDGPUHsaModuleScopeGlobal(GlobalName);
1339*9880d681SAndroid Build Coastguard Worker Lex();
1340*9880d681SAndroid Build Coastguard Worker return false;
1341*9880d681SAndroid Build Coastguard Worker }
1342*9880d681SAndroid Build Coastguard Worker
ParseDirectiveAMDGPUHsaProgramGlobal()1343*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaProgramGlobal() {
1344*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Identifier))
1345*9880d681SAndroid Build Coastguard Worker return TokError("expected symbol name");
1346*9880d681SAndroid Build Coastguard Worker
1347*9880d681SAndroid Build Coastguard Worker StringRef GlobalName = Parser.getTok().getIdentifier();
1348*9880d681SAndroid Build Coastguard Worker
1349*9880d681SAndroid Build Coastguard Worker getTargetStreamer().EmitAMDGPUHsaProgramScopeGlobal(GlobalName);
1350*9880d681SAndroid Build Coastguard Worker Lex();
1351*9880d681SAndroid Build Coastguard Worker return false;
1352*9880d681SAndroid Build Coastguard Worker }
1353*9880d681SAndroid Build Coastguard Worker
ParseSectionDirectiveHSADataGlobalAgent()1354*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseSectionDirectiveHSADataGlobalAgent() {
1355*9880d681SAndroid Build Coastguard Worker getParser().getStreamer().SwitchSection(
1356*9880d681SAndroid Build Coastguard Worker AMDGPU::getHSADataGlobalAgentSection(getContext()));
1357*9880d681SAndroid Build Coastguard Worker return false;
1358*9880d681SAndroid Build Coastguard Worker }
1359*9880d681SAndroid Build Coastguard Worker
ParseSectionDirectiveHSADataGlobalProgram()1360*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseSectionDirectiveHSADataGlobalProgram() {
1361*9880d681SAndroid Build Coastguard Worker getParser().getStreamer().SwitchSection(
1362*9880d681SAndroid Build Coastguard Worker AMDGPU::getHSADataGlobalProgramSection(getContext()));
1363*9880d681SAndroid Build Coastguard Worker return false;
1364*9880d681SAndroid Build Coastguard Worker }
1365*9880d681SAndroid Build Coastguard Worker
ParseSectionDirectiveHSARodataReadonlyAgent()1366*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseSectionDirectiveHSARodataReadonlyAgent() {
1367*9880d681SAndroid Build Coastguard Worker getParser().getStreamer().SwitchSection(
1368*9880d681SAndroid Build Coastguard Worker AMDGPU::getHSARodataReadonlyAgentSection(getContext()));
1369*9880d681SAndroid Build Coastguard Worker return false;
1370*9880d681SAndroid Build Coastguard Worker }
1371*9880d681SAndroid Build Coastguard Worker
ParseDirective(AsmToken DirectiveID)1372*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
1373*9880d681SAndroid Build Coastguard Worker StringRef IDVal = DirectiveID.getString();
1374*9880d681SAndroid Build Coastguard Worker
1375*9880d681SAndroid Build Coastguard Worker if (IDVal == ".hsa_code_object_version")
1376*9880d681SAndroid Build Coastguard Worker return ParseDirectiveHSACodeObjectVersion();
1377*9880d681SAndroid Build Coastguard Worker
1378*9880d681SAndroid Build Coastguard Worker if (IDVal == ".hsa_code_object_isa")
1379*9880d681SAndroid Build Coastguard Worker return ParseDirectiveHSACodeObjectISA();
1380*9880d681SAndroid Build Coastguard Worker
1381*9880d681SAndroid Build Coastguard Worker if (IDVal == ".amd_kernel_code_t")
1382*9880d681SAndroid Build Coastguard Worker return ParseDirectiveAMDKernelCodeT();
1383*9880d681SAndroid Build Coastguard Worker
1384*9880d681SAndroid Build Coastguard Worker if (IDVal == ".hsatext")
1385*9880d681SAndroid Build Coastguard Worker return ParseSectionDirectiveHSAText();
1386*9880d681SAndroid Build Coastguard Worker
1387*9880d681SAndroid Build Coastguard Worker if (IDVal == ".amdgpu_hsa_kernel")
1388*9880d681SAndroid Build Coastguard Worker return ParseDirectiveAMDGPUHsaKernel();
1389*9880d681SAndroid Build Coastguard Worker
1390*9880d681SAndroid Build Coastguard Worker if (IDVal == ".amdgpu_hsa_module_global")
1391*9880d681SAndroid Build Coastguard Worker return ParseDirectiveAMDGPUHsaModuleGlobal();
1392*9880d681SAndroid Build Coastguard Worker
1393*9880d681SAndroid Build Coastguard Worker if (IDVal == ".amdgpu_hsa_program_global")
1394*9880d681SAndroid Build Coastguard Worker return ParseDirectiveAMDGPUHsaProgramGlobal();
1395*9880d681SAndroid Build Coastguard Worker
1396*9880d681SAndroid Build Coastguard Worker if (IDVal == ".hsadata_global_agent")
1397*9880d681SAndroid Build Coastguard Worker return ParseSectionDirectiveHSADataGlobalAgent();
1398*9880d681SAndroid Build Coastguard Worker
1399*9880d681SAndroid Build Coastguard Worker if (IDVal == ".hsadata_global_program")
1400*9880d681SAndroid Build Coastguard Worker return ParseSectionDirectiveHSADataGlobalProgram();
1401*9880d681SAndroid Build Coastguard Worker
1402*9880d681SAndroid Build Coastguard Worker if (IDVal == ".hsarodata_readonly_agent")
1403*9880d681SAndroid Build Coastguard Worker return ParseSectionDirectiveHSARodataReadonlyAgent();
1404*9880d681SAndroid Build Coastguard Worker
1405*9880d681SAndroid Build Coastguard Worker return true;
1406*9880d681SAndroid Build Coastguard Worker }
1407*9880d681SAndroid Build Coastguard Worker
subtargetHasRegister(const MCRegisterInfo & MRI,unsigned RegNo) const1408*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::subtargetHasRegister(const MCRegisterInfo &MRI,
1409*9880d681SAndroid Build Coastguard Worker unsigned RegNo) const {
1410*9880d681SAndroid Build Coastguard Worker if (isCI())
1411*9880d681SAndroid Build Coastguard Worker return true;
1412*9880d681SAndroid Build Coastguard Worker
1413*9880d681SAndroid Build Coastguard Worker if (isSI()) {
1414*9880d681SAndroid Build Coastguard Worker // No flat_scr
1415*9880d681SAndroid Build Coastguard Worker switch (RegNo) {
1416*9880d681SAndroid Build Coastguard Worker case AMDGPU::FLAT_SCR:
1417*9880d681SAndroid Build Coastguard Worker case AMDGPU::FLAT_SCR_LO:
1418*9880d681SAndroid Build Coastguard Worker case AMDGPU::FLAT_SCR_HI:
1419*9880d681SAndroid Build Coastguard Worker return false;
1420*9880d681SAndroid Build Coastguard Worker default:
1421*9880d681SAndroid Build Coastguard Worker return true;
1422*9880d681SAndroid Build Coastguard Worker }
1423*9880d681SAndroid Build Coastguard Worker }
1424*9880d681SAndroid Build Coastguard Worker
1425*9880d681SAndroid Build Coastguard Worker // VI only has 102 SGPRs, so make sure we aren't trying to use the 2 more that
1426*9880d681SAndroid Build Coastguard Worker // SI/CI have.
1427*9880d681SAndroid Build Coastguard Worker for (MCRegAliasIterator R(AMDGPU::SGPR102_SGPR103, &MRI, true);
1428*9880d681SAndroid Build Coastguard Worker R.isValid(); ++R) {
1429*9880d681SAndroid Build Coastguard Worker if (*R == RegNo)
1430*9880d681SAndroid Build Coastguard Worker return false;
1431*9880d681SAndroid Build Coastguard Worker }
1432*9880d681SAndroid Build Coastguard Worker
1433*9880d681SAndroid Build Coastguard Worker return true;
1434*9880d681SAndroid Build Coastguard Worker }
1435*9880d681SAndroid Build Coastguard Worker
1436*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseOperand(OperandVector & Operands,StringRef Mnemonic)1437*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1438*9880d681SAndroid Build Coastguard Worker
1439*9880d681SAndroid Build Coastguard Worker // Try to parse with a custom parser
1440*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1441*9880d681SAndroid Build Coastguard Worker
1442*9880d681SAndroid Build Coastguard Worker // If we successfully parsed the operand or if there as an error parsing,
1443*9880d681SAndroid Build Coastguard Worker // we are done.
1444*9880d681SAndroid Build Coastguard Worker //
1445*9880d681SAndroid Build Coastguard Worker // If we are parsing after we reach EndOfStatement then this means we
1446*9880d681SAndroid Build Coastguard Worker // are appending default values to the Operands list. This is only done
1447*9880d681SAndroid Build Coastguard Worker // by custom parser, so we shouldn't continue on to the generic parsing.
1448*9880d681SAndroid Build Coastguard Worker if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail ||
1449*9880d681SAndroid Build Coastguard Worker getLexer().is(AsmToken::EndOfStatement))
1450*9880d681SAndroid Build Coastguard Worker return ResTy;
1451*9880d681SAndroid Build Coastguard Worker
1452*9880d681SAndroid Build Coastguard Worker ResTy = parseRegOrImm(Operands);
1453*9880d681SAndroid Build Coastguard Worker
1454*9880d681SAndroid Build Coastguard Worker if (ResTy == MatchOperand_Success)
1455*9880d681SAndroid Build Coastguard Worker return ResTy;
1456*9880d681SAndroid Build Coastguard Worker
1457*9880d681SAndroid Build Coastguard Worker if (getLexer().getKind() == AsmToken::Identifier) {
1458*9880d681SAndroid Build Coastguard Worker // If this identifier is a symbol, we want to create an expression for it.
1459*9880d681SAndroid Build Coastguard Worker // It is a little difficult to distinguish between a symbol name, and
1460*9880d681SAndroid Build Coastguard Worker // an instruction flag like 'gds'. In order to do this, we parse
1461*9880d681SAndroid Build Coastguard Worker // all tokens as expressions and then treate the symbol name as the token
1462*9880d681SAndroid Build Coastguard Worker // string when we want to interpret the operand as a token.
1463*9880d681SAndroid Build Coastguard Worker const auto &Tok = Parser.getTok();
1464*9880d681SAndroid Build Coastguard Worker SMLoc S = Tok.getLoc();
1465*9880d681SAndroid Build Coastguard Worker const MCExpr *Expr = nullptr;
1466*9880d681SAndroid Build Coastguard Worker if (!Parser.parseExpression(Expr)) {
1467*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateExpr(Expr, S));
1468*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
1469*9880d681SAndroid Build Coastguard Worker }
1470*9880d681SAndroid Build Coastguard Worker
1471*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateToken(Tok.getString(), Tok.getLoc()));
1472*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1473*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
1474*9880d681SAndroid Build Coastguard Worker }
1475*9880d681SAndroid Build Coastguard Worker return MatchOperand_NoMatch;
1476*9880d681SAndroid Build Coastguard Worker }
1477*9880d681SAndroid Build Coastguard Worker
parseMnemonicSuffix(StringRef Name)1478*9880d681SAndroid Build Coastguard Worker StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
1479*9880d681SAndroid Build Coastguard Worker // Clear any forced encodings from the previous instruction.
1480*9880d681SAndroid Build Coastguard Worker setForcedEncodingSize(0);
1481*9880d681SAndroid Build Coastguard Worker setForcedDPP(false);
1482*9880d681SAndroid Build Coastguard Worker setForcedSDWA(false);
1483*9880d681SAndroid Build Coastguard Worker
1484*9880d681SAndroid Build Coastguard Worker if (Name.endswith("_e64")) {
1485*9880d681SAndroid Build Coastguard Worker setForcedEncodingSize(64);
1486*9880d681SAndroid Build Coastguard Worker return Name.substr(0, Name.size() - 4);
1487*9880d681SAndroid Build Coastguard Worker } else if (Name.endswith("_e32")) {
1488*9880d681SAndroid Build Coastguard Worker setForcedEncodingSize(32);
1489*9880d681SAndroid Build Coastguard Worker return Name.substr(0, Name.size() - 4);
1490*9880d681SAndroid Build Coastguard Worker } else if (Name.endswith("_dpp")) {
1491*9880d681SAndroid Build Coastguard Worker setForcedDPP(true);
1492*9880d681SAndroid Build Coastguard Worker return Name.substr(0, Name.size() - 4);
1493*9880d681SAndroid Build Coastguard Worker } else if (Name.endswith("_sdwa")) {
1494*9880d681SAndroid Build Coastguard Worker setForcedSDWA(true);
1495*9880d681SAndroid Build Coastguard Worker return Name.substr(0, Name.size() - 5);
1496*9880d681SAndroid Build Coastguard Worker }
1497*9880d681SAndroid Build Coastguard Worker return Name;
1498*9880d681SAndroid Build Coastguard Worker }
1499*9880d681SAndroid Build Coastguard Worker
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)1500*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1501*9880d681SAndroid Build Coastguard Worker StringRef Name,
1502*9880d681SAndroid Build Coastguard Worker SMLoc NameLoc, OperandVector &Operands) {
1503*9880d681SAndroid Build Coastguard Worker // Add the instruction mnemonic
1504*9880d681SAndroid Build Coastguard Worker Name = parseMnemonicSuffix(Name);
1505*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateToken(Name, NameLoc));
1506*9880d681SAndroid Build Coastguard Worker
1507*9880d681SAndroid Build Coastguard Worker while (!getLexer().is(AsmToken::EndOfStatement)) {
1508*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy Res = parseOperand(Operands, Name);
1509*9880d681SAndroid Build Coastguard Worker
1510*9880d681SAndroid Build Coastguard Worker // Eat the comma or space if there is one.
1511*9880d681SAndroid Build Coastguard Worker if (getLexer().is(AsmToken::Comma))
1512*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1513*9880d681SAndroid Build Coastguard Worker
1514*9880d681SAndroid Build Coastguard Worker switch (Res) {
1515*9880d681SAndroid Build Coastguard Worker case MatchOperand_Success: break;
1516*9880d681SAndroid Build Coastguard Worker case MatchOperand_ParseFail:
1517*9880d681SAndroid Build Coastguard Worker Error(getLexer().getLoc(), "failed parsing operand.");
1518*9880d681SAndroid Build Coastguard Worker while (!getLexer().is(AsmToken::EndOfStatement)) {
1519*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1520*9880d681SAndroid Build Coastguard Worker }
1521*9880d681SAndroid Build Coastguard Worker return true;
1522*9880d681SAndroid Build Coastguard Worker case MatchOperand_NoMatch:
1523*9880d681SAndroid Build Coastguard Worker Error(getLexer().getLoc(), "not a valid operand.");
1524*9880d681SAndroid Build Coastguard Worker while (!getLexer().is(AsmToken::EndOfStatement)) {
1525*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1526*9880d681SAndroid Build Coastguard Worker }
1527*9880d681SAndroid Build Coastguard Worker return true;
1528*9880d681SAndroid Build Coastguard Worker }
1529*9880d681SAndroid Build Coastguard Worker }
1530*9880d681SAndroid Build Coastguard Worker
1531*9880d681SAndroid Build Coastguard Worker return false;
1532*9880d681SAndroid Build Coastguard Worker }
1533*9880d681SAndroid Build Coastguard Worker
1534*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1535*9880d681SAndroid Build Coastguard Worker // Utility functions
1536*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1537*9880d681SAndroid Build Coastguard Worker
1538*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseIntWithPrefix(const char * Prefix,int64_t & Int)1539*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix, int64_t &Int) {
1540*9880d681SAndroid Build Coastguard Worker switch(getLexer().getKind()) {
1541*9880d681SAndroid Build Coastguard Worker default: return MatchOperand_NoMatch;
1542*9880d681SAndroid Build Coastguard Worker case AsmToken::Identifier: {
1543*9880d681SAndroid Build Coastguard Worker StringRef Name = Parser.getTok().getString();
1544*9880d681SAndroid Build Coastguard Worker if (!Name.equals(Prefix)) {
1545*9880d681SAndroid Build Coastguard Worker return MatchOperand_NoMatch;
1546*9880d681SAndroid Build Coastguard Worker }
1547*9880d681SAndroid Build Coastguard Worker
1548*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1549*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Colon))
1550*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1551*9880d681SAndroid Build Coastguard Worker
1552*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1553*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
1554*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1555*9880d681SAndroid Build Coastguard Worker
1556*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(Int))
1557*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1558*9880d681SAndroid Build Coastguard Worker break;
1559*9880d681SAndroid Build Coastguard Worker }
1560*9880d681SAndroid Build Coastguard Worker }
1561*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
1562*9880d681SAndroid Build Coastguard Worker }
1563*9880d681SAndroid Build Coastguard Worker
1564*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseIntWithPrefix(const char * Prefix,OperandVector & Operands,enum AMDGPUOperand::ImmTy ImmTy,bool (* ConvertResult)(int64_t &))1565*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix, OperandVector &Operands,
1566*9880d681SAndroid Build Coastguard Worker enum AMDGPUOperand::ImmTy ImmTy,
1567*9880d681SAndroid Build Coastguard Worker bool (*ConvertResult)(int64_t&)) {
1568*9880d681SAndroid Build Coastguard Worker
1569*9880d681SAndroid Build Coastguard Worker SMLoc S = Parser.getTok().getLoc();
1570*9880d681SAndroid Build Coastguard Worker int64_t Value = 0;
1571*9880d681SAndroid Build Coastguard Worker
1572*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy Res = parseIntWithPrefix(Prefix, Value);
1573*9880d681SAndroid Build Coastguard Worker if (Res != MatchOperand_Success)
1574*9880d681SAndroid Build Coastguard Worker return Res;
1575*9880d681SAndroid Build Coastguard Worker
1576*9880d681SAndroid Build Coastguard Worker if (ConvertResult && !ConvertResult(Value)) {
1577*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1578*9880d681SAndroid Build Coastguard Worker }
1579*9880d681SAndroid Build Coastguard Worker
1580*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateImm(Value, S, ImmTy));
1581*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
1582*9880d681SAndroid Build Coastguard Worker }
1583*9880d681SAndroid Build Coastguard Worker
1584*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseNamedBit(const char * Name,OperandVector & Operands,enum AMDGPUOperand::ImmTy ImmTy)1585*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseNamedBit(const char *Name, OperandVector &Operands,
1586*9880d681SAndroid Build Coastguard Worker enum AMDGPUOperand::ImmTy ImmTy) {
1587*9880d681SAndroid Build Coastguard Worker int64_t Bit = 0;
1588*9880d681SAndroid Build Coastguard Worker SMLoc S = Parser.getTok().getLoc();
1589*9880d681SAndroid Build Coastguard Worker
1590*9880d681SAndroid Build Coastguard Worker // We are at the end of the statement, and this is a default argument, so
1591*9880d681SAndroid Build Coastguard Worker // use a default value.
1592*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::EndOfStatement)) {
1593*9880d681SAndroid Build Coastguard Worker switch(getLexer().getKind()) {
1594*9880d681SAndroid Build Coastguard Worker case AsmToken::Identifier: {
1595*9880d681SAndroid Build Coastguard Worker StringRef Tok = Parser.getTok().getString();
1596*9880d681SAndroid Build Coastguard Worker if (Tok == Name) {
1597*9880d681SAndroid Build Coastguard Worker Bit = 1;
1598*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1599*9880d681SAndroid Build Coastguard Worker } else if (Tok.startswith("no") && Tok.endswith(Name)) {
1600*9880d681SAndroid Build Coastguard Worker Bit = 0;
1601*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1602*9880d681SAndroid Build Coastguard Worker } else {
1603*9880d681SAndroid Build Coastguard Worker return MatchOperand_NoMatch;
1604*9880d681SAndroid Build Coastguard Worker }
1605*9880d681SAndroid Build Coastguard Worker break;
1606*9880d681SAndroid Build Coastguard Worker }
1607*9880d681SAndroid Build Coastguard Worker default:
1608*9880d681SAndroid Build Coastguard Worker return MatchOperand_NoMatch;
1609*9880d681SAndroid Build Coastguard Worker }
1610*9880d681SAndroid Build Coastguard Worker }
1611*9880d681SAndroid Build Coastguard Worker
1612*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateImm(Bit, S, ImmTy));
1613*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
1614*9880d681SAndroid Build Coastguard Worker }
1615*9880d681SAndroid Build Coastguard Worker
1616*9880d681SAndroid Build Coastguard Worker typedef std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalImmIndexMap;
1617*9880d681SAndroid Build Coastguard Worker
addOptionalImmOperand(MCInst & Inst,const OperandVector & Operands,OptionalImmIndexMap & OptionalIdx,enum AMDGPUOperand::ImmTy ImmT,int64_t Default=0)1618*9880d681SAndroid Build Coastguard Worker void addOptionalImmOperand(MCInst& Inst, const OperandVector& Operands,
1619*9880d681SAndroid Build Coastguard Worker OptionalImmIndexMap& OptionalIdx,
1620*9880d681SAndroid Build Coastguard Worker enum AMDGPUOperand::ImmTy ImmT, int64_t Default = 0) {
1621*9880d681SAndroid Build Coastguard Worker auto i = OptionalIdx.find(ImmT);
1622*9880d681SAndroid Build Coastguard Worker if (i != OptionalIdx.end()) {
1623*9880d681SAndroid Build Coastguard Worker unsigned Idx = i->second;
1624*9880d681SAndroid Build Coastguard Worker ((AMDGPUOperand &)*Operands[Idx]).addImmOperands(Inst, 1);
1625*9880d681SAndroid Build Coastguard Worker } else {
1626*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(Default));
1627*9880d681SAndroid Build Coastguard Worker }
1628*9880d681SAndroid Build Coastguard Worker }
1629*9880d681SAndroid Build Coastguard Worker
1630*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseStringWithPrefix(StringRef Prefix,StringRef & Value)1631*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix, StringRef &Value) {
1632*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Identifier)) {
1633*9880d681SAndroid Build Coastguard Worker return MatchOperand_NoMatch;
1634*9880d681SAndroid Build Coastguard Worker }
1635*9880d681SAndroid Build Coastguard Worker StringRef Tok = Parser.getTok().getString();
1636*9880d681SAndroid Build Coastguard Worker if (Tok != Prefix) {
1637*9880d681SAndroid Build Coastguard Worker return MatchOperand_NoMatch;
1638*9880d681SAndroid Build Coastguard Worker }
1639*9880d681SAndroid Build Coastguard Worker
1640*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1641*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Colon)) {
1642*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1643*9880d681SAndroid Build Coastguard Worker }
1644*9880d681SAndroid Build Coastguard Worker
1645*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1646*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Identifier)) {
1647*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1648*9880d681SAndroid Build Coastguard Worker }
1649*9880d681SAndroid Build Coastguard Worker
1650*9880d681SAndroid Build Coastguard Worker Value = Parser.getTok().getString();
1651*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
1652*9880d681SAndroid Build Coastguard Worker }
1653*9880d681SAndroid Build Coastguard Worker
1654*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1655*9880d681SAndroid Build Coastguard Worker // ds
1656*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1657*9880d681SAndroid Build Coastguard Worker
cvtDSOffset01(MCInst & Inst,const OperandVector & Operands)1658*9880d681SAndroid Build Coastguard Worker void AMDGPUAsmParser::cvtDSOffset01(MCInst &Inst,
1659*9880d681SAndroid Build Coastguard Worker const OperandVector &Operands) {
1660*9880d681SAndroid Build Coastguard Worker
1661*9880d681SAndroid Build Coastguard Worker OptionalImmIndexMap OptionalIdx;
1662*9880d681SAndroid Build Coastguard Worker
1663*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
1664*9880d681SAndroid Build Coastguard Worker AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
1665*9880d681SAndroid Build Coastguard Worker
1666*9880d681SAndroid Build Coastguard Worker // Add the register arguments
1667*9880d681SAndroid Build Coastguard Worker if (Op.isReg()) {
1668*9880d681SAndroid Build Coastguard Worker Op.addRegOperands(Inst, 1);
1669*9880d681SAndroid Build Coastguard Worker continue;
1670*9880d681SAndroid Build Coastguard Worker }
1671*9880d681SAndroid Build Coastguard Worker
1672*9880d681SAndroid Build Coastguard Worker // Handle optional arguments
1673*9880d681SAndroid Build Coastguard Worker OptionalIdx[Op.getImmTy()] = i;
1674*9880d681SAndroid Build Coastguard Worker }
1675*9880d681SAndroid Build Coastguard Worker
1676*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOffset0);
1677*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOffset1);
1678*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGDS);
1679*9880d681SAndroid Build Coastguard Worker
1680*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(AMDGPU::M0)); // m0
1681*9880d681SAndroid Build Coastguard Worker }
1682*9880d681SAndroid Build Coastguard Worker
cvtDS(MCInst & Inst,const OperandVector & Operands)1683*9880d681SAndroid Build Coastguard Worker void AMDGPUAsmParser::cvtDS(MCInst &Inst, const OperandVector &Operands) {
1684*9880d681SAndroid Build Coastguard Worker
1685*9880d681SAndroid Build Coastguard Worker std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
1686*9880d681SAndroid Build Coastguard Worker bool GDSOnly = false;
1687*9880d681SAndroid Build Coastguard Worker
1688*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
1689*9880d681SAndroid Build Coastguard Worker AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
1690*9880d681SAndroid Build Coastguard Worker
1691*9880d681SAndroid Build Coastguard Worker // Add the register arguments
1692*9880d681SAndroid Build Coastguard Worker if (Op.isReg()) {
1693*9880d681SAndroid Build Coastguard Worker Op.addRegOperands(Inst, 1);
1694*9880d681SAndroid Build Coastguard Worker continue;
1695*9880d681SAndroid Build Coastguard Worker }
1696*9880d681SAndroid Build Coastguard Worker
1697*9880d681SAndroid Build Coastguard Worker if (Op.isToken() && Op.getToken() == "gds") {
1698*9880d681SAndroid Build Coastguard Worker GDSOnly = true;
1699*9880d681SAndroid Build Coastguard Worker continue;
1700*9880d681SAndroid Build Coastguard Worker }
1701*9880d681SAndroid Build Coastguard Worker
1702*9880d681SAndroid Build Coastguard Worker // Handle optional arguments
1703*9880d681SAndroid Build Coastguard Worker OptionalIdx[Op.getImmTy()] = i;
1704*9880d681SAndroid Build Coastguard Worker }
1705*9880d681SAndroid Build Coastguard Worker
1706*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOffset);
1707*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGDS);
1708*9880d681SAndroid Build Coastguard Worker
1709*9880d681SAndroid Build Coastguard Worker if (!GDSOnly) {
1710*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGDS);
1711*9880d681SAndroid Build Coastguard Worker }
1712*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(AMDGPU::M0)); // m0
1713*9880d681SAndroid Build Coastguard Worker }
1714*9880d681SAndroid Build Coastguard Worker
1715*9880d681SAndroid Build Coastguard Worker
1716*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1717*9880d681SAndroid Build Coastguard Worker // s_waitcnt
1718*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1719*9880d681SAndroid Build Coastguard Worker
parseCnt(int64_t & IntVal)1720*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
1721*9880d681SAndroid Build Coastguard Worker StringRef CntName = Parser.getTok().getString();
1722*9880d681SAndroid Build Coastguard Worker int64_t CntVal;
1723*9880d681SAndroid Build Coastguard Worker
1724*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1725*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::LParen))
1726*9880d681SAndroid Build Coastguard Worker return true;
1727*9880d681SAndroid Build Coastguard Worker
1728*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1729*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
1730*9880d681SAndroid Build Coastguard Worker return true;
1731*9880d681SAndroid Build Coastguard Worker
1732*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(CntVal))
1733*9880d681SAndroid Build Coastguard Worker return true;
1734*9880d681SAndroid Build Coastguard Worker
1735*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::RParen))
1736*9880d681SAndroid Build Coastguard Worker return true;
1737*9880d681SAndroid Build Coastguard Worker
1738*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1739*9880d681SAndroid Build Coastguard Worker if (getLexer().is(AsmToken::Amp) || getLexer().is(AsmToken::Comma))
1740*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1741*9880d681SAndroid Build Coastguard Worker
1742*9880d681SAndroid Build Coastguard Worker int CntShift;
1743*9880d681SAndroid Build Coastguard Worker int CntMask;
1744*9880d681SAndroid Build Coastguard Worker
1745*9880d681SAndroid Build Coastguard Worker if (CntName == "vmcnt") {
1746*9880d681SAndroid Build Coastguard Worker CntMask = 0xf;
1747*9880d681SAndroid Build Coastguard Worker CntShift = 0;
1748*9880d681SAndroid Build Coastguard Worker } else if (CntName == "expcnt") {
1749*9880d681SAndroid Build Coastguard Worker CntMask = 0x7;
1750*9880d681SAndroid Build Coastguard Worker CntShift = 4;
1751*9880d681SAndroid Build Coastguard Worker } else if (CntName == "lgkmcnt") {
1752*9880d681SAndroid Build Coastguard Worker CntMask = 0xf;
1753*9880d681SAndroid Build Coastguard Worker CntShift = 8;
1754*9880d681SAndroid Build Coastguard Worker } else {
1755*9880d681SAndroid Build Coastguard Worker return true;
1756*9880d681SAndroid Build Coastguard Worker }
1757*9880d681SAndroid Build Coastguard Worker
1758*9880d681SAndroid Build Coastguard Worker IntVal &= ~(CntMask << CntShift);
1759*9880d681SAndroid Build Coastguard Worker IntVal |= (CntVal << CntShift);
1760*9880d681SAndroid Build Coastguard Worker return false;
1761*9880d681SAndroid Build Coastguard Worker }
1762*9880d681SAndroid Build Coastguard Worker
1763*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseSWaitCntOps(OperandVector & Operands)1764*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseSWaitCntOps(OperandVector &Operands) {
1765*9880d681SAndroid Build Coastguard Worker // Disable all counters by default.
1766*9880d681SAndroid Build Coastguard Worker // vmcnt [3:0]
1767*9880d681SAndroid Build Coastguard Worker // expcnt [6:4]
1768*9880d681SAndroid Build Coastguard Worker // lgkmcnt [11:8]
1769*9880d681SAndroid Build Coastguard Worker int64_t CntVal = 0xf7f;
1770*9880d681SAndroid Build Coastguard Worker SMLoc S = Parser.getTok().getLoc();
1771*9880d681SAndroid Build Coastguard Worker
1772*9880d681SAndroid Build Coastguard Worker switch(getLexer().getKind()) {
1773*9880d681SAndroid Build Coastguard Worker default: return MatchOperand_ParseFail;
1774*9880d681SAndroid Build Coastguard Worker case AsmToken::Integer:
1775*9880d681SAndroid Build Coastguard Worker // The operand can be an integer value.
1776*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(CntVal))
1777*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1778*9880d681SAndroid Build Coastguard Worker break;
1779*9880d681SAndroid Build Coastguard Worker
1780*9880d681SAndroid Build Coastguard Worker case AsmToken::Identifier:
1781*9880d681SAndroid Build Coastguard Worker do {
1782*9880d681SAndroid Build Coastguard Worker if (parseCnt(CntVal))
1783*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1784*9880d681SAndroid Build Coastguard Worker } while(getLexer().isNot(AsmToken::EndOfStatement));
1785*9880d681SAndroid Build Coastguard Worker break;
1786*9880d681SAndroid Build Coastguard Worker }
1787*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateImm(CntVal, S));
1788*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
1789*9880d681SAndroid Build Coastguard Worker }
1790*9880d681SAndroid Build Coastguard Worker
parseHwregConstruct(OperandInfoTy & HwReg,int64_t & Offset,int64_t & Width)1791*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::parseHwregConstruct(OperandInfoTy &HwReg, int64_t &Offset, int64_t &Width) {
1792*9880d681SAndroid Build Coastguard Worker using namespace llvm::AMDGPU::Hwreg;
1793*9880d681SAndroid Build Coastguard Worker
1794*9880d681SAndroid Build Coastguard Worker if (Parser.getTok().getString() != "hwreg")
1795*9880d681SAndroid Build Coastguard Worker return true;
1796*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1797*9880d681SAndroid Build Coastguard Worker
1798*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::LParen))
1799*9880d681SAndroid Build Coastguard Worker return true;
1800*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1801*9880d681SAndroid Build Coastguard Worker
1802*9880d681SAndroid Build Coastguard Worker if (getLexer().is(AsmToken::Identifier)) {
1803*9880d681SAndroid Build Coastguard Worker HwReg.IsSymbolic = true;
1804*9880d681SAndroid Build Coastguard Worker HwReg.Id = ID_UNKNOWN_;
1805*9880d681SAndroid Build Coastguard Worker const StringRef tok = Parser.getTok().getString();
1806*9880d681SAndroid Build Coastguard Worker for (int i = ID_SYMBOLIC_FIRST_; i < ID_SYMBOLIC_LAST_; ++i) {
1807*9880d681SAndroid Build Coastguard Worker if (tok == IdSymbolic[i]) {
1808*9880d681SAndroid Build Coastguard Worker HwReg.Id = i;
1809*9880d681SAndroid Build Coastguard Worker break;
1810*9880d681SAndroid Build Coastguard Worker }
1811*9880d681SAndroid Build Coastguard Worker }
1812*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1813*9880d681SAndroid Build Coastguard Worker } else {
1814*9880d681SAndroid Build Coastguard Worker HwReg.IsSymbolic = false;
1815*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
1816*9880d681SAndroid Build Coastguard Worker return true;
1817*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(HwReg.Id))
1818*9880d681SAndroid Build Coastguard Worker return true;
1819*9880d681SAndroid Build Coastguard Worker }
1820*9880d681SAndroid Build Coastguard Worker
1821*9880d681SAndroid Build Coastguard Worker if (getLexer().is(AsmToken::RParen)) {
1822*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1823*9880d681SAndroid Build Coastguard Worker return false;
1824*9880d681SAndroid Build Coastguard Worker }
1825*9880d681SAndroid Build Coastguard Worker
1826*9880d681SAndroid Build Coastguard Worker // optional params
1827*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Comma))
1828*9880d681SAndroid Build Coastguard Worker return true;
1829*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1830*9880d681SAndroid Build Coastguard Worker
1831*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
1832*9880d681SAndroid Build Coastguard Worker return true;
1833*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(Offset))
1834*9880d681SAndroid Build Coastguard Worker return true;
1835*9880d681SAndroid Build Coastguard Worker
1836*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Comma))
1837*9880d681SAndroid Build Coastguard Worker return true;
1838*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1839*9880d681SAndroid Build Coastguard Worker
1840*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
1841*9880d681SAndroid Build Coastguard Worker return true;
1842*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(Width))
1843*9880d681SAndroid Build Coastguard Worker return true;
1844*9880d681SAndroid Build Coastguard Worker
1845*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::RParen))
1846*9880d681SAndroid Build Coastguard Worker return true;
1847*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1848*9880d681SAndroid Build Coastguard Worker
1849*9880d681SAndroid Build Coastguard Worker return false;
1850*9880d681SAndroid Build Coastguard Worker }
1851*9880d681SAndroid Build Coastguard Worker
1852*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseHwreg(OperandVector & Operands)1853*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseHwreg(OperandVector &Operands) {
1854*9880d681SAndroid Build Coastguard Worker using namespace llvm::AMDGPU::Hwreg;
1855*9880d681SAndroid Build Coastguard Worker
1856*9880d681SAndroid Build Coastguard Worker int64_t Imm16Val = 0;
1857*9880d681SAndroid Build Coastguard Worker SMLoc S = Parser.getTok().getLoc();
1858*9880d681SAndroid Build Coastguard Worker
1859*9880d681SAndroid Build Coastguard Worker switch(getLexer().getKind()) {
1860*9880d681SAndroid Build Coastguard Worker default: return MatchOperand_NoMatch;
1861*9880d681SAndroid Build Coastguard Worker case AsmToken::Integer:
1862*9880d681SAndroid Build Coastguard Worker // The operand can be an integer value.
1863*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(Imm16Val))
1864*9880d681SAndroid Build Coastguard Worker return MatchOperand_NoMatch;
1865*9880d681SAndroid Build Coastguard Worker if (Imm16Val < 0 || !isUInt<16>(Imm16Val)) {
1866*9880d681SAndroid Build Coastguard Worker Error(S, "invalid immediate: only 16-bit values are legal");
1867*9880d681SAndroid Build Coastguard Worker // Do not return error code, but create an imm operand anyway and proceed
1868*9880d681SAndroid Build Coastguard Worker // to the next operand, if any. That avoids unneccessary error messages.
1869*9880d681SAndroid Build Coastguard Worker }
1870*9880d681SAndroid Build Coastguard Worker break;
1871*9880d681SAndroid Build Coastguard Worker
1872*9880d681SAndroid Build Coastguard Worker case AsmToken::Identifier: {
1873*9880d681SAndroid Build Coastguard Worker OperandInfoTy HwReg(ID_UNKNOWN_);
1874*9880d681SAndroid Build Coastguard Worker int64_t Offset = OFFSET_DEFAULT_;
1875*9880d681SAndroid Build Coastguard Worker int64_t Width = WIDTH_M1_DEFAULT_ + 1;
1876*9880d681SAndroid Build Coastguard Worker if (parseHwregConstruct(HwReg, Offset, Width))
1877*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
1878*9880d681SAndroid Build Coastguard Worker if (HwReg.Id < 0 || !isUInt<ID_WIDTH_>(HwReg.Id)) {
1879*9880d681SAndroid Build Coastguard Worker if (HwReg.IsSymbolic)
1880*9880d681SAndroid Build Coastguard Worker Error(S, "invalid symbolic name of hardware register");
1881*9880d681SAndroid Build Coastguard Worker else
1882*9880d681SAndroid Build Coastguard Worker Error(S, "invalid code of hardware register: only 6-bit values are legal");
1883*9880d681SAndroid Build Coastguard Worker }
1884*9880d681SAndroid Build Coastguard Worker if (Offset < 0 || !isUInt<OFFSET_WIDTH_>(Offset))
1885*9880d681SAndroid Build Coastguard Worker Error(S, "invalid bit offset: only 5-bit values are legal");
1886*9880d681SAndroid Build Coastguard Worker if ((Width-1) < 0 || !isUInt<WIDTH_M1_WIDTH_>(Width-1))
1887*9880d681SAndroid Build Coastguard Worker Error(S, "invalid bitfield width: only values from 1 to 32 are legal");
1888*9880d681SAndroid Build Coastguard Worker Imm16Val = (HwReg.Id << ID_SHIFT_) | (Offset << OFFSET_SHIFT_) | ((Width-1) << WIDTH_M1_SHIFT_);
1889*9880d681SAndroid Build Coastguard Worker }
1890*9880d681SAndroid Build Coastguard Worker break;
1891*9880d681SAndroid Build Coastguard Worker }
1892*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateImm(Imm16Val, S, AMDGPUOperand::ImmTyHwreg));
1893*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
1894*9880d681SAndroid Build Coastguard Worker }
1895*9880d681SAndroid Build Coastguard Worker
isSWaitCnt() const1896*9880d681SAndroid Build Coastguard Worker bool AMDGPUOperand::isSWaitCnt() const {
1897*9880d681SAndroid Build Coastguard Worker return isImm();
1898*9880d681SAndroid Build Coastguard Worker }
1899*9880d681SAndroid Build Coastguard Worker
isHwreg() const1900*9880d681SAndroid Build Coastguard Worker bool AMDGPUOperand::isHwreg() const {
1901*9880d681SAndroid Build Coastguard Worker return isImmTy(ImmTyHwreg);
1902*9880d681SAndroid Build Coastguard Worker }
1903*9880d681SAndroid Build Coastguard Worker
parseSendMsgConstruct(OperandInfoTy & Msg,OperandInfoTy & Operation,int64_t & StreamId)1904*9880d681SAndroid Build Coastguard Worker bool AMDGPUAsmParser::parseSendMsgConstruct(OperandInfoTy &Msg, OperandInfoTy &Operation, int64_t &StreamId) {
1905*9880d681SAndroid Build Coastguard Worker using namespace llvm::AMDGPU::SendMsg;
1906*9880d681SAndroid Build Coastguard Worker
1907*9880d681SAndroid Build Coastguard Worker if (Parser.getTok().getString() != "sendmsg")
1908*9880d681SAndroid Build Coastguard Worker return true;
1909*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1910*9880d681SAndroid Build Coastguard Worker
1911*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::LParen))
1912*9880d681SAndroid Build Coastguard Worker return true;
1913*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1914*9880d681SAndroid Build Coastguard Worker
1915*9880d681SAndroid Build Coastguard Worker if (getLexer().is(AsmToken::Identifier)) {
1916*9880d681SAndroid Build Coastguard Worker Msg.IsSymbolic = true;
1917*9880d681SAndroid Build Coastguard Worker Msg.Id = ID_UNKNOWN_;
1918*9880d681SAndroid Build Coastguard Worker const std::string tok = Parser.getTok().getString();
1919*9880d681SAndroid Build Coastguard Worker for (int i = ID_GAPS_FIRST_; i < ID_GAPS_LAST_; ++i) {
1920*9880d681SAndroid Build Coastguard Worker switch(i) {
1921*9880d681SAndroid Build Coastguard Worker default: continue; // Omit gaps.
1922*9880d681SAndroid Build Coastguard Worker case ID_INTERRUPT: case ID_GS: case ID_GS_DONE: case ID_SYSMSG: break;
1923*9880d681SAndroid Build Coastguard Worker }
1924*9880d681SAndroid Build Coastguard Worker if (tok == IdSymbolic[i]) {
1925*9880d681SAndroid Build Coastguard Worker Msg.Id = i;
1926*9880d681SAndroid Build Coastguard Worker break;
1927*9880d681SAndroid Build Coastguard Worker }
1928*9880d681SAndroid Build Coastguard Worker }
1929*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1930*9880d681SAndroid Build Coastguard Worker } else {
1931*9880d681SAndroid Build Coastguard Worker Msg.IsSymbolic = false;
1932*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
1933*9880d681SAndroid Build Coastguard Worker return true;
1934*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(Msg.Id))
1935*9880d681SAndroid Build Coastguard Worker return true;
1936*9880d681SAndroid Build Coastguard Worker if (getLexer().is(AsmToken::Integer))
1937*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(Msg.Id))
1938*9880d681SAndroid Build Coastguard Worker Msg.Id = ID_UNKNOWN_;
1939*9880d681SAndroid Build Coastguard Worker }
1940*9880d681SAndroid Build Coastguard Worker if (Msg.Id == ID_UNKNOWN_) // Don't know how to parse the rest.
1941*9880d681SAndroid Build Coastguard Worker return false;
1942*9880d681SAndroid Build Coastguard Worker
1943*9880d681SAndroid Build Coastguard Worker if (!(Msg.Id == ID_GS || Msg.Id == ID_GS_DONE || Msg.Id == ID_SYSMSG)) {
1944*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::RParen))
1945*9880d681SAndroid Build Coastguard Worker return true;
1946*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1947*9880d681SAndroid Build Coastguard Worker return false;
1948*9880d681SAndroid Build Coastguard Worker }
1949*9880d681SAndroid Build Coastguard Worker
1950*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Comma))
1951*9880d681SAndroid Build Coastguard Worker return true;
1952*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1953*9880d681SAndroid Build Coastguard Worker
1954*9880d681SAndroid Build Coastguard Worker assert(Msg.Id == ID_GS || Msg.Id == ID_GS_DONE || Msg.Id == ID_SYSMSG);
1955*9880d681SAndroid Build Coastguard Worker Operation.Id = ID_UNKNOWN_;
1956*9880d681SAndroid Build Coastguard Worker if (getLexer().is(AsmToken::Identifier)) {
1957*9880d681SAndroid Build Coastguard Worker Operation.IsSymbolic = true;
1958*9880d681SAndroid Build Coastguard Worker const char* const *S = (Msg.Id == ID_SYSMSG) ? OpSysSymbolic : OpGsSymbolic;
1959*9880d681SAndroid Build Coastguard Worker const int F = (Msg.Id == ID_SYSMSG) ? OP_SYS_FIRST_ : OP_GS_FIRST_;
1960*9880d681SAndroid Build Coastguard Worker const int L = (Msg.Id == ID_SYSMSG) ? OP_SYS_LAST_ : OP_GS_LAST_;
1961*9880d681SAndroid Build Coastguard Worker const StringRef Tok = Parser.getTok().getString();
1962*9880d681SAndroid Build Coastguard Worker for (int i = F; i < L; ++i) {
1963*9880d681SAndroid Build Coastguard Worker if (Tok == S[i]) {
1964*9880d681SAndroid Build Coastguard Worker Operation.Id = i;
1965*9880d681SAndroid Build Coastguard Worker break;
1966*9880d681SAndroid Build Coastguard Worker }
1967*9880d681SAndroid Build Coastguard Worker }
1968*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1969*9880d681SAndroid Build Coastguard Worker } else {
1970*9880d681SAndroid Build Coastguard Worker Operation.IsSymbolic = false;
1971*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
1972*9880d681SAndroid Build Coastguard Worker return true;
1973*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(Operation.Id))
1974*9880d681SAndroid Build Coastguard Worker return true;
1975*9880d681SAndroid Build Coastguard Worker }
1976*9880d681SAndroid Build Coastguard Worker
1977*9880d681SAndroid Build Coastguard Worker if ((Msg.Id == ID_GS || Msg.Id == ID_GS_DONE) && Operation.Id != OP_GS_NOP) {
1978*9880d681SAndroid Build Coastguard Worker // Stream id is optional.
1979*9880d681SAndroid Build Coastguard Worker if (getLexer().is(AsmToken::RParen)) {
1980*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1981*9880d681SAndroid Build Coastguard Worker return false;
1982*9880d681SAndroid Build Coastguard Worker }
1983*9880d681SAndroid Build Coastguard Worker
1984*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Comma))
1985*9880d681SAndroid Build Coastguard Worker return true;
1986*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1987*9880d681SAndroid Build Coastguard Worker
1988*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
1989*9880d681SAndroid Build Coastguard Worker return true;
1990*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(StreamId))
1991*9880d681SAndroid Build Coastguard Worker return true;
1992*9880d681SAndroid Build Coastguard Worker }
1993*9880d681SAndroid Build Coastguard Worker
1994*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::RParen))
1995*9880d681SAndroid Build Coastguard Worker return true;
1996*9880d681SAndroid Build Coastguard Worker Parser.Lex();
1997*9880d681SAndroid Build Coastguard Worker return false;
1998*9880d681SAndroid Build Coastguard Worker }
1999*9880d681SAndroid Build Coastguard Worker
2000*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseSendMsgOp(OperandVector & Operands)2001*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseSendMsgOp(OperandVector &Operands) {
2002*9880d681SAndroid Build Coastguard Worker using namespace llvm::AMDGPU::SendMsg;
2003*9880d681SAndroid Build Coastguard Worker
2004*9880d681SAndroid Build Coastguard Worker int64_t Imm16Val = 0;
2005*9880d681SAndroid Build Coastguard Worker SMLoc S = Parser.getTok().getLoc();
2006*9880d681SAndroid Build Coastguard Worker
2007*9880d681SAndroid Build Coastguard Worker switch(getLexer().getKind()) {
2008*9880d681SAndroid Build Coastguard Worker default:
2009*9880d681SAndroid Build Coastguard Worker return MatchOperand_NoMatch;
2010*9880d681SAndroid Build Coastguard Worker case AsmToken::Integer:
2011*9880d681SAndroid Build Coastguard Worker // The operand can be an integer value.
2012*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(Imm16Val))
2013*9880d681SAndroid Build Coastguard Worker return MatchOperand_NoMatch;
2014*9880d681SAndroid Build Coastguard Worker if (Imm16Val < 0 || !isUInt<16>(Imm16Val)) {
2015*9880d681SAndroid Build Coastguard Worker Error(S, "invalid immediate: only 16-bit values are legal");
2016*9880d681SAndroid Build Coastguard Worker // Do not return error code, but create an imm operand anyway and proceed
2017*9880d681SAndroid Build Coastguard Worker // to the next operand, if any. That avoids unneccessary error messages.
2018*9880d681SAndroid Build Coastguard Worker }
2019*9880d681SAndroid Build Coastguard Worker break;
2020*9880d681SAndroid Build Coastguard Worker case AsmToken::Identifier: {
2021*9880d681SAndroid Build Coastguard Worker OperandInfoTy Msg(ID_UNKNOWN_);
2022*9880d681SAndroid Build Coastguard Worker OperandInfoTy Operation(OP_UNKNOWN_);
2023*9880d681SAndroid Build Coastguard Worker int64_t StreamId = STREAM_ID_DEFAULT_;
2024*9880d681SAndroid Build Coastguard Worker if (parseSendMsgConstruct(Msg, Operation, StreamId))
2025*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2026*9880d681SAndroid Build Coastguard Worker do {
2027*9880d681SAndroid Build Coastguard Worker // Validate and encode message ID.
2028*9880d681SAndroid Build Coastguard Worker if (! ((ID_INTERRUPT <= Msg.Id && Msg.Id <= ID_GS_DONE)
2029*9880d681SAndroid Build Coastguard Worker || Msg.Id == ID_SYSMSG)) {
2030*9880d681SAndroid Build Coastguard Worker if (Msg.IsSymbolic)
2031*9880d681SAndroid Build Coastguard Worker Error(S, "invalid/unsupported symbolic name of message");
2032*9880d681SAndroid Build Coastguard Worker else
2033*9880d681SAndroid Build Coastguard Worker Error(S, "invalid/unsupported code of message");
2034*9880d681SAndroid Build Coastguard Worker break;
2035*9880d681SAndroid Build Coastguard Worker }
2036*9880d681SAndroid Build Coastguard Worker Imm16Val = (Msg.Id << ID_SHIFT_);
2037*9880d681SAndroid Build Coastguard Worker // Validate and encode operation ID.
2038*9880d681SAndroid Build Coastguard Worker if (Msg.Id == ID_GS || Msg.Id == ID_GS_DONE) {
2039*9880d681SAndroid Build Coastguard Worker if (! (OP_GS_FIRST_ <= Operation.Id && Operation.Id < OP_GS_LAST_)) {
2040*9880d681SAndroid Build Coastguard Worker if (Operation.IsSymbolic)
2041*9880d681SAndroid Build Coastguard Worker Error(S, "invalid symbolic name of GS_OP");
2042*9880d681SAndroid Build Coastguard Worker else
2043*9880d681SAndroid Build Coastguard Worker Error(S, "invalid code of GS_OP: only 2-bit values are legal");
2044*9880d681SAndroid Build Coastguard Worker break;
2045*9880d681SAndroid Build Coastguard Worker }
2046*9880d681SAndroid Build Coastguard Worker if (Operation.Id == OP_GS_NOP
2047*9880d681SAndroid Build Coastguard Worker && Msg.Id != ID_GS_DONE) {
2048*9880d681SAndroid Build Coastguard Worker Error(S, "invalid GS_OP: NOP is for GS_DONE only");
2049*9880d681SAndroid Build Coastguard Worker break;
2050*9880d681SAndroid Build Coastguard Worker }
2051*9880d681SAndroid Build Coastguard Worker Imm16Val |= (Operation.Id << OP_SHIFT_);
2052*9880d681SAndroid Build Coastguard Worker }
2053*9880d681SAndroid Build Coastguard Worker if (Msg.Id == ID_SYSMSG) {
2054*9880d681SAndroid Build Coastguard Worker if (! (OP_SYS_FIRST_ <= Operation.Id && Operation.Id < OP_SYS_LAST_)) {
2055*9880d681SAndroid Build Coastguard Worker if (Operation.IsSymbolic)
2056*9880d681SAndroid Build Coastguard Worker Error(S, "invalid/unsupported symbolic name of SYSMSG_OP");
2057*9880d681SAndroid Build Coastguard Worker else
2058*9880d681SAndroid Build Coastguard Worker Error(S, "invalid/unsupported code of SYSMSG_OP");
2059*9880d681SAndroid Build Coastguard Worker break;
2060*9880d681SAndroid Build Coastguard Worker }
2061*9880d681SAndroid Build Coastguard Worker Imm16Val |= (Operation.Id << OP_SHIFT_);
2062*9880d681SAndroid Build Coastguard Worker }
2063*9880d681SAndroid Build Coastguard Worker // Validate and encode stream ID.
2064*9880d681SAndroid Build Coastguard Worker if ((Msg.Id == ID_GS || Msg.Id == ID_GS_DONE) && Operation.Id != OP_GS_NOP) {
2065*9880d681SAndroid Build Coastguard Worker if (! (STREAM_ID_FIRST_ <= StreamId && StreamId < STREAM_ID_LAST_)) {
2066*9880d681SAndroid Build Coastguard Worker Error(S, "invalid stream id: only 2-bit values are legal");
2067*9880d681SAndroid Build Coastguard Worker break;
2068*9880d681SAndroid Build Coastguard Worker }
2069*9880d681SAndroid Build Coastguard Worker Imm16Val |= (StreamId << STREAM_ID_SHIFT_);
2070*9880d681SAndroid Build Coastguard Worker }
2071*9880d681SAndroid Build Coastguard Worker } while (0);
2072*9880d681SAndroid Build Coastguard Worker }
2073*9880d681SAndroid Build Coastguard Worker break;
2074*9880d681SAndroid Build Coastguard Worker }
2075*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateImm(Imm16Val, S, AMDGPUOperand::ImmTySendMsg));
2076*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
2077*9880d681SAndroid Build Coastguard Worker }
2078*9880d681SAndroid Build Coastguard Worker
isSendMsg() const2079*9880d681SAndroid Build Coastguard Worker bool AMDGPUOperand::isSendMsg() const {
2080*9880d681SAndroid Build Coastguard Worker return isImmTy(ImmTySendMsg);
2081*9880d681SAndroid Build Coastguard Worker }
2082*9880d681SAndroid Build Coastguard Worker
2083*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2084*9880d681SAndroid Build Coastguard Worker // sopp branch targets
2085*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2086*9880d681SAndroid Build Coastguard Worker
2087*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseSOppBrTarget(OperandVector & Operands)2088*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseSOppBrTarget(OperandVector &Operands) {
2089*9880d681SAndroid Build Coastguard Worker SMLoc S = Parser.getTok().getLoc();
2090*9880d681SAndroid Build Coastguard Worker
2091*9880d681SAndroid Build Coastguard Worker switch (getLexer().getKind()) {
2092*9880d681SAndroid Build Coastguard Worker default: return MatchOperand_ParseFail;
2093*9880d681SAndroid Build Coastguard Worker case AsmToken::Integer: {
2094*9880d681SAndroid Build Coastguard Worker int64_t Imm;
2095*9880d681SAndroid Build Coastguard Worker if (getParser().parseAbsoluteExpression(Imm))
2096*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2097*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateImm(Imm, S));
2098*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
2099*9880d681SAndroid Build Coastguard Worker }
2100*9880d681SAndroid Build Coastguard Worker
2101*9880d681SAndroid Build Coastguard Worker case AsmToken::Identifier:
2102*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateExpr(
2103*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(getContext().getOrCreateSymbol(
2104*9880d681SAndroid Build Coastguard Worker Parser.getTok().getString()), getContext()), S));
2105*9880d681SAndroid Build Coastguard Worker Parser.Lex();
2106*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
2107*9880d681SAndroid Build Coastguard Worker }
2108*9880d681SAndroid Build Coastguard Worker }
2109*9880d681SAndroid Build Coastguard Worker
2110*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2111*9880d681SAndroid Build Coastguard Worker // mubuf
2112*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2113*9880d681SAndroid Build Coastguard Worker
defaultGLC() const2114*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr AMDGPUAsmParser::defaultGLC() const {
2115*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTyGLC);
2116*9880d681SAndroid Build Coastguard Worker }
2117*9880d681SAndroid Build Coastguard Worker
defaultSLC() const2118*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSLC() const {
2119*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTySLC);
2120*9880d681SAndroid Build Coastguard Worker }
2121*9880d681SAndroid Build Coastguard Worker
defaultTFE() const2122*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr AMDGPUAsmParser::defaultTFE() const {
2123*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTyTFE);
2124*9880d681SAndroid Build Coastguard Worker }
2125*9880d681SAndroid Build Coastguard Worker
cvtMubufImpl(MCInst & Inst,const OperandVector & Operands,bool IsAtomic,bool IsAtomicReturn)2126*9880d681SAndroid Build Coastguard Worker void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
2127*9880d681SAndroid Build Coastguard Worker const OperandVector &Operands,
2128*9880d681SAndroid Build Coastguard Worker bool IsAtomic, bool IsAtomicReturn) {
2129*9880d681SAndroid Build Coastguard Worker OptionalImmIndexMap OptionalIdx;
2130*9880d681SAndroid Build Coastguard Worker assert(IsAtomicReturn ? IsAtomic : true);
2131*9880d681SAndroid Build Coastguard Worker
2132*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
2133*9880d681SAndroid Build Coastguard Worker AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
2134*9880d681SAndroid Build Coastguard Worker
2135*9880d681SAndroid Build Coastguard Worker // Add the register arguments
2136*9880d681SAndroid Build Coastguard Worker if (Op.isReg()) {
2137*9880d681SAndroid Build Coastguard Worker Op.addRegOperands(Inst, 1);
2138*9880d681SAndroid Build Coastguard Worker continue;
2139*9880d681SAndroid Build Coastguard Worker }
2140*9880d681SAndroid Build Coastguard Worker
2141*9880d681SAndroid Build Coastguard Worker // Handle the case where soffset is an immediate
2142*9880d681SAndroid Build Coastguard Worker if (Op.isImm() && Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
2143*9880d681SAndroid Build Coastguard Worker Op.addImmOperands(Inst, 1);
2144*9880d681SAndroid Build Coastguard Worker continue;
2145*9880d681SAndroid Build Coastguard Worker }
2146*9880d681SAndroid Build Coastguard Worker
2147*9880d681SAndroid Build Coastguard Worker // Handle tokens like 'offen' which are sometimes hard-coded into the
2148*9880d681SAndroid Build Coastguard Worker // asm string. There are no MCInst operands for these.
2149*9880d681SAndroid Build Coastguard Worker if (Op.isToken()) {
2150*9880d681SAndroid Build Coastguard Worker continue;
2151*9880d681SAndroid Build Coastguard Worker }
2152*9880d681SAndroid Build Coastguard Worker assert(Op.isImm());
2153*9880d681SAndroid Build Coastguard Worker
2154*9880d681SAndroid Build Coastguard Worker // Handle optional arguments
2155*9880d681SAndroid Build Coastguard Worker OptionalIdx[Op.getImmTy()] = i;
2156*9880d681SAndroid Build Coastguard Worker }
2157*9880d681SAndroid Build Coastguard Worker
2158*9880d681SAndroid Build Coastguard Worker // Copy $vdata_in operand and insert as $vdata for MUBUF_Atomic RTN insns.
2159*9880d681SAndroid Build Coastguard Worker if (IsAtomicReturn) {
2160*9880d681SAndroid Build Coastguard Worker MCInst::iterator I = Inst.begin(); // $vdata_in is always at the beginning.
2161*9880d681SAndroid Build Coastguard Worker Inst.insert(I, *I);
2162*9880d681SAndroid Build Coastguard Worker }
2163*9880d681SAndroid Build Coastguard Worker
2164*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOffset);
2165*9880d681SAndroid Build Coastguard Worker if (!IsAtomic) { // glc is hard-coded.
2166*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGLC);
2167*9880d681SAndroid Build Coastguard Worker }
2168*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySLC);
2169*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyTFE);
2170*9880d681SAndroid Build Coastguard Worker }
2171*9880d681SAndroid Build Coastguard Worker
2172*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2173*9880d681SAndroid Build Coastguard Worker // mimg
2174*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2175*9880d681SAndroid Build Coastguard Worker
cvtMIMG(MCInst & Inst,const OperandVector & Operands)2176*9880d681SAndroid Build Coastguard Worker void AMDGPUAsmParser::cvtMIMG(MCInst &Inst, const OperandVector &Operands) {
2177*9880d681SAndroid Build Coastguard Worker unsigned I = 1;
2178*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
2179*9880d681SAndroid Build Coastguard Worker for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
2180*9880d681SAndroid Build Coastguard Worker ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
2181*9880d681SAndroid Build Coastguard Worker }
2182*9880d681SAndroid Build Coastguard Worker
2183*9880d681SAndroid Build Coastguard Worker OptionalImmIndexMap OptionalIdx;
2184*9880d681SAndroid Build Coastguard Worker
2185*9880d681SAndroid Build Coastguard Worker for (unsigned E = Operands.size(); I != E; ++I) {
2186*9880d681SAndroid Build Coastguard Worker AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
2187*9880d681SAndroid Build Coastguard Worker
2188*9880d681SAndroid Build Coastguard Worker // Add the register arguments
2189*9880d681SAndroid Build Coastguard Worker if (Op.isRegOrImm()) {
2190*9880d681SAndroid Build Coastguard Worker Op.addRegOrImmOperands(Inst, 1);
2191*9880d681SAndroid Build Coastguard Worker continue;
2192*9880d681SAndroid Build Coastguard Worker } else if (Op.isImmModifier()) {
2193*9880d681SAndroid Build Coastguard Worker OptionalIdx[Op.getImmTy()] = I;
2194*9880d681SAndroid Build Coastguard Worker } else {
2195*9880d681SAndroid Build Coastguard Worker assert(false);
2196*9880d681SAndroid Build Coastguard Worker }
2197*9880d681SAndroid Build Coastguard Worker }
2198*9880d681SAndroid Build Coastguard Worker
2199*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDMask);
2200*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyUNorm);
2201*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGLC);
2202*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDA);
2203*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyR128);
2204*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyTFE);
2205*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyLWE);
2206*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySLC);
2207*9880d681SAndroid Build Coastguard Worker }
2208*9880d681SAndroid Build Coastguard Worker
cvtMIMGAtomic(MCInst & Inst,const OperandVector & Operands)2209*9880d681SAndroid Build Coastguard Worker void AMDGPUAsmParser::cvtMIMGAtomic(MCInst &Inst, const OperandVector &Operands) {
2210*9880d681SAndroid Build Coastguard Worker unsigned I = 1;
2211*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
2212*9880d681SAndroid Build Coastguard Worker for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
2213*9880d681SAndroid Build Coastguard Worker ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
2214*9880d681SAndroid Build Coastguard Worker }
2215*9880d681SAndroid Build Coastguard Worker
2216*9880d681SAndroid Build Coastguard Worker // Add src, same as dst
2217*9880d681SAndroid Build Coastguard Worker ((AMDGPUOperand &)*Operands[I]).addRegOperands(Inst, 1);
2218*9880d681SAndroid Build Coastguard Worker
2219*9880d681SAndroid Build Coastguard Worker OptionalImmIndexMap OptionalIdx;
2220*9880d681SAndroid Build Coastguard Worker
2221*9880d681SAndroid Build Coastguard Worker for (unsigned E = Operands.size(); I != E; ++I) {
2222*9880d681SAndroid Build Coastguard Worker AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
2223*9880d681SAndroid Build Coastguard Worker
2224*9880d681SAndroid Build Coastguard Worker // Add the register arguments
2225*9880d681SAndroid Build Coastguard Worker if (Op.isRegOrImm()) {
2226*9880d681SAndroid Build Coastguard Worker Op.addRegOrImmOperands(Inst, 1);
2227*9880d681SAndroid Build Coastguard Worker continue;
2228*9880d681SAndroid Build Coastguard Worker } else if (Op.isImmModifier()) {
2229*9880d681SAndroid Build Coastguard Worker OptionalIdx[Op.getImmTy()] = I;
2230*9880d681SAndroid Build Coastguard Worker } else {
2231*9880d681SAndroid Build Coastguard Worker assert(false);
2232*9880d681SAndroid Build Coastguard Worker }
2233*9880d681SAndroid Build Coastguard Worker }
2234*9880d681SAndroid Build Coastguard Worker
2235*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDMask);
2236*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyUNorm);
2237*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGLC);
2238*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDA);
2239*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyR128);
2240*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyTFE);
2241*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyLWE);
2242*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySLC);
2243*9880d681SAndroid Build Coastguard Worker }
2244*9880d681SAndroid Build Coastguard Worker
defaultDMask() const2245*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr AMDGPUAsmParser::defaultDMask() const {
2246*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTyDMask);
2247*9880d681SAndroid Build Coastguard Worker }
2248*9880d681SAndroid Build Coastguard Worker
defaultUNorm() const2249*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr AMDGPUAsmParser::defaultUNorm() const {
2250*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTyUNorm);
2251*9880d681SAndroid Build Coastguard Worker }
2252*9880d681SAndroid Build Coastguard Worker
defaultDA() const2253*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr AMDGPUAsmParser::defaultDA() const {
2254*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTyDA);
2255*9880d681SAndroid Build Coastguard Worker }
2256*9880d681SAndroid Build Coastguard Worker
defaultR128() const2257*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr AMDGPUAsmParser::defaultR128() const {
2258*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTyR128);
2259*9880d681SAndroid Build Coastguard Worker }
2260*9880d681SAndroid Build Coastguard Worker
defaultLWE() const2261*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr AMDGPUAsmParser::defaultLWE() const {
2262*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTyLWE);
2263*9880d681SAndroid Build Coastguard Worker }
2264*9880d681SAndroid Build Coastguard Worker
2265*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2266*9880d681SAndroid Build Coastguard Worker // smrd
2267*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2268*9880d681SAndroid Build Coastguard Worker
isSMRDOffset() const2269*9880d681SAndroid Build Coastguard Worker bool AMDGPUOperand::isSMRDOffset() const {
2270*9880d681SAndroid Build Coastguard Worker
2271*9880d681SAndroid Build Coastguard Worker // FIXME: Support 20-bit offsets on VI. We need to to pass subtarget
2272*9880d681SAndroid Build Coastguard Worker // information here.
2273*9880d681SAndroid Build Coastguard Worker return isImm() && isUInt<8>(getImm());
2274*9880d681SAndroid Build Coastguard Worker }
2275*9880d681SAndroid Build Coastguard Worker
isSMRDLiteralOffset() const2276*9880d681SAndroid Build Coastguard Worker bool AMDGPUOperand::isSMRDLiteralOffset() const {
2277*9880d681SAndroid Build Coastguard Worker // 32-bit literals are only supported on CI and we only want to use them
2278*9880d681SAndroid Build Coastguard Worker // when the offset is > 8-bits.
2279*9880d681SAndroid Build Coastguard Worker return isImm() && !isUInt<8>(getImm()) && isUInt<32>(getImm());
2280*9880d681SAndroid Build Coastguard Worker }
2281*9880d681SAndroid Build Coastguard Worker
defaultSMRDOffset() const2282*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDOffset() const {
2283*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTyOffset);
2284*9880d681SAndroid Build Coastguard Worker }
2285*9880d681SAndroid Build Coastguard Worker
defaultSMRDLiteralOffset() const2286*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDLiteralOffset() const {
2287*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTyOffset);
2288*9880d681SAndroid Build Coastguard Worker }
2289*9880d681SAndroid Build Coastguard Worker
2290*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2291*9880d681SAndroid Build Coastguard Worker // vop3
2292*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2293*9880d681SAndroid Build Coastguard Worker
ConvertOmodMul(int64_t & Mul)2294*9880d681SAndroid Build Coastguard Worker static bool ConvertOmodMul(int64_t &Mul) {
2295*9880d681SAndroid Build Coastguard Worker if (Mul != 1 && Mul != 2 && Mul != 4)
2296*9880d681SAndroid Build Coastguard Worker return false;
2297*9880d681SAndroid Build Coastguard Worker
2298*9880d681SAndroid Build Coastguard Worker Mul >>= 1;
2299*9880d681SAndroid Build Coastguard Worker return true;
2300*9880d681SAndroid Build Coastguard Worker }
2301*9880d681SAndroid Build Coastguard Worker
ConvertOmodDiv(int64_t & Div)2302*9880d681SAndroid Build Coastguard Worker static bool ConvertOmodDiv(int64_t &Div) {
2303*9880d681SAndroid Build Coastguard Worker if (Div == 1) {
2304*9880d681SAndroid Build Coastguard Worker Div = 0;
2305*9880d681SAndroid Build Coastguard Worker return true;
2306*9880d681SAndroid Build Coastguard Worker }
2307*9880d681SAndroid Build Coastguard Worker
2308*9880d681SAndroid Build Coastguard Worker if (Div == 2) {
2309*9880d681SAndroid Build Coastguard Worker Div = 3;
2310*9880d681SAndroid Build Coastguard Worker return true;
2311*9880d681SAndroid Build Coastguard Worker }
2312*9880d681SAndroid Build Coastguard Worker
2313*9880d681SAndroid Build Coastguard Worker return false;
2314*9880d681SAndroid Build Coastguard Worker }
2315*9880d681SAndroid Build Coastguard Worker
ConvertBoundCtrl(int64_t & BoundCtrl)2316*9880d681SAndroid Build Coastguard Worker static bool ConvertBoundCtrl(int64_t &BoundCtrl) {
2317*9880d681SAndroid Build Coastguard Worker if (BoundCtrl == 0) {
2318*9880d681SAndroid Build Coastguard Worker BoundCtrl = 1;
2319*9880d681SAndroid Build Coastguard Worker return true;
2320*9880d681SAndroid Build Coastguard Worker } else if (BoundCtrl == -1) {
2321*9880d681SAndroid Build Coastguard Worker BoundCtrl = 0;
2322*9880d681SAndroid Build Coastguard Worker return true;
2323*9880d681SAndroid Build Coastguard Worker }
2324*9880d681SAndroid Build Coastguard Worker return false;
2325*9880d681SAndroid Build Coastguard Worker }
2326*9880d681SAndroid Build Coastguard Worker
2327*9880d681SAndroid Build Coastguard Worker // Note: the order in this table matches the order of operands in AsmString.
2328*9880d681SAndroid Build Coastguard Worker static const OptionalOperand AMDGPUOptionalOperandTable[] = {
2329*9880d681SAndroid Build Coastguard Worker {"offen", AMDGPUOperand::ImmTyOffen, true, nullptr},
2330*9880d681SAndroid Build Coastguard Worker {"idxen", AMDGPUOperand::ImmTyIdxen, true, nullptr},
2331*9880d681SAndroid Build Coastguard Worker {"addr64", AMDGPUOperand::ImmTyAddr64, true, nullptr},
2332*9880d681SAndroid Build Coastguard Worker {"offset0", AMDGPUOperand::ImmTyOffset0, false, nullptr},
2333*9880d681SAndroid Build Coastguard Worker {"offset1", AMDGPUOperand::ImmTyOffset1, false, nullptr},
2334*9880d681SAndroid Build Coastguard Worker {"gds", AMDGPUOperand::ImmTyGDS, true, nullptr},
2335*9880d681SAndroid Build Coastguard Worker {"offset", AMDGPUOperand::ImmTyOffset, false, nullptr},
2336*9880d681SAndroid Build Coastguard Worker {"glc", AMDGPUOperand::ImmTyGLC, true, nullptr},
2337*9880d681SAndroid Build Coastguard Worker {"slc", AMDGPUOperand::ImmTySLC, true, nullptr},
2338*9880d681SAndroid Build Coastguard Worker {"tfe", AMDGPUOperand::ImmTyTFE, true, nullptr},
2339*9880d681SAndroid Build Coastguard Worker {"clamp", AMDGPUOperand::ImmTyClampSI, true, nullptr},
2340*9880d681SAndroid Build Coastguard Worker {"omod", AMDGPUOperand::ImmTyOModSI, false, ConvertOmodMul},
2341*9880d681SAndroid Build Coastguard Worker {"unorm", AMDGPUOperand::ImmTyUNorm, true, nullptr},
2342*9880d681SAndroid Build Coastguard Worker {"da", AMDGPUOperand::ImmTyDA, true, nullptr},
2343*9880d681SAndroid Build Coastguard Worker {"r128", AMDGPUOperand::ImmTyR128, true, nullptr},
2344*9880d681SAndroid Build Coastguard Worker {"lwe", AMDGPUOperand::ImmTyLWE, true, nullptr},
2345*9880d681SAndroid Build Coastguard Worker {"dmask", AMDGPUOperand::ImmTyDMask, false, nullptr},
2346*9880d681SAndroid Build Coastguard Worker {"row_mask", AMDGPUOperand::ImmTyDppRowMask, false, nullptr},
2347*9880d681SAndroid Build Coastguard Worker {"bank_mask", AMDGPUOperand::ImmTyDppBankMask, false, nullptr},
2348*9880d681SAndroid Build Coastguard Worker {"bound_ctrl", AMDGPUOperand::ImmTyDppBoundCtrl, false, ConvertBoundCtrl},
2349*9880d681SAndroid Build Coastguard Worker {"dst_sel", AMDGPUOperand::ImmTySdwaDstSel, false, nullptr},
2350*9880d681SAndroid Build Coastguard Worker {"src0_sel", AMDGPUOperand::ImmTySdwaSrc0Sel, false, nullptr},
2351*9880d681SAndroid Build Coastguard Worker {"src1_sel", AMDGPUOperand::ImmTySdwaSrc1Sel, false, nullptr},
2352*9880d681SAndroid Build Coastguard Worker {"dst_unused", AMDGPUOperand::ImmTySdwaDstUnused, false, nullptr},
2353*9880d681SAndroid Build Coastguard Worker };
2354*9880d681SAndroid Build Coastguard Worker
parseOptionalOperand(OperandVector & Operands)2355*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy AMDGPUAsmParser::parseOptionalOperand(OperandVector &Operands) {
2356*9880d681SAndroid Build Coastguard Worker OperandMatchResultTy res;
2357*9880d681SAndroid Build Coastguard Worker for (const OptionalOperand &Op : AMDGPUOptionalOperandTable) {
2358*9880d681SAndroid Build Coastguard Worker // try to parse any optional operand here
2359*9880d681SAndroid Build Coastguard Worker if (Op.IsBit) {
2360*9880d681SAndroid Build Coastguard Worker res = parseNamedBit(Op.Name, Operands, Op.Type);
2361*9880d681SAndroid Build Coastguard Worker } else if (Op.Type == AMDGPUOperand::ImmTyOModSI) {
2362*9880d681SAndroid Build Coastguard Worker res = parseOModOperand(Operands);
2363*9880d681SAndroid Build Coastguard Worker } else if (Op.Type == AMDGPUOperand::ImmTySdwaDstSel ||
2364*9880d681SAndroid Build Coastguard Worker Op.Type == AMDGPUOperand::ImmTySdwaSrc0Sel ||
2365*9880d681SAndroid Build Coastguard Worker Op.Type == AMDGPUOperand::ImmTySdwaSrc1Sel) {
2366*9880d681SAndroid Build Coastguard Worker res = parseSDWASel(Operands, Op.Name, Op.Type);
2367*9880d681SAndroid Build Coastguard Worker } else if (Op.Type == AMDGPUOperand::ImmTySdwaDstUnused) {
2368*9880d681SAndroid Build Coastguard Worker res = parseSDWADstUnused(Operands);
2369*9880d681SAndroid Build Coastguard Worker } else {
2370*9880d681SAndroid Build Coastguard Worker res = parseIntWithPrefix(Op.Name, Operands, Op.Type, Op.ConvertResult);
2371*9880d681SAndroid Build Coastguard Worker }
2372*9880d681SAndroid Build Coastguard Worker if (res != MatchOperand_NoMatch) {
2373*9880d681SAndroid Build Coastguard Worker return res;
2374*9880d681SAndroid Build Coastguard Worker }
2375*9880d681SAndroid Build Coastguard Worker }
2376*9880d681SAndroid Build Coastguard Worker return MatchOperand_NoMatch;
2377*9880d681SAndroid Build Coastguard Worker }
2378*9880d681SAndroid Build Coastguard Worker
parseOModOperand(OperandVector & Operands)2379*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy AMDGPUAsmParser::parseOModOperand(OperandVector &Operands)
2380*9880d681SAndroid Build Coastguard Worker {
2381*9880d681SAndroid Build Coastguard Worker StringRef Name = Parser.getTok().getString();
2382*9880d681SAndroid Build Coastguard Worker if (Name == "mul") {
2383*9880d681SAndroid Build Coastguard Worker return parseIntWithPrefix("mul", Operands, AMDGPUOperand::ImmTyOModSI, ConvertOmodMul);
2384*9880d681SAndroid Build Coastguard Worker } else if (Name == "div") {
2385*9880d681SAndroid Build Coastguard Worker return parseIntWithPrefix("div", Operands, AMDGPUOperand::ImmTyOModSI, ConvertOmodDiv);
2386*9880d681SAndroid Build Coastguard Worker } else {
2387*9880d681SAndroid Build Coastguard Worker return MatchOperand_NoMatch;
2388*9880d681SAndroid Build Coastguard Worker }
2389*9880d681SAndroid Build Coastguard Worker }
2390*9880d681SAndroid Build Coastguard Worker
cvtId(MCInst & Inst,const OperandVector & Operands)2391*9880d681SAndroid Build Coastguard Worker void AMDGPUAsmParser::cvtId(MCInst &Inst, const OperandVector &Operands) {
2392*9880d681SAndroid Build Coastguard Worker unsigned I = 1;
2393*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
2394*9880d681SAndroid Build Coastguard Worker for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
2395*9880d681SAndroid Build Coastguard Worker ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
2396*9880d681SAndroid Build Coastguard Worker }
2397*9880d681SAndroid Build Coastguard Worker for (unsigned E = Operands.size(); I != E; ++I)
2398*9880d681SAndroid Build Coastguard Worker ((AMDGPUOperand &)*Operands[I]).addRegOrImmOperands(Inst, 1);
2399*9880d681SAndroid Build Coastguard Worker }
2400*9880d681SAndroid Build Coastguard Worker
cvtVOP3_2_mod(MCInst & Inst,const OperandVector & Operands)2401*9880d681SAndroid Build Coastguard Worker void AMDGPUAsmParser::cvtVOP3_2_mod(MCInst &Inst, const OperandVector &Operands) {
2402*9880d681SAndroid Build Coastguard Worker uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
2403*9880d681SAndroid Build Coastguard Worker if (TSFlags & SIInstrFlags::VOP3) {
2404*9880d681SAndroid Build Coastguard Worker cvtVOP3(Inst, Operands);
2405*9880d681SAndroid Build Coastguard Worker } else {
2406*9880d681SAndroid Build Coastguard Worker cvtId(Inst, Operands);
2407*9880d681SAndroid Build Coastguard Worker }
2408*9880d681SAndroid Build Coastguard Worker }
2409*9880d681SAndroid Build Coastguard Worker
cvtVOP3(MCInst & Inst,const OperandVector & Operands)2410*9880d681SAndroid Build Coastguard Worker void AMDGPUAsmParser::cvtVOP3(MCInst &Inst, const OperandVector &Operands) {
2411*9880d681SAndroid Build Coastguard Worker OptionalImmIndexMap OptionalIdx;
2412*9880d681SAndroid Build Coastguard Worker unsigned I = 1;
2413*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
2414*9880d681SAndroid Build Coastguard Worker for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
2415*9880d681SAndroid Build Coastguard Worker ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
2416*9880d681SAndroid Build Coastguard Worker }
2417*9880d681SAndroid Build Coastguard Worker
2418*9880d681SAndroid Build Coastguard Worker for (unsigned E = Operands.size(); I != E; ++I) {
2419*9880d681SAndroid Build Coastguard Worker AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
2420*9880d681SAndroid Build Coastguard Worker if (Op.isRegOrImmWithInputMods()) {
2421*9880d681SAndroid Build Coastguard Worker // only fp modifiers allowed in VOP3
2422*9880d681SAndroid Build Coastguard Worker Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
2423*9880d681SAndroid Build Coastguard Worker } else if (Op.isImm()) {
2424*9880d681SAndroid Build Coastguard Worker OptionalIdx[Op.getImmTy()] = I;
2425*9880d681SAndroid Build Coastguard Worker } else {
2426*9880d681SAndroid Build Coastguard Worker assert(false);
2427*9880d681SAndroid Build Coastguard Worker }
2428*9880d681SAndroid Build Coastguard Worker }
2429*9880d681SAndroid Build Coastguard Worker
2430*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI);
2431*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOModSI);
2432*9880d681SAndroid Build Coastguard Worker }
2433*9880d681SAndroid Build Coastguard Worker
2434*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2435*9880d681SAndroid Build Coastguard Worker // dpp
2436*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2437*9880d681SAndroid Build Coastguard Worker
isDPPCtrl() const2438*9880d681SAndroid Build Coastguard Worker bool AMDGPUOperand::isDPPCtrl() const {
2439*9880d681SAndroid Build Coastguard Worker bool result = isImm() && getImmTy() == ImmTyDppCtrl && isUInt<9>(getImm());
2440*9880d681SAndroid Build Coastguard Worker if (result) {
2441*9880d681SAndroid Build Coastguard Worker int64_t Imm = getImm();
2442*9880d681SAndroid Build Coastguard Worker return ((Imm >= 0x000) && (Imm <= 0x0ff)) ||
2443*9880d681SAndroid Build Coastguard Worker ((Imm >= 0x101) && (Imm <= 0x10f)) ||
2444*9880d681SAndroid Build Coastguard Worker ((Imm >= 0x111) && (Imm <= 0x11f)) ||
2445*9880d681SAndroid Build Coastguard Worker ((Imm >= 0x121) && (Imm <= 0x12f)) ||
2446*9880d681SAndroid Build Coastguard Worker (Imm == 0x130) ||
2447*9880d681SAndroid Build Coastguard Worker (Imm == 0x134) ||
2448*9880d681SAndroid Build Coastguard Worker (Imm == 0x138) ||
2449*9880d681SAndroid Build Coastguard Worker (Imm == 0x13c) ||
2450*9880d681SAndroid Build Coastguard Worker (Imm == 0x140) ||
2451*9880d681SAndroid Build Coastguard Worker (Imm == 0x141) ||
2452*9880d681SAndroid Build Coastguard Worker (Imm == 0x142) ||
2453*9880d681SAndroid Build Coastguard Worker (Imm == 0x143);
2454*9880d681SAndroid Build Coastguard Worker }
2455*9880d681SAndroid Build Coastguard Worker return false;
2456*9880d681SAndroid Build Coastguard Worker }
2457*9880d681SAndroid Build Coastguard Worker
2458*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseDPPCtrl(OperandVector & Operands)2459*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseDPPCtrl(OperandVector &Operands) {
2460*9880d681SAndroid Build Coastguard Worker SMLoc S = Parser.getTok().getLoc();
2461*9880d681SAndroid Build Coastguard Worker StringRef Prefix;
2462*9880d681SAndroid Build Coastguard Worker int64_t Int;
2463*9880d681SAndroid Build Coastguard Worker
2464*9880d681SAndroid Build Coastguard Worker if (getLexer().getKind() == AsmToken::Identifier) {
2465*9880d681SAndroid Build Coastguard Worker Prefix = Parser.getTok().getString();
2466*9880d681SAndroid Build Coastguard Worker } else {
2467*9880d681SAndroid Build Coastguard Worker return MatchOperand_NoMatch;
2468*9880d681SAndroid Build Coastguard Worker }
2469*9880d681SAndroid Build Coastguard Worker
2470*9880d681SAndroid Build Coastguard Worker if (Prefix == "row_mirror") {
2471*9880d681SAndroid Build Coastguard Worker Int = 0x140;
2472*9880d681SAndroid Build Coastguard Worker } else if (Prefix == "row_half_mirror") {
2473*9880d681SAndroid Build Coastguard Worker Int = 0x141;
2474*9880d681SAndroid Build Coastguard Worker } else {
2475*9880d681SAndroid Build Coastguard Worker // Check to prevent parseDPPCtrlOps from eating invalid tokens
2476*9880d681SAndroid Build Coastguard Worker if (Prefix != "quad_perm"
2477*9880d681SAndroid Build Coastguard Worker && Prefix != "row_shl"
2478*9880d681SAndroid Build Coastguard Worker && Prefix != "row_shr"
2479*9880d681SAndroid Build Coastguard Worker && Prefix != "row_ror"
2480*9880d681SAndroid Build Coastguard Worker && Prefix != "wave_shl"
2481*9880d681SAndroid Build Coastguard Worker && Prefix != "wave_rol"
2482*9880d681SAndroid Build Coastguard Worker && Prefix != "wave_shr"
2483*9880d681SAndroid Build Coastguard Worker && Prefix != "wave_ror"
2484*9880d681SAndroid Build Coastguard Worker && Prefix != "row_bcast") {
2485*9880d681SAndroid Build Coastguard Worker return MatchOperand_NoMatch;
2486*9880d681SAndroid Build Coastguard Worker }
2487*9880d681SAndroid Build Coastguard Worker
2488*9880d681SAndroid Build Coastguard Worker Parser.Lex();
2489*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Colon))
2490*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2491*9880d681SAndroid Build Coastguard Worker
2492*9880d681SAndroid Build Coastguard Worker if (Prefix == "quad_perm") {
2493*9880d681SAndroid Build Coastguard Worker // quad_perm:[%d,%d,%d,%d]
2494*9880d681SAndroid Build Coastguard Worker Parser.Lex();
2495*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::LBrac))
2496*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2497*9880d681SAndroid Build Coastguard Worker
2498*9880d681SAndroid Build Coastguard Worker Parser.Lex();
2499*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
2500*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2501*9880d681SAndroid Build Coastguard Worker Int = getLexer().getTok().getIntVal();
2502*9880d681SAndroid Build Coastguard Worker
2503*9880d681SAndroid Build Coastguard Worker Parser.Lex();
2504*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Comma))
2505*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2506*9880d681SAndroid Build Coastguard Worker Parser.Lex();
2507*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
2508*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2509*9880d681SAndroid Build Coastguard Worker Int += (getLexer().getTok().getIntVal() << 2);
2510*9880d681SAndroid Build Coastguard Worker
2511*9880d681SAndroid Build Coastguard Worker Parser.Lex();
2512*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Comma))
2513*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2514*9880d681SAndroid Build Coastguard Worker Parser.Lex();
2515*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
2516*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2517*9880d681SAndroid Build Coastguard Worker Int += (getLexer().getTok().getIntVal() << 4);
2518*9880d681SAndroid Build Coastguard Worker
2519*9880d681SAndroid Build Coastguard Worker Parser.Lex();
2520*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Comma))
2521*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2522*9880d681SAndroid Build Coastguard Worker Parser.Lex();
2523*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
2524*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2525*9880d681SAndroid Build Coastguard Worker Int += (getLexer().getTok().getIntVal() << 6);
2526*9880d681SAndroid Build Coastguard Worker
2527*9880d681SAndroid Build Coastguard Worker Parser.Lex();
2528*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::RBrac))
2529*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2530*9880d681SAndroid Build Coastguard Worker
2531*9880d681SAndroid Build Coastguard Worker } else {
2532*9880d681SAndroid Build Coastguard Worker // sel:%d
2533*9880d681SAndroid Build Coastguard Worker Parser.Lex();
2534*9880d681SAndroid Build Coastguard Worker if (getLexer().isNot(AsmToken::Integer))
2535*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2536*9880d681SAndroid Build Coastguard Worker Int = getLexer().getTok().getIntVal();
2537*9880d681SAndroid Build Coastguard Worker
2538*9880d681SAndroid Build Coastguard Worker if (Prefix == "row_shl") {
2539*9880d681SAndroid Build Coastguard Worker Int |= 0x100;
2540*9880d681SAndroid Build Coastguard Worker } else if (Prefix == "row_shr") {
2541*9880d681SAndroid Build Coastguard Worker Int |= 0x110;
2542*9880d681SAndroid Build Coastguard Worker } else if (Prefix == "row_ror") {
2543*9880d681SAndroid Build Coastguard Worker Int |= 0x120;
2544*9880d681SAndroid Build Coastguard Worker } else if (Prefix == "wave_shl") {
2545*9880d681SAndroid Build Coastguard Worker Int = 0x130;
2546*9880d681SAndroid Build Coastguard Worker } else if (Prefix == "wave_rol") {
2547*9880d681SAndroid Build Coastguard Worker Int = 0x134;
2548*9880d681SAndroid Build Coastguard Worker } else if (Prefix == "wave_shr") {
2549*9880d681SAndroid Build Coastguard Worker Int = 0x138;
2550*9880d681SAndroid Build Coastguard Worker } else if (Prefix == "wave_ror") {
2551*9880d681SAndroid Build Coastguard Worker Int = 0x13C;
2552*9880d681SAndroid Build Coastguard Worker } else if (Prefix == "row_bcast") {
2553*9880d681SAndroid Build Coastguard Worker if (Int == 15) {
2554*9880d681SAndroid Build Coastguard Worker Int = 0x142;
2555*9880d681SAndroid Build Coastguard Worker } else if (Int == 31) {
2556*9880d681SAndroid Build Coastguard Worker Int = 0x143;
2557*9880d681SAndroid Build Coastguard Worker } else {
2558*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2559*9880d681SAndroid Build Coastguard Worker }
2560*9880d681SAndroid Build Coastguard Worker } else {
2561*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2562*9880d681SAndroid Build Coastguard Worker }
2563*9880d681SAndroid Build Coastguard Worker }
2564*9880d681SAndroid Build Coastguard Worker }
2565*9880d681SAndroid Build Coastguard Worker Parser.Lex(); // eat last token
2566*9880d681SAndroid Build Coastguard Worker
2567*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateImm(Int, S,
2568*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::ImmTyDppCtrl));
2569*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
2570*9880d681SAndroid Build Coastguard Worker }
2571*9880d681SAndroid Build Coastguard Worker
defaultRowMask() const2572*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr AMDGPUAsmParser::defaultRowMask() const {
2573*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateImm(0xf, SMLoc(), AMDGPUOperand::ImmTyDppRowMask);
2574*9880d681SAndroid Build Coastguard Worker }
2575*9880d681SAndroid Build Coastguard Worker
defaultBankMask() const2576*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr AMDGPUAsmParser::defaultBankMask() const {
2577*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateImm(0xf, SMLoc(), AMDGPUOperand::ImmTyDppBankMask);
2578*9880d681SAndroid Build Coastguard Worker }
2579*9880d681SAndroid Build Coastguard Worker
defaultBoundCtrl() const2580*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::Ptr AMDGPUAsmParser::defaultBoundCtrl() const {
2581*9880d681SAndroid Build Coastguard Worker return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTyDppBoundCtrl);
2582*9880d681SAndroid Build Coastguard Worker }
2583*9880d681SAndroid Build Coastguard Worker
cvtDPP(MCInst & Inst,const OperandVector & Operands)2584*9880d681SAndroid Build Coastguard Worker void AMDGPUAsmParser::cvtDPP(MCInst &Inst, const OperandVector &Operands) {
2585*9880d681SAndroid Build Coastguard Worker OptionalImmIndexMap OptionalIdx;
2586*9880d681SAndroid Build Coastguard Worker
2587*9880d681SAndroid Build Coastguard Worker unsigned I = 1;
2588*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
2589*9880d681SAndroid Build Coastguard Worker for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
2590*9880d681SAndroid Build Coastguard Worker ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
2591*9880d681SAndroid Build Coastguard Worker }
2592*9880d681SAndroid Build Coastguard Worker
2593*9880d681SAndroid Build Coastguard Worker for (unsigned E = Operands.size(); I != E; ++I) {
2594*9880d681SAndroid Build Coastguard Worker AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
2595*9880d681SAndroid Build Coastguard Worker // Add the register arguments
2596*9880d681SAndroid Build Coastguard Worker if (Op.isRegOrImmWithInputMods()) {
2597*9880d681SAndroid Build Coastguard Worker // Only float modifiers supported in DPP
2598*9880d681SAndroid Build Coastguard Worker Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
2599*9880d681SAndroid Build Coastguard Worker } else if (Op.isDPPCtrl()) {
2600*9880d681SAndroid Build Coastguard Worker Op.addImmOperands(Inst, 1);
2601*9880d681SAndroid Build Coastguard Worker } else if (Op.isImm()) {
2602*9880d681SAndroid Build Coastguard Worker // Handle optional arguments
2603*9880d681SAndroid Build Coastguard Worker OptionalIdx[Op.getImmTy()] = I;
2604*9880d681SAndroid Build Coastguard Worker } else {
2605*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid operand type");
2606*9880d681SAndroid Build Coastguard Worker }
2607*9880d681SAndroid Build Coastguard Worker }
2608*9880d681SAndroid Build Coastguard Worker
2609*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppRowMask, 0xf);
2610*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBankMask, 0xf);
2611*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBoundCtrl);
2612*9880d681SAndroid Build Coastguard Worker }
2613*9880d681SAndroid Build Coastguard Worker
2614*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2615*9880d681SAndroid Build Coastguard Worker // sdwa
2616*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2617*9880d681SAndroid Build Coastguard Worker
2618*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseSDWASel(OperandVector & Operands,StringRef Prefix,AMDGPUOperand::ImmTy Type)2619*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseSDWASel(OperandVector &Operands, StringRef Prefix,
2620*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::ImmTy Type) {
2621*9880d681SAndroid Build Coastguard Worker SMLoc S = Parser.getTok().getLoc();
2622*9880d681SAndroid Build Coastguard Worker StringRef Value;
2623*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy res;
2624*9880d681SAndroid Build Coastguard Worker
2625*9880d681SAndroid Build Coastguard Worker res = parseStringWithPrefix(Prefix, Value);
2626*9880d681SAndroid Build Coastguard Worker if (res != MatchOperand_Success) {
2627*9880d681SAndroid Build Coastguard Worker return res;
2628*9880d681SAndroid Build Coastguard Worker }
2629*9880d681SAndroid Build Coastguard Worker
2630*9880d681SAndroid Build Coastguard Worker int64_t Int;
2631*9880d681SAndroid Build Coastguard Worker Int = StringSwitch<int64_t>(Value)
2632*9880d681SAndroid Build Coastguard Worker .Case("BYTE_0", 0)
2633*9880d681SAndroid Build Coastguard Worker .Case("BYTE_1", 1)
2634*9880d681SAndroid Build Coastguard Worker .Case("BYTE_2", 2)
2635*9880d681SAndroid Build Coastguard Worker .Case("BYTE_3", 3)
2636*9880d681SAndroid Build Coastguard Worker .Case("WORD_0", 4)
2637*9880d681SAndroid Build Coastguard Worker .Case("WORD_1", 5)
2638*9880d681SAndroid Build Coastguard Worker .Case("DWORD", 6)
2639*9880d681SAndroid Build Coastguard Worker .Default(0xffffffff);
2640*9880d681SAndroid Build Coastguard Worker Parser.Lex(); // eat last token
2641*9880d681SAndroid Build Coastguard Worker
2642*9880d681SAndroid Build Coastguard Worker if (Int == 0xffffffff) {
2643*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2644*9880d681SAndroid Build Coastguard Worker }
2645*9880d681SAndroid Build Coastguard Worker
2646*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateImm(Int, S, Type));
2647*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
2648*9880d681SAndroid Build Coastguard Worker }
2649*9880d681SAndroid Build Coastguard Worker
2650*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy
parseSDWADstUnused(OperandVector & Operands)2651*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::parseSDWADstUnused(OperandVector &Operands) {
2652*9880d681SAndroid Build Coastguard Worker SMLoc S = Parser.getTok().getLoc();
2653*9880d681SAndroid Build Coastguard Worker StringRef Value;
2654*9880d681SAndroid Build Coastguard Worker AMDGPUAsmParser::OperandMatchResultTy res;
2655*9880d681SAndroid Build Coastguard Worker
2656*9880d681SAndroid Build Coastguard Worker res = parseStringWithPrefix("dst_unused", Value);
2657*9880d681SAndroid Build Coastguard Worker if (res != MatchOperand_Success) {
2658*9880d681SAndroid Build Coastguard Worker return res;
2659*9880d681SAndroid Build Coastguard Worker }
2660*9880d681SAndroid Build Coastguard Worker
2661*9880d681SAndroid Build Coastguard Worker int64_t Int;
2662*9880d681SAndroid Build Coastguard Worker Int = StringSwitch<int64_t>(Value)
2663*9880d681SAndroid Build Coastguard Worker .Case("UNUSED_PAD", 0)
2664*9880d681SAndroid Build Coastguard Worker .Case("UNUSED_SEXT", 1)
2665*9880d681SAndroid Build Coastguard Worker .Case("UNUSED_PRESERVE", 2)
2666*9880d681SAndroid Build Coastguard Worker .Default(0xffffffff);
2667*9880d681SAndroid Build Coastguard Worker Parser.Lex(); // eat last token
2668*9880d681SAndroid Build Coastguard Worker
2669*9880d681SAndroid Build Coastguard Worker if (Int == 0xffffffff) {
2670*9880d681SAndroid Build Coastguard Worker return MatchOperand_ParseFail;
2671*9880d681SAndroid Build Coastguard Worker }
2672*9880d681SAndroid Build Coastguard Worker
2673*9880d681SAndroid Build Coastguard Worker Operands.push_back(AMDGPUOperand::CreateImm(Int, S,
2674*9880d681SAndroid Build Coastguard Worker AMDGPUOperand::ImmTySdwaDstUnused));
2675*9880d681SAndroid Build Coastguard Worker return MatchOperand_Success;
2676*9880d681SAndroid Build Coastguard Worker }
2677*9880d681SAndroid Build Coastguard Worker
cvtSdwaVOP1(MCInst & Inst,const OperandVector & Operands)2678*9880d681SAndroid Build Coastguard Worker void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst, const OperandVector &Operands) {
2679*9880d681SAndroid Build Coastguard Worker cvtSDWA(Inst, Operands, SIInstrFlags::VOP1);
2680*9880d681SAndroid Build Coastguard Worker }
2681*9880d681SAndroid Build Coastguard Worker
cvtSdwaVOP2(MCInst & Inst,const OperandVector & Operands)2682*9880d681SAndroid Build Coastguard Worker void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst, const OperandVector &Operands) {
2683*9880d681SAndroid Build Coastguard Worker cvtSDWA(Inst, Operands, SIInstrFlags::VOP2);
2684*9880d681SAndroid Build Coastguard Worker }
2685*9880d681SAndroid Build Coastguard Worker
cvtSdwaVOPC(MCInst & Inst,const OperandVector & Operands)2686*9880d681SAndroid Build Coastguard Worker void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst, const OperandVector &Operands) {
2687*9880d681SAndroid Build Coastguard Worker cvtSDWA(Inst, Operands, SIInstrFlags::VOPC);
2688*9880d681SAndroid Build Coastguard Worker }
2689*9880d681SAndroid Build Coastguard Worker
cvtSDWA(MCInst & Inst,const OperandVector & Operands,uint64_t BasicInstType)2690*9880d681SAndroid Build Coastguard Worker void AMDGPUAsmParser::cvtSDWA(MCInst &Inst, const OperandVector &Operands,
2691*9880d681SAndroid Build Coastguard Worker uint64_t BasicInstType) {
2692*9880d681SAndroid Build Coastguard Worker OptionalImmIndexMap OptionalIdx;
2693*9880d681SAndroid Build Coastguard Worker
2694*9880d681SAndroid Build Coastguard Worker unsigned I = 1;
2695*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
2696*9880d681SAndroid Build Coastguard Worker for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
2697*9880d681SAndroid Build Coastguard Worker ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
2698*9880d681SAndroid Build Coastguard Worker }
2699*9880d681SAndroid Build Coastguard Worker
2700*9880d681SAndroid Build Coastguard Worker for (unsigned E = Operands.size(); I != E; ++I) {
2701*9880d681SAndroid Build Coastguard Worker AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
2702*9880d681SAndroid Build Coastguard Worker // Add the register arguments
2703*9880d681SAndroid Build Coastguard Worker if (BasicInstType == SIInstrFlags::VOPC &&
2704*9880d681SAndroid Build Coastguard Worker Op.isReg() &&
2705*9880d681SAndroid Build Coastguard Worker Op.Reg.RegNo == AMDGPU::VCC) {
2706*9880d681SAndroid Build Coastguard Worker // VOPC sdwa use "vcc" token as dst. Skip it.
2707*9880d681SAndroid Build Coastguard Worker continue;
2708*9880d681SAndroid Build Coastguard Worker } else if (Op.isRegOrImmWithInputMods()) {
2709*9880d681SAndroid Build Coastguard Worker Op.addRegOrImmWithInputModsOperands(Inst, 2);
2710*9880d681SAndroid Build Coastguard Worker } else if (Op.isImm()) {
2711*9880d681SAndroid Build Coastguard Worker // Handle optional arguments
2712*9880d681SAndroid Build Coastguard Worker OptionalIdx[Op.getImmTy()] = I;
2713*9880d681SAndroid Build Coastguard Worker } else {
2714*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid operand type");
2715*9880d681SAndroid Build Coastguard Worker }
2716*9880d681SAndroid Build Coastguard Worker }
2717*9880d681SAndroid Build Coastguard Worker
2718*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI, 0);
2719*9880d681SAndroid Build Coastguard Worker
2720*9880d681SAndroid Build Coastguard Worker if (Inst.getOpcode() == AMDGPU::V_NOP_sdwa) {
2721*9880d681SAndroid Build Coastguard Worker // V_NOP_sdwa has no optional sdwa arguments
2722*9880d681SAndroid Build Coastguard Worker return;
2723*9880d681SAndroid Build Coastguard Worker }
2724*9880d681SAndroid Build Coastguard Worker switch (BasicInstType) {
2725*9880d681SAndroid Build Coastguard Worker case SIInstrFlags::VOP1: {
2726*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaDstSel, 6);
2727*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaDstUnused, 2);
2728*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaSrc0Sel, 6);
2729*9880d681SAndroid Build Coastguard Worker break;
2730*9880d681SAndroid Build Coastguard Worker }
2731*9880d681SAndroid Build Coastguard Worker case SIInstrFlags::VOP2: {
2732*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaDstSel, 6);
2733*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaDstUnused, 2);
2734*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaSrc0Sel, 6);
2735*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaSrc1Sel, 6);
2736*9880d681SAndroid Build Coastguard Worker break;
2737*9880d681SAndroid Build Coastguard Worker }
2738*9880d681SAndroid Build Coastguard Worker case SIInstrFlags::VOPC: {
2739*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaSrc0Sel, 6);
2740*9880d681SAndroid Build Coastguard Worker addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaSrc1Sel, 6);
2741*9880d681SAndroid Build Coastguard Worker break;
2742*9880d681SAndroid Build Coastguard Worker }
2743*9880d681SAndroid Build Coastguard Worker default:
2744*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
2745*9880d681SAndroid Build Coastguard Worker }
2746*9880d681SAndroid Build Coastguard Worker }
2747*9880d681SAndroid Build Coastguard Worker
2748*9880d681SAndroid Build Coastguard Worker /// Force static initialization.
LLVMInitializeAMDGPUAsmParser()2749*9880d681SAndroid Build Coastguard Worker extern "C" void LLVMInitializeAMDGPUAsmParser() {
2750*9880d681SAndroid Build Coastguard Worker RegisterMCAsmParser<AMDGPUAsmParser> A(TheAMDGPUTarget);
2751*9880d681SAndroid Build Coastguard Worker RegisterMCAsmParser<AMDGPUAsmParser> B(TheGCNTarget);
2752*9880d681SAndroid Build Coastguard Worker }
2753*9880d681SAndroid Build Coastguard Worker
2754*9880d681SAndroid Build Coastguard Worker #define GET_REGISTER_MATCHER
2755*9880d681SAndroid Build Coastguard Worker #define GET_MATCHER_IMPLEMENTATION
2756*9880d681SAndroid Build Coastguard Worker #include "AMDGPUGenAsmMatcher.inc"
2757*9880d681SAndroid Build Coastguard Worker
2758*9880d681SAndroid Build Coastguard Worker
2759*9880d681SAndroid Build Coastguard Worker // This fuction should be defined after auto-generated include so that we have
2760*9880d681SAndroid Build Coastguard Worker // MatchClassKind enum defined
validateTargetOperandClass(MCParsedAsmOperand & Op,unsigned Kind)2761*9880d681SAndroid Build Coastguard Worker unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &Op,
2762*9880d681SAndroid Build Coastguard Worker unsigned Kind) {
2763*9880d681SAndroid Build Coastguard Worker // Tokens like "glc" would be parsed as immediate operands in ParseOperand().
2764*9880d681SAndroid Build Coastguard Worker // But MatchInstructionImpl() expects to meet token and fails to validate
2765*9880d681SAndroid Build Coastguard Worker // operand. This method checks if we are given immediate operand but expect to
2766*9880d681SAndroid Build Coastguard Worker // get corresponding token.
2767*9880d681SAndroid Build Coastguard Worker AMDGPUOperand &Operand = (AMDGPUOperand&)Op;
2768*9880d681SAndroid Build Coastguard Worker switch (Kind) {
2769*9880d681SAndroid Build Coastguard Worker case MCK_addr64:
2770*9880d681SAndroid Build Coastguard Worker return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
2771*9880d681SAndroid Build Coastguard Worker case MCK_gds:
2772*9880d681SAndroid Build Coastguard Worker return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
2773*9880d681SAndroid Build Coastguard Worker case MCK_glc:
2774*9880d681SAndroid Build Coastguard Worker return Operand.isGLC() ? Match_Success : Match_InvalidOperand;
2775*9880d681SAndroid Build Coastguard Worker case MCK_idxen:
2776*9880d681SAndroid Build Coastguard Worker return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
2777*9880d681SAndroid Build Coastguard Worker case MCK_offen:
2778*9880d681SAndroid Build Coastguard Worker return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
2779*9880d681SAndroid Build Coastguard Worker case MCK_SSrc32:
2780*9880d681SAndroid Build Coastguard Worker // When operands have expression values, they will return true for isToken,
2781*9880d681SAndroid Build Coastguard Worker // because it is not possible to distinguish between a token and an
2782*9880d681SAndroid Build Coastguard Worker // expression at parse time. MatchInstructionImpl() will always try to
2783*9880d681SAndroid Build Coastguard Worker // match an operand as a token, when isToken returns true, and when the
2784*9880d681SAndroid Build Coastguard Worker // name of the expression is not a valid token, the match will fail,
2785*9880d681SAndroid Build Coastguard Worker // so we need to handle it here.
2786*9880d681SAndroid Build Coastguard Worker return Operand.isSSrc32() ? Match_Success : Match_InvalidOperand;
2787*9880d681SAndroid Build Coastguard Worker case MCK_SoppBrTarget:
2788*9880d681SAndroid Build Coastguard Worker return Operand.isSoppBrTarget() ? Match_Success : Match_InvalidOperand;
2789*9880d681SAndroid Build Coastguard Worker default: return Match_InvalidOperand;
2790*9880d681SAndroid Build Coastguard Worker }
2791*9880d681SAndroid Build Coastguard Worker }
2792