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

Generated by: LCOV version 1.13