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