1 //===- AMDGPUAsmParser.cpp - Parse SI asm to MCInst instructions ----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "AMDKernelCodeT.h"
10 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
11 #include "MCTargetDesc/AMDGPUTargetStreamer.h"
12 #include "SIDefines.h"
13 #include "SIInstrInfo.h"
14 #include "SIRegisterInfo.h"
15 #include "TargetInfo/AMDGPUTargetInfo.h"
16 #include "Utils/AMDGPUAsmUtils.h"
17 #include "Utils/AMDGPUBaseInfo.h"
18 #include "Utils/AMDKernelCodeTUtils.h"
19 #include "llvm/ADT/APFloat.h"
20 #include "llvm/ADT/SmallBitVector.h"
21 #include "llvm/ADT/StringSet.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/BinaryFormat/ELF.h"
24 #include "llvm/CodeGen/MachineValueType.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/MCExpr.h"
28 #include "llvm/MC/MCInst.h"
29 #include "llvm/MC/MCInstrDesc.h"
30 #include "llvm/MC/MCParser/MCAsmLexer.h"
31 #include "llvm/MC/MCParser/MCAsmParser.h"
32 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
33 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
34 #include "llvm/MC/MCSymbol.h"
35 #include "llvm/MC/TargetRegistry.h"
36 #include "llvm/Support/AMDGPUMetadata.h"
37 #include "llvm/Support/AMDHSAKernelDescriptor.h"
38 #include "llvm/Support/Casting.h"
39 #include "llvm/Support/MathExtras.h"
40 #include "llvm/TargetParser/TargetParser.h"
41 #include <optional>
42 
43 using namespace llvm;
44 using namespace llvm::AMDGPU;
45 using namespace llvm::amdhsa;
46 
47 namespace {
48 
49 class AMDGPUAsmParser;
50 
51 enum RegisterKind { IS_UNKNOWN, IS_VGPR, IS_SGPR, IS_AGPR, IS_TTMP, IS_SPECIAL };
52 
53 //===----------------------------------------------------------------------===//
54 // Operand
55 //===----------------------------------------------------------------------===//
56 
57 class AMDGPUOperand : public MCParsedAsmOperand {
58   enum KindTy {
59     Token,
60     Immediate,
61     Register,
62     Expression
63   } Kind;
64 
65   SMLoc StartLoc, EndLoc;
66   const AMDGPUAsmParser *AsmParser;
67 
68 public:
69   AMDGPUOperand(KindTy Kind_, const AMDGPUAsmParser *AsmParser_)
70       : Kind(Kind_), AsmParser(AsmParser_) {}
71 
72   using Ptr = std::unique_ptr<AMDGPUOperand>;
73 
74   struct Modifiers {
75     bool Abs = false;
76     bool Neg = false;
77     bool Sext = false;
78     bool Lit = false;
79 
80     bool hasFPModifiers() const { return Abs || Neg; }
81     bool hasIntModifiers() const { return Sext; }
82     bool hasModifiers() const { return hasFPModifiers() || hasIntModifiers(); }
83 
84     int64_t getFPModifiersOperand() const {
85       int64_t Operand = 0;
86       Operand |= Abs ? SISrcMods::ABS : 0u;
87       Operand |= Neg ? SISrcMods::NEG : 0u;
88       return Operand;
89     }
90 
91     int64_t getIntModifiersOperand() const {
92       int64_t Operand = 0;
93       Operand |= Sext ? SISrcMods::SEXT : 0u;
94       return Operand;
95     }
96 
97     int64_t getModifiersOperand() const {
98       assert(!(hasFPModifiers() && hasIntModifiers())
99            && "fp and int modifiers should not be used simultaneously");
100       if (hasFPModifiers()) {
101         return getFPModifiersOperand();
102       } else if (hasIntModifiers()) {
103         return getIntModifiersOperand();
104       } else {
105         return 0;
106       }
107     }
108 
109     friend raw_ostream &operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
110   };
111 
112   enum ImmTy {
113     ImmTyNone,
114     ImmTyGDS,
115     ImmTyLDS,
116     ImmTyOffen,
117     ImmTyIdxen,
118     ImmTyAddr64,
119     ImmTyOffset,
120     ImmTyInstOffset,
121     ImmTyOffset0,
122     ImmTyOffset1,
123     ImmTySMEMOffsetMod,
124     ImmTyCPol,
125     ImmTyTFE,
126     ImmTyD16,
127     ImmTyClampSI,
128     ImmTyOModSI,
129     ImmTySDWADstSel,
130     ImmTySDWASrc0Sel,
131     ImmTySDWASrc1Sel,
132     ImmTySDWADstUnused,
133     ImmTyDMask,
134     ImmTyDim,
135     ImmTyUNorm,
136     ImmTyDA,
137     ImmTyR128A16,
138     ImmTyA16,
139     ImmTyLWE,
140     ImmTyExpTgt,
141     ImmTyExpCompr,
142     ImmTyExpVM,
143     ImmTyFORMAT,
144     ImmTyHwreg,
145     ImmTyOff,
146     ImmTySendMsg,
147     ImmTyInterpSlot,
148     ImmTyInterpAttr,
149     ImmTyInterpAttrChan,
150     ImmTyOpSel,
151     ImmTyOpSelHi,
152     ImmTyNegLo,
153     ImmTyNegHi,
154     ImmTyDPP8,
155     ImmTyDppCtrl,
156     ImmTyDppRowMask,
157     ImmTyDppBankMask,
158     ImmTyDppBoundCtrl,
159     ImmTyDppFI,
160     ImmTySwizzle,
161     ImmTyGprIdxMode,
162     ImmTyHigh,
163     ImmTyBLGP,
164     ImmTyCBSZ,
165     ImmTyABID,
166     ImmTyEndpgm,
167     ImmTyWaitVDST,
168     ImmTyWaitEXP,
169     ImmTyWaitVAVDst,
170     ImmTyWaitVMVSrc,
171   };
172 
173   // Immediate operand kind.
174   // It helps to identify the location of an offending operand after an error.
175   // Note that regular literals and mandatory literals (KImm) must be handled
176   // differently. When looking for an offending operand, we should usually
177   // ignore mandatory literals because they are part of the instruction and
178   // cannot be changed. Report location of mandatory operands only for VOPD,
179   // when both OpX and OpY have a KImm and there are no other literals.
180   enum ImmKindTy {
181     ImmKindTyNone,
182     ImmKindTyLiteral,
183     ImmKindTyMandatoryLiteral,
184     ImmKindTyConst,
185   };
186 
187 private:
188   struct TokOp {
189     const char *Data;
190     unsigned Length;
191   };
192 
193   struct ImmOp {
194     int64_t Val;
195     ImmTy Type;
196     bool IsFPImm;
197     mutable ImmKindTy Kind;
198     Modifiers Mods;
199   };
200 
201   struct RegOp {
202     unsigned RegNo;
203     Modifiers Mods;
204   };
205 
206   union {
207     TokOp Tok;
208     ImmOp Imm;
209     RegOp Reg;
210     const MCExpr *Expr;
211   };
212 
213 public:
214   bool isToken() const override { return Kind == Token; }
215 
216   bool isSymbolRefExpr() const {
217     return isExpr() && Expr && isa<MCSymbolRefExpr>(Expr);
218   }
219 
220   bool isImm() const override {
221     return Kind == Immediate;
222   }
223 
224   void setImmKindNone() const {
225     assert(isImm());
226     Imm.Kind = ImmKindTyNone;
227   }
228 
229   void setImmKindLiteral() const {
230     assert(isImm());
231     Imm.Kind = ImmKindTyLiteral;
232   }
233 
234   void setImmKindMandatoryLiteral() const {
235     assert(isImm());
236     Imm.Kind = ImmKindTyMandatoryLiteral;
237   }
238 
239   void setImmKindConst() const {
240     assert(isImm());
241     Imm.Kind = ImmKindTyConst;
242   }
243 
244   bool IsImmKindLiteral() const {
245     return isImm() && Imm.Kind == ImmKindTyLiteral;
246   }
247 
248   bool IsImmKindMandatoryLiteral() const {
249     return isImm() && Imm.Kind == ImmKindTyMandatoryLiteral;
250   }
251 
252   bool isImmKindConst() const {
253     return isImm() && Imm.Kind == ImmKindTyConst;
254   }
255 
256   bool isInlinableImm(MVT type) const;
257   bool isLiteralImm(MVT type) const;
258 
259   bool isRegKind() const {
260     return Kind == Register;
261   }
262 
263   bool isReg() const override {
264     return isRegKind() && !hasModifiers();
265   }
266 
267   bool isRegOrInline(unsigned RCID, MVT type) const {
268     return isRegClass(RCID) || isInlinableImm(type);
269   }
270 
271   bool isRegOrImmWithInputMods(unsigned RCID, MVT type) const {
272     return isRegOrInline(RCID, type) || isLiteralImm(type);
273   }
274 
275   bool isRegOrImmWithInt16InputMods() const {
276     return isRegOrImmWithInputMods(AMDGPU::VS_32RegClassID, MVT::i16);
277   }
278 
279   bool isRegOrImmWithIntT16InputMods() const {
280     return isRegOrImmWithInputMods(AMDGPU::VS_16RegClassID, MVT::i16);
281   }
282 
283   bool isRegOrImmWithInt32InputMods() const {
284     return isRegOrImmWithInputMods(AMDGPU::VS_32RegClassID, MVT::i32);
285   }
286 
287   bool isRegOrInlineImmWithInt16InputMods() const {
288     return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
289   }
290 
291   bool isRegOrInlineImmWithInt32InputMods() const {
292     return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
293   }
294 
295   bool isRegOrImmWithInt64InputMods() const {
296     return isRegOrImmWithInputMods(AMDGPU::VS_64RegClassID, MVT::i64);
297   }
298 
299   bool isRegOrImmWithFP16InputMods() const {
300     return isRegOrImmWithInputMods(AMDGPU::VS_32RegClassID, MVT::f16);
301   }
302 
303   bool isRegOrImmWithFPT16InputMods() const {
304     return isRegOrImmWithInputMods(AMDGPU::VS_16RegClassID, MVT::f16);
305   }
306 
307   bool isRegOrImmWithFP32InputMods() const {
308     return isRegOrImmWithInputMods(AMDGPU::VS_32RegClassID, MVT::f32);
309   }
310 
311   bool isRegOrImmWithFP64InputMods() const {
312     return isRegOrImmWithInputMods(AMDGPU::VS_64RegClassID, MVT::f64);
313   }
314 
315   bool isRegOrInlineImmWithFP16InputMods() const {
316     return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f16);
317   }
318 
319   bool isRegOrInlineImmWithFP32InputMods() const {
320     return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
321   }
322 
323 
324   bool isVReg() const {
325     return isRegClass(AMDGPU::VGPR_32RegClassID) ||
326            isRegClass(AMDGPU::VReg_64RegClassID) ||
327            isRegClass(AMDGPU::VReg_96RegClassID) ||
328            isRegClass(AMDGPU::VReg_128RegClassID) ||
329            isRegClass(AMDGPU::VReg_160RegClassID) ||
330            isRegClass(AMDGPU::VReg_192RegClassID) ||
331            isRegClass(AMDGPU::VReg_256RegClassID) ||
332            isRegClass(AMDGPU::VReg_512RegClassID) ||
333            isRegClass(AMDGPU::VReg_1024RegClassID);
334   }
335 
336   bool isVReg32() const {
337     return isRegClass(AMDGPU::VGPR_32RegClassID);
338   }
339 
340   bool isVReg32OrOff() const {
341     return isOff() || isVReg32();
342   }
343 
344   bool isNull() const {
345     return isRegKind() && getReg() == AMDGPU::SGPR_NULL;
346   }
347 
348   bool isVRegWithInputMods() const;
349   template <bool IsFake16> bool isT16VRegWithInputMods() const;
350 
351   bool isSDWAOperand(MVT type) const;
352   bool isSDWAFP16Operand() const;
353   bool isSDWAFP32Operand() const;
354   bool isSDWAInt16Operand() const;
355   bool isSDWAInt32Operand() const;
356 
357   bool isImmTy(ImmTy ImmT) const {
358     return isImm() && Imm.Type == ImmT;
359   }
360 
361   template <ImmTy Ty> bool isImmTy() const { return isImmTy(Ty); }
362 
363   bool isImmLiteral() const { return isImmTy(ImmTyNone); }
364 
365   bool isImmModifier() const {
366     return isImm() && Imm.Type != ImmTyNone;
367   }
368 
369   bool isOModSI() const { return isImmTy(ImmTyOModSI); }
370   bool isDMask() const { return isImmTy(ImmTyDMask); }
371   bool isDim() const { return isImmTy(ImmTyDim); }
372   bool isR128A16() const { return isImmTy(ImmTyR128A16); }
373   bool isOff() const { return isImmTy(ImmTyOff); }
374   bool isExpTgt() const { return isImmTy(ImmTyExpTgt); }
375   bool isOffen() const { return isImmTy(ImmTyOffen); }
376   bool isIdxen() const { return isImmTy(ImmTyIdxen); }
377   bool isAddr64() const { return isImmTy(ImmTyAddr64); }
378   bool isOffset() const { return isImmTy(ImmTyOffset); }
379   bool isOffset0() const { return isImmTy(ImmTyOffset0) && isUInt<8>(getImm()); }
380   bool isOffset1() const { return isImmTy(ImmTyOffset1) && isUInt<8>(getImm()); }
381   bool isSMEMOffsetMod() const { return isImmTy(ImmTySMEMOffsetMod); }
382   bool isFlatOffset() const { return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
383   bool isGDS() const { return isImmTy(ImmTyGDS); }
384   bool isLDS() const { return isImmTy(ImmTyLDS); }
385   bool isCPol() const { return isImmTy(ImmTyCPol); }
386   bool isTFE() const { return isImmTy(ImmTyTFE); }
387   bool isFORMAT() const { return isImmTy(ImmTyFORMAT) && isUInt<7>(getImm()); }
388   bool isDppBankMask() const { return isImmTy(ImmTyDppBankMask); }
389   bool isDppRowMask() const { return isImmTy(ImmTyDppRowMask); }
390   bool isDppBoundCtrl() const { return isImmTy(ImmTyDppBoundCtrl); }
391   bool isDppFI() const { return isImmTy(ImmTyDppFI); }
392   bool isSDWADstSel() const { return isImmTy(ImmTySDWADstSel); }
393   bool isSDWASrc0Sel() const { return isImmTy(ImmTySDWASrc0Sel); }
394   bool isSDWASrc1Sel() const { return isImmTy(ImmTySDWASrc1Sel); }
395   bool isSDWADstUnused() const { return isImmTy(ImmTySDWADstUnused); }
396   bool isInterpSlot() const { return isImmTy(ImmTyInterpSlot); }
397   bool isInterpAttr() const { return isImmTy(ImmTyInterpAttr); }
398   bool isInterpAttrChan() const { return isImmTy(ImmTyInterpAttrChan); }
399   bool isOpSel() const { return isImmTy(ImmTyOpSel); }
400   bool isOpSelHi() const { return isImmTy(ImmTyOpSelHi); }
401   bool isNegLo() const { return isImmTy(ImmTyNegLo); }
402   bool isNegHi() const { return isImmTy(ImmTyNegHi); }
403 
404   bool isRegOrImm() const {
405     return isReg() || isImm();
406   }
407 
408   bool isRegClass(unsigned RCID) const;
409 
410   bool isInlineValue() const;
411 
412   bool isRegOrInlineNoMods(unsigned RCID, MVT type) const {
413     return isRegOrInline(RCID, type) && !hasModifiers();
414   }
415 
416   bool isSCSrcB16() const {
417     return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
418   }
419 
420   bool isSCSrcV2B16() const {
421     return isSCSrcB16();
422   }
423 
424   bool isSCSrcB32() const {
425     return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
426   }
427 
428   bool isSCSrcB64() const {
429     return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
430   }
431 
432   bool isBoolReg() const;
433 
434   bool isSCSrcF16() const {
435     return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
436   }
437 
438   bool isSCSrcV2F16() const {
439     return isSCSrcF16();
440   }
441 
442   bool isSCSrcF32() const {
443     return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
444   }
445 
446   bool isSCSrcF64() const {
447     return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
448   }
449 
450   bool isSSrcB32() const {
451     return isSCSrcB32() || isLiteralImm(MVT::i32) || isExpr();
452   }
453 
454   bool isSSrcB16() const {
455     return isSCSrcB16() || isLiteralImm(MVT::i16);
456   }
457 
458   bool isSSrcV2B16() const {
459     llvm_unreachable("cannot happen");
460     return isSSrcB16();
461   }
462 
463   bool isSSrcB64() const {
464     // TODO: Find out how SALU supports extension of 32-bit literals to 64 bits.
465     // See isVSrc64().
466     return isSCSrcB64() || isLiteralImm(MVT::i64);
467   }
468 
469   bool isSSrcF32() const {
470     return isSCSrcB32() || isLiteralImm(MVT::f32) || isExpr();
471   }
472 
473   bool isSSrcF64() const {
474     return isSCSrcB64() || isLiteralImm(MVT::f64);
475   }
476 
477   bool isSSrcF16() const {
478     return isSCSrcB16() || isLiteralImm(MVT::f16);
479   }
480 
481   bool isSSrcV2F16() const {
482     llvm_unreachable("cannot happen");
483     return isSSrcF16();
484   }
485 
486   bool isSSrcV2FP32() const {
487     llvm_unreachable("cannot happen");
488     return isSSrcF32();
489   }
490 
491   bool isSCSrcV2FP32() const {
492     llvm_unreachable("cannot happen");
493     return isSCSrcF32();
494   }
495 
496   bool isSSrcV2INT32() const {
497     llvm_unreachable("cannot happen");
498     return isSSrcB32();
499   }
500 
501   bool isSCSrcV2INT32() const {
502     llvm_unreachable("cannot happen");
503     return isSCSrcB32();
504   }
505 
506   bool isSSrcOrLdsB32() const {
507     return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
508            isLiteralImm(MVT::i32) || isExpr();
509   }
510 
511   bool isVCSrcB32() const {
512     return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
513   }
514 
515   bool isVCSrcB64() const {
516     return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
517   }
518 
519   bool isVCSrcTB16() const {
520     return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
521   }
522 
523   bool isVCSrcTB16_Lo128() const {
524     return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
525   }
526 
527   bool isVCSrcFake16B16_Lo128() const {
528     return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
529   }
530 
531   bool isVCSrcB16() const {
532     return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
533   }
534 
535   bool isVCSrcV2B16() const {
536     return isVCSrcB16();
537   }
538 
539   bool isVCSrcF32() const {
540     return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
541   }
542 
543   bool isVCSrcF64() const {
544     return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
545   }
546 
547   bool isVCSrcTF16() const {
548     return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
549   }
550 
551   bool isVCSrcTF16_Lo128() const {
552     return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
553   }
554 
555   bool isVCSrcFake16F16_Lo128() const {
556     return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
557   }
558 
559   bool isVCSrcF16() const {
560     return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
561   }
562 
563   bool isVCSrcV2F16() const {
564     return isVCSrcF16();
565   }
566 
567   bool isVSrcB32() const {
568     return isVCSrcF32() || isLiteralImm(MVT::i32) || isExpr();
569   }
570 
571   bool isVSrcB64() const {
572     return isVCSrcF64() || isLiteralImm(MVT::i64);
573   }
574 
575   bool isVSrcTB16() const { return isVCSrcTB16() || isLiteralImm(MVT::i16); }
576 
577   bool isVSrcTB16_Lo128() const {
578     return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
579   }
580 
581   bool isVSrcFake16B16_Lo128() const {
582     return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
583   }
584 
585   bool isVSrcB16() const {
586     return isVCSrcB16() || isLiteralImm(MVT::i16);
587   }
588 
589   bool isVSrcV2B16() const {
590     return isVSrcB16() || isLiteralImm(MVT::v2i16);
591   }
592 
593   bool isVCSrcV2FP32() const {
594     return isVCSrcF64();
595   }
596 
597   bool isVSrcV2FP32() const {
598     return isVSrcF64() || isLiteralImm(MVT::v2f32);
599   }
600 
601   bool isVCSrcV2INT32() const {
602     return isVCSrcB64();
603   }
604 
605   bool isVSrcV2INT32() const {
606     return isVSrcB64() || isLiteralImm(MVT::v2i32);
607   }
608 
609   bool isVSrcF32() const {
610     return isVCSrcF32() || isLiteralImm(MVT::f32) || isExpr();
611   }
612 
613   bool isVSrcF64() const {
614     return isVCSrcF64() || isLiteralImm(MVT::f64);
615   }
616 
617   bool isVSrcTF16() const { return isVCSrcTF16() || isLiteralImm(MVT::f16); }
618 
619   bool isVSrcTF16_Lo128() const {
620     return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
621   }
622 
623   bool isVSrcFake16F16_Lo128() const {
624     return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
625   }
626 
627   bool isVSrcF16() const {
628     return isVCSrcF16() || isLiteralImm(MVT::f16);
629   }
630 
631   bool isVSrcV2F16() const {
632     return isVSrcF16() || isLiteralImm(MVT::v2f16);
633   }
634 
635   bool isVISrcB32() const {
636     return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
637   }
638 
639   bool isVISrcB16() const {
640     return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
641   }
642 
643   bool isVISrcV2B16() const {
644     return isVISrcB16();
645   }
646 
647   bool isVISrcF32() const {
648     return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
649   }
650 
651   bool isVISrcF16() const {
652     return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
653   }
654 
655   bool isVISrcV2F16() const {
656     return isVISrcF16() || isVISrcB32();
657   }
658 
659   bool isVISrc_64B64() const {
660     return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
661   }
662 
663   bool isVISrc_64F64() const {
664     return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
665   }
666 
667   bool isVISrc_64V2FP32() const {
668     return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
669   }
670 
671   bool isVISrc_64V2INT32() const {
672     return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
673   }
674 
675   bool isVISrc_256B64() const {
676     return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
677   }
678 
679   bool isVISrc_256F64() const {
680     return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
681   }
682 
683   bool isVISrc_128B16() const {
684     return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
685   }
686 
687   bool isVISrc_128V2B16() const {
688     return isVISrc_128B16();
689   }
690 
691   bool isVISrc_128B32() const {
692     return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
693   }
694 
695   bool isVISrc_128F32() const {
696     return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
697   }
698 
699   bool isVISrc_256V2FP32() const {
700     return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
701   }
702 
703   bool isVISrc_256V2INT32() const {
704     return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
705   }
706 
707   bool isVISrc_512B32() const {
708     return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
709   }
710 
711   bool isVISrc_512B16() const {
712     return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
713   }
714 
715   bool isVISrc_512V2B16() const {
716     return isVISrc_512B16();
717   }
718 
719   bool isVISrc_512F32() const {
720     return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
721   }
722 
723   bool isVISrc_512F16() const {
724     return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
725   }
726 
727   bool isVISrc_512V2F16() const {
728     return isVISrc_512F16() || isVISrc_512B32();
729   }
730 
731   bool isVISrc_1024B32() const {
732     return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
733   }
734 
735   bool isVISrc_1024B16() const {
736     return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
737   }
738 
739   bool isVISrc_1024V2B16() const {
740     return isVISrc_1024B16();
741   }
742 
743   bool isVISrc_1024F32() const {
744     return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
745   }
746 
747   bool isVISrc_1024F16() const {
748     return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
749   }
750 
751   bool isVISrc_1024V2F16() const {
752     return isVISrc_1024F16() || isVISrc_1024B32();
753   }
754 
755   bool isAISrcB32() const {
756     return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
757   }
758 
759   bool isAISrcB16() const {
760     return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
761   }
762 
763   bool isAISrcV2B16() const {
764     return isAISrcB16();
765   }
766 
767   bool isAISrcF32() const {
768     return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
769   }
770 
771   bool isAISrcF16() const {
772     return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
773   }
774 
775   bool isAISrcV2F16() const {
776     return isAISrcF16() || isAISrcB32();
777   }
778 
779   bool isAISrc_64B64() const {
780     return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
781   }
782 
783   bool isAISrc_64F64() const {
784     return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
785   }
786 
787   bool isAISrc_128B32() const {
788     return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
789   }
790 
791   bool isAISrc_128B16() const {
792     return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
793   }
794 
795   bool isAISrc_128V2B16() const {
796     return isAISrc_128B16();
797   }
798 
799   bool isAISrc_128F32() const {
800     return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
801   }
802 
803   bool isAISrc_128F16() const {
804     return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
805   }
806 
807   bool isAISrc_128V2F16() const {
808     return isAISrc_128F16() || isAISrc_128B32();
809   }
810 
811   bool isVISrc_128F16() const {
812     return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
813   }
814 
815   bool isVISrc_128V2F16() const {
816     return isVISrc_128F16() || isVISrc_128B32();
817   }
818 
819   bool isAISrc_256B64() const {
820     return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
821   }
822 
823   bool isAISrc_256F64() const {
824     return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
825   }
826 
827   bool isAISrc_512B32() const {
828     return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
829   }
830 
831   bool isAISrc_512B16() const {
832     return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
833   }
834 
835   bool isAISrc_512V2B16() const {
836     return isAISrc_512B16();
837   }
838 
839   bool isAISrc_512F32() const {
840     return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
841   }
842 
843   bool isAISrc_512F16() const {
844     return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
845   }
846 
847   bool isAISrc_512V2F16() const {
848     return isAISrc_512F16() || isAISrc_512B32();
849   }
850 
851   bool isAISrc_1024B32() const {
852     return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
853   }
854 
855   bool isAISrc_1024B16() const {
856     return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
857   }
858 
859   bool isAISrc_1024V2B16() const {
860     return isAISrc_1024B16();
861   }
862 
863   bool isAISrc_1024F32() const {
864     return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
865   }
866 
867   bool isAISrc_1024F16() const {
868     return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
869   }
870 
871   bool isAISrc_1024V2F16() const {
872     return isAISrc_1024F16() || isAISrc_1024B32();
873   }
874 
875   bool isKImmFP32() const {
876     return isLiteralImm(MVT::f32);
877   }
878 
879   bool isKImmFP16() const {
880     return isLiteralImm(MVT::f16);
881   }
882 
883   bool isMem() const override {
884     return false;
885   }
886 
887   bool isExpr() const {
888     return Kind == Expression;
889   }
890 
891   bool isSOPPBrTarget() const { return isExpr() || isImm(); }
892 
893   bool isSWaitCnt() const;
894   bool isDepCtr() const;
895   bool isSDelayALU() const;
896   bool isHwreg() const;
897   bool isSendMsg() const;
898   bool isSplitBarrier() const;
899   bool isSwizzle() const;
900   bool isSMRDOffset8() const;
901   bool isSMEMOffset() const;
902   bool isSMRDLiteralOffset() const;
903   bool isDPP8() const;
904   bool isDPPCtrl() const;
905   bool isBLGP() const;
906   bool isCBSZ() const;
907   bool isABID() const;
908   bool isGPRIdxMode() const;
909   bool isS16Imm() const;
910   bool isU16Imm() const;
911   bool isEndpgm() const;
912   bool isWaitVDST() const;
913   bool isWaitEXP() const;
914   bool isWaitVAVDst() const;
915   bool isWaitVMVSrc() const;
916 
917   auto getPredicate(std::function<bool(const AMDGPUOperand &Op)> P) const {
918     return std::bind(P, *this);
919   }
920 
921   StringRef getToken() const {
922     assert(isToken());
923     return StringRef(Tok.Data, Tok.Length);
924   }
925 
926   int64_t getImm() const {
927     assert(isImm());
928     return Imm.Val;
929   }
930 
931   void setImm(int64_t Val) {
932     assert(isImm());
933     Imm.Val = Val;
934   }
935 
936   ImmTy getImmTy() const {
937     assert(isImm());
938     return Imm.Type;
939   }
940 
941   unsigned getReg() const override {
942     assert(isRegKind());
943     return Reg.RegNo;
944   }
945 
946   SMLoc getStartLoc() const override {
947     return StartLoc;
948   }
949 
950   SMLoc getEndLoc() const override {
951     return EndLoc;
952   }
953 
954   SMRange getLocRange() const {
955     return SMRange(StartLoc, EndLoc);
956   }
957 
958   Modifiers getModifiers() const {
959     assert(isRegKind() || isImmTy(ImmTyNone));
960     return isRegKind() ? Reg.Mods : Imm.Mods;
961   }
962 
963   void setModifiers(Modifiers Mods) {
964     assert(isRegKind() || isImmTy(ImmTyNone));
965     if (isRegKind())
966       Reg.Mods = Mods;
967     else
968       Imm.Mods = Mods;
969   }
970 
971   bool hasModifiers() const {
972     return getModifiers().hasModifiers();
973   }
974 
975   bool hasFPModifiers() const {
976     return getModifiers().hasFPModifiers();
977   }
978 
979   bool hasIntModifiers() const {
980     return getModifiers().hasIntModifiers();
981   }
982 
983   uint64_t applyInputFPModifiers(uint64_t Val, unsigned Size) const;
984 
985   void addImmOperands(MCInst &Inst, unsigned N, bool ApplyModifiers = true) const;
986 
987   void addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyModifiers) const;
988 
989   void addRegOperands(MCInst &Inst, unsigned N) const;
990 
991   void addRegOrImmOperands(MCInst &Inst, unsigned N) const {
992     if (isRegKind())
993       addRegOperands(Inst, N);
994     else
995       addImmOperands(Inst, N);
996   }
997 
998   void addRegOrImmWithInputModsOperands(MCInst &Inst, unsigned N) const {
999     Modifiers Mods = getModifiers();
1000     Inst.addOperand(MCOperand::createImm(Mods.getModifiersOperand()));
1001     if (isRegKind()) {
1002       addRegOperands(Inst, N);
1003     } else {
1004       addImmOperands(Inst, N, false);
1005     }
1006   }
1007 
1008   void addRegOrImmWithFPInputModsOperands(MCInst &Inst, unsigned N) const {
1009     assert(!hasIntModifiers());
1010     addRegOrImmWithInputModsOperands(Inst, N);
1011   }
1012 
1013   void addRegOrImmWithIntInputModsOperands(MCInst &Inst, unsigned N) const {
1014     assert(!hasFPModifiers());
1015     addRegOrImmWithInputModsOperands(Inst, N);
1016   }
1017 
1018   void addRegWithInputModsOperands(MCInst &Inst, unsigned N) const {
1019     Modifiers Mods = getModifiers();
1020     Inst.addOperand(MCOperand::createImm(Mods.getModifiersOperand()));
1021     assert(isRegKind());
1022     addRegOperands(Inst, N);
1023   }
1024 
1025   void addRegWithFPInputModsOperands(MCInst &Inst, unsigned N) const {
1026     assert(!hasIntModifiers());
1027     addRegWithInputModsOperands(Inst, N);
1028   }
1029 
1030   void addRegWithIntInputModsOperands(MCInst &Inst, unsigned N) const {
1031     assert(!hasFPModifiers());
1032     addRegWithInputModsOperands(Inst, N);
1033   }
1034 
1035   static void printImmTy(raw_ostream& OS, ImmTy Type) {
1036     // clang-format off
1037     switch (Type) {
1038     case ImmTyNone: OS << "None"; break;
1039     case ImmTyGDS: OS << "GDS"; break;
1040     case ImmTyLDS: OS << "LDS"; break;
1041     case ImmTyOffen: OS << "Offen"; break;
1042     case ImmTyIdxen: OS << "Idxen"; break;
1043     case ImmTyAddr64: OS << "Addr64"; break;
1044     case ImmTyOffset: OS << "Offset"; break;
1045     case ImmTyInstOffset: OS << "InstOffset"; break;
1046     case ImmTyOffset0: OS << "Offset0"; break;
1047     case ImmTyOffset1: OS << "Offset1"; break;
1048     case ImmTySMEMOffsetMod: OS << "SMEMOffsetMod"; break;
1049     case ImmTyCPol: OS << "CPol"; break;
1050     case ImmTyTFE: OS << "TFE"; break;
1051     case ImmTyD16: OS << "D16"; break;
1052     case ImmTyFORMAT: OS << "FORMAT"; break;
1053     case ImmTyClampSI: OS << "ClampSI"; break;
1054     case ImmTyOModSI: OS << "OModSI"; break;
1055     case ImmTyDPP8: OS << "DPP8"; break;
1056     case ImmTyDppCtrl: OS << "DppCtrl"; break;
1057     case ImmTyDppRowMask: OS << "DppRowMask"; break;
1058     case ImmTyDppBankMask: OS << "DppBankMask"; break;
1059     case ImmTyDppBoundCtrl: OS << "DppBoundCtrl"; break;
1060     case ImmTyDppFI: OS << "DppFI"; break;
1061     case ImmTySDWADstSel: OS << "SDWADstSel"; break;
1062     case ImmTySDWASrc0Sel: OS << "SDWASrc0Sel"; break;
1063     case ImmTySDWASrc1Sel: OS << "SDWASrc1Sel"; break;
1064     case ImmTySDWADstUnused: OS << "SDWADstUnused"; break;
1065     case ImmTyDMask: OS << "DMask"; break;
1066     case ImmTyDim: OS << "Dim"; break;
1067     case ImmTyUNorm: OS << "UNorm"; break;
1068     case ImmTyDA: OS << "DA"; break;
1069     case ImmTyR128A16: OS << "R128A16"; break;
1070     case ImmTyA16: OS << "A16"; break;
1071     case ImmTyLWE: OS << "LWE"; break;
1072     case ImmTyOff: OS << "Off"; break;
1073     case ImmTyExpTgt: OS << "ExpTgt"; break;
1074     case ImmTyExpCompr: OS << "ExpCompr"; break;
1075     case ImmTyExpVM: OS << "ExpVM"; break;
1076     case ImmTyHwreg: OS << "Hwreg"; break;
1077     case ImmTySendMsg: OS << "SendMsg"; break;
1078     case ImmTyInterpSlot: OS << "InterpSlot"; break;
1079     case ImmTyInterpAttr: OS << "InterpAttr"; break;
1080     case ImmTyInterpAttrChan: OS << "InterpAttrChan"; break;
1081     case ImmTyOpSel: OS << "OpSel"; break;
1082     case ImmTyOpSelHi: OS << "OpSelHi"; break;
1083     case ImmTyNegLo: OS << "NegLo"; break;
1084     case ImmTyNegHi: OS << "NegHi"; break;
1085     case ImmTySwizzle: OS << "Swizzle"; break;
1086     case ImmTyGprIdxMode: OS << "GprIdxMode"; break;
1087     case ImmTyHigh: OS << "High"; break;
1088     case ImmTyBLGP: OS << "BLGP"; break;
1089     case ImmTyCBSZ: OS << "CBSZ"; break;
1090     case ImmTyABID: OS << "ABID"; break;
1091     case ImmTyEndpgm: OS << "Endpgm"; break;
1092     case ImmTyWaitVDST: OS << "WaitVDST"; break;
1093     case ImmTyWaitEXP: OS << "WaitEXP"; break;
1094     case ImmTyWaitVAVDst: OS << "WaitVAVDst"; break;
1095     case ImmTyWaitVMVSrc: OS << "WaitVMVSrc"; break;
1096     }
1097     // clang-format on
1098   }
1099 
1100   void print(raw_ostream &OS) const override {
1101     switch (Kind) {
1102     case Register:
1103       OS << "<register " << getReg() << " mods: " << Reg.Mods << '>';
1104       break;
1105     case Immediate:
1106       OS << '<' << getImm();
1107       if (getImmTy() != ImmTyNone) {
1108         OS << " type: "; printImmTy(OS, getImmTy());
1109       }
1110       OS << " mods: " << Imm.Mods << '>';
1111       break;
1112     case Token:
1113       OS << '\'' << getToken() << '\'';
1114       break;
1115     case Expression:
1116       OS << "<expr " << *Expr << '>';
1117       break;
1118     }
1119   }
1120 
1121   static AMDGPUOperand::Ptr CreateImm(const AMDGPUAsmParser *AsmParser,
1122                                       int64_t Val, SMLoc Loc,
1123                                       ImmTy Type = ImmTyNone,
1124                                       bool IsFPImm = false) {
1125     auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1126     Op->Imm.Val = Val;
1127     Op->Imm.IsFPImm = IsFPImm;
1128     Op->Imm.Kind = ImmKindTyNone;
1129     Op->Imm.Type = Type;
1130     Op->Imm.Mods = Modifiers();
1131     Op->StartLoc = Loc;
1132     Op->EndLoc = Loc;
1133     return Op;
1134   }
1135 
1136   static AMDGPUOperand::Ptr CreateToken(const AMDGPUAsmParser *AsmParser,
1137                                         StringRef Str, SMLoc Loc,
1138                                         bool HasExplicitEncodingSize = true) {
1139     auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1140     Res->Tok.Data = Str.data();
1141     Res->Tok.Length = Str.size();
1142     Res->StartLoc = Loc;
1143     Res->EndLoc = Loc;
1144     return Res;
1145   }
1146 
1147   static AMDGPUOperand::Ptr CreateReg(const AMDGPUAsmParser *AsmParser,
1148                                       unsigned RegNo, SMLoc S,
1149                                       SMLoc E) {
1150     auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1151     Op->Reg.RegNo = RegNo;
1152     Op->Reg.Mods = Modifiers();
1153     Op->StartLoc = S;
1154     Op->EndLoc = E;
1155     return Op;
1156   }
1157 
1158   static AMDGPUOperand::Ptr CreateExpr(const AMDGPUAsmParser *AsmParser,
1159                                        const class MCExpr *Expr, SMLoc S) {
1160     auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1161     Op->Expr = Expr;
1162     Op->StartLoc = S;
1163     Op->EndLoc = S;
1164     return Op;
1165   }
1166 };
1167 
1168 raw_ostream &operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods) {
1169   OS << "abs:" << Mods.Abs << " neg: " << Mods.Neg << " sext:" << Mods.Sext;
1170   return OS;
1171 }
1172 
1173 //===----------------------------------------------------------------------===//
1174 // AsmParser
1175 //===----------------------------------------------------------------------===//
1176 
1177 // Holds info related to the current kernel, e.g. count of SGPRs used.
1178 // Kernel scope begins at .amdgpu_hsa_kernel directive, ends at next
1179 // .amdgpu_hsa_kernel or at EOF.
1180 class KernelScopeInfo {
1181   int SgprIndexUnusedMin = -1;
1182   int VgprIndexUnusedMin = -1;
1183   int AgprIndexUnusedMin = -1;
1184   MCContext *Ctx = nullptr;
1185   MCSubtargetInfo const *MSTI = nullptr;
1186 
1187   void usesSgprAt(int i) {
1188     if (i >= SgprIndexUnusedMin) {
1189       SgprIndexUnusedMin = ++i;
1190       if (Ctx) {
1191         MCSymbol* const Sym =
1192           Ctx->getOrCreateSymbol(Twine(".kernel.sgpr_count"));
1193         Sym->setVariableValue(MCConstantExpr::create(SgprIndexUnusedMin, *Ctx));
1194       }
1195     }
1196   }
1197 
1198   void usesVgprAt(int i) {
1199     if (i >= VgprIndexUnusedMin) {
1200       VgprIndexUnusedMin = ++i;
1201       if (Ctx) {
1202         MCSymbol* const Sym =
1203           Ctx->getOrCreateSymbol(Twine(".kernel.vgpr_count"));
1204         int totalVGPR = getTotalNumVGPRs(isGFX90A(*MSTI), AgprIndexUnusedMin,
1205                                          VgprIndexUnusedMin);
1206         Sym->setVariableValue(MCConstantExpr::create(totalVGPR, *Ctx));
1207       }
1208     }
1209   }
1210 
1211   void usesAgprAt(int i) {
1212     // Instruction will error in AMDGPUAsmParser::MatchAndEmitInstruction
1213     if (!hasMAIInsts(*MSTI))
1214       return;
1215 
1216     if (i >= AgprIndexUnusedMin) {
1217       AgprIndexUnusedMin = ++i;
1218       if (Ctx) {
1219         MCSymbol* const Sym =
1220           Ctx->getOrCreateSymbol(Twine(".kernel.agpr_count"));
1221         Sym->setVariableValue(MCConstantExpr::create(AgprIndexUnusedMin, *Ctx));
1222 
1223         // Also update vgpr_count (dependent on agpr_count for gfx908/gfx90a)
1224         MCSymbol* const vSym =
1225           Ctx->getOrCreateSymbol(Twine(".kernel.vgpr_count"));
1226         int totalVGPR = getTotalNumVGPRs(isGFX90A(*MSTI), AgprIndexUnusedMin,
1227                                          VgprIndexUnusedMin);
1228         vSym->setVariableValue(MCConstantExpr::create(totalVGPR, *Ctx));
1229       }
1230     }
1231   }
1232 
1233 public:
1234   KernelScopeInfo() = default;
1235 
1236   void initialize(MCContext &Context) {
1237     Ctx = &Context;
1238     MSTI = Ctx->getSubtargetInfo();
1239 
1240     usesSgprAt(SgprIndexUnusedMin = -1);
1241     usesVgprAt(VgprIndexUnusedMin = -1);
1242     if (hasMAIInsts(*MSTI)) {
1243       usesAgprAt(AgprIndexUnusedMin = -1);
1244     }
1245   }
1246 
1247   void usesRegister(RegisterKind RegKind, unsigned DwordRegIndex,
1248                     unsigned RegWidth) {
1249     switch (RegKind) {
1250     case IS_SGPR:
1251       usesSgprAt(DwordRegIndex + divideCeil(RegWidth, 32) - 1);
1252       break;
1253     case IS_AGPR:
1254       usesAgprAt(DwordRegIndex + divideCeil(RegWidth, 32) - 1);
1255       break;
1256     case IS_VGPR:
1257       usesVgprAt(DwordRegIndex + divideCeil(RegWidth, 32) - 1);
1258       break;
1259     default:
1260       break;
1261     }
1262   }
1263 };
1264 
1265 class AMDGPUAsmParser : public MCTargetAsmParser {
1266   MCAsmParser &Parser;
1267 
1268   unsigned ForcedEncodingSize = 0;
1269   bool ForcedDPP = false;
1270   bool ForcedSDWA = false;
1271   KernelScopeInfo KernelScope;
1272 
1273   /// @name Auto-generated Match Functions
1274   /// {
1275 
1276 #define GET_ASSEMBLER_HEADER
1277 #include "AMDGPUGenAsmMatcher.inc"
1278 
1279   /// }
1280 
1281 private:
1282   bool ParseAsAbsoluteExpression(uint32_t &Ret);
1283   bool OutOfRangeError(SMRange Range);
1284   /// Calculate VGPR/SGPR blocks required for given target, reserved
1285   /// registers, and user-specified NextFreeXGPR values.
1286   ///
1287   /// \param Features [in] Target features, used for bug corrections.
1288   /// \param VCCUsed [in] Whether VCC special SGPR is reserved.
1289   /// \param FlatScrUsed [in] Whether FLAT_SCRATCH special SGPR is reserved.
1290   /// \param XNACKUsed [in] Whether XNACK_MASK special SGPR is reserved.
1291   /// \param EnableWavefrontSize32 [in] Value of ENABLE_WAVEFRONT_SIZE32 kernel
1292   /// descriptor field, if valid.
1293   /// \param NextFreeVGPR [in] Max VGPR number referenced, plus one.
1294   /// \param VGPRRange [in] Token range, used for VGPR diagnostics.
1295   /// \param NextFreeSGPR [in] Max SGPR number referenced, plus one.
1296   /// \param SGPRRange [in] Token range, used for SGPR diagnostics.
1297   /// \param VGPRBlocks [out] Result VGPR block count.
1298   /// \param SGPRBlocks [out] Result SGPR block count.
1299   bool calculateGPRBlocks(const FeatureBitset &Features, bool VCCUsed,
1300                           bool FlatScrUsed, bool XNACKUsed,
1301                           std::optional<bool> EnableWavefrontSize32,
1302                           unsigned NextFreeVGPR, SMRange VGPRRange,
1303                           unsigned NextFreeSGPR, SMRange SGPRRange,
1304                           unsigned &VGPRBlocks, unsigned &SGPRBlocks);
1305   bool ParseDirectiveAMDGCNTarget();
1306   bool ParseDirectiveAMDHSACodeObjectVersion();
1307   bool ParseDirectiveAMDHSAKernel();
1308   bool ParseAMDKernelCodeTValue(StringRef ID, amd_kernel_code_t &Header);
1309   bool ParseDirectiveAMDKernelCodeT();
1310   // TODO: Possibly make subtargetHasRegister const.
1311   bool subtargetHasRegister(const MCRegisterInfo &MRI, unsigned RegNo);
1312   bool ParseDirectiveAMDGPUHsaKernel();
1313 
1314   bool ParseDirectiveISAVersion();
1315   bool ParseDirectiveHSAMetadata();
1316   bool ParseDirectivePALMetadataBegin();
1317   bool ParseDirectivePALMetadata();
1318   bool ParseDirectiveAMDGPULDS();
1319 
1320   /// Common code to parse out a block of text (typically YAML) between start and
1321   /// end directives.
1322   bool ParseToEndDirective(const char *AssemblerDirectiveBegin,
1323                            const char *AssemblerDirectiveEnd,
1324                            std::string &CollectString);
1325 
1326   bool AddNextRegisterToList(unsigned& Reg, unsigned& RegWidth,
1327                              RegisterKind RegKind, unsigned Reg1, SMLoc Loc);
1328   bool ParseAMDGPURegister(RegisterKind &RegKind, unsigned &Reg,
1329                            unsigned &RegNum, unsigned &RegWidth,
1330                            bool RestoreOnFailure = false);
1331   bool ParseAMDGPURegister(RegisterKind &RegKind, unsigned &Reg,
1332                            unsigned &RegNum, unsigned &RegWidth,
1333                            SmallVectorImpl<AsmToken> &Tokens);
1334   unsigned ParseRegularReg(RegisterKind &RegKind, unsigned &RegNum,
1335                            unsigned &RegWidth,
1336                            SmallVectorImpl<AsmToken> &Tokens);
1337   unsigned ParseSpecialReg(RegisterKind &RegKind, unsigned &RegNum,
1338                            unsigned &RegWidth,
1339                            SmallVectorImpl<AsmToken> &Tokens);
1340   unsigned ParseRegList(RegisterKind &RegKind, unsigned &RegNum,
1341                         unsigned &RegWidth, SmallVectorImpl<AsmToken> &Tokens);
1342   bool ParseRegRange(unsigned& Num, unsigned& Width);
1343   unsigned getRegularReg(RegisterKind RegKind, unsigned RegNum, unsigned SubReg,
1344                          unsigned RegWidth, SMLoc Loc);
1345 
1346   bool isRegister();
1347   bool isRegister(const AsmToken &Token, const AsmToken &NextToken) const;
1348   std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1349   void initializeGprCountSymbol(RegisterKind RegKind);
1350   bool updateGprCountSymbols(RegisterKind RegKind, unsigned DwordRegIndex,
1351                              unsigned RegWidth);
1352   void cvtMubufImpl(MCInst &Inst, const OperandVector &Operands,
1353                     bool IsAtomic);
1354 
1355 public:
1356   enum AMDGPUMatchResultTy {
1357     Match_PreferE32 = FIRST_TARGET_MATCH_RESULT_TY
1358   };
1359   enum OperandMode {
1360     OperandMode_Default,
1361     OperandMode_NSA,
1362   };
1363 
1364   using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1365 
1366   AMDGPUAsmParser(const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1367                const MCInstrInfo &MII,
1368                const MCTargetOptions &Options)
1369       : MCTargetAsmParser(Options, STI, MII), Parser(_Parser) {
1370     MCAsmParserExtension::Initialize(Parser);
1371 
1372     if (getFeatureBits().none()) {
1373       // Set default features.
1374       copySTI().ToggleFeature("southern-islands");
1375     }
1376 
1377     setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1378 
1379     {
1380       // TODO: make those pre-defined variables read-only.
1381       // Currently there is none suitable machinery in the core llvm-mc for this.
1382       // MCSymbol::isRedefinable is intended for another purpose, and
1383       // AsmParser::parseDirectiveSet() cannot be specialized for specific target.
1384       AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(getSTI().getCPU());
1385       MCContext &Ctx = getContext();
1386       if (ISA.Major >= 6 && isHsaAbi(getSTI())) {
1387         MCSymbol *Sym =
1388             Ctx.getOrCreateSymbol(Twine(".amdgcn.gfx_generation_number"));
1389         Sym->setVariableValue(MCConstantExpr::create(ISA.Major, Ctx));
1390         Sym = Ctx.getOrCreateSymbol(Twine(".amdgcn.gfx_generation_minor"));
1391         Sym->setVariableValue(MCConstantExpr::create(ISA.Minor, Ctx));
1392         Sym = Ctx.getOrCreateSymbol(Twine(".amdgcn.gfx_generation_stepping"));
1393         Sym->setVariableValue(MCConstantExpr::create(ISA.Stepping, Ctx));
1394       } else {
1395         MCSymbol *Sym =
1396             Ctx.getOrCreateSymbol(Twine(".option.machine_version_major"));
1397         Sym->setVariableValue(MCConstantExpr::create(ISA.Major, Ctx));
1398         Sym = Ctx.getOrCreateSymbol(Twine(".option.machine_version_minor"));
1399         Sym->setVariableValue(MCConstantExpr::create(ISA.Minor, Ctx));
1400         Sym = Ctx.getOrCreateSymbol(Twine(".option.machine_version_stepping"));
1401         Sym->setVariableValue(MCConstantExpr::create(ISA.Stepping, Ctx));
1402       }
1403       if (ISA.Major >= 6 && isHsaAbi(getSTI())) {
1404         initializeGprCountSymbol(IS_VGPR);
1405         initializeGprCountSymbol(IS_SGPR);
1406       } else
1407         KernelScope.initialize(getContext());
1408     }
1409   }
1410 
1411   bool hasMIMG_R128() const {
1412     return AMDGPU::hasMIMG_R128(getSTI());
1413   }
1414 
1415   bool hasPackedD16() const {
1416     return AMDGPU::hasPackedD16(getSTI());
1417   }
1418 
1419   bool hasA16() const { return AMDGPU::hasA16(getSTI()); }
1420 
1421   bool hasG16() const { return AMDGPU::hasG16(getSTI()); }
1422 
1423   bool hasGDS() const { return AMDGPU::hasGDS(getSTI()); }
1424 
1425   bool isSI() const {
1426     return AMDGPU::isSI(getSTI());
1427   }
1428 
1429   bool isCI() const {
1430     return AMDGPU::isCI(getSTI());
1431   }
1432 
1433   bool isVI() const {
1434     return AMDGPU::isVI(getSTI());
1435   }
1436 
1437   bool isGFX9() const {
1438     return AMDGPU::isGFX9(getSTI());
1439   }
1440 
1441   // TODO: isGFX90A is also true for GFX940. We need to clean it.
1442   bool isGFX90A() const {
1443     return AMDGPU::isGFX90A(getSTI());
1444   }
1445 
1446   bool isGFX940() const {
1447     return AMDGPU::isGFX940(getSTI());
1448   }
1449 
1450   bool isGFX9Plus() const {
1451     return AMDGPU::isGFX9Plus(getSTI());
1452   }
1453 
1454   bool isGFX10() const {
1455     return AMDGPU::isGFX10(getSTI());
1456   }
1457 
1458   bool isGFX10Plus() const { return AMDGPU::isGFX10Plus(getSTI()); }
1459 
1460   bool isGFX11() const {
1461     return AMDGPU::isGFX11(getSTI());
1462   }
1463 
1464   bool isGFX11Plus() const {
1465     return AMDGPU::isGFX11Plus(getSTI());
1466   }
1467 
1468   bool isGFX12() const { return AMDGPU::isGFX12(getSTI()); }
1469 
1470   bool isGFX12Plus() const { return AMDGPU::isGFX12Plus(getSTI()); }
1471 
1472   bool isGFX10_AEncoding() const { return AMDGPU::isGFX10_AEncoding(getSTI()); }
1473 
1474   bool isGFX10_BEncoding() const {
1475     return AMDGPU::isGFX10_BEncoding(getSTI());
1476   }
1477 
1478   bool hasInv2PiInlineImm() const {
1479     return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1480   }
1481 
1482   bool hasFlatOffsets() const {
1483     return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1484   }
1485 
1486   bool hasArchitectedFlatScratch() const {
1487     return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1488   }
1489 
1490   bool hasSGPR102_SGPR103() const {
1491     return !isVI() && !isGFX9();
1492   }
1493 
1494   bool hasSGPR104_SGPR105() const { return isGFX10Plus(); }
1495 
1496   bool hasIntClamp() const {
1497     return getFeatureBits()[AMDGPU::FeatureIntClamp];
1498   }
1499 
1500   bool hasPartialNSAEncoding() const {
1501     return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1502   }
1503 
1504   unsigned getNSAMaxSize(bool HasSampler = false) const {
1505     return AMDGPU::getNSAMaxSize(getSTI(), HasSampler);
1506   }
1507 
1508   unsigned getMaxNumUserSGPRs() const {
1509     return AMDGPU::getMaxNumUserSGPRs(getSTI());
1510   }
1511 
1512   bool hasKernargPreload() const { return AMDGPU::hasKernargPreload(getSTI()); }
1513 
1514   AMDGPUTargetStreamer &getTargetStreamer() {
1515     MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1516     return static_cast<AMDGPUTargetStreamer &>(TS);
1517   }
1518 
1519   const MCRegisterInfo *getMRI() const {
1520     // We need this const_cast because for some reason getContext() is not const
1521     // in MCAsmParser.
1522     return const_cast<AMDGPUAsmParser*>(this)->getContext().getRegisterInfo();
1523   }
1524 
1525   const MCInstrInfo *getMII() const {
1526     return &MII;
1527   }
1528 
1529   const FeatureBitset &getFeatureBits() const {
1530     return getSTI().getFeatureBits();
1531   }
1532 
1533   void setForcedEncodingSize(unsigned Size) { ForcedEncodingSize = Size; }
1534   void setForcedDPP(bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1535   void setForcedSDWA(bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1536 
1537   unsigned getForcedEncodingSize() const { return ForcedEncodingSize; }
1538   bool isForcedVOP3() const { return ForcedEncodingSize == 64; }
1539   bool isForcedDPP() const { return ForcedDPP; }
1540   bool isForcedSDWA() const { return ForcedSDWA; }
1541   ArrayRef<unsigned> getMatchedVariants() const;
1542   StringRef getMatchedVariantName() const;
1543 
1544   std::unique_ptr<AMDGPUOperand> parseRegister(bool RestoreOnFailure = false);
1545   bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1546                      bool RestoreOnFailure);
1547   bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
1548   ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
1549                                SMLoc &EndLoc) override;
1550   unsigned checkTargetMatchPredicate(MCInst &Inst) override;
1551   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
1552                                       unsigned Kind) override;
1553   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1554                                OperandVector &Operands, MCStreamer &Out,
1555                                uint64_t &ErrorInfo,
1556                                bool MatchingInlineAsm) override;
1557   bool ParseDirective(AsmToken DirectiveID) override;
1558   ParseStatus parseOperand(OperandVector &Operands, StringRef Mnemonic,
1559                            OperandMode Mode = OperandMode_Default);
1560   StringRef parseMnemonicSuffix(StringRef Name);
1561   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1562                         SMLoc NameLoc, OperandVector &Operands) override;
1563   //bool ProcessInstruction(MCInst &Inst);
1564 
1565   ParseStatus parseTokenOp(StringRef Name, OperandVector &Operands);
1566 
1567   ParseStatus parseIntWithPrefix(const char *Prefix, int64_t &Int);
1568 
1569   ParseStatus
1570   parseIntWithPrefix(const char *Prefix, OperandVector &Operands,
1571                      AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1572                      std::function<bool(int64_t &)> ConvertResult = nullptr);
1573 
1574   ParseStatus parseOperandArrayWithPrefix(
1575       const char *Prefix, OperandVector &Operands,
1576       AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1577       bool (*ConvertResult)(int64_t &) = nullptr);
1578 
1579   ParseStatus
1580   parseNamedBit(StringRef Name, OperandVector &Operands,
1581                 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1582   unsigned getCPolKind(StringRef Id, StringRef Mnemo, bool &Disabling) const;
1583   ParseStatus parseCPol(OperandVector &Operands);
1584   ParseStatus parseScope(OperandVector &Operands, int64_t &Scope);
1585   ParseStatus parseTH(OperandVector &Operands, int64_t &TH);
1586   ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &Value,
1587                                     SMLoc &StringLoc);
1588 
1589   bool isModifier();
1590   bool isOperandModifier(const AsmToken &Token, const AsmToken &NextToken) const;
1591   bool isRegOrOperandModifier(const AsmToken &Token, const AsmToken &NextToken) const;
1592   bool isNamedOperandModifier(const AsmToken &Token, const AsmToken &NextToken) const;
1593   bool isOpcodeModifierWithVal(const AsmToken &Token, const AsmToken &NextToken) const;
1594   bool parseSP3NegModifier();
1595   ParseStatus parseImm(OperandVector &Operands, bool HasSP3AbsModifier = false,
1596                        bool HasLit = false);
1597   ParseStatus parseReg(OperandVector &Operands);
1598   ParseStatus parseRegOrImm(OperandVector &Operands, bool HasSP3AbsMod = false,
1599                             bool HasLit = false);
1600   ParseStatus parseRegOrImmWithFPInputMods(OperandVector &Operands,
1601                                            bool AllowImm = true);
1602   ParseStatus parseRegOrImmWithIntInputMods(OperandVector &Operands,
1603                                             bool AllowImm = true);
1604   ParseStatus parseRegWithFPInputMods(OperandVector &Operands);
1605   ParseStatus parseRegWithIntInputMods(OperandVector &Operands);
1606   ParseStatus parseVReg32OrOff(OperandVector &Operands);
1607   ParseStatus parseDfmtNfmt(int64_t &Format);
1608   ParseStatus parseUfmt(int64_t &Format);
1609   ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1610                                        int64_t &Format);
1611   ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1612                                          int64_t &Format);
1613   ParseStatus parseFORMAT(OperandVector &Operands);
1614   ParseStatus parseSymbolicOrNumericFormat(int64_t &Format);
1615   ParseStatus parseNumericFormat(int64_t &Format);
1616   ParseStatus parseFlatOffset(OperandVector &Operands);
1617   ParseStatus parseR128A16(OperandVector &Operands);
1618   ParseStatus parseBLGP(OperandVector &Operands);
1619   bool tryParseFmt(const char *Pref, int64_t MaxVal, int64_t &Val);
1620   bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1621 
1622   void cvtExp(MCInst &Inst, const OperandVector &Operands);
1623 
1624   bool parseCnt(int64_t &IntVal);
1625   ParseStatus parseSWaitCnt(OperandVector &Operands);
1626 
1627   bool parseDepCtr(int64_t &IntVal, unsigned &Mask);
1628   void depCtrError(SMLoc Loc, int ErrorId, StringRef DepCtrName);
1629   ParseStatus parseDepCtr(OperandVector &Operands);
1630 
1631   bool parseDelay(int64_t &Delay);
1632   ParseStatus parseSDelayALU(OperandVector &Operands);
1633 
1634   ParseStatus parseHwreg(OperandVector &Operands);
1635 
1636 private:
1637   struct OperandInfoTy {
1638     SMLoc Loc;
1639     int64_t Id;
1640     bool IsSymbolic = false;
1641     bool IsDefined = false;
1642 
1643     OperandInfoTy(int64_t Id_) : Id(Id_) {}
1644   };
1645 
1646   bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &Op, OperandInfoTy &Stream);
1647   bool validateSendMsg(const OperandInfoTy &Msg,
1648                        const OperandInfoTy &Op,
1649                        const OperandInfoTy &Stream);
1650 
1651   bool parseHwregBody(OperandInfoTy &HwReg,
1652                       OperandInfoTy &Offset,
1653                       OperandInfoTy &Width);
1654   bool validateHwreg(const OperandInfoTy &HwReg,
1655                      const OperandInfoTy &Offset,
1656                      const OperandInfoTy &Width);
1657 
1658   SMLoc getFlatOffsetLoc(const OperandVector &Operands) const;
1659   SMLoc getSMEMOffsetLoc(const OperandVector &Operands) const;
1660   SMLoc getBLGPLoc(const OperandVector &Operands) const;
1661 
1662   SMLoc getOperandLoc(std::function<bool(const AMDGPUOperand&)> Test,
1663                       const OperandVector &Operands) const;
1664   SMLoc getImmLoc(AMDGPUOperand::ImmTy Type, const OperandVector &Operands) const;
1665   SMLoc getRegLoc(unsigned Reg, const OperandVector &Operands) const;
1666   SMLoc getLitLoc(const OperandVector &Operands,
1667                   bool SearchMandatoryLiterals = false) const;
1668   SMLoc getMandatoryLitLoc(const OperandVector &Operands) const;
1669   SMLoc getConstLoc(const OperandVector &Operands) const;
1670   SMLoc getInstLoc(const OperandVector &Operands) const;
1671 
1672   bool validateInstruction(const MCInst &Inst, const SMLoc &IDLoc, const OperandVector &Operands);
1673   bool validateOffset(const MCInst &Inst, const OperandVector &Operands);
1674   bool validateFlatOffset(const MCInst &Inst, const OperandVector &Operands);
1675   bool validateSMEMOffset(const MCInst &Inst, const OperandVector &Operands);
1676   bool validateSOPLiteral(const MCInst &Inst) const;
1677   bool validateConstantBusLimitations(const MCInst &Inst, const OperandVector &Operands);
1678   bool validateVOPDRegBankConstraints(const MCInst &Inst,
1679                                       const OperandVector &Operands);
1680   bool validateIntClampSupported(const MCInst &Inst);
1681   bool validateMIMGAtomicDMask(const MCInst &Inst);
1682   bool validateMIMGGatherDMask(const MCInst &Inst);
1683   bool validateMovrels(const MCInst &Inst, const OperandVector &Operands);
1684   bool validateMIMGDataSize(const MCInst &Inst, const SMLoc &IDLoc);
1685   bool validateMIMGAddrSize(const MCInst &Inst, const SMLoc &IDLoc);
1686   bool validateMIMGD16(const MCInst &Inst);
1687   bool validateMIMGMSAA(const MCInst &Inst);
1688   bool validateOpSel(const MCInst &Inst);
1689   bool validateNeg(const MCInst &Inst, int OpName);
1690   bool validateDPP(const MCInst &Inst, const OperandVector &Operands);
1691   bool validateVccOperand(unsigned Reg) const;
1692   bool validateVOPLiteral(const MCInst &Inst, const OperandVector &Operands);
1693   bool validateMAIAccWrite(const MCInst &Inst, const OperandVector &Operands);
1694   bool validateMAISrc2(const MCInst &Inst, const OperandVector &Operands);
1695   bool validateMFMA(const MCInst &Inst, const OperandVector &Operands);
1696   bool validateAGPRLdSt(const MCInst &Inst) const;
1697   bool validateVGPRAlign(const MCInst &Inst) const;
1698   bool validateBLGP(const MCInst &Inst, const OperandVector &Operands);
1699   bool validateDS(const MCInst &Inst, const OperandVector &Operands);
1700   bool validateGWS(const MCInst &Inst, const OperandVector &Operands);
1701   bool validateDivScale(const MCInst &Inst);
1702   bool validateWaitCnt(const MCInst &Inst, const OperandVector &Operands);
1703   bool validateCoherencyBits(const MCInst &Inst, const OperandVector &Operands,
1704                              const SMLoc &IDLoc);
1705   bool validateTHAndScopeBits(const MCInst &Inst, const OperandVector &Operands,
1706                               const unsigned CPol);
1707   bool validateExeczVcczOperands(const OperandVector &Operands);
1708   bool validateTFE(const MCInst &Inst, const OperandVector &Operands);
1709   std::optional<StringRef> validateLdsDirect(const MCInst &Inst);
1710   unsigned getConstantBusLimit(unsigned Opcode) const;
1711   bool usesConstantBus(const MCInst &Inst, unsigned OpIdx);
1712   bool isInlineConstant(const MCInst &Inst, unsigned OpIdx) const;
1713   unsigned findImplicitSGPRReadInVOP(const MCInst &Inst) const;
1714 
1715   bool isSupportedMnemo(StringRef Mnemo,
1716                         const FeatureBitset &FBS);
1717   bool isSupportedMnemo(StringRef Mnemo,
1718                         const FeatureBitset &FBS,
1719                         ArrayRef<unsigned> Variants);
1720   bool checkUnsupportedInstruction(StringRef Name, const SMLoc &IDLoc);
1721 
1722   bool isId(const StringRef Id) const;
1723   bool isId(const AsmToken &Token, const StringRef Id) const;
1724   bool isToken(const AsmToken::TokenKind Kind) const;
1725   StringRef getId() const;
1726   bool trySkipId(const StringRef Id);
1727   bool trySkipId(const StringRef Pref, const StringRef Id);
1728   bool trySkipId(const StringRef Id, const AsmToken::TokenKind Kind);
1729   bool trySkipToken(const AsmToken::TokenKind Kind);
1730   bool skipToken(const AsmToken::TokenKind Kind, const StringRef ErrMsg);
1731   bool parseString(StringRef &Val, const StringRef ErrMsg = "expected a string");
1732   bool parseId(StringRef &Val, const StringRef ErrMsg = "");
1733 
1734   void peekTokens(MutableArrayRef<AsmToken> Tokens);
1735   AsmToken::TokenKind getTokenKind() const;
1736   bool parseExpr(int64_t &Imm, StringRef Expected = "");
1737   bool parseExpr(OperandVector &Operands);
1738   StringRef getTokenStr() const;
1739   AsmToken peekToken(bool ShouldSkipSpace = true);
1740   AsmToken getToken() const;
1741   SMLoc getLoc() const;
1742   void lex();
1743 
1744 public:
1745   void onBeginOfFile() override;
1746 
1747   ParseStatus parseCustomOperand(OperandVector &Operands, unsigned MCK);
1748 
1749   ParseStatus parseExpTgt(OperandVector &Operands);
1750   ParseStatus parseSendMsg(OperandVector &Operands);
1751   ParseStatus parseInterpSlot(OperandVector &Operands);
1752   ParseStatus parseInterpAttr(OperandVector &Operands);
1753   ParseStatus parseSOPPBrTarget(OperandVector &Operands);
1754   ParseStatus parseBoolReg(OperandVector &Operands);
1755 
1756   bool parseSwizzleOperand(int64_t &Op,
1757                            const unsigned MinVal,
1758                            const unsigned MaxVal,
1759                            const StringRef ErrMsg,
1760                            SMLoc &Loc);
1761   bool parseSwizzleOperands(const unsigned OpNum, int64_t* Op,
1762                             const unsigned MinVal,
1763                             const unsigned MaxVal,
1764                             const StringRef ErrMsg);
1765   ParseStatus parseSwizzle(OperandVector &Operands);
1766   bool parseSwizzleOffset(int64_t &Imm);
1767   bool parseSwizzleMacro(int64_t &Imm);
1768   bool parseSwizzleQuadPerm(int64_t &Imm);
1769   bool parseSwizzleBitmaskPerm(int64_t &Imm);
1770   bool parseSwizzleBroadcast(int64_t &Imm);
1771   bool parseSwizzleSwap(int64_t &Imm);
1772   bool parseSwizzleReverse(int64_t &Imm);
1773 
1774   ParseStatus parseGPRIdxMode(OperandVector &Operands);
1775   int64_t parseGPRIdxMacro();
1776 
1777   void cvtMubuf(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, false); }
1778   void cvtMubufAtomic(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true); }
1779 
1780   ParseStatus parseOModSI(OperandVector &Operands);
1781 
1782   void cvtVOP3(MCInst &Inst, const OperandVector &Operands,
1783                OptionalImmIndexMap &OptionalIdx);
1784   void cvtVOP3OpSel(MCInst &Inst, const OperandVector &Operands);
1785   void cvtVOP3(MCInst &Inst, const OperandVector &Operands);
1786   void cvtVOP3P(MCInst &Inst, const OperandVector &Operands);
1787   void cvtVOPD(MCInst &Inst, const OperandVector &Operands);
1788   void cvtVOP3OpSel(MCInst &Inst, const OperandVector &Operands,
1789                     OptionalImmIndexMap &OptionalIdx);
1790   void cvtVOP3P(MCInst &Inst, const OperandVector &Operands,
1791                 OptionalImmIndexMap &OptionalIdx);
1792 
1793   void cvtVOP3Interp(MCInst &Inst, const OperandVector &Operands);
1794   void cvtVINTERP(MCInst &Inst, const OperandVector &Operands);
1795 
1796   bool parseDimId(unsigned &Encoding);
1797   ParseStatus parseDim(OperandVector &Operands);
1798   bool convertDppBoundCtrl(int64_t &BoundCtrl);
1799   ParseStatus parseDPP8(OperandVector &Operands);
1800   ParseStatus parseDPPCtrl(OperandVector &Operands);
1801   bool isSupportedDPPCtrl(StringRef Ctrl, const OperandVector &Operands);
1802   int64_t parseDPPCtrlSel(StringRef Ctrl);
1803   int64_t parseDPPCtrlPerm();
1804   void cvtDPP(MCInst &Inst, const OperandVector &Operands, bool IsDPP8 = false);
1805   void cvtDPP8(MCInst &Inst, const OperandVector &Operands) {
1806     cvtDPP(Inst, Operands, true);
1807   }
1808   void cvtVOP3DPP(MCInst &Inst, const OperandVector &Operands,
1809                   bool IsDPP8 = false);
1810   void cvtVOP3DPP8(MCInst &Inst, const OperandVector &Operands) {
1811     cvtVOP3DPP(Inst, Operands, true);
1812   }
1813 
1814   ParseStatus parseSDWASel(OperandVector &Operands, StringRef Prefix,
1815                            AMDGPUOperand::ImmTy Type);
1816   ParseStatus parseSDWADstUnused(OperandVector &Operands);
1817   void cvtSdwaVOP1(MCInst &Inst, const OperandVector &Operands);
1818   void cvtSdwaVOP2(MCInst &Inst, const OperandVector &Operands);
1819   void cvtSdwaVOP2b(MCInst &Inst, const OperandVector &Operands);
1820   void cvtSdwaVOP2e(MCInst &Inst, const OperandVector &Operands);
1821   void cvtSdwaVOPC(MCInst &Inst, const OperandVector &Operands);
1822   void cvtSDWA(MCInst &Inst, const OperandVector &Operands,
1823                uint64_t BasicInstType,
1824                bool SkipDstVcc = false,
1825                bool SkipSrcVcc = false);
1826 
1827   ParseStatus parseEndpgm(OperandVector &Operands);
1828 
1829   ParseStatus parseVOPD(OperandVector &Operands);
1830 };
1831 
1832 } // end anonymous namespace
1833 
1834 // May be called with integer type with equivalent bitwidth.
1835 static const fltSemantics *getFltSemantics(unsigned Size) {
1836   switch (Size) {
1837   case 4:
1838     return &APFloat::IEEEsingle();
1839   case 8:
1840     return &APFloat::IEEEdouble();
1841   case 2:
1842     return &APFloat::IEEEhalf();
1843   default:
1844     llvm_unreachable("unsupported fp type");
1845   }
1846 }
1847 
1848 static const fltSemantics *getFltSemantics(MVT VT) {
1849   return getFltSemantics(VT.getSizeInBits() / 8);
1850 }
1851 
1852 static const fltSemantics *getOpFltSemantics(uint8_t OperandType) {
1853   switch (OperandType) {
1854   case AMDGPU::OPERAND_REG_IMM_INT32:
1855   case AMDGPU::OPERAND_REG_IMM_FP32:
1856   case AMDGPU::OPERAND_REG_IMM_FP32_DEFERRED:
1857   case AMDGPU::OPERAND_REG_INLINE_C_INT32:
1858   case AMDGPU::OPERAND_REG_INLINE_C_FP32:
1859   case AMDGPU::OPERAND_REG_INLINE_AC_INT32:
1860   case AMDGPU::OPERAND_REG_INLINE_AC_FP32:
1861   case AMDGPU::OPERAND_REG_INLINE_C_V2FP32:
1862   case AMDGPU::OPERAND_REG_IMM_V2FP32:
1863   case AMDGPU::OPERAND_REG_INLINE_C_V2INT32:
1864   case AMDGPU::OPERAND_REG_IMM_V2INT32:
1865   case AMDGPU::OPERAND_REG_IMM_V2INT16:
1866   case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
1867   case AMDGPU::OPERAND_REG_INLINE_AC_V2INT16:
1868   case AMDGPU::OPERAND_KIMM32:
1869   case AMDGPU::OPERAND_INLINE_SPLIT_BARRIER_INT32:
1870     return &APFloat::IEEEsingle();
1871   case AMDGPU::OPERAND_REG_IMM_INT64:
1872   case AMDGPU::OPERAND_REG_IMM_FP64:
1873   case AMDGPU::OPERAND_REG_INLINE_C_INT64:
1874   case AMDGPU::OPERAND_REG_INLINE_C_FP64:
1875   case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
1876     return &APFloat::IEEEdouble();
1877   case AMDGPU::OPERAND_REG_IMM_INT16:
1878   case AMDGPU::OPERAND_REG_IMM_FP16:
1879   case AMDGPU::OPERAND_REG_IMM_FP16_DEFERRED:
1880   case AMDGPU::OPERAND_REG_INLINE_C_INT16:
1881   case AMDGPU::OPERAND_REG_INLINE_C_FP16:
1882   case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
1883   case AMDGPU::OPERAND_REG_INLINE_AC_INT16:
1884   case AMDGPU::OPERAND_REG_INLINE_AC_FP16:
1885   case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16:
1886   case AMDGPU::OPERAND_REG_IMM_V2FP16:
1887   case AMDGPU::OPERAND_KIMM16:
1888     return &APFloat::IEEEhalf();
1889   default:
1890     llvm_unreachable("unsupported fp type");
1891   }
1892 }
1893 
1894 //===----------------------------------------------------------------------===//
1895 // Operand
1896 //===----------------------------------------------------------------------===//
1897 
1898 static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT) {
1899   bool Lost;
1900 
1901   // Convert literal to single precision
1902   APFloat::opStatus Status = FPLiteral.convert(*getFltSemantics(VT),
1903                                                APFloat::rmNearestTiesToEven,
1904                                                &Lost);
1905   // We allow precision lost but not overflow or underflow
1906   if (Status != APFloat::opOK &&
1907       Lost &&
1908       ((Status & APFloat::opOverflow)  != 0 ||
1909        (Status & APFloat::opUnderflow) != 0)) {
1910     return false;
1911   }
1912 
1913   return true;
1914 }
1915 
1916 static bool isSafeTruncation(int64_t Val, unsigned Size) {
1917   return isUIntN(Size, Val) || isIntN(Size, Val);
1918 }
1919 
1920 static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi) {
1921   if (VT.getScalarType() == MVT::i16) {
1922     // FP immediate values are broken.
1923     return isInlinableIntLiteral(Val);
1924   }
1925 
1926   // f16/v2f16 operands work correctly for all values.
1927   return AMDGPU::isInlinableLiteral16(Val, HasInv2Pi);
1928 }
1929 
1930 bool AMDGPUOperand::isInlinableImm(MVT type) const {
1931 
1932   // This is a hack to enable named inline values like
1933   // shared_base with both 32-bit and 64-bit operands.
1934   // Note that these values are defined as
1935   // 32-bit operands only.
1936   if (isInlineValue()) {
1937     return true;
1938   }
1939 
1940   if (!isImmTy(ImmTyNone)) {
1941     // Only plain immediates are inlinable (e.g. "clamp" attribute is not)
1942     return false;
1943   }
1944   // TODO: We should avoid using host float here. It would be better to
1945   // check the float bit values which is what a few other places do.
1946   // We've had bot failures before due to weird NaN support on mips hosts.
1947 
1948   APInt Literal(64, Imm.Val);
1949 
1950   if (Imm.IsFPImm) { // We got fp literal token
1951     if (type == MVT::f64 || type == MVT::i64) { // Expected 64-bit operand
1952       return AMDGPU::isInlinableLiteral64(Imm.Val,
1953                                           AsmParser->hasInv2PiInlineImm());
1954     }
1955 
1956     APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64, Imm.Val));
1957     if (!canLosslesslyConvertToFPType(FPLiteral, type))
1958       return false;
1959 
1960     if (type.getScalarSizeInBits() == 16) {
1961       return isInlineableLiteralOp16(
1962         static_cast<int16_t>(FPLiteral.bitcastToAPInt().getZExtValue()),
1963         type, AsmParser->hasInv2PiInlineImm());
1964     }
1965 
1966     // Check if single precision literal is inlinable
1967     return AMDGPU::isInlinableLiteral32(
1968       static_cast<int32_t>(FPLiteral.bitcastToAPInt().getZExtValue()),
1969       AsmParser->hasInv2PiInlineImm());
1970   }
1971 
1972   // We got int literal token.
1973   if (type == MVT::f64 || type == MVT::i64) { // Expected 64-bit operand
1974     return AMDGPU::isInlinableLiteral64(Imm.Val,
1975                                         AsmParser->hasInv2PiInlineImm());
1976   }
1977 
1978   if (!isSafeTruncation(Imm.Val, type.getScalarSizeInBits())) {
1979     return false;
1980   }
1981 
1982   if (type.getScalarSizeInBits() == 16) {
1983     return isInlineableLiteralOp16(
1984       static_cast<int16_t>(Literal.getLoBits(16).getSExtValue()),
1985       type, AsmParser->hasInv2PiInlineImm());
1986   }
1987 
1988   return AMDGPU::isInlinableLiteral32(
1989     static_cast<int32_t>(Literal.getLoBits(32).getZExtValue()),
1990     AsmParser->hasInv2PiInlineImm());
1991 }
1992 
1993 bool AMDGPUOperand::isLiteralImm(MVT type) const {
1994   // Check that this immediate can be added as literal
1995   if (!isImmTy(ImmTyNone)) {
1996     return false;
1997   }
1998 
1999   if (!Imm.IsFPImm) {
2000     // We got int literal token.
2001 
2002     if (type == MVT::f64 && hasFPModifiers()) {
2003       // Cannot apply fp modifiers to int literals preserving the same semantics
2004       // for VOP1/2/C and VOP3 because of integer truncation. To avoid ambiguity,
2005       // disable these cases.
2006       return false;
2007     }
2008 
2009     unsigned Size = type.getSizeInBits();
2010     if (Size == 64)
2011       Size = 32;
2012 
2013     // FIXME: 64-bit operands can zero extend, sign extend, or pad zeroes for FP
2014     // types.
2015     return isSafeTruncation(Imm.Val, Size);
2016   }
2017 
2018   // We got fp literal token
2019   if (type == MVT::f64) { // Expected 64-bit fp operand
2020     // We would set low 64-bits of literal to zeroes but we accept this literals
2021     return true;
2022   }
2023 
2024   if (type == MVT::i64) { // Expected 64-bit int operand
2025     // We don't allow fp literals in 64-bit integer instructions. It is
2026     // unclear how we should encode them.
2027     return false;
2028   }
2029 
2030   // We allow fp literals with f16x2 operands assuming that the specified
2031   // literal goes into the lower half and the upper half is zero. We also
2032   // require that the literal may be losslessly converted to f16.
2033   //
2034   // For i16x2 operands, we assume that the specified literal is encoded as a
2035   // single-precision float. This is pretty odd, but it matches SP3 and what
2036   // happens in hardware.
2037   MVT ExpectedType = (type == MVT::v2f16)   ? MVT::f16
2038                      : (type == MVT::v2i16) ? MVT::f32
2039                      : (type == MVT::v2f32) ? MVT::f32
2040                                             : type;
2041 
2042   APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64, Imm.Val));
2043   return canLosslesslyConvertToFPType(FPLiteral, ExpectedType);
2044 }
2045 
2046 bool AMDGPUOperand::isRegClass(unsigned RCID) const {
2047   return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(getReg());
2048 }
2049 
2050 bool AMDGPUOperand::isVRegWithInputMods() const {
2051   return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2052          // GFX90A allows DPP on 64-bit operands.
2053          (isRegClass(AMDGPU::VReg_64RegClassID) &&
2054           AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2055 }
2056 
2057 template <bool IsFake16> bool AMDGPUOperand::isT16VRegWithInputMods() const {
2058   return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2059                              : AMDGPU::VGPR_16_Lo128RegClassID);
2060 }
2061 
2062 bool AMDGPUOperand::isSDWAOperand(MVT type) const {
2063   if (AsmParser->isVI())
2064     return isVReg32();
2065   else if (AsmParser->isGFX9Plus())
2066     return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2067   else
2068     return false;
2069 }
2070 
2071 bool AMDGPUOperand::isSDWAFP16Operand() const {
2072   return isSDWAOperand(MVT::f16);
2073 }
2074 
2075 bool AMDGPUOperand::isSDWAFP32Operand() const {
2076   return isSDWAOperand(MVT::f32);
2077 }
2078 
2079 bool AMDGPUOperand::isSDWAInt16Operand() const {
2080   return isSDWAOperand(MVT::i16);
2081 }
2082 
2083 bool AMDGPUOperand::isSDWAInt32Operand() const {
2084   return isSDWAOperand(MVT::i32);
2085 }
2086 
2087 bool AMDGPUOperand::isBoolReg() const {
2088   auto FB = AsmParser->getFeatureBits();
2089   return isReg() && ((FB[AMDGPU::FeatureWavefrontSize64] && isSCSrcB64()) ||
2090                      (FB[AMDGPU::FeatureWavefrontSize32] && isSCSrcB32()));
2091 }
2092 
2093 uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val, unsigned Size) const
2094 {
2095   assert(isImmTy(ImmTyNone) && Imm.Mods.hasFPModifiers());
2096   assert(Size == 2 || Size == 4 || Size == 8);
2097 
2098   const uint64_t FpSignMask = (1ULL << (Size * 8 - 1));
2099 
2100   if (Imm.Mods.Abs) {
2101     Val &= ~FpSignMask;
2102   }
2103   if (Imm.Mods.Neg) {
2104     Val ^= FpSignMask;
2105   }
2106 
2107   return Val;
2108 }
2109 
2110 void AMDGPUOperand::addImmOperands(MCInst &Inst, unsigned N, bool ApplyModifiers) const {
2111   if (isExpr()) {
2112     Inst.addOperand(MCOperand::createExpr(Expr));
2113     return;
2114   }
2115 
2116   if (AMDGPU::isSISrcOperand(AsmParser->getMII()->get(Inst.getOpcode()),
2117                              Inst.getNumOperands())) {
2118     addLiteralImmOperand(Inst, Imm.Val,
2119                          ApplyModifiers &
2120                          isImmTy(ImmTyNone) && Imm.Mods.hasFPModifiers());
2121   } else {
2122     assert(!isImmTy(ImmTyNone) || !hasModifiers());
2123     Inst.addOperand(MCOperand::createImm(Imm.Val));
2124     setImmKindNone();
2125   }
2126 }
2127 
2128 void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyModifiers) const {
2129   const auto& InstDesc = AsmParser->getMII()->get(Inst.getOpcode());
2130   auto OpNum = Inst.getNumOperands();
2131   // Check that this operand accepts literals
2132   assert(AMDGPU::isSISrcOperand(InstDesc, OpNum));
2133 
2134   if (ApplyModifiers) {
2135     assert(AMDGPU::isSISrcFPOperand(InstDesc, OpNum));
2136     const unsigned Size = Imm.IsFPImm ? sizeof(double) : getOperandSize(InstDesc, OpNum);
2137     Val = applyInputFPModifiers(Val, Size);
2138   }
2139 
2140   APInt Literal(64, Val);
2141   uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2142 
2143   if (Imm.IsFPImm) { // We got fp literal token
2144     switch (OpTy) {
2145     case AMDGPU::OPERAND_REG_IMM_INT64:
2146     case AMDGPU::OPERAND_REG_IMM_FP64:
2147     case AMDGPU::OPERAND_REG_INLINE_C_INT64:
2148     case AMDGPU::OPERAND_REG_INLINE_C_FP64:
2149     case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
2150       if (AMDGPU::isInlinableLiteral64(Literal.getZExtValue(),
2151                                        AsmParser->hasInv2PiInlineImm())) {
2152         Inst.addOperand(MCOperand::createImm(Literal.getZExtValue()));
2153         setImmKindConst();
2154         return;
2155       }
2156 
2157       // Non-inlineable
2158       if (AMDGPU::isSISrcFPOperand(InstDesc, OpNum)) { // Expected 64-bit fp operand
2159         // For fp operands we check if low 32 bits are zeros
2160         if (Literal.getLoBits(32) != 0) {
2161           const_cast<AMDGPUAsmParser *>(AsmParser)->Warning(Inst.getLoc(),
2162           "Can't encode literal as exact 64-bit floating-point operand. "
2163           "Low 32-bits will be set to zero");
2164           Val &= 0xffffffff00000000u;
2165         }
2166 
2167         Inst.addOperand(MCOperand::createImm(Val));
2168         setImmKindLiteral();
2169         return;
2170       }
2171 
2172       // We don't allow fp literals in 64-bit integer instructions. It is
2173       // unclear how we should encode them. This case should be checked earlier
2174       // in predicate methods (isLiteralImm())
2175       llvm_unreachable("fp literal in 64-bit integer instruction.");
2176 
2177     case AMDGPU::OPERAND_REG_IMM_INT32:
2178     case AMDGPU::OPERAND_REG_IMM_FP32:
2179     case AMDGPU::OPERAND_REG_IMM_FP32_DEFERRED:
2180     case AMDGPU::OPERAND_REG_INLINE_C_INT32:
2181     case AMDGPU::OPERAND_REG_INLINE_C_FP32:
2182     case AMDGPU::OPERAND_REG_INLINE_AC_INT32:
2183     case AMDGPU::OPERAND_REG_INLINE_AC_FP32:
2184     case AMDGPU::OPERAND_REG_IMM_INT16:
2185     case AMDGPU::OPERAND_REG_IMM_FP16:
2186     case AMDGPU::OPERAND_REG_IMM_FP16_DEFERRED:
2187     case AMDGPU::OPERAND_REG_INLINE_C_INT16:
2188     case AMDGPU::OPERAND_REG_INLINE_C_FP16:
2189     case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
2190     case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
2191     case AMDGPU::OPERAND_REG_INLINE_AC_INT16:
2192     case AMDGPU::OPERAND_REG_INLINE_AC_FP16:
2193     case AMDGPU::OPERAND_REG_INLINE_AC_V2INT16:
2194     case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16:
2195     case AMDGPU::OPERAND_REG_IMM_V2INT16:
2196     case AMDGPU::OPERAND_REG_IMM_V2FP16:
2197     case AMDGPU::OPERAND_REG_INLINE_C_V2FP32:
2198     case AMDGPU::OPERAND_REG_IMM_V2FP32:
2199     case AMDGPU::OPERAND_REG_INLINE_C_V2INT32:
2200     case AMDGPU::OPERAND_REG_IMM_V2INT32:
2201     case AMDGPU::OPERAND_KIMM32:
2202     case AMDGPU::OPERAND_KIMM16:
2203     case AMDGPU::OPERAND_INLINE_SPLIT_BARRIER_INT32: {
2204       bool lost;
2205       APFloat FPLiteral(APFloat::IEEEdouble(), Literal);
2206       // Convert literal to single precision
2207       FPLiteral.convert(*getOpFltSemantics(OpTy),
2208                         APFloat::rmNearestTiesToEven, &lost);
2209       // We allow precision lost but not overflow or underflow. This should be
2210       // checked earlier in isLiteralImm()
2211 
2212       uint64_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2213       Inst.addOperand(MCOperand::createImm(ImmVal));
2214       if (OpTy == AMDGPU::OPERAND_KIMM32 || OpTy == AMDGPU::OPERAND_KIMM16) {
2215         setImmKindMandatoryLiteral();
2216       } else {
2217         setImmKindLiteral();
2218       }
2219       return;
2220     }
2221     default:
2222       llvm_unreachable("invalid operand size");
2223     }
2224 
2225     return;
2226   }
2227 
2228   // We got int literal token.
2229   // Only sign extend inline immediates.
2230   switch (OpTy) {
2231   case AMDGPU::OPERAND_REG_IMM_INT32:
2232   case AMDGPU::OPERAND_REG_IMM_FP32:
2233   case AMDGPU::OPERAND_REG_IMM_FP32_DEFERRED:
2234   case AMDGPU::OPERAND_REG_INLINE_C_INT32:
2235   case AMDGPU::OPERAND_REG_INLINE_C_FP32:
2236   case AMDGPU::OPERAND_REG_INLINE_AC_INT32:
2237   case AMDGPU::OPERAND_REG_INLINE_AC_FP32:
2238   case AMDGPU::OPERAND_REG_IMM_V2INT16:
2239   case AMDGPU::OPERAND_REG_IMM_V2FP16:
2240   case AMDGPU::OPERAND_REG_IMM_V2FP32:
2241   case AMDGPU::OPERAND_REG_INLINE_C_V2FP32:
2242   case AMDGPU::OPERAND_REG_IMM_V2INT32:
2243   case AMDGPU::OPERAND_REG_INLINE_C_V2INT32:
2244   case AMDGPU::OPERAND_INLINE_SPLIT_BARRIER_INT32:
2245     if (isSafeTruncation(Val, 32) &&
2246         AMDGPU::isInlinableLiteral32(static_cast<int32_t>(Val),
2247                                      AsmParser->hasInv2PiInlineImm())) {
2248       Inst.addOperand(MCOperand::createImm(Val));
2249       setImmKindConst();
2250       return;
2251     }
2252 
2253     Inst.addOperand(MCOperand::createImm(Val & 0xffffffff));
2254     setImmKindLiteral();
2255     return;
2256 
2257   case AMDGPU::OPERAND_REG_IMM_INT64:
2258   case AMDGPU::OPERAND_REG_IMM_FP64:
2259   case AMDGPU::OPERAND_REG_INLINE_C_INT64:
2260   case AMDGPU::OPERAND_REG_INLINE_C_FP64:
2261   case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
2262     if (AMDGPU::isInlinableLiteral64(Val, AsmParser->hasInv2PiInlineImm())) {
2263       Inst.addOperand(MCOperand::createImm(Val));
2264       setImmKindConst();
2265       return;
2266     }
2267 
2268     Val = AMDGPU::isSISrcFPOperand(InstDesc, OpNum) ? (uint64_t)Val << 32
2269                                                     : Lo_32(Val);
2270 
2271     Inst.addOperand(MCOperand::createImm(Val));
2272     setImmKindLiteral();
2273     return;
2274 
2275   case AMDGPU::OPERAND_REG_IMM_INT16:
2276   case AMDGPU::OPERAND_REG_IMM_FP16:
2277   case AMDGPU::OPERAND_REG_IMM_FP16_DEFERRED:
2278   case AMDGPU::OPERAND_REG_INLINE_C_INT16:
2279   case AMDGPU::OPERAND_REG_INLINE_C_FP16:
2280   case AMDGPU::OPERAND_REG_INLINE_AC_INT16:
2281   case AMDGPU::OPERAND_REG_INLINE_AC_FP16:
2282     if (isSafeTruncation(Val, 16) &&
2283         AMDGPU::isInlinableLiteral16(static_cast<int16_t>(Val),
2284                                      AsmParser->hasInv2PiInlineImm())) {
2285       Inst.addOperand(MCOperand::createImm(Val));
2286       setImmKindConst();
2287       return;
2288     }
2289 
2290     Inst.addOperand(MCOperand::createImm(Val & 0xffff));
2291     setImmKindLiteral();
2292     return;
2293 
2294   case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
2295   case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
2296   case AMDGPU::OPERAND_REG_INLINE_AC_V2INT16:
2297   case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16: {
2298     assert(isSafeTruncation(Val, 16));
2299     assert(AMDGPU::isInlinableLiteral16(static_cast<int16_t>(Val),
2300                                         AsmParser->hasInv2PiInlineImm()));
2301 
2302     Inst.addOperand(MCOperand::createImm(Val));
2303     return;
2304   }
2305   case AMDGPU::OPERAND_KIMM32:
2306     Inst.addOperand(MCOperand::createImm(Literal.getLoBits(32).getZExtValue()));
2307     setImmKindMandatoryLiteral();
2308     return;
2309   case AMDGPU::OPERAND_KIMM16:
2310     Inst.addOperand(MCOperand::createImm(Literal.getLoBits(16).getZExtValue()));
2311     setImmKindMandatoryLiteral();
2312     return;
2313   default:
2314     llvm_unreachable("invalid operand size");
2315   }
2316 }
2317 
2318 void AMDGPUOperand::addRegOperands(MCInst &Inst, unsigned N) const {
2319   Inst.addOperand(MCOperand::createReg(AMDGPU::getMCReg(getReg(), AsmParser->getSTI())));
2320 }
2321 
2322 bool AMDGPUOperand::isInlineValue() const {
2323   return isRegKind() && ::isInlineValue(getReg());
2324 }
2325 
2326 //===----------------------------------------------------------------------===//
2327 // AsmParser
2328 //===----------------------------------------------------------------------===//
2329 
2330 static int getRegClass(RegisterKind Is, unsigned RegWidth) {
2331   if (Is == IS_VGPR) {
2332     switch (RegWidth) {
2333       default: return -1;
2334       case 32:
2335         return AMDGPU::VGPR_32RegClassID;
2336       case 64:
2337         return AMDGPU::VReg_64RegClassID;
2338       case 96:
2339         return AMDGPU::VReg_96RegClassID;
2340       case 128:
2341         return AMDGPU::VReg_128RegClassID;
2342       case 160:
2343         return AMDGPU::VReg_160RegClassID;
2344       case 192:
2345         return AMDGPU::VReg_192RegClassID;
2346       case 224:
2347         return AMDGPU::VReg_224RegClassID;
2348       case 256:
2349         return AMDGPU::VReg_256RegClassID;
2350       case 288:
2351         return AMDGPU::VReg_288RegClassID;
2352       case 320:
2353         return AMDGPU::VReg_320RegClassID;
2354       case 352:
2355         return AMDGPU::VReg_352RegClassID;
2356       case 384:
2357         return AMDGPU::VReg_384RegClassID;
2358       case 512:
2359         return AMDGPU::VReg_512RegClassID;
2360       case 1024:
2361         return AMDGPU::VReg_1024RegClassID;
2362     }
2363   } else if (Is == IS_TTMP) {
2364     switch (RegWidth) {
2365       default: return -1;
2366       case 32:
2367         return AMDGPU::TTMP_32RegClassID;
2368       case 64:
2369         return AMDGPU::TTMP_64RegClassID;
2370       case 128:
2371         return AMDGPU::TTMP_128RegClassID;
2372       case 256:
2373         return AMDGPU::TTMP_256RegClassID;
2374       case 512:
2375         return AMDGPU::TTMP_512RegClassID;
2376     }
2377   } else if (Is == IS_SGPR) {
2378     switch (RegWidth) {
2379       default: return -1;
2380       case 32:
2381         return AMDGPU::SGPR_32RegClassID;
2382       case 64:
2383         return AMDGPU::SGPR_64RegClassID;
2384       case 96:
2385         return AMDGPU::SGPR_96RegClassID;
2386       case 128:
2387         return AMDGPU::SGPR_128RegClassID;
2388       case 160:
2389         return AMDGPU::SGPR_160RegClassID;
2390       case 192:
2391         return AMDGPU::SGPR_192RegClassID;
2392       case 224:
2393         return AMDGPU::SGPR_224RegClassID;
2394       case 256:
2395         return AMDGPU::SGPR_256RegClassID;
2396       case 288:
2397         return AMDGPU::SGPR_288RegClassID;
2398       case 320:
2399         return AMDGPU::SGPR_320RegClassID;
2400       case 352:
2401         return AMDGPU::SGPR_352RegClassID;
2402       case 384:
2403         return AMDGPU::SGPR_384RegClassID;
2404       case 512:
2405         return AMDGPU::SGPR_512RegClassID;
2406     }
2407   } else if (Is == IS_AGPR) {
2408     switch (RegWidth) {
2409       default: return -1;
2410       case 32:
2411         return AMDGPU::AGPR_32RegClassID;
2412       case 64:
2413         return AMDGPU::AReg_64RegClassID;
2414       case 96:
2415         return AMDGPU::AReg_96RegClassID;
2416       case 128:
2417         return AMDGPU::AReg_128RegClassID;
2418       case 160:
2419         return AMDGPU::AReg_160RegClassID;
2420       case 192:
2421         return AMDGPU::AReg_192RegClassID;
2422       case 224:
2423         return AMDGPU::AReg_224RegClassID;
2424       case 256:
2425         return AMDGPU::AReg_256RegClassID;
2426       case 288:
2427         return AMDGPU::AReg_288RegClassID;
2428       case 320:
2429         return AMDGPU::AReg_320RegClassID;
2430       case 352:
2431         return AMDGPU::AReg_352RegClassID;
2432       case 384:
2433         return AMDGPU::AReg_384RegClassID;
2434       case 512:
2435         return AMDGPU::AReg_512RegClassID;
2436       case 1024:
2437         return AMDGPU::AReg_1024RegClassID;
2438     }
2439   }
2440   return -1;
2441 }
2442 
2443 static unsigned getSpecialRegForName(StringRef RegName) {
2444   return StringSwitch<unsigned>(RegName)
2445     .Case("exec", AMDGPU::EXEC)
2446     .Case("vcc", AMDGPU::VCC)
2447     .Case("flat_scratch", AMDGPU::FLAT_SCR)
2448     .Case("xnack_mask", AMDGPU::XNACK_MASK)
2449     .Case("shared_base", AMDGPU::SRC_SHARED_BASE)
2450     .Case("src_shared_base", AMDGPU::SRC_SHARED_BASE)
2451     .Case("shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2452     .Case("src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2453     .Case("private_base", AMDGPU::SRC_PRIVATE_BASE)
2454     .Case("src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2455     .Case("private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2456     .Case("src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2457     .Case("pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2458     .Case("src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2459     .Case("lds_direct", AMDGPU::LDS_DIRECT)
2460     .Case("src_lds_direct", AMDGPU::LDS_DIRECT)
2461     .Case("m0", AMDGPU::M0)
2462     .Case("vccz", AMDGPU::SRC_VCCZ)
2463     .Case("src_vccz", AMDGPU::SRC_VCCZ)
2464     .Case("execz", AMDGPU::SRC_EXECZ)
2465     .Case("src_execz", AMDGPU::SRC_EXECZ)
2466     .Case("scc", AMDGPU::SRC_SCC)
2467     .Case("src_scc", AMDGPU::SRC_SCC)
2468     .Case("tba", AMDGPU::TBA)
2469     .Case("tma", AMDGPU::TMA)
2470     .Case("flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2471     .Case("flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2472     .Case("xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2473     .Case("xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2474     .Case("vcc_lo", AMDGPU::VCC_LO)
2475     .Case("vcc_hi", AMDGPU::VCC_HI)
2476     .Case("exec_lo", AMDGPU::EXEC_LO)
2477     .Case("exec_hi", AMDGPU::EXEC_HI)
2478     .Case("tma_lo", AMDGPU::TMA_LO)
2479     .Case("tma_hi", AMDGPU::TMA_HI)
2480     .Case("tba_lo", AMDGPU::TBA_LO)
2481     .Case("tba_hi", AMDGPU::TBA_HI)
2482     .Case("pc", AMDGPU::PC_REG)
2483     .Case("null", AMDGPU::SGPR_NULL)
2484     .Default(AMDGPU::NoRegister);
2485 }
2486 
2487 bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2488                                     SMLoc &EndLoc, bool RestoreOnFailure) {
2489   auto R = parseRegister();
2490   if (!R) return true;
2491   assert(R->isReg());
2492   RegNo = R->getReg();
2493   StartLoc = R->getStartLoc();
2494   EndLoc = R->getEndLoc();
2495   return false;
2496 }
2497 
2498 bool AMDGPUAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
2499                                     SMLoc &EndLoc) {
2500   return ParseRegister(Reg, StartLoc, EndLoc, /*RestoreOnFailure=*/false);
2501 }
2502 
2503 ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
2504                                               SMLoc &EndLoc) {
2505   bool Result = ParseRegister(Reg, StartLoc, EndLoc, /*RestoreOnFailure=*/true);
2506   bool PendingErrors = getParser().hasPendingError();
2507   getParser().clearPendingErrors();
2508   if (PendingErrors)
2509     return ParseStatus::Failure;
2510   if (Result)
2511     return ParseStatus::NoMatch;
2512   return ParseStatus::Success;
2513 }
2514 
2515 bool AMDGPUAsmParser::AddNextRegisterToList(unsigned &Reg, unsigned &RegWidth,
2516                                             RegisterKind RegKind, unsigned Reg1,
2517                                             SMLoc Loc) {
2518   switch (RegKind) {
2519   case IS_SPECIAL:
2520     if (Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2521       Reg = AMDGPU::EXEC;
2522       RegWidth = 64;
2523       return true;
2524     }
2525     if (Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2526       Reg = AMDGPU::FLAT_SCR;
2527       RegWidth = 64;
2528       return true;
2529     }
2530     if (Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2531       Reg = AMDGPU::XNACK_MASK;
2532       RegWidth = 64;
2533       return true;
2534     }
2535     if (Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2536       Reg = AMDGPU::VCC;
2537       RegWidth = 64;
2538       return true;
2539     }
2540     if (Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2541       Reg = AMDGPU::TBA;
2542       RegWidth = 64;
2543       return true;
2544     }
2545     if (Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2546       Reg = AMDGPU::TMA;
2547       RegWidth = 64;
2548       return true;
2549     }
2550     Error(Loc, "register does not fit in the list");
2551     return false;
2552   case IS_VGPR:
2553   case IS_SGPR:
2554   case IS_AGPR:
2555   case IS_TTMP:
2556     if (Reg1 != Reg + RegWidth / 32) {
2557       Error(Loc, "registers in a list must have consecutive indices");
2558       return false;
2559     }
2560     RegWidth += 32;
2561     return true;
2562   default:
2563     llvm_unreachable("unexpected register kind");
2564   }
2565 }
2566 
2567 struct RegInfo {
2568   StringLiteral Name;
2569   RegisterKind Kind;
2570 };
2571 
2572 static constexpr RegInfo RegularRegisters[] = {
2573   {{"v"},    IS_VGPR},
2574   {{"s"},    IS_SGPR},
2575   {{"ttmp"}, IS_TTMP},
2576   {{"acc"},  IS_AGPR},
2577   {{"a"},    IS_AGPR},
2578 };
2579 
2580 static bool isRegularReg(RegisterKind Kind) {
2581   return Kind == IS_VGPR ||
2582          Kind == IS_SGPR ||
2583          Kind == IS_TTMP ||
2584          Kind == IS_AGPR;
2585 }
2586 
2587 static const RegInfo* getRegularRegInfo(StringRef Str) {
2588   for (const RegInfo &Reg : RegularRegisters)
2589     if (Str.starts_with(Reg.Name))
2590       return &Reg;
2591   return nullptr;
2592 }
2593 
2594 static bool getRegNum(StringRef Str, unsigned& Num) {
2595   return !Str.getAsInteger(10, Num);
2596 }
2597 
2598 bool
2599 AMDGPUAsmParser::isRegister(const AsmToken &Token,
2600                             const AsmToken &NextToken) const {
2601 
2602   // A list of consecutive registers: [s0,s1,s2,s3]
2603   if (Token.is(AsmToken::LBrac))
2604     return true;
2605 
2606   if (!Token.is(AsmToken::Identifier))
2607     return false;
2608 
2609   // A single register like s0 or a range of registers like s[0:1]
2610 
2611   StringRef Str = Token.getString();
2612   const RegInfo *Reg = getRegularRegInfo(Str);
2613   if (Reg) {
2614     StringRef RegName = Reg->Name;
2615     StringRef RegSuffix = Str.substr(RegName.size());
2616     if (!RegSuffix.empty()) {
2617       RegSuffix.consume_back(".l");
2618       RegSuffix.consume_back(".h");
2619       unsigned Num;
2620       // A single register with an index: rXX
2621       if (getRegNum(RegSuffix, Num))
2622         return true;
2623     } else {
2624       // A range of registers: r[XX:YY].
2625       if (NextToken.is(AsmToken::LBrac))
2626         return true;
2627     }
2628   }
2629 
2630   return getSpecialRegForName(Str) != AMDGPU::NoRegister;
2631 }
2632 
2633 bool
2634 AMDGPUAsmParser::isRegister()
2635 {
2636   return isRegister(getToken(), peekToken());
2637 }
2638 
2639 unsigned AMDGPUAsmParser::getRegularReg(RegisterKind RegKind, unsigned RegNum,
2640                                         unsigned SubReg, unsigned RegWidth,
2641                                         SMLoc Loc) {
2642   assert(isRegularReg(RegKind));
2643 
2644   unsigned AlignSize = 1;
2645   if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2646     // SGPR and TTMP registers must be aligned.
2647     // Max required alignment is 4 dwords.
2648     AlignSize = std::min(llvm::bit_ceil(RegWidth / 32), 4u);
2649   }
2650 
2651   if (RegNum % AlignSize != 0) {
2652     Error(Loc, "invalid register alignment");
2653     return AMDGPU::NoRegister;
2654   }
2655 
2656   unsigned RegIdx = RegNum / AlignSize;
2657   int RCID = getRegClass(RegKind, RegWidth);
2658   if (RCID == -1) {
2659     Error(Loc, "invalid or unsupported register size");
2660     return AMDGPU::NoRegister;
2661   }
2662 
2663   const MCRegisterInfo *TRI = getContext().getRegisterInfo();
2664   const MCRegisterClass RC = TRI->getRegClass(RCID);
2665   if (RegIdx >= RC.getNumRegs()) {
2666     Error(Loc, "register index is out of range");
2667     return AMDGPU::NoRegister;
2668   }
2669 
2670   unsigned Reg = RC.getRegister(RegIdx);
2671 
2672   if (SubReg) {
2673     Reg = TRI->getSubReg(Reg, SubReg);
2674 
2675     // Currently all regular registers have their .l and .h subregisters, so
2676     // we should never need to generate an error here.
2677     assert(Reg && "Invalid subregister!");
2678   }
2679 
2680   return Reg;
2681 }
2682 
2683 bool AMDGPUAsmParser::ParseRegRange(unsigned &Num, unsigned &RegWidth) {
2684   int64_t RegLo, RegHi;
2685   if (!skipToken(AsmToken::LBrac, "missing register index"))
2686     return false;
2687 
2688   SMLoc FirstIdxLoc = getLoc();
2689   SMLoc SecondIdxLoc;
2690 
2691   if (!parseExpr(RegLo))
2692     return false;
2693 
2694   if (trySkipToken(AsmToken::Colon)) {
2695     SecondIdxLoc = getLoc();
2696     if (!parseExpr(RegHi))
2697       return false;
2698   } else {
2699     RegHi = RegLo;
2700   }
2701 
2702   if (!skipToken(AsmToken::RBrac, "expected a closing square bracket"))
2703     return false;
2704 
2705   if (!isUInt<32>(RegLo)) {
2706     Error(FirstIdxLoc, "invalid register index");
2707     return false;
2708   }
2709 
2710   if (!isUInt<32>(RegHi)) {
2711     Error(SecondIdxLoc, "invalid register index");
2712     return false;
2713   }
2714 
2715   if (RegLo > RegHi) {
2716     Error(FirstIdxLoc, "first register index should not exceed second index");
2717     return false;
2718   }
2719 
2720   Num = static_cast<unsigned>(RegLo);
2721   RegWidth = 32 * ((RegHi - RegLo) + 1);
2722   return true;
2723 }
2724 
2725 unsigned AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
2726                                           unsigned &RegNum, unsigned &RegWidth,
2727                                           SmallVectorImpl<AsmToken> &Tokens) {
2728   assert(isToken(AsmToken::Identifier));
2729   unsigned Reg = getSpecialRegForName(getTokenStr());
2730   if (Reg) {
2731     RegNum = 0;
2732     RegWidth = 32;
2733     RegKind = IS_SPECIAL;
2734     Tokens.push_back(getToken());
2735     lex(); // skip register name
2736   }
2737   return Reg;
2738 }
2739 
2740 unsigned AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
2741                                           unsigned &RegNum, unsigned &RegWidth,
2742                                           SmallVectorImpl<AsmToken> &Tokens) {
2743   assert(isToken(AsmToken::Identifier));
2744   StringRef RegName = getTokenStr();
2745   auto Loc = getLoc();
2746 
2747   const RegInfo *RI = getRegularRegInfo(RegName);
2748   if (!RI) {
2749     Error(Loc, "invalid register name");
2750     return AMDGPU::NoRegister;
2751   }
2752 
2753   Tokens.push_back(getToken());
2754   lex(); // skip register name
2755 
2756   RegKind = RI->Kind;
2757   StringRef RegSuffix = RegName.substr(RI->Name.size());
2758   unsigned SubReg = NoSubRegister;
2759   if (!RegSuffix.empty()) {
2760     // We don't know the opcode till we are done parsing, so we don't know if
2761     // registers should be 16 or 32 bit. It is therefore mandatory to put .l or
2762     // .h to correctly specify 16 bit registers. We also can't determine class
2763     // VGPR_16_Lo128 or VGPR_16, so always parse them as VGPR_16.
2764     if (RegSuffix.consume_back(".l"))
2765       SubReg = AMDGPU::lo16;
2766     else if (RegSuffix.consume_back(".h"))
2767       SubReg = AMDGPU::hi16;
2768 
2769     // Single 32-bit register: vXX.
2770     if (!getRegNum(RegSuffix, RegNum)) {
2771       Error(Loc, "invalid register index");
2772       return AMDGPU::NoRegister;
2773     }
2774     RegWidth = 32;
2775   } else {
2776     // Range of registers: v[XX:YY]. ":YY" is optional.
2777     if (!ParseRegRange(RegNum, RegWidth))
2778       return AMDGPU::NoRegister;
2779   }
2780 
2781   return getRegularReg(RegKind, RegNum, SubReg, RegWidth, Loc);
2782 }
2783 
2784 unsigned AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind, unsigned &RegNum,
2785                                        unsigned &RegWidth,
2786                                        SmallVectorImpl<AsmToken> &Tokens) {
2787   unsigned Reg = AMDGPU::NoRegister;
2788   auto ListLoc = getLoc();
2789 
2790   if (!skipToken(AsmToken::LBrac,
2791                  "expected a register or a list of registers")) {
2792     return AMDGPU::NoRegister;
2793   }
2794 
2795   // List of consecutive registers, e.g.: [s0,s1,s2,s3]
2796 
2797   auto Loc = getLoc();
2798   if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth))
2799     return AMDGPU::NoRegister;
2800   if (RegWidth != 32) {
2801     Error(Loc, "expected a single 32-bit register");
2802     return AMDGPU::NoRegister;
2803   }
2804 
2805   for (; trySkipToken(AsmToken::Comma); ) {
2806     RegisterKind NextRegKind;
2807     unsigned NextReg, NextRegNum, NextRegWidth;
2808     Loc = getLoc();
2809 
2810     if (!ParseAMDGPURegister(NextRegKind, NextReg,
2811                              NextRegNum, NextRegWidth,
2812                              Tokens)) {
2813       return AMDGPU::NoRegister;
2814     }
2815     if (NextRegWidth != 32) {
2816       Error(Loc, "expected a single 32-bit register");
2817       return AMDGPU::NoRegister;
2818     }
2819     if (NextRegKind != RegKind) {
2820       Error(Loc, "registers in a list must be of the same kind");
2821       return AMDGPU::NoRegister;
2822     }
2823     if (!AddNextRegisterToList(Reg, RegWidth, RegKind, NextReg, Loc))
2824       return AMDGPU::NoRegister;
2825   }
2826 
2827   if (!skipToken(AsmToken::RBrac,
2828                  "expected a comma or a closing square bracket")) {
2829     return AMDGPU::NoRegister;
2830   }
2831 
2832   if (isRegularReg(RegKind))
2833     Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
2834 
2835   return Reg;
2836 }
2837 
2838 bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind, unsigned &Reg,
2839                                           unsigned &RegNum, unsigned &RegWidth,
2840                                           SmallVectorImpl<AsmToken> &Tokens) {
2841   auto Loc = getLoc();
2842   Reg = AMDGPU::NoRegister;
2843 
2844   if (isToken(AsmToken::Identifier)) {
2845     Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
2846     if (Reg == AMDGPU::NoRegister)
2847       Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
2848   } else {
2849     Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
2850   }
2851 
2852   const MCRegisterInfo *TRI = getContext().getRegisterInfo();
2853   if (Reg == AMDGPU::NoRegister) {
2854     assert(Parser.hasPendingError());
2855     return false;
2856   }
2857 
2858   if (!subtargetHasRegister(*TRI, Reg)) {
2859     if (Reg == AMDGPU::SGPR_NULL) {
2860       Error(Loc, "'null' operand is not supported on this GPU");
2861     } else {
2862       Error(Loc, "register not available on this GPU");
2863     }
2864     return false;
2865   }
2866 
2867   return true;
2868 }
2869 
2870 bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind, unsigned &Reg,
2871                                           unsigned &RegNum, unsigned &RegWidth,
2872                                           bool RestoreOnFailure /*=false*/) {
2873   Reg = AMDGPU::NoRegister;
2874 
2875   SmallVector<AsmToken, 1> Tokens;
2876   if (ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth, Tokens)) {
2877     if (RestoreOnFailure) {
2878       while (!Tokens.empty()) {
2879         getLexer().UnLex(Tokens.pop_back_val());
2880       }
2881     }
2882     return true;
2883   }
2884   return false;
2885 }
2886 
2887 std::optional<StringRef>
2888 AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
2889   switch (RegKind) {
2890   case IS_VGPR:
2891     return StringRef(".amdgcn.next_free_vgpr");
2892   case IS_SGPR:
2893     return StringRef(".amdgcn.next_free_sgpr");
2894   default:
2895     return std::nullopt;
2896   }
2897 }
2898 
2899 void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
2900   auto SymbolName = getGprCountSymbolName(RegKind);
2901   assert(SymbolName && "initializing invalid register kind");
2902   MCSymbol *Sym = getContext().getOrCreateSymbol(*SymbolName);
2903   Sym->setVariableValue(MCConstantExpr::create(0, getContext()));
2904 }
2905 
2906 bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
2907                                             unsigned DwordRegIndex,
2908                                             unsigned RegWidth) {
2909   // Symbols are only defined for GCN targets
2910   if (AMDGPU::getIsaVersion(getSTI().getCPU()).Major < 6)
2911     return true;
2912 
2913   auto SymbolName = getGprCountSymbolName(RegKind);
2914   if (!SymbolName)
2915     return true;
2916   MCSymbol *Sym = getContext().getOrCreateSymbol(*SymbolName);
2917 
2918   int64_t NewMax = DwordRegIndex + divideCeil(RegWidth, 32) - 1;
2919   int64_t OldCount;
2920 
2921   if (!Sym->isVariable())
2922     return !Error(getLoc(),
2923                   ".amdgcn.next_free_{v,s}gpr symbols must be variable");
2924   if (!Sym->getVariableValue(false)->evaluateAsAbsolute(OldCount))
2925     return !Error(
2926         getLoc(),
2927         ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
2928 
2929   if (OldCount <= NewMax)
2930     Sym->setVariableValue(MCConstantExpr::create(NewMax + 1, getContext()));
2931 
2932   return true;
2933 }
2934 
2935 std::unique_ptr<AMDGPUOperand>
2936 AMDGPUAsmParser::parseRegister(bool RestoreOnFailure) {
2937   const auto &Tok = getToken();
2938   SMLoc StartLoc = Tok.getLoc();
2939   SMLoc EndLoc = Tok.getEndLoc();
2940   RegisterKind RegKind;
2941   unsigned Reg, RegNum, RegWidth;
2942 
2943   if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth)) {
2944     return nullptr;
2945   }
2946   if (isHsaAbi(getSTI())) {
2947     if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
2948       return nullptr;
2949   } else
2950     KernelScope.usesRegister(RegKind, RegNum, RegWidth);
2951   return AMDGPUOperand::CreateReg(this, Reg, StartLoc, EndLoc);
2952 }
2953 
2954 ParseStatus AMDGPUAsmParser::parseImm(OperandVector &Operands,
2955                                       bool HasSP3AbsModifier, bool HasLit) {
2956   // TODO: add syntactic sugar for 1/(2*PI)
2957 
2958   if (isRegister())
2959     return ParseStatus::NoMatch;
2960   assert(!isModifier());
2961 
2962   if (!HasLit) {
2963     HasLit = trySkipId("lit");
2964     if (HasLit) {
2965       if (!skipToken(AsmToken::LParen, "expected left paren after lit"))
2966         return ParseStatus::Failure;
2967       ParseStatus S = parseImm(Operands, HasSP3AbsModifier, HasLit);
2968       if (S.isSuccess() &&
2969           !skipToken(AsmToken::RParen, "expected closing parentheses"))
2970         return ParseStatus::Failure;
2971       return S;
2972     }
2973   }
2974 
2975   const auto& Tok = getToken();
2976   const auto& NextTok = peekToken();
2977   bool IsReal = Tok.is(AsmToken::Real);
2978   SMLoc S = getLoc();
2979   bool Negate = false;
2980 
2981   if (!IsReal && Tok.is(AsmToken::Minus) && NextTok.is(AsmToken::Real)) {
2982     lex();
2983     IsReal = true;
2984     Negate = true;
2985   }
2986 
2987   AMDGPUOperand::Modifiers Mods;
2988   Mods.Lit = HasLit;
2989 
2990   if (IsReal) {
2991     // Floating-point expressions are not supported.
2992     // Can only allow floating-point literals with an
2993     // optional sign.
2994 
2995     StringRef Num = getTokenStr();
2996     lex();
2997 
2998     APFloat RealVal(APFloat::IEEEdouble());
2999     auto roundMode = APFloat::rmNearestTiesToEven;
3000     if (errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3001       return ParseStatus::Failure;
3002     if (Negate)
3003       RealVal.changeSign();
3004 
3005     Operands.push_back(
3006       AMDGPUOperand::CreateImm(this, RealVal.bitcastToAPInt().getZExtValue(), S,
3007                                AMDGPUOperand::ImmTyNone, true));
3008     AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands.back());
3009     Op.setModifiers(Mods);
3010 
3011     return ParseStatus::Success;
3012 
3013   } else {
3014     int64_t IntVal;
3015     const MCExpr *Expr;
3016     SMLoc S = getLoc();
3017 
3018     if (HasSP3AbsModifier) {
3019       // This is a workaround for handling expressions
3020       // as arguments of SP3 'abs' modifier, for example:
3021       //     |1.0|
3022       //     |-1|
3023       //     |1+x|
3024       // This syntax is not compatible with syntax of standard
3025       // MC expressions (due to the trailing '|').
3026       SMLoc EndLoc;
3027       if (getParser().parsePrimaryExpr(Expr, EndLoc, nullptr))
3028         return ParseStatus::Failure;
3029     } else {
3030       if (Parser.parseExpression(Expr))
3031         return ParseStatus::Failure;
3032     }
3033 
3034     if (Expr->evaluateAsAbsolute(IntVal)) {
3035       Operands.push_back(AMDGPUOperand::CreateImm(this, IntVal, S));
3036       AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands.back());
3037       Op.setModifiers(Mods);
3038     } else {
3039       if (HasLit)
3040         return ParseStatus::NoMatch;
3041       Operands.push_back(AMDGPUOperand::CreateExpr(this, Expr, S));
3042     }
3043 
3044     return ParseStatus::Success;
3045   }
3046 
3047   return ParseStatus::NoMatch;
3048 }
3049 
3050 ParseStatus AMDGPUAsmParser::parseReg(OperandVector &Operands) {
3051   if (!isRegister())
3052     return ParseStatus::NoMatch;
3053 
3054   if (auto R = parseRegister()) {
3055     assert(R->isReg());
3056     Operands.push_back(std::move(R));
3057     return ParseStatus::Success;
3058   }
3059   return ParseStatus::Failure;
3060 }
3061 
3062 ParseStatus AMDGPUAsmParser::parseRegOrImm(OperandVector &Operands,
3063                                            bool HasSP3AbsMod, bool HasLit) {
3064   ParseStatus Res = parseReg(Operands);
3065   if (!Res.isNoMatch())
3066     return Res;
3067   if (isModifier())
3068     return ParseStatus::NoMatch;
3069   return parseImm(Operands, HasSP3AbsMod, HasLit);
3070 }
3071 
3072 bool
3073 AMDGPUAsmParser::isNamedOperandModifier(const AsmToken &Token, const AsmToken &NextToken) const {
3074   if (Token.is(AsmToken::Identifier) && NextToken.is(AsmToken::LParen)) {
3075     const auto &str = Token.getString();
3076     return str == "abs" || str == "neg" || str == "sext";
3077   }
3078   return false;
3079 }
3080 
3081 bool
3082 AMDGPUAsmParser::isOpcodeModifierWithVal(const AsmToken &Token, const AsmToken &NextToken) const {
3083   return Token.is(AsmToken::Identifier) && NextToken.is(AsmToken::Colon);
3084 }
3085 
3086 bool
3087 AMDGPUAsmParser::isOperandModifier(const AsmToken &Token, const AsmToken &NextToken) const {
3088   return isNamedOperandModifier(Token, NextToken) || Token.is(AsmToken::Pipe);
3089 }
3090 
3091 bool
3092 AMDGPUAsmParser::isRegOrOperandModifier(const AsmToken &Token, const AsmToken &NextToken) const {
3093   return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3094 }
3095 
3096 // Check if this is an operand modifier or an opcode modifier
3097 // which may look like an expression but it is not. We should
3098 // avoid parsing these modifiers as expressions. Currently
3099 // recognized sequences are:
3100 //   |...|
3101 //   abs(...)
3102 //   neg(...)
3103 //   sext(...)
3104 //   -reg
3105 //   -|...|
3106 //   -abs(...)
3107 //   name:...
3108 //
3109 bool
3110 AMDGPUAsmParser::isModifier() {
3111 
3112   AsmToken Tok = getToken();
3113   AsmToken NextToken[2];
3114   peekTokens(NextToken);
3115 
3116   return isOperandModifier(Tok, NextToken[0]) ||
3117          (Tok.is(AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3118          isOpcodeModifierWithVal(Tok, NextToken[0]);
3119 }
3120 
3121 // Check if the current token is an SP3 'neg' modifier.
3122 // Currently this modifier is allowed in the following context:
3123 //
3124 // 1. Before a register, e.g. "-v0", "-v[...]" or "-[v0,v1]".
3125 // 2. Before an 'abs' modifier: -abs(...)
3126 // 3. Before an SP3 'abs' modifier: -|...|
3127 //
3128 // In all other cases "-" is handled as a part
3129 // of an expression that follows the sign.
3130 //
3131 // Note: When "-" is followed by an integer literal,
3132 // this is interpreted as integer negation rather
3133 // than a floating-point NEG modifier applied to N.
3134 // Beside being contr-intuitive, such use of floating-point
3135 // NEG modifier would have resulted in different meaning
3136 // of integer literals used with VOP1/2/C and VOP3,
3137 // for example:
3138 //    v_exp_f32_e32 v5, -1 // VOP1: src0 = 0xFFFFFFFF
3139 //    v_exp_f32_e64 v5, -1 // VOP3: src0 = 0x80000001
3140 // Negative fp literals with preceding "-" are
3141 // handled likewise for uniformity
3142 //
3143 bool
3144 AMDGPUAsmParser::parseSP3NegModifier() {
3145 
3146   AsmToken NextToken[2];
3147   peekTokens(NextToken);
3148 
3149   if (isToken(AsmToken::Minus) &&
3150       (isRegister(NextToken[0], NextToken[1]) ||
3151        NextToken[0].is(AsmToken::Pipe) ||
3152        isId(NextToken[0], "abs"))) {
3153     lex();
3154     return true;
3155   }
3156 
3157   return false;
3158 }
3159 
3160 ParseStatus
3161 AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
3162                                               bool AllowImm) {
3163   bool Neg, SP3Neg;
3164   bool Abs, SP3Abs;
3165   bool Lit;
3166   SMLoc Loc;
3167 
3168   // Disable ambiguous constructs like '--1' etc. Should use neg(-1) instead.
3169   if (isToken(AsmToken::Minus) && peekToken().is(AsmToken::Minus))
3170     return Error(getLoc(), "invalid syntax, expected 'neg' modifier");
3171 
3172   SP3Neg = parseSP3NegModifier();
3173 
3174   Loc = getLoc();
3175   Neg = trySkipId("neg");
3176   if (Neg && SP3Neg)
3177     return Error(Loc, "expected register or immediate");
3178   if (Neg && !skipToken(AsmToken::LParen, "expected left paren after neg"))
3179     return ParseStatus::Failure;
3180 
3181   Abs = trySkipId("abs");
3182   if (Abs && !skipToken(AsmToken::LParen, "expected left paren after abs"))
3183     return ParseStatus::Failure;
3184 
3185   Lit = trySkipId("lit");
3186   if (Lit && !skipToken(AsmToken::LParen, "expected left paren after lit"))
3187     return ParseStatus::Failure;
3188 
3189   Loc = getLoc();
3190   SP3Abs = trySkipToken(AsmToken::Pipe);
3191   if (Abs && SP3Abs)
3192     return Error(Loc, "expected register or immediate");
3193 
3194   ParseStatus Res;
3195   if (AllowImm) {
3196     Res = parseRegOrImm(Operands, SP3Abs, Lit);
3197   } else {
3198     Res = parseReg(Operands);
3199   }
3200   if (!Res.isSuccess())
3201     return (SP3Neg || Neg || SP3Abs || Abs || Lit) ? ParseStatus::Failure : Res;
3202 
3203   if (Lit && !Operands.back()->isImm())
3204     Error(Loc, "expected immediate with lit modifier");
3205 
3206   if (SP3Abs && !skipToken(AsmToken::Pipe, "expected vertical bar"))
3207     return ParseStatus::Failure;
3208   if (Abs && !skipToken(AsmToken::RParen, "expected closing parentheses"))
3209     return ParseStatus::Failure;
3210   if (Neg && !skipToken(AsmToken::RParen, "expected closing parentheses"))
3211     return ParseStatus::Failure;
3212   if (Lit && !skipToken(AsmToken::RParen, "expected closing parentheses"))
3213     return ParseStatus::Failure;
3214 
3215   AMDGPUOperand::Modifiers Mods;
3216   Mods.Abs = Abs || SP3Abs;
3217   Mods.Neg = Neg || SP3Neg;
3218   Mods.Lit = Lit;
3219 
3220   if (Mods.hasFPModifiers() || Lit) {
3221     AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands.back());
3222     if (Op.isExpr())
3223       return Error(Op.getStartLoc(), "expected an absolute expression");
3224     Op.setModifiers(Mods);
3225   }
3226   return ParseStatus::Success;
3227 }
3228 
3229 ParseStatus
3230 AMDGPUAsmParser::parseRegOrImmWithIntInputMods(OperandVector &Operands,
3231                                                bool AllowImm) {
3232   bool Sext = trySkipId("sext");
3233   if (Sext && !skipToken(AsmToken::LParen, "expected left paren after sext"))
3234     return ParseStatus::Failure;
3235 
3236   ParseStatus Res;
3237   if (AllowImm) {
3238     Res = parseRegOrImm(Operands);
3239   } else {
3240     Res = parseReg(Operands);
3241   }
3242   if (!Res.isSuccess())
3243     return Sext ? ParseStatus::Failure : Res;
3244 
3245   if (Sext && !skipToken(AsmToken::RParen, "expected closing parentheses"))
3246     return ParseStatus::Failure;
3247 
3248   AMDGPUOperand::Modifiers Mods;
3249   Mods.Sext = Sext;
3250 
3251   if (Mods.hasIntModifiers()) {
3252     AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands.back());
3253     if (Op.isExpr())
3254       return Error(Op.getStartLoc(), "expected an absolute expression");
3255     Op.setModifiers(Mods);
3256   }
3257 
3258   return ParseStatus::Success;
3259 }
3260 
3261 ParseStatus AMDGPUAsmParser::parseRegWithFPInputMods(OperandVector &Operands) {
3262   return parseRegOrImmWithFPInputMods(Operands, false);
3263 }
3264 
3265 ParseStatus AMDGPUAsmParser::parseRegWithIntInputMods(OperandVector &Operands) {
3266   return parseRegOrImmWithIntInputMods(Operands, false);
3267 }
3268 
3269 ParseStatus AMDGPUAsmParser::parseVReg32OrOff(OperandVector &Operands) {
3270   auto Loc = getLoc();
3271   if (trySkipId("off")) {
3272     Operands.push_back(AMDGPUOperand::CreateImm(this, 0, Loc,
3273                                                 AMDGPUOperand::ImmTyOff, false));
3274     return ParseStatus::Success;
3275   }
3276 
3277   if (!isRegister())
3278     return ParseStatus::NoMatch;
3279 
3280   std::unique_ptr<AMDGPUOperand> Reg = parseRegister();
3281   if (Reg) {
3282     Operands.push_back(std::move(Reg));
3283     return ParseStatus::Success;
3284   }
3285 
3286   return ParseStatus::Failure;
3287 }
3288 
3289 unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3290   uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
3291 
3292   if ((getForcedEncodingSize() == 32 && (TSFlags & SIInstrFlags::VOP3)) ||
3293       (getForcedEncodingSize() == 64 && !(TSFlags & SIInstrFlags::VOP3)) ||
3294       (isForcedDPP() && !(TSFlags & SIInstrFlags::DPP)) ||
3295       (isForcedSDWA() && !(TSFlags & SIInstrFlags::SDWA)) )
3296     return Match_InvalidOperand;
3297 
3298   if ((TSFlags & SIInstrFlags::VOP3) &&
3299       (TSFlags & SIInstrFlags::VOPAsmPrefer32Bit) &&
3300       getForcedEncodingSize() != 64)
3301     return Match_PreferE32;
3302 
3303   if (Inst.getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3304       Inst.getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3305     // v_mac_f32/16 allow only dst_sel == DWORD;
3306     auto OpNum =
3307         AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::dst_sel);
3308     const auto &Op = Inst.getOperand(OpNum);
3309     if (!Op.isImm() || Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3310       return Match_InvalidOperand;
3311     }
3312   }
3313 
3314   return Match_Success;
3315 }
3316 
3317 static ArrayRef<unsigned> getAllVariants() {
3318   static const unsigned Variants[] = {
3319     AMDGPUAsmVariants::DEFAULT, AMDGPUAsmVariants::VOP3,
3320     AMDGPUAsmVariants::SDWA, AMDGPUAsmVariants::SDWA9,
3321     AMDGPUAsmVariants::DPP, AMDGPUAsmVariants::VOP3_DPP
3322   };
3323 
3324   return ArrayRef(Variants);
3325 }
3326 
3327 // What asm variants we should check
3328 ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants() const {
3329   if (isForcedDPP() && isForcedVOP3()) {
3330     static const unsigned Variants[] = {AMDGPUAsmVariants::VOP3_DPP};
3331     return ArrayRef(Variants);
3332   }
3333   if (getForcedEncodingSize() == 32) {
3334     static const unsigned Variants[] = {AMDGPUAsmVariants::DEFAULT};
3335     return ArrayRef(Variants);
3336   }
3337 
3338   if (isForcedVOP3()) {
3339     static const unsigned Variants[] = {AMDGPUAsmVariants::VOP3};
3340     return ArrayRef(Variants);
3341   }
3342 
3343   if (isForcedSDWA()) {
3344     static const unsigned Variants[] = {AMDGPUAsmVariants::SDWA,
3345                                         AMDGPUAsmVariants::SDWA9};
3346     return ArrayRef(Variants);
3347   }
3348 
3349   if (isForcedDPP()) {
3350     static const unsigned Variants[] = {AMDGPUAsmVariants::DPP};
3351     return ArrayRef(Variants);
3352   }
3353 
3354   return getAllVariants();
3355 }
3356 
3357 StringRef AMDGPUAsmParser::getMatchedVariantName() const {
3358   if (isForcedDPP() && isForcedVOP3())
3359     return "e64_dpp";
3360 
3361   if (getForcedEncodingSize() == 32)
3362     return "e32";
3363 
3364   if (isForcedVOP3())
3365     return "e64";
3366 
3367   if (isForcedSDWA())
3368     return "sdwa";
3369 
3370   if (isForcedDPP())
3371     return "dpp";
3372 
3373   return "";
3374 }
3375 
3376 unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(const MCInst &Inst) const {
3377   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
3378   for (MCPhysReg Reg : Desc.implicit_uses()) {
3379     switch (Reg) {
3380     case AMDGPU::FLAT_SCR:
3381     case AMDGPU::VCC:
3382     case AMDGPU::VCC_LO:
3383     case AMDGPU::VCC_HI:
3384     case AMDGPU::M0:
3385       return Reg;
3386     default:
3387       break;
3388     }
3389   }
3390   return AMDGPU::NoRegister;
3391 }
3392 
3393 // NB: This code is correct only when used to check constant
3394 // bus limitations because GFX7 support no f16 inline constants.
3395 // Note that there are no cases when a GFX7 opcode violates
3396 // constant bus limitations due to the use of an f16 constant.
3397 bool AMDGPUAsmParser::isInlineConstant(const MCInst &Inst,
3398                                        unsigned OpIdx) const {
3399   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
3400 
3401   if (!AMDGPU::isSISrcOperand(Desc, OpIdx) ||
3402       AMDGPU::isKImmOperand(Desc, OpIdx)) {
3403     return false;
3404   }
3405 
3406   const MCOperand &MO = Inst.getOperand(OpIdx);
3407 
3408   int64_t Val = MO.getImm();
3409   auto OpSize = AMDGPU::getOperandSize(Desc, OpIdx);
3410 
3411   switch (OpSize) { // expected operand size
3412   case 8:
3413     return AMDGPU::isInlinableLiteral64(Val, hasInv2PiInlineImm());
3414   case 4:
3415     return AMDGPU::isInlinableLiteral32(Val, hasInv2PiInlineImm());
3416   case 2: {
3417     const unsigned OperandType = Desc.operands()[OpIdx].OperandType;
3418     if (OperandType == AMDGPU::OPERAND_REG_IMM_INT16 ||
3419         OperandType == AMDGPU::OPERAND_REG_INLINE_C_INT16 ||
3420         OperandType == AMDGPU::OPERAND_REG_INLINE_AC_INT16)
3421       return AMDGPU::isInlinableIntLiteral(Val);
3422 
3423     if (OperandType == AMDGPU::OPERAND_REG_INLINE_C_V2INT16 ||
3424         OperandType == AMDGPU::OPERAND_REG_INLINE_AC_V2INT16 ||
3425         OperandType == AMDGPU::OPERAND_REG_IMM_V2INT16)
3426       return AMDGPU::isInlinableLiteralV2I16(Val);
3427 
3428     if (OperandType == AMDGPU::OPERAND_REG_INLINE_C_V2FP16 ||
3429         OperandType == AMDGPU::OPERAND_REG_INLINE_AC_V2FP16 ||
3430         OperandType == AMDGPU::OPERAND_REG_IMM_V2FP16)
3431       return AMDGPU::isInlinableLiteralV2F16(Val);
3432 
3433     return AMDGPU::isInlinableLiteral16(Val, hasInv2PiInlineImm());
3434   }
3435   default:
3436     llvm_unreachable("invalid operand size");
3437   }
3438 }
3439 
3440 unsigned AMDGPUAsmParser::getConstantBusLimit(unsigned Opcode) const {
3441   if (!isGFX10Plus())
3442     return 1;
3443 
3444   switch (Opcode) {
3445   // 64-bit shift instructions can use only one scalar value input
3446   case AMDGPU::V_LSHLREV_B64_e64:
3447   case AMDGPU::V_LSHLREV_B64_gfx10:
3448   case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3449   case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3450   case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3451   case AMDGPU::V_LSHRREV_B64_e64:
3452   case AMDGPU::V_LSHRREV_B64_gfx10:
3453   case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3454   case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3455   case AMDGPU::V_ASHRREV_I64_e64:
3456   case AMDGPU::V_ASHRREV_I64_gfx10:
3457   case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3458   case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3459   case AMDGPU::V_LSHL_B64_e64:
3460   case AMDGPU::V_LSHR_B64_e64:
3461   case AMDGPU::V_ASHR_I64_e64:
3462     return 1;
3463   default:
3464     return 2;
3465   }
3466 }
3467 
3468 constexpr unsigned MAX_SRC_OPERANDS_NUM = 6;
3469 using OperandIndices = SmallVector<int16_t, MAX_SRC_OPERANDS_NUM>;
3470 
3471 // Get regular operand indices in the same order as specified
3472 // in the instruction (but append mandatory literals to the end).
3473 static OperandIndices getSrcOperandIndices(unsigned Opcode,
3474                                            bool AddMandatoryLiterals = false) {
3475 
3476   int16_t ImmIdx =
3477       AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3478 
3479   if (isVOPD(Opcode)) {
3480     int16_t ImmDeferredIdx =
3481         AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immDeferred)
3482                              : -1;
3483 
3484     return {getNamedOperandIdx(Opcode, OpName::src0X),
3485             getNamedOperandIdx(Opcode, OpName::vsrc1X),
3486             getNamedOperandIdx(Opcode, OpName::src0Y),
3487             getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3488             ImmDeferredIdx,
3489             ImmIdx};
3490   }
3491 
3492   return {getNamedOperandIdx(Opcode, OpName::src0),
3493           getNamedOperandIdx(Opcode, OpName::src1),
3494           getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3495 }
3496 
3497 bool AMDGPUAsmParser::usesConstantBus(const MCInst &Inst, unsigned OpIdx) {
3498   const MCOperand &MO = Inst.getOperand(OpIdx);
3499   if (MO.isImm()) {
3500     return !isInlineConstant(Inst, OpIdx);
3501   } else if (MO.isReg()) {
3502     auto Reg = MO.getReg();
3503     const MCRegisterInfo *TRI = getContext().getRegisterInfo();
3504     auto PReg = mc2PseudoReg(Reg);
3505     return isSGPR(PReg, TRI) && PReg != SGPR_NULL;
3506   } else {
3507     return true;
3508   }
3509 }
3510 
3511 bool AMDGPUAsmParser::validateConstantBusLimitations(
3512     const MCInst &Inst, const OperandVector &Operands) {
3513   const unsigned Opcode = Inst.getOpcode();
3514   const MCInstrDesc &Desc = MII.get(Opcode);
3515   unsigned LastSGPR = AMDGPU::NoRegister;
3516   unsigned ConstantBusUseCount = 0;
3517   unsigned NumLiterals = 0;
3518   unsigned LiteralSize;
3519 
3520   if (!(Desc.TSFlags &
3521         (SIInstrFlags::VOPC | SIInstrFlags::VOP1 | SIInstrFlags::VOP2 |
3522          SIInstrFlags::VOP3 | SIInstrFlags::VOP3P | SIInstrFlags::SDWA)) &&
3523       !isVOPD(Opcode))
3524     return true;
3525 
3526   // Check special imm operands (used by madmk, etc)
3527   if (AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::imm)) {
3528     ++NumLiterals;
3529     LiteralSize = 4;
3530   }
3531 
3532   SmallDenseSet<unsigned> SGPRsUsed;
3533   unsigned SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3534   if (SGPRUsed != AMDGPU::NoRegister) {
3535     SGPRsUsed.insert(SGPRUsed);
3536     ++ConstantBusUseCount;
3537   }
3538 
3539   OperandIndices OpIndices = getSrcOperandIndices(Opcode);
3540 
3541   for (int OpIdx : OpIndices) {
3542     if (OpIdx == -1)
3543       continue;
3544 
3545     const MCOperand &MO = Inst.getOperand(OpIdx);
3546     if (usesConstantBus(Inst, OpIdx)) {
3547       if (MO.isReg()) {
3548         LastSGPR = mc2PseudoReg(MO.getReg());
3549         // Pairs of registers with a partial intersections like these
3550         //   s0, s[0:1]
3551         //   flat_scratch_lo, flat_scratch
3552         //   flat_scratch_lo, flat_scratch_hi
3553         // are theoretically valid but they are disabled anyway.
3554         // Note that this code mimics SIInstrInfo::verifyInstruction
3555         if (SGPRsUsed.insert(LastSGPR).second) {
3556           ++ConstantBusUseCount;
3557         }
3558       } else { // Expression or a literal
3559 
3560         if (Desc.operands()[OpIdx].OperandType == MCOI::OPERAND_IMMEDIATE)
3561           continue; // special operand like VINTERP attr_chan
3562 
3563         // An instruction may use only one literal.
3564         // This has been validated on the previous step.
3565         // See validateVOPLiteral.
3566         // This literal may be used as more than one operand.
3567         // If all these operands are of the same size,
3568         // this literal counts as one scalar value.
3569         // Otherwise it counts as 2 scalar values.
3570         // See "GFX10 Shader Programming", section 3.6.2.3.
3571 
3572         unsigned Size = AMDGPU::getOperandSize(Desc, OpIdx);
3573         if (Size < 4)
3574           Size = 4;
3575 
3576         if (NumLiterals == 0) {
3577           NumLiterals = 1;
3578           LiteralSize = Size;
3579         } else if (LiteralSize != Size) {
3580           NumLiterals = 2;
3581         }
3582       }
3583     }
3584   }
3585   ConstantBusUseCount += NumLiterals;
3586 
3587   if (ConstantBusUseCount <= getConstantBusLimit(Opcode))
3588     return true;
3589 
3590   SMLoc LitLoc = getLitLoc(Operands);
3591   SMLoc RegLoc = getRegLoc(LastSGPR, Operands);
3592   SMLoc Loc = (LitLoc.getPointer() < RegLoc.getPointer()) ? RegLoc : LitLoc;
3593   Error(Loc, "invalid operand (violates constant bus restrictions)");
3594   return false;
3595 }
3596 
3597 bool AMDGPUAsmParser::validateVOPDRegBankConstraints(
3598     const MCInst &Inst, const OperandVector &Operands) {
3599 
3600   const unsigned Opcode = Inst.getOpcode();
3601   if (!isVOPD(Opcode))
3602     return true;
3603 
3604   const MCRegisterInfo *TRI = getContext().getRegisterInfo();
3605 
3606   auto getVRegIdx = [&](unsigned, unsigned OperandIdx) {
3607     const MCOperand &Opr = Inst.getOperand(OperandIdx);
3608     return (Opr.isReg() && !isSGPR(mc2PseudoReg(Opr.getReg()), TRI))
3609                ? Opr.getReg()
3610                : MCRegister::NoRegister;
3611   };
3612 
3613   // On GFX12 if both OpX and OpY are V_MOV_B32 then OPY uses SRC2 source-cache.
3614   bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12;
3615 
3616   const auto &InstInfo = getVOPDInstInfo(Opcode, &MII);
3617   auto InvalidCompOprIdx =
3618       InstInfo.getInvalidCompOperandIndex(getVRegIdx, SkipSrc);
3619   if (!InvalidCompOprIdx)
3620     return true;
3621 
3622   auto CompOprIdx = *InvalidCompOprIdx;
3623   auto ParsedIdx =
3624       std::max(InstInfo[VOPD::X].getIndexInParsedOperands(CompOprIdx),
3625                InstInfo[VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3626   assert(ParsedIdx > 0 && ParsedIdx < Operands.size());
3627 
3628   auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
3629   if (CompOprIdx == VOPD::Component::DST) {
3630     Error(Loc, "one dst register must be even and the other odd");
3631   } else {
3632     auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
3633     Error(Loc, Twine("src") + Twine(CompSrcIdx) +
3634                    " operands must use different VGPR banks");
3635   }
3636 
3637   return false;
3638 }
3639 
3640 bool AMDGPUAsmParser::validateIntClampSupported(const MCInst &Inst) {
3641 
3642   const unsigned Opc = Inst.getOpcode();
3643   const MCInstrDesc &Desc = MII.get(Opc);
3644 
3645   if ((Desc.TSFlags & SIInstrFlags::IntClamp) != 0 && !hasIntClamp()) {
3646     int ClampIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::clamp);
3647     assert(ClampIdx != -1);
3648     return Inst.getOperand(ClampIdx).getImm() == 0;
3649   }
3650 
3651   return true;
3652 }
3653 
3654 constexpr uint64_t MIMGFlags =
3655     SIInstrFlags::MIMG | SIInstrFlags::VIMAGE | SIInstrFlags::VSAMPLE;
3656 
3657 bool AMDGPUAsmParser::validateMIMGDataSize(const MCInst &Inst,
3658                                            const SMLoc &IDLoc) {
3659 
3660   const unsigned Opc = Inst.getOpcode();
3661   const MCInstrDesc &Desc = MII.get(Opc);
3662 
3663   if ((Desc.TSFlags & MIMGFlags) == 0)
3664     return true;
3665 
3666   int VDataIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdata);
3667   int DMaskIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dmask);
3668   int TFEIdx   = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::tfe);
3669 
3670   assert(VDataIdx != -1);
3671 
3672   if ((DMaskIdx == -1 || TFEIdx == -1) && isGFX10_AEncoding()) // intersect_ray
3673     return true;
3674 
3675   unsigned VDataSize = AMDGPU::getRegOperandSize(getMRI(), Desc, VDataIdx);
3676   unsigned TFESize = (TFEIdx != -1 && Inst.getOperand(TFEIdx).getImm()) ? 1 : 0;
3677   unsigned DMask = Inst.getOperand(DMaskIdx).getImm() & 0xf;
3678   if (DMask == 0)
3679     DMask = 1;
3680 
3681   bool IsPackedD16 = false;
3682   unsigned DataSize =
3683       (Desc.TSFlags & SIInstrFlags::Gather4) ? 4 : llvm::popcount(DMask);
3684   if (hasPackedD16()) {
3685     int D16Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::d16);
3686     IsPackedD16 = D16Idx >= 0;
3687     if (IsPackedD16 && Inst.getOperand(D16Idx).getImm())
3688       DataSize = (DataSize + 1) / 2;
3689   }
3690 
3691   if ((VDataSize / 4) == DataSize + TFESize)
3692     return true;
3693 
3694   StringRef Modifiers;
3695   if (isGFX90A())
3696     Modifiers = IsPackedD16 ? "dmask and d16" : "dmask";
3697   else
3698     Modifiers = IsPackedD16 ? "dmask, d16 and tfe" : "dmask and tfe";
3699 
3700   Error(IDLoc, Twine("image data size does not match ") + Modifiers);
3701   return false;
3702 }
3703 
3704 bool AMDGPUAsmParser::validateMIMGAddrSize(const MCInst &Inst,
3705                                            const SMLoc &IDLoc) {
3706   const unsigned Opc = Inst.getOpcode();
3707   const MCInstrDesc &Desc = MII.get(Opc);
3708 
3709   if ((Desc.TSFlags & MIMGFlags) == 0 || !isGFX10Plus())
3710     return true;
3711 
3712   const AMDGPU::MIMGInfo *Info = AMDGPU::getMIMGInfo(Opc);
3713 
3714   const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
3715       AMDGPU::getMIMGBaseOpcodeInfo(Info->BaseOpcode);
3716   int VAddr0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vaddr0);
3717   int RSrcOpName = Desc.TSFlags & SIInstrFlags::MIMG ? AMDGPU::OpName::srsrc
3718                                                      : AMDGPU::OpName::rsrc;
3719   int SrsrcIdx = AMDGPU::getNamedOperandIdx(Opc, RSrcOpName);
3720   int DimIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dim);
3721   int A16Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::a16);
3722 
3723   assert(VAddr0Idx != -1);
3724   assert(SrsrcIdx != -1);
3725   assert(SrsrcIdx > VAddr0Idx);
3726 
3727   bool IsA16 = (A16Idx != -1 && Inst.getOperand(A16Idx).getImm());
3728   if (BaseOpcode->BVH) {
3729     if (IsA16 == BaseOpcode->A16)
3730       return true;
3731     Error(IDLoc, "image address size does not match a16");
3732     return false;
3733   }
3734 
3735   unsigned Dim = Inst.getOperand(DimIdx).getImm();
3736   const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfoByEncoding(Dim);
3737   bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
3738   unsigned ActualAddrSize =
3739       IsNSA ? SrsrcIdx - VAddr0Idx
3740             : AMDGPU::getRegOperandSize(getMRI(), Desc, VAddr0Idx) / 4;
3741 
3742   unsigned ExpectedAddrSize =
3743       AMDGPU::getAddrSizeMIMGOp(BaseOpcode, DimInfo, IsA16, hasG16());
3744 
3745   if (IsNSA) {
3746     if (hasPartialNSAEncoding() &&
3747         ExpectedAddrSize >
3748             getNSAMaxSize(Desc.TSFlags & SIInstrFlags::VSAMPLE)) {
3749       int VAddrLastIdx = SrsrcIdx - 1;
3750       unsigned VAddrLastSize =
3751           AMDGPU::getRegOperandSize(getMRI(), Desc, VAddrLastIdx) / 4;
3752 
3753       ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
3754     }
3755   } else {
3756     if (ExpectedAddrSize > 12)
3757       ExpectedAddrSize = 16;
3758 
3759     // Allow oversized 8 VGPR vaddr when only 5/6/7 VGPRs are required.
3760     // This provides backward compatibility for assembly created
3761     // before 160b/192b/224b types were directly supported.
3762     if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
3763       return true;
3764   }
3765 
3766   if (ActualAddrSize == ExpectedAddrSize)
3767     return true;
3768 
3769   Error(IDLoc, "image address size does not match dim and a16");
3770   return false;
3771 }
3772 
3773 bool AMDGPUAsmParser::validateMIMGAtomicDMask(const MCInst &Inst) {
3774 
3775   const unsigned Opc = Inst.getOpcode();
3776   const MCInstrDesc &Desc = MII.get(Opc);
3777 
3778   if ((Desc.TSFlags & MIMGFlags) == 0)
3779     return true;
3780   if (!Desc.mayLoad() || !Desc.mayStore())
3781     return true; // Not atomic
3782 
3783   int DMaskIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dmask);
3784   unsigned DMask = Inst.getOperand(DMaskIdx).getImm() & 0xf;
3785 
3786   // This is an incomplete check because image_atomic_cmpswap
3787   // may only use 0x3 and 0xf while other atomic operations
3788   // may use 0x1 and 0x3. However these limitations are
3789   // verified when we check that dmask matches dst size.
3790   return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
3791 }
3792 
3793 bool AMDGPUAsmParser::validateMIMGGatherDMask(const MCInst &Inst) {
3794 
3795   const unsigned Opc = Inst.getOpcode();
3796   const MCInstrDesc &Desc = MII.get(Opc);
3797 
3798   if ((Desc.TSFlags & SIInstrFlags::Gather4) == 0)
3799     return true;
3800 
3801   int DMaskIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dmask);
3802   unsigned DMask = Inst.getOperand(DMaskIdx).getImm() & 0xf;
3803 
3804   // GATHER4 instructions use dmask in a different fashion compared to
3805   // other MIMG instructions. The only useful DMASK values are
3806   // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
3807   // (red,red,red,red) etc.) The ISA document doesn't mention
3808   // this.
3809   return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
3810 }
3811 
3812 bool AMDGPUAsmParser::validateMIMGMSAA(const MCInst &Inst) {
3813   const unsigned Opc = Inst.getOpcode();
3814   const MCInstrDesc &Desc = MII.get(Opc);
3815 
3816   if ((Desc.TSFlags & MIMGFlags) == 0)
3817     return true;
3818 
3819   const AMDGPU::MIMGInfo *Info = AMDGPU::getMIMGInfo(Opc);
3820   const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
3821       AMDGPU::getMIMGBaseOpcodeInfo(Info->BaseOpcode);
3822 
3823   if (!BaseOpcode->MSAA)
3824     return true;
3825 
3826   int DimIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dim);
3827   assert(DimIdx != -1);
3828 
3829   unsigned Dim = Inst.getOperand(DimIdx).getImm();
3830   const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfoByEncoding(Dim);
3831 
3832   return DimInfo->MSAA;
3833 }
3834 
3835 static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
3836 {
3837   switch (Opcode) {
3838   case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
3839   case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
3840   case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
3841     return true;
3842   default:
3843     return false;
3844   }
3845 }
3846 
3847 // movrels* opcodes should only allow VGPRS as src0.
3848 // This is specified in .td description for vop1/vop3,
3849 // but sdwa is handled differently. See isSDWAOperand.
3850 bool AMDGPUAsmParser::validateMovrels(const MCInst &Inst,
3851                                       const OperandVector &Operands) {
3852 
3853   const unsigned Opc = Inst.getOpcode();
3854   const MCInstrDesc &Desc = MII.get(Opc);
3855 
3856   if ((Desc.TSFlags & SIInstrFlags::SDWA) == 0 || !IsMovrelsSDWAOpcode(Opc))
3857     return true;
3858 
3859   const int Src0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0);
3860   assert(Src0Idx != -1);
3861 
3862   SMLoc ErrLoc;
3863   const MCOperand &Src0 = Inst.getOperand(Src0Idx);
3864   if (Src0.isReg()) {
3865     auto Reg = mc2PseudoReg(Src0.getReg());
3866     const MCRegisterInfo *TRI = getContext().getRegisterInfo();
3867     if (!isSGPR(Reg, TRI))
3868       return true;
3869     ErrLoc = getRegLoc(Reg, Operands);
3870   } else {
3871     ErrLoc = getConstLoc(Operands);
3872   }
3873 
3874   Error(ErrLoc, "source operand must be a VGPR");
3875   return false;
3876 }
3877 
3878 bool AMDGPUAsmParser::validateMAIAccWrite(const MCInst &Inst,
3879                                           const OperandVector &Operands) {
3880 
3881   const unsigned Opc = Inst.getOpcode();
3882 
3883   if (Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
3884     return true;
3885 
3886   const int Src0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0);
3887   assert(Src0Idx != -1);
3888 
3889   const MCOperand &Src0 = Inst.getOperand(Src0Idx);
3890   if (!Src0.isReg())
3891     return true;
3892 
3893   auto Reg = mc2PseudoReg(Src0.getReg());
3894   const MCRegisterInfo *TRI = getContext().getRegisterInfo();
3895   if (!isGFX90A() && isSGPR(Reg, TRI)) {
3896     Error(getRegLoc(Reg, Operands),
3897           "source operand must be either a VGPR or an inline constant");
3898     return false;
3899   }
3900 
3901   return true;
3902 }
3903 
3904 bool AMDGPUAsmParser::validateMAISrc2(const MCInst &Inst,
3905                                       const OperandVector &Operands) {
3906   unsigned Opcode = Inst.getOpcode();
3907   const MCInstrDesc &Desc = MII.get(Opcode);
3908 
3909   if (!(Desc.TSFlags & SIInstrFlags::IsMAI) ||
3910       !getFeatureBits()[FeatureMFMAInlineLiteralBug])
3911     return true;
3912 
3913   const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
3914   if (Src2Idx == -1)
3915     return true;
3916 
3917   if (Inst.getOperand(Src2Idx).isImm() && isInlineConstant(Inst, Src2Idx)) {
3918     Error(getConstLoc(Operands),
3919           "inline constants are not allowed for this operand");
3920     return false;
3921   }
3922 
3923   return true;
3924 }
3925 
3926 bool AMDGPUAsmParser::validateMFMA(const MCInst &Inst,
3927                                    const OperandVector &Operands) {
3928   const unsigned Opc = Inst.getOpcode();
3929   const MCInstrDesc &Desc = MII.get(Opc);
3930 
3931   if ((Desc.TSFlags & SIInstrFlags::IsMAI) == 0)
3932     return true;
3933 
3934   const int Src2Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2);
3935   if (Src2Idx == -1)
3936     return true;
3937 
3938   const MCOperand &Src2 = Inst.getOperand(Src2Idx);
3939   if (!Src2.isReg())
3940     return true;
3941 
3942   MCRegister Src2Reg = Src2.getReg();
3943   MCRegister DstReg = Inst.getOperand(0).getReg();
3944   if (Src2Reg == DstReg)
3945     return true;
3946 
3947   const MCRegisterInfo *TRI = getContext().getRegisterInfo();
3948   if (TRI->getRegClass(Desc.operands()[0].RegClass).getSizeInBits() <= 128)
3949     return true;
3950 
3951   if (TRI->regsOverlap(Src2Reg, DstReg)) {
3952     Error(getRegLoc(mc2PseudoReg(Src2Reg), Operands),
3953           "source 2 operand must not partially overlap with dst");
3954     return false;
3955   }
3956 
3957   return true;
3958 }
3959 
3960 bool AMDGPUAsmParser::validateDivScale(const MCInst &Inst) {
3961   switch (Inst.getOpcode()) {
3962   default:
3963     return true;
3964   case V_DIV_SCALE_F32_gfx6_gfx7:
3965   case V_DIV_SCALE_F32_vi:
3966   case V_DIV_SCALE_F32_gfx10:
3967   case V_DIV_SCALE_F64_gfx6_gfx7:
3968   case V_DIV_SCALE_F64_vi:
3969   case V_DIV_SCALE_F64_gfx10:
3970     break;
3971   }
3972 
3973   // TODO: Check that src0 = src1 or src2.
3974 
3975   for (auto Name : {AMDGPU::OpName::src0_modifiers,
3976                     AMDGPU::OpName::src2_modifiers,
3977                     AMDGPU::OpName::src2_modifiers}) {
3978     if (Inst.getOperand(AMDGPU::getNamedOperandIdx(Inst.getOpcode(), Name))
3979             .getImm() &
3980         SISrcMods::ABS) {
3981       return false;
3982     }
3983   }
3984 
3985   return true;
3986 }
3987 
3988 bool AMDGPUAsmParser::validateMIMGD16(const MCInst &Inst) {
3989 
3990   const unsigned Opc = Inst.getOpcode();
3991   const MCInstrDesc &Desc = MII.get(Opc);
3992 
3993   if ((Desc.TSFlags & MIMGFlags) == 0)
3994     return true;
3995 
3996   int D16Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::d16);
3997   if (D16Idx >= 0 && Inst.getOperand(D16Idx).getImm()) {
3998     if (isCI() || isSI())
3999       return false;
4000   }
4001 
4002   return true;
4003 }
4004 
4005 static bool IsRevOpcode(const unsigned Opcode)
4006 {
4007   switch (Opcode) {
4008   case AMDGPU::V_SUBREV_F32_e32:
4009   case AMDGPU::V_SUBREV_F32_e64:
4010   case AMDGPU::V_SUBREV_F32_e32_gfx10:
4011   case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4012   case AMDGPU::V_SUBREV_F32_e32_vi:
4013   case AMDGPU::V_SUBREV_F32_e64_gfx10:
4014   case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4015   case AMDGPU::V_SUBREV_F32_e64_vi:
4016 
4017   case AMDGPU::V_SUBREV_CO_U32_e32:
4018   case AMDGPU::V_SUBREV_CO_U32_e64:
4019   case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4020   case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4021 
4022   case AMDGPU::V_SUBBREV_U32_e32:
4023   case AMDGPU::V_SUBBREV_U32_e64:
4024   case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4025   case AMDGPU::V_SUBBREV_U32_e32_vi:
4026   case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4027   case AMDGPU::V_SUBBREV_U32_e64_vi:
4028 
4029   case AMDGPU::V_SUBREV_U32_e32:
4030   case AMDGPU::V_SUBREV_U32_e64:
4031   case AMDGPU::V_SUBREV_U32_e32_gfx9:
4032   case AMDGPU::V_SUBREV_U32_e32_vi:
4033   case AMDGPU::V_SUBREV_U32_e64_gfx9:
4034   case AMDGPU::V_SUBREV_U32_e64_vi:
4035 
4036   case AMDGPU::V_SUBREV_F16_e32:
4037   case AMDGPU::V_SUBREV_F16_e64:
4038   case AMDGPU::V_SUBREV_F16_e32_gfx10:
4039   case AMDGPU::V_SUBREV_F16_e32_vi:
4040   case AMDGPU::V_SUBREV_F16_e64_gfx10:
4041   case AMDGPU::V_SUBREV_F16_e64_vi:
4042 
4043   case AMDGPU::V_SUBREV_U16_e32:
4044   case AMDGPU::V_SUBREV_U16_e64:
4045   case AMDGPU::V_SUBREV_U16_e32_vi:
4046   case AMDGPU::V_SUBREV_U16_e64_vi:
4047 
4048   case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4049   case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4050   case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4051 
4052   case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4053   case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4054 
4055   case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4056   case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4057 
4058   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4059   case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4060 
4061   case AMDGPU::V_LSHRREV_B32_e32:
4062   case AMDGPU::V_LSHRREV_B32_e64:
4063   case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4064   case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4065   case AMDGPU::V_LSHRREV_B32_e32_vi:
4066   case AMDGPU::V_LSHRREV_B32_e64_vi:
4067   case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4068   case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4069 
4070   case AMDGPU::V_ASHRREV_I32_e32:
4071   case AMDGPU::V_ASHRREV_I32_e64:
4072   case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4073   case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4074   case AMDGPU::V_ASHRREV_I32_e32_vi:
4075   case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4076   case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4077   case AMDGPU::V_ASHRREV_I32_e64_vi:
4078 
4079   case AMDGPU::V_LSHLREV_B32_e32:
4080   case AMDGPU::V_LSHLREV_B32_e64:
4081   case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4082   case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4083   case AMDGPU::V_LSHLREV_B32_e32_vi:
4084   case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4085   case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4086   case AMDGPU::V_LSHLREV_B32_e64_vi:
4087 
4088   case AMDGPU::V_LSHLREV_B16_e32:
4089   case AMDGPU::V_LSHLREV_B16_e64:
4090   case AMDGPU::V_LSHLREV_B16_e32_vi:
4091   case AMDGPU::V_LSHLREV_B16_e64_vi:
4092   case AMDGPU::V_LSHLREV_B16_gfx10:
4093 
4094   case AMDGPU::V_LSHRREV_B16_e32:
4095   case AMDGPU::V_LSHRREV_B16_e64:
4096   case AMDGPU::V_LSHRREV_B16_e32_vi:
4097   case AMDGPU::V_LSHRREV_B16_e64_vi:
4098   case AMDGPU::V_LSHRREV_B16_gfx10:
4099 
4100   case AMDGPU::V_ASHRREV_I16_e32:
4101   case AMDGPU::V_ASHRREV_I16_e64:
4102   case AMDGPU::V_ASHRREV_I16_e32_vi:
4103   case AMDGPU::V_ASHRREV_I16_e64_vi:
4104   case AMDGPU::V_ASHRREV_I16_gfx10:
4105 
4106   case AMDGPU::V_LSHLREV_B64_e64:
4107   case AMDGPU::V_LSHLREV_B64_gfx10:
4108   case AMDGPU::V_LSHLREV_B64_vi:
4109 
4110   case AMDGPU::V_LSHRREV_B64_e64:
4111   case AMDGPU::V_LSHRREV_B64_gfx10:
4112   case AMDGPU::V_LSHRREV_B64_vi:
4113 
4114   case AMDGPU::V_ASHRREV_I64_e64:
4115   case AMDGPU::V_ASHRREV_I64_gfx10:
4116   case AMDGPU::V_ASHRREV_I64_vi:
4117 
4118   case AMDGPU::V_PK_LSHLREV_B16:
4119   case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4120   case AMDGPU::V_PK_LSHLREV_B16_vi:
4121 
4122   case AMDGPU::V_PK_LSHRREV_B16:
4123   case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4124   case AMDGPU::V_PK_LSHRREV_B16_vi:
4125   case AMDGPU::V_PK_ASHRREV_I16:
4126   case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4127   case AMDGPU::V_PK_ASHRREV_I16_vi:
4128     return true;
4129   default:
4130     return false;
4131   }
4132 }
4133 
4134 std::optional<StringRef>
4135 AMDGPUAsmParser::validateLdsDirect(const MCInst &Inst) {
4136 
4137   using namespace SIInstrFlags;
4138   const unsigned Opcode = Inst.getOpcode();
4139   const MCInstrDesc &Desc = MII.get(Opcode);
4140 
4141   // lds_direct register is defined so that it can be used
4142   // with 9-bit operands only. Ignore encodings which do not accept these.
4143   const auto Enc = VOP1 | VOP2 | VOP3 | VOPC | VOP3P | SIInstrFlags::SDWA;
4144   if ((Desc.TSFlags & Enc) == 0)
4145     return std::nullopt;
4146 
4147   for (auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4148     auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4149     if (SrcIdx == -1)
4150       break;
4151     const auto &Src = Inst.getOperand(SrcIdx);
4152     if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4153 
4154       if (isGFX90A() || isGFX11Plus())
4155         return StringRef("lds_direct is not supported on this GPU");
4156 
4157       if (IsRevOpcode(Opcode) || (Desc.TSFlags & SIInstrFlags::SDWA))
4158         return StringRef("lds_direct cannot be used with this instruction");
4159 
4160       if (SrcName != OpName::src0)
4161         return StringRef("lds_direct may be used as src0 only");
4162     }
4163   }
4164 
4165   return std::nullopt;
4166 }
4167 
4168 SMLoc AMDGPUAsmParser::getFlatOffsetLoc(const OperandVector &Operands) const {
4169   for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
4170     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
4171     if (Op.isFlatOffset())
4172       return Op.getStartLoc();
4173   }
4174   return getLoc();
4175 }
4176 
4177 bool AMDGPUAsmParser::validateOffset(const MCInst &Inst,
4178                                      const OperandVector &Operands) {
4179   auto Opcode = Inst.getOpcode();
4180   auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4181   if (OpNum == -1)
4182     return true;
4183 
4184   uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
4185   if ((TSFlags & SIInstrFlags::FLAT))
4186     return validateFlatOffset(Inst, Operands);
4187 
4188   if ((TSFlags & SIInstrFlags::SMRD))
4189     return validateSMEMOffset(Inst, Operands);
4190 
4191   const auto &Op = Inst.getOperand(OpNum);
4192   if (isGFX12Plus() &&
4193       (TSFlags & (SIInstrFlags::MUBUF | SIInstrFlags::MTBUF))) {
4194     const unsigned OffsetSize = 24;
4195     if (!isIntN(OffsetSize, Op.getImm())) {
4196       Error(getFlatOffsetLoc(Operands),
4197             Twine("expected a ") + Twine(OffsetSize) + "-bit signed offset");
4198       return false;
4199     }
4200   } else {
4201     const unsigned OffsetSize = 16;
4202     if (!isUIntN(OffsetSize, Op.getImm())) {
4203       Error(getFlatOffsetLoc(Operands),
4204             Twine("expected a ") + Twine(OffsetSize) + "-bit unsigned offset");
4205       return false;
4206     }
4207   }
4208   return true;
4209 }
4210 
4211 bool AMDGPUAsmParser::validateFlatOffset(const MCInst &Inst,
4212                                          const OperandVector &Operands) {
4213   uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
4214   if ((TSFlags & SIInstrFlags::FLAT) == 0)
4215     return true;
4216 
4217   auto Opcode = Inst.getOpcode();
4218   auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4219   assert(OpNum != -1);
4220 
4221   const auto &Op = Inst.getOperand(OpNum);
4222   if (!hasFlatOffsets() && Op.getImm() != 0) {
4223     Error(getFlatOffsetLoc(Operands),
4224           "flat offset modifier is not supported on this GPU");
4225     return false;
4226   }
4227 
4228   // For pre-GFX12 FLAT instructions the offset must be positive;
4229   // MSB is ignored and forced to zero.
4230   unsigned OffsetSize = AMDGPU::getNumFlatOffsetBits(getSTI());
4231   bool AllowNegative =
4232       (TSFlags & (SIInstrFlags::FlatGlobal | SIInstrFlags::FlatScratch)) ||
4233       isGFX12Plus();
4234   if (!isIntN(OffsetSize, Op.getImm()) || (!AllowNegative && Op.getImm() < 0)) {
4235     Error(getFlatOffsetLoc(Operands),
4236           Twine("expected a ") +
4237               (AllowNegative ? Twine(OffsetSize) + "-bit signed offset"
4238                              : Twine(OffsetSize - 1) + "-bit unsigned offset"));
4239     return false;
4240   }
4241 
4242   return true;
4243 }
4244 
4245 SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(const OperandVector &Operands) const {
4246   // Start with second operand because SMEM Offset cannot be dst or src0.
4247   for (unsigned i = 2, e = Operands.size(); i != e; ++i) {
4248     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
4249     if (Op.isSMEMOffset() || Op.isSMEMOffsetMod())
4250       return Op.getStartLoc();
4251   }
4252   return getLoc();
4253 }
4254 
4255 bool AMDGPUAsmParser::validateSMEMOffset(const MCInst &Inst,
4256                                          const OperandVector &Operands) {
4257   if (isCI() || isSI())
4258     return true;
4259 
4260   uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
4261   if ((TSFlags & SIInstrFlags::SMRD) == 0)
4262     return true;
4263 
4264   auto Opcode = Inst.getOpcode();
4265   auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4266   if (OpNum == -1)
4267     return true;
4268 
4269   const auto &Op = Inst.getOperand(OpNum);
4270   if (!Op.isImm())
4271     return true;
4272 
4273   uint64_t Offset = Op.getImm();
4274   bool IsBuffer = AMDGPU::getSMEMIsBuffer(Opcode);
4275   if (AMDGPU::isLegalSMRDEncodedUnsignedOffset(getSTI(), Offset) ||
4276       AMDGPU::isLegalSMRDEncodedSignedOffset(getSTI(), Offset, IsBuffer))
4277     return true;
4278 
4279   Error(getSMEMOffsetLoc(Operands),
4280         isGFX12Plus()          ? "expected a 24-bit signed offset"
4281         : (isVI() || IsBuffer) ? "expected a 20-bit unsigned offset"
4282                                : "expected a 21-bit signed offset");
4283 
4284   return false;
4285 }
4286 
4287 bool AMDGPUAsmParser::validateSOPLiteral(const MCInst &Inst) const {
4288   unsigned Opcode = Inst.getOpcode();
4289   const MCInstrDesc &Desc = MII.get(Opcode);
4290   if (!(Desc.TSFlags & (SIInstrFlags::SOP2 | SIInstrFlags::SOPC)))
4291     return true;
4292 
4293   const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4294   const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4295 
4296   const int OpIndices[] = { Src0Idx, Src1Idx };
4297 
4298   unsigned NumExprs = 0;
4299   unsigned NumLiterals = 0;
4300   uint32_t LiteralValue;
4301 
4302   for (int OpIdx : OpIndices) {
4303     if (OpIdx == -1) break;
4304 
4305     const MCOperand &MO = Inst.getOperand(OpIdx);
4306     // Exclude special imm operands (like that used by s_set_gpr_idx_on)
4307     if (AMDGPU::isSISrcOperand(Desc, OpIdx)) {
4308       if (MO.isImm() && !isInlineConstant(Inst, OpIdx)) {
4309         uint32_t Value = static_cast<uint32_t>(MO.getImm());
4310         if (NumLiterals == 0 || LiteralValue != Value) {
4311           LiteralValue = Value;
4312           ++NumLiterals;
4313         }
4314       } else if (MO.isExpr()) {
4315         ++NumExprs;
4316       }
4317     }
4318   }
4319 
4320   return NumLiterals + NumExprs <= 1;
4321 }
4322 
4323 bool AMDGPUAsmParser::validateOpSel(const MCInst &Inst) {
4324   const unsigned Opc = Inst.getOpcode();
4325   if (isPermlane16(Opc)) {
4326     int OpSelIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
4327     unsigned OpSel = Inst.getOperand(OpSelIdx).getImm();
4328 
4329     if (OpSel & ~3)
4330       return false;
4331   }
4332 
4333   uint64_t TSFlags = MII.get(Opc).TSFlags;
4334 
4335   if (isGFX940() && (TSFlags & SIInstrFlags::IsDOT)) {
4336     int OpSelIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
4337     if (OpSelIdx != -1) {
4338       if (Inst.getOperand(OpSelIdx).getImm() != 0)
4339         return false;
4340     }
4341     int OpSelHiIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel_hi);
4342     if (OpSelHiIdx != -1) {
4343       if (Inst.getOperand(OpSelHiIdx).getImm() != -1)
4344         return false;
4345     }
4346   }
4347 
4348   // op_sel[0:1] must be 0 for v_dot2_bf16_bf16 and v_dot2_f16_f16 (VOP3 Dot).
4349   if (isGFX11Plus() && (TSFlags & SIInstrFlags::IsDOT) &&
4350       (TSFlags & SIInstrFlags::VOP3) && !(TSFlags & SIInstrFlags::VOP3P)) {
4351     int OpSelIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
4352     unsigned OpSel = Inst.getOperand(OpSelIdx).getImm();
4353     if (OpSel & 3)
4354       return false;
4355   }
4356 
4357   return true;
4358 }
4359 
4360 bool AMDGPUAsmParser::validateNeg(const MCInst &Inst, int OpName) {
4361   assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
4362 
4363   const unsigned Opc = Inst.getOpcode();
4364   uint64_t TSFlags = MII.get(Opc).TSFlags;
4365 
4366   // v_dot4 fp8/bf8 neg_lo/neg_hi not allowed on src0 and src1 (allowed on src2)
4367   if (!(TSFlags & SIInstrFlags::IsDOT))
4368     return true;
4369 
4370   int NegIdx = AMDGPU::getNamedOperandIdx(Opc, OpName);
4371   if (NegIdx == -1)
4372     return true;
4373 
4374   unsigned Neg = Inst.getOperand(NegIdx).getImm();
4375 
4376   // Instructions that have neg_lo or neg_hi operand but neg modifier is allowed
4377   // on some src operands but not allowed on other.
4378   // It is convenient that such instructions don't have src_modifiers operand
4379   // for src operands that don't allow neg because they also don't allow opsel.
4380 
4381   int SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4382                     AMDGPU::OpName::src1_modifiers,
4383                     AMDGPU::OpName::src2_modifiers};
4384 
4385   for (unsigned i = 0; i < 3; ++i) {
4386     if (!AMDGPU::hasNamedOperand(Opc, SrcMods[i])) {
4387       if (Neg & (1 << i))
4388         return false;
4389     }
4390   }
4391 
4392   return true;
4393 }
4394 
4395 bool AMDGPUAsmParser::validateDPP(const MCInst &Inst,
4396                                   const OperandVector &Operands) {
4397   const unsigned Opc = Inst.getOpcode();
4398   int DppCtrlIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dpp_ctrl);
4399   if (DppCtrlIdx >= 0) {
4400     unsigned DppCtrl = Inst.getOperand(DppCtrlIdx).getImm();
4401 
4402     if (!AMDGPU::isLegalDPALU_DPPControl(DppCtrl) &&
4403         AMDGPU::isDPALU_DPP(MII.get(Opc))) {
4404       // DP ALU DPP is supported for row_newbcast only on GFX9*
4405       SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl, Operands);
4406       Error(S, "DP ALU dpp only supports row_newbcast");
4407       return false;
4408     }
4409   }
4410 
4411   int Dpp8Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dpp8);
4412   bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
4413 
4414   if (IsDPP && !hasDPPSrc1SGPR(getSTI())) {
4415     int Src1Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1);
4416     if (Src1Idx >= 0) {
4417       const MCOperand &Src1 = Inst.getOperand(Src1Idx);
4418       const MCRegisterInfo *TRI = getContext().getRegisterInfo();
4419       if (Src1.isImm() ||
4420           (Src1.isReg() && isSGPR(mc2PseudoReg(Src1.getReg()), TRI))) {
4421         AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[Src1Idx]);
4422         Error(Op.getStartLoc(), "invalid operand for instruction");
4423         return false;
4424       }
4425     }
4426   }
4427 
4428   return true;
4429 }
4430 
4431 // Check if VCC register matches wavefront size
4432 bool AMDGPUAsmParser::validateVccOperand(unsigned Reg) const {
4433   auto FB = getFeatureBits();
4434   return (FB[AMDGPU::FeatureWavefrontSize64] && Reg == AMDGPU::VCC) ||
4435     (FB[AMDGPU::FeatureWavefrontSize32] && Reg == AMDGPU::VCC_LO);
4436 }
4437 
4438 // One unique literal can be used. VOP3 literal is only allowed in GFX10+
4439 bool AMDGPUAsmParser::validateVOPLiteral(const MCInst &Inst,
4440                                          const OperandVector &Operands) {
4441   unsigned Opcode = Inst.getOpcode();
4442   const MCInstrDesc &Desc = MII.get(Opcode);
4443   bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
4444   if (!(Desc.TSFlags & (SIInstrFlags::VOP3 | SIInstrFlags::VOP3P)) &&
4445       !HasMandatoryLiteral && !isVOPD(Opcode))
4446     return true;
4447 
4448   OperandIndices OpIndices = getSrcOperandIndices(Opcode, HasMandatoryLiteral);
4449 
4450   unsigned NumExprs = 0;
4451   unsigned NumLiterals = 0;
4452   uint32_t LiteralValue;
4453 
4454   for (int OpIdx : OpIndices) {
4455     if (OpIdx == -1)
4456       continue;
4457 
4458     const MCOperand &MO = Inst.getOperand(OpIdx);
4459     if (!MO.isImm() && !MO.isExpr())
4460       continue;
4461     if (!isSISrcOperand(Desc, OpIdx))
4462       continue;
4463 
4464     if (MO.isImm() && !isInlineConstant(Inst, OpIdx)) {
4465       uint64_t Value = static_cast<uint64_t>(MO.getImm());
4466       bool IsFP64 = AMDGPU::isSISrcFPOperand(Desc, OpIdx) &&
4467                     AMDGPU::getOperandSize(Desc.operands()[OpIdx]) == 8;
4468       bool IsValid32Op = AMDGPU::isValid32BitLiteral(Value, IsFP64);
4469 
4470       if (!IsValid32Op && !isInt<32>(Value) && !isUInt<32>(Value)) {
4471         Error(getLitLoc(Operands), "invalid operand for instruction");
4472         return false;
4473       }
4474 
4475       if (IsFP64 && IsValid32Op)
4476         Value = Hi_32(Value);
4477 
4478       if (NumLiterals == 0 || LiteralValue != Value) {
4479         LiteralValue = Value;
4480         ++NumLiterals;
4481       }
4482     } else if (MO.isExpr()) {
4483       ++NumExprs;
4484     }
4485   }
4486   NumLiterals += NumExprs;
4487 
4488   if (!NumLiterals)
4489     return true;
4490 
4491   if (!HasMandatoryLiteral && !getFeatureBits()[FeatureVOP3Literal]) {
4492     Error(getLitLoc(Operands), "literal operands are not supported");
4493     return false;
4494   }
4495 
4496   if (NumLiterals > 1) {
4497     Error(getLitLoc(Operands, true), "only one unique literal operand is allowed");
4498     return false;
4499   }
4500 
4501   return true;
4502 }
4503 
4504 // Returns -1 if not a register, 0 if VGPR and 1 if AGPR.
4505 static int IsAGPROperand(const MCInst &Inst, uint16_t NameIdx,
4506                          const MCRegisterInfo *MRI) {
4507   int OpIdx = AMDGPU::getNamedOperandIdx(Inst.getOpcode(), NameIdx);
4508   if (OpIdx < 0)
4509     return -1;
4510 
4511   const MCOperand &Op = Inst.getOperand(OpIdx);
4512   if (!Op.isReg())
4513     return -1;
4514 
4515   unsigned Sub = MRI->getSubReg(Op.getReg(), AMDGPU::sub0);
4516   auto Reg = Sub ? Sub : Op.getReg();
4517   const MCRegisterClass &AGPR32 = MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
4518   return AGPR32.contains(Reg) ? 1 : 0;
4519 }
4520 
4521 bool AMDGPUAsmParser::validateAGPRLdSt(const MCInst &Inst) const {
4522   uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
4523   if ((TSFlags & (SIInstrFlags::FLAT | SIInstrFlags::MUBUF |
4524                   SIInstrFlags::MTBUF | SIInstrFlags::MIMG |
4525                   SIInstrFlags::DS)) == 0)
4526     return true;
4527 
4528   uint16_t DataNameIdx = (TSFlags & SIInstrFlags::DS) ? AMDGPU::OpName::data0
4529                                                       : AMDGPU::OpName::vdata;
4530 
4531   const MCRegisterInfo *MRI = getMRI();
4532   int DstAreg = IsAGPROperand(Inst, AMDGPU::OpName::vdst, MRI);
4533   int DataAreg = IsAGPROperand(Inst, DataNameIdx, MRI);
4534 
4535   if ((TSFlags & SIInstrFlags::DS) && DataAreg >= 0) {
4536     int Data2Areg = IsAGPROperand(Inst, AMDGPU::OpName::data1, MRI);
4537     if (Data2Areg >= 0 && Data2Areg != DataAreg)
4538       return false;
4539   }
4540 
4541   auto FB = getFeatureBits();
4542   if (FB[AMDGPU::FeatureGFX90AInsts]) {
4543     if (DataAreg < 0 || DstAreg < 0)
4544       return true;
4545     return DstAreg == DataAreg;
4546   }
4547 
4548   return DstAreg < 1 && DataAreg < 1;
4549 }
4550 
4551 bool AMDGPUAsmParser::validateVGPRAlign(const MCInst &Inst) const {
4552   auto FB = getFeatureBits();
4553   if (!FB[AMDGPU::FeatureGFX90AInsts])
4554     return true;
4555 
4556   const MCRegisterInfo *MRI = getMRI();
4557   const MCRegisterClass &VGPR32 = MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
4558   const MCRegisterClass &AGPR32 = MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
4559   for (unsigned I = 0, E = Inst.getNumOperands(); I != E; ++I) {
4560     const MCOperand &Op = Inst.getOperand(I);
4561     if (!Op.isReg())
4562       continue;
4563 
4564     unsigned Sub = MRI->getSubReg(Op.getReg(), AMDGPU::sub0);
4565     if (!Sub)
4566       continue;
4567 
4568     if (VGPR32.contains(Sub) && ((Sub - AMDGPU::VGPR0) & 1))
4569       return false;
4570     if (AGPR32.contains(Sub) && ((Sub - AMDGPU::AGPR0) & 1))
4571       return false;
4572   }
4573 
4574   return true;
4575 }
4576 
4577 SMLoc AMDGPUAsmParser::getBLGPLoc(const OperandVector &Operands) const {
4578   for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
4579     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
4580     if (Op.isBLGP())
4581       return Op.getStartLoc();
4582   }
4583   return SMLoc();
4584 }
4585 
4586 bool AMDGPUAsmParser::validateBLGP(const MCInst &Inst,
4587                                    const OperandVector &Operands) {
4588   unsigned Opc = Inst.getOpcode();
4589   int BlgpIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::blgp);
4590   if (BlgpIdx == -1)
4591     return true;
4592   SMLoc BLGPLoc = getBLGPLoc(Operands);
4593   if (!BLGPLoc.isValid())
4594     return true;
4595   bool IsNeg = StringRef(BLGPLoc.getPointer()).starts_with("neg:");
4596   auto FB = getFeatureBits();
4597   bool UsesNeg = false;
4598   if (FB[AMDGPU::FeatureGFX940Insts]) {
4599     switch (Opc) {
4600     case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
4601     case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
4602     case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
4603     case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
4604       UsesNeg = true;
4605     }
4606   }
4607 
4608   if (IsNeg == UsesNeg)
4609     return true;
4610 
4611   Error(BLGPLoc,
4612         UsesNeg ? "invalid modifier: blgp is not supported"
4613                 : "invalid modifier: neg is not supported");
4614 
4615   return false;
4616 }
4617 
4618 bool AMDGPUAsmParser::validateWaitCnt(const MCInst &Inst,
4619                                       const OperandVector &Operands) {
4620   if (!isGFX11Plus())
4621     return true;
4622 
4623   unsigned Opc = Inst.getOpcode();
4624   if (Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
4625       Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
4626       Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
4627       Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
4628     return true;
4629 
4630   int Src0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::sdst);
4631   assert(Src0Idx >= 0 && Inst.getOperand(Src0Idx).isReg());
4632   auto Reg = mc2PseudoReg(Inst.getOperand(Src0Idx).getReg());
4633   if (Reg == AMDGPU::SGPR_NULL)
4634     return true;
4635 
4636   SMLoc RegLoc = getRegLoc(Reg, Operands);
4637   Error(RegLoc, "src0 must be null");
4638   return false;
4639 }
4640 
4641 bool AMDGPUAsmParser::validateDS(const MCInst &Inst,
4642                                  const OperandVector &Operands) {
4643   uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
4644   if ((TSFlags & SIInstrFlags::DS) == 0)
4645     return true;
4646   if (TSFlags & SIInstrFlags::GWS)
4647     return validateGWS(Inst, Operands);
4648   // Only validate GDS for non-GWS instructions.
4649   if (hasGDS())
4650     return true;
4651   int GDSIdx =
4652       AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::gds);
4653   if (GDSIdx < 0)
4654     return true;
4655   unsigned GDS = Inst.getOperand(GDSIdx).getImm();
4656   if (GDS) {
4657     SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS, Operands);
4658     Error(S, "gds modifier is not supported on this GPU");
4659     return false;
4660   }
4661   return true;
4662 }
4663 
4664 // gfx90a has an undocumented limitation:
4665 // DS_GWS opcodes must use even aligned registers.
4666 bool AMDGPUAsmParser::validateGWS(const MCInst &Inst,
4667                                   const OperandVector &Operands) {
4668   if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
4669     return true;
4670 
4671   int Opc = Inst.getOpcode();
4672   if (Opc != AMDGPU::DS_GWS_INIT_vi && Opc != AMDGPU::DS_GWS_BARRIER_vi &&
4673       Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
4674     return true;
4675 
4676   const MCRegisterInfo *MRI = getMRI();
4677   const MCRegisterClass &VGPR32 = MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
4678   int Data0Pos =
4679       AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::data0);
4680   assert(Data0Pos != -1);
4681   auto Reg = Inst.getOperand(Data0Pos).getReg();
4682   auto RegIdx = Reg - (VGPR32.contains(Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
4683   if (RegIdx & 1) {
4684     SMLoc RegLoc = getRegLoc(Reg, Operands);
4685     Error(RegLoc, "vgpr must be even aligned");
4686     return false;
4687   }
4688 
4689   return true;
4690 }
4691 
4692 bool AMDGPUAsmParser::validateCoherencyBits(const MCInst &Inst,
4693                                             const OperandVector &Operands,
4694                                             const SMLoc &IDLoc) {
4695   int CPolPos = AMDGPU::getNamedOperandIdx(Inst.getOpcode(),
4696                                            AMDGPU::OpName::cpol);
4697   if (CPolPos == -1)
4698     return true;
4699 
4700   unsigned CPol = Inst.getOperand(CPolPos).getImm();
4701 
4702   if (isGFX12Plus())
4703     return validateTHAndScopeBits(Inst, Operands, CPol);
4704 
4705   uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
4706   if (TSFlags & SIInstrFlags::SMRD) {
4707     if (CPol && (isSI() || isCI())) {
4708       SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
4709       Error(S, "cache policy is not supported for SMRD instructions");
4710       return false;
4711     }
4712     if (CPol & ~(AMDGPU::CPol::GLC | AMDGPU::CPol::DLC)) {
4713       Error(IDLoc, "invalid cache policy for SMEM instruction");
4714       return false;
4715     }
4716   }
4717 
4718   if (isGFX90A() && !isGFX940() && (CPol & CPol::SCC)) {
4719     const uint64_t AllowSCCModifier = SIInstrFlags::MUBUF |
4720                                       SIInstrFlags::MTBUF | SIInstrFlags::MIMG |
4721                                       SIInstrFlags::FLAT;
4722     if (!(TSFlags & AllowSCCModifier)) {
4723       SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
4724       StringRef CStr(S.getPointer());
4725       S = SMLoc::getFromPointer(&CStr.data()[CStr.find("scc")]);
4726       Error(S,
4727             "scc modifier is not supported for this instruction on this GPU");
4728       return false;
4729     }
4730   }
4731 
4732   if (!(TSFlags & (SIInstrFlags::IsAtomicNoRet | SIInstrFlags::IsAtomicRet)))
4733     return true;
4734 
4735   if (TSFlags & SIInstrFlags::IsAtomicRet) {
4736     if (!(TSFlags & SIInstrFlags::MIMG) && !(CPol & CPol::GLC)) {
4737       Error(IDLoc, isGFX940() ? "instruction must use sc0"
4738                               : "instruction must use glc");
4739       return false;
4740     }
4741   } else {
4742     if (CPol & CPol::GLC) {
4743       SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
4744       StringRef CStr(S.getPointer());
4745       S = SMLoc::getFromPointer(
4746           &CStr.data()[CStr.find(isGFX940() ? "sc0" : "glc")]);
4747       Error(S, isGFX940() ? "instruction must not use sc0"
4748                           : "instruction must not use glc");
4749       return false;
4750     }
4751   }
4752 
4753   return true;
4754 }
4755 
4756 bool AMDGPUAsmParser::validateTHAndScopeBits(const MCInst &Inst,
4757                                              const OperandVector &Operands,
4758                                              const unsigned CPol) {
4759   const unsigned TH = CPol & AMDGPU::CPol::TH;
4760   const unsigned Scope = CPol & AMDGPU::CPol::SCOPE;
4761 
4762   const unsigned Opcode = Inst.getOpcode();
4763   const MCInstrDesc &TID = MII.get(Opcode);
4764 
4765   auto PrintError = [&](StringRef Msg) {
4766     SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
4767     Error(S, Msg);
4768     return false;
4769   };
4770 
4771   if ((TID.TSFlags & SIInstrFlags::IsAtomicRet) &&
4772       (TID.TSFlags & (SIInstrFlags::FLAT | SIInstrFlags::MUBUF)) &&
4773       (!(TH & AMDGPU::CPol::TH_ATOMIC_RETURN)))
4774     return PrintError("instruction must use th:TH_ATOMIC_RETURN");
4775 
4776   if (TH == 0)
4777     return true;
4778 
4779   if ((TID.TSFlags & SIInstrFlags::SMRD) &&
4780       ((TH == AMDGPU::CPol::TH_NT_RT) || (TH == AMDGPU::CPol::TH_RT_NT) ||
4781        (TH == AMDGPU::CPol::TH_NT_HT)))
4782     return PrintError("invalid th value for SMEM instruction");
4783 
4784   if (TH == AMDGPU::CPol::TH_BYPASS) {
4785     if ((Scope != AMDGPU::CPol::SCOPE_SYS &&
4786          CPol & AMDGPU::CPol::TH_REAL_BYPASS) ||
4787         (Scope == AMDGPU::CPol::SCOPE_SYS &&
4788          !(CPol & AMDGPU::CPol::TH_REAL_BYPASS)))
4789       return PrintError("scope and th combination is not valid");
4790   }
4791 
4792   bool IsStore = TID.mayStore();
4793   bool IsAtomic =
4794       TID.TSFlags & (SIInstrFlags::IsAtomicNoRet | SIInstrFlags::IsAtomicRet);
4795 
4796   if (IsAtomic) {
4797     if (!(CPol & AMDGPU::CPol::TH_TYPE_ATOMIC))
4798       return PrintError("invalid th value for atomic instructions");
4799   } else if (IsStore) {
4800     if (!(CPol & AMDGPU::CPol::TH_TYPE_STORE))
4801       return PrintError("invalid th value for store instructions");
4802   } else {
4803     if (!(CPol & AMDGPU::CPol::TH_TYPE_LOAD))
4804       return PrintError("invalid th value for load instructions");
4805   }
4806 
4807   return true;
4808 }
4809 
4810 bool AMDGPUAsmParser::validateExeczVcczOperands(const OperandVector &Operands) {
4811   if (!isGFX11Plus())
4812     return true;
4813   for (auto &Operand : Operands) {
4814     if (!Operand->isReg())
4815       continue;
4816     unsigned Reg = Operand->getReg();
4817     if (Reg == SRC_EXECZ || Reg == SRC_VCCZ) {
4818       Error(getRegLoc(Reg, Operands),
4819             "execz and vccz are not supported on this GPU");
4820       return false;
4821     }
4822   }
4823   return true;
4824 }
4825 
4826 bool AMDGPUAsmParser::validateTFE(const MCInst &Inst,
4827                                   const OperandVector &Operands) {
4828   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
4829   if (Desc.mayStore() &&
4830       (Desc.TSFlags & (SIInstrFlags::MUBUF | SIInstrFlags::MTBUF))) {
4831     SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE, Operands);
4832     if (Loc != getInstLoc(Operands)) {
4833       Error(Loc, "TFE modifier has no meaning for store instructions");
4834       return false;
4835     }
4836   }
4837 
4838   return true;
4839 }
4840 
4841 bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst,
4842                                           const SMLoc &IDLoc,
4843                                           const OperandVector &Operands) {
4844   if (auto ErrMsg = validateLdsDirect(Inst)) {
4845     Error(getRegLoc(LDS_DIRECT, Operands), *ErrMsg);
4846     return false;
4847   }
4848   if (!validateSOPLiteral(Inst)) {
4849     Error(getLitLoc(Operands),
4850       "only one unique literal operand is allowed");
4851     return false;
4852   }
4853   if (!validateVOPLiteral(Inst, Operands)) {
4854     return false;
4855   }
4856   if (!validateConstantBusLimitations(Inst, Operands)) {
4857     return false;
4858   }
4859   if (!validateVOPDRegBankConstraints(Inst, Operands)) {
4860     return false;
4861   }
4862   if (!validateIntClampSupported(Inst)) {
4863     Error(getImmLoc(AMDGPUOperand::ImmTyClampSI, Operands),
4864       "integer clamping is not supported on this GPU");
4865     return false;
4866   }
4867   if (!validateOpSel(Inst)) {
4868     Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
4869       "invalid op_sel operand");
4870     return false;
4871   }
4872   if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
4873     Error(getImmLoc(AMDGPUOperand::ImmTyNegLo, Operands),
4874           "invalid neg_lo operand");
4875     return false;
4876   }
4877   if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
4878     Error(getImmLoc(AMDGPUOperand::ImmTyNegHi, Operands),
4879           "invalid neg_hi operand");
4880     return false;
4881   }
4882   if (!validateDPP(Inst, Operands)) {
4883     return false;
4884   }
4885   // For MUBUF/MTBUF d16 is a part of opcode, so there is nothing to validate.
4886   if (!validateMIMGD16(Inst)) {
4887     Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
4888       "d16 modifier is not supported on this GPU");
4889     return false;
4890   }
4891   if (!validateMIMGMSAA(Inst)) {
4892     Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands),
4893           "invalid dim; must be MSAA type");
4894     return false;
4895   }
4896   if (!validateMIMGDataSize(Inst, IDLoc)) {
4897     return false;
4898   }
4899   if (!validateMIMGAddrSize(Inst, IDLoc))
4900     return false;
4901   if (!validateMIMGAtomicDMask(Inst)) {
4902     Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
4903       "invalid atomic image dmask");
4904     return false;
4905   }
4906   if (!validateMIMGGatherDMask(Inst)) {
4907     Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
4908       "invalid image_gather dmask: only one bit must be set");
4909     return false;
4910   }
4911   if (!validateMovrels(Inst, Operands)) {
4912     return false;
4913   }
4914   if (!validateOffset(Inst, Operands)) {
4915     return false;
4916   }
4917   if (!validateMAIAccWrite(Inst, Operands)) {
4918     return false;
4919   }
4920   if (!validateMAISrc2(Inst, Operands)) {
4921     return false;
4922   }
4923   if (!validateMFMA(Inst, Operands)) {
4924     return false;
4925   }
4926   if (!validateCoherencyBits(Inst, Operands, IDLoc)) {
4927     return false;
4928   }
4929 
4930   if (!validateAGPRLdSt(Inst)) {
4931     Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
4932     ? "invalid register class: data and dst should be all VGPR or AGPR"
4933     : "invalid register class: agpr loads and stores not supported on this GPU"
4934     );
4935     return false;
4936   }
4937   if (!validateVGPRAlign(Inst)) {
4938     Error(IDLoc,
4939       "invalid register class: vgpr tuples must be 64 bit aligned");
4940     return false;
4941   }
4942   if (!validateDS(Inst, Operands)) {
4943     return false;
4944   }
4945 
4946   if (!validateBLGP(Inst, Operands)) {
4947     return false;
4948   }
4949 
4950   if (!validateDivScale(Inst)) {
4951     Error(IDLoc, "ABS not allowed in VOP3B instructions");
4952     return false;
4953   }
4954   if (!validateWaitCnt(Inst, Operands)) {
4955     return false;
4956   }
4957   if (!validateExeczVcczOperands(Operands)) {
4958     return false;
4959   }
4960   if (!validateTFE(Inst, Operands)) {
4961     return false;
4962   }
4963 
4964   return true;
4965 }
4966 
4967 static std::string AMDGPUMnemonicSpellCheck(StringRef S,
4968                                             const FeatureBitset &FBS,
4969                                             unsigned VariantID = 0);
4970 
4971 static bool AMDGPUCheckMnemonic(StringRef Mnemonic,
4972                                 const FeatureBitset &AvailableFeatures,
4973                                 unsigned VariantID);
4974 
4975 bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
4976                                        const FeatureBitset &FBS) {
4977   return isSupportedMnemo(Mnemo, FBS, getAllVariants());
4978 }
4979 
4980 bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
4981                                        const FeatureBitset &FBS,
4982                                        ArrayRef<unsigned> Variants) {
4983   for (auto Variant : Variants) {
4984     if (AMDGPUCheckMnemonic(Mnemo, FBS, Variant))
4985       return true;
4986   }
4987 
4988   return false;
4989 }
4990 
4991 bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
4992                                                   const SMLoc &IDLoc) {
4993   FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
4994 
4995   // Check if requested instruction variant is supported.
4996   if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
4997     return false;
4998 
4999   // This instruction is not supported.
5000   // Clear any other pending errors because they are no longer relevant.
5001   getParser().clearPendingErrors();
5002 
5003   // Requested instruction variant is not supported.
5004   // Check if any other variants are supported.
5005   StringRef VariantName = getMatchedVariantName();
5006   if (!VariantName.empty() && isSupportedMnemo(Mnemo, FBS)) {
5007     return Error(IDLoc,
5008                  Twine(VariantName,
5009                        " variant of this instruction is not supported"));
5010   }
5011 
5012   // Check if this instruction may be used with a different wavesize.
5013   if (isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5014       !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5015 
5016     FeatureBitset FeaturesWS32 = getFeatureBits();
5017     FeaturesWS32.flip(AMDGPU::FeatureWavefrontSize64)
5018         .flip(AMDGPU::FeatureWavefrontSize32);
5019     FeatureBitset AvailableFeaturesWS32 =
5020         ComputeAvailableFeatures(FeaturesWS32);
5021 
5022     if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5023       return Error(IDLoc, "instruction requires wavesize=32");
5024   }
5025 
5026   // Finally check if this instruction is supported on any other GPU.
5027   if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5028     return Error(IDLoc, "instruction not supported on this GPU");
5029   }
5030 
5031   // Instruction not supported on any GPU. Probably a typo.
5032   std::string Suggestion = AMDGPUMnemonicSpellCheck(Mnemo, FBS);
5033   return Error(IDLoc, "invalid instruction" + Suggestion);
5034 }
5035 
5036 static bool isInvalidVOPDY(const OperandVector &Operands,
5037                            uint64_t InvalidOprIdx) {
5038   assert(InvalidOprIdx < Operands.size());
5039   const auto &Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5040   if (Op.isToken() && InvalidOprIdx > 1) {
5041     const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5042     return PrevOp.isToken() && PrevOp.getToken() == "::";
5043   }
5044   return false;
5045 }
5046 
5047 bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5048                                               OperandVector &Operands,
5049                                               MCStreamer &Out,
5050                                               uint64_t &ErrorInfo,
5051                                               bool MatchingInlineAsm) {
5052   MCInst Inst;
5053   unsigned Result = Match_Success;
5054   for (auto Variant : getMatchedVariants()) {
5055     uint64_t EI;
5056     auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5057                                   Variant);
5058     // We order match statuses from least to most specific. We use most specific
5059     // status as resulting
5060     // Match_MnemonicFail < Match_InvalidOperand < Match_MissingFeature < Match_PreferE32
5061     if ((R == Match_Success) ||
5062         (R == Match_PreferE32) ||
5063         (R == Match_MissingFeature && Result != Match_PreferE32) ||
5064         (R == Match_InvalidOperand && Result != Match_MissingFeature
5065                                    && Result != Match_PreferE32) ||
5066         (R == Match_MnemonicFail   && Result != Match_InvalidOperand
5067                                    && Result != Match_MissingFeature
5068                                    && Result != Match_PreferE32)) {
5069       Result = R;
5070       ErrorInfo = EI;
5071     }
5072     if (R == Match_Success)
5073       break;
5074   }
5075 
5076   if (Result == Match_Success) {
5077     if (!validateInstruction(Inst, IDLoc, Operands)) {
5078       return true;
5079     }
5080     Inst.setLoc(IDLoc);
5081     Out.emitInstruction(Inst, getSTI());
5082     return false;
5083   }
5084 
5085   StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).getToken();
5086   if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5087     return true;
5088   }
5089 
5090   switch (Result) {
5091   default: break;
5092   case Match_MissingFeature:
5093     // It has been verified that the specified instruction
5094     // mnemonic is valid. A match was found but it requires
5095     // features which are not supported on this GPU.
5096     return Error(IDLoc, "operands are not valid for this GPU or mode");
5097 
5098   case Match_InvalidOperand: {
5099     SMLoc ErrorLoc = IDLoc;
5100     if (ErrorInfo != ~0ULL) {
5101       if (ErrorInfo >= Operands.size()) {
5102         return Error(IDLoc, "too few operands for instruction");
5103       }
5104       ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5105       if (ErrorLoc == SMLoc())
5106         ErrorLoc = IDLoc;
5107 
5108       if (isInvalidVOPDY(Operands, ErrorInfo))
5109         return Error(ErrorLoc, "invalid VOPDY instruction");
5110     }
5111     return Error(ErrorLoc, "invalid operand for instruction");
5112   }
5113 
5114   case Match_PreferE32:
5115     return Error(IDLoc, "internal error: instruction without _e64 suffix "
5116                         "should be encoded as e32");
5117   case Match_MnemonicFail:
5118     llvm_unreachable("Invalid instructions should have been handled already");
5119   }
5120   llvm_unreachable("Implement any new match types added!");
5121 }
5122 
5123 bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5124   int64_t Tmp = -1;
5125   if (!isToken(AsmToken::Integer) && !isToken(AsmToken::Identifier)) {
5126     return true;
5127   }
5128   if (getParser().parseAbsoluteExpression(Tmp)) {
5129     return true;
5130   }
5131   Ret = static_cast<uint32_t>(Tmp);
5132   return false;
5133 }
5134 
5135 bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5136   if (getSTI().getTargetTriple().getArch() != Triple::amdgcn)
5137     return TokError("directive only supported for amdgcn architecture");
5138 
5139   std::string TargetIDDirective;
5140   SMLoc TargetStart = getTok().getLoc();
5141   if (getParser().parseEscapedString(TargetIDDirective))
5142     return true;
5143 
5144   SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5145   if (getTargetStreamer().getTargetID()->toString() != TargetIDDirective)
5146     return getParser().Error(TargetRange.Start,
5147         (Twine(".amdgcn_target directive's target id ") +
5148          Twine(TargetIDDirective) +
5149          Twine(" does not match the specified target id ") +
5150          Twine(getTargetStreamer().getTargetID()->toString())).str());
5151 
5152   return false;
5153 }
5154 
5155 bool AMDGPUAsmParser::OutOfRangeError(SMRange Range) {
5156   return Error(Range.Start, "value out of range", Range);
5157 }
5158 
5159 bool AMDGPUAsmParser::calculateGPRBlocks(
5160     const FeatureBitset &Features, bool VCCUsed, bool FlatScrUsed,
5161     bool XNACKUsed, std::optional<bool> EnableWavefrontSize32,
5162     unsigned NextFreeVGPR, SMRange VGPRRange, unsigned NextFreeSGPR,
5163     SMRange SGPRRange, unsigned &VGPRBlocks, unsigned &SGPRBlocks) {
5164   // TODO(scott.linder): These calculations are duplicated from
5165   // AMDGPUAsmPrinter::getSIProgramInfo and could be unified.
5166   IsaVersion Version = getIsaVersion(getSTI().getCPU());
5167 
5168   unsigned NumVGPRs = NextFreeVGPR;
5169   unsigned NumSGPRs = NextFreeSGPR;
5170 
5171   if (Version.Major >= 10)
5172     NumSGPRs = 0;
5173   else {
5174     unsigned MaxAddressableNumSGPRs =
5175         IsaInfo::getAddressableNumSGPRs(&getSTI());
5176 
5177     if (Version.Major >= 8 && !Features.test(FeatureSGPRInitBug) &&
5178         NumSGPRs > MaxAddressableNumSGPRs)
5179       return OutOfRangeError(SGPRRange);
5180 
5181     NumSGPRs +=
5182         IsaInfo::getNumExtraSGPRs(&getSTI(), VCCUsed, FlatScrUsed, XNACKUsed);
5183 
5184     if ((Version.Major <= 7 || Features.test(FeatureSGPRInitBug)) &&
5185         NumSGPRs > MaxAddressableNumSGPRs)
5186       return OutOfRangeError(SGPRRange);
5187 
5188     if (Features.test(FeatureSGPRInitBug))
5189       NumSGPRs = IsaInfo::FIXED_NUM_SGPRS_FOR_INIT_BUG;
5190   }
5191 
5192   VGPRBlocks =
5193       IsaInfo::getNumVGPRBlocks(&getSTI(), NumVGPRs, EnableWavefrontSize32);
5194   SGPRBlocks = IsaInfo::getNumSGPRBlocks(&getSTI(), NumSGPRs);
5195 
5196   return false;
5197 }
5198 
5199 bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5200   if (getSTI().getTargetTriple().getArch() != Triple::amdgcn)
5201     return TokError("directive only supported for amdgcn architecture");
5202 
5203   if (!isHsaAbi(getSTI()))
5204     return TokError("directive only supported for amdhsa OS");
5205 
5206   StringRef KernelName;
5207   if (getParser().parseIdentifier(KernelName))
5208     return true;
5209 
5210   kernel_descriptor_t KD = getDefaultAmdhsaKernelDescriptor(&getSTI());
5211 
5212   StringSet<> Seen;
5213 
5214   IsaVersion IVersion = getIsaVersion(getSTI().getCPU());
5215 
5216   SMRange VGPRRange;
5217   uint64_t NextFreeVGPR = 0;
5218   uint64_t AccumOffset = 0;
5219   uint64_t SharedVGPRCount = 0;
5220   uint64_t PreloadLength = 0;
5221   uint64_t PreloadOffset = 0;
5222   SMRange SGPRRange;
5223   uint64_t NextFreeSGPR = 0;
5224 
5225   // Count the number of user SGPRs implied from the enabled feature bits.
5226   unsigned ImpliedUserSGPRCount = 0;
5227 
5228   // Track if the asm explicitly contains the directive for the user SGPR
5229   // count.
5230   std::optional<unsigned> ExplicitUserSGPRCount;
5231   bool ReserveVCC = true;
5232   bool ReserveFlatScr = true;
5233   std::optional<bool> EnableWavefrontSize32;
5234 
5235   while (true) {
5236     while (trySkipToken(AsmToken::EndOfStatement));
5237 
5238     StringRef ID;
5239     SMRange IDRange = getTok().getLocRange();
5240     if (!parseId(ID, "expected .amdhsa_ directive or .end_amdhsa_kernel"))
5241       return true;
5242 
5243     if (ID == ".end_amdhsa_kernel")
5244       break;
5245 
5246     if (!Seen.insert(ID).second)
5247       return TokError(".amdhsa_ directives cannot be repeated");
5248 
5249     SMLoc ValStart = getLoc();
5250     int64_t IVal;
5251     if (getParser().parseAbsoluteExpression(IVal))
5252       return true;
5253     SMLoc ValEnd = getLoc();
5254     SMRange ValRange = SMRange(ValStart, ValEnd);
5255 
5256     if (IVal < 0)
5257       return OutOfRangeError(ValRange);
5258 
5259     uint64_t Val = IVal;
5260 
5261 #define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)                           \
5262   if (!isUInt<ENTRY##_WIDTH>(VALUE))                                           \
5263     return OutOfRangeError(RANGE);                                             \
5264   AMDHSA_BITS_SET(FIELD, ENTRY, VALUE);
5265 
5266     if (ID == ".amdhsa_group_segment_fixed_size") {
5267       if (!isUInt<sizeof(KD.group_segment_fixed_size) * CHAR_BIT>(Val))
5268         return OutOfRangeError(ValRange);
5269       KD.group_segment_fixed_size = Val;
5270     } else if (ID == ".amdhsa_private_segment_fixed_size") {
5271       if (!isUInt<sizeof(KD.private_segment_fixed_size) * CHAR_BIT>(Val))
5272         return OutOfRangeError(ValRange);
5273       KD.private_segment_fixed_size = Val;
5274     } else if (ID == ".amdhsa_kernarg_size") {
5275       if (!isUInt<sizeof(KD.kernarg_size) * CHAR_BIT>(Val))
5276         return OutOfRangeError(ValRange);
5277       KD.kernarg_size = Val;
5278     } else if (ID == ".amdhsa_user_sgpr_count") {
5279       ExplicitUserSGPRCount = Val;
5280     } else if (ID == ".amdhsa_user_sgpr_private_segment_buffer") {
5281       if (hasArchitectedFlatScratch())
5282         return Error(IDRange.Start,
5283                      "directive is not supported with architected flat scratch",
5284                      IDRange);
5285       PARSE_BITS_ENTRY(KD.kernel_code_properties,
5286                        KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
5287                        Val, ValRange);
5288       if (Val)
5289         ImpliedUserSGPRCount += 4;
5290     } else if (ID == ".amdhsa_user_sgpr_kernarg_preload_length") {
5291       if (!hasKernargPreload())
5292         return Error(IDRange.Start, "directive requires gfx90a+", IDRange);
5293 
5294       if (Val > getMaxNumUserSGPRs())
5295         return OutOfRangeError(ValRange);
5296       PARSE_BITS_ENTRY(KD.kernarg_preload, KERNARG_PRELOAD_SPEC_LENGTH, Val,
5297                        ValRange);
5298       if (Val) {
5299         ImpliedUserSGPRCount += Val;
5300         PreloadLength = Val;
5301       }
5302     } else if (ID == ".amdhsa_user_sgpr_kernarg_preload_offset") {
5303       if (!hasKernargPreload())
5304         return Error(IDRange.Start, "directive requires gfx90a+", IDRange);
5305 
5306       if (Val >= 1024)
5307         return OutOfRangeError(ValRange);
5308       PARSE_BITS_ENTRY(KD.kernarg_preload, KERNARG_PRELOAD_SPEC_OFFSET, Val,
5309                        ValRange);
5310       if (Val)
5311         PreloadOffset = Val;
5312     } else if (ID == ".amdhsa_user_sgpr_dispatch_ptr") {
5313       PARSE_BITS_ENTRY(KD.kernel_code_properties,
5314                        KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, Val,
5315                        ValRange);
5316       if (Val)
5317         ImpliedUserSGPRCount += 2;
5318     } else if (ID == ".amdhsa_user_sgpr_queue_ptr") {
5319       PARSE_BITS_ENTRY(KD.kernel_code_properties,
5320                        KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, Val,
5321                        ValRange);
5322       if (Val)
5323         ImpliedUserSGPRCount += 2;
5324     } else if (ID == ".amdhsa_user_sgpr_kernarg_segment_ptr") {
5325       PARSE_BITS_ENTRY(KD.kernel_code_properties,
5326                        KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
5327                        Val, ValRange);
5328       if (Val)
5329         ImpliedUserSGPRCount += 2;
5330     } else if (ID == ".amdhsa_user_sgpr_dispatch_id") {
5331       PARSE_BITS_ENTRY(KD.kernel_code_properties,
5332                        KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, Val,
5333                        ValRange);
5334       if (Val)
5335         ImpliedUserSGPRCount += 2;
5336     } else if (ID == ".amdhsa_user_sgpr_flat_scratch_init") {
5337       if (hasArchitectedFlatScratch())
5338         return Error(IDRange.Start,
5339                      "directive is not supported with architected flat scratch",
5340                      IDRange);
5341       PARSE_BITS_ENTRY(KD.kernel_code_properties,
5342                        KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT, Val,
5343                        ValRange);
5344       if (Val)
5345         ImpliedUserSGPRCount += 2;
5346     } else if (ID == ".amdhsa_user_sgpr_private_segment_size") {
5347       PARSE_BITS_ENTRY(KD.kernel_code_properties,
5348                        KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
5349                        Val, ValRange);
5350       if (Val)
5351         ImpliedUserSGPRCount += 1;
5352     } else if (ID == ".amdhsa_wavefront_size32") {
5353       if (IVersion.Major < 10)
5354         return Error(IDRange.Start, "directive requires gfx10+", IDRange);
5355       EnableWavefrontSize32 = Val;
5356       PARSE_BITS_ENTRY(KD.kernel_code_properties,
5357                        KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32,
5358                        Val, ValRange);
5359     } else if (ID == ".amdhsa_uses_dynamic_stack") {
5360       PARSE_BITS_ENTRY(KD.kernel_code_properties,
5361                        KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, Val, ValRange);
5362     } else if (ID == ".amdhsa_system_sgpr_private_segment_wavefront_offset") {
5363       if (hasArchitectedFlatScratch())
5364         return Error(IDRange.Start,
5365                      "directive is not supported with architected flat scratch",
5366                      IDRange);
5367       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5368                        COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, Val, ValRange);
5369     } else if (ID == ".amdhsa_enable_private_segment") {
5370       if (!hasArchitectedFlatScratch())
5371         return Error(
5372             IDRange.Start,
5373             "directive is not supported without architected flat scratch",
5374             IDRange);
5375       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5376                        COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, Val, ValRange);
5377     } else if (ID == ".amdhsa_system_sgpr_workgroup_id_x") {
5378       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5379                        COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, Val,
5380                        ValRange);
5381     } else if (ID == ".amdhsa_system_sgpr_workgroup_id_y") {
5382       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5383                        COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, Val,
5384                        ValRange);
5385     } else if (ID == ".amdhsa_system_sgpr_workgroup_id_z") {
5386       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5387                        COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, Val,
5388                        ValRange);
5389     } else if (ID == ".amdhsa_system_sgpr_workgroup_info") {
5390       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5391                        COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, Val,
5392                        ValRange);
5393     } else if (ID == ".amdhsa_system_vgpr_workitem_id") {
5394       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5395                        COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, Val,
5396                        ValRange);
5397     } else if (ID == ".amdhsa_next_free_vgpr") {
5398       VGPRRange = ValRange;
5399       NextFreeVGPR = Val;
5400     } else if (ID == ".amdhsa_next_free_sgpr") {
5401       SGPRRange = ValRange;
5402       NextFreeSGPR = Val;
5403     } else if (ID == ".amdhsa_accum_offset") {
5404       if (!isGFX90A())
5405         return Error(IDRange.Start, "directive requires gfx90a+", IDRange);
5406       AccumOffset = Val;
5407     } else if (ID == ".amdhsa_reserve_vcc") {
5408       if (!isUInt<1>(Val))
5409         return OutOfRangeError(ValRange);
5410       ReserveVCC = Val;
5411     } else if (ID == ".amdhsa_reserve_flat_scratch") {
5412       if (IVersion.Major < 7)
5413         return Error(IDRange.Start, "directive requires gfx7+", IDRange);
5414       if (hasArchitectedFlatScratch())
5415         return Error(IDRange.Start,
5416                      "directive is not supported with architected flat scratch",
5417                      IDRange);
5418       if (!isUInt<1>(Val))
5419         return OutOfRangeError(ValRange);
5420       ReserveFlatScr = Val;
5421     } else if (ID == ".amdhsa_reserve_xnack_mask") {
5422       if (IVersion.Major < 8)
5423         return Error(IDRange.Start, "directive requires gfx8+", IDRange);
5424       if (!isUInt<1>(Val))
5425         return OutOfRangeError(ValRange);
5426       if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
5427         return getParser().Error(IDRange.Start, ".amdhsa_reserve_xnack_mask does not match target id",
5428                                  IDRange);
5429     } else if (ID == ".amdhsa_float_round_mode_32") {
5430       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5431                        COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, Val, ValRange);
5432     } else if (ID == ".amdhsa_float_round_mode_16_64") {
5433       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5434                        COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, Val, ValRange);
5435     } else if (ID == ".amdhsa_float_denorm_mode_32") {
5436       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5437                        COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, Val, ValRange);
5438     } else if (ID == ".amdhsa_float_denorm_mode_16_64") {
5439       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5440                        COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, Val,
5441                        ValRange);
5442     } else if (ID == ".amdhsa_dx10_clamp") {
5443       if (IVersion.Major >= 12)
5444         return Error(IDRange.Start, "directive unsupported on gfx12+", IDRange);
5445       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5446                        COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, Val,
5447                        ValRange);
5448     } else if (ID == ".amdhsa_ieee_mode") {
5449       if (IVersion.Major >= 12)
5450         return Error(IDRange.Start, "directive unsupported on gfx12+", IDRange);
5451       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5452                        COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, Val,
5453                        ValRange);
5454     } else if (ID == ".amdhsa_fp16_overflow") {
5455       if (IVersion.Major < 9)
5456         return Error(IDRange.Start, "directive requires gfx9+", IDRange);
5457       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1, COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, Val,
5458                        ValRange);
5459     } else if (ID == ".amdhsa_tg_split") {
5460       if (!isGFX90A())
5461         return Error(IDRange.Start, "directive requires gfx90a+", IDRange);
5462       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc3, COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT, Val,
5463                        ValRange);
5464     } else if (ID == ".amdhsa_workgroup_processor_mode") {
5465       if (IVersion.Major < 10)
5466         return Error(IDRange.Start, "directive requires gfx10+", IDRange);
5467       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1, COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, Val,
5468                        ValRange);
5469     } else if (ID == ".amdhsa_memory_ordered") {
5470       if (IVersion.Major < 10)
5471         return Error(IDRange.Start, "directive requires gfx10+", IDRange);
5472       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1, COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, Val,
5473                        ValRange);
5474     } else if (ID == ".amdhsa_forward_progress") {
5475       if (IVersion.Major < 10)
5476         return Error(IDRange.Start, "directive requires gfx10+", IDRange);
5477       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1, COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, Val,
5478                        ValRange);
5479     } else if (ID == ".amdhsa_shared_vgpr_count") {
5480       if (IVersion.Major < 10 || IVersion.Major >= 12)
5481         return Error(IDRange.Start, "directive requires gfx10 or gfx11",
5482                      IDRange);
5483       SharedVGPRCount = Val;
5484       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc3,
5485                        COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, Val,
5486                        ValRange);
5487     } else if (ID == ".amdhsa_exception_fp_ieee_invalid_op") {
5488       PARSE_BITS_ENTRY(
5489           KD.compute_pgm_rsrc2,
5490           COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION, Val,
5491           ValRange);
5492     } else if (ID == ".amdhsa_exception_fp_denorm_src") {
5493       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5494                        COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
5495                        Val, ValRange);
5496     } else if (ID == ".amdhsa_exception_fp_ieee_div_zero") {
5497       PARSE_BITS_ENTRY(
5498           KD.compute_pgm_rsrc2,
5499           COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO, Val,
5500           ValRange);
5501     } else if (ID == ".amdhsa_exception_fp_ieee_overflow") {
5502       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5503                        COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
5504                        Val, ValRange);
5505     } else if (ID == ".amdhsa_exception_fp_ieee_underflow") {
5506       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5507                        COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
5508                        Val, ValRange);
5509     } else if (ID == ".amdhsa_exception_fp_ieee_inexact") {
5510       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5511                        COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
5512                        Val, ValRange);
5513     } else if (ID == ".amdhsa_exception_int_div_zero") {
5514       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5515                        COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
5516                        Val, ValRange);
5517     } else if (ID == ".amdhsa_round_robin_scheduling") {
5518       if (IVersion.Major < 12)
5519         return Error(IDRange.Start, "directive requires gfx12+", IDRange);
5520       PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5521                        COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, Val,
5522                        ValRange);
5523     } else {
5524       return Error(IDRange.Start, "unknown .amdhsa_kernel directive", IDRange);
5525     }
5526 
5527 #undef PARSE_BITS_ENTRY
5528   }
5529 
5530   if (!Seen.contains(".amdhsa_next_free_vgpr"))
5531     return TokError(".amdhsa_next_free_vgpr directive is required");
5532 
5533   if (!Seen.contains(".amdhsa_next_free_sgpr"))
5534     return TokError(".amdhsa_next_free_sgpr directive is required");
5535 
5536   unsigned VGPRBlocks;
5537   unsigned SGPRBlocks;
5538   if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
5539                          getTargetStreamer().getTargetID()->isXnackOnOrAny(),
5540                          EnableWavefrontSize32, NextFreeVGPR,
5541                          VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
5542                          SGPRBlocks))
5543     return true;
5544 
5545   if (!isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_WIDTH>(
5546           VGPRBlocks))
5547     return OutOfRangeError(VGPRRange);
5548   AMDHSA_BITS_SET(KD.compute_pgm_rsrc1,
5549                   COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT, VGPRBlocks);
5550 
5551   if (!isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_WIDTH>(
5552           SGPRBlocks))
5553     return OutOfRangeError(SGPRRange);
5554   AMDHSA_BITS_SET(KD.compute_pgm_rsrc1,
5555                   COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
5556                   SGPRBlocks);
5557 
5558   if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
5559     return TokError("amdgpu_user_sgpr_count smaller than than implied by "
5560                     "enabled user SGPRs");
5561 
5562   unsigned UserSGPRCount =
5563       ExplicitUserSGPRCount ? *ExplicitUserSGPRCount : ImpliedUserSGPRCount;
5564 
5565   if (!isUInt<COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_WIDTH>(UserSGPRCount))
5566     return TokError("too many user SGPRs enabled");
5567   AMDHSA_BITS_SET(KD.compute_pgm_rsrc2, COMPUTE_PGM_RSRC2_USER_SGPR_COUNT,
5568                   UserSGPRCount);
5569 
5570   if (PreloadLength && KD.kernarg_size &&
5571       (PreloadLength * 4 + PreloadOffset * 4 > KD.kernarg_size))
5572     return TokError("Kernarg preload length + offset is larger than the "
5573                     "kernarg segment size");
5574 
5575   if (isGFX90A()) {
5576     if (!Seen.contains(".amdhsa_accum_offset"))
5577       return TokError(".amdhsa_accum_offset directive is required");
5578     if (AccumOffset < 4 || AccumOffset > 256 || (AccumOffset & 3))
5579       return TokError("accum_offset should be in range [4..256] in "
5580                       "increments of 4");
5581     if (AccumOffset > alignTo(std::max((uint64_t)1, NextFreeVGPR), 4))
5582       return TokError("accum_offset exceeds total VGPR allocation");
5583     AMDHSA_BITS_SET(KD.compute_pgm_rsrc3, COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
5584                     (AccumOffset / 4 - 1));
5585   }
5586 
5587   if (IVersion.Major >= 10 && IVersion.Major < 12) {
5588     // SharedVGPRCount < 16 checked by PARSE_ENTRY_BITS
5589     if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
5590       return TokError("shared_vgpr_count directive not valid on "
5591                       "wavefront size 32");
5592     }
5593     if (SharedVGPRCount * 2 + VGPRBlocks > 63) {
5594       return TokError("shared_vgpr_count*2 + "
5595                       "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
5596                       "exceed 63\n");
5597     }
5598   }
5599 
5600   getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
5601                                                  NextFreeVGPR, NextFreeSGPR,
5602                                                  ReserveVCC, ReserveFlatScr);
5603   return false;
5604 }
5605 
5606 bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
5607   uint32_t Version;
5608   if (ParseAsAbsoluteExpression(Version))
5609     return true;
5610 
5611   getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(Version);
5612   return false;
5613 }
5614 
5615 bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef ID,
5616                                                amd_kernel_code_t &Header) {
5617   // max_scratch_backing_memory_byte_size is deprecated. Ignore it while parsing
5618   // assembly for backwards compatibility.
5619   if (ID == "max_scratch_backing_memory_byte_size") {
5620     Parser.eatToEndOfStatement();
5621     return false;
5622   }
5623 
5624   SmallString<40> ErrStr;
5625   raw_svector_ostream Err(ErrStr);
5626   if (!parseAmdKernelCodeField(ID, getParser(), Header, Err)) {
5627     return TokError(Err.str());
5628   }
5629   Lex();
5630 
5631   if (ID == "enable_dx10_clamp") {
5632     if (G_00B848_DX10_CLAMP(Header.compute_pgm_resource_registers) &&
5633         isGFX12Plus())
5634       return TokError("enable_dx10_clamp=1 is not allowed on GFX12+");
5635   }
5636 
5637   if (ID == "enable_ieee_mode") {
5638     if (G_00B848_IEEE_MODE(Header.compute_pgm_resource_registers) &&
5639         isGFX12Plus())
5640       return TokError("enable_ieee_mode=1 is not allowed on GFX12+");
5641   }
5642 
5643   if (ID == "enable_wavefront_size32") {
5644     if (Header.code_properties & AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32) {
5645       if (!isGFX10Plus())
5646         return TokError("enable_wavefront_size32=1 is only allowed on GFX10+");
5647       if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5648         return TokError("enable_wavefront_size32=1 requires +WavefrontSize32");
5649     } else {
5650       if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5651         return TokError("enable_wavefront_size32=0 requires +WavefrontSize64");
5652     }
5653   }
5654 
5655   if (ID == "wavefront_size") {
5656     if (Header.wavefront_size == 5) {
5657       if (!isGFX10Plus())
5658         return TokError("wavefront_size=5 is only allowed on GFX10+");
5659       if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5660         return TokError("wavefront_size=5 requires +WavefrontSize32");
5661     } else if (Header.wavefront_size == 6) {
5662       if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5663         return TokError("wavefront_size=6 requires +WavefrontSize64");
5664     }
5665   }
5666 
5667   if (ID == "enable_wgp_mode") {
5668     if (G_00B848_WGP_MODE(Header.compute_pgm_resource_registers) &&
5669         !isGFX10Plus())
5670       return TokError("enable_wgp_mode=1 is only allowed on GFX10+");
5671   }
5672 
5673   if (ID == "enable_mem_ordered") {
5674     if (G_00B848_MEM_ORDERED(Header.compute_pgm_resource_registers) &&
5675         !isGFX10Plus())
5676       return TokError("enable_mem_ordered=1 is only allowed on GFX10+");
5677   }
5678 
5679   if (ID == "enable_fwd_progress") {
5680     if (G_00B848_FWD_PROGRESS(Header.compute_pgm_resource_registers) &&
5681         !isGFX10Plus())
5682       return TokError("enable_fwd_progress=1 is only allowed on GFX10+");
5683   }
5684 
5685   return false;
5686 }
5687 
5688 bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
5689   amd_kernel_code_t Header;
5690   AMDGPU::initDefaultAMDKernelCodeT(Header, &getSTI());
5691 
5692   while (true) {
5693     // Lex EndOfStatement.  This is in a while loop, because lexing a comment
5694     // will set the current token to EndOfStatement.
5695     while(trySkipToken(AsmToken::EndOfStatement));
5696 
5697     StringRef ID;
5698     if (!parseId(ID, "expected value identifier or .end_amd_kernel_code_t"))
5699       return true;
5700 
5701     if (ID == ".end_amd_kernel_code_t")
5702       break;
5703 
5704     if (ParseAMDKernelCodeTValue(ID, Header))
5705       return true;
5706   }
5707 
5708   getTargetStreamer().EmitAMDKernelCodeT(Header);
5709 
5710   return false;
5711 }
5712 
5713 bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
5714   StringRef KernelName;
5715   if (!parseId(KernelName, "expected symbol name"))
5716     return true;
5717 
5718   getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
5719                                            ELF::STT_AMDGPU_HSA_KERNEL);
5720 
5721   KernelScope.initialize(getContext());
5722   return false;
5723 }
5724 
5725 bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
5726   if (getSTI().getTargetTriple().getArch() != Triple::amdgcn) {
5727     return Error(getLoc(),
5728                  ".amd_amdgpu_isa directive is not available on non-amdgcn "
5729                  "architectures");
5730   }
5731 
5732   auto TargetIDDirective = getLexer().getTok().getStringContents();
5733   if (getTargetStreamer().getTargetID()->toString() != TargetIDDirective)
5734     return Error(getParser().getTok().getLoc(), "target id must match options");
5735 
5736   getTargetStreamer().EmitISAVersion();
5737   Lex();
5738 
5739   return false;
5740 }
5741 
5742 bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
5743   assert(isHsaAbi(getSTI()));
5744 
5745   std::string HSAMetadataString;
5746   if (ParseToEndDirective(HSAMD::V3::AssemblerDirectiveBegin,
5747                           HSAMD::V3::AssemblerDirectiveEnd, HSAMetadataString))
5748     return true;
5749 
5750   if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
5751     return Error(getLoc(), "invalid HSA metadata");
5752 
5753   return false;
5754 }
5755 
5756 /// Common code to parse out a block of text (typically YAML) between start and
5757 /// end directives.
5758 bool AMDGPUAsmParser::ParseToEndDirective(const char *AssemblerDirectiveBegin,
5759                                           const char *AssemblerDirectiveEnd,
5760                                           std::string &CollectString) {
5761 
5762   raw_string_ostream CollectStream(CollectString);
5763 
5764   getLexer().setSkipSpace(false);
5765 
5766   bool FoundEnd = false;
5767   while (!isToken(AsmToken::Eof)) {
5768     while (isToken(AsmToken::Space)) {
5769       CollectStream << getTokenStr();
5770       Lex();
5771     }
5772 
5773     if (trySkipId(AssemblerDirectiveEnd)) {
5774       FoundEnd = true;
5775       break;
5776     }
5777 
5778     CollectStream << Parser.parseStringToEndOfStatement()
5779                   << getContext().getAsmInfo()->getSeparatorString();
5780 
5781     Parser.eatToEndOfStatement();
5782   }
5783 
5784   getLexer().setSkipSpace(true);
5785 
5786   if (isToken(AsmToken::Eof) && !FoundEnd) {
5787     return TokError(Twine("expected directive ") +
5788                     Twine(AssemblerDirectiveEnd) + Twine(" not found"));
5789   }
5790 
5791   CollectStream.flush();
5792   return false;
5793 }
5794 
5795 /// Parse the assembler directive for new MsgPack-format PAL metadata.
5796 bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
5797   std::string String;
5798   if (ParseToEndDirective(AMDGPU::PALMD::AssemblerDirectiveBegin,
5799                           AMDGPU::PALMD::AssemblerDirectiveEnd, String))
5800     return true;
5801 
5802   auto PALMetadata = getTargetStreamer().getPALMetadata();
5803   if (!PALMetadata->setFromString(String))
5804     return Error(getLoc(), "invalid PAL metadata");
5805   return false;
5806 }
5807 
5808 /// Parse the assembler directive for old linear-format PAL metadata.
5809 bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
5810   if (getSTI().getTargetTriple().getOS() != Triple::AMDPAL) {
5811     return Error(getLoc(),
5812                  (Twine(PALMD::AssemblerDirective) + Twine(" directive is "
5813                  "not available on non-amdpal OSes")).str());
5814   }
5815 
5816   auto PALMetadata = getTargetStreamer().getPALMetadata();
5817   PALMetadata->setLegacy();
5818   for (;;) {
5819     uint32_t Key, Value;
5820     if (ParseAsAbsoluteExpression(Key)) {
5821       return TokError(Twine("invalid value in ") +
5822                       Twine(PALMD::AssemblerDirective));
5823     }
5824     if (!trySkipToken(AsmToken::Comma)) {
5825       return TokError(Twine("expected an even number of values in ") +
5826                       Twine(PALMD::AssemblerDirective));
5827     }
5828     if (ParseAsAbsoluteExpression(Value)) {
5829       return TokError(Twine("invalid value in ") +
5830                       Twine(PALMD::AssemblerDirective));
5831     }
5832     PALMetadata->setRegister(Key, Value);
5833     if (!trySkipToken(AsmToken::Comma))
5834       break;
5835   }
5836   return false;
5837 }
5838 
5839 /// ParseDirectiveAMDGPULDS
5840 ///  ::= .amdgpu_lds identifier ',' size_expression [',' align_expression]
5841 bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
5842   if (getParser().checkForValidSection())
5843     return true;
5844 
5845   StringRef Name;
5846   SMLoc NameLoc = getLoc();
5847   if (getParser().parseIdentifier(Name))
5848     return TokError("expected identifier in directive");
5849 
5850   MCSymbol *Symbol = getContext().getOrCreateSymbol(Name);
5851   if (getParser().parseComma())
5852     return true;
5853 
5854   unsigned LocalMemorySize = AMDGPU::IsaInfo::getLocalMemorySize(&getSTI());
5855 
5856   int64_t Size;
5857   SMLoc SizeLoc = getLoc();
5858   if (getParser().parseAbsoluteExpression(Size))
5859     return true;
5860   if (Size < 0)
5861     return Error(SizeLoc, "size must be non-negative");
5862   if (Size > LocalMemorySize)
5863     return Error(SizeLoc, "size is too large");
5864 
5865   int64_t Alignment = 4;
5866   if (trySkipToken(AsmToken::Comma)) {
5867     SMLoc AlignLoc = getLoc();
5868     if (getParser().parseAbsoluteExpression(Alignment))
5869       return true;
5870     if (Alignment < 0 || !isPowerOf2_64(Alignment))
5871       return Error(AlignLoc, "alignment must be a power of two");
5872 
5873     // Alignment larger than the size of LDS is possible in theory, as long
5874     // as the linker manages to place to symbol at address 0, but we do want
5875     // to make sure the alignment fits nicely into a 32-bit integer.
5876     if (Alignment >= 1u << 31)
5877       return Error(AlignLoc, "alignment is too large");
5878   }
5879 
5880   if (parseEOL())
5881     return true;
5882 
5883   Symbol->redefineIfPossible();
5884   if (!Symbol->isUndefined())
5885     return Error(NameLoc, "invalid symbol redefinition");
5886 
5887   getTargetStreamer().emitAMDGPULDS(Symbol, Size, Align(Alignment));
5888   return false;
5889 }
5890 
5891 bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
5892   StringRef IDVal = DirectiveID.getString();
5893 
5894   if (isHsaAbi(getSTI())) {
5895     if (IDVal == ".amdhsa_kernel")
5896      return ParseDirectiveAMDHSAKernel();
5897 
5898     if (IDVal == ".amdhsa_code_object_version")
5899       return ParseDirectiveAMDHSACodeObjectVersion();
5900 
5901     // TODO: Restructure/combine with PAL metadata directive.
5902     if (IDVal == AMDGPU::HSAMD::V3::AssemblerDirectiveBegin)
5903       return ParseDirectiveHSAMetadata();
5904   } else {
5905     if (IDVal == ".amd_kernel_code_t")
5906       return ParseDirectiveAMDKernelCodeT();
5907 
5908     if (IDVal == ".amdgpu_hsa_kernel")
5909       return ParseDirectiveAMDGPUHsaKernel();
5910 
5911     if (IDVal == ".amd_amdgpu_isa")
5912       return ParseDirectiveISAVersion();
5913 
5914     if (IDVal == AMDGPU::HSAMD::AssemblerDirectiveBegin) {
5915       return Error(getLoc(), (Twine(HSAMD::AssemblerDirectiveBegin) +
5916                               Twine(" directive is "
5917                                     "not available on non-amdhsa OSes"))
5918                                  .str());
5919     }
5920   }
5921 
5922   if (IDVal == ".amdgcn_target")
5923     return ParseDirectiveAMDGCNTarget();
5924 
5925   if (IDVal == ".amdgpu_lds")
5926     return ParseDirectiveAMDGPULDS();
5927 
5928   if (IDVal == PALMD::AssemblerDirectiveBegin)
5929     return ParseDirectivePALMetadataBegin();
5930 
5931   if (IDVal == PALMD::AssemblerDirective)
5932     return ParseDirectivePALMetadata();
5933 
5934   return true;
5935 }
5936 
5937 bool AMDGPUAsmParser::subtargetHasRegister(const MCRegisterInfo &MRI,
5938                                            unsigned RegNo) {
5939 
5940   if (MRI.regsOverlap(AMDGPU::TTMP12_TTMP13_TTMP14_TTMP15, RegNo))
5941     return isGFX9Plus();
5942 
5943   // GFX10+ has 2 more SGPRs 104 and 105.
5944   if (MRI.regsOverlap(AMDGPU::SGPR104_SGPR105, RegNo))
5945     return hasSGPR104_SGPR105();
5946 
5947   switch (RegNo) {
5948   case AMDGPU::SRC_SHARED_BASE_LO:
5949   case AMDGPU::SRC_SHARED_BASE:
5950   case AMDGPU::SRC_SHARED_LIMIT_LO:
5951   case AMDGPU::SRC_SHARED_LIMIT:
5952   case AMDGPU::SRC_PRIVATE_BASE_LO:
5953   case AMDGPU::SRC_PRIVATE_BASE:
5954   case AMDGPU::SRC_PRIVATE_LIMIT_LO:
5955   case AMDGPU::SRC_PRIVATE_LIMIT:
5956     return isGFX9Plus();
5957   case AMDGPU::SRC_POPS_EXITING_WAVE_ID:
5958     return isGFX9Plus() && !isGFX11Plus();
5959   case AMDGPU::TBA:
5960   case AMDGPU::TBA_LO:
5961   case AMDGPU::TBA_HI:
5962   case AMDGPU::TMA:
5963   case AMDGPU::TMA_LO:
5964   case AMDGPU::TMA_HI:
5965     return !isGFX9Plus();
5966   case AMDGPU::XNACK_MASK:
5967   case AMDGPU::XNACK_MASK_LO:
5968   case AMDGPU::XNACK_MASK_HI:
5969     return (isVI() || isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
5970   case AMDGPU::SGPR_NULL:
5971     return isGFX10Plus();
5972   default:
5973     break;
5974   }
5975 
5976   if (isCI())
5977     return true;
5978 
5979   if (isSI() || isGFX10Plus()) {
5980     // No flat_scr on SI.
5981     // On GFX10Plus flat scratch is not a valid register operand and can only be
5982     // accessed with s_setreg/s_getreg.
5983     switch (RegNo) {
5984     case AMDGPU::FLAT_SCR:
5985     case AMDGPU::FLAT_SCR_LO:
5986     case AMDGPU::FLAT_SCR_HI:
5987       return false;
5988     default:
5989       return true;
5990     }
5991   }
5992 
5993   // VI only has 102 SGPRs, so make sure we aren't trying to use the 2 more that
5994   // SI/CI have.
5995   if (MRI.regsOverlap(AMDGPU::SGPR102_SGPR103, RegNo))
5996     return hasSGPR102_SGPR103();
5997 
5998   return true;
5999 }
6000 
6001 ParseStatus AMDGPUAsmParser::parseOperand(OperandVector &Operands,
6002                                           StringRef Mnemonic,
6003                                           OperandMode Mode) {
6004   ParseStatus Res = parseVOPD(Operands);
6005   if (Res.isSuccess() || Res.isFailure() || isToken(AsmToken::EndOfStatement))
6006     return Res;
6007 
6008   // Try to parse with a custom parser
6009   Res = MatchOperandParserImpl(Operands, Mnemonic);
6010 
6011   // If we successfully parsed the operand or if there as an error parsing,
6012   // we are done.
6013   //
6014   // If we are parsing after we reach EndOfStatement then this means we
6015   // are appending default values to the Operands list.  This is only done
6016   // by custom parser, so we shouldn't continue on to the generic parsing.
6017   if (Res.isSuccess() || Res.isFailure() || isToken(AsmToken::EndOfStatement))
6018     return Res;
6019 
6020   SMLoc RBraceLoc;
6021   SMLoc LBraceLoc = getLoc();
6022   if (Mode == OperandMode_NSA && trySkipToken(AsmToken::LBrac)) {
6023     unsigned Prefix = Operands.size();
6024 
6025     for (;;) {
6026       auto Loc = getLoc();
6027       Res = parseReg(Operands);
6028       if (Res.isNoMatch())
6029         Error(Loc, "expected a register");
6030       if (!Res.isSuccess())
6031         return ParseStatus::Failure;
6032 
6033       RBraceLoc = getLoc();
6034       if (trySkipToken(AsmToken::RBrac))
6035         break;
6036 
6037       if (!skipToken(AsmToken::Comma,
6038                      "expected a comma or a closing square bracket"))
6039         return ParseStatus::Failure;
6040     }
6041 
6042     if (Operands.size() - Prefix > 1) {
6043       Operands.insert(Operands.begin() + Prefix,
6044                       AMDGPUOperand::CreateToken(this, "[", LBraceLoc));
6045       Operands.push_back(AMDGPUOperand::CreateToken(this, "]", RBraceLoc));
6046     }
6047 
6048     return ParseStatus::Success;
6049   }
6050 
6051   return parseRegOrImm(Operands);
6052 }
6053 
6054 StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6055   // Clear any forced encodings from the previous instruction.
6056   setForcedEncodingSize(0);
6057   setForcedDPP(false);
6058   setForcedSDWA(false);
6059 
6060   if (Name.ends_with("_e64_dpp")) {
6061     setForcedDPP(true);
6062     setForcedEncodingSize(64);
6063     return Name.substr(0, Name.size() - 8);
6064   } else if (Name.ends_with("_e64")) {
6065     setForcedEncodingSize(64);
6066     return Name.substr(0, Name.size() - 4);
6067   } else if (Name.ends_with("_e32")) {
6068     setForcedEncodingSize(32);
6069     return Name.substr(0, Name.size() - 4);
6070   } else if (Name.ends_with("_dpp")) {
6071     setForcedDPP(true);
6072     return Name.substr(0, Name.size() - 4);
6073   } else if (Name.ends_with("_sdwa")) {
6074     setForcedSDWA(true);
6075     return Name.substr(0, Name.size() - 5);
6076   }
6077   return Name;
6078 }
6079 
6080 static void applyMnemonicAliases(StringRef &Mnemonic,
6081                                  const FeatureBitset &Features,
6082                                  unsigned VariantID);
6083 
6084 bool AMDGPUAsmParser::ParseInstruction(ParseInstructionInfo &Info,
6085                                        StringRef Name,
6086                                        SMLoc NameLoc, OperandVector &Operands) {
6087   // Add the instruction mnemonic
6088   Name = parseMnemonicSuffix(Name);
6089 
6090   // If the target architecture uses MnemonicAlias, call it here to parse
6091   // operands correctly.
6092   applyMnemonicAliases(Name, getAvailableFeatures(), 0);
6093 
6094   Operands.push_back(AMDGPUOperand::CreateToken(this, Name, NameLoc));
6095 
6096   bool IsMIMG = Name.starts_with("image_");
6097 
6098   while (!trySkipToken(AsmToken::EndOfStatement)) {
6099     OperandMode Mode = OperandMode_Default;
6100     if (IsMIMG && isGFX10Plus() && Operands.size() == 2)
6101       Mode = OperandMode_NSA;
6102     ParseStatus Res = parseOperand(Operands, Name, Mode);
6103 
6104     if (!Res.isSuccess()) {
6105       checkUnsupportedInstruction(Name, NameLoc);
6106       if (!Parser.hasPendingError()) {
6107         // FIXME: use real operand location rather than the current location.
6108         StringRef Msg = Res.isFailure() ? "failed parsing operand."
6109                                         : "not a valid operand.";
6110         Error(getLoc(), Msg);
6111       }
6112       while (!trySkipToken(AsmToken::EndOfStatement)) {
6113         lex();
6114       }
6115       return true;
6116     }
6117 
6118     // Eat the comma or space if there is one.
6119     trySkipToken(AsmToken::Comma);
6120   }
6121 
6122   return false;
6123 }
6124 
6125 //===----------------------------------------------------------------------===//
6126 // Utility functions
6127 //===----------------------------------------------------------------------===//
6128 
6129 ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6130                                           OperandVector &Operands) {
6131   SMLoc S = getLoc();
6132   if (!trySkipId(Name))
6133     return ParseStatus::NoMatch;
6134 
6135   Operands.push_back(AMDGPUOperand::CreateToken(this, Name, S));
6136   return ParseStatus::Success;
6137 }
6138 
6139 ParseStatus AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix,
6140                                                 int64_t &IntVal) {
6141 
6142   if (!trySkipId(Prefix, AsmToken::Colon))
6143     return ParseStatus::NoMatch;
6144 
6145   return parseExpr(IntVal) ? ParseStatus::Success : ParseStatus::Failure;
6146 }
6147 
6148 ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
6149     const char *Prefix, OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6150     std::function<bool(int64_t &)> ConvertResult) {
6151   SMLoc S = getLoc();
6152   int64_t Value = 0;
6153 
6154   ParseStatus Res = parseIntWithPrefix(Prefix, Value);
6155   if (!Res.isSuccess())
6156     return Res;
6157 
6158   if (ConvertResult && !ConvertResult(Value)) {
6159     Error(S, "invalid " + StringRef(Prefix) + " value.");
6160   }
6161 
6162   Operands.push_back(AMDGPUOperand::CreateImm(this, Value, S, ImmTy));
6163   return ParseStatus::Success;
6164 }
6165 
6166 ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
6167     const char *Prefix, OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6168     bool (*ConvertResult)(int64_t &)) {
6169   SMLoc S = getLoc();
6170   if (!trySkipId(Prefix, AsmToken::Colon))
6171     return ParseStatus::NoMatch;
6172 
6173   if (!skipToken(AsmToken::LBrac, "expected a left square bracket"))
6174     return ParseStatus::Failure;
6175 
6176   unsigned Val = 0;
6177   const unsigned MaxSize = 4;
6178 
6179   // FIXME: How to verify the number of elements matches the number of src
6180   // operands?
6181   for (int I = 0; ; ++I) {
6182     int64_t Op;
6183     SMLoc Loc = getLoc();
6184     if (!parseExpr(Op))
6185       return ParseStatus::Failure;
6186 
6187     if (Op != 0 && Op != 1)
6188       return Error(Loc, "invalid " + StringRef(Prefix) + " value.");
6189 
6190     Val |= (Op << I);
6191 
6192     if (trySkipToken(AsmToken::RBrac))
6193       break;
6194 
6195     if (I + 1 == MaxSize)
6196       return Error(getLoc(), "expected a closing square bracket");
6197 
6198     if (!skipToken(AsmToken::Comma, "expected a comma"))
6199       return ParseStatus::Failure;
6200   }
6201 
6202   Operands.push_back(AMDGPUOperand::CreateImm(this, Val, S, ImmTy));
6203   return ParseStatus::Success;
6204 }
6205 
6206 ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
6207                                            OperandVector &Operands,
6208                                            AMDGPUOperand::ImmTy ImmTy) {
6209   int64_t Bit;
6210   SMLoc S = getLoc();
6211 
6212   if (trySkipId(Name)) {
6213     Bit = 1;
6214   } else if (trySkipId("no", Name)) {
6215     Bit = 0;
6216   } else {
6217     return ParseStatus::NoMatch;
6218   }
6219 
6220   if (Name == "r128" && !hasMIMG_R128())
6221     return Error(S, "r128 modifier is not supported on this GPU");
6222   if (Name == "a16" && !hasA16())
6223     return Error(S, "a16 modifier is not supported on this GPU");
6224 
6225   if (isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
6226     ImmTy = AMDGPUOperand::ImmTyR128A16;
6227 
6228   Operands.push_back(AMDGPUOperand::CreateImm(this, Bit, S, ImmTy));
6229   return ParseStatus::Success;
6230 }
6231 
6232 unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
6233                                       bool &Disabling) const {
6234   Disabling = Id.consume_front("no");
6235 
6236   if (isGFX940() && !Mnemo.starts_with("s_")) {
6237     return StringSwitch<unsigned>(Id)
6238         .Case("nt", AMDGPU::CPol::NT)
6239         .Case("sc0", AMDGPU::CPol::SC0)
6240         .Case("sc1", AMDGPU::CPol::SC1)
6241         .Default(0);
6242   }
6243 
6244   return StringSwitch<unsigned>(Id)
6245       .Case("dlc", AMDGPU::CPol::DLC)
6246       .Case("glc", AMDGPU::CPol::GLC)
6247       .Case("scc", AMDGPU::CPol::SCC)
6248       .Case("slc", AMDGPU::CPol::SLC)
6249       .Default(0);
6250 }
6251 
6252 ParseStatus AMDGPUAsmParser::parseCPol(OperandVector &Operands) {
6253   if (isGFX12Plus()) {
6254     SMLoc StringLoc = getLoc();
6255 
6256     int64_t CPolVal = 0;
6257     ParseStatus ResTH = ParseStatus::NoMatch;
6258     ParseStatus ResScope = ParseStatus::NoMatch;
6259 
6260     for (;;) {
6261       if (ResTH.isNoMatch()) {
6262         int64_t TH;
6263         ResTH = parseTH(Operands, TH);
6264         if (ResTH.isFailure())
6265           return ResTH;
6266         if (ResTH.isSuccess()) {
6267           CPolVal |= TH;
6268           continue;
6269         }
6270       }
6271 
6272       if (ResScope.isNoMatch()) {
6273         int64_t Scope;
6274         ResScope = parseScope(Operands, Scope);
6275         if (ResScope.isFailure())
6276           return ResScope;
6277         if (ResScope.isSuccess()) {
6278           CPolVal |= Scope;
6279           continue;
6280         }
6281       }
6282 
6283       break;
6284     }
6285 
6286     if (ResTH.isNoMatch() && ResScope.isNoMatch())
6287       return ParseStatus::NoMatch;
6288 
6289     Operands.push_back(AMDGPUOperand::CreateImm(this, CPolVal, StringLoc,
6290                                                 AMDGPUOperand::ImmTyCPol));
6291     return ParseStatus::Success;
6292   }
6293 
6294   StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).getToken();
6295   SMLoc OpLoc = getLoc();
6296   unsigned Enabled = 0, Seen = 0;
6297   for (;;) {
6298     SMLoc S = getLoc();
6299     bool Disabling;
6300     unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
6301     if (!CPol)
6302       break;
6303 
6304     lex();
6305 
6306     if (!isGFX10Plus() && CPol == AMDGPU::CPol::DLC)
6307       return Error(S, "dlc modifier is not supported on this GPU");
6308 
6309     if (!isGFX90A() && CPol == AMDGPU::CPol::SCC)
6310       return Error(S, "scc modifier is not supported on this GPU");
6311 
6312     if (Seen & CPol)
6313       return Error(S, "duplicate cache policy modifier");
6314 
6315     if (!Disabling)
6316       Enabled |= CPol;
6317 
6318     Seen |= CPol;
6319   }
6320 
6321   if (!Seen)
6322     return ParseStatus::NoMatch;
6323 
6324   Operands.push_back(
6325       AMDGPUOperand::CreateImm(this, Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
6326   return ParseStatus::Success;
6327 }
6328 
6329 ParseStatus AMDGPUAsmParser::parseScope(OperandVector &Operands,
6330                                         int64_t &Scope) {
6331   Scope = AMDGPU::CPol::SCOPE_CU; // default;
6332 
6333   StringRef Value;
6334   SMLoc StringLoc;
6335   ParseStatus Res;
6336 
6337   Res = parseStringWithPrefix("scope", Value, StringLoc);
6338   if (!Res.isSuccess())
6339     return Res;
6340 
6341   Scope = StringSwitch<int64_t>(Value)
6342               .Case("SCOPE_CU", AMDGPU::CPol::SCOPE_CU)
6343               .Case("SCOPE_SE", AMDGPU::CPol::SCOPE_SE)
6344               .Case("SCOPE_DEV", AMDGPU::CPol::SCOPE_DEV)
6345               .Case("SCOPE_SYS", AMDGPU::CPol::SCOPE_SYS)
6346               .Default(0xffffffff);
6347 
6348   if (Scope == 0xffffffff)
6349     return Error(StringLoc, "invalid scope value");
6350 
6351   return ParseStatus::Success;
6352 }
6353 
6354 ParseStatus AMDGPUAsmParser::parseTH(OperandVector &Operands, int64_t &TH) {
6355   TH = AMDGPU::CPol::TH_RT; // default
6356 
6357   StringRef Value;
6358   SMLoc StringLoc;
6359   ParseStatus Res = parseStringWithPrefix("th", Value, StringLoc);
6360   if (!Res.isSuccess())
6361     return Res;
6362 
6363   if (Value == "TH_DEFAULT")
6364     TH = AMDGPU::CPol::TH_RT;
6365   else if (Value == "TH_STORE_LU" || Value == "TH_LOAD_RT_WB" ||
6366            Value == "TH_LOAD_NT_WB") {
6367     return Error(StringLoc, "invalid th value");
6368   } else if (Value.starts_with("TH_ATOMIC_")) {
6369     Value = Value.drop_front(10);
6370     TH = AMDGPU::CPol::TH_TYPE_ATOMIC;
6371   } else if (Value.starts_with("TH_LOAD_")) {
6372     Value = Value.drop_front(8);
6373     TH = AMDGPU::CPol::TH_TYPE_LOAD;
6374   } else if (Value.starts_with("TH_STORE_")) {
6375     Value = Value.drop_front(9);
6376     TH = AMDGPU::CPol::TH_TYPE_STORE;
6377   } else {
6378     return Error(StringLoc, "invalid th value");
6379   }
6380 
6381   if (Value == "BYPASS")
6382     TH |= AMDGPU::CPol::TH_REAL_BYPASS;
6383 
6384   if (TH != 0) {
6385     if (TH & AMDGPU::CPol::TH_TYPE_ATOMIC)
6386       TH |= StringSwitch<int64_t>(Value)
6387                 .Case("RETURN", AMDGPU::CPol::TH_ATOMIC_RETURN)
6388                 .Case("RT", AMDGPU::CPol::TH_RT)
6389                 .Case("RT_RETURN", AMDGPU::CPol::TH_ATOMIC_RETURN)
6390                 .Case("NT", AMDGPU::CPol::TH_ATOMIC_NT)
6391                 .Case("NT_RETURN", AMDGPU::CPol::TH_ATOMIC_NT |
6392                                        AMDGPU::CPol::TH_ATOMIC_RETURN)
6393                 .Case("CASCADE_RT", AMDGPU::CPol::TH_ATOMIC_CASCADE)
6394                 .Case("CASCADE_NT", AMDGPU::CPol::TH_ATOMIC_CASCADE |
6395                                         AMDGPU::CPol::TH_ATOMIC_NT)
6396                 .Default(0xffffffff);
6397     else
6398       TH |= StringSwitch<int64_t>(Value)
6399                 .Case("RT", AMDGPU::CPol::TH_RT)
6400                 .Case("NT", AMDGPU::CPol::TH_NT)
6401                 .Case("HT", AMDGPU::CPol::TH_HT)
6402                 .Case("LU", AMDGPU::CPol::TH_LU)
6403                 .Case("RT_WB", AMDGPU::CPol::TH_RT_WB)
6404                 .Case("NT_RT", AMDGPU::CPol::TH_NT_RT)
6405                 .Case("RT_NT", AMDGPU::CPol::TH_RT_NT)
6406                 .Case("NT_HT", AMDGPU::CPol::TH_NT_HT)
6407                 .Case("NT_WB", AMDGPU::CPol::TH_NT_WB)
6408                 .Case("BYPASS", AMDGPU::CPol::TH_BYPASS)
6409                 .Default(0xffffffff);
6410   }
6411 
6412   if (TH == 0xffffffff)
6413     return Error(StringLoc, "invalid th value");
6414 
6415   return ParseStatus::Success;
6416 }
6417 
6418 static void addOptionalImmOperand(
6419   MCInst& Inst, const OperandVector& Operands,
6420   AMDGPUAsmParser::OptionalImmIndexMap& OptionalIdx,
6421   AMDGPUOperand::ImmTy ImmT,
6422   int64_t Default = 0) {
6423   auto i = OptionalIdx.find(ImmT);
6424   if (i != OptionalIdx.end()) {
6425     unsigned Idx = i->second;
6426     ((AMDGPUOperand &)*Operands[Idx]).addImmOperands(Inst, 1);
6427   } else {
6428     Inst.addOperand(MCOperand::createImm(Default));
6429   }
6430 }
6431 
6432 ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
6433                                                    StringRef &Value,
6434                                                    SMLoc &StringLoc) {
6435   if (!trySkipId(Prefix, AsmToken::Colon))
6436     return ParseStatus::NoMatch;
6437 
6438   StringLoc = getLoc();
6439   return parseId(Value, "expected an identifier") ? ParseStatus::Success
6440                                                   : ParseStatus::Failure;
6441 }
6442 
6443 //===----------------------------------------------------------------------===//
6444 // MTBUF format
6445 //===----------------------------------------------------------------------===//
6446 
6447 bool AMDGPUAsmParser::tryParseFmt(const char *Pref,
6448                                   int64_t MaxVal,
6449                                   int64_t &Fmt) {
6450   int64_t Val;
6451   SMLoc Loc = getLoc();
6452 
6453   auto Res = parseIntWithPrefix(Pref, Val);
6454   if (Res.isFailure())
6455     return false;
6456   if (Res.isNoMatch())
6457     return true;
6458 
6459   if (Val < 0 || Val > MaxVal) {
6460     Error(Loc, Twine("out of range ", StringRef(Pref)));
6461     return false;
6462   }
6463 
6464   Fmt = Val;
6465   return true;
6466 }
6467 
6468 // dfmt and nfmt (in a tbuffer instruction) are parsed as one to allow their
6469 // values to live in a joint format operand in the MCInst encoding.
6470 ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &Format) {
6471   using namespace llvm::AMDGPU::MTBUFFormat;
6472 
6473   int64_t Dfmt = DFMT_UNDEF;
6474   int64_t Nfmt = NFMT_UNDEF;
6475 
6476   // dfmt and nfmt can appear in either order, and each is optional.
6477   for (int I = 0; I < 2; ++I) {
6478     if (Dfmt == DFMT_UNDEF && !tryParseFmt("dfmt", DFMT_MAX, Dfmt))
6479       return ParseStatus::Failure;
6480 
6481     if (Nfmt == NFMT_UNDEF && !tryParseFmt("nfmt", NFMT_MAX, Nfmt))
6482       return ParseStatus::Failure;
6483 
6484     // Skip optional comma between dfmt/nfmt
6485     // but guard against 2 commas following each other.
6486     if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
6487         !peekToken().is(AsmToken::Comma)) {
6488       trySkipToken(AsmToken::Comma);
6489     }
6490   }
6491 
6492   if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
6493     return ParseStatus::NoMatch;
6494 
6495   Dfmt = (Dfmt == DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
6496   Nfmt = (Nfmt == NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
6497 
6498   Format = encodeDfmtNfmt(Dfmt, Nfmt);
6499   return ParseStatus::Success;
6500 }
6501 
6502 ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &Format) {
6503   using namespace llvm::AMDGPU::MTBUFFormat;
6504 
6505   int64_t Fmt = UFMT_UNDEF;
6506 
6507   if (!tryParseFmt("format", UFMT_MAX, Fmt))
6508     return ParseStatus::Failure;
6509 
6510   if (Fmt == UFMT_UNDEF)
6511     return ParseStatus::NoMatch;
6512 
6513   Format = Fmt;
6514   return ParseStatus::Success;
6515 }
6516 
6517 bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
6518                                     int64_t &Nfmt,
6519                                     StringRef FormatStr,
6520                                     SMLoc Loc) {
6521   using namespace llvm::AMDGPU::MTBUFFormat;
6522   int64_t Format;
6523 
6524   Format = getDfmt(FormatStr);
6525   if (Format != DFMT_UNDEF) {
6526     Dfmt = Format;
6527     return true;
6528   }
6529 
6530   Format = getNfmt(FormatStr, getSTI());
6531   if (Format != NFMT_UNDEF) {
6532     Nfmt = Format;
6533     return true;
6534   }
6535 
6536   Error(Loc, "unsupported format");
6537   return false;
6538 }
6539 
6540 ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
6541                                                       SMLoc FormatLoc,
6542                                                       int64_t &Format) {
6543   using namespace llvm::AMDGPU::MTBUFFormat;
6544 
6545   int64_t Dfmt = DFMT_UNDEF;
6546   int64_t Nfmt = NFMT_UNDEF;
6547   if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
6548     return ParseStatus::Failure;
6549 
6550   if (trySkipToken(AsmToken::Comma)) {
6551     StringRef Str;
6552     SMLoc Loc = getLoc();
6553     if (!parseId(Str, "expected a format string") ||
6554         !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
6555       return ParseStatus::Failure;
6556     if (Dfmt == DFMT_UNDEF)
6557       return Error(Loc, "duplicate numeric format");
6558     if (Nfmt == NFMT_UNDEF)
6559       return Error(Loc, "duplicate data format");
6560   }
6561 
6562   Dfmt = (Dfmt == DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
6563   Nfmt = (Nfmt == NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
6564 
6565   if (isGFX10Plus()) {
6566     auto Ufmt = convertDfmtNfmt2Ufmt(Dfmt, Nfmt, getSTI());
6567     if (Ufmt == UFMT_UNDEF)
6568       return Error(FormatLoc, "unsupported format");
6569     Format = Ufmt;
6570   } else {
6571     Format = encodeDfmtNfmt(Dfmt, Nfmt);
6572   }
6573 
6574   return ParseStatus::Success;
6575 }
6576 
6577 ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
6578                                                         SMLoc Loc,
6579                                                         int64_t &Format) {
6580   using namespace llvm::AMDGPU::MTBUFFormat;
6581 
6582   auto Id = getUnifiedFormat(FormatStr, getSTI());
6583   if (Id == UFMT_UNDEF)
6584     return ParseStatus::NoMatch;
6585 
6586   if (!isGFX10Plus())
6587     return Error(Loc, "unified format is not supported on this GPU");
6588 
6589   Format = Id;
6590   return ParseStatus::Success;
6591 }
6592 
6593 ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &Format) {
6594   using namespace llvm::AMDGPU::MTBUFFormat;
6595   SMLoc Loc = getLoc();
6596 
6597   if (!parseExpr(Format))
6598     return ParseStatus::Failure;
6599   if (!isValidFormatEncoding(Format, getSTI()))
6600     return Error(Loc, "out of range format");
6601 
6602   return ParseStatus::Success;
6603 }
6604 
6605 ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &Format) {
6606   using namespace llvm::AMDGPU::MTBUFFormat;
6607 
6608   if (!trySkipId("format", AsmToken::Colon))
6609     return ParseStatus::NoMatch;
6610 
6611   if (trySkipToken(AsmToken::LBrac)) {
6612     StringRef FormatStr;
6613     SMLoc Loc = getLoc();
6614     if (!parseId(FormatStr, "expected a format string"))
6615       return ParseStatus::Failure;
6616 
6617     auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc, Format);
6618     if (Res.isNoMatch())
6619       Res = parseSymbolicSplitFormat(FormatStr, Loc, Format);
6620     if (!Res.isSuccess())
6621       return Res;
6622 
6623     if (!skipToken(AsmToken::RBrac, "expected a closing square bracket"))
6624       return ParseStatus::Failure;
6625 
6626     return ParseStatus::Success;
6627   }
6628 
6629   return parseNumericFormat(Format);
6630 }
6631 
6632 ParseStatus AMDGPUAsmParser::parseFORMAT(OperandVector &Operands) {
6633   using namespace llvm::AMDGPU::MTBUFFormat;
6634 
6635   int64_t Format = getDefaultFormatEncoding(getSTI());
6636   ParseStatus Res;
6637   SMLoc Loc = getLoc();
6638 
6639   // Parse legacy format syntax.
6640   Res = isGFX10Plus() ? parseUfmt(Format) : parseDfmtNfmt(Format);
6641   if (Res.isFailure())
6642     return Res;
6643 
6644   bool FormatFound = Res.isSuccess();
6645 
6646   Operands.push_back(
6647     AMDGPUOperand::CreateImm(this, Format, Loc, AMDGPUOperand::ImmTyFORMAT));
6648 
6649   if (FormatFound)
6650     trySkipToken(AsmToken::Comma);
6651 
6652   if (isToken(AsmToken::EndOfStatement)) {
6653     // We are expecting an soffset operand,
6654     // but let matcher handle the error.
6655     return ParseStatus::Success;
6656   }
6657 
6658   // Parse soffset.
6659   Res = parseRegOrImm(Operands);
6660   if (!Res.isSuccess())
6661     return Res;
6662 
6663   trySkipToken(AsmToken::Comma);
6664 
6665   if (!FormatFound) {
6666     Res = parseSymbolicOrNumericFormat(Format);
6667     if (Res.isFailure())
6668       return Res;
6669     if (Res.isSuccess()) {
6670       auto Size = Operands.size();
6671       AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands[Size - 2]);
6672       assert(Op.isImm() && Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
6673       Op.setImm(Format);
6674     }
6675     return ParseStatus::Success;
6676   }
6677 
6678   if (isId("format") && peekToken().is(AsmToken::Colon))
6679     return Error(getLoc(), "duplicate format");
6680   return ParseStatus::Success;
6681 }
6682 
6683 ParseStatus AMDGPUAsmParser::parseFlatOffset(OperandVector &Operands) {
6684   ParseStatus Res =
6685       parseIntWithPrefix("offset", Operands, AMDGPUOperand::ImmTyOffset);
6686   if (Res.isNoMatch()) {
6687     Res = parseIntWithPrefix("inst_offset", Operands,
6688                              AMDGPUOperand::ImmTyInstOffset);
6689   }
6690   return Res;
6691 }
6692 
6693 ParseStatus AMDGPUAsmParser::parseR128A16(OperandVector &Operands) {
6694   ParseStatus Res =
6695       parseNamedBit("r128", Operands, AMDGPUOperand::ImmTyR128A16);
6696   if (Res.isNoMatch())
6697     Res = parseNamedBit("a16", Operands, AMDGPUOperand::ImmTyA16);
6698   return Res;
6699 }
6700 
6701 ParseStatus AMDGPUAsmParser::parseBLGP(OperandVector &Operands) {
6702   ParseStatus Res =
6703       parseIntWithPrefix("blgp", Operands, AMDGPUOperand::ImmTyBLGP);
6704   if (Res.isNoMatch()) {
6705     Res =
6706         parseOperandArrayWithPrefix("neg", Operands, AMDGPUOperand::ImmTyBLGP);
6707   }
6708   return Res;
6709 }
6710 
6711 //===----------------------------------------------------------------------===//
6712 // Exp
6713 //===----------------------------------------------------------------------===//
6714 
6715 void AMDGPUAsmParser::cvtExp(MCInst &Inst, const OperandVector &Operands) {
6716   OptionalImmIndexMap OptionalIdx;
6717 
6718   unsigned OperandIdx[4];
6719   unsigned EnMask = 0;
6720   int SrcIdx = 0;
6721 
6722   for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
6723     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
6724 
6725     // Add the register arguments
6726     if (Op.isReg()) {
6727       assert(SrcIdx < 4);
6728       OperandIdx[SrcIdx] = Inst.size();
6729       Op.addRegOperands(Inst, 1);
6730       ++SrcIdx;
6731       continue;
6732     }
6733 
6734     if (Op.isOff()) {
6735       assert(SrcIdx < 4);
6736       OperandIdx[SrcIdx] = Inst.size();
6737       Inst.addOperand(MCOperand::createReg(AMDGPU::NoRegister));
6738       ++SrcIdx;
6739       continue;
6740     }
6741 
6742     if (Op.isImm() && Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
6743       Op.addImmOperands(Inst, 1);
6744       continue;
6745     }
6746 
6747     if (Op.isToken() && (Op.getToken() == "done" || Op.getToken() == "row_en"))
6748       continue;
6749 
6750     // Handle optional arguments
6751     OptionalIdx[Op.getImmTy()] = i;
6752   }
6753 
6754   assert(SrcIdx == 4);
6755 
6756   bool Compr = false;
6757   if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
6758     Compr = true;
6759     Inst.getOperand(OperandIdx[1]) = Inst.getOperand(OperandIdx[2]);
6760     Inst.getOperand(OperandIdx[2]).setReg(AMDGPU::NoRegister);
6761     Inst.getOperand(OperandIdx[3]).setReg(AMDGPU::NoRegister);
6762   }
6763 
6764   for (auto i = 0; i < SrcIdx; ++i) {
6765     if (Inst.getOperand(OperandIdx[i]).getReg() != AMDGPU::NoRegister) {
6766       EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
6767     }
6768   }
6769 
6770   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyExpVM);
6771   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyExpCompr);
6772 
6773   Inst.addOperand(MCOperand::createImm(EnMask));
6774 }
6775 
6776 //===----------------------------------------------------------------------===//
6777 // s_waitcnt
6778 //===----------------------------------------------------------------------===//
6779 
6780 static bool
6781 encodeCnt(
6782   const AMDGPU::IsaVersion ISA,
6783   int64_t &IntVal,
6784   int64_t CntVal,
6785   bool Saturate,
6786   unsigned (*encode)(const IsaVersion &Version, unsigned, unsigned),
6787   unsigned (*decode)(const IsaVersion &Version, unsigned))
6788 {
6789   bool Failed = false;
6790 
6791   IntVal = encode(ISA, IntVal, CntVal);
6792   if (CntVal != decode(ISA, IntVal)) {
6793     if (Saturate) {
6794       IntVal = encode(ISA, IntVal, -1);
6795     } else {
6796       Failed = true;
6797     }
6798   }
6799   return Failed;
6800 }
6801 
6802 bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
6803 
6804   SMLoc CntLoc = getLoc();
6805   StringRef CntName = getTokenStr();
6806 
6807   if (!skipToken(AsmToken::Identifier, "expected a counter name") ||
6808       !skipToken(AsmToken::LParen, "expected a left parenthesis"))
6809     return false;
6810 
6811   int64_t CntVal;
6812   SMLoc ValLoc = getLoc();
6813   if (!parseExpr(CntVal))
6814     return false;
6815 
6816   AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(getSTI().getCPU());
6817 
6818   bool Failed = true;
6819   bool Sat = CntName.ends_with("_sat");
6820 
6821   if (CntName == "vmcnt" || CntName == "vmcnt_sat") {
6822     Failed = encodeCnt(ISA, IntVal, CntVal, Sat, encodeVmcnt, decodeVmcnt);
6823   } else if (CntName == "expcnt" || CntName == "expcnt_sat") {
6824     Failed = encodeCnt(ISA, IntVal, CntVal, Sat, encodeExpcnt, decodeExpcnt);
6825   } else if (CntName == "lgkmcnt" || CntName == "lgkmcnt_sat") {
6826     Failed = encodeCnt(ISA, IntVal, CntVal, Sat, encodeLgkmcnt, decodeLgkmcnt);
6827   } else {
6828     Error(CntLoc, "invalid counter name " + CntName);
6829     return false;
6830   }
6831 
6832   if (Failed) {
6833     Error(ValLoc, "too large value for " + CntName);
6834     return false;
6835   }
6836 
6837   if (!skipToken(AsmToken::RParen, "expected a closing parenthesis"))
6838     return false;
6839 
6840   if (trySkipToken(AsmToken::Amp) || trySkipToken(AsmToken::Comma)) {
6841     if (isToken(AsmToken::EndOfStatement)) {
6842       Error(getLoc(), "expected a counter name");
6843       return false;
6844     }
6845   }
6846 
6847   return true;
6848 }
6849 
6850 ParseStatus AMDGPUAsmParser::parseSWaitCnt(OperandVector &Operands) {
6851   AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(getSTI().getCPU());
6852   int64_t Waitcnt = getWaitcntBitMask(ISA);
6853   SMLoc S = getLoc();
6854 
6855   if (isToken(AsmToken::Identifier) && peekToken().is(AsmToken::LParen)) {
6856     while (!isToken(AsmToken::EndOfStatement)) {
6857       if (!parseCnt(Waitcnt))
6858         return ParseStatus::Failure;
6859     }
6860   } else {
6861     if (!parseExpr(Waitcnt))
6862       return ParseStatus::Failure;
6863   }
6864 
6865   Operands.push_back(AMDGPUOperand::CreateImm(this, Waitcnt, S));
6866   return ParseStatus::Success;
6867 }
6868 
6869 bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
6870   SMLoc FieldLoc = getLoc();
6871   StringRef FieldName = getTokenStr();
6872   if (!skipToken(AsmToken::Identifier, "expected a field name") ||
6873       !skipToken(AsmToken::LParen, "expected a left parenthesis"))
6874     return false;
6875 
6876   SMLoc ValueLoc = getLoc();
6877   StringRef ValueName = getTokenStr();
6878   if (!skipToken(AsmToken::Identifier, "expected a value name") ||
6879       !skipToken(AsmToken::RParen, "expected a right parenthesis"))
6880     return false;
6881 
6882   unsigned Shift;
6883   if (FieldName == "instid0") {
6884     Shift = 0;
6885   } else if (FieldName == "instskip") {
6886     Shift = 4;
6887   } else if (FieldName == "instid1") {
6888     Shift = 7;
6889   } else {
6890     Error(FieldLoc, "invalid field name " + FieldName);
6891     return false;
6892   }
6893 
6894   int Value;
6895   if (Shift == 4) {
6896     // Parse values for instskip.
6897     Value = StringSwitch<int>(ValueName)
6898                 .Case("SAME", 0)
6899                 .Case("NEXT", 1)
6900                 .Case("SKIP_1", 2)
6901                 .Case("SKIP_2", 3)
6902                 .Case("SKIP_3", 4)
6903                 .Case("SKIP_4", 5)
6904                 .Default(-1);
6905   } else {
6906     // Parse values for instid0 and instid1.
6907     Value = StringSwitch<int>(ValueName)
6908                 .Case("NO_DEP", 0)
6909                 .Case("VALU_DEP_1", 1)
6910                 .Case("VALU_DEP_2", 2)
6911                 .Case("VALU_DEP_3", 3)
6912                 .Case("VALU_DEP_4", 4)
6913                 .Case("TRANS32_DEP_1", 5)
6914                 .Case("TRANS32_DEP_2", 6)
6915                 .Case("TRANS32_DEP_3", 7)
6916                 .Case("FMA_ACCUM_CYCLE_1", 8)
6917                 .Case("SALU_CYCLE_1", 9)
6918                 .Case("SALU_CYCLE_2", 10)
6919                 .Case("SALU_CYCLE_3", 11)
6920                 .Default(-1);
6921   }
6922   if (Value < 0) {
6923     Error(ValueLoc, "invalid value name " + ValueName);
6924     return false;
6925   }
6926 
6927   Delay |= Value << Shift;
6928   return true;
6929 }
6930 
6931 ParseStatus AMDGPUAsmParser::parseSDelayALU(OperandVector &Operands) {
6932   int64_t Delay = 0;
6933   SMLoc S = getLoc();
6934 
6935   if (isToken(AsmToken::Identifier) && peekToken().is(AsmToken::LParen)) {
6936     do {
6937       if (!parseDelay(Delay))
6938         return ParseStatus::Failure;
6939     } while (trySkipToken(AsmToken::Pipe));
6940   } else {
6941     if (!parseExpr(Delay))
6942       return ParseStatus::Failure;
6943   }
6944 
6945   Operands.push_back(AMDGPUOperand::CreateImm(this, Delay, S));
6946   return ParseStatus::Success;
6947 }
6948 
6949 bool
6950 AMDGPUOperand::isSWaitCnt() const {
6951   return isImm();
6952 }
6953 
6954 bool AMDGPUOperand::isSDelayALU() const { return isImm(); }
6955 
6956 //===----------------------------------------------------------------------===//
6957 // DepCtr
6958 //===----------------------------------------------------------------------===//
6959 
6960 void AMDGPUAsmParser::depCtrError(SMLoc Loc, int ErrorId,
6961                                   StringRef DepCtrName) {
6962   switch (ErrorId) {
6963   case OPR_ID_UNKNOWN:
6964     Error(Loc, Twine("invalid counter name ", DepCtrName));
6965     return;
6966   case OPR_ID_UNSUPPORTED:
6967     Error(Loc, Twine(DepCtrName, " is not supported on this GPU"));
6968     return;
6969   case OPR_ID_DUPLICATE:
6970     Error(Loc, Twine("duplicate counter name ", DepCtrName));
6971     return;
6972   case OPR_VAL_INVALID:
6973     Error(Loc, Twine("invalid value for ", DepCtrName));
6974     return;
6975   default:
6976     assert(false);
6977   }
6978 }
6979 
6980 bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr, unsigned &UsedOprMask) {
6981 
6982   using namespace llvm::AMDGPU::DepCtr;
6983 
6984   SMLoc DepCtrLoc = getLoc();
6985   StringRef DepCtrName = getTokenStr();
6986 
6987   if (!skipToken(AsmToken::Identifier, "expected a counter name") ||
6988       !skipToken(AsmToken::LParen, "expected a left parenthesis"))
6989     return false;
6990 
6991   int64_t ExprVal;
6992   if (!parseExpr(ExprVal))
6993     return false;
6994 
6995   unsigned PrevOprMask = UsedOprMask;
6996   int CntVal = encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
6997 
6998   if (CntVal < 0) {
6999     depCtrError(DepCtrLoc, CntVal, DepCtrName);
7000     return false;
7001   }
7002 
7003   if (!skipToken(AsmToken::RParen, "expected a closing parenthesis"))
7004     return false;
7005 
7006   if (trySkipToken(AsmToken::Amp) || trySkipToken(AsmToken::Comma)) {
7007     if (isToken(AsmToken::EndOfStatement)) {
7008       Error(getLoc(), "expected a counter name");
7009       return false;
7010     }
7011   }
7012 
7013   unsigned CntValMask = PrevOprMask ^ UsedOprMask;
7014   DepCtr = (DepCtr & ~CntValMask) | CntVal;
7015   return true;
7016 }
7017 
7018 ParseStatus AMDGPUAsmParser::parseDepCtr(OperandVector &Operands) {
7019   using namespace llvm::AMDGPU::DepCtr;
7020 
7021   int64_t DepCtr = getDefaultDepCtrEncoding(getSTI());
7022   SMLoc Loc = getLoc();
7023 
7024   if (isToken(AsmToken::Identifier) && peekToken().is(AsmToken::LParen)) {
7025     unsigned UsedOprMask = 0;
7026     while (!isToken(AsmToken::EndOfStatement)) {
7027       if (!parseDepCtr(DepCtr, UsedOprMask))
7028         return ParseStatus::Failure;
7029     }
7030   } else {
7031     if (!parseExpr(DepCtr))
7032       return ParseStatus::Failure;
7033   }
7034 
7035   Operands.push_back(AMDGPUOperand::CreateImm(this, DepCtr, Loc));
7036   return ParseStatus::Success;
7037 }
7038 
7039 bool AMDGPUOperand::isDepCtr() const { return isS16Imm(); }
7040 
7041 //===----------------------------------------------------------------------===//
7042 // hwreg
7043 //===----------------------------------------------------------------------===//
7044 
7045 bool
7046 AMDGPUAsmParser::parseHwregBody(OperandInfoTy &HwReg,
7047                                 OperandInfoTy &Offset,
7048                                 OperandInfoTy &Width) {
7049   using namespace llvm::AMDGPU::Hwreg;
7050 
7051   // The register may be specified by name or using a numeric code
7052   HwReg.Loc = getLoc();
7053   if (isToken(AsmToken::Identifier) &&
7054       (HwReg.Id = getHwregId(getTokenStr(), getSTI())) != OPR_ID_UNKNOWN) {
7055     HwReg.IsSymbolic = true;
7056     lex(); // skip register name
7057   } else if (!parseExpr(HwReg.Id, "a register name")) {
7058     return false;
7059   }
7060 
7061   if (trySkipToken(AsmToken::RParen))
7062     return true;
7063 
7064   // parse optional params
7065   if (!skipToken(AsmToken::Comma, "expected a comma or a closing parenthesis"))
7066     return false;
7067 
7068   Offset.Loc = getLoc();
7069   if (!parseExpr(Offset.Id))
7070     return false;
7071 
7072   if (!skipToken(AsmToken::Comma, "expected a comma"))
7073     return false;
7074 
7075   Width.Loc = getLoc();
7076   return parseExpr(Width.Id) &&
7077          skipToken(AsmToken::RParen, "expected a closing parenthesis");
7078 }
7079 
7080 bool
7081 AMDGPUAsmParser::validateHwreg(const OperandInfoTy &HwReg,
7082                                const OperandInfoTy &Offset,
7083                                const OperandInfoTy &Width) {
7084 
7085   using namespace llvm::AMDGPU::Hwreg;
7086 
7087   if (HwReg.IsSymbolic) {
7088     if (HwReg.Id == OPR_ID_UNSUPPORTED) {
7089       Error(HwReg.Loc,
7090             "specified hardware register is not supported on this GPU");
7091       return false;
7092     }
7093   } else {
7094     if (!isValidHwreg(HwReg.Id)) {
7095       Error(HwReg.Loc,
7096             "invalid code of hardware register: only 6-bit values are legal");
7097       return false;
7098     }
7099   }
7100   if (!isValidHwregOffset(Offset.Id)) {
7101     Error(Offset.Loc, "invalid bit offset: only 5-bit values are legal");
7102     return false;
7103   }
7104   if (!isValidHwregWidth(Width.Id)) {
7105     Error(Width.Loc,
7106           "invalid bitfield width: only values from 1 to 32 are legal");
7107     return false;
7108   }
7109   return true;
7110 }
7111 
7112 ParseStatus AMDGPUAsmParser::parseHwreg(OperandVector &Operands) {
7113   using namespace llvm::AMDGPU::Hwreg;
7114 
7115   int64_t ImmVal = 0;
7116   SMLoc Loc = getLoc();
7117 
7118   if (trySkipId("hwreg", AsmToken::LParen)) {
7119     OperandInfoTy HwReg(OPR_ID_UNKNOWN);
7120     OperandInfoTy Offset(OFFSET_DEFAULT_);
7121     OperandInfoTy Width(WIDTH_DEFAULT_);
7122     if (parseHwregBody(HwReg, Offset, Width) &&
7123         validateHwreg(HwReg, Offset, Width)) {
7124       ImmVal = encodeHwreg(HwReg.Id, Offset.Id, Width.Id);
7125     } else {
7126       return ParseStatus::Failure;
7127     }
7128   } else if (parseExpr(ImmVal, "a hwreg macro")) {
7129     if (ImmVal < 0 || !isUInt<16>(ImmVal))
7130       return Error(Loc, "invalid immediate: only 16-bit values are legal");
7131   } else {
7132     return ParseStatus::Failure;
7133   }
7134 
7135   Operands.push_back(AMDGPUOperand::CreateImm(this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
7136   return ParseStatus::Success;
7137 }
7138 
7139 bool AMDGPUOperand::isHwreg() const {
7140   return isImmTy(ImmTyHwreg);
7141 }
7142 
7143 //===----------------------------------------------------------------------===//
7144 // sendmsg
7145 //===----------------------------------------------------------------------===//
7146 
7147 bool
7148 AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
7149                                   OperandInfoTy &Op,
7150                                   OperandInfoTy &Stream) {
7151   using namespace llvm::AMDGPU::SendMsg;
7152 
7153   Msg.Loc = getLoc();
7154   if (isToken(AsmToken::Identifier) &&
7155       (Msg.Id = getMsgId(getTokenStr(), getSTI())) != OPR_ID_UNKNOWN) {
7156     Msg.IsSymbolic = true;
7157     lex(); // skip message name
7158   } else if (!parseExpr(Msg.Id, "a message name")) {
7159     return false;
7160   }
7161 
7162   if (trySkipToken(AsmToken::Comma)) {
7163     Op.IsDefined = true;
7164     Op.Loc = getLoc();
7165     if (isToken(AsmToken::Identifier) &&
7166         (Op.Id = getMsgOpId(Msg.Id, getTokenStr())) >= 0) {
7167       lex(); // skip operation name
7168     } else if (!parseExpr(Op.Id, "an operation name")) {
7169       return false;
7170     }
7171 
7172     if (trySkipToken(AsmToken::Comma)) {
7173       Stream.IsDefined = true;
7174       Stream.Loc = getLoc();
7175       if (!parseExpr(Stream.Id))
7176         return false;
7177     }
7178   }
7179 
7180   return skipToken(AsmToken::RParen, "expected a closing parenthesis");
7181 }
7182 
7183 bool
7184 AMDGPUAsmParser::validateSendMsg(const OperandInfoTy &Msg,
7185                                  const OperandInfoTy &Op,
7186                                  const OperandInfoTy &Stream) {
7187   using namespace llvm::AMDGPU::SendMsg;
7188 
7189   // Validation strictness depends on whether message is specified
7190   // in a symbolic or in a numeric form. In the latter case
7191   // only encoding possibility is checked.
7192   bool Strict = Msg.IsSymbolic;
7193 
7194   if (Strict) {
7195     if (Msg.Id == OPR_ID_UNSUPPORTED) {
7196       Error(Msg.Loc, "specified message id is not supported on this GPU");
7197       return false;
7198     }
7199   } else {
7200     if (!isValidMsgId(Msg.Id, getSTI())) {
7201       Error(Msg.Loc, "invalid message id");
7202       return false;
7203     }
7204   }
7205   if (Strict && (msgRequiresOp(Msg.Id, getSTI()) != Op.IsDefined)) {
7206     if (Op.IsDefined) {
7207       Error(Op.Loc, "message does not support operations");
7208     } else {
7209       Error(Msg.Loc, "missing message operation");
7210     }
7211     return false;
7212   }
7213   if (!isValidMsgOp(Msg.Id, Op.Id, getSTI(), Strict)) {
7214     Error(Op.Loc, "invalid operation id");
7215     return false;
7216   }
7217   if (Strict && !msgSupportsStream(Msg.Id, Op.Id, getSTI()) &&
7218       Stream.IsDefined) {
7219     Error(Stream.Loc, "message operation does not support streams");
7220     return false;
7221   }
7222   if (!isValidMsgStream(Msg.Id, Op.Id, Stream.Id, getSTI(), Strict)) {
7223     Error(Stream.Loc, "invalid message stream id");
7224     return false;
7225   }
7226   return true;
7227 }
7228 
7229 ParseStatus AMDGPUAsmParser::parseSendMsg(OperandVector &Operands) {
7230   using namespace llvm::AMDGPU::SendMsg;
7231 
7232   int64_t ImmVal = 0;
7233   SMLoc Loc = getLoc();
7234 
7235   if (trySkipId("sendmsg", AsmToken::LParen)) {
7236     OperandInfoTy Msg(OPR_ID_UNKNOWN);
7237     OperandInfoTy Op(OP_NONE_);
7238     OperandInfoTy Stream(STREAM_ID_NONE_);
7239     if (parseSendMsgBody(Msg, Op, Stream) &&
7240         validateSendMsg(Msg, Op, Stream)) {
7241       ImmVal = encodeMsg(Msg.Id, Op.Id, Stream.Id);
7242     } else {
7243       return ParseStatus::Failure;
7244     }
7245   } else if (parseExpr(ImmVal, "a sendmsg macro")) {
7246     if (ImmVal < 0 || !isUInt<16>(ImmVal))
7247       return Error(Loc, "invalid immediate: only 16-bit values are legal");
7248   } else {
7249     return ParseStatus::Failure;
7250   }
7251 
7252   Operands.push_back(AMDGPUOperand::CreateImm(this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
7253   return ParseStatus::Success;
7254 }
7255 
7256 bool AMDGPUOperand::isSendMsg() const {
7257   return isImmTy(ImmTySendMsg);
7258 }
7259 
7260 //===----------------------------------------------------------------------===//
7261 // v_interp
7262 //===----------------------------------------------------------------------===//
7263 
7264 ParseStatus AMDGPUAsmParser::parseInterpSlot(OperandVector &Operands) {
7265   StringRef Str;
7266   SMLoc S = getLoc();
7267 
7268   if (!parseId(Str))
7269     return ParseStatus::NoMatch;
7270 
7271   int Slot = StringSwitch<int>(Str)
7272     .Case("p10", 0)
7273     .Case("p20", 1)
7274     .Case("p0", 2)
7275     .Default(-1);
7276 
7277   if (Slot == -1)
7278     return Error(S, "invalid interpolation slot");
7279 
7280   Operands.push_back(AMDGPUOperand::CreateImm(this, Slot, S,
7281                                               AMDGPUOperand::ImmTyInterpSlot));
7282   return ParseStatus::Success;
7283 }
7284 
7285 ParseStatus AMDGPUAsmParser::parseInterpAttr(OperandVector &Operands) {
7286   StringRef Str;
7287   SMLoc S = getLoc();
7288 
7289   if (!parseId(Str))
7290     return ParseStatus::NoMatch;
7291 
7292   if (!Str.starts_with("attr"))
7293     return Error(S, "invalid interpolation attribute");
7294 
7295   StringRef Chan = Str.take_back(2);
7296   int AttrChan = StringSwitch<int>(Chan)
7297     .Case(".x", 0)
7298     .Case(".y", 1)
7299     .Case(".z", 2)
7300     .Case(".w", 3)
7301     .Default(-1);
7302   if (AttrChan == -1)
7303     return Error(S, "invalid or missing interpolation attribute channel");
7304 
7305   Str = Str.drop_back(2).drop_front(4);
7306 
7307   uint8_t Attr;
7308   if (Str.getAsInteger(10, Attr))
7309     return Error(S, "invalid or missing interpolation attribute number");
7310 
7311   if (Attr > 32)
7312     return Error(S, "out of bounds interpolation attribute number");
7313 
7314   SMLoc SChan = SMLoc::getFromPointer(Chan.data());
7315 
7316   Operands.push_back(AMDGPUOperand::CreateImm(this, Attr, S,
7317                                               AMDGPUOperand::ImmTyInterpAttr));
7318   Operands.push_back(AMDGPUOperand::CreateImm(
7319       this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
7320   return ParseStatus::Success;
7321 }
7322 
7323 //===----------------------------------------------------------------------===//
7324 // exp
7325 //===----------------------------------------------------------------------===//
7326 
7327 ParseStatus AMDGPUAsmParser::parseExpTgt(OperandVector &Operands) {
7328   using namespace llvm::AMDGPU::Exp;
7329 
7330   StringRef Str;
7331   SMLoc S = getLoc();
7332 
7333   if (!parseId(Str))
7334     return ParseStatus::NoMatch;
7335 
7336   unsigned Id = getTgtId(Str);
7337   if (Id == ET_INVALID || !isSupportedTgtId(Id, getSTI()))
7338     return Error(S, (Id == ET_INVALID)
7339                         ? "invalid exp target"
7340                         : "exp target is not supported on this GPU");
7341 
7342   Operands.push_back(AMDGPUOperand::CreateImm(this, Id, S,
7343                                               AMDGPUOperand::ImmTyExpTgt));
7344   return ParseStatus::Success;
7345 }
7346 
7347 //===----------------------------------------------------------------------===//
7348 // parser helpers
7349 //===----------------------------------------------------------------------===//
7350 
7351 bool
7352 AMDGPUAsmParser::isId(const AsmToken &Token, const StringRef Id) const {
7353   return Token.is(AsmToken::Identifier) && Token.getString() == Id;
7354 }
7355 
7356 bool
7357 AMDGPUAsmParser::isId(const StringRef Id) const {
7358   return isId(getToken(), Id);
7359 }
7360 
7361 bool
7362 AMDGPUAsmParser::isToken(const AsmToken::TokenKind Kind) const {
7363   return getTokenKind() == Kind;
7364 }
7365 
7366 StringRef AMDGPUAsmParser::getId() const {
7367   return isToken(AsmToken::Identifier) ? getTokenStr() : StringRef();
7368 }
7369 
7370 bool
7371 AMDGPUAsmParser::trySkipId(const StringRef Id) {
7372   if (isId(Id)) {
7373     lex();
7374     return true;
7375   }
7376   return false;
7377 }
7378 
7379 bool
7380 AMDGPUAsmParser::trySkipId(const StringRef Pref, const StringRef Id) {
7381   if (isToken(AsmToken::Identifier)) {
7382     StringRef Tok = getTokenStr();
7383     if (Tok.starts_with(Pref) && Tok.drop_front(Pref.size()) == Id) {
7384       lex();
7385       return true;
7386     }
7387   }
7388   return false;
7389 }
7390 
7391 bool
7392 AMDGPUAsmParser::trySkipId(const StringRef Id, const AsmToken::TokenKind Kind) {
7393   if (isId(Id) && peekToken().is(Kind)) {
7394     lex();
7395     lex();
7396     return true;
7397   }
7398   return false;
7399 }
7400 
7401 bool
7402 AMDGPUAsmParser::trySkipToken(const AsmToken::TokenKind Kind) {
7403   if (isToken(Kind)) {
7404     lex();
7405     return true;
7406   }
7407   return false;
7408 }
7409 
7410 bool
7411 AMDGPUAsmParser::skipToken(const AsmToken::TokenKind Kind,
7412                            const StringRef ErrMsg) {
7413   if (!trySkipToken(Kind)) {
7414     Error(getLoc(), ErrMsg);
7415     return false;
7416   }
7417   return true;
7418 }
7419 
7420 bool
7421 AMDGPUAsmParser::parseExpr(int64_t &Imm, StringRef Expected) {
7422   SMLoc S = getLoc();
7423 
7424   const MCExpr *Expr;
7425   if (Parser.parseExpression(Expr))
7426     return false;
7427 
7428   if (Expr->evaluateAsAbsolute(Imm))
7429     return true;
7430 
7431   if (Expected.empty()) {
7432     Error(S, "expected absolute expression");
7433   } else {
7434     Error(S, Twine("expected ", Expected) +
7435              Twine(" or an absolute expression"));
7436   }
7437   return false;
7438 }
7439 
7440 bool
7441 AMDGPUAsmParser::parseExpr(OperandVector &Operands) {
7442   SMLoc S = getLoc();
7443 
7444   const MCExpr *Expr;
7445   if (Parser.parseExpression(Expr))
7446     return false;
7447 
7448   int64_t IntVal;
7449   if (Expr->evaluateAsAbsolute(IntVal)) {
7450     Operands.push_back(AMDGPUOperand::CreateImm(this, IntVal, S));
7451   } else {
7452     Operands.push_back(AMDGPUOperand::CreateExpr(this, Expr, S));
7453   }
7454   return true;
7455 }
7456 
7457 bool
7458 AMDGPUAsmParser::parseString(StringRef &Val, const StringRef ErrMsg) {
7459   if (isToken(AsmToken::String)) {
7460     Val = getToken().getStringContents();
7461     lex();
7462     return true;
7463   } else {
7464     Error(getLoc(), ErrMsg);
7465     return false;
7466   }
7467 }
7468 
7469 bool
7470 AMDGPUAsmParser::parseId(StringRef &Val, const StringRef ErrMsg) {
7471   if (isToken(AsmToken::Identifier)) {
7472     Val = getTokenStr();
7473     lex();
7474     return true;
7475   } else {
7476     if (!ErrMsg.empty())
7477       Error(getLoc(), ErrMsg);
7478     return false;
7479   }
7480 }
7481 
7482 AsmToken
7483 AMDGPUAsmParser::getToken() const {
7484   return Parser.getTok();
7485 }
7486 
7487 AsmToken AMDGPUAsmParser::peekToken(bool ShouldSkipSpace) {
7488   return isToken(AsmToken::EndOfStatement)
7489              ? getToken()
7490              : getLexer().peekTok(ShouldSkipSpace);
7491 }
7492 
7493 void
7494 AMDGPUAsmParser::peekTokens(MutableArrayRef<AsmToken> Tokens) {
7495   auto TokCount = getLexer().peekTokens(Tokens);
7496 
7497   for (auto Idx = TokCount; Idx < Tokens.size(); ++Idx)
7498     Tokens[Idx] = AsmToken(AsmToken::Error, "");
7499 }
7500 
7501 AsmToken::TokenKind
7502 AMDGPUAsmParser::getTokenKind() const {
7503   return getLexer().getKind();
7504 }
7505 
7506 SMLoc
7507 AMDGPUAsmParser::getLoc() const {
7508   return getToken().getLoc();
7509 }
7510 
7511 StringRef
7512 AMDGPUAsmParser::getTokenStr() const {
7513   return getToken().getString();
7514 }
7515 
7516 void
7517 AMDGPUAsmParser::lex() {
7518   Parser.Lex();
7519 }
7520 
7521 SMLoc AMDGPUAsmParser::getInstLoc(const OperandVector &Operands) const {
7522   return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
7523 }
7524 
7525 SMLoc
7526 AMDGPUAsmParser::getOperandLoc(std::function<bool(const AMDGPUOperand&)> Test,
7527                                const OperandVector &Operands) const {
7528   for (unsigned i = Operands.size() - 1; i > 0; --i) {
7529     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
7530     if (Test(Op))
7531       return Op.getStartLoc();
7532   }
7533   return getInstLoc(Operands);
7534 }
7535 
7536 SMLoc
7537 AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy Type,
7538                            const OperandVector &Operands) const {
7539   auto Test = [=](const AMDGPUOperand& Op) { return Op.isImmTy(Type); };
7540   return getOperandLoc(Test, Operands);
7541 }
7542 
7543 SMLoc
7544 AMDGPUAsmParser::getRegLoc(unsigned Reg,
7545                            const OperandVector &Operands) const {
7546   auto Test = [=](const AMDGPUOperand& Op) {
7547     return Op.isRegKind() && Op.getReg() == Reg;
7548   };
7549   return getOperandLoc(Test, Operands);
7550 }
7551 
7552 SMLoc AMDGPUAsmParser::getLitLoc(const OperandVector &Operands,
7553                                  bool SearchMandatoryLiterals) const {
7554   auto Test = [](const AMDGPUOperand& Op) {
7555     return Op.IsImmKindLiteral() || Op.isExpr();
7556   };
7557   SMLoc Loc = getOperandLoc(Test, Operands);
7558   if (SearchMandatoryLiterals && Loc == getInstLoc(Operands))
7559     Loc = getMandatoryLitLoc(Operands);
7560   return Loc;
7561 }
7562 
7563 SMLoc AMDGPUAsmParser::getMandatoryLitLoc(const OperandVector &Operands) const {
7564   auto Test = [](const AMDGPUOperand &Op) {
7565     return Op.IsImmKindMandatoryLiteral();
7566   };
7567   return getOperandLoc(Test, Operands);
7568 }
7569 
7570 SMLoc
7571 AMDGPUAsmParser::getConstLoc(const OperandVector &Operands) const {
7572   auto Test = [](const AMDGPUOperand& Op) {
7573     return Op.isImmKindConst();
7574   };
7575   return getOperandLoc(Test, Operands);
7576 }
7577 
7578 //===----------------------------------------------------------------------===//
7579 // swizzle
7580 //===----------------------------------------------------------------------===//
7581 
7582 LLVM_READNONE
7583 static unsigned
7584 encodeBitmaskPerm(const unsigned AndMask,
7585                   const unsigned OrMask,
7586                   const unsigned XorMask) {
7587   using namespace llvm::AMDGPU::Swizzle;
7588 
7589   return BITMASK_PERM_ENC |
7590          (AndMask << BITMASK_AND_SHIFT) |
7591          (OrMask  << BITMASK_OR_SHIFT)  |
7592          (XorMask << BITMASK_XOR_SHIFT);
7593 }
7594 
7595 bool
7596 AMDGPUAsmParser::parseSwizzleOperand(int64_t &Op,
7597                                      const unsigned MinVal,
7598                                      const unsigned MaxVal,
7599                                      const StringRef ErrMsg,
7600                                      SMLoc &Loc) {
7601   if (!skipToken(AsmToken::Comma, "expected a comma")) {
7602     return false;
7603   }
7604   Loc = getLoc();
7605   if (!parseExpr(Op)) {
7606     return false;
7607   }
7608   if (Op < MinVal || Op > MaxVal) {
7609     Error(Loc, ErrMsg);
7610     return false;
7611   }
7612 
7613   return true;
7614 }
7615 
7616 bool
7617 AMDGPUAsmParser::parseSwizzleOperands(const unsigned OpNum, int64_t* Op,
7618                                       const unsigned MinVal,
7619                                       const unsigned MaxVal,
7620                                       const StringRef ErrMsg) {
7621   SMLoc Loc;
7622   for (unsigned i = 0; i < OpNum; ++i) {
7623     if (!parseSwizzleOperand(Op[i], MinVal, MaxVal, ErrMsg, Loc))
7624       return false;
7625   }
7626 
7627   return true;
7628 }
7629 
7630 bool
7631 AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &Imm) {
7632   using namespace llvm::AMDGPU::Swizzle;
7633 
7634   int64_t Lane[LANE_NUM];
7635   if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
7636                            "expected a 2-bit lane id")) {
7637     Imm = QUAD_PERM_ENC;
7638     for (unsigned I = 0; I < LANE_NUM; ++I) {
7639       Imm |= Lane[I] << (LANE_SHIFT * I);
7640     }
7641     return true;
7642   }
7643   return false;
7644 }
7645 
7646 bool
7647 AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &Imm) {
7648   using namespace llvm::AMDGPU::Swizzle;
7649 
7650   SMLoc Loc;
7651   int64_t GroupSize;
7652   int64_t LaneIdx;
7653 
7654   if (!parseSwizzleOperand(GroupSize,
7655                            2, 32,
7656                            "group size must be in the interval [2,32]",
7657                            Loc)) {
7658     return false;
7659   }
7660   if (!isPowerOf2_64(GroupSize)) {
7661     Error(Loc, "group size must be a power of two");
7662     return false;
7663   }
7664   if (parseSwizzleOperand(LaneIdx,
7665                           0, GroupSize - 1,
7666                           "lane id must be in the interval [0,group size - 1]",
7667                           Loc)) {
7668     Imm = encodeBitmaskPerm(BITMASK_MAX - GroupSize + 1, LaneIdx, 0);
7669     return true;
7670   }
7671   return false;
7672 }
7673 
7674 bool
7675 AMDGPUAsmParser::parseSwizzleReverse(int64_t &Imm) {
7676   using namespace llvm::AMDGPU::Swizzle;
7677 
7678   SMLoc Loc;
7679   int64_t GroupSize;
7680 
7681   if (!parseSwizzleOperand(GroupSize,
7682                            2, 32,
7683                            "group size must be in the interval [2,32]",
7684                            Loc)) {
7685     return false;
7686   }
7687   if (!isPowerOf2_64(GroupSize)) {
7688     Error(Loc, "group size must be a power of two");
7689     return false;
7690   }
7691 
7692   Imm = encodeBitmaskPerm(BITMASK_MAX, 0, GroupSize - 1);
7693   return true;
7694 }
7695 
7696 bool
7697 AMDGPUAsmParser::parseSwizzleSwap(int64_t &Imm) {
7698   using namespace llvm::AMDGPU::Swizzle;
7699 
7700   SMLoc Loc;
7701   int64_t GroupSize;
7702 
7703   if (!parseSwizzleOperand(GroupSize,
7704                            1, 16,
7705                            "group size must be in the interval [1,16]",
7706                            Loc)) {
7707     return false;
7708   }
7709   if (!isPowerOf2_64(GroupSize)) {
7710     Error(Loc, "group size must be a power of two");
7711     return false;
7712   }
7713 
7714   Imm = encodeBitmaskPerm(BITMASK_MAX, 0, GroupSize);
7715   return true;
7716 }
7717 
7718 bool
7719 AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &Imm) {
7720   using namespace llvm::AMDGPU::Swizzle;
7721 
7722   if (!skipToken(AsmToken::Comma, "expected a comma")) {
7723     return false;
7724   }
7725 
7726   StringRef Ctl;
7727   SMLoc StrLoc = getLoc();
7728   if (!parseString(Ctl)) {
7729     return false;
7730   }
7731   if (Ctl.size() != BITMASK_WIDTH) {
7732     Error(StrLoc, "expected a 5-character mask");
7733     return false;
7734   }
7735 
7736   unsigned AndMask = 0;
7737   unsigned OrMask = 0;
7738   unsigned XorMask = 0;
7739 
7740   for (size_t i = 0; i < Ctl.size(); ++i) {
7741     unsigned Mask = 1 << (BITMASK_WIDTH - 1 - i);
7742     switch(Ctl[i]) {
7743     default:
7744       Error(StrLoc, "invalid mask");
7745       return false;
7746     case '0':
7747       break;
7748     case '1':
7749       OrMask |= Mask;
7750       break;
7751     case 'p':
7752       AndMask |= Mask;
7753       break;
7754     case 'i':
7755       AndMask |= Mask;
7756       XorMask |= Mask;
7757       break;
7758     }
7759   }
7760 
7761   Imm = encodeBitmaskPerm(AndMask, OrMask, XorMask);
7762   return true;
7763 }
7764 
7765 bool
7766 AMDGPUAsmParser::parseSwizzleOffset(int64_t &Imm) {
7767 
7768   SMLoc OffsetLoc = getLoc();
7769 
7770   if (!parseExpr(Imm, "a swizzle macro")) {
7771     return false;
7772   }
7773   if (!isUInt<16>(Imm)) {
7774     Error(OffsetLoc, "expected a 16-bit offset");
7775     return false;
7776   }
7777   return true;
7778 }
7779 
7780 bool
7781 AMDGPUAsmParser::parseSwizzleMacro(int64_t &Imm) {
7782   using namespace llvm::AMDGPU::Swizzle;
7783 
7784   if (skipToken(AsmToken::LParen, "expected a left parentheses")) {
7785 
7786     SMLoc ModeLoc = getLoc();
7787     bool Ok = false;
7788 
7789     if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
7790       Ok = parseSwizzleQuadPerm(Imm);
7791     } else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
7792       Ok = parseSwizzleBitmaskPerm(Imm);
7793     } else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
7794       Ok = parseSwizzleBroadcast(Imm);
7795     } else if (trySkipId(IdSymbolic[ID_SWAP])) {
7796       Ok = parseSwizzleSwap(Imm);
7797     } else if (trySkipId(IdSymbolic[ID_REVERSE])) {
7798       Ok = parseSwizzleReverse(Imm);
7799     } else {
7800       Error(ModeLoc, "expected a swizzle mode");
7801     }
7802 
7803     return Ok && skipToken(AsmToken::RParen, "expected a closing parentheses");
7804   }
7805 
7806   return false;
7807 }
7808 
7809 ParseStatus AMDGPUAsmParser::parseSwizzle(OperandVector &Operands) {
7810   SMLoc S = getLoc();
7811   int64_t Imm = 0;
7812 
7813   if (trySkipId("offset")) {
7814 
7815     bool Ok = false;
7816     if (skipToken(AsmToken::Colon, "expected a colon")) {
7817       if (trySkipId("swizzle")) {
7818         Ok = parseSwizzleMacro(Imm);
7819       } else {
7820         Ok = parseSwizzleOffset(Imm);
7821       }
7822     }
7823 
7824     Operands.push_back(AMDGPUOperand::CreateImm(this, Imm, S, AMDGPUOperand::ImmTySwizzle));
7825 
7826     return Ok ? ParseStatus::Success : ParseStatus::Failure;
7827   }
7828   return ParseStatus::NoMatch;
7829 }
7830 
7831 bool
7832 AMDGPUOperand::isSwizzle() const {
7833   return isImmTy(ImmTySwizzle);
7834 }
7835 
7836 //===----------------------------------------------------------------------===//
7837 // VGPR Index Mode
7838 //===----------------------------------------------------------------------===//
7839 
7840 int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
7841 
7842   using namespace llvm::AMDGPU::VGPRIndexMode;
7843 
7844   if (trySkipToken(AsmToken::RParen)) {
7845     return OFF;
7846   }
7847 
7848   int64_t Imm = 0;
7849 
7850   while (true) {
7851     unsigned Mode = 0;
7852     SMLoc S = getLoc();
7853 
7854     for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
7855       if (trySkipId(IdSymbolic[ModeId])) {
7856         Mode = 1 << ModeId;
7857         break;
7858       }
7859     }
7860 
7861     if (Mode == 0) {
7862       Error(S, (Imm == 0)?
7863                "expected a VGPR index mode or a closing parenthesis" :
7864                "expected a VGPR index mode");
7865       return UNDEF;
7866     }
7867 
7868     if (Imm & Mode) {
7869       Error(S, "duplicate VGPR index mode");
7870       return UNDEF;
7871     }
7872     Imm |= Mode;
7873 
7874     if (trySkipToken(AsmToken::RParen))
7875       break;
7876     if (!skipToken(AsmToken::Comma,
7877                    "expected a comma or a closing parenthesis"))
7878       return UNDEF;
7879   }
7880 
7881   return Imm;
7882 }
7883 
7884 ParseStatus AMDGPUAsmParser::parseGPRIdxMode(OperandVector &Operands) {
7885 
7886   using namespace llvm::AMDGPU::VGPRIndexMode;
7887 
7888   int64_t Imm = 0;
7889   SMLoc S = getLoc();
7890 
7891   if (trySkipId("gpr_idx", AsmToken::LParen)) {
7892     Imm = parseGPRIdxMacro();
7893     if (Imm == UNDEF)
7894       return ParseStatus::Failure;
7895   } else {
7896     if (getParser().parseAbsoluteExpression(Imm))
7897       return ParseStatus::Failure;
7898     if (Imm < 0 || !isUInt<4>(Imm))
7899       return Error(S, "invalid immediate: only 4-bit values are legal");
7900   }
7901 
7902   Operands.push_back(
7903       AMDGPUOperand::CreateImm(this, Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
7904   return ParseStatus::Success;
7905 }
7906 
7907 bool AMDGPUOperand::isGPRIdxMode() const {
7908   return isImmTy(ImmTyGprIdxMode);
7909 }
7910 
7911 //===----------------------------------------------------------------------===//
7912 // sopp branch targets
7913 //===----------------------------------------------------------------------===//
7914 
7915 ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(OperandVector &Operands) {
7916 
7917   // Make sure we are not parsing something
7918   // that looks like a label or an expression but is not.
7919   // This will improve error messages.
7920   if (isRegister() || isModifier())
7921     return ParseStatus::NoMatch;
7922 
7923   if (!parseExpr(Operands))
7924     return ParseStatus::Failure;
7925 
7926   AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.size() - 1]);
7927   assert(Opr.isImm() || Opr.isExpr());
7928   SMLoc Loc = Opr.getStartLoc();
7929 
7930   // Currently we do not support arbitrary expressions as branch targets.
7931   // Only labels and absolute expressions are accepted.
7932   if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
7933     Error(Loc, "expected an absolute expression or a label");
7934   } else if (Opr.isImm() && !Opr.isS16Imm()) {
7935     Error(Loc, "expected a 16-bit signed jump offset");
7936   }
7937 
7938   return ParseStatus::Success;
7939 }
7940 
7941 //===----------------------------------------------------------------------===//
7942 // Boolean holding registers
7943 //===----------------------------------------------------------------------===//
7944 
7945 ParseStatus AMDGPUAsmParser::parseBoolReg(OperandVector &Operands) {
7946   return parseReg(Operands);
7947 }
7948 
7949 //===----------------------------------------------------------------------===//
7950 // mubuf
7951 //===----------------------------------------------------------------------===//
7952 
7953 void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
7954                                    const OperandVector &Operands,
7955                                    bool IsAtomic) {
7956   OptionalImmIndexMap OptionalIdx;
7957   unsigned FirstOperandIdx = 1;
7958   bool IsAtomicReturn = false;
7959 
7960   if (IsAtomic) {
7961     for (unsigned i = FirstOperandIdx, e = Operands.size(); i != e; ++i) {
7962       AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
7963       if (!Op.isCPol())
7964         continue;
7965       IsAtomicReturn = Op.getImm() & AMDGPU::CPol::GLC;
7966       break;
7967     }
7968 
7969     if (!IsAtomicReturn) {
7970       int NewOpc = AMDGPU::getAtomicNoRetOp(Inst.getOpcode());
7971       if (NewOpc != -1)
7972         Inst.setOpcode(NewOpc);
7973     }
7974 
7975     IsAtomicReturn =  MII.get(Inst.getOpcode()).TSFlags &
7976                       SIInstrFlags::IsAtomicRet;
7977   }
7978 
7979   for (unsigned i = FirstOperandIdx, e = Operands.size(); i != e; ++i) {
7980     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
7981 
7982     // Add the register arguments
7983     if (Op.isReg()) {
7984       Op.addRegOperands(Inst, 1);
7985       // Insert a tied src for atomic return dst.
7986       // This cannot be postponed as subsequent calls to
7987       // addImmOperands rely on correct number of MC operands.
7988       if (IsAtomicReturn && i == FirstOperandIdx)
7989         Op.addRegOperands(Inst, 1);
7990       continue;
7991     }
7992 
7993     // Handle the case where soffset is an immediate
7994     if (Op.isImm() && Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
7995       Op.addImmOperands(Inst, 1);
7996       continue;
7997     }
7998 
7999     // Handle tokens like 'offen' which are sometimes hard-coded into the
8000     // asm string.  There are no MCInst operands for these.
8001     if (Op.isToken()) {
8002       continue;
8003     }
8004     assert(Op.isImm());
8005 
8006     // Handle optional arguments
8007     OptionalIdx[Op.getImmTy()] = i;
8008   }
8009 
8010   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOffset);
8011   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyCPol, 0);
8012 }
8013 
8014 //===----------------------------------------------------------------------===//
8015 // smrd
8016 //===----------------------------------------------------------------------===//
8017 
8018 bool AMDGPUOperand::isSMRDOffset8() const {
8019   return isImmLiteral() && isUInt<8>(getImm());
8020 }
8021 
8022 bool AMDGPUOperand::isSMEMOffset() const {
8023   // Offset range is checked later by validator.
8024   return isImmLiteral();
8025 }
8026 
8027 bool AMDGPUOperand::isSMRDLiteralOffset() const {
8028   // 32-bit literals are only supported on CI and we only want to use them
8029   // when the offset is > 8-bits.
8030   return isImmLiteral() && !isUInt<8>(getImm()) && isUInt<32>(getImm());
8031 }
8032 
8033 //===----------------------------------------------------------------------===//
8034 // vop3
8035 //===----------------------------------------------------------------------===//
8036 
8037 static bool ConvertOmodMul(int64_t &Mul) {
8038   if (Mul != 1 && Mul != 2 && Mul != 4)
8039     return false;
8040 
8041   Mul >>= 1;
8042   return true;
8043 }
8044 
8045 static bool ConvertOmodDiv(int64_t &Div) {
8046   if (Div == 1) {
8047     Div = 0;
8048     return true;
8049   }
8050 
8051   if (Div == 2) {
8052     Div = 3;
8053     return true;
8054   }
8055 
8056   return false;
8057 }
8058 
8059 // For pre-gfx11 targets, both bound_ctrl:0 and bound_ctrl:1 are encoded as 1.
8060 // This is intentional and ensures compatibility with sp3.
8061 // See bug 35397 for details.
8062 bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
8063   if (BoundCtrl == 0 || BoundCtrl == 1) {
8064     if (!isGFX11Plus())
8065       BoundCtrl = 1;
8066     return true;
8067   }
8068   return false;
8069 }
8070 
8071 void AMDGPUAsmParser::onBeginOfFile() {
8072   if (!getParser().getStreamer().getTargetStreamer() ||
8073       getSTI().getTargetTriple().getArch() == Triple::r600)
8074     return;
8075 
8076   if (!getTargetStreamer().getTargetID())
8077     getTargetStreamer().initializeTargetID(getSTI(),
8078                                            getSTI().getFeatureString());
8079 
8080   if (isHsaAbi(getSTI()))
8081     getTargetStreamer().EmitDirectiveAMDGCNTarget();
8082 }
8083 
8084 ParseStatus AMDGPUAsmParser::parseOModSI(OperandVector &Operands) {
8085   StringRef Name = getTokenStr();
8086   if (Name == "mul") {
8087     return parseIntWithPrefix("mul", Operands,
8088                               AMDGPUOperand::ImmTyOModSI, ConvertOmodMul);
8089   }
8090 
8091   if (Name == "div") {
8092     return parseIntWithPrefix("div", Operands,
8093                               AMDGPUOperand::ImmTyOModSI, ConvertOmodDiv);
8094   }
8095 
8096   return ParseStatus::NoMatch;
8097 }
8098 
8099 // Determines which bit DST_OP_SEL occupies in the op_sel operand according to
8100 // the number of src operands present, then copies that bit into src0_modifiers.
8101 void cvtVOP3DstOpSelOnly(MCInst &Inst) {
8102   int Opc = Inst.getOpcode();
8103   int OpSelIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
8104   if (OpSelIdx == -1)
8105     return;
8106 
8107   int SrcNum;
8108   const int Ops[] = { AMDGPU::OpName::src0,
8109                       AMDGPU::OpName::src1,
8110                       AMDGPU::OpName::src2 };
8111   for (SrcNum = 0; SrcNum < 3 && AMDGPU::hasNamedOperand(Opc, Ops[SrcNum]);
8112        ++SrcNum)
8113     ;
8114   assert(SrcNum > 0);
8115 
8116   unsigned OpSel = Inst.getOperand(OpSelIdx).getImm();
8117 
8118   if ((OpSel & (1 << SrcNum)) != 0) {
8119     int ModIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
8120     uint32_t ModVal = Inst.getOperand(ModIdx).getImm();
8121     Inst.getOperand(ModIdx).setImm(ModVal | SISrcMods::DST_OP_SEL);
8122   }
8123 }
8124 
8125 void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
8126                                    const OperandVector &Operands) {
8127   cvtVOP3P(Inst, Operands);
8128   cvtVOP3DstOpSelOnly(Inst);
8129 }
8130 
8131 void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst, const OperandVector &Operands,
8132                                    OptionalImmIndexMap &OptionalIdx) {
8133   cvtVOP3P(Inst, Operands, OptionalIdx);
8134   cvtVOP3DstOpSelOnly(Inst);
8135 }
8136 
8137 static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum) {
8138   return
8139       // 1. This operand is input modifiers
8140       Desc.operands()[OpNum].OperandType == AMDGPU::OPERAND_INPUT_MODS
8141       // 2. This is not last operand
8142       && Desc.NumOperands > (OpNum + 1)
8143       // 3. Next operand is register class
8144       && Desc.operands()[OpNum + 1].RegClass != -1
8145       // 4. Next register is not tied to any other operand
8146       && Desc.getOperandConstraint(OpNum + 1,
8147                                    MCOI::OperandConstraint::TIED_TO) == -1;
8148 }
8149 
8150 void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst, const OperandVector &Operands)
8151 {
8152   OptionalImmIndexMap OptionalIdx;
8153   unsigned Opc = Inst.getOpcode();
8154 
8155   unsigned I = 1;
8156   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
8157   for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
8158     ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
8159   }
8160 
8161   for (unsigned E = Operands.size(); I != E; ++I) {
8162     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
8163     if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
8164       Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8165     } else if (Op.isInterpSlot() || Op.isInterpAttr() ||
8166                Op.isInterpAttrChan()) {
8167       Inst.addOperand(MCOperand::createImm(Op.getImm()));
8168     } else if (Op.isImmModifier()) {
8169       OptionalIdx[Op.getImmTy()] = I;
8170     } else {
8171       llvm_unreachable("unhandled operand type");
8172     }
8173   }
8174 
8175   if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::high))
8176     addOptionalImmOperand(Inst, Operands, OptionalIdx,
8177                           AMDGPUOperand::ImmTyHigh);
8178 
8179   if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::clamp))
8180     addOptionalImmOperand(Inst, Operands, OptionalIdx,
8181                           AMDGPUOperand::ImmTyClampSI);
8182 
8183   if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::omod))
8184     addOptionalImmOperand(Inst, Operands, OptionalIdx,
8185                           AMDGPUOperand::ImmTyOModSI);
8186 }
8187 
8188 void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst, const OperandVector &Operands)
8189 {
8190   OptionalImmIndexMap OptionalIdx;
8191   unsigned Opc = Inst.getOpcode();
8192 
8193   unsigned I = 1;
8194   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
8195   for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
8196     ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
8197   }
8198 
8199   for (unsigned E = Operands.size(); I != E; ++I) {
8200     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
8201     if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
8202       Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8203     } else if (Op.isImmModifier()) {
8204       OptionalIdx[Op.getImmTy()] = I;
8205     } else {
8206       llvm_unreachable("unhandled operand type");
8207     }
8208   }
8209 
8210   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI);
8211 
8212   int OpSelIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
8213   if (OpSelIdx != -1)
8214     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOpSel);
8215 
8216   addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyWaitEXP);
8217 
8218   if (OpSelIdx == -1)
8219     return;
8220 
8221   const int Ops[] = { AMDGPU::OpName::src0,
8222                       AMDGPU::OpName::src1,
8223                       AMDGPU::OpName::src2 };
8224   const int ModOps[] = { AMDGPU::OpName::src0_modifiers,
8225                          AMDGPU::OpName::src1_modifiers,
8226                          AMDGPU::OpName::src2_modifiers };
8227 
8228   unsigned OpSel = Inst.getOperand(OpSelIdx).getImm();
8229 
8230   for (int J = 0; J < 3; ++J) {
8231     int OpIdx = AMDGPU::getNamedOperandIdx(Opc, Ops[J]);
8232     if (OpIdx == -1)
8233       break;
8234 
8235     int ModIdx = AMDGPU::getNamedOperandIdx(Opc, ModOps[J]);
8236     uint32_t ModVal = Inst.getOperand(ModIdx).getImm();
8237 
8238     if ((OpSel & (1 << J)) != 0)
8239       ModVal |= SISrcMods::OP_SEL_0;
8240     if (ModOps[J] == AMDGPU::OpName::src0_modifiers &&
8241         (OpSel & (1 << 3)) != 0)
8242       ModVal |= SISrcMods::DST_OP_SEL;
8243 
8244     Inst.getOperand(ModIdx).setImm(ModVal);
8245   }
8246 }
8247 
8248 void AMDGPUAsmParser::cvtVOP3(MCInst &Inst, const OperandVector &Operands,
8249                               OptionalImmIndexMap &OptionalIdx) {
8250   unsigned Opc = Inst.getOpcode();
8251 
8252   unsigned I = 1;
8253   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
8254   for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
8255     ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
8256   }
8257 
8258   for (unsigned E = Operands.size(); I != E; ++I) {
8259     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
8260     if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
8261       Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8262     } else if (Op.isImmModifier()) {
8263       OptionalIdx[Op.getImmTy()] = I;
8264     } else if (Op.isRegOrImm()) {
8265       Op.addRegOrImmOperands(Inst, 1);
8266     } else {
8267       llvm_unreachable("unhandled operand type");
8268     }
8269   }
8270 
8271   if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::clamp))
8272     addOptionalImmOperand(Inst, Operands, OptionalIdx,
8273                           AMDGPUOperand::ImmTyClampSI);
8274 
8275   if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::omod))
8276     addOptionalImmOperand(Inst, Operands, OptionalIdx,
8277                           AMDGPUOperand::ImmTyOModSI);
8278 
8279   // Special case v_mac_{f16, f32} and v_fmac_{f16, f32} (gfx906/gfx10+):
8280   // it has src2 register operand that is tied to dst operand
8281   // we don't allow modifiers for this operand in assembler so src2_modifiers
8282   // should be 0.
8283   if (isMAC(Opc)) {
8284     auto it = Inst.begin();
8285     std::advance(it, AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2_modifiers));
8286     it = Inst.insert(it, MCOperand::createImm(0)); // no modifiers for src2
8287     ++it;
8288     // Copy the operand to ensure it's not invalidated when Inst grows.
8289     Inst.insert(it, MCOperand(Inst.getOperand(0))); // src2 = dst
8290   }
8291 }
8292 
8293 void AMDGPUAsmParser::cvtVOP3(MCInst &Inst, const OperandVector &Operands) {
8294   OptionalImmIndexMap OptionalIdx;
8295   cvtVOP3(Inst, Operands, OptionalIdx);
8296 }
8297 
8298 void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst, const OperandVector &Operands,
8299                                OptionalImmIndexMap &OptIdx) {
8300   const int Opc = Inst.getOpcode();
8301   const MCInstrDesc &Desc = MII.get(Opc);
8302 
8303   const bool IsPacked = (Desc.TSFlags & SIInstrFlags::IsPacked) != 0;
8304 
8305   if (Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
8306       Opc == AMDGPU::V_CVT_SR_FP8_F32_vi) {
8307     Inst.addOperand(MCOperand::createImm(0)); // Placeholder for src2_mods
8308     Inst.addOperand(Inst.getOperand(0));
8309   }
8310 
8311   if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::vdst_in)) {
8312     assert(!IsPacked);
8313     Inst.addOperand(Inst.getOperand(0));
8314   }
8315 
8316   // FIXME: This is messy. Parse the modifiers as if it was a normal VOP3
8317   // instruction, and then figure out where to actually put the modifiers
8318 
8319   int OpSelIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
8320   if (OpSelIdx != -1) {
8321     addOptionalImmOperand(Inst, Operands, OptIdx, AMDGPUOperand::ImmTyOpSel);
8322   }
8323 
8324   int OpSelHiIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel_hi);
8325   if (OpSelHiIdx != -1) {
8326     int DefaultVal = IsPacked ? -1 : 0;
8327     addOptionalImmOperand(Inst, Operands, OptIdx, AMDGPUOperand::ImmTyOpSelHi,
8328                           DefaultVal);
8329   }
8330 
8331   int NegLoIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::neg_lo);
8332   if (NegLoIdx != -1) {
8333     addOptionalImmOperand(Inst, Operands, OptIdx, AMDGPUOperand::ImmTyNegLo);
8334     addOptionalImmOperand(Inst, Operands, OptIdx, AMDGPUOperand::ImmTyNegHi);
8335   }
8336 
8337   const int Ops[] = { AMDGPU::OpName::src0,
8338                       AMDGPU::OpName::src1,
8339                       AMDGPU::OpName::src2 };
8340   const int ModOps[] = { AMDGPU::OpName::src0_modifiers,
8341                          AMDGPU::OpName::src1_modifiers,
8342                          AMDGPU::OpName::src2_modifiers };
8343 
8344   unsigned OpSel = 0;
8345   unsigned OpSelHi = 0;
8346   unsigned NegLo = 0;
8347   unsigned NegHi = 0;
8348 
8349   if (OpSelIdx != -1)
8350     OpSel = Inst.getOperand(OpSelIdx).getImm();
8351 
8352   if (OpSelHiIdx != -1)
8353     OpSelHi = Inst.getOperand(OpSelHiIdx).getImm();
8354 
8355   if (NegLoIdx != -1) {
8356     int NegHiIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::neg_hi);
8357     NegLo = Inst.getOperand(NegLoIdx).getImm();
8358     NegHi = Inst.getOperand(NegHiIdx).getImm();
8359   }
8360 
8361   for (int J = 0; J < 3; ++J) {
8362     int OpIdx = AMDGPU::getNamedOperandIdx(Opc, Ops[J]);
8363     if (OpIdx == -1)
8364       break;
8365 
8366     int ModIdx = AMDGPU::getNamedOperandIdx(Opc, ModOps[J]);
8367 
8368     if (ModIdx == -1)
8369       continue;
8370 
8371     uint32_t ModVal = 0;
8372 
8373     if ((OpSel & (1 << J)) != 0)
8374       ModVal |= SISrcMods::OP_SEL_0;
8375 
8376     if ((OpSelHi & (1 << J)) != 0)
8377       ModVal |= SISrcMods::OP_SEL_1;
8378 
8379     if ((NegLo & (1 << J)) != 0)
8380       ModVal |= SISrcMods::NEG;
8381 
8382     if ((NegHi & (1 << J)) != 0)
8383       ModVal |= SISrcMods::NEG_HI;
8384 
8385     Inst.getOperand(ModIdx).setImm(Inst.getOperand(ModIdx).getImm() | ModVal);
8386   }
8387 }
8388 
8389 void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst, const OperandVector &Operands) {
8390   OptionalImmIndexMap OptIdx;
8391   cvtVOP3(Inst, Operands, OptIdx);
8392   cvtVOP3P(Inst, Operands, OptIdx);
8393 }
8394 
8395 //===----------------------------------------------------------------------===//
8396 // VOPD
8397 //===----------------------------------------------------------------------===//
8398 
8399 ParseStatus AMDGPUAsmParser::parseVOPD(OperandVector &Operands) {
8400   if (!hasVOPD(getSTI()))
8401     return ParseStatus::NoMatch;
8402 
8403   if (isToken(AsmToken::Colon) && peekToken(false).is(AsmToken::Colon)) {
8404     SMLoc S = getLoc();
8405     lex();
8406     lex();
8407     Operands.push_back(AMDGPUOperand::CreateToken(this, "::", S));
8408     SMLoc OpYLoc = getLoc();
8409     StringRef OpYName;
8410     if (isToken(AsmToken::Identifier) && !Parser.parseIdentifier(OpYName)) {
8411       Operands.push_back(AMDGPUOperand::CreateToken(this, OpYName, OpYLoc));
8412       return ParseStatus::Success;
8413     }
8414     return Error(OpYLoc, "expected a VOPDY instruction after ::");
8415   }
8416   return ParseStatus::NoMatch;
8417 }
8418 
8419 // Create VOPD MCInst operands using parsed assembler operands.
8420 void AMDGPUAsmParser::cvtVOPD(MCInst &Inst, const OperandVector &Operands) {
8421   auto addOp = [&](uint16_t ParsedOprIdx) { // NOLINT:function pointer
8422     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
8423     if (Op.isReg()) {
8424       Op.addRegOperands(Inst, 1);
8425       return;
8426     }
8427     if (Op.isImm()) {
8428       Op.addImmOperands(Inst, 1);
8429       return;
8430     }
8431     llvm_unreachable("Unhandled operand type in cvtVOPD");
8432   };
8433 
8434   const auto &InstInfo = getVOPDInstInfo(Inst.getOpcode(), &MII);
8435 
8436   // MCInst operands are ordered as follows:
8437   //   dstX, dstY, src0X [, other OpX operands], src0Y [, other OpY operands]
8438 
8439   for (auto CompIdx : VOPD::COMPONENTS) {
8440     addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
8441   }
8442 
8443   for (auto CompIdx : VOPD::COMPONENTS) {
8444     const auto &CInfo = InstInfo[CompIdx];
8445     auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
8446     for (unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
8447       addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
8448     if (CInfo.hasSrc2Acc())
8449       addOp(CInfo.getIndexOfDstInParsedOperands());
8450   }
8451 }
8452 
8453 //===----------------------------------------------------------------------===//
8454 // dpp
8455 //===----------------------------------------------------------------------===//
8456 
8457 bool AMDGPUOperand::isDPP8() const {
8458   return isImmTy(ImmTyDPP8);
8459 }
8460 
8461 bool AMDGPUOperand::isDPPCtrl() const {
8462   using namespace AMDGPU::DPP;
8463 
8464   bool result = isImm() && getImmTy() == ImmTyDppCtrl && isUInt<9>(getImm());
8465   if (result) {
8466     int64_t Imm = getImm();
8467     return (Imm >= DppCtrl::QUAD_PERM_FIRST && Imm <= DppCtrl::QUAD_PERM_LAST) ||
8468            (Imm >= DppCtrl::ROW_SHL_FIRST && Imm <= DppCtrl::ROW_SHL_LAST) ||
8469            (Imm >= DppCtrl::ROW_SHR_FIRST && Imm <= DppCtrl::ROW_SHR_LAST) ||
8470            (Imm >= DppCtrl::ROW_ROR_FIRST && Imm <= DppCtrl::ROW_ROR_LAST) ||
8471            (Imm == DppCtrl::WAVE_SHL1) ||
8472            (Imm == DppCtrl::WAVE_ROL1) ||
8473            (Imm == DppCtrl::WAVE_SHR1) ||
8474            (Imm == DppCtrl::WAVE_ROR1) ||
8475            (Imm == DppCtrl::ROW_MIRROR) ||
8476            (Imm == DppCtrl::ROW_HALF_MIRROR) ||
8477            (Imm == DppCtrl::BCAST15) ||
8478            (Imm == DppCtrl::BCAST31) ||
8479            (Imm >= DppCtrl::ROW_SHARE_FIRST && Imm <= DppCtrl::ROW_SHARE_LAST) ||
8480            (Imm >= DppCtrl::ROW_XMASK_FIRST && Imm <= DppCtrl::ROW_XMASK_LAST);
8481   }
8482   return false;
8483 }
8484 
8485 //===----------------------------------------------------------------------===//
8486 // mAI
8487 //===----------------------------------------------------------------------===//
8488 
8489 bool AMDGPUOperand::isBLGP() const {
8490   return isImm() && getImmTy() == ImmTyBLGP && isUInt<3>(getImm());
8491 }
8492 
8493 bool AMDGPUOperand::isCBSZ() const {
8494   return isImm() && getImmTy() == ImmTyCBSZ && isUInt<3>(getImm());
8495 }
8496 
8497 bool AMDGPUOperand::isABID() const {
8498   return isImm() && getImmTy() == ImmTyABID && isUInt<4>(getImm());
8499 }
8500 
8501 bool AMDGPUOperand::isS16Imm() const {
8502   return isImmLiteral() && (isInt<16>(getImm()) || isUInt<16>(getImm()));
8503 }
8504 
8505 bool AMDGPUOperand::isU16Imm() const {
8506   return isImmLiteral() && isUInt<16>(getImm());
8507 }
8508 
8509 //===----------------------------------------------------------------------===//
8510 // dim
8511 //===----------------------------------------------------------------------===//
8512 
8513 bool AMDGPUAsmParser::parseDimId(unsigned &Encoding) {
8514   // We want to allow "dim:1D" etc.,
8515   // but the initial 1 is tokenized as an integer.
8516   std::string Token;
8517   if (isToken(AsmToken::Integer)) {
8518     SMLoc Loc = getToken().getEndLoc();
8519     Token = std::string(getTokenStr());
8520     lex();
8521     if (getLoc() != Loc)
8522       return false;
8523   }
8524 
8525   StringRef Suffix;
8526   if (!parseId(Suffix))
8527     return false;
8528   Token += Suffix;
8529 
8530   StringRef DimId = Token;
8531   if (DimId.starts_with("SQ_RSRC_IMG_"))
8532     DimId = DimId.drop_front(12);
8533 
8534   const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfoByAsmSuffix(DimId);
8535   if (!DimInfo)
8536     return false;
8537 
8538   Encoding = DimInfo->Encoding;
8539   return true;
8540 }
8541 
8542 ParseStatus AMDGPUAsmParser::parseDim(OperandVector &Operands) {
8543   if (!isGFX10Plus())
8544     return ParseStatus::NoMatch;
8545 
8546   SMLoc S = getLoc();
8547 
8548   if (!trySkipId("dim", AsmToken::Colon))
8549     return ParseStatus::NoMatch;
8550 
8551   unsigned Encoding;
8552   SMLoc Loc = getLoc();
8553   if (!parseDimId(Encoding))
8554     return Error(Loc, "invalid dim value");
8555 
8556   Operands.push_back(AMDGPUOperand::CreateImm(this, Encoding, S,
8557                                               AMDGPUOperand::ImmTyDim));
8558   return ParseStatus::Success;
8559 }
8560 
8561 //===----------------------------------------------------------------------===//
8562 // dpp
8563 //===----------------------------------------------------------------------===//
8564 
8565 ParseStatus AMDGPUAsmParser::parseDPP8(OperandVector &Operands) {
8566   SMLoc S = getLoc();
8567 
8568   if (!isGFX10Plus() || !trySkipId("dpp8", AsmToken::Colon))
8569     return ParseStatus::NoMatch;
8570 
8571   // dpp8:[%d,%d,%d,%d,%d,%d,%d,%d]
8572 
8573   int64_t Sels[8];
8574 
8575   if (!skipToken(AsmToken::LBrac, "expected an opening square bracket"))
8576     return ParseStatus::Failure;
8577 
8578   for (size_t i = 0; i < 8; ++i) {
8579     if (i > 0 && !skipToken(AsmToken::Comma, "expected a comma"))
8580       return ParseStatus::Failure;
8581 
8582     SMLoc Loc = getLoc();
8583     if (getParser().parseAbsoluteExpression(Sels[i]))
8584       return ParseStatus::Failure;
8585     if (0 > Sels[i] || 7 < Sels[i])
8586       return Error(Loc, "expected a 3-bit value");
8587   }
8588 
8589   if (!skipToken(AsmToken::RBrac, "expected a closing square bracket"))
8590     return ParseStatus::Failure;
8591 
8592   unsigned DPP8 = 0;
8593   for (size_t i = 0; i < 8; ++i)
8594     DPP8 |= (Sels[i] << (i * 3));
8595 
8596   Operands.push_back(AMDGPUOperand::CreateImm(this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
8597   return ParseStatus::Success;
8598 }
8599 
8600 bool
8601 AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
8602                                     const OperandVector &Operands) {
8603   if (Ctrl == "row_newbcast")
8604     return isGFX90A();
8605 
8606   if (Ctrl == "row_share" ||
8607       Ctrl == "row_xmask")
8608     return isGFX10Plus();
8609 
8610   if (Ctrl == "wave_shl" ||
8611       Ctrl == "wave_shr" ||
8612       Ctrl == "wave_rol" ||
8613       Ctrl == "wave_ror" ||
8614       Ctrl == "row_bcast")
8615     return isVI() || isGFX9();
8616 
8617   return Ctrl == "row_mirror" ||
8618          Ctrl == "row_half_mirror" ||
8619          Ctrl == "quad_perm" ||
8620          Ctrl == "row_shl" ||
8621          Ctrl == "row_shr" ||
8622          Ctrl == "row_ror";
8623 }
8624 
8625 int64_t
8626 AMDGPUAsmParser::parseDPPCtrlPerm() {
8627   // quad_perm:[%d,%d,%d,%d]
8628 
8629   if (!skipToken(AsmToken::LBrac, "expected an opening square bracket"))
8630     return -1;
8631 
8632   int64_t Val = 0;
8633   for (int i = 0; i < 4; ++i) {
8634     if (i > 0 && !skipToken(AsmToken::Comma, "expected a comma"))
8635       return -1;
8636 
8637     int64_t Temp;
8638     SMLoc Loc = getLoc();
8639     if (getParser().parseAbsoluteExpression(Temp))
8640       return -1;
8641     if (Temp < 0 || Temp > 3) {
8642       Error(Loc, "expected a 2-bit value");
8643       return -1;
8644     }
8645 
8646     Val += (Temp << i * 2);
8647   }
8648 
8649   if (!skipToken(AsmToken::RBrac, "expected a closing square bracket"))
8650     return -1;
8651 
8652   return Val;
8653 }
8654 
8655 int64_t
8656 AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
8657   using namespace AMDGPU::DPP;
8658 
8659   // sel:%d
8660 
8661   int64_t Val;
8662   SMLoc Loc = getLoc();
8663 
8664   if (getParser().parseAbsoluteExpression(Val))
8665     return -1;
8666 
8667   struct DppCtrlCheck {
8668     int64_t Ctrl;
8669     int Lo;
8670     int Hi;
8671   };
8672 
8673   DppCtrlCheck Check = StringSwitch<DppCtrlCheck>(Ctrl)
8674     .Case("wave_shl",  {DppCtrl::WAVE_SHL1,       1,  1})
8675     .Case("wave_rol",  {DppCtrl::WAVE_ROL1,       1,  1})
8676     .Case("wave_shr",  {DppCtrl::WAVE_SHR1,       1,  1})
8677     .Case("wave_ror",  {DppCtrl::WAVE_ROR1,       1,  1})
8678     .Case("row_shl",   {DppCtrl::ROW_SHL0,        1, 15})
8679     .Case("row_shr",   {DppCtrl::ROW_SHR0,        1, 15})
8680     .Case("row_ror",   {DppCtrl::ROW_ROR0,        1, 15})
8681     .Case("row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
8682     .Case("row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
8683     .Case("row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
8684     .Default({-1, 0, 0});
8685 
8686   bool Valid;
8687   if (Check.Ctrl == -1) {
8688     Valid = (Ctrl == "row_bcast" && (Val == 15 || Val == 31));
8689     Val = (Val == 15)? DppCtrl::BCAST15 : DppCtrl::BCAST31;
8690   } else {
8691     Valid = Check.Lo <= Val && Val <= Check.Hi;
8692     Val = (Check.Lo == Check.Hi) ? Check.Ctrl : (Check.Ctrl | Val);
8693   }
8694 
8695   if (!Valid) {
8696     Error(Loc, Twine("invalid ", Ctrl) + Twine(" value"));
8697     return -1;
8698   }
8699 
8700   return Val;
8701 }
8702 
8703 ParseStatus AMDGPUAsmParser::parseDPPCtrl(OperandVector &Operands) {
8704   using namespace AMDGPU::DPP;
8705 
8706   if (!isToken(AsmToken::Identifier) ||
8707       !isSupportedDPPCtrl(getTokenStr(), Operands))
8708     return ParseStatus::NoMatch;
8709 
8710   SMLoc S = getLoc();
8711   int64_t Val = -1;
8712   StringRef Ctrl;
8713 
8714   parseId(Ctrl);
8715 
8716   if (Ctrl == "row_mirror") {
8717     Val = DppCtrl::ROW_MIRROR;
8718   } else if (Ctrl == "row_half_mirror") {
8719     Val = DppCtrl::ROW_HALF_MIRROR;
8720   } else {
8721     if (skipToken(AsmToken::Colon, "expected a colon")) {
8722       if (Ctrl == "quad_perm") {
8723         Val = parseDPPCtrlPerm();
8724       } else {
8725         Val = parseDPPCtrlSel(Ctrl);
8726       }
8727     }
8728   }
8729 
8730   if (Val == -1)
8731     return ParseStatus::Failure;
8732 
8733   Operands.push_back(
8734     AMDGPUOperand::CreateImm(this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
8735   return ParseStatus::Success;
8736 }
8737 
8738 void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst, const OperandVector &Operands,
8739                                  bool IsDPP8) {
8740   OptionalImmIndexMap OptionalIdx;
8741   unsigned Opc = Inst.getOpcode();
8742   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
8743 
8744   // MAC instructions are special because they have 'old'
8745   // operand which is not tied to dst (but assumed to be).
8746   // They also have dummy unused src2_modifiers.
8747   int OldIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::old);
8748   int Src2ModIdx =
8749       AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2_modifiers);
8750   bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
8751                Desc.getOperandConstraint(OldIdx, MCOI::TIED_TO) == -1;
8752 
8753   unsigned I = 1;
8754   for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
8755     ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
8756   }
8757 
8758   int Fi = 0;
8759   for (unsigned E = Operands.size(); I != E; ++I) {
8760 
8761     if (IsMAC) {
8762       int NumOperands = Inst.getNumOperands();
8763       if (OldIdx == NumOperands) {
8764         // Handle old operand
8765         constexpr int DST_IDX = 0;
8766         Inst.addOperand(Inst.getOperand(DST_IDX));
8767       } else if (Src2ModIdx == NumOperands) {
8768         // Add unused dummy src2_modifiers
8769         Inst.addOperand(MCOperand::createImm(0));
8770       }
8771     }
8772 
8773     auto TiedTo = Desc.getOperandConstraint(Inst.getNumOperands(),
8774                                             MCOI::TIED_TO);
8775     if (TiedTo != -1) {
8776       assert((unsigned)TiedTo < Inst.getNumOperands());
8777       // handle tied old or src2 for MAC instructions
8778       Inst.addOperand(Inst.getOperand(TiedTo));
8779     }
8780     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
8781     // Add the register arguments
8782     if (IsDPP8 && Op.isDppFI()) {
8783       Fi = Op.getImm();
8784     } else if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
8785       Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8786     } else if (Op.isReg()) {
8787       Op.addRegOperands(Inst, 1);
8788     } else if (Op.isImm() &&
8789                Desc.operands()[Inst.getNumOperands()].RegClass != -1) {
8790       assert(!Op.IsImmKindLiteral() && "Cannot use literal with DPP");
8791       Op.addImmOperands(Inst, 1);
8792     } else if (Op.isImm()) {
8793       OptionalIdx[Op.getImmTy()] = I;
8794     } else {
8795       llvm_unreachable("unhandled operand type");
8796     }
8797   }
8798   if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::clamp))
8799     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI);
8800 
8801   if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::omod))
8802     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOModSI);
8803 
8804   if (Desc.TSFlags & SIInstrFlags::VOP3P)
8805     cvtVOP3P(Inst, Operands, OptionalIdx);
8806   else if (Desc.TSFlags & SIInstrFlags::VOP3)
8807     cvtVOP3OpSel(Inst, Operands, OptionalIdx);
8808   else if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::op_sel)) {
8809     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOpSel);
8810   }
8811 
8812   if (IsDPP8) {
8813     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDPP8);
8814     using namespace llvm::AMDGPU::DPP;
8815     Inst.addOperand(MCOperand::createImm(Fi? DPP8_FI_1 : DPP8_FI_0));
8816   } else {
8817     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppCtrl, 0xe4);
8818     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppRowMask, 0xf);
8819     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBankMask, 0xf);
8820     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBoundCtrl);
8821 
8822     if (AMDGPU::hasNamedOperand(Inst.getOpcode(), AMDGPU::OpName::fi))
8823       addOptionalImmOperand(Inst, Operands, OptionalIdx,
8824                             AMDGPUOperand::ImmTyDppFI);
8825   }
8826 }
8827 
8828 void AMDGPUAsmParser::cvtDPP(MCInst &Inst, const OperandVector &Operands, bool IsDPP8) {
8829   OptionalImmIndexMap OptionalIdx;
8830 
8831   unsigned I = 1;
8832   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
8833   for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
8834     ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
8835   }
8836 
8837   int Fi = 0;
8838   for (unsigned E = Operands.size(); I != E; ++I) {
8839     auto TiedTo = Desc.getOperandConstraint(Inst.getNumOperands(),
8840                                             MCOI::TIED_TO);
8841     if (TiedTo != -1) {
8842       assert((unsigned)TiedTo < Inst.getNumOperands());
8843       // handle tied old or src2 for MAC instructions
8844       Inst.addOperand(Inst.getOperand(TiedTo));
8845     }
8846     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
8847     // Add the register arguments
8848     if (Op.isReg() && validateVccOperand(Op.getReg())) {
8849       // VOP2b (v_add_u32, v_sub_u32 ...) dpp use "vcc" token.
8850       // Skip it.
8851       continue;
8852     }
8853 
8854     if (IsDPP8) {
8855       if (Op.isDPP8()) {
8856         Op.addImmOperands(Inst, 1);
8857       } else if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
8858         Op.addRegWithFPInputModsOperands(Inst, 2);
8859       } else if (Op.isDppFI()) {
8860         Fi = Op.getImm();
8861       } else if (Op.isReg()) {
8862         Op.addRegOperands(Inst, 1);
8863       } else {
8864         llvm_unreachable("Invalid operand type");
8865       }
8866     } else {
8867       if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
8868         Op.addRegWithFPInputModsOperands(Inst, 2);
8869       } else if (Op.isReg()) {
8870         Op.addRegOperands(Inst, 1);
8871       } else if (Op.isDPPCtrl()) {
8872         Op.addImmOperands(Inst, 1);
8873       } else if (Op.isImm()) {
8874         // Handle optional arguments
8875         OptionalIdx[Op.getImmTy()] = I;
8876       } else {
8877         llvm_unreachable("Invalid operand type");
8878       }
8879     }
8880   }
8881 
8882   if (IsDPP8) {
8883     using namespace llvm::AMDGPU::DPP;
8884     Inst.addOperand(MCOperand::createImm(Fi? DPP8_FI_1 : DPP8_FI_0));
8885   } else {
8886     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppRowMask, 0xf);
8887     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBankMask, 0xf);
8888     addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBoundCtrl);
8889     if (AMDGPU::hasNamedOperand(Inst.getOpcode(), AMDGPU::OpName::fi)) {
8890       addOptionalImmOperand(Inst, Operands, OptionalIdx,
8891                             AMDGPUOperand::ImmTyDppFI);
8892     }
8893   }
8894 }
8895 
8896 //===----------------------------------------------------------------------===//
8897 // sdwa
8898 //===----------------------------------------------------------------------===//
8899 
8900 ParseStatus AMDGPUAsmParser::parseSDWASel(OperandVector &Operands,
8901                                           StringRef Prefix,
8902                                           AMDGPUOperand::ImmTy Type) {
8903   using namespace llvm::AMDGPU::SDWA;
8904 
8905   SMLoc S = getLoc();
8906   StringRef Value;
8907 
8908   SMLoc StringLoc;
8909   ParseStatus Res = parseStringWithPrefix(Prefix, Value, StringLoc);
8910   if (!Res.isSuccess())
8911     return Res;
8912 
8913   int64_t Int;
8914   Int = StringSwitch<int64_t>(Value)
8915         .Case("BYTE_0", SdwaSel::BYTE_0)
8916         .Case("BYTE_1", SdwaSel::BYTE_1)
8917         .Case("BYTE_2", SdwaSel::BYTE_2)
8918         .Case("BYTE_3", SdwaSel::BYTE_3)
8919         .Case("WORD_0", SdwaSel::WORD_0)
8920         .Case("WORD_1", SdwaSel::WORD_1)
8921         .Case("DWORD", SdwaSel::DWORD)
8922         .Default(0xffffffff);
8923 
8924   if (Int == 0xffffffff)
8925     return Error(StringLoc, "invalid " + Twine(Prefix) + " value");
8926 
8927   Operands.push_back(AMDGPUOperand::CreateImm(this, Int, S, Type));
8928   return ParseStatus::Success;
8929 }
8930 
8931 ParseStatus AMDGPUAsmParser::parseSDWADstUnused(OperandVector &Operands) {
8932   using namespace llvm::AMDGPU::SDWA;
8933 
8934   SMLoc S = getLoc();
8935   StringRef Value;
8936 
8937   SMLoc StringLoc;
8938   ParseStatus Res = parseStringWithPrefix("dst_unused", Value, StringLoc);
8939   if (!Res.isSuccess())
8940     return Res;
8941 
8942   int64_t Int;
8943   Int = StringSwitch<int64_t>(Value)
8944         .Case("UNUSED_PAD", DstUnused::UNUSED_PAD)
8945         .Case("UNUSED_SEXT", DstUnused::UNUSED_SEXT)
8946         .Case("UNUSED_PRESERVE", DstUnused::UNUSED_PRESERVE)
8947         .Default(0xffffffff);
8948 
8949   if (Int == 0xffffffff)
8950     return Error(StringLoc, "invalid dst_unused value");
8951 
8952   Operands.push_back(AMDGPUOperand::CreateImm(this, Int, S, AMDGPUOperand::ImmTySDWADstUnused));
8953   return ParseStatus::Success;
8954 }
8955 
8956 void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst, const OperandVector &Operands) {
8957   cvtSDWA(Inst, Operands, SIInstrFlags::VOP1);
8958 }
8959 
8960 void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst, const OperandVector &Operands) {
8961   cvtSDWA(Inst, Operands, SIInstrFlags::VOP2);
8962 }
8963 
8964 void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst, const OperandVector &Operands) {
8965   cvtSDWA(Inst, Operands, SIInstrFlags::VOP2, true, true);
8966 }
8967 
8968 void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst, const OperandVector &Operands) {
8969   cvtSDWA(Inst, Operands, SIInstrFlags::VOP2, false, true);
8970 }
8971 
8972 void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst, const OperandVector &Operands) {
8973   cvtSDWA(Inst, Operands, SIInstrFlags::VOPC, isVI());
8974 }
8975 
8976 void AMDGPUAsmParser::cvtSDWA(MCInst &Inst, const OperandVector &Operands,
8977                               uint64_t BasicInstType,
8978                               bool SkipDstVcc,
8979                               bool SkipSrcVcc) {
8980   using namespace llvm::AMDGPU::SDWA;
8981 
8982   OptionalImmIndexMap OptionalIdx;
8983   bool SkipVcc = SkipDstVcc || SkipSrcVcc;
8984   bool SkippedVcc = false;
8985 
8986   unsigned I = 1;
8987   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
8988   for (unsigned J = 0; J < Desc.getNumDefs(); ++J) {
8989     ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
8990   }
8991 
8992   for (unsigned E = Operands.size(); I != E; ++I) {
8993     AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
8994     if (SkipVcc && !SkippedVcc && Op.isReg() &&
8995         (Op.getReg() == AMDGPU::VCC || Op.getReg() == AMDGPU::VCC_LO)) {
8996       // VOP2b (v_add_u32, v_sub_u32 ...) sdwa use "vcc" token as dst.
8997       // Skip it if it's 2nd (e.g. v_add_i32_sdwa v1, vcc, v2, v3)
8998       // or 4th (v_addc_u32_sdwa v1, vcc, v2, v3, vcc) operand.
8999       // Skip VCC only if we didn't skip it on previous iteration.
9000       // Note that src0 and src1 occupy 2 slots each because of modifiers.
9001       if (BasicInstType == SIInstrFlags::VOP2 &&
9002           ((SkipDstVcc && Inst.getNumOperands() == 1) ||
9003            (SkipSrcVcc && Inst.getNumOperands() == 5))) {
9004         SkippedVcc = true;
9005         continue;
9006       } else if (BasicInstType == SIInstrFlags::VOPC &&
9007                  Inst.getNumOperands() == 0) {
9008         SkippedVcc = true;
9009         continue;
9010       }
9011     }
9012     if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
9013       Op.addRegOrImmWithInputModsOperands(Inst, 2);
9014     } else if (Op.isImm()) {
9015       // Handle optional arguments
9016       OptionalIdx[Op.getImmTy()] = I;
9017     } else {
9018       llvm_unreachable("Invalid operand type");
9019     }
9020     SkippedVcc = false;
9021   }
9022 
9023   const unsigned Opc = Inst.getOpcode();
9024   if (Opc != AMDGPU::V_NOP_sdwa_gfx10 && Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
9025       Opc != AMDGPU::V_NOP_sdwa_vi) {
9026     // v_nop_sdwa_sdwa_vi/gfx9 has no optional sdwa arguments
9027     switch (BasicInstType) {
9028     case SIInstrFlags::VOP1:
9029       if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::clamp))
9030         addOptionalImmOperand(Inst, Operands, OptionalIdx,
9031                               AMDGPUOperand::ImmTyClampSI, 0);
9032 
9033       if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::omod))
9034         addOptionalImmOperand(Inst, Operands, OptionalIdx,
9035                               AMDGPUOperand::ImmTyOModSI, 0);
9036 
9037       if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::dst_sel))
9038         addOptionalImmOperand(Inst, Operands, OptionalIdx,
9039                               AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
9040 
9041       if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::dst_unused))
9042         addOptionalImmOperand(Inst, Operands, OptionalIdx,
9043                               AMDGPUOperand::ImmTySDWADstUnused,
9044                               DstUnused::UNUSED_PRESERVE);
9045 
9046       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
9047       break;
9048 
9049     case SIInstrFlags::VOP2:
9050       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI, 0);
9051 
9052       if (AMDGPU::hasNamedOperand(Inst.getOpcode(), AMDGPU::OpName::omod))
9053         addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOModSI, 0);
9054 
9055       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
9056       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
9057       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
9058       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
9059       break;
9060 
9061     case SIInstrFlags::VOPC:
9062       if (AMDGPU::hasNamedOperand(Inst.getOpcode(), AMDGPU::OpName::clamp))
9063         addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI, 0);
9064       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
9065       addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
9066       break;
9067 
9068     default:
9069       llvm_unreachable("Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
9070     }
9071   }
9072 
9073   // special case v_mac_{f16, f32}:
9074   // it has src2 register operand that is tied to dst operand
9075   if (Inst.getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
9076       Inst.getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi)  {
9077     auto it = Inst.begin();
9078     std::advance(
9079       it, AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::src2));
9080     Inst.insert(it, Inst.getOperand(0)); // src2 = dst
9081   }
9082 }
9083 
9084 /// Force static initialization.
9085 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser() {
9086   RegisterMCAsmParser<AMDGPUAsmParser> A(getTheR600Target());
9087   RegisterMCAsmParser<AMDGPUAsmParser> B(getTheGCNTarget());
9088 }
9089 
9090 #define GET_REGISTER_MATCHER
9091 #define GET_MATCHER_IMPLEMENTATION
9092 #define GET_MNEMONIC_SPELL_CHECKER
9093 #define GET_MNEMONIC_CHECKER
9094 #include "AMDGPUGenAsmMatcher.inc"
9095 
9096 ParseStatus AMDGPUAsmParser::parseCustomOperand(OperandVector &Operands,
9097                                                 unsigned MCK) {
9098   switch (MCK) {
9099   case MCK_addr64:
9100     return parseTokenOp("addr64", Operands);
9101   case MCK_done:
9102     return parseTokenOp("done", Operands);
9103   case MCK_idxen:
9104     return parseTokenOp("idxen", Operands);
9105   case MCK_lds:
9106     return parseTokenOp("lds", Operands);
9107   case MCK_offen:
9108     return parseTokenOp("offen", Operands);
9109   case MCK_off:
9110     return parseTokenOp("off", Operands);
9111   case MCK_row_95_en:
9112     return parseTokenOp("row_en", Operands);
9113   case MCK_gds:
9114     return parseNamedBit("gds", Operands, AMDGPUOperand::ImmTyGDS);
9115   case MCK_tfe:
9116     return parseNamedBit("tfe", Operands, AMDGPUOperand::ImmTyTFE);
9117   }
9118   return tryCustomParseOperand(Operands, MCK);
9119 }
9120 
9121 // This function should be defined after auto-generated include so that we have
9122 // MatchClassKind enum defined
9123 unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &Op,
9124                                                      unsigned Kind) {
9125   // Tokens like "glc" would be parsed as immediate operands in ParseOperand().
9126   // But MatchInstructionImpl() expects to meet token and fails to validate
9127   // operand. This method checks if we are given immediate operand but expect to
9128   // get corresponding token.
9129   AMDGPUOperand &Operand = (AMDGPUOperand&)Op;
9130   switch (Kind) {
9131   case MCK_addr64:
9132     return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
9133   case MCK_gds:
9134     return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
9135   case MCK_lds:
9136     return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
9137   case MCK_idxen:
9138     return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
9139   case MCK_offen:
9140     return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
9141   case MCK_tfe:
9142     return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
9143   case MCK_SSrcB32:
9144     // When operands have expression values, they will return true for isToken,
9145     // because it is not possible to distinguish between a token and an
9146     // expression at parse time. MatchInstructionImpl() will always try to
9147     // match an operand as a token, when isToken returns true, and when the
9148     // name of the expression is not a valid token, the match will fail,
9149     // so we need to handle it here.
9150     return Operand.isSSrcB32() ? Match_Success : Match_InvalidOperand;
9151   case MCK_SSrcF32:
9152     return Operand.isSSrcF32() ? Match_Success : Match_InvalidOperand;
9153   case MCK_SOPPBrTarget:
9154     return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
9155   case MCK_VReg32OrOff:
9156     return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
9157   case MCK_InterpSlot:
9158     return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
9159   case MCK_InterpAttr:
9160     return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
9161   case MCK_InterpAttrChan:
9162     return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
9163   case MCK_SReg_64:
9164   case MCK_SReg_64_XEXEC:
9165     // Null is defined as a 32-bit register but
9166     // it should also be enabled with 64-bit operands.
9167     // The following code enables it for SReg_64 operands
9168     // used as source and destination. Remaining source
9169     // operands are handled in isInlinableImm.
9170     return Operand.isNull() ? Match_Success : Match_InvalidOperand;
9171   default:
9172     return Match_InvalidOperand;
9173   }
9174 }
9175 
9176 //===----------------------------------------------------------------------===//
9177 // endpgm
9178 //===----------------------------------------------------------------------===//
9179 
9180 ParseStatus AMDGPUAsmParser::parseEndpgm(OperandVector &Operands) {
9181   SMLoc S = getLoc();
9182   int64_t Imm = 0;
9183 
9184   if (!parseExpr(Imm)) {
9185     // The operand is optional, if not present default to 0
9186     Imm = 0;
9187   }
9188 
9189   if (!isUInt<16>(Imm))
9190     return Error(S, "expected a 16-bit value");
9191 
9192   Operands.push_back(
9193       AMDGPUOperand::CreateImm(this, Imm, S, AMDGPUOperand::ImmTyEndpgm));
9194   return ParseStatus::Success;
9195 }
9196 
9197 bool AMDGPUOperand::isEndpgm() const { return isImmTy(ImmTyEndpgm); }
9198 
9199 //===----------------------------------------------------------------------===//
9200 // LDSDIR
9201 //===----------------------------------------------------------------------===//
9202 
9203 bool AMDGPUOperand::isWaitVDST() const {
9204   return isImmTy(ImmTyWaitVDST) && isUInt<4>(getImm());
9205 }
9206 
9207 bool AMDGPUOperand::isWaitVAVDst() const {
9208   return isImmTy(ImmTyWaitVAVDst) && isUInt<4>(getImm());
9209 }
9210 
9211 bool AMDGPUOperand::isWaitVMVSrc() const {
9212   return isImmTy(ImmTyWaitVMVSrc) && isUInt<1>(getImm());
9213 }
9214 
9215 //===----------------------------------------------------------------------===//
9216 // VINTERP
9217 //===----------------------------------------------------------------------===//
9218 
9219 bool AMDGPUOperand::isWaitEXP() const {
9220   return isImmTy(ImmTyWaitEXP) && isUInt<3>(getImm());
9221 }
9222 
9223 //===----------------------------------------------------------------------===//
9224 // Split Barrier
9225 //===----------------------------------------------------------------------===//
9226 
9227 bool AMDGPUOperand::isSplitBarrier() const { return isInlinableImm(MVT::i32); }
9228