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