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