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

Generated by: LCOV version 1.13