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