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