LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU/AsmParser - AMDGPUAsmParser.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 1713 1906 89.9 %
Date: 2018-06-17 00:07:59 Functions: 133 150 88.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13