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/AMDGPUAsmUtils.h"
15 #include "Utils/AMDGPUBaseInfo.h"
16 #include "Utils/AMDKernelCodeTUtils.h"
17 #include "llvm/ADT/APFloat.h"
18 #include "llvm/ADT/APInt.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/SmallBitVector.h"
22 #include "llvm/ADT/SmallString.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/ADT/StringSwitch.h"
25 #include "llvm/ADT/Twine.h"
26 #include "llvm/BinaryFormat/ELF.h"
27 #include "llvm/CodeGen/MachineValueType.h"
28 #include "llvm/MC/MCAsmInfo.h"
29 #include "llvm/MC/MCContext.h"
30 #include "llvm/MC/MCExpr.h"
31 #include "llvm/MC/MCInst.h"
32 #include "llvm/MC/MCInstrDesc.h"
33 #include "llvm/MC/MCInstrInfo.h"
34 #include "llvm/MC/MCParser/MCAsmLexer.h"
35 #include "llvm/MC/MCParser/MCAsmParser.h"
36 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
37 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
38 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
39 #include "llvm/MC/MCRegisterInfo.h"
40 #include "llvm/MC/MCStreamer.h"
41 #include "llvm/MC/MCSubtargetInfo.h"
42 #include "llvm/MC/MCSymbol.h"
43 #include "llvm/Support/Casting.h"
44 #include "llvm/Support/ErrorHandling.h"
45 #include "llvm/Support/MathExtras.h"
46 #include "llvm/Support/SMLoc.h"
47 #include "llvm/Support/TargetRegistry.h"
48 #include "llvm/Support/raw_ostream.h"
49 #include <algorithm>
50 #include <cassert>
51 #include <cstdint>
52 #include <cstring>
53 #include <iterator>
54 #include <map>
55 #include <memory>
56 #include <string>
57 
58 using namespace llvm;
59 using namespace llvm::AMDGPU;
60 
61 namespace {
62 
63 class AMDGPUAsmParser;
64 
65 enum RegisterKind { IS_UNKNOWN, IS_VGPR, IS_SGPR, IS_TTMP, IS_SPECIAL };
66 
67 //===----------------------------------------------------------------------===//
68 // Operand
69 //===----------------------------------------------------------------------===//
70 
71 class AMDGPUOperand : public MCParsedAsmOperand {
72   enum KindTy {
73     Token,
74     Immediate,
75     Register,
76     Expression
77   } Kind;
78 
79   SMLoc StartLoc, EndLoc;
80   const AMDGPUAsmParser *AsmParser;
81 
82 public:
83   AMDGPUOperand(KindTy Kind_, const AMDGPUAsmParser *AsmParser_)
84     : MCParsedAsmOperand(), Kind(Kind_), AsmParser(AsmParser_) {}
85 
86   typedef std::unique_ptr<AMDGPUOperand> Ptr;
87 
88   struct Modifiers {
89     bool Abs = false;
90     bool Neg = false;
91     bool Sext = false;
92 
93     bool hasFPModifiers() const { return Abs || Neg; }
94     bool hasIntModifiers() const { return Sext; }
95     bool hasModifiers() const { return hasFPModifiers() || hasIntModifiers(); }
96 
97     int64_t getFPModifiersOperand() const {
98       int64_t Operand = 0;
99       Operand |= Abs ? SISrcMods::ABS : 0;
100       Operand |= Neg ? SISrcMods::NEG : 0;
101       return Operand;
102     }
103 
104     int64_t getIntModifiersOperand() const {
105       int64_t Operand = 0;
106       Operand |= Sext ? SISrcMods::SEXT : 0;
107       return Operand;
108     }
109 
110     int64_t getModifiersOperand() const {
111       assert(!(hasFPModifiers() && hasIntModifiers())
112            && "fp and int modifiers should not be used simultaneously");
113       if (hasFPModifiers()) {
114         return getFPModifiersOperand();
115       } else if (hasIntModifiers()) {
116         return getIntModifiersOperand();
117       } else {
118         return 0;
119       }
120     }
121 
122     friend raw_ostream &operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
123   };
124 
125   enum ImmTy {
126     ImmTyNone,
127     ImmTyGDS,
128     ImmTyOffen,
129     ImmTyIdxen,
130     ImmTyAddr64,
131     ImmTyOffset,
132     ImmTyOffset0,
133     ImmTyOffset1,
134     ImmTyGLC,
135     ImmTySLC,
136     ImmTyTFE,
137     ImmTyClampSI,
138     ImmTyOModSI,
139     ImmTyDppCtrl,
140     ImmTyDppRowMask,
141     ImmTyDppBankMask,
142     ImmTyDppBoundCtrl,
143     ImmTySdwaDstSel,
144     ImmTySdwaSrc0Sel,
145     ImmTySdwaSrc1Sel,
146     ImmTySdwaDstUnused,
147     ImmTyDMask,
148     ImmTyUNorm,
149     ImmTyDA,
150     ImmTyR128,
151     ImmTyLWE,
152     ImmTyExpTgt,
153     ImmTyExpCompr,
154     ImmTyExpVM,
155     ImmTyHwreg,
156     ImmTyOff,
157     ImmTySendMsg,
158     ImmTyInterpSlot,
159     ImmTyInterpAttr,
160     ImmTyAttrChan,
161     ImmTyOpSel,
162     ImmTyOpSelHi,
163     ImmTyNegLo,
164     ImmTyNegHi,
165     ImmTySwizzle
166   };
167 
168   struct TokOp {
169     const char *Data;
170     unsigned Length;
171   };
172 
173   struct ImmOp {
174     int64_t Val;
175     ImmTy Type;
176     bool IsFPImm;
177     Modifiers Mods;
178   };
179 
180   struct RegOp {
181     unsigned RegNo;
182     bool IsForcedVOP3;
183     Modifiers Mods;
184   };
185 
186   union {
187     TokOp Tok;
188     ImmOp Imm;
189     RegOp Reg;
190     const MCExpr *Expr;
191   };
192 
193   bool isToken() const override {
194     if (Kind == Token)
195       return true;
196 
197     if (Kind != Expression || !Expr)
198       return false;
199 
200     // When parsing operands, we can't always tell if something was meant to be
201     // a token, like 'gds', or an expression that references a global variable.
202     // In this case, we assume the string is an expression, and if we need to
203     // interpret is a token, then we treat the symbol name as the token.
204     return isa<MCSymbolRefExpr>(Expr);
205   }
206 
207   bool isImm() const override {
208     return Kind == Immediate;
209   }
210 
211   bool isInlinableImm(MVT type) const;
212   bool isLiteralImm(MVT type) const;
213 
214   bool isRegKind() const {
215     return Kind == Register;
216   }
217 
218   bool isReg() const override {
219     return isRegKind() && !hasModifiers();
220   }
221 
222   bool isRegOrImmWithInputMods(MVT type) const {
223     return isRegKind() || isInlinableImm(type);
224   }
225 
226   bool isRegOrImmWithInt16InputMods() const {
227     return isRegOrImmWithInputMods(MVT::i16);
228   }
229 
230   bool isRegOrImmWithInt32InputMods() const {
231     return isRegOrImmWithInputMods(MVT::i32);
232   }
233 
234   bool isRegOrImmWithInt64InputMods() const {
235     return isRegOrImmWithInputMods(MVT::i64);
236   }
237 
238   bool isRegOrImmWithFP16InputMods() const {
239     return isRegOrImmWithInputMods(MVT::f16);
240   }
241 
242   bool isRegOrImmWithFP32InputMods() const {
243     return isRegOrImmWithInputMods(MVT::f32);
244   }
245 
246   bool isRegOrImmWithFP64InputMods() const {
247     return isRegOrImmWithInputMods(MVT::f64);
248   }
249 
250   bool isVReg() const {
251     return isRegClass(AMDGPU::VGPR_32RegClassID) ||
252            isRegClass(AMDGPU::VReg_64RegClassID) ||
253            isRegClass(AMDGPU::VReg_96RegClassID) ||
254            isRegClass(AMDGPU::VReg_128RegClassID) ||
255            isRegClass(AMDGPU::VReg_256RegClassID) ||
256            isRegClass(AMDGPU::VReg_512RegClassID);
257   }
258 
259   bool isVReg32OrOff() const {
260     return isOff() || isRegClass(AMDGPU::VGPR_32RegClassID);
261   }
262 
263   bool isImmTy(ImmTy ImmT) const {
264     return isImm() && Imm.Type == ImmT;
265   }
266 
267   bool isImmModifier() const {
268     return isImm() && Imm.Type != ImmTyNone;
269   }
270 
271   bool isClampSI() const { return isImmTy(ImmTyClampSI); }
272   bool isOModSI() const { return isImmTy(ImmTyOModSI); }
273   bool isDMask() const { return isImmTy(ImmTyDMask); }
274   bool isUNorm() const { return isImmTy(ImmTyUNorm); }
275   bool isDA() const { return isImmTy(ImmTyDA); }
276   bool isR128() const { return isImmTy(ImmTyUNorm); }
277   bool isLWE() const { return isImmTy(ImmTyLWE); }
278   bool isOff() const { return isImmTy(ImmTyOff); }
279   bool isExpTgt() const { return isImmTy(ImmTyExpTgt); }
280   bool isExpVM() const { return isImmTy(ImmTyExpVM); }
281   bool isExpCompr() const { return isImmTy(ImmTyExpCompr); }
282   bool isOffen() const { return isImmTy(ImmTyOffen); }
283   bool isIdxen() const { return isImmTy(ImmTyIdxen); }
284   bool isAddr64() const { return isImmTy(ImmTyAddr64); }
285   bool isOffset() const { return isImmTy(ImmTyOffset) && isUInt<16>(getImm()); }
286   bool isOffset0() const { return isImmTy(ImmTyOffset0) && isUInt<16>(getImm()); }
287   bool isOffset1() const { return isImmTy(ImmTyOffset1) && isUInt<8>(getImm()); }
288 
289   bool isOffsetU12() const { return isImmTy(ImmTyOffset) && isUInt<12>(getImm()); }
290   bool isOffsetS13() const { return isImmTy(ImmTyOffset) && isInt<13>(getImm()); }
291   bool isGDS() const { return isImmTy(ImmTyGDS); }
292   bool isGLC() const { return isImmTy(ImmTyGLC); }
293   bool isSLC() const { return isImmTy(ImmTySLC); }
294   bool isTFE() const { return isImmTy(ImmTyTFE); }
295   bool isBankMask() const { return isImmTy(ImmTyDppBankMask); }
296   bool isRowMask() const { return isImmTy(ImmTyDppRowMask); }
297   bool isBoundCtrl() const { return isImmTy(ImmTyDppBoundCtrl); }
298   bool isSDWADstSel() const { return isImmTy(ImmTySdwaDstSel); }
299   bool isSDWASrc0Sel() const { return isImmTy(ImmTySdwaSrc0Sel); }
300   bool isSDWASrc1Sel() const { return isImmTy(ImmTySdwaSrc1Sel); }
301   bool isSDWADstUnused() const { return isImmTy(ImmTySdwaDstUnused); }
302   bool isInterpSlot() const { return isImmTy(ImmTyInterpSlot); }
303   bool isInterpAttr() const { return isImmTy(ImmTyInterpAttr); }
304   bool isAttrChan() const { return isImmTy(ImmTyAttrChan); }
305   bool isOpSel() const { return isImmTy(ImmTyOpSel); }
306   bool isOpSelHi() const { return isImmTy(ImmTyOpSelHi); }
307   bool isNegLo() const { return isImmTy(ImmTyNegLo); }
308   bool isNegHi() const { return isImmTy(ImmTyNegHi); }
309 
310   bool isMod() const {
311     return isClampSI() || isOModSI();
312   }
313 
314   bool isRegOrImm() const {
315     return isReg() || isImm();
316   }
317 
318   bool isRegClass(unsigned RCID) const;
319 
320   bool isRegOrInlineNoMods(unsigned RCID, MVT type) const {
321     return (isRegClass(RCID) || isInlinableImm(type)) && !hasModifiers();
322   }
323 
324   bool isSCSrcB16() const {
325     return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
326   }
327 
328   bool isSCSrcV2B16() const {
329     return isSCSrcB16();
330   }
331 
332   bool isSCSrcB32() const {
333     return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
334   }
335 
336   bool isSCSrcB64() const {
337     return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
338   }
339 
340   bool isSCSrcF16() const {
341     return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
342   }
343 
344   bool isSCSrcV2F16() const {
345     return isSCSrcF16();
346   }
347 
348   bool isSCSrcF32() const {
349     return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
350   }
351 
352   bool isSCSrcF64() const {
353     return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
354   }
355 
356   bool isSSrcB32() const {
357     return isSCSrcB32() || isLiteralImm(MVT::i32) || isExpr();
358   }
359 
360   bool isSSrcB16() const {
361     return isSCSrcB16() || isLiteralImm(MVT::i16);
362   }
363 
364   bool isSSrcV2B16() const {
365     llvm_unreachable("cannot happen");
366     return isSSrcB16();
367   }
368 
369   bool isSSrcB64() const {
370     // TODO: Find out how SALU supports extension of 32-bit literals to 64 bits.
371     // See isVSrc64().
372     return isSCSrcB64() || isLiteralImm(MVT::i64);
373   }
374 
375   bool isSSrcF32() const {
376     return isSCSrcB32() || isLiteralImm(MVT::f32) || isExpr();
377   }
378 
379   bool isSSrcF64() const {
380     return isSCSrcB64() || isLiteralImm(MVT::f64);
381   }
382 
383   bool isSSrcF16() const {
384     return isSCSrcB16() || isLiteralImm(MVT::f16);
385   }
386 
387   bool isSSrcV2F16() const {
388     llvm_unreachable("cannot happen");
389     return isSSrcF16();
390   }
391 
392   bool isVCSrcB32() const {
393     return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
394   }
395 
396   bool isVCSrcB64() const {
397     return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
398   }
399 
400   bool isVCSrcB16() const {
401     return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
402   }
403 
404   bool isVCSrcV2B16() const {
405     return isVCSrcB16();
406   }
407 
408   bool isVCSrcF32() const {
409     return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
410   }
411 
412   bool isVCSrcF64() const {
413     return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
414   }
415 
416   bool isVCSrcF16() const {
417     return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
418   }
419 
420   bool isVCSrcV2F16() const {
421     return isVCSrcF16();
422   }
423 
424   bool isVSrcB32() const {
425     return isVCSrcF32() || isLiteralImm(MVT::i32);
426   }
427 
428   bool isVSrcB64() const {
429     return isVCSrcF64() || isLiteralImm(MVT::i64);
430   }
431 
432   bool isVSrcB16() const {
433     return isVCSrcF16() || isLiteralImm(MVT::i16);
434   }
435 
436   bool isVSrcV2B16() const {
437     llvm_unreachable("cannot happen");
438     return isVSrcB16();
439   }
440 
441   bool isVSrcF32() const {
442     return isVCSrcF32() || isLiteralImm(MVT::f32);
443   }
444 
445   bool isVSrcF64() const {
446     return isVCSrcF64() || isLiteralImm(MVT::f64);
447   }
448 
449   bool isVSrcF16() const {
450     return isVCSrcF16() || isLiteralImm(MVT::f16);
451   }
452 
453   bool isVSrcV2F16() const {
454     llvm_unreachable("cannot happen");
455     return isVSrcF16();
456   }
457 
458   bool isKImmFP32() const {
459     return isLiteralImm(MVT::f32);
460   }
461 
462   bool isKImmFP16() const {
463     return isLiteralImm(MVT::f16);
464   }
465 
466   bool isMem() const override {
467     return false;
468   }
469 
470   bool isExpr() const {
471     return Kind == Expression;
472   }
473 
474   bool isSoppBrTarget() const {
475     return isExpr() || isImm();
476   }
477 
478   bool isSWaitCnt() const;
479   bool isHwreg() const;
480   bool isSendMsg() const;
481   bool isSwizzle() const;
482   bool isSMRDOffset8() const;
483   bool isSMRDOffset20() const;
484   bool isSMRDLiteralOffset() const;
485   bool isDPPCtrl() const;
486   bool isGPRIdxMode() const;
487   bool isS16Imm() const;
488   bool isU16Imm() const;
489 
490   StringRef getExpressionAsToken() const {
491     assert(isExpr());
492     const MCSymbolRefExpr *S = cast<MCSymbolRefExpr>(Expr);
493     return S->getSymbol().getName();
494   }
495 
496   StringRef getToken() const {
497     assert(isToken());
498 
499     if (Kind == Expression)
500       return getExpressionAsToken();
501 
502     return StringRef(Tok.Data, Tok.Length);
503   }
504 
505   int64_t getImm() const {
506     assert(isImm());
507     return Imm.Val;
508   }
509 
510   ImmTy getImmTy() const {
511     assert(isImm());
512     return Imm.Type;
513   }
514 
515   unsigned getReg() const override {
516     return Reg.RegNo;
517   }
518 
519   SMLoc getStartLoc() const override {
520     return StartLoc;
521   }
522 
523   SMLoc getEndLoc() const override {
524     return EndLoc;
525   }
526 
527   Modifiers getModifiers() const {
528     assert(isRegKind() || isImmTy(ImmTyNone));
529     return isRegKind() ? Reg.Mods : Imm.Mods;
530   }
531 
532   void setModifiers(Modifiers Mods) {
533     assert(isRegKind() || isImmTy(ImmTyNone));
534     if (isRegKind())
535       Reg.Mods = Mods;
536     else
537       Imm.Mods = Mods;
538   }
539 
540   bool hasModifiers() const {
541     return getModifiers().hasModifiers();
542   }
543 
544   bool hasFPModifiers() const {
545     return getModifiers().hasFPModifiers();
546   }
547 
548   bool hasIntModifiers() const {
549     return getModifiers().hasIntModifiers();
550   }
551 
552   uint64_t applyInputFPModifiers(uint64_t Val, unsigned Size) const;
553 
554   void addImmOperands(MCInst &Inst, unsigned N, bool ApplyModifiers = true) const;
555 
556   void addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyModifiers) const;
557 
558   template <unsigned Bitwidth>
559   void addKImmFPOperands(MCInst &Inst, unsigned N) const;
560 
561   void addKImmFP16Operands(MCInst &Inst, unsigned N) const {
562     addKImmFPOperands<16>(Inst, N);
563   }
564 
565   void addKImmFP32Operands(MCInst &Inst, unsigned N) const {
566     addKImmFPOperands<32>(Inst, N);
567   }
568 
569   void addRegOperands(MCInst &Inst, unsigned N) const;
570 
571   void addRegOrImmOperands(MCInst &Inst, unsigned N) const {
572     if (isRegKind())
573       addRegOperands(Inst, N);
574     else if (isExpr())
575       Inst.addOperand(MCOperand::createExpr(Expr));
576     else
577       addImmOperands(Inst, N);
578   }
579 
580   void addRegOrImmWithInputModsOperands(MCInst &Inst, unsigned N) const {
581     Modifiers Mods = getModifiers();
582     Inst.addOperand(MCOperand::createImm(Mods.getModifiersOperand()));
583     if (isRegKind()) {
584       addRegOperands(Inst, N);
585     } else {
586       addImmOperands(Inst, N, false);
587     }
588   }
589 
590   void addRegOrImmWithFPInputModsOperands(MCInst &Inst, unsigned N) const {
591     assert(!hasIntModifiers());
592     addRegOrImmWithInputModsOperands(Inst, N);
593   }
594 
595   void addRegOrImmWithIntInputModsOperands(MCInst &Inst, unsigned N) const {
596     assert(!hasFPModifiers());
597     addRegOrImmWithInputModsOperands(Inst, N);
598   }
599 
600   void addRegWithInputModsOperands(MCInst &Inst, unsigned N) const {
601     Modifiers Mods = getModifiers();
602     Inst.addOperand(MCOperand::createImm(Mods.getModifiersOperand()));
603     assert(isRegKind());
604     addRegOperands(Inst, N);
605   }
606 
607   void addRegWithFPInputModsOperands(MCInst &Inst, unsigned N) const {
608     assert(!hasIntModifiers());
609     addRegWithInputModsOperands(Inst, N);
610   }
611 
612   void addRegWithIntInputModsOperands(MCInst &Inst, unsigned N) const {
613     assert(!hasFPModifiers());
614     addRegWithInputModsOperands(Inst, N);
615   }
616 
617   void addSoppBrTargetOperands(MCInst &Inst, unsigned N) const {
618     if (isImm())
619       addImmOperands(Inst, N);
620     else {
621       assert(isExpr());
622       Inst.addOperand(MCOperand::createExpr(Expr));
623     }
624   }
625 
626   static void printImmTy(raw_ostream& OS, ImmTy Type) {
627     switch (Type) {
628     case ImmTyNone: OS << "None"; break;
629     case ImmTyGDS: OS << "GDS"; break;
630     case ImmTyOffen: OS << "Offen"; break;
631     case ImmTyIdxen: OS << "Idxen"; break;
632     case ImmTyAddr64: OS << "Addr64"; break;
633     case ImmTyOffset: OS << "Offset"; break;
634     case ImmTyOffset0: OS << "Offset0"; break;
635     case ImmTyOffset1: OS << "Offset1"; break;
636     case ImmTyGLC: OS << "GLC"; break;
637     case ImmTySLC: OS << "SLC"; break;
638     case ImmTyTFE: OS << "TFE"; break;
639     case ImmTyClampSI: OS << "ClampSI"; break;
640     case ImmTyOModSI: OS << "OModSI"; break;
641     case ImmTyDppCtrl: OS << "DppCtrl"; break;
642     case ImmTyDppRowMask: OS << "DppRowMask"; break;
643     case ImmTyDppBankMask: OS << "DppBankMask"; break;
644     case ImmTyDppBoundCtrl: OS << "DppBoundCtrl"; break;
645     case ImmTySdwaDstSel: OS << "SdwaDstSel"; break;
646     case ImmTySdwaSrc0Sel: OS << "SdwaSrc0Sel"; break;
647     case ImmTySdwaSrc1Sel: OS << "SdwaSrc1Sel"; break;
648     case ImmTySdwaDstUnused: OS << "SdwaDstUnused"; break;
649     case ImmTyDMask: OS << "DMask"; break;
650     case ImmTyUNorm: OS << "UNorm"; break;
651     case ImmTyDA: OS << "DA"; break;
652     case ImmTyR128: OS << "R128"; break;
653     case ImmTyLWE: OS << "LWE"; break;
654     case ImmTyOff: OS << "Off"; break;
655     case ImmTyExpTgt: OS << "ExpTgt"; break;
656     case ImmTyExpCompr: OS << "ExpCompr"; break;
657     case ImmTyExpVM: OS << "ExpVM"; break;
658     case ImmTyHwreg: OS << "Hwreg"; break;
659     case ImmTySendMsg: OS << "SendMsg"; break;
660     case ImmTyInterpSlot: OS << "InterpSlot"; break;
661     case ImmTyInterpAttr: OS << "InterpAttr"; break;
662     case ImmTyAttrChan: OS << "AttrChan"; break;
663     case ImmTyOpSel: OS << "OpSel"; break;
664     case ImmTyOpSelHi: OS << "OpSelHi"; break;
665     case ImmTyNegLo: OS << "NegLo"; break;
666     case ImmTyNegHi: OS << "NegHi"; break;
667     case ImmTySwizzle: OS << "Swizzle"; break;
668     }
669   }
670 
671   void print(raw_ostream &OS) const override {
672     switch (Kind) {
673     case Register:
674       OS << "<register " << getReg() << " mods: " << Reg.Mods << '>';
675       break;
676     case Immediate:
677       OS << '<' << getImm();
678       if (getImmTy() != ImmTyNone) {
679         OS << " type: "; printImmTy(OS, getImmTy());
680       }
681       OS << " mods: " << Imm.Mods << '>';
682       break;
683     case Token:
684       OS << '\'' << getToken() << '\'';
685       break;
686     case Expression:
687       OS << "<expr " << *Expr << '>';
688       break;
689     }
690   }
691 
692   static AMDGPUOperand::Ptr CreateImm(const AMDGPUAsmParser *AsmParser,
693                                       int64_t Val, SMLoc Loc,
694                                       ImmTy Type = ImmTyNone,
695                                       bool IsFPImm = false) {
696     auto Op = llvm::make_unique<AMDGPUOperand>(Immediate, AsmParser);
697     Op->Imm.Val = Val;
698     Op->Imm.IsFPImm = IsFPImm;
699     Op->Imm.Type = Type;
700     Op->Imm.Mods = Modifiers();
701     Op->StartLoc = Loc;
702     Op->EndLoc = Loc;
703     return Op;
704   }
705 
706   static AMDGPUOperand::Ptr CreateToken(const AMDGPUAsmParser *AsmParser,
707                                         StringRef Str, SMLoc Loc,
708                                         bool HasExplicitEncodingSize = true) {
709     auto Res = llvm::make_unique<AMDGPUOperand>(Token, AsmParser);
710     Res->Tok.Data = Str.data();
711     Res->Tok.Length = Str.size();
712     Res->StartLoc = Loc;
713     Res->EndLoc = Loc;
714     return Res;
715   }
716 
717   static AMDGPUOperand::Ptr CreateReg(const AMDGPUAsmParser *AsmParser,
718                                       unsigned RegNo, SMLoc S,
719                                       SMLoc E,
720                                       bool ForceVOP3) {
721     auto Op = llvm::make_unique<AMDGPUOperand>(Register, AsmParser);
722     Op->Reg.RegNo = RegNo;
723     Op->Reg.Mods = Modifiers();
724     Op->Reg.IsForcedVOP3 = ForceVOP3;
725     Op->StartLoc = S;
726     Op->EndLoc = E;
727     return Op;
728   }
729 
730   static AMDGPUOperand::Ptr CreateExpr(const AMDGPUAsmParser *AsmParser,
731                                        const class MCExpr *Expr, SMLoc S) {
732     auto Op = llvm::make_unique<AMDGPUOperand>(Expression, AsmParser);
733     Op->Expr = Expr;
734     Op->StartLoc = S;
735     Op->EndLoc = S;
736     return Op;
737   }
738 };
739 
740 raw_ostream &operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods) {
741   OS << "abs:" << Mods.Abs << " neg: " << Mods.Neg << " sext:" << Mods.Sext;
742   return OS;
743 }
744 
745 //===----------------------------------------------------------------------===//
746 // AsmParser
747 //===----------------------------------------------------------------------===//
748 
749 // Holds info related to the current kernel, e.g. count of SGPRs used.
750 // Kernel scope begins at .amdgpu_hsa_kernel directive, ends at next
751 // .amdgpu_hsa_kernel or at EOF.
752 class KernelScopeInfo {
753   int SgprIndexUnusedMin = -1;
754   int VgprIndexUnusedMin = -1;
755   MCContext *Ctx = nullptr;
756 
757   void usesSgprAt(int i) {
758     if (i >= SgprIndexUnusedMin) {
759       SgprIndexUnusedMin = ++i;
760       if (Ctx) {
761         MCSymbol * const Sym = Ctx->getOrCreateSymbol(Twine(".kernel.sgpr_count"));
762         Sym->setVariableValue(MCConstantExpr::create(SgprIndexUnusedMin, *Ctx));
763       }
764     }
765   }
766 
767   void usesVgprAt(int i) {
768     if (i >= VgprIndexUnusedMin) {
769       VgprIndexUnusedMin = ++i;
770       if (Ctx) {
771         MCSymbol * const Sym = Ctx->getOrCreateSymbol(Twine(".kernel.vgpr_count"));
772         Sym->setVariableValue(MCConstantExpr::create(VgprIndexUnusedMin, *Ctx));
773       }
774     }
775   }
776 
777 public:
778   KernelScopeInfo() = default;
779 
780   void initialize(MCContext &Context) {
781     Ctx = &Context;
782     usesSgprAt(SgprIndexUnusedMin = -1);
783     usesVgprAt(VgprIndexUnusedMin = -1);
784   }
785 
786   void usesRegister(RegisterKind RegKind, unsigned DwordRegIndex, unsigned RegWidth) {
787     switch (RegKind) {
788       case IS_SGPR: usesSgprAt(DwordRegIndex + RegWidth - 1); break;
789       case IS_VGPR: usesVgprAt(DwordRegIndex + RegWidth - 1); break;
790       default: break;
791     }
792   }
793 };
794 
795 class AMDGPUAsmParser : public MCTargetAsmParser {
796   const MCInstrInfo &MII;
797   MCAsmParser &Parser;
798 
799   unsigned ForcedEncodingSize = 0;
800   bool ForcedDPP = false;
801   bool ForcedSDWA = false;
802   KernelScopeInfo KernelScope;
803 
804   /// @name Auto-generated Match Functions
805   /// {
806 
807 #define GET_ASSEMBLER_HEADER
808 #include "AMDGPUGenAsmMatcher.inc"
809 
810   /// }
811 
812 private:
813   bool ParseAsAbsoluteExpression(uint32_t &Ret);
814   bool ParseDirectiveMajorMinor(uint32_t &Major, uint32_t &Minor);
815   bool ParseDirectiveHSACodeObjectVersion();
816   bool ParseDirectiveHSACodeObjectISA();
817   bool ParseDirectiveCodeObjectMetadata();
818   bool ParseAMDKernelCodeTValue(StringRef ID, amd_kernel_code_t &Header);
819   bool ParseDirectiveAMDKernelCodeT();
820   bool subtargetHasRegister(const MCRegisterInfo &MRI, unsigned RegNo) const;
821   bool ParseDirectiveAMDGPUHsaKernel();
822   bool AddNextRegisterToList(unsigned& Reg, unsigned& RegWidth,
823                              RegisterKind RegKind, unsigned Reg1,
824                              unsigned RegNum);
825   bool ParseAMDGPURegister(RegisterKind& RegKind, unsigned& Reg,
826                            unsigned& RegNum, unsigned& RegWidth,
827                            unsigned *DwordRegIndex);
828   void cvtMubufImpl(MCInst &Inst, const OperandVector &Operands,
829                     bool IsAtomic, bool IsAtomicReturn);
830   void cvtDSImpl(MCInst &Inst, const OperandVector &Operands,
831                  bool IsGdsHardcoded);
832 
833 public:
834   enum AMDGPUMatchResultTy {
835     Match_PreferE32 = FIRST_TARGET_MATCH_RESULT_TY
836   };
837 
838   typedef std::map<AMDGPUOperand::ImmTy, unsigned> OptionalImmIndexMap;
839 
840   AMDGPUAsmParser(const MCSubtargetInfo &STI, MCAsmParser &_Parser,
841                const MCInstrInfo &MII,
842                const MCTargetOptions &Options)
843       : MCTargetAsmParser(Options, STI), MII(MII), Parser(_Parser) {
844     MCAsmParserExtension::Initialize(Parser);
845 
846     if (getFeatureBits().none()) {
847       // Set default features.
848       copySTI().ToggleFeature("SOUTHERN_ISLANDS");
849     }
850 
851     setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
852 
853     {
854       // TODO: make those pre-defined variables read-only.
855       // Currently there is none suitable machinery in the core llvm-mc for this.
856       // MCSymbol::isRedefinable is intended for another purpose, and
857       // AsmParser::parseDirectiveSet() cannot be specialized for specific target.
858       AMDGPU::IsaInfo::IsaVersion ISA =
859           AMDGPU::IsaInfo::getIsaVersion(getFeatureBits());
860       MCContext &Ctx = getContext();
861       MCSymbol *Sym =
862           Ctx.getOrCreateSymbol(Twine(".option.machine_version_major"));
863       Sym->setVariableValue(MCConstantExpr::create(ISA.Major, Ctx));
864       Sym = Ctx.getOrCreateSymbol(Twine(".option.machine_version_minor"));
865       Sym->setVariableValue(MCConstantExpr::create(ISA.Minor, Ctx));
866       Sym = Ctx.getOrCreateSymbol(Twine(".option.machine_version_stepping"));
867       Sym->setVariableValue(MCConstantExpr::create(ISA.Stepping, Ctx));
868     }
869     KernelScope.initialize(getContext());
870   }
871 
872   bool isSI() const {
873     return AMDGPU::isSI(getSTI());
874   }
875 
876   bool isCI() const {
877     return AMDGPU::isCI(getSTI());
878   }
879 
880   bool isVI() const {
881     return AMDGPU::isVI(getSTI());
882   }
883 
884   bool isGFX9() const {
885     return AMDGPU::isGFX9(getSTI());
886   }
887 
888   bool hasInv2PiInlineImm() const {
889     return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
890   }
891 
892   bool hasFlatOffsets() const {
893     return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
894   }
895 
896   bool hasSGPR102_SGPR103() const {
897     return !isVI();
898   }
899 
900   AMDGPUTargetStreamer &getTargetStreamer() {
901     MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
902     return static_cast<AMDGPUTargetStreamer &>(TS);
903   }
904 
905   const MCRegisterInfo *getMRI() const {
906     // We need this const_cast because for some reason getContext() is not const
907     // in MCAsmParser.
908     return const_cast<AMDGPUAsmParser*>(this)->getContext().getRegisterInfo();
909   }
910 
911   const MCInstrInfo *getMII() const {
912     return &MII;
913   }
914 
915   const FeatureBitset &getFeatureBits() const {
916     return getSTI().getFeatureBits();
917   }
918 
919   void setForcedEncodingSize(unsigned Size) { ForcedEncodingSize = Size; }
920   void setForcedDPP(bool ForceDPP_) { ForcedDPP = ForceDPP_; }
921   void setForcedSDWA(bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
922 
923   unsigned getForcedEncodingSize() const { return ForcedEncodingSize; }
924   bool isForcedVOP3() const { return ForcedEncodingSize == 64; }
925   bool isForcedDPP() const { return ForcedDPP; }
926   bool isForcedSDWA() const { return ForcedSDWA; }
927   ArrayRef<unsigned> getMatchedVariants() const;
928 
929   std::unique_ptr<AMDGPUOperand> parseRegister();
930   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
931   unsigned checkTargetMatchPredicate(MCInst &Inst) override;
932   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
933                                       unsigned Kind) override;
934   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
935                                OperandVector &Operands, MCStreamer &Out,
936                                uint64_t &ErrorInfo,
937                                bool MatchingInlineAsm) override;
938   bool ParseDirective(AsmToken DirectiveID) override;
939   OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Mnemonic);
940   StringRef parseMnemonicSuffix(StringRef Name);
941   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
942                         SMLoc NameLoc, OperandVector &Operands) override;
943   //bool ProcessInstruction(MCInst &Inst);
944 
945   OperandMatchResultTy parseIntWithPrefix(const char *Prefix, int64_t &Int);
946 
947   OperandMatchResultTy
948   parseIntWithPrefix(const char *Prefix, OperandVector &Operands,
949                      AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
950                      bool (*ConvertResult)(int64_t &) = nullptr);
951 
952   OperandMatchResultTy parseOperandArrayWithPrefix(
953     const char *Prefix,
954     OperandVector &Operands,
955     AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
956     bool (*ConvertResult)(int64_t&) = nullptr);
957 
958   OperandMatchResultTy
959   parseNamedBit(const char *Name, OperandVector &Operands,
960                 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
961   OperandMatchResultTy parseStringWithPrefix(StringRef Prefix,
962                                              StringRef &Value);
963 
964   bool parseAbsoluteExpr(int64_t &Val, bool AbsMod = false);
965   OperandMatchResultTy parseImm(OperandVector &Operands, bool AbsMod = false);
966   OperandMatchResultTy parseReg(OperandVector &Operands);
967   OperandMatchResultTy parseRegOrImm(OperandVector &Operands, bool AbsMod = false);
968   OperandMatchResultTy parseRegOrImmWithFPInputMods(OperandVector &Operands, bool AllowImm = true);
969   OperandMatchResultTy parseRegOrImmWithIntInputMods(OperandVector &Operands, bool AllowImm = true);
970   OperandMatchResultTy parseRegWithFPInputMods(OperandVector &Operands);
971   OperandMatchResultTy parseRegWithIntInputMods(OperandVector &Operands);
972   OperandMatchResultTy parseVReg32OrOff(OperandVector &Operands);
973 
974   void cvtDSOffset01(MCInst &Inst, const OperandVector &Operands);
975   void cvtDS(MCInst &Inst, const OperandVector &Operands) { cvtDSImpl(Inst, Operands, false); }
976   void cvtDSGds(MCInst &Inst, const OperandVector &Operands) { cvtDSImpl(Inst, Operands, true); }
977   void cvtExp(MCInst &Inst, const OperandVector &Operands);
978 
979   bool parseCnt(int64_t &IntVal);
980   OperandMatchResultTy parseSWaitCntOps(OperandVector &Operands);
981   OperandMatchResultTy parseHwreg(OperandVector &Operands);
982 
983 private:
984   struct OperandInfoTy {
985     int64_t Id;
986     bool IsSymbolic;
987     OperandInfoTy(int64_t Id_) : Id(Id_), IsSymbolic(false) { }
988   };
989 
990   bool parseSendMsgConstruct(OperandInfoTy &Msg, OperandInfoTy &Operation, int64_t &StreamId);
991   bool parseHwregConstruct(OperandInfoTy &HwReg, int64_t &Offset, int64_t &Width);
992 
993   void errorExpTgt();
994   OperandMatchResultTy parseExpTgtImpl(StringRef Str, uint8_t &Val);
995 
996   bool validateOperandLimitations(const MCInst &Inst);
997   bool usesConstantBus(const MCInst &Inst, unsigned OpIdx);
998   bool isInlineConstant(const MCInst &Inst, unsigned OpIdx) const;
999   unsigned findImplicitSGPRReadInVOP(const MCInst &Inst) const;
1000 
1001   bool trySkipId(const StringRef Id);
1002   bool trySkipToken(const AsmToken::TokenKind Kind);
1003   bool skipToken(const AsmToken::TokenKind Kind, const StringRef ErrMsg);
1004   bool parseString(StringRef &Val, const StringRef ErrMsg = "expected a string");
1005   bool parseExpr(int64_t &Imm);
1006 
1007 public:
1008   OperandMatchResultTy parseOptionalOperand(OperandVector &Operands);
1009 
1010   OperandMatchResultTy parseExpTgt(OperandVector &Operands);
1011   OperandMatchResultTy parseSendMsgOp(OperandVector &Operands);
1012   OperandMatchResultTy parseInterpSlot(OperandVector &Operands);
1013   OperandMatchResultTy parseInterpAttr(OperandVector &Operands);
1014   OperandMatchResultTy parseSOppBrTarget(OperandVector &Operands);
1015 
1016   bool parseSwizzleOperands(const unsigned OpNum, int64_t* Op,
1017                             const unsigned MinVal,
1018                             const unsigned MaxVal,
1019                             const StringRef ErrMsg);
1020   OperandMatchResultTy parseSwizzleOp(OperandVector &Operands);
1021   bool parseSwizzleOffset(int64_t &Imm);
1022   bool parseSwizzleMacro(int64_t &Imm);
1023   bool parseSwizzleQuadPerm(int64_t &Imm);
1024   bool parseSwizzleBitmaskPerm(int64_t &Imm);
1025   bool parseSwizzleBroadcast(int64_t &Imm);
1026   bool parseSwizzleSwap(int64_t &Imm);
1027   bool parseSwizzleReverse(int64_t &Imm);
1028 
1029   void cvtMubuf(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, false, false); }
1030   void cvtMubufAtomic(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, false); }
1031   void cvtMubufAtomicReturn(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, true); }
1032   AMDGPUOperand::Ptr defaultGLC() const;
1033   AMDGPUOperand::Ptr defaultSLC() const;
1034   AMDGPUOperand::Ptr defaultTFE() const;
1035 
1036   AMDGPUOperand::Ptr defaultDMask() const;
1037   AMDGPUOperand::Ptr defaultUNorm() const;
1038   AMDGPUOperand::Ptr defaultDA() const;
1039   AMDGPUOperand::Ptr defaultR128() const;
1040   AMDGPUOperand::Ptr defaultLWE() const;
1041   AMDGPUOperand::Ptr defaultSMRDOffset8() const;
1042   AMDGPUOperand::Ptr defaultSMRDOffset20() const;
1043   AMDGPUOperand::Ptr defaultSMRDLiteralOffset() const;
1044   AMDGPUOperand::Ptr defaultOffsetU12() const;
1045   AMDGPUOperand::Ptr defaultOffsetS13() const;
1046 
1047   OperandMatchResultTy parseOModOperand(OperandVector &Operands);
1048 
1049   void cvtId(MCInst &Inst, const OperandVector &Operands);
1050   void cvtVOP3_2_mod(MCInst &Inst, const OperandVector &Operands);
1051 
1052   void cvtVOP3Impl(MCInst &Inst,
1053                    const OperandVector &Operands,
1054                    OptionalImmIndexMap &OptionalIdx);
1055   void cvtVOP3(MCInst &Inst, const OperandVector &Operands);
1056   void cvtVOP3OMod(MCInst &Inst, const OperandVector &Operands);
1057   void cvtVOP3P(MCInst &Inst, const OperandVector &Operands);
1058 
1059   void cvtMIMG(MCInst &Inst, const OperandVector &Operands);
1060   void cvtMIMGAtomic(MCInst &Inst, const OperandVector &Operands);
1061 
1062   OperandMatchResultTy parseDPPCtrl(OperandVector &Operands);
1063   AMDGPUOperand::Ptr defaultRowMask() const;
1064   AMDGPUOperand::Ptr defaultBankMask() const;
1065   AMDGPUOperand::Ptr defaultBoundCtrl() const;
1066   void cvtDPP(MCInst &Inst, const OperandVector &Operands);
1067 
1068   OperandMatchResultTy parseSDWASel(OperandVector &Operands, StringRef Prefix,
1069                                     AMDGPUOperand::ImmTy Type);
1070   OperandMatchResultTy parseSDWADstUnused(OperandVector &Operands);
1071   void cvtSdwaVOP1(MCInst &Inst, const OperandVector &Operands);
1072   void cvtSdwaVOP2(MCInst &Inst, const OperandVector &Operands);
1073   void cvtSdwaVOP2b(MCInst &Inst, const OperandVector &Operands);
1074   void cvtSdwaVOPC(MCInst &Inst, const OperandVector &Operands);
1075   void cvtSDWA(MCInst &Inst, const OperandVector &Operands,
1076                 uint64_t BasicInstType, bool skipVcc = false);
1077 };
1078 
1079 struct OptionalOperand {
1080   const char *Name;
1081   AMDGPUOperand::ImmTy Type;
1082   bool IsBit;
1083   bool (*ConvertResult)(int64_t&);
1084 };
1085 
1086 } // end anonymous namespace
1087 
1088 // May be called with integer type with equivalent bitwidth.
1089 static const fltSemantics *getFltSemantics(unsigned Size) {
1090   switch (Size) {
1091   case 4:
1092     return &APFloat::IEEEsingle();
1093   case 8:
1094     return &APFloat::IEEEdouble();
1095   case 2:
1096     return &APFloat::IEEEhalf();
1097   default:
1098     llvm_unreachable("unsupported fp type");
1099   }
1100 }
1101 
1102 static const fltSemantics *getFltSemantics(MVT VT) {
1103   return getFltSemantics(VT.getSizeInBits() / 8);
1104 }
1105 
1106 static const fltSemantics *getOpFltSemantics(uint8_t OperandType) {
1107   switch (OperandType) {
1108   case AMDGPU::OPERAND_REG_IMM_INT32:
1109   case AMDGPU::OPERAND_REG_IMM_FP32:
1110   case AMDGPU::OPERAND_REG_INLINE_C_INT32:
1111   case AMDGPU::OPERAND_REG_INLINE_C_FP32:
1112     return &APFloat::IEEEsingle();
1113   case AMDGPU::OPERAND_REG_IMM_INT64:
1114   case AMDGPU::OPERAND_REG_IMM_FP64:
1115   case AMDGPU::OPERAND_REG_INLINE_C_INT64:
1116   case AMDGPU::OPERAND_REG_INLINE_C_FP64:
1117     return &APFloat::IEEEdouble();
1118   case AMDGPU::OPERAND_REG_IMM_INT16:
1119   case AMDGPU::OPERAND_REG_IMM_FP16:
1120   case AMDGPU::OPERAND_REG_INLINE_C_INT16:
1121   case AMDGPU::OPERAND_REG_INLINE_C_FP16:
1122   case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
1123   case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
1124     return &APFloat::IEEEhalf();
1125   default:
1126     llvm_unreachable("unsupported fp type");
1127   }
1128 }
1129 
1130 //===----------------------------------------------------------------------===//
1131 // Operand
1132 //===----------------------------------------------------------------------===//
1133 
1134 static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT) {
1135   bool Lost;
1136 
1137   // Convert literal to single precision
1138   APFloat::opStatus Status = FPLiteral.convert(*getFltSemantics(VT),
1139                                                APFloat::rmNearestTiesToEven,
1140                                                &Lost);
1141   // We allow precision lost but not overflow or underflow
1142   if (Status != APFloat::opOK &&
1143       Lost &&
1144       ((Status & APFloat::opOverflow)  != 0 ||
1145        (Status & APFloat::opUnderflow) != 0)) {
1146     return false;
1147   }
1148 
1149   return true;
1150 }
1151 
1152 bool AMDGPUOperand::isInlinableImm(MVT type) const {
1153   if (!isImmTy(ImmTyNone)) {
1154     // Only plain immediates are inlinable (e.g. "clamp" attribute is not)
1155     return false;
1156   }
1157   // TODO: We should avoid using host float here. It would be better to
1158   // check the float bit values which is what a few other places do.
1159   // We've had bot failures before due to weird NaN support on mips hosts.
1160 
1161   APInt Literal(64, Imm.Val);
1162 
1163   if (Imm.IsFPImm) { // We got fp literal token
1164     if (type == MVT::f64 || type == MVT::i64) { // Expected 64-bit operand
1165       return AMDGPU::isInlinableLiteral64(Imm.Val,
1166                                           AsmParser->hasInv2PiInlineImm());
1167     }
1168 
1169     APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64, Imm.Val));
1170     if (!canLosslesslyConvertToFPType(FPLiteral, type))
1171       return false;
1172 
1173     if (type.getScalarSizeInBits() == 16) {
1174       return AMDGPU::isInlinableLiteral16(
1175         static_cast<int16_t>(FPLiteral.bitcastToAPInt().getZExtValue()),
1176         AsmParser->hasInv2PiInlineImm());
1177     }
1178 
1179     // Check if single precision literal is inlinable
1180     return AMDGPU::isInlinableLiteral32(
1181       static_cast<int32_t>(FPLiteral.bitcastToAPInt().getZExtValue()),
1182       AsmParser->hasInv2PiInlineImm());
1183   }
1184 
1185   // We got int literal token.
1186   if (type == MVT::f64 || type == MVT::i64) { // Expected 64-bit operand
1187     return AMDGPU::isInlinableLiteral64(Imm.Val,
1188                                         AsmParser->hasInv2PiInlineImm());
1189   }
1190 
1191   if (type.getScalarSizeInBits() == 16) {
1192     return AMDGPU::isInlinableLiteral16(
1193       static_cast<int16_t>(Literal.getLoBits(16).getSExtValue()),
1194       AsmParser->hasInv2PiInlineImm());
1195   }
1196 
1197   return AMDGPU::isInlinableLiteral32(
1198     static_cast<int32_t>(Literal.getLoBits(32).getZExtValue()),
1199     AsmParser->hasInv2PiInlineImm());
1200 }
1201 
1202 bool AMDGPUOperand::isLiteralImm(MVT type) const {
1203   // Check that this imediate can be added as literal
1204   if (!isImmTy(ImmTyNone)) {
1205     return false;
1206   }
1207 
1208   if (!Imm.IsFPImm) {
1209     // We got int literal token.
1210 
1211     if (type == MVT::f64 && hasFPModifiers()) {
1212       // Cannot apply fp modifiers to int literals preserving the same semantics
1213       // for VOP1/2/C and VOP3 because of integer truncation. To avoid ambiguity,
1214       // disable these cases.
1215       return false;
1216     }
1217 
1218     unsigned Size = type.getSizeInBits();
1219     if (Size == 64)
1220       Size = 32;
1221 
1222     // FIXME: 64-bit operands can zero extend, sign extend, or pad zeroes for FP
1223     // types.
1224     return isUIntN(Size, Imm.Val) || isIntN(Size, Imm.Val);
1225   }
1226 
1227   // We got fp literal token
1228   if (type == MVT::f64) { // Expected 64-bit fp operand
1229     // We would set low 64-bits of literal to zeroes but we accept this literals
1230     return true;
1231   }
1232 
1233   if (type == MVT::i64) { // Expected 64-bit int operand
1234     // We don't allow fp literals in 64-bit integer instructions. It is
1235     // unclear how we should encode them.
1236     return false;
1237   }
1238 
1239   APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64, Imm.Val));
1240   return canLosslesslyConvertToFPType(FPLiteral, type);
1241 }
1242 
1243 bool AMDGPUOperand::isRegClass(unsigned RCID) const {
1244   return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(getReg());
1245 }
1246 
1247 uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val, unsigned Size) const
1248 {
1249   assert(isImmTy(ImmTyNone) && Imm.Mods.hasFPModifiers());
1250   assert(Size == 2 || Size == 4 || Size == 8);
1251 
1252   const uint64_t FpSignMask = (1ULL << (Size * 8 - 1));
1253 
1254   if (Imm.Mods.Abs) {
1255     Val &= ~FpSignMask;
1256   }
1257   if (Imm.Mods.Neg) {
1258     Val ^= FpSignMask;
1259   }
1260 
1261   return Val;
1262 }
1263 
1264 void AMDGPUOperand::addImmOperands(MCInst &Inst, unsigned N, bool ApplyModifiers) const {
1265 
1266   if (AMDGPU::isSISrcOperand(AsmParser->getMII()->get(Inst.getOpcode()),
1267                              Inst.getNumOperands())) {
1268     addLiteralImmOperand(Inst, Imm.Val,
1269                          ApplyModifiers &
1270                          isImmTy(ImmTyNone) && Imm.Mods.hasFPModifiers());
1271   } else {
1272     assert(!isImmTy(ImmTyNone) || !hasModifiers());
1273     Inst.addOperand(MCOperand::createImm(Imm.Val));
1274   }
1275 }
1276 
1277 void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyModifiers) const {
1278   const auto& InstDesc = AsmParser->getMII()->get(Inst.getOpcode());
1279   auto OpNum = Inst.getNumOperands();
1280   // Check that this operand accepts literals
1281   assert(AMDGPU::isSISrcOperand(InstDesc, OpNum));
1282 
1283   if (ApplyModifiers) {
1284     assert(AMDGPU::isSISrcFPOperand(InstDesc, OpNum));
1285     const unsigned Size = Imm.IsFPImm ? sizeof(double) : getOperandSize(InstDesc, OpNum);
1286     Val = applyInputFPModifiers(Val, Size);
1287   }
1288 
1289   APInt Literal(64, Val);
1290   uint8_t OpTy = InstDesc.OpInfo[OpNum].OperandType;
1291 
1292   if (Imm.IsFPImm) { // We got fp literal token
1293     switch (OpTy) {
1294     case AMDGPU::OPERAND_REG_IMM_INT64:
1295     case AMDGPU::OPERAND_REG_IMM_FP64:
1296     case AMDGPU::OPERAND_REG_INLINE_C_INT64:
1297     case AMDGPU::OPERAND_REG_INLINE_C_FP64: {
1298       if (AMDGPU::isInlinableLiteral64(Literal.getZExtValue(),
1299                                        AsmParser->hasInv2PiInlineImm())) {
1300         Inst.addOperand(MCOperand::createImm(Literal.getZExtValue()));
1301         return;
1302       }
1303 
1304       // Non-inlineable
1305       if (AMDGPU::isSISrcFPOperand(InstDesc, OpNum)) { // Expected 64-bit fp operand
1306         // For fp operands we check if low 32 bits are zeros
1307         if (Literal.getLoBits(32) != 0) {
1308           const_cast<AMDGPUAsmParser *>(AsmParser)->Warning(Inst.getLoc(),
1309           "Can't encode literal as exact 64-bit floating-point operand. "
1310           "Low 32-bits will be set to zero");
1311         }
1312 
1313         Inst.addOperand(MCOperand::createImm(Literal.lshr(32).getZExtValue()));
1314         return;
1315       }
1316 
1317       // We don't allow fp literals in 64-bit integer instructions. It is
1318       // unclear how we should encode them. This case should be checked earlier
1319       // in predicate methods (isLiteralImm())
1320       llvm_unreachable("fp literal in 64-bit integer instruction.");
1321     }
1322     case AMDGPU::OPERAND_REG_IMM_INT32:
1323     case AMDGPU::OPERAND_REG_IMM_FP32:
1324     case AMDGPU::OPERAND_REG_INLINE_C_INT32:
1325     case AMDGPU::OPERAND_REG_INLINE_C_FP32:
1326     case AMDGPU::OPERAND_REG_IMM_INT16:
1327     case AMDGPU::OPERAND_REG_IMM_FP16:
1328     case AMDGPU::OPERAND_REG_INLINE_C_INT16:
1329     case AMDGPU::OPERAND_REG_INLINE_C_FP16:
1330     case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
1331     case AMDGPU::OPERAND_REG_INLINE_C_V2FP16: {
1332       bool lost;
1333       APFloat FPLiteral(APFloat::IEEEdouble(), Literal);
1334       // Convert literal to single precision
1335       FPLiteral.convert(*getOpFltSemantics(OpTy),
1336                         APFloat::rmNearestTiesToEven, &lost);
1337       // We allow precision lost but not overflow or underflow. This should be
1338       // checked earlier in isLiteralImm()
1339 
1340       uint64_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
1341       if (OpTy == AMDGPU::OPERAND_REG_INLINE_C_V2INT16 ||
1342           OpTy == AMDGPU::OPERAND_REG_INLINE_C_V2FP16) {
1343         ImmVal |= (ImmVal << 16);
1344       }
1345 
1346       Inst.addOperand(MCOperand::createImm(ImmVal));
1347       return;
1348     }
1349     default:
1350       llvm_unreachable("invalid operand size");
1351     }
1352 
1353     return;
1354   }
1355 
1356    // We got int literal token.
1357   // Only sign extend inline immediates.
1358   // FIXME: No errors on truncation
1359   switch (OpTy) {
1360   case AMDGPU::OPERAND_REG_IMM_INT32:
1361   case AMDGPU::OPERAND_REG_IMM_FP32:
1362   case AMDGPU::OPERAND_REG_INLINE_C_INT32:
1363   case AMDGPU::OPERAND_REG_INLINE_C_FP32: {
1364     if (isInt<32>(Val) &&
1365         AMDGPU::isInlinableLiteral32(static_cast<int32_t>(Val),
1366                                      AsmParser->hasInv2PiInlineImm())) {
1367       Inst.addOperand(MCOperand::createImm(Val));
1368       return;
1369     }
1370 
1371     Inst.addOperand(MCOperand::createImm(Val & 0xffffffff));
1372     return;
1373   }
1374   case AMDGPU::OPERAND_REG_IMM_INT64:
1375   case AMDGPU::OPERAND_REG_IMM_FP64:
1376   case AMDGPU::OPERAND_REG_INLINE_C_INT64:
1377   case AMDGPU::OPERAND_REG_INLINE_C_FP64: {
1378     if (AMDGPU::isInlinableLiteral64(Val, AsmParser->hasInv2PiInlineImm())) {
1379       Inst.addOperand(MCOperand::createImm(Val));
1380       return;
1381     }
1382 
1383     Inst.addOperand(MCOperand::createImm(Lo_32(Val)));
1384     return;
1385   }
1386   case AMDGPU::OPERAND_REG_IMM_INT16:
1387   case AMDGPU::OPERAND_REG_IMM_FP16:
1388   case AMDGPU::OPERAND_REG_INLINE_C_INT16:
1389   case AMDGPU::OPERAND_REG_INLINE_C_FP16: {
1390     if (isInt<16>(Val) &&
1391         AMDGPU::isInlinableLiteral16(static_cast<int16_t>(Val),
1392                                      AsmParser->hasInv2PiInlineImm())) {
1393       Inst.addOperand(MCOperand::createImm(Val));
1394       return;
1395     }
1396 
1397     Inst.addOperand(MCOperand::createImm(Val & 0xffff));
1398     return;
1399   }
1400   case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
1401   case AMDGPU::OPERAND_REG_INLINE_C_V2FP16: {
1402     auto LiteralVal = static_cast<uint16_t>(Literal.getLoBits(16).getZExtValue());
1403     assert(AMDGPU::isInlinableLiteral16(LiteralVal,
1404                                         AsmParser->hasInv2PiInlineImm()));
1405 
1406     uint32_t ImmVal = static_cast<uint32_t>(LiteralVal) << 16 |
1407                       static_cast<uint32_t>(LiteralVal);
1408     Inst.addOperand(MCOperand::createImm(ImmVal));
1409     return;
1410   }
1411   default:
1412     llvm_unreachable("invalid operand size");
1413   }
1414 }
1415 
1416 template <unsigned Bitwidth>
1417 void AMDGPUOperand::addKImmFPOperands(MCInst &Inst, unsigned N) const {
1418   APInt Literal(64, Imm.Val);
1419 
1420   if (!Imm.IsFPImm) {
1421     // We got int literal token.
1422     Inst.addOperand(MCOperand::createImm(Literal.getLoBits(Bitwidth).getZExtValue()));
1423     return;
1424   }
1425 
1426   bool Lost;
1427   APFloat FPLiteral(APFloat::IEEEdouble(), Literal);
1428   FPLiteral.convert(*getFltSemantics(Bitwidth / 8),
1429                     APFloat::rmNearestTiesToEven, &Lost);
1430   Inst.addOperand(MCOperand::createImm(FPLiteral.bitcastToAPInt().getZExtValue()));
1431 }
1432 
1433 void AMDGPUOperand::addRegOperands(MCInst &Inst, unsigned N) const {
1434   Inst.addOperand(MCOperand::createReg(AMDGPU::getMCReg(getReg(), AsmParser->getSTI())));
1435 }
1436 
1437 //===----------------------------------------------------------------------===//
1438 // AsmParser
1439 //===----------------------------------------------------------------------===//
1440 
1441 static int getRegClass(RegisterKind Is, unsigned RegWidth) {
1442   if (Is == IS_VGPR) {
1443     switch (RegWidth) {
1444       default: return -1;
1445       case 1: return AMDGPU::VGPR_32RegClassID;
1446       case 2: return AMDGPU::VReg_64RegClassID;
1447       case 3: return AMDGPU::VReg_96RegClassID;
1448       case 4: return AMDGPU::VReg_128RegClassID;
1449       case 8: return AMDGPU::VReg_256RegClassID;
1450       case 16: return AMDGPU::VReg_512RegClassID;
1451     }
1452   } else if (Is == IS_TTMP) {
1453     switch (RegWidth) {
1454       default: return -1;
1455       case 1: return AMDGPU::TTMP_32RegClassID;
1456       case 2: return AMDGPU::TTMP_64RegClassID;
1457       case 4: return AMDGPU::TTMP_128RegClassID;
1458     }
1459   } else if (Is == IS_SGPR) {
1460     switch (RegWidth) {
1461       default: return -1;
1462       case 1: return AMDGPU::SGPR_32RegClassID;
1463       case 2: return AMDGPU::SGPR_64RegClassID;
1464       case 4: return AMDGPU::SGPR_128RegClassID;
1465       case 8: return AMDGPU::SReg_256RegClassID;
1466       case 16: return AMDGPU::SReg_512RegClassID;
1467     }
1468   }
1469   return -1;
1470 }
1471 
1472 static unsigned getSpecialRegForName(StringRef RegName) {
1473   return StringSwitch<unsigned>(RegName)
1474     .Case("exec", AMDGPU::EXEC)
1475     .Case("vcc", AMDGPU::VCC)
1476     .Case("flat_scratch", AMDGPU::FLAT_SCR)
1477     .Case("m0", AMDGPU::M0)
1478     .Case("scc", AMDGPU::SCC)
1479     .Case("tba", AMDGPU::TBA)
1480     .Case("tma", AMDGPU::TMA)
1481     .Case("flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
1482     .Case("flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
1483     .Case("vcc_lo", AMDGPU::VCC_LO)
1484     .Case("vcc_hi", AMDGPU::VCC_HI)
1485     .Case("exec_lo", AMDGPU::EXEC_LO)
1486     .Case("exec_hi", AMDGPU::EXEC_HI)
1487     .Case("tma_lo", AMDGPU::TMA_LO)
1488     .Case("tma_hi", AMDGPU::TMA_HI)
1489     .Case("tba_lo", AMDGPU::TBA_LO)
1490     .Case("tba_hi", AMDGPU::TBA_HI)
1491     .Default(0);
1492 }
1493 
1494 bool AMDGPUAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1495                                     SMLoc &EndLoc) {
1496   auto R = parseRegister();
1497   if (!R) return true;
1498   assert(R->isReg());
1499   RegNo = R->getReg();
1500   StartLoc = R->getStartLoc();
1501   EndLoc = R->getEndLoc();
1502   return false;
1503 }
1504 
1505 bool AMDGPUAsmParser::AddNextRegisterToList(unsigned &Reg, unsigned &RegWidth,
1506                                             RegisterKind RegKind, unsigned Reg1,
1507                                             unsigned RegNum) {
1508   switch (RegKind) {
1509   case IS_SPECIAL:
1510     if (Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
1511       Reg = AMDGPU::EXEC;
1512       RegWidth = 2;
1513       return true;
1514     }
1515     if (Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
1516       Reg = AMDGPU::FLAT_SCR;
1517       RegWidth = 2;
1518       return true;
1519     }
1520     if (Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
1521       Reg = AMDGPU::VCC;
1522       RegWidth = 2;
1523       return true;
1524     }
1525     if (Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
1526       Reg = AMDGPU::TBA;
1527       RegWidth = 2;
1528       return true;
1529     }
1530     if (Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
1531       Reg = AMDGPU::TMA;
1532       RegWidth = 2;
1533       return true;
1534     }
1535     return false;
1536   case IS_VGPR:
1537   case IS_SGPR:
1538   case IS_TTMP:
1539     if (Reg1 != Reg + RegWidth) {
1540       return false;
1541     }
1542     RegWidth++;
1543     return true;
1544   default:
1545     llvm_unreachable("unexpected register kind");
1546   }
1547 }
1548 
1549 bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind, unsigned &Reg,
1550                                           unsigned &RegNum, unsigned &RegWidth,
1551                                           unsigned *DwordRegIndex) {
1552   if (DwordRegIndex) { *DwordRegIndex = 0; }
1553   const MCRegisterInfo *TRI = getContext().getRegisterInfo();
1554   if (getLexer().is(AsmToken::Identifier)) {
1555     StringRef RegName = Parser.getTok().getString();
1556     if ((Reg = getSpecialRegForName(RegName))) {
1557       Parser.Lex();
1558       RegKind = IS_SPECIAL;
1559     } else {
1560       unsigned RegNumIndex = 0;
1561       if (RegName[0] == 'v') {
1562         RegNumIndex = 1;
1563         RegKind = IS_VGPR;
1564       } else if (RegName[0] == 's') {
1565         RegNumIndex = 1;
1566         RegKind = IS_SGPR;
1567       } else if (RegName.startswith("ttmp")) {
1568         RegNumIndex = strlen("ttmp");
1569         RegKind = IS_TTMP;
1570       } else {
1571         return false;
1572       }
1573       if (RegName.size() > RegNumIndex) {
1574         // Single 32-bit register: vXX.
1575         if (RegName.substr(RegNumIndex).getAsInteger(10, RegNum))
1576           return false;
1577         Parser.Lex();
1578         RegWidth = 1;
1579       } else {
1580         // Range of registers: v[XX:YY]. ":YY" is optional.
1581         Parser.Lex();
1582         int64_t RegLo, RegHi;
1583         if (getLexer().isNot(AsmToken::LBrac))
1584           return false;
1585         Parser.Lex();
1586 
1587         if (getParser().parseAbsoluteExpression(RegLo))
1588           return false;
1589 
1590         const bool isRBrace = getLexer().is(AsmToken::RBrac);
1591         if (!isRBrace && getLexer().isNot(AsmToken::Colon))
1592           return false;
1593         Parser.Lex();
1594 
1595         if (isRBrace) {
1596           RegHi = RegLo;
1597         } else {
1598           if (getParser().parseAbsoluteExpression(RegHi))
1599             return false;
1600 
1601           if (getLexer().isNot(AsmToken::RBrac))
1602             return false;
1603           Parser.Lex();
1604         }
1605         RegNum = (unsigned) RegLo;
1606         RegWidth = (RegHi - RegLo) + 1;
1607       }
1608     }
1609   } else if (getLexer().is(AsmToken::LBrac)) {
1610     // List of consecutive registers: [s0,s1,s2,s3]
1611     Parser.Lex();
1612     if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth, nullptr))
1613       return false;
1614     if (RegWidth != 1)
1615       return false;
1616     RegisterKind RegKind1;
1617     unsigned Reg1, RegNum1, RegWidth1;
1618     do {
1619       if (getLexer().is(AsmToken::Comma)) {
1620         Parser.Lex();
1621       } else if (getLexer().is(AsmToken::RBrac)) {
1622         Parser.Lex();
1623         break;
1624       } else if (ParseAMDGPURegister(RegKind1, Reg1, RegNum1, RegWidth1, nullptr)) {
1625         if (RegWidth1 != 1) {
1626           return false;
1627         }
1628         if (RegKind1 != RegKind) {
1629           return false;
1630         }
1631         if (!AddNextRegisterToList(Reg, RegWidth, RegKind1, Reg1, RegNum1)) {
1632           return false;
1633         }
1634       } else {
1635         return false;
1636       }
1637     } while (true);
1638   } else {
1639     return false;
1640   }
1641   switch (RegKind) {
1642   case IS_SPECIAL:
1643     RegNum = 0;
1644     RegWidth = 1;
1645     break;
1646   case IS_VGPR:
1647   case IS_SGPR:
1648   case IS_TTMP:
1649   {
1650     unsigned Size = 1;
1651     if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
1652       // SGPR and TTMP registers must be aligned. Max required alignment is 4 dwords.
1653       Size = std::min(RegWidth, 4u);
1654     }
1655     if (RegNum % Size != 0)
1656       return false;
1657     if (DwordRegIndex) { *DwordRegIndex = RegNum; }
1658     RegNum = RegNum / Size;
1659     int RCID = getRegClass(RegKind, RegWidth);
1660     if (RCID == -1)
1661       return false;
1662     const MCRegisterClass RC = TRI->getRegClass(RCID);
1663     if (RegNum >= RC.getNumRegs())
1664       return false;
1665     Reg = RC.getRegister(RegNum);
1666     break;
1667   }
1668 
1669   default:
1670     llvm_unreachable("unexpected register kind");
1671   }
1672 
1673   if (!subtargetHasRegister(*TRI, Reg))
1674     return false;
1675   return true;
1676 }
1677 
1678 std::unique_ptr<AMDGPUOperand> AMDGPUAsmParser::parseRegister() {
1679   const auto &Tok = Parser.getTok();
1680   SMLoc StartLoc = Tok.getLoc();
1681   SMLoc EndLoc = Tok.getEndLoc();
1682   RegisterKind RegKind;
1683   unsigned Reg, RegNum, RegWidth, DwordRegIndex;
1684 
1685   if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth, &DwordRegIndex)) {
1686     return nullptr;
1687   }
1688   KernelScope.usesRegister(RegKind, DwordRegIndex, RegWidth);
1689   return AMDGPUOperand::CreateReg(this, Reg, StartLoc, EndLoc, false);
1690 }
1691 
1692 bool
1693 AMDGPUAsmParser::parseAbsoluteExpr(int64_t &Val, bool AbsMod) {
1694   if (AbsMod && getLexer().peekTok().is(AsmToken::Pipe) &&
1695       (getLexer().getKind() == AsmToken::Integer ||
1696        getLexer().getKind() == AsmToken::Real)) {
1697 
1698     // This is a workaround for handling operands like these:
1699     //     |1.0|
1700     //     |-1|
1701     // This syntax is not compatible with syntax of standard
1702     // MC expressions (due to the trailing '|').
1703 
1704     SMLoc EndLoc;
1705     const MCExpr *Expr;
1706 
1707     if (getParser().parsePrimaryExpr(Expr, EndLoc)) {
1708       return true;
1709     }
1710 
1711     return !Expr->evaluateAsAbsolute(Val);
1712   }
1713 
1714   return getParser().parseAbsoluteExpression(Val);
1715 }
1716 
1717 OperandMatchResultTy
1718 AMDGPUAsmParser::parseImm(OperandVector &Operands, bool AbsMod) {
1719   // TODO: add syntactic sugar for 1/(2*PI)
1720   bool Minus = false;
1721   if (getLexer().getKind() == AsmToken::Minus) {
1722     Minus = true;
1723     Parser.Lex();
1724   }
1725 
1726   SMLoc S = Parser.getTok().getLoc();
1727   switch(getLexer().getKind()) {
1728   case AsmToken::Integer: {
1729     int64_t IntVal;
1730     if (parseAbsoluteExpr(IntVal, AbsMod))
1731       return MatchOperand_ParseFail;
1732     if (Minus)
1733       IntVal *= -1;
1734     Operands.push_back(AMDGPUOperand::CreateImm(this, IntVal, S));
1735     return MatchOperand_Success;
1736   }
1737   case AsmToken::Real: {
1738     int64_t IntVal;
1739     if (parseAbsoluteExpr(IntVal, AbsMod))
1740       return MatchOperand_ParseFail;
1741 
1742     APFloat F(BitsToDouble(IntVal));
1743     if (Minus)
1744       F.changeSign();
1745     Operands.push_back(
1746         AMDGPUOperand::CreateImm(this, F.bitcastToAPInt().getZExtValue(), S,
1747                                  AMDGPUOperand::ImmTyNone, true));
1748     return MatchOperand_Success;
1749   }
1750   default:
1751     return Minus ? MatchOperand_ParseFail : MatchOperand_NoMatch;
1752   }
1753 }
1754 
1755 OperandMatchResultTy
1756 AMDGPUAsmParser::parseReg(OperandVector &Operands) {
1757   if (auto R = parseRegister()) {
1758     assert(R->isReg());
1759     R->Reg.IsForcedVOP3 = isForcedVOP3();
1760     Operands.push_back(std::move(R));
1761     return MatchOperand_Success;
1762   }
1763   return MatchOperand_NoMatch;
1764 }
1765 
1766 OperandMatchResultTy
1767 AMDGPUAsmParser::parseRegOrImm(OperandVector &Operands, bool AbsMod) {
1768   auto res = parseImm(Operands, AbsMod);
1769   if (res != MatchOperand_NoMatch) {
1770     return res;
1771   }
1772 
1773   return parseReg(Operands);
1774 }
1775 
1776 OperandMatchResultTy
1777 AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
1778                                               bool AllowImm) {
1779   bool Negate = false, Negate2 = false, Abs = false, Abs2 = false;
1780 
1781   if (getLexer().getKind()== AsmToken::Minus) {
1782     const AsmToken NextToken = getLexer().peekTok();
1783 
1784     // Disable ambiguous constructs like '--1' etc. Should use neg(-1) instead.
1785     if (NextToken.is(AsmToken::Minus)) {
1786       Error(Parser.getTok().getLoc(), "invalid syntax, expected 'neg' modifier");
1787       return MatchOperand_ParseFail;
1788     }
1789 
1790     // '-' followed by an integer literal N should be interpreted as integer
1791     // negation rather than a floating-point NEG modifier applied to N.
1792     // Beside being contr-intuitive, such use of floating-point NEG modifier
1793     // results in different meaning of integer literals used with VOP1/2/C
1794     // and VOP3, for example:
1795     //    v_exp_f32_e32 v5, -1 // VOP1: src0 = 0xFFFFFFFF
1796     //    v_exp_f32_e64 v5, -1 // VOP3: src0 = 0x80000001
1797     // Negative fp literals should be handled likewise for unifomtity
1798     if (!NextToken.is(AsmToken::Integer) && !NextToken.is(AsmToken::Real)) {
1799       Parser.Lex();
1800       Negate = true;
1801     }
1802   }
1803 
1804   if (getLexer().getKind() == AsmToken::Identifier &&
1805       Parser.getTok().getString() == "neg") {
1806     if (Negate) {
1807       Error(Parser.getTok().getLoc(), "expected register or immediate");
1808       return MatchOperand_ParseFail;
1809     }
1810     Parser.Lex();
1811     Negate2 = true;
1812     if (getLexer().isNot(AsmToken::LParen)) {
1813       Error(Parser.getTok().getLoc(), "expected left paren after neg");
1814       return MatchOperand_ParseFail;
1815     }
1816     Parser.Lex();
1817   }
1818 
1819   if (getLexer().getKind() == AsmToken::Identifier &&
1820       Parser.getTok().getString() == "abs") {
1821     Parser.Lex();
1822     Abs2 = true;
1823     if (getLexer().isNot(AsmToken::LParen)) {
1824       Error(Parser.getTok().getLoc(), "expected left paren after abs");
1825       return MatchOperand_ParseFail;
1826     }
1827     Parser.Lex();
1828   }
1829 
1830   if (getLexer().getKind() == AsmToken::Pipe) {
1831     if (Abs2) {
1832       Error(Parser.getTok().getLoc(), "expected register or immediate");
1833       return MatchOperand_ParseFail;
1834     }
1835     Parser.Lex();
1836     Abs = true;
1837   }
1838 
1839   OperandMatchResultTy Res;
1840   if (AllowImm) {
1841     Res = parseRegOrImm(Operands, Abs);
1842   } else {
1843     Res = parseReg(Operands);
1844   }
1845   if (Res != MatchOperand_Success) {
1846     return Res;
1847   }
1848 
1849   AMDGPUOperand::Modifiers Mods;
1850   if (Abs) {
1851     if (getLexer().getKind() != AsmToken::Pipe) {
1852       Error(Parser.getTok().getLoc(), "expected vertical bar");
1853       return MatchOperand_ParseFail;
1854     }
1855     Parser.Lex();
1856     Mods.Abs = true;
1857   }
1858   if (Abs2) {
1859     if (getLexer().isNot(AsmToken::RParen)) {
1860       Error(Parser.getTok().getLoc(), "expected closing parentheses");
1861       return MatchOperand_ParseFail;
1862     }
1863     Parser.Lex();
1864     Mods.Abs = true;
1865   }
1866 
1867   if (Negate) {
1868     Mods.Neg = true;
1869   } else if (Negate2) {
1870     if (getLexer().isNot(AsmToken::RParen)) {
1871       Error(Parser.getTok().getLoc(), "expected closing parentheses");
1872       return MatchOperand_ParseFail;
1873     }
1874     Parser.Lex();
1875     Mods.Neg = true;
1876   }
1877 
1878   if (Mods.hasFPModifiers()) {
1879     AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands.back());
1880     Op.setModifiers(Mods);
1881   }
1882   return MatchOperand_Success;
1883 }
1884 
1885 OperandMatchResultTy
1886 AMDGPUAsmParser::parseRegOrImmWithIntInputMods(OperandVector &Operands,
1887                                                bool AllowImm) {
1888   bool Sext = false;
1889 
1890   if (getLexer().getKind() == AsmToken::Identifier &&
1891       Parser.getTok().getString() == "sext") {
1892     Parser.Lex();
1893     Sext = true;
1894     if (getLexer().isNot(AsmToken::LParen)) {
1895       Error(Parser.getTok().getLoc(), "expected left paren after sext");
1896       return MatchOperand_ParseFail;
1897     }
1898     Parser.Lex();
1899   }
1900 
1901   OperandMatchResultTy Res;
1902   if (AllowImm) {
1903     Res = parseRegOrImm(Operands);
1904   } else {
1905     Res = parseReg(Operands);
1906   }
1907   if (Res != MatchOperand_Success) {
1908     return Res;
1909   }
1910 
1911   AMDGPUOperand::Modifiers Mods;
1912   if (Sext) {
1913     if (getLexer().isNot(AsmToken::RParen)) {
1914       Error(Parser.getTok().getLoc(), "expected closing parentheses");
1915       return MatchOperand_ParseFail;
1916     }
1917     Parser.Lex();
1918     Mods.Sext = true;
1919   }
1920 
1921   if (Mods.hasIntModifiers()) {
1922     AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands.back());
1923     Op.setModifiers(Mods);
1924   }
1925 
1926   return MatchOperand_Success;
1927 }
1928 
1929 OperandMatchResultTy
1930 AMDGPUAsmParser::parseRegWithFPInputMods(OperandVector &Operands) {
1931   return parseRegOrImmWithFPInputMods(Operands, false);
1932 }
1933 
1934 OperandMatchResultTy
1935 AMDGPUAsmParser::parseRegWithIntInputMods(OperandVector &Operands) {
1936   return parseRegOrImmWithIntInputMods(Operands, false);
1937 }
1938 
1939 OperandMatchResultTy AMDGPUAsmParser::parseVReg32OrOff(OperandVector &Operands) {
1940   std::unique_ptr<AMDGPUOperand> Reg = parseRegister();
1941   if (Reg) {
1942     Operands.push_back(std::move(Reg));
1943     return MatchOperand_Success;
1944   }
1945 
1946   const AsmToken &Tok = Parser.getTok();
1947   if (Tok.getString() == "off") {
1948     Operands.push_back(AMDGPUOperand::CreateImm(this, 0, Tok.getLoc(),
1949                                                 AMDGPUOperand::ImmTyOff, false));
1950     Parser.Lex();
1951     return MatchOperand_Success;
1952   }
1953 
1954   return MatchOperand_NoMatch;
1955 }
1956 
1957 unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1958   uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
1959 
1960   if ((getForcedEncodingSize() == 32 && (TSFlags & SIInstrFlags::VOP3)) ||
1961       (getForcedEncodingSize() == 64 && !(TSFlags & SIInstrFlags::VOP3)) ||
1962       (isForcedDPP() && !(TSFlags & SIInstrFlags::DPP)) ||
1963       (isForcedSDWA() && !(TSFlags & SIInstrFlags::SDWA)) )
1964     return Match_InvalidOperand;
1965 
1966   if ((TSFlags & SIInstrFlags::VOP3) &&
1967       (TSFlags & SIInstrFlags::VOPAsmPrefer32Bit) &&
1968       getForcedEncodingSize() != 64)
1969     return Match_PreferE32;
1970 
1971   if (Inst.getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
1972       Inst.getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
1973     // v_mac_f32/16 allow only dst_sel == DWORD;
1974     auto OpNum =
1975         AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::dst_sel);
1976     const auto &Op = Inst.getOperand(OpNum);
1977     if (!Op.isImm() || Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
1978       return Match_InvalidOperand;
1979     }
1980   }
1981 
1982   if ((TSFlags & SIInstrFlags::FLAT) && !hasFlatOffsets()) {
1983     // FIXME: Produces error without correct column reported.
1984     auto OpNum =
1985         AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::offset);
1986     const auto &Op = Inst.getOperand(OpNum);
1987     if (Op.getImm() != 0)
1988       return Match_InvalidOperand;
1989   }
1990 
1991   return Match_Success;
1992 }
1993 
1994 // What asm variants we should check
1995 ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants() const {
1996   if (getForcedEncodingSize() == 32) {
1997     static const unsigned Variants[] = {AMDGPUAsmVariants::DEFAULT};
1998     return makeArrayRef(Variants);
1999   }
2000 
2001   if (isForcedVOP3()) {
2002     static const unsigned Variants[] = {AMDGPUAsmVariants::VOP3};
2003     return makeArrayRef(Variants);
2004   }
2005 
2006   if (isForcedSDWA()) {
2007     static const unsigned Variants[] = {AMDGPUAsmVariants::SDWA,
2008                                         AMDGPUAsmVariants::SDWA9};
2009     return makeArrayRef(Variants);
2010   }
2011 
2012   if (isForcedDPP()) {
2013     static const unsigned Variants[] = {AMDGPUAsmVariants::DPP};
2014     return makeArrayRef(Variants);
2015   }
2016 
2017   static const unsigned Variants[] = {
2018     AMDGPUAsmVariants::DEFAULT, AMDGPUAsmVariants::VOP3,
2019     AMDGPUAsmVariants::SDWA, AMDGPUAsmVariants::SDWA9, AMDGPUAsmVariants::DPP
2020   };
2021 
2022   return makeArrayRef(Variants);
2023 }
2024 
2025 unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(const MCInst &Inst) const {
2026   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
2027   const unsigned Num = Desc.getNumImplicitUses();
2028   for (unsigned i = 0; i < Num; ++i) {
2029     unsigned Reg = Desc.ImplicitUses[i];
2030     switch (Reg) {
2031     case AMDGPU::FLAT_SCR:
2032     case AMDGPU::VCC:
2033     case AMDGPU::M0:
2034       return Reg;
2035     default:
2036       break;
2037     }
2038   }
2039   return AMDGPU::NoRegister;
2040 }
2041 
2042 // NB: This code is correct only when used to check constant
2043 // bus limitations because GFX7 support no f16 inline constants.
2044 // Note that there are no cases when a GFX7 opcode violates
2045 // constant bus limitations due to the use of an f16 constant.
2046 bool AMDGPUAsmParser::isInlineConstant(const MCInst &Inst,
2047                                        unsigned OpIdx) const {
2048   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
2049 
2050   if (!AMDGPU::isSISrcOperand(Desc, OpIdx)) {
2051     return false;
2052   }
2053 
2054   const MCOperand &MO = Inst.getOperand(OpIdx);
2055 
2056   int64_t Val = MO.getImm();
2057   auto OpSize = AMDGPU::getOperandSize(Desc, OpIdx);
2058 
2059   switch (OpSize) { // expected operand size
2060   case 8:
2061     return AMDGPU::isInlinableLiteral64(Val, hasInv2PiInlineImm());
2062   case 4:
2063     return AMDGPU::isInlinableLiteral32(Val, hasInv2PiInlineImm());
2064   case 2: {
2065     const unsigned OperandType = Desc.OpInfo[OpIdx].OperandType;
2066     if (OperandType == AMDGPU::OPERAND_REG_INLINE_C_V2INT16 ||
2067         OperandType == AMDGPU::OPERAND_REG_INLINE_C_V2FP16) {
2068       return AMDGPU::isInlinableLiteralV216(Val, hasInv2PiInlineImm());
2069     } else {
2070       return AMDGPU::isInlinableLiteral16(Val, hasInv2PiInlineImm());
2071     }
2072   }
2073   default:
2074     llvm_unreachable("invalid operand size");
2075   }
2076 }
2077 
2078 bool AMDGPUAsmParser::usesConstantBus(const MCInst &Inst, unsigned OpIdx) {
2079   const MCOperand &MO = Inst.getOperand(OpIdx);
2080   if (MO.isImm()) {
2081     return !isInlineConstant(Inst, OpIdx);
2082   }
2083   return !MO.isReg() ||
2084          isSGPR(mc2PseudoReg(MO.getReg()), getContext().getRegisterInfo());
2085 }
2086 
2087 bool AMDGPUAsmParser::validateOperandLimitations(const MCInst &Inst) {
2088   const unsigned Opcode = Inst.getOpcode();
2089   const MCInstrDesc &Desc = MII.get(Opcode);
2090   unsigned ConstantBusUseCount = 0;
2091 
2092   if (Desc.TSFlags &
2093       (SIInstrFlags::VOPC |
2094        SIInstrFlags::VOP1 | SIInstrFlags::VOP2 |
2095        SIInstrFlags::VOP3 | SIInstrFlags::VOP3P |
2096        SIInstrFlags::SDWA)) {
2097 
2098     // Check special imm operands (used by madmk, etc)
2099     if (AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::imm) != -1) {
2100       ++ConstantBusUseCount;
2101     }
2102 
2103     unsigned SGPRUsed = findImplicitSGPRReadInVOP(Inst);
2104     if (SGPRUsed != AMDGPU::NoRegister) {
2105       ++ConstantBusUseCount;
2106     }
2107 
2108     const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
2109     const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
2110     const int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2);
2111 
2112     const int OpIndices[] = { Src0Idx, Src1Idx, Src2Idx };
2113 
2114     for (int OpIdx : OpIndices) {
2115       if (OpIdx == -1) break;
2116 
2117       const MCOperand &MO = Inst.getOperand(OpIdx);
2118       if (usesConstantBus(Inst, OpIdx)) {
2119         if (MO.isReg()) {
2120           const unsigned Reg = mc2PseudoReg(MO.getReg());
2121           // Pairs of registers with a partial intersections like these
2122           //   s0, s[0:1]
2123           //   flat_scratch_lo, flat_scratch
2124           //   flat_scratch_lo, flat_scratch_hi
2125           // are theoretically valid but they are disabled anyway.
2126           // Note that this code mimics SIInstrInfo::verifyInstruction
2127           if (Reg != SGPRUsed) {
2128             ++ConstantBusUseCount;
2129           }
2130           SGPRUsed = Reg;
2131         } else { // Expression or a literal
2132           ++ConstantBusUseCount;
2133         }
2134       }
2135     }
2136   }
2137 
2138   return ConstantBusUseCount <= 1;
2139 }
2140 
2141 bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2142                                               OperandVector &Operands,
2143                                               MCStreamer &Out,
2144                                               uint64_t &ErrorInfo,
2145                                               bool MatchingInlineAsm) {
2146   MCInst Inst;
2147   unsigned Result = Match_Success;
2148   for (auto Variant : getMatchedVariants()) {
2149     uint64_t EI;
2150     auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
2151                                   Variant);
2152     // We order match statuses from least to most specific. We use most specific
2153     // status as resulting
2154     // Match_MnemonicFail < Match_InvalidOperand < Match_MissingFeature < Match_PreferE32
2155     if ((R == Match_Success) ||
2156         (R == Match_PreferE32) ||
2157         (R == Match_MissingFeature && Result != Match_PreferE32) ||
2158         (R == Match_InvalidOperand && Result != Match_MissingFeature
2159                                    && Result != Match_PreferE32) ||
2160         (R == Match_MnemonicFail   && Result != Match_InvalidOperand
2161                                    && Result != Match_MissingFeature
2162                                    && Result != Match_PreferE32)) {
2163       Result = R;
2164       ErrorInfo = EI;
2165     }
2166     if (R == Match_Success)
2167       break;
2168   }
2169 
2170   switch (Result) {
2171   default: break;
2172   case Match_Success:
2173     if (!validateOperandLimitations(Inst)) {
2174       return Error(IDLoc,
2175                    "invalid operand (violates constant bus restrictions)");
2176     }
2177     Inst.setLoc(IDLoc);
2178     Out.EmitInstruction(Inst, getSTI());
2179     return false;
2180 
2181   case Match_MissingFeature:
2182     return Error(IDLoc, "instruction not supported on this GPU");
2183 
2184   case Match_MnemonicFail:
2185     return Error(IDLoc, "unrecognized instruction mnemonic");
2186 
2187   case Match_InvalidOperand: {
2188     SMLoc ErrorLoc = IDLoc;
2189     if (ErrorInfo != ~0ULL) {
2190       if (ErrorInfo >= Operands.size()) {
2191         return Error(IDLoc, "too few operands for instruction");
2192       }
2193       ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
2194       if (ErrorLoc == SMLoc())
2195         ErrorLoc = IDLoc;
2196     }
2197     return Error(ErrorLoc, "invalid operand for instruction");
2198   }
2199 
2200   case Match_PreferE32:
2201     return Error(IDLoc, "internal error: instruction without _e64 suffix "
2202                         "should be encoded as e32");
2203   }
2204   llvm_unreachable("Implement any new match types added!");
2205 }
2206 
2207 bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
2208   int64_t Tmp = -1;
2209   if (getLexer().isNot(AsmToken::Integer) && getLexer().isNot(AsmToken::Identifier)) {
2210     return true;
2211   }
2212   if (getParser().parseAbsoluteExpression(Tmp)) {
2213     return true;
2214   }
2215   Ret = static_cast<uint32_t>(Tmp);
2216   return false;
2217 }
2218 
2219 bool AMDGPUAsmParser::ParseDirectiveMajorMinor(uint32_t &Major,
2220                                                uint32_t &Minor) {
2221   if (ParseAsAbsoluteExpression(Major))
2222     return TokError("invalid major version");
2223 
2224   if (getLexer().isNot(AsmToken::Comma))
2225     return TokError("minor version number required, comma expected");
2226   Lex();
2227 
2228   if (ParseAsAbsoluteExpression(Minor))
2229     return TokError("invalid minor version");
2230 
2231   return false;
2232 }
2233 
2234 bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectVersion() {
2235   uint32_t Major;
2236   uint32_t Minor;
2237 
2238   if (ParseDirectiveMajorMinor(Major, Minor))
2239     return true;
2240 
2241   getTargetStreamer().EmitDirectiveHSACodeObjectVersion(Major, Minor);
2242   return false;
2243 }
2244 
2245 bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectISA() {
2246   uint32_t Major;
2247   uint32_t Minor;
2248   uint32_t Stepping;
2249   StringRef VendorName;
2250   StringRef ArchName;
2251 
2252   // If this directive has no arguments, then use the ISA version for the
2253   // targeted GPU.
2254   if (getLexer().is(AsmToken::EndOfStatement)) {
2255     AMDGPU::IsaInfo::IsaVersion ISA =
2256         AMDGPU::IsaInfo::getIsaVersion(getFeatureBits());
2257     getTargetStreamer().EmitDirectiveHSACodeObjectISA(ISA.Major, ISA.Minor,
2258                                                       ISA.Stepping,
2259                                                       "AMD", "AMDGPU");
2260     return false;
2261   }
2262 
2263   if (ParseDirectiveMajorMinor(Major, Minor))
2264     return true;
2265 
2266   if (getLexer().isNot(AsmToken::Comma))
2267     return TokError("stepping version number required, comma expected");
2268   Lex();
2269 
2270   if (ParseAsAbsoluteExpression(Stepping))
2271     return TokError("invalid stepping version");
2272 
2273   if (getLexer().isNot(AsmToken::Comma))
2274     return TokError("vendor name required, comma expected");
2275   Lex();
2276 
2277   if (getLexer().isNot(AsmToken::String))
2278     return TokError("invalid vendor name");
2279 
2280   VendorName = getLexer().getTok().getStringContents();
2281   Lex();
2282 
2283   if (getLexer().isNot(AsmToken::Comma))
2284     return TokError("arch name required, comma expected");
2285   Lex();
2286 
2287   if (getLexer().isNot(AsmToken::String))
2288     return TokError("invalid arch name");
2289 
2290   ArchName = getLexer().getTok().getStringContents();
2291   Lex();
2292 
2293   getTargetStreamer().EmitDirectiveHSACodeObjectISA(Major, Minor, Stepping,
2294                                                     VendorName, ArchName);
2295   return false;
2296 }
2297 
2298 bool AMDGPUAsmParser::ParseDirectiveCodeObjectMetadata() {
2299   std::string YamlString;
2300   raw_string_ostream YamlStream(YamlString);
2301 
2302   getLexer().setSkipSpace(false);
2303 
2304   bool FoundEnd = false;
2305   while (!getLexer().is(AsmToken::Eof)) {
2306     while (getLexer().is(AsmToken::Space)) {
2307       YamlStream << getLexer().getTok().getString();
2308       Lex();
2309     }
2310 
2311     if (getLexer().is(AsmToken::Identifier)) {
2312       StringRef ID = getLexer().getTok().getIdentifier();
2313       if (ID == AMDGPU::CodeObject::MetadataAssemblerDirectiveEnd) {
2314         Lex();
2315         FoundEnd = true;
2316         break;
2317       }
2318     }
2319 
2320     YamlStream << Parser.parseStringToEndOfStatement()
2321                << getContext().getAsmInfo()->getSeparatorString();
2322 
2323     Parser.eatToEndOfStatement();
2324   }
2325 
2326   getLexer().setSkipSpace(true);
2327 
2328   if (getLexer().is(AsmToken::Eof) && !FoundEnd) {
2329     return TokError(
2330         "expected directive .end_amdgpu_code_object_metadata not found");
2331   }
2332 
2333   YamlStream.flush();
2334 
2335   if (!getTargetStreamer().EmitCodeObjectMetadata(YamlString))
2336     return Error(getParser().getTok().getLoc(), "invalid code object metadata");
2337 
2338   return false;
2339 }
2340 
2341 bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef ID,
2342                                                amd_kernel_code_t &Header) {
2343   SmallString<40> ErrStr;
2344   raw_svector_ostream Err(ErrStr);
2345   if (!parseAmdKernelCodeField(ID, getParser(), Header, Err)) {
2346     return TokError(Err.str());
2347   }
2348   Lex();
2349   return false;
2350 }
2351 
2352 bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
2353   amd_kernel_code_t Header;
2354   AMDGPU::initDefaultAMDKernelCodeT(Header, getFeatureBits());
2355 
2356   while (true) {
2357     // Lex EndOfStatement.  This is in a while loop, because lexing a comment
2358     // will set the current token to EndOfStatement.
2359     while(getLexer().is(AsmToken::EndOfStatement))
2360       Lex();
2361 
2362     if (getLexer().isNot(AsmToken::Identifier))
2363       return TokError("expected value identifier or .end_amd_kernel_code_t");
2364 
2365     StringRef ID = getLexer().getTok().getIdentifier();
2366     Lex();
2367 
2368     if (ID == ".end_amd_kernel_code_t")
2369       break;
2370 
2371     if (ParseAMDKernelCodeTValue(ID, Header))
2372       return true;
2373   }
2374 
2375   getTargetStreamer().EmitAMDKernelCodeT(Header);
2376 
2377   return false;
2378 }
2379 
2380 bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
2381   if (getLexer().isNot(AsmToken::Identifier))
2382     return TokError("expected symbol name");
2383 
2384   StringRef KernelName = Parser.getTok().getString();
2385 
2386   getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
2387                                            ELF::STT_AMDGPU_HSA_KERNEL);
2388   Lex();
2389   KernelScope.initialize(getContext());
2390   return false;
2391 }
2392 
2393 bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
2394   StringRef IDVal = DirectiveID.getString();
2395 
2396   if (IDVal == ".hsa_code_object_version")
2397     return ParseDirectiveHSACodeObjectVersion();
2398 
2399   if (IDVal == ".hsa_code_object_isa")
2400     return ParseDirectiveHSACodeObjectISA();
2401 
2402   if (IDVal == AMDGPU::CodeObject::MetadataAssemblerDirectiveBegin)
2403     return ParseDirectiveCodeObjectMetadata();
2404 
2405   if (IDVal == ".amd_kernel_code_t")
2406     return ParseDirectiveAMDKernelCodeT();
2407 
2408   if (IDVal == ".amdgpu_hsa_kernel")
2409     return ParseDirectiveAMDGPUHsaKernel();
2410 
2411   return true;
2412 }
2413 
2414 bool AMDGPUAsmParser::subtargetHasRegister(const MCRegisterInfo &MRI,
2415                                            unsigned RegNo) const {
2416   if (isCI())
2417     return true;
2418 
2419   if (isSI()) {
2420     // No flat_scr
2421     switch (RegNo) {
2422     case AMDGPU::FLAT_SCR:
2423     case AMDGPU::FLAT_SCR_LO:
2424     case AMDGPU::FLAT_SCR_HI:
2425       return false;
2426     default:
2427       return true;
2428     }
2429   }
2430 
2431   // VI only has 102 SGPRs, so make sure we aren't trying to use the 2 more that
2432   // SI/CI have.
2433   for (MCRegAliasIterator R(AMDGPU::SGPR102_SGPR103, &MRI, true);
2434        R.isValid(); ++R) {
2435     if (*R == RegNo)
2436       return false;
2437   }
2438 
2439   return true;
2440 }
2441 
2442 OperandMatchResultTy
2443 AMDGPUAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2444   // Try to parse with a custom parser
2445   OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2446 
2447   // If we successfully parsed the operand or if there as an error parsing,
2448   // we are done.
2449   //
2450   // If we are parsing after we reach EndOfStatement then this means we
2451   // are appending default values to the Operands list.  This is only done
2452   // by custom parser, so we shouldn't continue on to the generic parsing.
2453   if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail ||
2454       getLexer().is(AsmToken::EndOfStatement))
2455     return ResTy;
2456 
2457   ResTy = parseRegOrImm(Operands);
2458 
2459   if (ResTy == MatchOperand_Success)
2460     return ResTy;
2461 
2462   if (getLexer().getKind() == AsmToken::Identifier) {
2463     // If this identifier is a symbol, we want to create an expression for it.
2464     // It is a little difficult to distinguish between a symbol name, and
2465     // an instruction flag like 'gds'.  In order to do this, we parse
2466     // all tokens as expressions and then treate the symbol name as the token
2467     // string when we want to interpret the operand as a token.
2468     const auto &Tok = Parser.getTok();
2469     SMLoc S = Tok.getLoc();
2470     const MCExpr *Expr = nullptr;
2471     if (!Parser.parseExpression(Expr)) {
2472       Operands.push_back(AMDGPUOperand::CreateExpr(this, Expr, S));
2473       return MatchOperand_Success;
2474     }
2475 
2476     Operands.push_back(AMDGPUOperand::CreateToken(this, Tok.getString(), Tok.getLoc()));
2477     Parser.Lex();
2478     return MatchOperand_Success;
2479   }
2480   return MatchOperand_NoMatch;
2481 }
2482 
2483 StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
2484   // Clear any forced encodings from the previous instruction.
2485   setForcedEncodingSize(0);
2486   setForcedDPP(false);
2487   setForcedSDWA(false);
2488 
2489   if (Name.endswith("_e64")) {
2490     setForcedEncodingSize(64);
2491     return Name.substr(0, Name.size() - 4);
2492   } else if (Name.endswith("_e32")) {
2493     setForcedEncodingSize(32);
2494     return Name.substr(0, Name.size() - 4);
2495   } else if (Name.endswith("_dpp")) {
2496     setForcedDPP(true);
2497     return Name.substr(0, Name.size() - 4);
2498   } else if (Name.endswith("_sdwa")) {
2499     setForcedSDWA(true);
2500     return Name.substr(0, Name.size() - 5);
2501   }
2502   return Name;
2503 }
2504 
2505 bool AMDGPUAsmParser::ParseInstruction(ParseInstructionInfo &Info,
2506                                        StringRef Name,
2507                                        SMLoc NameLoc, OperandVector &Operands) {
2508   // Add the instruction mnemonic
2509   Name = parseMnemonicSuffix(Name);
2510   Operands.push_back(AMDGPUOperand::CreateToken(this, Name, NameLoc));
2511 
2512   while (!getLexer().is(AsmToken::EndOfStatement)) {
2513     OperandMatchResultTy Res = parseOperand(Operands, Name);
2514 
2515     // Eat the comma or space if there is one.
2516     if (getLexer().is(AsmToken::Comma))
2517       Parser.Lex();
2518 
2519     switch (Res) {
2520       case MatchOperand_Success: break;
2521       case MatchOperand_ParseFail:
2522         Error(getLexer().getLoc(), "failed parsing operand.");
2523         while (!getLexer().is(AsmToken::EndOfStatement)) {
2524           Parser.Lex();
2525         }
2526         return true;
2527       case MatchOperand_NoMatch:
2528         Error(getLexer().getLoc(), "not a valid operand.");
2529         while (!getLexer().is(AsmToken::EndOfStatement)) {
2530           Parser.Lex();
2531         }
2532         return true;
2533     }
2534   }
2535 
2536   return false;
2537 }
2538 
2539 //===----------------------------------------------------------------------===//
2540 // Utility functions
2541 //===----------------------------------------------------------------------===//
2542 
2543 OperandMatchResultTy
2544 AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix, int64_t &Int) {
2545   switch(getLexer().getKind()) {
2546     default: return MatchOperand_NoMatch;
2547     case AsmToken::Identifier: {
2548       StringRef Name = Parser.getTok().getString();
2549       if (!Name.equals(Prefix)) {
2550         return MatchOperand_NoMatch;
2551       }
2552 
2553       Parser.Lex();
2554       if (getLexer().isNot(AsmToken::Colon))
2555         return MatchOperand_ParseFail;
2556 
2557       Parser.Lex();
2558 
2559       bool IsMinus = false;
2560       if (getLexer().getKind() == AsmToken::Minus) {
2561         Parser.Lex();
2562         IsMinus = true;
2563       }
2564 
2565       if (getLexer().isNot(AsmToken::Integer))
2566         return MatchOperand_ParseFail;
2567 
2568       if (getParser().parseAbsoluteExpression(Int))
2569         return MatchOperand_ParseFail;
2570 
2571       if (IsMinus)
2572         Int = -Int;
2573       break;
2574     }
2575   }
2576   return MatchOperand_Success;
2577 }
2578 
2579 OperandMatchResultTy
2580 AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix, OperandVector &Operands,
2581                                     AMDGPUOperand::ImmTy ImmTy,
2582                                     bool (*ConvertResult)(int64_t&)) {
2583   SMLoc S = Parser.getTok().getLoc();
2584   int64_t Value = 0;
2585 
2586   OperandMatchResultTy Res = parseIntWithPrefix(Prefix, Value);
2587   if (Res != MatchOperand_Success)
2588     return Res;
2589 
2590   if (ConvertResult && !ConvertResult(Value)) {
2591     return MatchOperand_ParseFail;
2592   }
2593 
2594   Operands.push_back(AMDGPUOperand::CreateImm(this, Value, S, ImmTy));
2595   return MatchOperand_Success;
2596 }
2597 
2598 OperandMatchResultTy AMDGPUAsmParser::parseOperandArrayWithPrefix(
2599   const char *Prefix,
2600   OperandVector &Operands,
2601   AMDGPUOperand::ImmTy ImmTy,
2602   bool (*ConvertResult)(int64_t&)) {
2603   StringRef Name = Parser.getTok().getString();
2604   if (!Name.equals(Prefix))
2605     return MatchOperand_NoMatch;
2606 
2607   Parser.Lex();
2608   if (getLexer().isNot(AsmToken::Colon))
2609     return MatchOperand_ParseFail;
2610 
2611   Parser.Lex();
2612   if (getLexer().isNot(AsmToken::LBrac))
2613     return MatchOperand_ParseFail;
2614   Parser.Lex();
2615 
2616   unsigned Val = 0;
2617   SMLoc S = Parser.getTok().getLoc();
2618 
2619   // FIXME: How to verify the number of elements matches the number of src
2620   // operands?
2621   for (int I = 0; I < 3; ++I) {
2622     if (I != 0) {
2623       if (getLexer().is(AsmToken::RBrac))
2624         break;
2625 
2626       if (getLexer().isNot(AsmToken::Comma))
2627         return MatchOperand_ParseFail;
2628       Parser.Lex();
2629     }
2630 
2631     if (getLexer().isNot(AsmToken::Integer))
2632       return MatchOperand_ParseFail;
2633 
2634     int64_t Op;
2635     if (getParser().parseAbsoluteExpression(Op))
2636       return MatchOperand_ParseFail;
2637 
2638     if (Op != 0 && Op != 1)
2639       return MatchOperand_ParseFail;
2640     Val |= (Op << I);
2641   }
2642 
2643   Parser.Lex();
2644   Operands.push_back(AMDGPUOperand::CreateImm(this, Val, S, ImmTy));
2645   return MatchOperand_Success;
2646 }
2647 
2648 OperandMatchResultTy
2649 AMDGPUAsmParser::parseNamedBit(const char *Name, OperandVector &Operands,
2650                                AMDGPUOperand::ImmTy ImmTy) {
2651   int64_t Bit = 0;
2652   SMLoc S = Parser.getTok().getLoc();
2653 
2654   // We are at the end of the statement, and this is a default argument, so
2655   // use a default value.
2656   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2657     switch(getLexer().getKind()) {
2658       case AsmToken::Identifier: {
2659         StringRef Tok = Parser.getTok().getString();
2660         if (Tok == Name) {
2661           Bit = 1;
2662           Parser.Lex();
2663         } else if (Tok.startswith("no") && Tok.endswith(Name)) {
2664           Bit = 0;
2665           Parser.Lex();
2666         } else {
2667           return MatchOperand_NoMatch;
2668         }
2669         break;
2670       }
2671       default:
2672         return MatchOperand_NoMatch;
2673     }
2674   }
2675 
2676   Operands.push_back(AMDGPUOperand::CreateImm(this, Bit, S, ImmTy));
2677   return MatchOperand_Success;
2678 }
2679 
2680 static void addOptionalImmOperand(
2681   MCInst& Inst, const OperandVector& Operands,
2682   AMDGPUAsmParser::OptionalImmIndexMap& OptionalIdx,
2683   AMDGPUOperand::ImmTy ImmT,
2684   int64_t Default = 0) {
2685   auto i = OptionalIdx.find(ImmT);
2686   if (i != OptionalIdx.end()) {
2687     unsigned Idx = i->second;
2688     ((AMDGPUOperand &)*Operands[Idx]).addImmOperands(Inst, 1);
2689   } else {
2690     Inst.addOperand(MCOperand::createImm(Default));
2691   }
2692 }
2693 
2694 OperandMatchResultTy
2695 AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix, StringRef &Value) {
2696   if (getLexer().isNot(AsmToken::Identifier)) {
2697     return MatchOperand_NoMatch;
2698   }
2699   StringRef Tok = Parser.getTok().getString();
2700   if (Tok != Prefix) {
2701     return MatchOperand_NoMatch;
2702   }
2703 
2704   Parser.Lex();
2705   if (getLexer().isNot(AsmToken::Colon)) {
2706     return MatchOperand_ParseFail;
2707   }
2708 
2709   Parser.Lex();
2710   if (getLexer().isNot(AsmToken::Identifier)) {
2711     return MatchOperand_ParseFail;
2712   }
2713 
2714   Value = Parser.getTok().getString();
2715   return MatchOperand_Success;
2716 }
2717 
2718 //===----------------------------------------------------------------------===//
2719 // ds
2720 //===----------------------------------------------------------------------===//
2721 
2722 void AMDGPUAsmParser::cvtDSOffset01(MCInst &Inst,
2723                                     const OperandVector &Operands) {
2724   OptionalImmIndexMap OptionalIdx;
2725 
2726   for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
2727     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
2728 
2729     // Add the register arguments
2730     if (Op.isReg()) {
2731       Op.addRegOperands(Inst, 1);
2732       continue;
2733     }
2734 
2735     // Handle optional arguments
2736     OptionalIdx[Op.getImmTy()] = i;
2737   }
2738 
2739   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOffset0);
2740   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOffset1);
2741   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGDS);
2742 
2743   Inst.addOperand(MCOperand::createReg(AMDGPU::M0)); // m0
2744 }
2745 
2746 void AMDGPUAsmParser::cvtDSImpl(MCInst &Inst, const OperandVector &Operands,
2747                                 bool IsGdsHardcoded) {
2748   OptionalImmIndexMap OptionalIdx;
2749 
2750   for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
2751     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
2752 
2753     // Add the register arguments
2754     if (Op.isReg()) {
2755       Op.addRegOperands(Inst, 1);
2756       continue;
2757     }
2758 
2759     if (Op.isToken() && Op.getToken() == "gds") {
2760       IsGdsHardcoded = true;
2761       continue;
2762     }
2763 
2764     // Handle optional arguments
2765     OptionalIdx[Op.getImmTy()] = i;
2766   }
2767 
2768   AMDGPUOperand::ImmTy OffsetType =
2769     (Inst.getOpcode() == AMDGPU::DS_SWIZZLE_B32_si ||
2770      Inst.getOpcode() == AMDGPU::DS_SWIZZLE_B32_vi) ? AMDGPUOperand::ImmTySwizzle :
2771                                                       AMDGPUOperand::ImmTyOffset;
2772 
2773   addOptionalImmOperand(Inst, Operands, OptionalIdx, OffsetType);
2774 
2775   if (!IsGdsHardcoded) {
2776     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGDS);
2777   }
2778   Inst.addOperand(MCOperand::createReg(AMDGPU::M0)); // m0
2779 }
2780 
2781 void AMDGPUAsmParser::cvtExp(MCInst &Inst, const OperandVector &Operands) {
2782   OptionalImmIndexMap OptionalIdx;
2783 
2784   unsigned OperandIdx[4];
2785   unsigned EnMask = 0;
2786   int SrcIdx = 0;
2787 
2788   for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
2789     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
2790 
2791     // Add the register arguments
2792     if (Op.isReg()) {
2793       assert(SrcIdx < 4);
2794       OperandIdx[SrcIdx] = Inst.size();
2795       Op.addRegOperands(Inst, 1);
2796       ++SrcIdx;
2797       continue;
2798     }
2799 
2800     if (Op.isOff()) {
2801       assert(SrcIdx < 4);
2802       OperandIdx[SrcIdx] = Inst.size();
2803       Inst.addOperand(MCOperand::createReg(AMDGPU::NoRegister));
2804       ++SrcIdx;
2805       continue;
2806     }
2807 
2808     if (Op.isImm() && Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
2809       Op.addImmOperands(Inst, 1);
2810       continue;
2811     }
2812 
2813     if (Op.isToken() && Op.getToken() == "done")
2814       continue;
2815 
2816     // Handle optional arguments
2817     OptionalIdx[Op.getImmTy()] = i;
2818   }
2819 
2820   assert(SrcIdx == 4);
2821 
2822   bool Compr = false;
2823   if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
2824     Compr = true;
2825     Inst.getOperand(OperandIdx[1]) = Inst.getOperand(OperandIdx[2]);
2826     Inst.getOperand(OperandIdx[2]).setReg(AMDGPU::NoRegister);
2827     Inst.getOperand(OperandIdx[3]).setReg(AMDGPU::NoRegister);
2828   }
2829 
2830   for (auto i = 0; i < SrcIdx; ++i) {
2831     if (Inst.getOperand(OperandIdx[i]).getReg() != AMDGPU::NoRegister) {
2832       EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
2833     }
2834   }
2835 
2836   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyExpVM);
2837   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyExpCompr);
2838 
2839   Inst.addOperand(MCOperand::createImm(EnMask));
2840 }
2841 
2842 //===----------------------------------------------------------------------===//
2843 // s_waitcnt
2844 //===----------------------------------------------------------------------===//
2845 
2846 static bool
2847 encodeCnt(
2848   const AMDGPU::IsaInfo::IsaVersion ISA,
2849   int64_t &IntVal,
2850   int64_t CntVal,
2851   bool Saturate,
2852   unsigned (*encode)(const IsaInfo::IsaVersion &Version, unsigned, unsigned),
2853   unsigned (*decode)(const IsaInfo::IsaVersion &Version, unsigned))
2854 {
2855   bool Failed = false;
2856 
2857   IntVal = encode(ISA, IntVal, CntVal);
2858   if (CntVal != decode(ISA, IntVal)) {
2859     if (Saturate) {
2860       IntVal = encode(ISA, IntVal, -1);
2861     } else {
2862       Failed = true;
2863     }
2864   }
2865   return Failed;
2866 }
2867 
2868 bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
2869   StringRef CntName = Parser.getTok().getString();
2870   int64_t CntVal;
2871 
2872   Parser.Lex();
2873   if (getLexer().isNot(AsmToken::LParen))
2874     return true;
2875 
2876   Parser.Lex();
2877   if (getLexer().isNot(AsmToken::Integer))
2878     return true;
2879 
2880   SMLoc ValLoc = Parser.getTok().getLoc();
2881   if (getParser().parseAbsoluteExpression(CntVal))
2882     return true;
2883 
2884   AMDGPU::IsaInfo::IsaVersion ISA =
2885       AMDGPU::IsaInfo::getIsaVersion(getFeatureBits());
2886 
2887   bool Failed = true;
2888   bool Sat = CntName.endswith("_sat");
2889 
2890   if (CntName == "vmcnt" || CntName == "vmcnt_sat") {
2891     Failed = encodeCnt(ISA, IntVal, CntVal, Sat, encodeVmcnt, decodeVmcnt);
2892   } else if (CntName == "expcnt" || CntName == "expcnt_sat") {
2893     Failed = encodeCnt(ISA, IntVal, CntVal, Sat, encodeExpcnt, decodeExpcnt);
2894   } else if (CntName == "lgkmcnt" || CntName == "lgkmcnt_sat") {
2895     Failed = encodeCnt(ISA, IntVal, CntVal, Sat, encodeLgkmcnt, decodeLgkmcnt);
2896   }
2897 
2898   if (Failed) {
2899     Error(ValLoc, "too large value for " + CntName);
2900     return true;
2901   }
2902 
2903   if (getLexer().isNot(AsmToken::RParen)) {
2904     return true;
2905   }
2906 
2907   Parser.Lex();
2908   if (getLexer().is(AsmToken::Amp) || getLexer().is(AsmToken::Comma)) {
2909     const AsmToken NextToken = getLexer().peekTok();
2910     if (NextToken.is(AsmToken::Identifier)) {
2911       Parser.Lex();
2912     }
2913   }
2914 
2915   return false;
2916 }
2917 
2918 OperandMatchResultTy
2919 AMDGPUAsmParser::parseSWaitCntOps(OperandVector &Operands) {
2920   AMDGPU::IsaInfo::IsaVersion ISA =
2921       AMDGPU::IsaInfo::getIsaVersion(getFeatureBits());
2922   int64_t Waitcnt = getWaitcntBitMask(ISA);
2923   SMLoc S = Parser.getTok().getLoc();
2924 
2925   switch(getLexer().getKind()) {
2926     default: return MatchOperand_ParseFail;
2927     case AsmToken::Integer:
2928       // The operand can be an integer value.
2929       if (getParser().parseAbsoluteExpression(Waitcnt))
2930         return MatchOperand_ParseFail;
2931       break;
2932 
2933     case AsmToken::Identifier:
2934       do {
2935         if (parseCnt(Waitcnt))
2936           return MatchOperand_ParseFail;
2937       } while(getLexer().isNot(AsmToken::EndOfStatement));
2938       break;
2939   }
2940   Operands.push_back(AMDGPUOperand::CreateImm(this, Waitcnt, S));
2941   return MatchOperand_Success;
2942 }
2943 
2944 bool AMDGPUAsmParser::parseHwregConstruct(OperandInfoTy &HwReg, int64_t &Offset,
2945                                           int64_t &Width) {
2946   using namespace llvm::AMDGPU::Hwreg;
2947 
2948   if (Parser.getTok().getString() != "hwreg")
2949     return true;
2950   Parser.Lex();
2951 
2952   if (getLexer().isNot(AsmToken::LParen))
2953     return true;
2954   Parser.Lex();
2955 
2956   if (getLexer().is(AsmToken::Identifier)) {
2957     HwReg.IsSymbolic = true;
2958     HwReg.Id = ID_UNKNOWN_;
2959     const StringRef tok = Parser.getTok().getString();
2960     for (int i = ID_SYMBOLIC_FIRST_; i < ID_SYMBOLIC_LAST_; ++i) {
2961       if (tok == IdSymbolic[i]) {
2962         HwReg.Id = i;
2963         break;
2964       }
2965     }
2966     Parser.Lex();
2967   } else {
2968     HwReg.IsSymbolic = false;
2969     if (getLexer().isNot(AsmToken::Integer))
2970       return true;
2971     if (getParser().parseAbsoluteExpression(HwReg.Id))
2972       return true;
2973   }
2974 
2975   if (getLexer().is(AsmToken::RParen)) {
2976     Parser.Lex();
2977     return false;
2978   }
2979 
2980   // optional params
2981   if (getLexer().isNot(AsmToken::Comma))
2982     return true;
2983   Parser.Lex();
2984 
2985   if (getLexer().isNot(AsmToken::Integer))
2986     return true;
2987   if (getParser().parseAbsoluteExpression(Offset))
2988     return true;
2989 
2990   if (getLexer().isNot(AsmToken::Comma))
2991     return true;
2992   Parser.Lex();
2993 
2994   if (getLexer().isNot(AsmToken::Integer))
2995     return true;
2996   if (getParser().parseAbsoluteExpression(Width))
2997     return true;
2998 
2999   if (getLexer().isNot(AsmToken::RParen))
3000     return true;
3001   Parser.Lex();
3002 
3003   return false;
3004 }
3005 
3006 OperandMatchResultTy AMDGPUAsmParser::parseHwreg(OperandVector &Operands) {
3007   using namespace llvm::AMDGPU::Hwreg;
3008 
3009   int64_t Imm16Val = 0;
3010   SMLoc S = Parser.getTok().getLoc();
3011 
3012   switch(getLexer().getKind()) {
3013     default: return MatchOperand_NoMatch;
3014     case AsmToken::Integer:
3015       // The operand can be an integer value.
3016       if (getParser().parseAbsoluteExpression(Imm16Val))
3017         return MatchOperand_NoMatch;
3018       if (Imm16Val < 0 || !isUInt<16>(Imm16Val)) {
3019         Error(S, "invalid immediate: only 16-bit values are legal");
3020         // Do not return error code, but create an imm operand anyway and proceed
3021         // to the next operand, if any. That avoids unneccessary error messages.
3022       }
3023       break;
3024 
3025     case AsmToken::Identifier: {
3026         OperandInfoTy HwReg(ID_UNKNOWN_);
3027         int64_t Offset = OFFSET_DEFAULT_;
3028         int64_t Width = WIDTH_M1_DEFAULT_ + 1;
3029         if (parseHwregConstruct(HwReg, Offset, Width))
3030           return MatchOperand_ParseFail;
3031         if (HwReg.Id < 0 || !isUInt<ID_WIDTH_>(HwReg.Id)) {
3032           if (HwReg.IsSymbolic)
3033             Error(S, "invalid symbolic name of hardware register");
3034           else
3035             Error(S, "invalid code of hardware register: only 6-bit values are legal");
3036         }
3037         if (Offset < 0 || !isUInt<OFFSET_WIDTH_>(Offset))
3038           Error(S, "invalid bit offset: only 5-bit values are legal");
3039         if ((Width-1) < 0 || !isUInt<WIDTH_M1_WIDTH_>(Width-1))
3040           Error(S, "invalid bitfield width: only values from 1 to 32 are legal");
3041         Imm16Val = (HwReg.Id << ID_SHIFT_) | (Offset << OFFSET_SHIFT_) | ((Width-1) << WIDTH_M1_SHIFT_);
3042       }
3043       break;
3044   }
3045   Operands.push_back(AMDGPUOperand::CreateImm(this, Imm16Val, S, AMDGPUOperand::ImmTyHwreg));
3046   return MatchOperand_Success;
3047 }
3048 
3049 bool AMDGPUOperand::isSWaitCnt() const {
3050   return isImm();
3051 }
3052 
3053 bool AMDGPUOperand::isHwreg() const {
3054   return isImmTy(ImmTyHwreg);
3055 }
3056 
3057 bool AMDGPUAsmParser::parseSendMsgConstruct(OperandInfoTy &Msg, OperandInfoTy &Operation, int64_t &StreamId) {
3058   using namespace llvm::AMDGPU::SendMsg;
3059 
3060   if (Parser.getTok().getString() != "sendmsg")
3061     return true;
3062   Parser.Lex();
3063 
3064   if (getLexer().isNot(AsmToken::LParen))
3065     return true;
3066   Parser.Lex();
3067 
3068   if (getLexer().is(AsmToken::Identifier)) {
3069     Msg.IsSymbolic = true;
3070     Msg.Id = ID_UNKNOWN_;
3071     const std::string tok = Parser.getTok().getString();
3072     for (int i = ID_GAPS_FIRST_; i < ID_GAPS_LAST_; ++i) {
3073       switch(i) {
3074         default: continue; // Omit gaps.
3075         case ID_INTERRUPT: case ID_GS: case ID_GS_DONE:  case ID_SYSMSG: break;
3076       }
3077       if (tok == IdSymbolic[i]) {
3078         Msg.Id = i;
3079         break;
3080       }
3081     }
3082     Parser.Lex();
3083   } else {
3084     Msg.IsSymbolic = false;
3085     if (getLexer().isNot(AsmToken::Integer))
3086       return true;
3087     if (getParser().parseAbsoluteExpression(Msg.Id))
3088       return true;
3089     if (getLexer().is(AsmToken::Integer))
3090       if (getParser().parseAbsoluteExpression(Msg.Id))
3091         Msg.Id = ID_UNKNOWN_;
3092   }
3093   if (Msg.Id == ID_UNKNOWN_) // Don't know how to parse the rest.
3094     return false;
3095 
3096   if (!(Msg.Id == ID_GS || Msg.Id == ID_GS_DONE || Msg.Id == ID_SYSMSG)) {
3097     if (getLexer().isNot(AsmToken::RParen))
3098       return true;
3099     Parser.Lex();
3100     return false;
3101   }
3102 
3103   if (getLexer().isNot(AsmToken::Comma))
3104     return true;
3105   Parser.Lex();
3106 
3107   assert(Msg.Id == ID_GS || Msg.Id == ID_GS_DONE || Msg.Id == ID_SYSMSG);
3108   Operation.Id = ID_UNKNOWN_;
3109   if (getLexer().is(AsmToken::Identifier)) {
3110     Operation.IsSymbolic = true;
3111     const char* const *S = (Msg.Id == ID_SYSMSG) ? OpSysSymbolic : OpGsSymbolic;
3112     const int F = (Msg.Id == ID_SYSMSG) ? OP_SYS_FIRST_ : OP_GS_FIRST_;
3113     const int L = (Msg.Id == ID_SYSMSG) ? OP_SYS_LAST_ : OP_GS_LAST_;
3114     const StringRef Tok = Parser.getTok().getString();
3115     for (int i = F; i < L; ++i) {
3116       if (Tok == S[i]) {
3117         Operation.Id = i;
3118         break;
3119       }
3120     }
3121     Parser.Lex();
3122   } else {
3123     Operation.IsSymbolic = false;
3124     if (getLexer().isNot(AsmToken::Integer))
3125       return true;
3126     if (getParser().parseAbsoluteExpression(Operation.Id))
3127       return true;
3128   }
3129 
3130   if ((Msg.Id == ID_GS || Msg.Id == ID_GS_DONE) && Operation.Id != OP_GS_NOP) {
3131     // Stream id is optional.
3132     if (getLexer().is(AsmToken::RParen)) {
3133       Parser.Lex();
3134       return false;
3135     }
3136 
3137     if (getLexer().isNot(AsmToken::Comma))
3138       return true;
3139     Parser.Lex();
3140 
3141     if (getLexer().isNot(AsmToken::Integer))
3142       return true;
3143     if (getParser().parseAbsoluteExpression(StreamId))
3144       return true;
3145   }
3146 
3147   if (getLexer().isNot(AsmToken::RParen))
3148     return true;
3149   Parser.Lex();
3150   return false;
3151 }
3152 
3153 OperandMatchResultTy AMDGPUAsmParser::parseInterpSlot(OperandVector &Operands) {
3154   if (getLexer().getKind() != AsmToken::Identifier)
3155     return MatchOperand_NoMatch;
3156 
3157   StringRef Str = Parser.getTok().getString();
3158   int Slot = StringSwitch<int>(Str)
3159     .Case("p10", 0)
3160     .Case("p20", 1)
3161     .Case("p0", 2)
3162     .Default(-1);
3163 
3164   SMLoc S = Parser.getTok().getLoc();
3165   if (Slot == -1)
3166     return MatchOperand_ParseFail;
3167 
3168   Parser.Lex();
3169   Operands.push_back(AMDGPUOperand::CreateImm(this, Slot, S,
3170                                               AMDGPUOperand::ImmTyInterpSlot));
3171   return MatchOperand_Success;
3172 }
3173 
3174 OperandMatchResultTy AMDGPUAsmParser::parseInterpAttr(OperandVector &Operands) {
3175   if (getLexer().getKind() != AsmToken::Identifier)
3176     return MatchOperand_NoMatch;
3177 
3178   StringRef Str = Parser.getTok().getString();
3179   if (!Str.startswith("attr"))
3180     return MatchOperand_NoMatch;
3181 
3182   StringRef Chan = Str.take_back(2);
3183   int AttrChan = StringSwitch<int>(Chan)
3184     .Case(".x", 0)
3185     .Case(".y", 1)
3186     .Case(".z", 2)
3187     .Case(".w", 3)
3188     .Default(-1);
3189   if (AttrChan == -1)
3190     return MatchOperand_ParseFail;
3191 
3192   Str = Str.drop_back(2).drop_front(4);
3193 
3194   uint8_t Attr;
3195   if (Str.getAsInteger(10, Attr))
3196     return MatchOperand_ParseFail;
3197 
3198   SMLoc S = Parser.getTok().getLoc();
3199   Parser.Lex();
3200   if (Attr > 63) {
3201     Error(S, "out of bounds attr");
3202     return MatchOperand_Success;
3203   }
3204 
3205   SMLoc SChan = SMLoc::getFromPointer(Chan.data());
3206 
3207   Operands.push_back(AMDGPUOperand::CreateImm(this, Attr, S,
3208                                               AMDGPUOperand::ImmTyInterpAttr));
3209   Operands.push_back(AMDGPUOperand::CreateImm(this, AttrChan, SChan,
3210                                               AMDGPUOperand::ImmTyAttrChan));
3211   return MatchOperand_Success;
3212 }
3213 
3214 void AMDGPUAsmParser::errorExpTgt() {
3215   Error(Parser.getTok().getLoc(), "invalid exp target");
3216 }
3217 
3218 OperandMatchResultTy AMDGPUAsmParser::parseExpTgtImpl(StringRef Str,
3219                                                       uint8_t &Val) {
3220   if (Str == "null") {
3221     Val = 9;
3222     return MatchOperand_Success;
3223   }
3224 
3225   if (Str.startswith("mrt")) {
3226     Str = Str.drop_front(3);
3227     if (Str == "z") { // == mrtz
3228       Val = 8;
3229       return MatchOperand_Success;
3230     }
3231 
3232     if (Str.getAsInteger(10, Val))
3233       return MatchOperand_ParseFail;
3234 
3235     if (Val > 7)
3236       errorExpTgt();
3237 
3238     return MatchOperand_Success;
3239   }
3240 
3241   if (Str.startswith("pos")) {
3242     Str = Str.drop_front(3);
3243     if (Str.getAsInteger(10, Val))
3244       return MatchOperand_ParseFail;
3245 
3246     if (Val > 3)
3247       errorExpTgt();
3248 
3249     Val += 12;
3250     return MatchOperand_Success;
3251   }
3252 
3253   if (Str.startswith("param")) {
3254     Str = Str.drop_front(5);
3255     if (Str.getAsInteger(10, Val))
3256       return MatchOperand_ParseFail;
3257 
3258     if (Val >= 32)
3259       errorExpTgt();
3260 
3261     Val += 32;
3262     return MatchOperand_Success;
3263   }
3264 
3265   if (Str.startswith("invalid_target_")) {
3266     Str = Str.drop_front(15);
3267     if (Str.getAsInteger(10, Val))
3268       return MatchOperand_ParseFail;
3269 
3270     errorExpTgt();
3271     return MatchOperand_Success;
3272   }
3273 
3274   return MatchOperand_NoMatch;
3275 }
3276 
3277 OperandMatchResultTy AMDGPUAsmParser::parseExpTgt(OperandVector &Operands) {
3278   uint8_t Val;
3279   StringRef Str = Parser.getTok().getString();
3280 
3281   auto Res = parseExpTgtImpl(Str, Val);
3282   if (Res != MatchOperand_Success)
3283     return Res;
3284 
3285   SMLoc S = Parser.getTok().getLoc();
3286   Parser.Lex();
3287 
3288   Operands.push_back(AMDGPUOperand::CreateImm(this, Val, S,
3289                                               AMDGPUOperand::ImmTyExpTgt));
3290   return MatchOperand_Success;
3291 }
3292 
3293 OperandMatchResultTy
3294 AMDGPUAsmParser::parseSendMsgOp(OperandVector &Operands) {
3295   using namespace llvm::AMDGPU::SendMsg;
3296 
3297   int64_t Imm16Val = 0;
3298   SMLoc S = Parser.getTok().getLoc();
3299 
3300   switch(getLexer().getKind()) {
3301   default:
3302     return MatchOperand_NoMatch;
3303   case AsmToken::Integer:
3304     // The operand can be an integer value.
3305     if (getParser().parseAbsoluteExpression(Imm16Val))
3306       return MatchOperand_NoMatch;
3307     if (Imm16Val < 0 || !isUInt<16>(Imm16Val)) {
3308       Error(S, "invalid immediate: only 16-bit values are legal");
3309       // Do not return error code, but create an imm operand anyway and proceed
3310       // to the next operand, if any. That avoids unneccessary error messages.
3311     }
3312     break;
3313   case AsmToken::Identifier: {
3314       OperandInfoTy Msg(ID_UNKNOWN_);
3315       OperandInfoTy Operation(OP_UNKNOWN_);
3316       int64_t StreamId = STREAM_ID_DEFAULT_;
3317       if (parseSendMsgConstruct(Msg, Operation, StreamId))
3318         return MatchOperand_ParseFail;
3319       do {
3320         // Validate and encode message ID.
3321         if (! ((ID_INTERRUPT <= Msg.Id && Msg.Id <= ID_GS_DONE)
3322                 || Msg.Id == ID_SYSMSG)) {
3323           if (Msg.IsSymbolic)
3324             Error(S, "invalid/unsupported symbolic name of message");
3325           else
3326             Error(S, "invalid/unsupported code of message");
3327           break;
3328         }
3329         Imm16Val = (Msg.Id << ID_SHIFT_);
3330         // Validate and encode operation ID.
3331         if (Msg.Id == ID_GS || Msg.Id == ID_GS_DONE) {
3332           if (! (OP_GS_FIRST_ <= Operation.Id && Operation.Id < OP_GS_LAST_)) {
3333             if (Operation.IsSymbolic)
3334               Error(S, "invalid symbolic name of GS_OP");
3335             else
3336               Error(S, "invalid code of GS_OP: only 2-bit values are legal");
3337             break;
3338           }
3339           if (Operation.Id == OP_GS_NOP
3340               && Msg.Id != ID_GS_DONE) {
3341             Error(S, "invalid GS_OP: NOP is for GS_DONE only");
3342             break;
3343           }
3344           Imm16Val |= (Operation.Id << OP_SHIFT_);
3345         }
3346         if (Msg.Id == ID_SYSMSG) {
3347           if (! (OP_SYS_FIRST_ <= Operation.Id && Operation.Id < OP_SYS_LAST_)) {
3348             if (Operation.IsSymbolic)
3349               Error(S, "invalid/unsupported symbolic name of SYSMSG_OP");
3350             else
3351               Error(S, "invalid/unsupported code of SYSMSG_OP");
3352             break;
3353           }
3354           Imm16Val |= (Operation.Id << OP_SHIFT_);
3355         }
3356         // Validate and encode stream ID.
3357         if ((Msg.Id == ID_GS || Msg.Id == ID_GS_DONE) && Operation.Id != OP_GS_NOP) {
3358           if (! (STREAM_ID_FIRST_ <= StreamId && StreamId < STREAM_ID_LAST_)) {
3359             Error(S, "invalid stream id: only 2-bit values are legal");
3360             break;
3361           }
3362           Imm16Val |= (StreamId << STREAM_ID_SHIFT_);
3363         }
3364       } while (false);
3365     }
3366     break;
3367   }
3368   Operands.push_back(AMDGPUOperand::CreateImm(this, Imm16Val, S, AMDGPUOperand::ImmTySendMsg));
3369   return MatchOperand_Success;
3370 }
3371 
3372 bool AMDGPUOperand::isSendMsg() const {
3373   return isImmTy(ImmTySendMsg);
3374 }
3375 
3376 //===----------------------------------------------------------------------===//
3377 // parser helpers
3378 //===----------------------------------------------------------------------===//
3379 
3380 bool
3381 AMDGPUAsmParser::trySkipId(const StringRef Id) {
3382   if (getLexer().getKind() == AsmToken::Identifier &&
3383       Parser.getTok().getString() == Id) {
3384     Parser.Lex();
3385     return true;
3386   }
3387   return false;
3388 }
3389 
3390 bool
3391 AMDGPUAsmParser::trySkipToken(const AsmToken::TokenKind Kind) {
3392   if (getLexer().getKind() == Kind) {
3393     Parser.Lex();
3394     return true;
3395   }
3396   return false;
3397 }
3398 
3399 bool
3400 AMDGPUAsmParser::skipToken(const AsmToken::TokenKind Kind,
3401                            const StringRef ErrMsg) {
3402   if (!trySkipToken(Kind)) {
3403     Error(Parser.getTok().getLoc(), ErrMsg);
3404     return false;
3405   }
3406   return true;
3407 }
3408 
3409 bool
3410 AMDGPUAsmParser::parseExpr(int64_t &Imm) {
3411   return !getParser().parseAbsoluteExpression(Imm);
3412 }
3413 
3414 bool
3415 AMDGPUAsmParser::parseString(StringRef &Val, const StringRef ErrMsg) {
3416   SMLoc S = Parser.getTok().getLoc();
3417   if (getLexer().getKind() == AsmToken::String) {
3418     Val = Parser.getTok().getStringContents();
3419     Parser.Lex();
3420     return true;
3421   } else {
3422     Error(S, ErrMsg);
3423     return false;
3424   }
3425 }
3426 
3427 //===----------------------------------------------------------------------===//
3428 // swizzle
3429 //===----------------------------------------------------------------------===//
3430 
3431 LLVM_READNONE
3432 static unsigned
3433 encodeBitmaskPerm(const unsigned AndMask,
3434                   const unsigned OrMask,
3435                   const unsigned XorMask) {
3436   using namespace llvm::AMDGPU::Swizzle;
3437 
3438   return BITMASK_PERM_ENC |
3439          (AndMask << BITMASK_AND_SHIFT) |
3440          (OrMask  << BITMASK_OR_SHIFT)  |
3441          (XorMask << BITMASK_XOR_SHIFT);
3442 }
3443 
3444 bool
3445 AMDGPUAsmParser::parseSwizzleOperands(const unsigned OpNum, int64_t* Op,
3446                                       const unsigned MinVal,
3447                                       const unsigned MaxVal,
3448                                       const StringRef ErrMsg) {
3449   for (unsigned i = 0; i < OpNum; ++i) {
3450     if (!skipToken(AsmToken::Comma, "expected a comma")){
3451       return false;
3452     }
3453     SMLoc ExprLoc = Parser.getTok().getLoc();
3454     if (!parseExpr(Op[i])) {
3455       return false;
3456     }
3457     if (Op[i] < MinVal || Op[i] > MaxVal) {
3458       Error(ExprLoc, ErrMsg);
3459       return false;
3460     }
3461   }
3462 
3463   return true;
3464 }
3465 
3466 bool
3467 AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &Imm) {
3468   using namespace llvm::AMDGPU::Swizzle;
3469 
3470   int64_t Lane[LANE_NUM];
3471   if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
3472                            "expected a 2-bit lane id")) {
3473     Imm = QUAD_PERM_ENC;
3474     for (auto i = 0; i < LANE_NUM; ++i) {
3475       Imm |= Lane[i] << (LANE_SHIFT * i);
3476     }
3477     return true;
3478   }
3479   return false;
3480 }
3481 
3482 bool
3483 AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &Imm) {
3484   using namespace llvm::AMDGPU::Swizzle;
3485 
3486   SMLoc S = Parser.getTok().getLoc();
3487   int64_t GroupSize;
3488   int64_t LaneIdx;
3489 
3490   if (!parseSwizzleOperands(1, &GroupSize,
3491                             2, 32,
3492                             "group size must be in the interval [2,32]")) {
3493     return false;
3494   }
3495   if (!isPowerOf2_64(GroupSize)) {
3496     Error(S, "group size must be a power of two");
3497     return false;
3498   }
3499   if (parseSwizzleOperands(1, &LaneIdx,
3500                            0, GroupSize - 1,
3501                            "lane id must be in the interval [0,group size - 1]")) {
3502     Imm = encodeBitmaskPerm(BITMASK_MAX - GroupSize + 1, LaneIdx, 0);
3503     return true;
3504   }
3505   return false;
3506 }
3507 
3508 bool
3509 AMDGPUAsmParser::parseSwizzleReverse(int64_t &Imm) {
3510   using namespace llvm::AMDGPU::Swizzle;
3511 
3512   SMLoc S = Parser.getTok().getLoc();
3513   int64_t GroupSize;
3514 
3515   if (!parseSwizzleOperands(1, &GroupSize,
3516       2, 32, "group size must be in the interval [2,32]")) {
3517     return false;
3518   }
3519   if (!isPowerOf2_64(GroupSize)) {
3520     Error(S, "group size must be a power of two");
3521     return false;
3522   }
3523 
3524   Imm = encodeBitmaskPerm(BITMASK_MAX, 0, GroupSize - 1);
3525   return true;
3526 }
3527 
3528 bool
3529 AMDGPUAsmParser::parseSwizzleSwap(int64_t &Imm) {
3530   using namespace llvm::AMDGPU::Swizzle;
3531 
3532   SMLoc S = Parser.getTok().getLoc();
3533   int64_t GroupSize;
3534 
3535   if (!parseSwizzleOperands(1, &GroupSize,
3536       1, 16, "group size must be in the interval [1,16]")) {
3537     return false;
3538   }
3539   if (!isPowerOf2_64(GroupSize)) {
3540     Error(S, "group size must be a power of two");
3541     return false;
3542   }
3543 
3544   Imm = encodeBitmaskPerm(BITMASK_MAX, 0, GroupSize);
3545   return true;
3546 }
3547 
3548 bool
3549 AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &Imm) {
3550   using namespace llvm::AMDGPU::Swizzle;
3551 
3552   if (!skipToken(AsmToken::Comma, "expected a comma")) {
3553     return false;
3554   }
3555 
3556   StringRef Ctl;
3557   SMLoc StrLoc = Parser.getTok().getLoc();
3558   if (!parseString(Ctl)) {
3559     return false;
3560   }
3561   if (Ctl.size() != BITMASK_WIDTH) {
3562     Error(StrLoc, "expected a 5-character mask");
3563     return false;
3564   }
3565 
3566   unsigned AndMask = 0;
3567   unsigned OrMask = 0;
3568   unsigned XorMask = 0;
3569 
3570   for (size_t i = 0; i < Ctl.size(); ++i) {
3571     unsigned Mask = 1 << (BITMASK_WIDTH - 1 - i);
3572     switch(Ctl[i]) {
3573     default:
3574       Error(StrLoc, "invalid mask");
3575       return false;
3576     case '0':
3577       break;
3578     case '1':
3579       OrMask |= Mask;
3580       break;
3581     case 'p':
3582       AndMask |= Mask;
3583       break;
3584     case 'i':
3585       AndMask |= Mask;
3586       XorMask |= Mask;
3587       break;
3588     }
3589   }
3590 
3591   Imm = encodeBitmaskPerm(AndMask, OrMask, XorMask);
3592   return true;
3593 }
3594 
3595 bool
3596 AMDGPUAsmParser::parseSwizzleOffset(int64_t &Imm) {
3597 
3598   SMLoc OffsetLoc = Parser.getTok().getLoc();
3599 
3600   if (!parseExpr(Imm)) {
3601     return false;
3602   }
3603   if (!isUInt<16>(Imm)) {
3604     Error(OffsetLoc, "expected a 16-bit offset");
3605     return false;
3606   }
3607   return true;
3608 }
3609 
3610 bool
3611 AMDGPUAsmParser::parseSwizzleMacro(int64_t &Imm) {
3612   using namespace llvm::AMDGPU::Swizzle;
3613 
3614   if (skipToken(AsmToken::LParen, "expected a left parentheses")) {
3615 
3616     SMLoc ModeLoc = Parser.getTok().getLoc();
3617     bool Ok = false;
3618 
3619     if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
3620       Ok = parseSwizzleQuadPerm(Imm);
3621     } else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
3622       Ok = parseSwizzleBitmaskPerm(Imm);
3623     } else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
3624       Ok = parseSwizzleBroadcast(Imm);
3625     } else if (trySkipId(IdSymbolic[ID_SWAP])) {
3626       Ok = parseSwizzleSwap(Imm);
3627     } else if (trySkipId(IdSymbolic[ID_REVERSE])) {
3628       Ok = parseSwizzleReverse(Imm);
3629     } else {
3630       Error(ModeLoc, "expected a swizzle mode");
3631     }
3632 
3633     return Ok && skipToken(AsmToken::RParen, "expected a closing parentheses");
3634   }
3635 
3636   return false;
3637 }
3638 
3639 OperandMatchResultTy
3640 AMDGPUAsmParser::parseSwizzleOp(OperandVector &Operands) {
3641   SMLoc S = Parser.getTok().getLoc();
3642   int64_t Imm = 0;
3643 
3644   if (trySkipId("offset")) {
3645 
3646     bool Ok = false;
3647     if (skipToken(AsmToken::Colon, "expected a colon")) {
3648       if (trySkipId("swizzle")) {
3649         Ok = parseSwizzleMacro(Imm);
3650       } else {
3651         Ok = parseSwizzleOffset(Imm);
3652       }
3653     }
3654 
3655     Operands.push_back(AMDGPUOperand::CreateImm(this, Imm, S, AMDGPUOperand::ImmTySwizzle));
3656 
3657     return Ok? MatchOperand_Success : MatchOperand_ParseFail;
3658   } else {
3659     return MatchOperand_NoMatch;
3660   }
3661 }
3662 
3663 bool
3664 AMDGPUOperand::isSwizzle() const {
3665   return isImmTy(ImmTySwizzle);
3666 }
3667 
3668 //===----------------------------------------------------------------------===//
3669 // sopp branch targets
3670 //===----------------------------------------------------------------------===//
3671 
3672 OperandMatchResultTy
3673 AMDGPUAsmParser::parseSOppBrTarget(OperandVector &Operands) {
3674   SMLoc S = Parser.getTok().getLoc();
3675 
3676   switch (getLexer().getKind()) {
3677     default: return MatchOperand_ParseFail;
3678     case AsmToken::Integer: {
3679       int64_t Imm;
3680       if (getParser().parseAbsoluteExpression(Imm))
3681         return MatchOperand_ParseFail;
3682       Operands.push_back(AMDGPUOperand::CreateImm(this, Imm, S));
3683       return MatchOperand_Success;
3684     }
3685 
3686     case AsmToken::Identifier:
3687       Operands.push_back(AMDGPUOperand::CreateExpr(this,
3688           MCSymbolRefExpr::create(getContext().getOrCreateSymbol(
3689                                   Parser.getTok().getString()), getContext()), S));
3690       Parser.Lex();
3691       return MatchOperand_Success;
3692   }
3693 }
3694 
3695 //===----------------------------------------------------------------------===//
3696 // mubuf
3697 //===----------------------------------------------------------------------===//
3698 
3699 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultGLC() const {
3700   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyGLC);
3701 }
3702 
3703 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSLC() const {
3704   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTySLC);
3705 }
3706 
3707 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultTFE() const {
3708   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyTFE);
3709 }
3710 
3711 void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
3712                                const OperandVector &Operands,
3713                                bool IsAtomic, bool IsAtomicReturn) {
3714   OptionalImmIndexMap OptionalIdx;
3715   assert(IsAtomicReturn ? IsAtomic : true);
3716 
3717   for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
3718     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
3719 
3720     // Add the register arguments
3721     if (Op.isReg()) {
3722       Op.addRegOperands(Inst, 1);
3723       continue;
3724     }
3725 
3726     // Handle the case where soffset is an immediate
3727     if (Op.isImm() && Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
3728       Op.addImmOperands(Inst, 1);
3729       continue;
3730     }
3731 
3732     // Handle tokens like 'offen' which are sometimes hard-coded into the
3733     // asm string.  There are no MCInst operands for these.
3734     if (Op.isToken()) {
3735       continue;
3736     }
3737     assert(Op.isImm());
3738 
3739     // Handle optional arguments
3740     OptionalIdx[Op.getImmTy()] = i;
3741   }
3742 
3743   // Copy $vdata_in operand and insert as $vdata for MUBUF_Atomic RTN insns.
3744   if (IsAtomicReturn) {
3745     MCInst::iterator I = Inst.begin(); // $vdata_in is always at the beginning.
3746     Inst.insert(I, *I);
3747   }
3748 
3749   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOffset);
3750   if (!IsAtomic) { // glc is hard-coded.
3751     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGLC);
3752   }
3753   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySLC);
3754   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyTFE);
3755 }
3756 
3757 //===----------------------------------------------------------------------===//
3758 // mimg
3759 //===----------------------------------------------------------------------===//
3760 
3761 void AMDGPUAsmParser::cvtMIMG(MCInst &Inst, const OperandVector &Operands) {
3762   unsigned I = 1;
3763   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
3764   for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
3765     ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
3766   }
3767 
3768   OptionalImmIndexMap OptionalIdx;
3769 
3770   for (unsigned E = Operands.size(); I != E; ++I) {
3771     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
3772 
3773     // Add the register arguments
3774     if (Op.isRegOrImm()) {
3775       Op.addRegOrImmOperands(Inst, 1);
3776       continue;
3777     } else if (Op.isImmModifier()) {
3778       OptionalIdx[Op.getImmTy()] = I;
3779     } else {
3780       llvm_unreachable("unexpected operand type");
3781     }
3782   }
3783 
3784   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDMask);
3785   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyUNorm);
3786   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGLC);
3787   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDA);
3788   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyR128);
3789   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyTFE);
3790   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyLWE);
3791   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySLC);
3792 }
3793 
3794 void AMDGPUAsmParser::cvtMIMGAtomic(MCInst &Inst, const OperandVector &Operands) {
3795   unsigned I = 1;
3796   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
3797   for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
3798     ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
3799   }
3800 
3801   // Add src, same as dst
3802   ((AMDGPUOperand &)*Operands[I]).addRegOperands(Inst, 1);
3803 
3804   OptionalImmIndexMap OptionalIdx;
3805 
3806   for (unsigned E = Operands.size(); I != E; ++I) {
3807     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
3808 
3809     // Add the register arguments
3810     if (Op.isRegOrImm()) {
3811       Op.addRegOrImmOperands(Inst, 1);
3812       continue;
3813     } else if (Op.isImmModifier()) {
3814       OptionalIdx[Op.getImmTy()] = I;
3815     } else {
3816       llvm_unreachable("unexpected operand type");
3817     }
3818   }
3819 
3820   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDMask);
3821   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyUNorm);
3822   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGLC);
3823   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDA);
3824   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyR128);
3825   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyTFE);
3826   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyLWE);
3827   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySLC);
3828 }
3829 
3830 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultDMask() const {
3831   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyDMask);
3832 }
3833 
3834 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultUNorm() const {
3835   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyUNorm);
3836 }
3837 
3838 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultDA() const {
3839   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyDA);
3840 }
3841 
3842 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultR128() const {
3843   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyR128);
3844 }
3845 
3846 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultLWE() const {
3847   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyLWE);
3848 }
3849 
3850 //===----------------------------------------------------------------------===//
3851 // smrd
3852 //===----------------------------------------------------------------------===//
3853 
3854 bool AMDGPUOperand::isSMRDOffset8() const {
3855   return isImm() && isUInt<8>(getImm());
3856 }
3857 
3858 bool AMDGPUOperand::isSMRDOffset20() const {
3859   return isImm() && isUInt<20>(getImm());
3860 }
3861 
3862 bool AMDGPUOperand::isSMRDLiteralOffset() const {
3863   // 32-bit literals are only supported on CI and we only want to use them
3864   // when the offset is > 8-bits.
3865   return isImm() && !isUInt<8>(getImm()) && isUInt<32>(getImm());
3866 }
3867 
3868 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDOffset8() const {
3869   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyOffset);
3870 }
3871 
3872 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDOffset20() const {
3873   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyOffset);
3874 }
3875 
3876 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDLiteralOffset() const {
3877   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyOffset);
3878 }
3879 
3880 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultOffsetU12() const {
3881   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyOffset);
3882 }
3883 
3884 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultOffsetS13() const {
3885   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyOffset);
3886 }
3887 
3888 //===----------------------------------------------------------------------===//
3889 // vop3
3890 //===----------------------------------------------------------------------===//
3891 
3892 static bool ConvertOmodMul(int64_t &Mul) {
3893   if (Mul != 1 && Mul != 2 && Mul != 4)
3894     return false;
3895 
3896   Mul >>= 1;
3897   return true;
3898 }
3899 
3900 static bool ConvertOmodDiv(int64_t &Div) {
3901   if (Div == 1) {
3902     Div = 0;
3903     return true;
3904   }
3905 
3906   if (Div == 2) {
3907     Div = 3;
3908     return true;
3909   }
3910 
3911   return false;
3912 }
3913 
3914 static bool ConvertBoundCtrl(int64_t &BoundCtrl) {
3915   if (BoundCtrl == 0) {
3916     BoundCtrl = 1;
3917     return true;
3918   }
3919 
3920   if (BoundCtrl == -1) {
3921     BoundCtrl = 0;
3922     return true;
3923   }
3924 
3925   return false;
3926 }
3927 
3928 // Note: the order in this table matches the order of operands in AsmString.
3929 static const OptionalOperand AMDGPUOptionalOperandTable[] = {
3930   {"offen",   AMDGPUOperand::ImmTyOffen, true, nullptr},
3931   {"idxen",   AMDGPUOperand::ImmTyIdxen, true, nullptr},
3932   {"addr64",  AMDGPUOperand::ImmTyAddr64, true, nullptr},
3933   {"offset0", AMDGPUOperand::ImmTyOffset0, false, nullptr},
3934   {"offset1", AMDGPUOperand::ImmTyOffset1, false, nullptr},
3935   {"gds",     AMDGPUOperand::ImmTyGDS, true, nullptr},
3936   {"offset",  AMDGPUOperand::ImmTyOffset, false, nullptr},
3937   {"glc",     AMDGPUOperand::ImmTyGLC, true, nullptr},
3938   {"slc",     AMDGPUOperand::ImmTySLC, true, nullptr},
3939   {"tfe",     AMDGPUOperand::ImmTyTFE, true, nullptr},
3940   {"clamp",   AMDGPUOperand::ImmTyClampSI, true, nullptr},
3941   {"omod",    AMDGPUOperand::ImmTyOModSI, false, ConvertOmodMul},
3942   {"unorm",   AMDGPUOperand::ImmTyUNorm, true, nullptr},
3943   {"da",      AMDGPUOperand::ImmTyDA,    true, nullptr},
3944   {"r128",    AMDGPUOperand::ImmTyR128,  true, nullptr},
3945   {"lwe",     AMDGPUOperand::ImmTyLWE,   true, nullptr},
3946   {"dmask",   AMDGPUOperand::ImmTyDMask, false, nullptr},
3947   {"row_mask",   AMDGPUOperand::ImmTyDppRowMask, false, nullptr},
3948   {"bank_mask",  AMDGPUOperand::ImmTyDppBankMask, false, nullptr},
3949   {"bound_ctrl", AMDGPUOperand::ImmTyDppBoundCtrl, false, ConvertBoundCtrl},
3950   {"dst_sel",    AMDGPUOperand::ImmTySdwaDstSel, false, nullptr},
3951   {"src0_sel",   AMDGPUOperand::ImmTySdwaSrc0Sel, false, nullptr},
3952   {"src1_sel",   AMDGPUOperand::ImmTySdwaSrc1Sel, false, nullptr},
3953   {"dst_unused", AMDGPUOperand::ImmTySdwaDstUnused, false, nullptr},
3954   {"compr", AMDGPUOperand::ImmTyExpCompr, true, nullptr },
3955   {"vm", AMDGPUOperand::ImmTyExpVM, true, nullptr},
3956   {"op_sel", AMDGPUOperand::ImmTyOpSel, false, nullptr},
3957   {"op_sel_hi", AMDGPUOperand::ImmTyOpSelHi, false, nullptr},
3958   {"neg_lo", AMDGPUOperand::ImmTyNegLo, false, nullptr},
3959   {"neg_hi", AMDGPUOperand::ImmTyNegHi, false, nullptr}
3960 };
3961 
3962 OperandMatchResultTy AMDGPUAsmParser::parseOptionalOperand(OperandVector &Operands) {
3963   OperandMatchResultTy res;
3964   for (const OptionalOperand &Op : AMDGPUOptionalOperandTable) {
3965     // try to parse any optional operand here
3966     if (Op.IsBit) {
3967       res = parseNamedBit(Op.Name, Operands, Op.Type);
3968     } else if (Op.Type == AMDGPUOperand::ImmTyOModSI) {
3969       res = parseOModOperand(Operands);
3970     } else if (Op.Type == AMDGPUOperand::ImmTySdwaDstSel ||
3971                Op.Type == AMDGPUOperand::ImmTySdwaSrc0Sel ||
3972                Op.Type == AMDGPUOperand::ImmTySdwaSrc1Sel) {
3973       res = parseSDWASel(Operands, Op.Name, Op.Type);
3974     } else if (Op.Type == AMDGPUOperand::ImmTySdwaDstUnused) {
3975       res = parseSDWADstUnused(Operands);
3976     } else if (Op.Type == AMDGPUOperand::ImmTyOpSel ||
3977                Op.Type == AMDGPUOperand::ImmTyOpSelHi ||
3978                Op.Type == AMDGPUOperand::ImmTyNegLo ||
3979                Op.Type == AMDGPUOperand::ImmTyNegHi) {
3980       res = parseOperandArrayWithPrefix(Op.Name, Operands, Op.Type,
3981                                         Op.ConvertResult);
3982     } else {
3983       res = parseIntWithPrefix(Op.Name, Operands, Op.Type, Op.ConvertResult);
3984     }
3985     if (res != MatchOperand_NoMatch) {
3986       return res;
3987     }
3988   }
3989   return MatchOperand_NoMatch;
3990 }
3991 
3992 OperandMatchResultTy AMDGPUAsmParser::parseOModOperand(OperandVector &Operands) {
3993   StringRef Name = Parser.getTok().getString();
3994   if (Name == "mul") {
3995     return parseIntWithPrefix("mul", Operands,
3996                               AMDGPUOperand::ImmTyOModSI, ConvertOmodMul);
3997   }
3998 
3999   if (Name == "div") {
4000     return parseIntWithPrefix("div", Operands,
4001                               AMDGPUOperand::ImmTyOModSI, ConvertOmodDiv);
4002   }
4003 
4004   return MatchOperand_NoMatch;
4005 }
4006 
4007 void AMDGPUAsmParser::cvtId(MCInst &Inst, const OperandVector &Operands) {
4008   unsigned I = 1;
4009   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
4010   for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
4011     ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
4012   }
4013   for (unsigned E = Operands.size(); I != E; ++I)
4014     ((AMDGPUOperand &)*Operands[I]).addRegOrImmOperands(Inst, 1);
4015 }
4016 
4017 void AMDGPUAsmParser::cvtVOP3_2_mod(MCInst &Inst, const OperandVector &Operands) {
4018   uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
4019   if (TSFlags & SIInstrFlags::VOP3) {
4020     cvtVOP3(Inst, Operands);
4021   } else {
4022     cvtId(Inst, Operands);
4023   }
4024 }
4025 
4026 static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum) {
4027       // 1. This operand is input modifiers
4028   return Desc.OpInfo[OpNum].OperandType == AMDGPU::OPERAND_INPUT_MODS
4029       // 2. This is not last operand
4030       && Desc.NumOperands > (OpNum + 1)
4031       // 3. Next operand is register class
4032       && Desc.OpInfo[OpNum + 1].RegClass != -1
4033       // 4. Next register is not tied to any other operand
4034       && Desc.getOperandConstraint(OpNum + 1, MCOI::OperandConstraint::TIED_TO) == -1;
4035 }
4036 
4037 void AMDGPUAsmParser::cvtVOP3Impl(MCInst &Inst, const OperandVector &Operands,
4038                                   OptionalImmIndexMap &OptionalIdx) {
4039   unsigned I = 1;
4040   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
4041   for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
4042     ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
4043   }
4044 
4045   for (unsigned E = Operands.size(); I != E; ++I) {
4046     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
4047     if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
4048       Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
4049     } else if (Op.isImmModifier()) {
4050       OptionalIdx[Op.getImmTy()] = I;
4051     } else if (Op.isRegOrImm()) {
4052       Op.addRegOrImmOperands(Inst, 1);
4053     } else {
4054       llvm_unreachable("unhandled operand type");
4055     }
4056   }
4057 }
4058 
4059 void AMDGPUAsmParser::cvtVOP3(MCInst &Inst, const OperandVector &Operands) {
4060   OptionalImmIndexMap OptionalIdx;
4061 
4062   cvtVOP3Impl(Inst, Operands, OptionalIdx);
4063 
4064   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI);
4065   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOModSI);
4066 
4067   // special case v_mac_{f16, f32}:
4068   // it has src2 register operand that is tied to dst operand
4069   // we don't allow modifiers for this operand in assembler so src2_modifiers
4070   // should be 0
4071   if (Inst.getOpcode() == AMDGPU::V_MAC_F32_e64_si ||
4072       Inst.getOpcode() == AMDGPU::V_MAC_F32_e64_vi ||
4073       Inst.getOpcode() == AMDGPU::V_MAC_F16_e64_vi) {
4074     auto it = Inst.begin();
4075     std::advance(
4076       it,
4077       AMDGPU::getNamedOperandIdx(Inst.getOpcode() == AMDGPU::V_MAC_F16_e64_vi ?
4078                                      AMDGPU::V_MAC_F16_e64 :
4079                                      AMDGPU::V_MAC_F32_e64,
4080                                  AMDGPU::OpName::src2_modifiers));
4081     it = Inst.insert(it, MCOperand::createImm(0)); // no modifiers for src2
4082     ++it;
4083     Inst.insert(it, Inst.getOperand(0)); // src2 = dst
4084   }
4085 }
4086 
4087 void AMDGPUAsmParser::cvtVOP3OMod(MCInst &Inst, const OperandVector &Operands) {
4088   OptionalImmIndexMap OptionalIdx;
4089 
4090   unsigned I = 1;
4091   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
4092   for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
4093     ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
4094   }
4095 
4096   for (unsigned E = Operands.size(); I != E; ++I) {
4097     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
4098     if (Op.isMod()) {
4099       OptionalIdx[Op.getImmTy()] = I;
4100     } else {
4101       Op.addRegOrImmOperands(Inst, 1);
4102     }
4103   }
4104 
4105   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI);
4106   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOModSI);
4107 }
4108 
4109 void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst, const OperandVector &Operands) {
4110   OptionalImmIndexMap OptIdx;
4111 
4112   cvtVOP3Impl(Inst, Operands, OptIdx);
4113 
4114   // FIXME: This is messy. Parse the modifiers as if it was a normal VOP3
4115   // instruction, and then figure out where to actually put the modifiers
4116   int Opc = Inst.getOpcode();
4117 
4118   if (AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::clamp) != -1) {
4119     addOptionalImmOperand(Inst, Operands, OptIdx, AMDGPUOperand::ImmTyClampSI);
4120   }
4121 
4122   addOptionalImmOperand(Inst, Operands, OptIdx, AMDGPUOperand::ImmTyOpSel);
4123   addOptionalImmOperand(Inst, Operands, OptIdx, AMDGPUOperand::ImmTyOpSelHi, -1);
4124 
4125   int NegLoIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::neg_lo);
4126   if (NegLoIdx != -1) {
4127     addOptionalImmOperand(Inst, Operands, OptIdx, AMDGPUOperand::ImmTyNegLo);
4128     addOptionalImmOperand(Inst, Operands, OptIdx, AMDGPUOperand::ImmTyNegHi);
4129   }
4130 
4131   const int Ops[] = { AMDGPU::OpName::src0,
4132                       AMDGPU::OpName::src1,
4133                       AMDGPU::OpName::src2 };
4134   const int ModOps[] = { AMDGPU::OpName::src0_modifiers,
4135                          AMDGPU::OpName::src1_modifiers,
4136                          AMDGPU::OpName::src2_modifiers };
4137 
4138   int OpSelIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
4139   int OpSelHiIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel_hi);
4140 
4141   unsigned OpSel = Inst.getOperand(OpSelIdx).getImm();
4142   unsigned OpSelHi = Inst.getOperand(OpSelHiIdx).getImm();
4143   unsigned NegLo = 0;
4144   unsigned NegHi = 0;
4145 
4146   if (NegLoIdx != -1) {
4147     int NegHiIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::neg_hi);
4148     NegLo = Inst.getOperand(NegLoIdx).getImm();
4149     NegHi = Inst.getOperand(NegHiIdx).getImm();
4150   }
4151 
4152   for (int J = 0; J < 3; ++J) {
4153     int OpIdx = AMDGPU::getNamedOperandIdx(Opc, Ops[J]);
4154     if (OpIdx == -1)
4155       break;
4156 
4157     uint32_t ModVal = 0;
4158 
4159     if ((OpSel & (1 << J)) != 0)
4160       ModVal |= SISrcMods::OP_SEL_0;
4161 
4162     if ((OpSelHi & (1 << J)) != 0)
4163       ModVal |= SISrcMods::OP_SEL_1;
4164 
4165     if ((NegLo & (1 << J)) != 0)
4166       ModVal |= SISrcMods::NEG;
4167 
4168     if ((NegHi & (1 << J)) != 0)
4169       ModVal |= SISrcMods::NEG_HI;
4170 
4171     int ModIdx = AMDGPU::getNamedOperandIdx(Opc, ModOps[J]);
4172 
4173     Inst.getOperand(ModIdx).setImm(ModVal);
4174   }
4175 }
4176 
4177 //===----------------------------------------------------------------------===//
4178 // dpp
4179 //===----------------------------------------------------------------------===//
4180 
4181 bool AMDGPUOperand::isDPPCtrl() const {
4182   bool result = isImm() && getImmTy() == ImmTyDppCtrl && isUInt<9>(getImm());
4183   if (result) {
4184     int64_t Imm = getImm();
4185     return ((Imm >= 0x000) && (Imm <= 0x0ff)) ||
4186            ((Imm >= 0x101) && (Imm <= 0x10f)) ||
4187            ((Imm >= 0x111) && (Imm <= 0x11f)) ||
4188            ((Imm >= 0x121) && (Imm <= 0x12f)) ||
4189            (Imm == 0x130) ||
4190            (Imm == 0x134) ||
4191            (Imm == 0x138) ||
4192            (Imm == 0x13c) ||
4193            (Imm == 0x140) ||
4194            (Imm == 0x141) ||
4195            (Imm == 0x142) ||
4196            (Imm == 0x143);
4197   }
4198   return false;
4199 }
4200 
4201 bool AMDGPUOperand::isGPRIdxMode() const {
4202   return isImm() && isUInt<4>(getImm());
4203 }
4204 
4205 bool AMDGPUOperand::isS16Imm() const {
4206   return isImm() && (isInt<16>(getImm()) || isUInt<16>(getImm()));
4207 }
4208 
4209 bool AMDGPUOperand::isU16Imm() const {
4210   return isImm() && isUInt<16>(getImm());
4211 }
4212 
4213 OperandMatchResultTy
4214 AMDGPUAsmParser::parseDPPCtrl(OperandVector &Operands) {
4215   SMLoc S = Parser.getTok().getLoc();
4216   StringRef Prefix;
4217   int64_t Int;
4218 
4219   if (getLexer().getKind() == AsmToken::Identifier) {
4220     Prefix = Parser.getTok().getString();
4221   } else {
4222     return MatchOperand_NoMatch;
4223   }
4224 
4225   if (Prefix == "row_mirror") {
4226     Int = 0x140;
4227     Parser.Lex();
4228   } else if (Prefix == "row_half_mirror") {
4229     Int = 0x141;
4230     Parser.Lex();
4231   } else {
4232     // Check to prevent parseDPPCtrlOps from eating invalid tokens
4233     if (Prefix != "quad_perm"
4234         && Prefix != "row_shl"
4235         && Prefix != "row_shr"
4236         && Prefix != "row_ror"
4237         && Prefix != "wave_shl"
4238         && Prefix != "wave_rol"
4239         && Prefix != "wave_shr"
4240         && Prefix != "wave_ror"
4241         && Prefix != "row_bcast") {
4242       return MatchOperand_NoMatch;
4243     }
4244 
4245     Parser.Lex();
4246     if (getLexer().isNot(AsmToken::Colon))
4247       return MatchOperand_ParseFail;
4248 
4249     if (Prefix == "quad_perm") {
4250       // quad_perm:[%d,%d,%d,%d]
4251       Parser.Lex();
4252       if (getLexer().isNot(AsmToken::LBrac))
4253         return MatchOperand_ParseFail;
4254       Parser.Lex();
4255 
4256       if (getParser().parseAbsoluteExpression(Int) || !(0 <= Int && Int <=3))
4257         return MatchOperand_ParseFail;
4258 
4259       for (int i = 0; i < 3; ++i) {
4260         if (getLexer().isNot(AsmToken::Comma))
4261           return MatchOperand_ParseFail;
4262         Parser.Lex();
4263 
4264         int64_t Temp;
4265         if (getParser().parseAbsoluteExpression(Temp) || !(0 <= Temp && Temp <=3))
4266           return MatchOperand_ParseFail;
4267         const int shift = i*2 + 2;
4268         Int += (Temp << shift);
4269       }
4270 
4271       if (getLexer().isNot(AsmToken::RBrac))
4272         return MatchOperand_ParseFail;
4273       Parser.Lex();
4274 
4275     } else {
4276       // sel:%d
4277       Parser.Lex();
4278       if (getParser().parseAbsoluteExpression(Int))
4279         return MatchOperand_ParseFail;
4280 
4281       if (Prefix == "row_shl" && 1 <= Int && Int <= 15) {
4282         Int |= 0x100;
4283       } else if (Prefix == "row_shr" && 1 <= Int && Int <= 15) {
4284         Int |= 0x110;
4285       } else if (Prefix == "row_ror" && 1 <= Int && Int <= 15) {
4286         Int |= 0x120;
4287       } else if (Prefix == "wave_shl" && 1 == Int) {
4288         Int = 0x130;
4289       } else if (Prefix == "wave_rol" && 1 == Int) {
4290         Int = 0x134;
4291       } else if (Prefix == "wave_shr" && 1 == Int) {
4292         Int = 0x138;
4293       } else if (Prefix == "wave_ror" && 1 == Int) {
4294         Int = 0x13C;
4295       } else if (Prefix == "row_bcast") {
4296         if (Int == 15) {
4297           Int = 0x142;
4298         } else if (Int == 31) {
4299           Int = 0x143;
4300         } else {
4301           return MatchOperand_ParseFail;
4302         }
4303       } else {
4304         return MatchOperand_ParseFail;
4305       }
4306     }
4307   }
4308 
4309   Operands.push_back(AMDGPUOperand::CreateImm(this, Int, S, AMDGPUOperand::ImmTyDppCtrl));
4310   return MatchOperand_Success;
4311 }
4312 
4313 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultRowMask() const {
4314   return AMDGPUOperand::CreateImm(this, 0xf, SMLoc(), AMDGPUOperand::ImmTyDppRowMask);
4315 }
4316 
4317 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultBankMask() const {
4318   return AMDGPUOperand::CreateImm(this, 0xf, SMLoc(), AMDGPUOperand::ImmTyDppBankMask);
4319 }
4320 
4321 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultBoundCtrl() const {
4322   return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyDppBoundCtrl);
4323 }
4324 
4325 void AMDGPUAsmParser::cvtDPP(MCInst &Inst, const OperandVector &Operands) {
4326   OptionalImmIndexMap OptionalIdx;
4327 
4328   unsigned I = 1;
4329   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
4330   for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
4331     ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
4332   }
4333 
4334   for (unsigned E = Operands.size(); I != E; ++I) {
4335     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
4336     // Add the register arguments
4337     if (Op.isReg() && Op.Reg.RegNo == AMDGPU::VCC) {
4338       // VOP2b (v_add_u32, v_sub_u32 ...) dpp use "vcc" token.
4339       // Skip it.
4340       continue;
4341     } if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
4342       Op.addRegWithFPInputModsOperands(Inst, 2);
4343     } else if (Op.isDPPCtrl()) {
4344       Op.addImmOperands(Inst, 1);
4345     } else if (Op.isImm()) {
4346       // Handle optional arguments
4347       OptionalIdx[Op.getImmTy()] = I;
4348     } else {
4349       llvm_unreachable("Invalid operand type");
4350     }
4351   }
4352 
4353   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppRowMask, 0xf);
4354   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBankMask, 0xf);
4355   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBoundCtrl);
4356 
4357   // special case v_mac_{f16, f32}:
4358   // it has src2 register operand that is tied to dst operand
4359   if (Inst.getOpcode() == AMDGPU::V_MAC_F32_dpp ||
4360       Inst.getOpcode() == AMDGPU::V_MAC_F16_dpp) {
4361     auto it = Inst.begin();
4362     std::advance(
4363         it, AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::src2));
4364     Inst.insert(it, Inst.getOperand(0)); // src2 = dst
4365   }
4366 }
4367 
4368 //===----------------------------------------------------------------------===//
4369 // sdwa
4370 //===----------------------------------------------------------------------===//
4371 
4372 OperandMatchResultTy
4373 AMDGPUAsmParser::parseSDWASel(OperandVector &Operands, StringRef Prefix,
4374                               AMDGPUOperand::ImmTy Type) {
4375   using namespace llvm::AMDGPU::SDWA;
4376 
4377   SMLoc S = Parser.getTok().getLoc();
4378   StringRef Value;
4379   OperandMatchResultTy res;
4380 
4381   res = parseStringWithPrefix(Prefix, Value);
4382   if (res != MatchOperand_Success) {
4383     return res;
4384   }
4385 
4386   int64_t Int;
4387   Int = StringSwitch<int64_t>(Value)
4388         .Case("BYTE_0", SdwaSel::BYTE_0)
4389         .Case("BYTE_1", SdwaSel::BYTE_1)
4390         .Case("BYTE_2", SdwaSel::BYTE_2)
4391         .Case("BYTE_3", SdwaSel::BYTE_3)
4392         .Case("WORD_0", SdwaSel::WORD_0)
4393         .Case("WORD_1", SdwaSel::WORD_1)
4394         .Case("DWORD", SdwaSel::DWORD)
4395         .Default(0xffffffff);
4396   Parser.Lex(); // eat last token
4397 
4398   if (Int == 0xffffffff) {
4399     return MatchOperand_ParseFail;
4400   }
4401 
4402   Operands.push_back(AMDGPUOperand::CreateImm(this, Int, S, Type));
4403   return MatchOperand_Success;
4404 }
4405 
4406 OperandMatchResultTy
4407 AMDGPUAsmParser::parseSDWADstUnused(OperandVector &Operands) {
4408   using namespace llvm::AMDGPU::SDWA;
4409 
4410   SMLoc S = Parser.getTok().getLoc();
4411   StringRef Value;
4412   OperandMatchResultTy res;
4413 
4414   res = parseStringWithPrefix("dst_unused", Value);
4415   if (res != MatchOperand_Success) {
4416     return res;
4417   }
4418 
4419   int64_t Int;
4420   Int = StringSwitch<int64_t>(Value)
4421         .Case("UNUSED_PAD", DstUnused::UNUSED_PAD)
4422         .Case("UNUSED_SEXT", DstUnused::UNUSED_SEXT)
4423         .Case("UNUSED_PRESERVE", DstUnused::UNUSED_PRESERVE)
4424         .Default(0xffffffff);
4425   Parser.Lex(); // eat last token
4426 
4427   if (Int == 0xffffffff) {
4428     return MatchOperand_ParseFail;
4429   }
4430 
4431   Operands.push_back(AMDGPUOperand::CreateImm(this, Int, S, AMDGPUOperand::ImmTySdwaDstUnused));
4432   return MatchOperand_Success;
4433 }
4434 
4435 void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst, const OperandVector &Operands) {
4436   cvtSDWA(Inst, Operands, SIInstrFlags::VOP1);
4437 }
4438 
4439 void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst, const OperandVector &Operands) {
4440   cvtSDWA(Inst, Operands, SIInstrFlags::VOP2);
4441 }
4442 
4443 void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst, const OperandVector &Operands) {
4444   cvtSDWA(Inst, Operands, SIInstrFlags::VOP2, true);
4445 }
4446 
4447 void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst, const OperandVector &Operands) {
4448   cvtSDWA(Inst, Operands, SIInstrFlags::VOPC, isVI());
4449 }
4450 
4451 void AMDGPUAsmParser::cvtSDWA(MCInst &Inst, const OperandVector &Operands,
4452                               uint64_t BasicInstType, bool skipVcc) {
4453   using namespace llvm::AMDGPU::SDWA;
4454   OptionalImmIndexMap OptionalIdx;
4455   bool skippedVcc = false;
4456 
4457   unsigned I = 1;
4458   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
4459   for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
4460     ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
4461   }
4462 
4463   for (unsigned E = Operands.size(); I != E; ++I) {
4464     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
4465     if (skipVcc && !skippedVcc && Op.isReg() && Op.Reg.RegNo == AMDGPU::VCC) {
4466       // VOP2b (v_add_u32, v_sub_u32 ...) sdwa use "vcc" token as dst.
4467       // Skip it if it's 2nd (e.g. v_add_i32_sdwa v1, vcc, v2, v3)
4468       // or 4th (v_addc_u32_sdwa v1, vcc, v2, v3, vcc) operand.
4469       // Skip VCC only if we didn't skip it on previous iteration.
4470       if (BasicInstType == SIInstrFlags::VOP2 &&
4471           (Inst.getNumOperands() == 1 || Inst.getNumOperands() == 5)) {
4472         skippedVcc = true;
4473         continue;
4474       } else if (BasicInstType == SIInstrFlags::VOPC &&
4475                  Inst.getNumOperands() == 0) {
4476         skippedVcc = true;
4477         continue;
4478       }
4479     }
4480     if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
4481       Op.addRegWithInputModsOperands(Inst, 2);
4482     } else if (Op.isImm()) {
4483       // Handle optional arguments
4484       OptionalIdx[Op.getImmTy()] = I;
4485     } else {
4486       llvm_unreachable("Invalid operand type");
4487     }
4488     skippedVcc = false;
4489   }
4490 
4491   if (Inst.getOpcode() != AMDGPU::V_NOP_sdwa_gfx9 &&
4492       Inst.getOpcode() != AMDGPU::V_NOP_sdwa_vi) {
4493     // V_NOP_sdwa_vi has no optional sdwa arguments
4494     switch (BasicInstType) {
4495     case SIInstrFlags::VOP1:
4496       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI, 0);
4497       if (isGFX9() &&
4498           AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::omod) != -1) {
4499         addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOModSI, 0);
4500       }
4501       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaDstSel, SdwaSel::DWORD);
4502       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaDstUnused, DstUnused::UNUSED_PRESERVE);
4503       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaSrc0Sel, SdwaSel::DWORD);
4504       break;
4505 
4506     case SIInstrFlags::VOP2:
4507       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI, 0);
4508       if (isGFX9() &&
4509           AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::omod) != -1) {
4510         addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOModSI, 0);
4511       }
4512       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaDstSel, SdwaSel::DWORD);
4513       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaDstUnused, DstUnused::UNUSED_PRESERVE);
4514       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaSrc0Sel, SdwaSel::DWORD);
4515       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaSrc1Sel, SdwaSel::DWORD);
4516       break;
4517 
4518     case SIInstrFlags::VOPC:
4519       if (isVI()) {
4520         addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI, 0);
4521       }
4522       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaSrc0Sel, SdwaSel::DWORD);
4523       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySdwaSrc1Sel, SdwaSel::DWORD);
4524       break;
4525 
4526     default:
4527       llvm_unreachable("Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
4528     }
4529   }
4530 
4531   // special case v_mac_{f16, f32}:
4532   // it has src2 register operand that is tied to dst operand
4533   if (Inst.getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
4534       Inst.getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi)  {
4535     auto it = Inst.begin();
4536     std::advance(
4537       it, AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::src2));
4538     Inst.insert(it, Inst.getOperand(0)); // src2 = dst
4539   }
4540 }
4541 
4542 /// Force static initialization.
4543 extern "C" void LLVMInitializeAMDGPUAsmParser() {
4544   RegisterMCAsmParser<AMDGPUAsmParser> A(getTheAMDGPUTarget());
4545   RegisterMCAsmParser<AMDGPUAsmParser> B(getTheGCNTarget());
4546 }
4547 
4548 #define GET_REGISTER_MATCHER
4549 #define GET_MATCHER_IMPLEMENTATION
4550 #include "AMDGPUGenAsmMatcher.inc"
4551 
4552 // This fuction should be defined after auto-generated include so that we have
4553 // MatchClassKind enum defined
4554 unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &Op,
4555                                                      unsigned Kind) {
4556   // Tokens like "glc" would be parsed as immediate operands in ParseOperand().
4557   // But MatchInstructionImpl() expects to meet token and fails to validate
4558   // operand. This method checks if we are given immediate operand but expect to
4559   // get corresponding token.
4560   AMDGPUOperand &Operand = (AMDGPUOperand&)Op;
4561   switch (Kind) {
4562   case MCK_addr64:
4563     return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
4564   case MCK_gds:
4565     return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
4566   case MCK_glc:
4567     return Operand.isGLC() ? Match_Success : Match_InvalidOperand;
4568   case MCK_idxen:
4569     return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
4570   case MCK_offen:
4571     return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
4572   case MCK_SSrcB32:
4573     // When operands have expression values, they will return true for isToken,
4574     // because it is not possible to distinguish between a token and an
4575     // expression at parse time. MatchInstructionImpl() will always try to
4576     // match an operand as a token, when isToken returns true, and when the
4577     // name of the expression is not a valid token, the match will fail,
4578     // so we need to handle it here.
4579     return Operand.isSSrcB32() ? Match_Success : Match_InvalidOperand;
4580   case MCK_SSrcF32:
4581     return Operand.isSSrcF32() ? Match_Success : Match_InvalidOperand;
4582   case MCK_SoppBrTarget:
4583     return Operand.isSoppBrTarget() ? Match_Success : Match_InvalidOperand;
4584   case MCK_VReg32OrOff:
4585     return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
4586   case MCK_InterpSlot:
4587     return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
4588   case MCK_Attr:
4589     return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
4590   case MCK_AttrChan:
4591     return Operand.isAttrChan() ? Match_Success : Match_InvalidOperand;
4592   default:
4593     return Match_InvalidOperand;
4594   }
4595 }
4596