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