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