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