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