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