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