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