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

Generated by: LCOV version 1.13