//===-- AMDGPUAsmParser.cpp - Parse SI asm to MCInst instructions ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
#include "MCTargetDesc/AMDGPUTargetStreamer.h"
#include "Utils/AMDGPUBaseInfo.h"
#include "AMDKernelCodeT.h"
#include "SIDefines.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Debug.h"

using namespace llvm;

namespace {

struct OptionalOperand;

class AMDGPUOperand : public MCParsedAsmOperand {
  enum KindTy {
    Token,
    Immediate,
    Register,
    Expression
  } Kind;

  SMLoc StartLoc, EndLoc;

public:
  AMDGPUOperand(enum KindTy K) : MCParsedAsmOperand(), Kind(K) {}

  MCContext *Ctx;

  enum ImmTy {
    ImmTyNone,
    ImmTyDSOffset0,
    ImmTyDSOffset1,
    ImmTyGDS,
    ImmTyOffset,
    ImmTyGLC,
    ImmTySLC,
    ImmTyTFE,
    ImmTyClamp,
    ImmTyOMod
  };

  struct TokOp {
    const char *Data;
    unsigned Length;
  };

  struct ImmOp {
    bool IsFPImm;
    ImmTy Type;
    int64_t Val;
  };

  struct RegOp {
    unsigned RegNo;
    int Modifiers;
    const MCRegisterInfo *TRI;
    const MCSubtargetInfo *STI;
    bool IsForcedVOP3;
  };

  union {
    TokOp Tok;
    ImmOp Imm;
    RegOp Reg;
    const MCExpr *Expr;
  };

  void addImmOperands(MCInst &Inst, unsigned N) const {
    Inst.addOperand(MCOperand::createImm(getImm()));
  }

  StringRef getToken() const {
    return StringRef(Tok.Data, Tok.Length);
  }

  void addRegOperands(MCInst &Inst, unsigned N) const {
    Inst.addOperand(MCOperand::createReg(AMDGPU::getMCReg(getReg(), *Reg.STI)));
  }

  void addRegOrImmOperands(MCInst &Inst, unsigned N) const {
    if (isReg())
      addRegOperands(Inst, N);
    else
      addImmOperands(Inst, N);
  }

  void addRegWithInputModsOperands(MCInst &Inst, unsigned N) const {
    Inst.addOperand(MCOperand::createImm(
        Reg.Modifiers == -1 ? 0 : Reg.Modifiers));
    addRegOperands(Inst, N);
  }

  void addSoppBrTargetOperands(MCInst &Inst, unsigned N) const {
    if (isImm())
      addImmOperands(Inst, N);
    else {
      assert(isExpr());
      Inst.addOperand(MCOperand::createExpr(Expr));
    }
  }

  bool defaultTokenHasSuffix() const {
    StringRef Token(Tok.Data, Tok.Length);

    return Token.endswith("_e32") || Token.endswith("_e64");
  }

  bool isToken() const override {
    return Kind == Token;
  }

  bool isImm() const override {
    return Kind == Immediate;
  }

  bool isInlineImm() const {
    float F = BitsToFloat(Imm.Val);
    // TODO: Add 0.5pi for VI
    return isImm() && ((Imm.Val <= 64 && Imm.Val >= -16) ||
           (F == 0.0 || F == 0.5 || F == -0.5 || F == 1.0 || F == -1.0 ||
           F == 2.0 || F == -2.0 || F == 4.0 || F == -4.0));
  }

  bool isDSOffset0() const {
    assert(isImm());
    return Imm.Type == ImmTyDSOffset0;
  }

  bool isDSOffset1() const {
    assert(isImm());
    return Imm.Type == ImmTyDSOffset1;
  }

  int64_t getImm() const {
    return Imm.Val;
  }

  enum ImmTy getImmTy() const {
    assert(isImm());
    return Imm.Type;
  }

  bool isRegKind() const {
    return Kind == Register;
  }

  bool isReg() const override {
    return Kind == Register && Reg.Modifiers == -1;
  }

  bool isRegWithInputMods() const {
    return Kind == Register && (Reg.IsForcedVOP3 || Reg.Modifiers != -1);
  }

  void setModifiers(unsigned Mods) {
    assert(isReg());
    Reg.Modifiers = Mods;
  }

  bool hasModifiers() const {
    assert(isRegKind());
    return Reg.Modifiers != -1;
  }

  unsigned getReg() const override {
    return Reg.RegNo;
  }

  bool isRegOrImm() const {
    return isReg() || isImm();
  }

  bool isRegClass(unsigned RCID) const {
    return Reg.TRI->getRegClass(RCID).contains(getReg());
  }

  bool isSCSrc32() const {
    return isInlineImm() || (isReg() && isRegClass(AMDGPU::SReg_32RegClassID));
  }

  bool isSSrc32() const {
    return isImm() || (isReg() && isRegClass(AMDGPU::SReg_32RegClassID));
  }

  bool isSSrc64() const {
    return isImm() || isInlineImm() ||
           (isReg() && isRegClass(AMDGPU::SReg_64RegClassID));
  }

  bool isSCSrc64() const {
    return (isReg() && isRegClass(AMDGPU::SReg_64RegClassID)) || isInlineImm();
  }

  bool isVCSrc32() const {
    return isInlineImm() || (isReg() && isRegClass(AMDGPU::VS_32RegClassID));
  }

  bool isVCSrc64() const {
    return isInlineImm() || (isReg() && isRegClass(AMDGPU::VS_64RegClassID));
  }

  bool isVSrc32() const {
    return isImm() || (isReg() && isRegClass(AMDGPU::VS_32RegClassID));
  }

  bool isVSrc64() const {
    return isImm() || (isReg() && isRegClass(AMDGPU::VS_64RegClassID));
  }

  bool isMem() const override {
    return false;
  }

  bool isExpr() const {
    return Kind == Expression;
  }

  bool isSoppBrTarget() const {
    return isExpr() || isImm();
  }

  SMLoc getStartLoc() const override {
    return StartLoc;
  }

  SMLoc getEndLoc() const override {
    return EndLoc;
  }

  void print(raw_ostream &OS) const override {
    switch (Kind) {
    case Register:
      OS << "<register " << getReg() << " mods: " << Reg.Modifiers << '>';
      break;
    case Immediate:
      OS << getImm();
      break;
    case Token:
      OS << '\'' << getToken() << '\'';
      break;
    case Expression:
      OS << "<expr " << *Expr << '>';
      break;
    }
  }

  static std::unique_ptr<AMDGPUOperand> CreateImm(int64_t Val, SMLoc Loc,
                                                  enum ImmTy Type = ImmTyNone,
                                                  bool IsFPImm = false) {
    auto Op = llvm::make_unique<AMDGPUOperand>(Immediate);
    Op->Imm.Val = Val;
    Op->Imm.IsFPImm = IsFPImm;
    Op->Imm.Type = Type;
    Op->StartLoc = Loc;
    Op->EndLoc = Loc;
    return Op;
  }

  static std::unique_ptr<AMDGPUOperand> CreateToken(StringRef Str, SMLoc Loc,
                                           bool HasExplicitEncodingSize = true) {
    auto Res = llvm::make_unique<AMDGPUOperand>(Token);
    Res->Tok.Data = Str.data();
    Res->Tok.Length = Str.size();
    Res->StartLoc = Loc;
    Res->EndLoc = Loc;
    return Res;
  }

  static std::unique_ptr<AMDGPUOperand> CreateReg(unsigned RegNo, SMLoc S,
                                                  SMLoc E,
                                                  const MCRegisterInfo *TRI,
                                                  const MCSubtargetInfo *STI,
                                                  bool ForceVOP3) {
    auto Op = llvm::make_unique<AMDGPUOperand>(Register);
    Op->Reg.RegNo = RegNo;
    Op->Reg.TRI = TRI;
    Op->Reg.STI = STI;
    Op->Reg.Modifiers = -1;
    Op->Reg.IsForcedVOP3 = ForceVOP3;
    Op->StartLoc = S;
    Op->EndLoc = E;
    return Op;
  }

  static std::unique_ptr<AMDGPUOperand> CreateExpr(const class MCExpr *Expr, SMLoc S) {
    auto Op = llvm::make_unique<AMDGPUOperand>(Expression);
    Op->Expr = Expr;
    Op->StartLoc = S;
    Op->EndLoc = S;
    return Op;
  }

  bool isDSOffset() const;
  bool isDSOffset01() const;
  bool isSWaitCnt() const;
  bool isMubufOffset() const;
  bool isSMRDOffset() const;
  bool isSMRDLiteralOffset() const;
};

class AMDGPUAsmParser : public MCTargetAsmParser {
  const MCInstrInfo &MII;
  MCAsmParser &Parser;

  unsigned ForcedEncodingSize;

  bool isSI() const {
    return AMDGPU::isSI(getSTI());
  }

  bool isCI() const {
    return AMDGPU::isCI(getSTI());
  }

  bool isVI() const {
    return AMDGPU::isVI(getSTI());
  }

  bool hasSGPR102_SGPR103() const {
    return !isVI();
  }

  /// @name Auto-generated Match Functions
  /// {

#define GET_ASSEMBLER_HEADER
#include "AMDGPUGenAsmMatcher.inc"

  /// }

private:
  bool ParseDirectiveMajorMinor(uint32_t &Major, uint32_t &Minor);
  bool ParseDirectiveHSACodeObjectVersion();
  bool ParseDirectiveHSACodeObjectISA();
  bool ParseAMDKernelCodeTValue(StringRef ID, amd_kernel_code_t &Header);
  bool ParseDirectiveAMDKernelCodeT();
  bool ParseSectionDirectiveHSAText();
  bool subtargetHasRegister(const MCRegisterInfo &MRI, unsigned RegNo) const;
  bool ParseDirectiveAMDGPUHsaKernel();
  bool ParseDirectiveAMDGPUHsaModuleGlobal();
  bool ParseDirectiveAMDGPUHsaProgramGlobal();
  bool ParseSectionDirectiveHSADataGlobalAgent();
  bool ParseSectionDirectiveHSADataGlobalProgram();
  bool ParseSectionDirectiveHSARodataReadonlyAgent();

public:
public:
  enum AMDGPUMatchResultTy {
    Match_PreferE32 = FIRST_TARGET_MATCH_RESULT_TY
  };

  AMDGPUAsmParser(const MCSubtargetInfo &STI, MCAsmParser &_Parser,
               const MCInstrInfo &MII,
               const MCTargetOptions &Options)
      : MCTargetAsmParser(Options, STI), MII(MII), Parser(_Parser),
        ForcedEncodingSize(0) {
    MCAsmParserExtension::Initialize(Parser);

    if (getSTI().getFeatureBits().none()) {
      // Set default features.
      copySTI().ToggleFeature("SOUTHERN_ISLANDS");
    }

    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
  }

  AMDGPUTargetStreamer &getTargetStreamer() {
    MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
    return static_cast<AMDGPUTargetStreamer &>(TS);
  }

  unsigned getForcedEncodingSize() const {
    return ForcedEncodingSize;
  }

  void setForcedEncodingSize(unsigned Size) {
    ForcedEncodingSize = Size;
  }

  bool isForcedVOP3() const {
    return ForcedEncodingSize == 64;
  }

  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
  unsigned checkTargetMatchPredicate(MCInst &Inst) override;
  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                               OperandVector &Operands, MCStreamer &Out,
                               uint64_t &ErrorInfo,
                               bool MatchingInlineAsm) override;
  bool ParseDirective(AsmToken DirectiveID) override;
  OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Mnemonic);
  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                        SMLoc NameLoc, OperandVector &Operands) override;

  OperandMatchResultTy parseIntWithPrefix(const char *Prefix, int64_t &Int,
                                          int64_t Default = 0);
  OperandMatchResultTy parseIntWithPrefix(const char *Prefix,
                                          OperandVector &Operands,
                                          enum AMDGPUOperand::ImmTy ImmTy =
                                                      AMDGPUOperand::ImmTyNone);
  OperandMatchResultTy parseNamedBit(const char *Name, OperandVector &Operands,
                                     enum AMDGPUOperand::ImmTy ImmTy =
                                                      AMDGPUOperand::ImmTyNone);
  OperandMatchResultTy parseOptionalOps(
                                   const ArrayRef<OptionalOperand> &OptionalOps,
                                   OperandVector &Operands);


  void cvtDSOffset01(MCInst &Inst, const OperandVector &Operands);
  void cvtDS(MCInst &Inst, const OperandVector &Operands);
  OperandMatchResultTy parseDSOptionalOps(OperandVector &Operands);
  OperandMatchResultTy parseDSOff01OptionalOps(OperandVector &Operands);
  OperandMatchResultTy parseDSOffsetOptional(OperandVector &Operands);

  bool parseCnt(int64_t &IntVal);
  OperandMatchResultTy parseSWaitCntOps(OperandVector &Operands);
  OperandMatchResultTy parseSOppBrTarget(OperandVector &Operands);

  OperandMatchResultTy parseFlatOptionalOps(OperandVector &Operands);
  OperandMatchResultTy parseFlatAtomicOptionalOps(OperandVector &Operands);
  void cvtFlat(MCInst &Inst, const OperandVector &Operands);

  void cvtMubuf(MCInst &Inst, const OperandVector &Operands);
  OperandMatchResultTy parseOffset(OperandVector &Operands);
  OperandMatchResultTy parseMubufOptionalOps(OperandVector &Operands);
  OperandMatchResultTy parseGLC(OperandVector &Operands);
  OperandMatchResultTy parseSLC(OperandVector &Operands);
  OperandMatchResultTy parseTFE(OperandVector &Operands);

  OperandMatchResultTy parseDMask(OperandVector &Operands);
  OperandMatchResultTy parseUNorm(OperandVector &Operands);
  OperandMatchResultTy parseR128(OperandVector &Operands);

  void cvtVOP3(MCInst &Inst, const OperandVector &Operands);
  OperandMatchResultTy parseVOP3OptionalOps(OperandVector &Operands);
};

struct OptionalOperand {
  const char *Name;
  AMDGPUOperand::ImmTy Type;
  bool IsBit;
  int64_t Default;
  bool (*ConvertResult)(int64_t&);
};

}

static int getRegClass(bool IsVgpr, unsigned RegWidth) {
  if (IsVgpr) {
    switch (RegWidth) {
      default: return -1;
      case 1: return AMDGPU::VGPR_32RegClassID;
      case 2: return AMDGPU::VReg_64RegClassID;
      case 3: return AMDGPU::VReg_96RegClassID;
      case 4: return AMDGPU::VReg_128RegClassID;
      case 8: return AMDGPU::VReg_256RegClassID;
      case 16: return AMDGPU::VReg_512RegClassID;
    }
  }

  switch (RegWidth) {
    default: return -1;
    case 1: return AMDGPU::SGPR_32RegClassID;
    case 2: return AMDGPU::SGPR_64RegClassID;
    case 4: return AMDGPU::SReg_128RegClassID;
    case 8: return AMDGPU::SReg_256RegClassID;
    case 16: return AMDGPU::SReg_512RegClassID;
  }
}

static unsigned getRegForName(StringRef RegName) {

  return StringSwitch<unsigned>(RegName)
    .Case("exec", AMDGPU::EXEC)
    .Case("vcc", AMDGPU::VCC)
    .Case("flat_scratch", AMDGPU::FLAT_SCR)
    .Case("m0", AMDGPU::M0)
    .Case("scc", AMDGPU::SCC)
    .Case("flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
    .Case("flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
    .Case("vcc_lo", AMDGPU::VCC_LO)
    .Case("vcc_hi", AMDGPU::VCC_HI)
    .Case("exec_lo", AMDGPU::EXEC_LO)
    .Case("exec_hi", AMDGPU::EXEC_HI)
    .Default(0);
}

bool AMDGPUAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
  const AsmToken Tok = Parser.getTok();
  StartLoc = Tok.getLoc();
  EndLoc = Tok.getEndLoc();
  const MCRegisterInfo *TRI = getContext().getRegisterInfo();

  StringRef RegName = Tok.getString();
  RegNo = getRegForName(RegName);

  if (RegNo) {
    Parser.Lex();
    return !subtargetHasRegister(*TRI, RegNo);
  }

  // Match vgprs and sgprs
  if (RegName[0] != 's' && RegName[0] != 'v')
    return true;

  bool IsVgpr = RegName[0] == 'v';
  unsigned RegWidth;
  unsigned RegIndexInClass;
  if (RegName.size() > 1) {
    // We have a 32-bit register
    RegWidth = 1;
    if (RegName.substr(1).getAsInteger(10, RegIndexInClass))
      return true;
    Parser.Lex();
  } else {
    // We have a register greater than 32-bits.

    int64_t RegLo, RegHi;
    Parser.Lex();
    if (getLexer().isNot(AsmToken::LBrac))
      return true;

    Parser.Lex();
    if (getParser().parseAbsoluteExpression(RegLo))
      return true;

    if (getLexer().isNot(AsmToken::Colon))
      return true;

    Parser.Lex();
    if (getParser().parseAbsoluteExpression(RegHi))
      return true;

    if (getLexer().isNot(AsmToken::RBrac))
      return true;

    Parser.Lex();
    RegWidth = (RegHi - RegLo) + 1;
    if (IsVgpr) {
      // VGPR registers aren't aligned.
      RegIndexInClass = RegLo;
    } else {
      // SGPR registers are aligned.  Max alignment is 4 dwords.
      unsigned Size = std::min(RegWidth, 4u);
      if (RegLo % Size != 0)
        return true;

      RegIndexInClass = RegLo / Size;
    }
  }

  int RCID = getRegClass(IsVgpr, RegWidth);
  if (RCID == -1)
    return true;

  const MCRegisterClass RC = TRI->getRegClass(RCID);
  if (RegIndexInClass >= RC.getNumRegs())
    return true;

  RegNo = RC.getRegister(RegIndexInClass);
  return !subtargetHasRegister(*TRI, RegNo);
}

unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {

  uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;

  if ((getForcedEncodingSize() == 32 && (TSFlags & SIInstrFlags::VOP3)) ||
      (getForcedEncodingSize() == 64 && !(TSFlags & SIInstrFlags::VOP3)))
    return Match_InvalidOperand;

  if ((TSFlags & SIInstrFlags::VOP3) &&
      (TSFlags & SIInstrFlags::VOPAsmPrefer32Bit) &&
      getForcedEncodingSize() != 64)
    return Match_PreferE32;

  return Match_Success;
}


bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                                              OperandVector &Operands,
                                              MCStreamer &Out,
                                              uint64_t &ErrorInfo,
                                              bool MatchingInlineAsm) {
  MCInst Inst;

  switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
    default: break;
    case Match_Success:
      Inst.setLoc(IDLoc);
      Out.EmitInstruction(Inst, getSTI());
      return false;
    case Match_MissingFeature:
      return Error(IDLoc, "instruction not supported on this GPU");

    case Match_MnemonicFail:
      return Error(IDLoc, "unrecognized instruction mnemonic");

    case Match_InvalidOperand: {
      SMLoc ErrorLoc = IDLoc;
      if (ErrorInfo != ~0ULL) {
        if (ErrorInfo >= Operands.size()) {
          if (isForcedVOP3()) {
            // If 64-bit encoding has been forced we can end up with no
            // clamp or omod operands if none of the registers have modifiers,
            // so we need to add these to the operand list.
            AMDGPUOperand &LastOp =
                ((AMDGPUOperand &)*Operands[Operands.size() - 1]);
            if (LastOp.isRegKind() ||
               (LastOp.isImm() &&
                LastOp.getImmTy() != AMDGPUOperand::ImmTyNone)) {
              SMLoc S = Parser.getTok().getLoc();
              Operands.push_back(AMDGPUOperand::CreateImm(0, S,
                                 AMDGPUOperand::ImmTyClamp));
              Operands.push_back(AMDGPUOperand::CreateImm(0, S,
                                 AMDGPUOperand::ImmTyOMod));
              bool Res = MatchAndEmitInstruction(IDLoc, Opcode, Operands,
                                                 Out, ErrorInfo,
                                                 MatchingInlineAsm);
              if (!Res)
                return Res;
            }

          }
          return Error(IDLoc, "too few operands for instruction");
        }

        ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
        if (ErrorLoc == SMLoc())
          ErrorLoc = IDLoc;
      }
      return Error(ErrorLoc, "invalid operand for instruction");
    }
    case Match_PreferE32:
      return Error(IDLoc, "internal error: instruction without _e64 suffix "
                          "should be encoded as e32");
  }
  llvm_unreachable("Implement any new match types added!");
}

bool AMDGPUAsmParser::ParseDirectiveMajorMinor(uint32_t &Major,
                                               uint32_t &Minor) {
  if (getLexer().isNot(AsmToken::Integer))
    return TokError("invalid major version");

  Major = getLexer().getTok().getIntVal();
  Lex();

  if (getLexer().isNot(AsmToken::Comma))
    return TokError("minor version number required, comma expected");
  Lex();

  if (getLexer().isNot(AsmToken::Integer))
    return TokError("invalid minor version");

  Minor = getLexer().getTok().getIntVal();
  Lex();

  return false;
}

bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectVersion() {

  uint32_t Major;
  uint32_t Minor;

  if (ParseDirectiveMajorMinor(Major, Minor))
    return true;

  getTargetStreamer().EmitDirectiveHSACodeObjectVersion(Major, Minor);
  return false;
}

bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectISA() {

  uint32_t Major;
  uint32_t Minor;
  uint32_t Stepping;
  StringRef VendorName;
  StringRef ArchName;

  // If this directive has no arguments, then use the ISA version for the
  // targeted GPU.
  if (getLexer().is(AsmToken::EndOfStatement)) {
    AMDGPU::IsaVersion Isa = AMDGPU::getIsaVersion(getSTI().getFeatureBits());
    getTargetStreamer().EmitDirectiveHSACodeObjectISA(Isa.Major, Isa.Minor,
                                                      Isa.Stepping,
                                                      "AMD", "AMDGPU");
    return false;
  }


  if (ParseDirectiveMajorMinor(Major, Minor))
    return true;

  if (getLexer().isNot(AsmToken::Comma))
    return TokError("stepping version number required, comma expected");
  Lex();

  if (getLexer().isNot(AsmToken::Integer))
    return TokError("invalid stepping version");

  Stepping = getLexer().getTok().getIntVal();
  Lex();

  if (getLexer().isNot(AsmToken::Comma))
    return TokError("vendor name required, comma expected");
  Lex();

  if (getLexer().isNot(AsmToken::String))
    return TokError("invalid vendor name");

  VendorName = getLexer().getTok().getStringContents();
  Lex();

  if (getLexer().isNot(AsmToken::Comma))
    return TokError("arch name required, comma expected");
  Lex();

  if (getLexer().isNot(AsmToken::String))
    return TokError("invalid arch name");

  ArchName = getLexer().getTok().getStringContents();
  Lex();

  getTargetStreamer().EmitDirectiveHSACodeObjectISA(Major, Minor, Stepping,
                                                    VendorName, ArchName);
  return false;
}

bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef ID,
                                               amd_kernel_code_t &Header) {

  if (getLexer().isNot(AsmToken::Equal))
    return TokError("expected '='");
  Lex();

  if (getLexer().isNot(AsmToken::Integer))
    return TokError("amd_kernel_code_t values must be integers");

  uint64_t Value = getLexer().getTok().getIntVal();
  Lex();

  if (ID == "kernel_code_version_major")
    Header.amd_kernel_code_version_major = Value;
  else if (ID == "kernel_code_version_minor")
    Header.amd_kernel_code_version_minor = Value;
  else if (ID == "machine_kind")
    Header.amd_machine_kind = Value;
  else if (ID == "machine_version_major")
    Header.amd_machine_version_major = Value;
  else if (ID == "machine_version_minor")
    Header.amd_machine_version_minor = Value;
  else if (ID == "machine_version_stepping")
    Header.amd_machine_version_stepping = Value;
  else if (ID == "kernel_code_entry_byte_offset")
    Header.kernel_code_entry_byte_offset = Value;
  else if (ID == "kernel_code_prefetch_byte_size")
    Header.kernel_code_prefetch_byte_size = Value;
  else if (ID == "max_scratch_backing_memory_byte_size")
    Header.max_scratch_backing_memory_byte_size = Value;
  else if (ID == "compute_pgm_rsrc1_vgprs")
    Header.compute_pgm_resource_registers |= S_00B848_VGPRS(Value);
  else if (ID == "compute_pgm_rsrc1_sgprs")
    Header.compute_pgm_resource_registers |= S_00B848_SGPRS(Value);
  else if (ID == "compute_pgm_rsrc1_priority")
    Header.compute_pgm_resource_registers |= S_00B848_PRIORITY(Value);
  else if (ID == "compute_pgm_rsrc1_float_mode")
    Header.compute_pgm_resource_registers |= S_00B848_FLOAT_MODE(Value);
  else if (ID == "compute_pgm_rsrc1_priv")
    Header.compute_pgm_resource_registers |= S_00B848_PRIV(Value);
  else if (ID == "compute_pgm_rsrc1_dx10_clamp")
    Header.compute_pgm_resource_registers |= S_00B848_DX10_CLAMP(Value);
  else if (ID == "compute_pgm_rsrc1_debug_mode")
    Header.compute_pgm_resource_registers |= S_00B848_DEBUG_MODE(Value);
  else if (ID == "compute_pgm_rsrc1_ieee_mode")
    Header.compute_pgm_resource_registers |= S_00B848_IEEE_MODE(Value);
  else if (ID == "compute_pgm_rsrc2_scratch_en")
    Header.compute_pgm_resource_registers |= (S_00B84C_SCRATCH_EN(Value) << 32);
  else if (ID == "compute_pgm_rsrc2_user_sgpr")
    Header.compute_pgm_resource_registers |= (S_00B84C_USER_SGPR(Value) << 32);
  else if (ID == "compute_pgm_rsrc2_tgid_x_en")
    Header.compute_pgm_resource_registers |= (S_00B84C_TGID_X_EN(Value) << 32);
  else if (ID == "compute_pgm_rsrc2_tgid_y_en")
    Header.compute_pgm_resource_registers |= (S_00B84C_TGID_Y_EN(Value) << 32);
  else if (ID == "compute_pgm_rsrc2_tgid_z_en")
    Header.compute_pgm_resource_registers |= (S_00B84C_TGID_Z_EN(Value) << 32);
  else if (ID == "compute_pgm_rsrc2_tg_size_en")
    Header.compute_pgm_resource_registers |= (S_00B84C_TG_SIZE_EN(Value) << 32);
  else if (ID == "compute_pgm_rsrc2_tidig_comp_cnt")
    Header.compute_pgm_resource_registers |=
        (S_00B84C_TIDIG_COMP_CNT(Value) << 32);
  else if (ID == "compute_pgm_rsrc2_excp_en_msb")
    Header.compute_pgm_resource_registers |=
        (S_00B84C_EXCP_EN_MSB(Value) << 32);
  else if (ID == "compute_pgm_rsrc2_lds_size")
    Header.compute_pgm_resource_registers |= (S_00B84C_LDS_SIZE(Value) << 32);
  else if (ID == "compute_pgm_rsrc2_excp_en")
    Header.compute_pgm_resource_registers |= (S_00B84C_EXCP_EN(Value) << 32);
  else if (ID == "compute_pgm_resource_registers")
    Header.compute_pgm_resource_registers = Value;
  else if (ID == "enable_sgpr_private_segment_buffer")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER_SHIFT);
  else if (ID == "enable_sgpr_dispatch_ptr")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR_SHIFT);
  else if (ID == "enable_sgpr_queue_ptr")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR_SHIFT);
  else if (ID == "enable_sgpr_kernarg_segment_ptr")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR_SHIFT);
  else if (ID == "enable_sgpr_dispatch_id")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID_SHIFT);
  else if (ID == "enable_sgpr_flat_scratch_init")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT_SHIFT);
  else if (ID == "enable_sgpr_private_segment_size")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE_SHIFT);
  else if (ID == "enable_sgpr_grid_workgroup_count_x")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_GRID_WORKGROUP_COUNT_X_SHIFT);
  else if (ID == "enable_sgpr_grid_workgroup_count_y")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_GRID_WORKGROUP_COUNT_Y_SHIFT);
  else if (ID == "enable_sgpr_grid_workgroup_count_z")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_ENABLE_SGPR_GRID_WORKGROUP_COUNT_Z_SHIFT);
  else if (ID == "enable_ordered_append_gds")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_ENABLE_ORDERED_APPEND_GDS_SHIFT);
  else if (ID == "private_element_size")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_PRIVATE_ELEMENT_SIZE_SHIFT);
  else if (ID == "is_ptr64")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_IS_PTR64_SHIFT);
  else if (ID == "is_dynamic_callstack")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_IS_DYNAMIC_CALLSTACK_SHIFT);
  else if (ID == "is_debug_enabled")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_IS_DEBUG_SUPPORTED_SHIFT);
  else if (ID == "is_xnack_enabled")
    Header.code_properties |=
        (Value << AMD_CODE_PROPERTY_IS_XNACK_SUPPORTED_SHIFT);
  else if (ID == "workitem_private_segment_byte_size")
    Header.workitem_private_segment_byte_size = Value;
  else if (ID == "workgroup_group_segment_byte_size")
    Header.workgroup_group_segment_byte_size = Value;
  else if (ID == "gds_segment_byte_size")
    Header.gds_segment_byte_size = Value;
  else if (ID == "kernarg_segment_byte_size")
    Header.kernarg_segment_byte_size = Value;
  else if (ID == "workgroup_fbarrier_count")
    Header.workgroup_fbarrier_count = Value;
  else if (ID == "wavefront_sgpr_count")
    Header.wavefront_sgpr_count = Value;
  else if (ID == "workitem_vgpr_count")
    Header.workitem_vgpr_count = Value;
  else if (ID == "reserved_vgpr_first")
    Header.reserved_vgpr_first = Value;
  else if (ID == "reserved_vgpr_count")
    Header.reserved_vgpr_count = Value;
  else if (ID == "reserved_sgpr_first")
    Header.reserved_sgpr_first = Value;
  else if (ID == "reserved_sgpr_count")
    Header.reserved_sgpr_count = Value;
  else if (ID == "debug_wavefront_private_segment_offset_sgpr")
    Header.debug_wavefront_private_segment_offset_sgpr = Value;
  else if (ID == "debug_private_segment_buffer_sgpr")
    Header.debug_private_segment_buffer_sgpr = Value;
  else if (ID == "kernarg_segment_alignment")
    Header.kernarg_segment_alignment = Value;
  else if (ID == "group_segment_alignment")
    Header.group_segment_alignment = Value;
  else if (ID == "private_segment_alignment")
    Header.private_segment_alignment = Value;
  else if (ID == "wavefront_size")
    Header.wavefront_size = Value;
  else if (ID == "call_convention")
    Header.call_convention = Value;
  else if (ID == "runtime_loader_kernel_symbol")
    Header.runtime_loader_kernel_symbol = Value;
  else
    return TokError("amd_kernel_code_t value not recognized.");

  return false;
}

bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {

  amd_kernel_code_t Header;
  AMDGPU::initDefaultAMDKernelCodeT(Header, getSTI().getFeatureBits());

  while (true) {

    if (getLexer().isNot(AsmToken::EndOfStatement))
      return TokError("amd_kernel_code_t values must begin on a new line");

    // Lex EndOfStatement.  This is in a while loop, because lexing a comment
    // will set the current token to EndOfStatement.
    while(getLexer().is(AsmToken::EndOfStatement))
      Lex();

    if (getLexer().isNot(AsmToken::Identifier))
      return TokError("expected value identifier or .end_amd_kernel_code_t");

    StringRef ID = getLexer().getTok().getIdentifier();
    Lex();

    if (ID == ".end_amd_kernel_code_t")
      break;

    if (ParseAMDKernelCodeTValue(ID, Header))
      return true;
  }

  getTargetStreamer().EmitAMDKernelCodeT(Header);

  return false;
}

bool AMDGPUAsmParser::ParseSectionDirectiveHSAText() {
  getParser().getStreamer().SwitchSection(
      AMDGPU::getHSATextSection(getContext()));
  return false;
}

bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
  if (getLexer().isNot(AsmToken::Identifier))
    return TokError("expected symbol name");

  StringRef KernelName = Parser.getTok().getString();

  getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
                                           ELF::STT_AMDGPU_HSA_KERNEL);
  Lex();
  return false;
}

bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaModuleGlobal() {
  if (getLexer().isNot(AsmToken::Identifier))
    return TokError("expected symbol name");

  StringRef GlobalName = Parser.getTok().getIdentifier();

  getTargetStreamer().EmitAMDGPUHsaModuleScopeGlobal(GlobalName);
  Lex();
  return false;
}

bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaProgramGlobal() {
  if (getLexer().isNot(AsmToken::Identifier))
    return TokError("expected symbol name");

  StringRef GlobalName = Parser.getTok().getIdentifier();

  getTargetStreamer().EmitAMDGPUHsaProgramScopeGlobal(GlobalName);
  Lex();
  return false;
}

bool AMDGPUAsmParser::ParseSectionDirectiveHSADataGlobalAgent() {
  getParser().getStreamer().SwitchSection(
      AMDGPU::getHSADataGlobalAgentSection(getContext()));
  return false;
}

bool AMDGPUAsmParser::ParseSectionDirectiveHSADataGlobalProgram() {
  getParser().getStreamer().SwitchSection(
      AMDGPU::getHSADataGlobalProgramSection(getContext()));
  return false;
}

bool AMDGPUAsmParser::ParseSectionDirectiveHSARodataReadonlyAgent() {
  getParser().getStreamer().SwitchSection(
      AMDGPU::getHSARodataReadonlyAgentSection(getContext()));
  return false;
}

bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
  StringRef IDVal = DirectiveID.getString();

  if (IDVal == ".hsa_code_object_version")
    return ParseDirectiveHSACodeObjectVersion();

  if (IDVal == ".hsa_code_object_isa")
    return ParseDirectiveHSACodeObjectISA();

  if (IDVal == ".amd_kernel_code_t")
    return ParseDirectiveAMDKernelCodeT();

  if (IDVal == ".hsatext" || IDVal == ".text")
    return ParseSectionDirectiveHSAText();

  if (IDVal == ".amdgpu_hsa_kernel")
    return ParseDirectiveAMDGPUHsaKernel();

  if (IDVal == ".amdgpu_hsa_module_global")
    return ParseDirectiveAMDGPUHsaModuleGlobal();

  if (IDVal == ".amdgpu_hsa_program_global")
    return ParseDirectiveAMDGPUHsaProgramGlobal();

  if (IDVal == ".hsadata_global_agent")
    return ParseSectionDirectiveHSADataGlobalAgent();

  if (IDVal == ".hsadata_global_program")
    return ParseSectionDirectiveHSADataGlobalProgram();

  if (IDVal == ".hsarodata_readonly_agent")
    return ParseSectionDirectiveHSARodataReadonlyAgent();

  return true;
}

bool AMDGPUAsmParser::subtargetHasRegister(const MCRegisterInfo &MRI,
                                           unsigned RegNo) const {
  if (isCI())
    return true;

  if (isSI()) {
    // No flat_scr
    switch (RegNo) {
    case AMDGPU::FLAT_SCR:
    case AMDGPU::FLAT_SCR_LO:
    case AMDGPU::FLAT_SCR_HI:
      return false;
    default:
      return true;
    }
  }

  // VI only has 102 SGPRs, so make sure we aren't trying to use the 2 more that
  // SI/CI have.
  for (MCRegAliasIterator R(AMDGPU::SGPR102_SGPR103, &MRI, true);
       R.isValid(); ++R) {
    if (*R == RegNo)
      return false;
  }

  return true;
}

static bool operandsHaveModifiers(const OperandVector &Operands) {

  for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
    const AMDGPUOperand &Op = ((AMDGPUOperand&)*Operands[i]);
    if (Op.isRegKind() && Op.hasModifiers())
      return true;
    if (Op.isImm() && (Op.getImmTy() == AMDGPUOperand::ImmTyOMod ||
                       Op.getImmTy() == AMDGPUOperand::ImmTyClamp))
      return true;
  }
  return false;
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {

  // Try to parse with a custom parser
  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);

  // If we successfully parsed the operand or if there as an error parsing,
  // we are done.
  //
  // If we are parsing after we reach EndOfStatement then this means we
  // are appending default values to the Operands list.  This is only done
  // by custom parser, so we shouldn't continue on to the generic parsing.
  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail ||
      getLexer().is(AsmToken::EndOfStatement))
    return ResTy;

  bool Negate = false, Abs = false;
  if (getLexer().getKind()== AsmToken::Minus) {
    Parser.Lex();
    Negate = true;
  }

  if (getLexer().getKind() == AsmToken::Pipe) {
    Parser.Lex();
    Abs = true;
  }

  switch(getLexer().getKind()) {
    case AsmToken::Integer: {
      SMLoc S = Parser.getTok().getLoc();
      int64_t IntVal;
      if (getParser().parseAbsoluteExpression(IntVal))
        return MatchOperand_ParseFail;
      if (!isInt<32>(IntVal) && !isUInt<32>(IntVal)) {
        Error(S, "invalid immediate: only 32-bit values are legal");
        return MatchOperand_ParseFail;
      }

      if (Negate)
        IntVal *= -1;
      Operands.push_back(AMDGPUOperand::CreateImm(IntVal, S));
      return MatchOperand_Success;
    }
    case AsmToken::Real: {
      // FIXME: We should emit an error if a double precisions floating-point
      // value is used.  I'm not sure the best way to detect this.
      SMLoc S = Parser.getTok().getLoc();
      int64_t IntVal;
      if (getParser().parseAbsoluteExpression(IntVal))
        return MatchOperand_ParseFail;

      APFloat F((float)BitsToDouble(IntVal));
      if (Negate)
        F.changeSign();
      Operands.push_back(
          AMDGPUOperand::CreateImm(F.bitcastToAPInt().getZExtValue(), S));
      return MatchOperand_Success;
    }
    case AsmToken::Identifier: {
      SMLoc S, E;
      unsigned RegNo;
      if (!ParseRegister(RegNo, S, E)) {

        bool HasModifiers = operandsHaveModifiers(Operands);
        unsigned Modifiers = 0;

        if (Negate)
          Modifiers |= 0x1;

        if (Abs) {
          if (getLexer().getKind() != AsmToken::Pipe)
            return MatchOperand_ParseFail;
          Parser.Lex();
          Modifiers |= 0x2;
        }

        if (Modifiers && !HasModifiers) {
          // We are adding a modifier to src1 or src2 and previous sources
          // don't have modifiers, so we need to go back and empty modifers
          // for each previous source.
          for (unsigned PrevRegIdx = Operands.size() - 1; PrevRegIdx > 1;
               --PrevRegIdx) {

            AMDGPUOperand &RegOp = ((AMDGPUOperand&)*Operands[PrevRegIdx]);
            RegOp.setModifiers(0);
          }
        }


        Operands.push_back(AMDGPUOperand::CreateReg(
            RegNo, S, E, getContext().getRegisterInfo(), &getSTI(),
            isForcedVOP3()));

        if (HasModifiers || Modifiers) {
          AMDGPUOperand &RegOp = ((AMDGPUOperand&)*Operands[Operands.size() - 1]);
          RegOp.setModifiers(Modifiers);

        }
     }  else {
      Operands.push_back(AMDGPUOperand::CreateToken(Parser.getTok().getString(),
                                                    S));
      Parser.Lex();
     }
     return MatchOperand_Success;
    }
    default:
      return MatchOperand_NoMatch;
  }
}

bool AMDGPUAsmParser::ParseInstruction(ParseInstructionInfo &Info,
                                       StringRef Name,
                                       SMLoc NameLoc, OperandVector &Operands) {

  // Clear any forced encodings from the previous instruction.
  setForcedEncodingSize(0);

  if (Name.endswith("_e64"))
    setForcedEncodingSize(64);
  else if (Name.endswith("_e32"))
    setForcedEncodingSize(32);

  // Add the instruction mnemonic
  Operands.push_back(AMDGPUOperand::CreateToken(Name, NameLoc));

  while (!getLexer().is(AsmToken::EndOfStatement)) {
    AMDGPUAsmParser::OperandMatchResultTy Res = parseOperand(Operands, Name);

    // Eat the comma or space if there is one.
    if (getLexer().is(AsmToken::Comma))
      Parser.Lex();

    switch (Res) {
      case MatchOperand_Success: break;
      case MatchOperand_ParseFail: return Error(getLexer().getLoc(),
                                                "failed parsing operand.");
      case MatchOperand_NoMatch: return Error(getLexer().getLoc(),
                                              "not a valid operand.");
    }
  }

  // Once we reach end of statement, continue parsing so we can add default
  // values for optional arguments.
  AMDGPUAsmParser::OperandMatchResultTy Res;
  while ((Res = parseOperand(Operands, Name)) != MatchOperand_NoMatch) {
    if (Res != MatchOperand_Success)
      return Error(getLexer().getLoc(), "failed parsing operand.");
  }
  return false;
}

//===----------------------------------------------------------------------===//
// Utility functions
//===----------------------------------------------------------------------===//

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix, int64_t &Int,
                                    int64_t Default) {

  // We are at the end of the statement, and this is a default argument, so
  // use a default value.
  if (getLexer().is(AsmToken::EndOfStatement)) {
    Int = Default;
    return MatchOperand_Success;
  }

  switch(getLexer().getKind()) {
    default: return MatchOperand_NoMatch;
    case AsmToken::Identifier: {
      StringRef OffsetName = Parser.getTok().getString();
      if (!OffsetName.equals(Prefix))
        return MatchOperand_NoMatch;

      Parser.Lex();
      if (getLexer().isNot(AsmToken::Colon))
        return MatchOperand_ParseFail;

      Parser.Lex();
      if (getLexer().isNot(AsmToken::Integer))
        return MatchOperand_ParseFail;

      if (getParser().parseAbsoluteExpression(Int))
        return MatchOperand_ParseFail;
      break;
    }
  }
  return MatchOperand_Success;
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix, OperandVector &Operands,
                                    enum AMDGPUOperand::ImmTy ImmTy) {

  SMLoc S = Parser.getTok().getLoc();
  int64_t Offset = 0;

  AMDGPUAsmParser::OperandMatchResultTy Res = parseIntWithPrefix(Prefix, Offset);
  if (Res != MatchOperand_Success)
    return Res;

  Operands.push_back(AMDGPUOperand::CreateImm(Offset, S, ImmTy));
  return MatchOperand_Success;
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseNamedBit(const char *Name, OperandVector &Operands,
                               enum AMDGPUOperand::ImmTy ImmTy) {
  int64_t Bit = 0;
  SMLoc S = Parser.getTok().getLoc();

  // We are at the end of the statement, and this is a default argument, so
  // use a default value.
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
    switch(getLexer().getKind()) {
      case AsmToken::Identifier: {
        StringRef Tok = Parser.getTok().getString();
        if (Tok == Name) {
          Bit = 1;
          Parser.Lex();
        } else if (Tok.startswith("no") && Tok.endswith(Name)) {
          Bit = 0;
          Parser.Lex();
        } else {
          return MatchOperand_NoMatch;
        }
        break;
      }
      default:
        return MatchOperand_NoMatch;
    }
  }

  Operands.push_back(AMDGPUOperand::CreateImm(Bit, S, ImmTy));
  return MatchOperand_Success;
}

static bool operandsHasOptionalOp(const OperandVector &Operands,
                                  const OptionalOperand &OOp) {
  for (unsigned i = 0; i < Operands.size(); i++) {
    const AMDGPUOperand &ParsedOp = ((const AMDGPUOperand &)*Operands[i]);
    if ((ParsedOp.isImm() && ParsedOp.getImmTy() == OOp.Type) ||
        (ParsedOp.isToken() && ParsedOp.getToken() == OOp.Name))
      return true;

  }
  return false;
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseOptionalOps(const ArrayRef<OptionalOperand> &OptionalOps,
                                   OperandVector &Operands) {
  SMLoc S = Parser.getTok().getLoc();
  for (const OptionalOperand &Op : OptionalOps) {
    if (operandsHasOptionalOp(Operands, Op))
      continue;
    AMDGPUAsmParser::OperandMatchResultTy Res;
    int64_t Value;
    if (Op.IsBit) {
      Res = parseNamedBit(Op.Name, Operands, Op.Type);
      if (Res == MatchOperand_NoMatch)
        continue;
      return Res;
    }

    Res = parseIntWithPrefix(Op.Name, Value, Op.Default);

    if (Res == MatchOperand_NoMatch)
      continue;

    if (Res != MatchOperand_Success)
      return Res;

    if (Op.ConvertResult && !Op.ConvertResult(Value)) {
      return MatchOperand_ParseFail;
    }

    Operands.push_back(AMDGPUOperand::CreateImm(Value, S, Op.Type));
    return MatchOperand_Success;
  }
  return MatchOperand_NoMatch;
}

//===----------------------------------------------------------------------===//
// ds
//===----------------------------------------------------------------------===//

static const OptionalOperand DSOptionalOps [] = {
  {"offset",  AMDGPUOperand::ImmTyOffset, false, 0, nullptr},
  {"gds",     AMDGPUOperand::ImmTyGDS, true, 0, nullptr}
};

static const OptionalOperand DSOptionalOpsOff01 [] = {
  {"offset0", AMDGPUOperand::ImmTyDSOffset0, false, 0, nullptr},
  {"offset1", AMDGPUOperand::ImmTyDSOffset1, false, 0, nullptr},
  {"gds",     AMDGPUOperand::ImmTyGDS, true, 0, nullptr}
};

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseDSOptionalOps(OperandVector &Operands) {
  return parseOptionalOps(DSOptionalOps, Operands);
}
AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseDSOff01OptionalOps(OperandVector &Operands) {
  return parseOptionalOps(DSOptionalOpsOff01, Operands);
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseDSOffsetOptional(OperandVector &Operands) {
  SMLoc S = Parser.getTok().getLoc();
  AMDGPUAsmParser::OperandMatchResultTy Res =
    parseIntWithPrefix("offset", Operands, AMDGPUOperand::ImmTyOffset);
  if (Res == MatchOperand_NoMatch) {
    Operands.push_back(AMDGPUOperand::CreateImm(0, S,
                       AMDGPUOperand::ImmTyOffset));
    Res = MatchOperand_Success;
  }
  return Res;
}

bool AMDGPUOperand::isDSOffset() const {
  return isImm() && isUInt<16>(getImm());
}

bool AMDGPUOperand::isDSOffset01() const {
  return isImm() && isUInt<8>(getImm());
}

void AMDGPUAsmParser::cvtDSOffset01(MCInst &Inst,
                                    const OperandVector &Operands) {

  std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;

  for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
    AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);

    // Add the register arguments
    if (Op.isReg()) {
      Op.addRegOperands(Inst, 1);
      continue;
    }

    // Handle optional arguments
    OptionalIdx[Op.getImmTy()] = i;
  }

  unsigned Offset0Idx = OptionalIdx[AMDGPUOperand::ImmTyDSOffset0];
  unsigned Offset1Idx = OptionalIdx[AMDGPUOperand::ImmTyDSOffset1];
  unsigned GDSIdx = OptionalIdx[AMDGPUOperand::ImmTyGDS];

  ((AMDGPUOperand &)*Operands[Offset0Idx]).addImmOperands(Inst, 1); // offset0
  ((AMDGPUOperand &)*Operands[Offset1Idx]).addImmOperands(Inst, 1); // offset1
  ((AMDGPUOperand &)*Operands[GDSIdx]).addImmOperands(Inst, 1); // gds
  Inst.addOperand(MCOperand::createReg(AMDGPU::M0)); // m0
}

void AMDGPUAsmParser::cvtDS(MCInst &Inst, const OperandVector &Operands) {

  std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
  bool GDSOnly = false;

  for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
    AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);

    // Add the register arguments
    if (Op.isReg()) {
      Op.addRegOperands(Inst, 1);
      continue;
    }

    if (Op.isToken() && Op.getToken() == "gds") {
      GDSOnly = true;
      continue;
    }

    // Handle optional arguments
    OptionalIdx[Op.getImmTy()] = i;
  }

  unsigned OffsetIdx = OptionalIdx[AMDGPUOperand::ImmTyOffset];
  ((AMDGPUOperand &)*Operands[OffsetIdx]).addImmOperands(Inst, 1); // offset

  if (!GDSOnly) {
    unsigned GDSIdx = OptionalIdx[AMDGPUOperand::ImmTyGDS];
    ((AMDGPUOperand &)*Operands[GDSIdx]).addImmOperands(Inst, 1); // gds
  }
  Inst.addOperand(MCOperand::createReg(AMDGPU::M0)); // m0
}


//===----------------------------------------------------------------------===//
// s_waitcnt
//===----------------------------------------------------------------------===//

bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
  StringRef CntName = Parser.getTok().getString();
  int64_t CntVal;

  Parser.Lex();
  if (getLexer().isNot(AsmToken::LParen))
    return true;

  Parser.Lex();
  if (getLexer().isNot(AsmToken::Integer))
    return true;

  if (getParser().parseAbsoluteExpression(CntVal))
    return true;

  if (getLexer().isNot(AsmToken::RParen))
    return true;

  Parser.Lex();
  if (getLexer().is(AsmToken::Amp) || getLexer().is(AsmToken::Comma))
    Parser.Lex();

  int CntShift;
  int CntMask;

  if (CntName == "vmcnt") {
    CntMask = 0xf;
    CntShift = 0;
  } else if (CntName == "expcnt") {
    CntMask = 0x7;
    CntShift = 4;
  } else if (CntName == "lgkmcnt") {
    CntMask = 0xf;
    CntShift = 8;
  } else {
    return true;
  }

  IntVal &= ~(CntMask << CntShift);
  IntVal |= (CntVal << CntShift);
  return false;
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseSWaitCntOps(OperandVector &Operands) {
  // Disable all counters by default.
  // vmcnt   [3:0]
  // expcnt  [6:4]
  // lgkmcnt [11:8]
  int64_t CntVal = 0xf7f;
  SMLoc S = Parser.getTok().getLoc();

  switch(getLexer().getKind()) {
    default: return MatchOperand_ParseFail;
    case AsmToken::Integer:
      // The operand can be an integer value.
      if (getParser().parseAbsoluteExpression(CntVal))
        return MatchOperand_ParseFail;
      break;

    case AsmToken::Identifier:
      do {
        if (parseCnt(CntVal))
          return MatchOperand_ParseFail;
      } while(getLexer().isNot(AsmToken::EndOfStatement));
      break;
  }
  Operands.push_back(AMDGPUOperand::CreateImm(CntVal, S));
  return MatchOperand_Success;
}

bool AMDGPUOperand::isSWaitCnt() const {
  return isImm();
}

//===----------------------------------------------------------------------===//
// sopp branch targets
//===----------------------------------------------------------------------===//

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseSOppBrTarget(OperandVector &Operands) {
  SMLoc S = Parser.getTok().getLoc();

  switch (getLexer().getKind()) {
    default: return MatchOperand_ParseFail;
    case AsmToken::Integer: {
      int64_t Imm;
      if (getParser().parseAbsoluteExpression(Imm))
        return MatchOperand_ParseFail;
      Operands.push_back(AMDGPUOperand::CreateImm(Imm, S));
      return MatchOperand_Success;
    }

    case AsmToken::Identifier:
      Operands.push_back(AMDGPUOperand::CreateExpr(
          MCSymbolRefExpr::create(getContext().getOrCreateSymbol(
                                  Parser.getTok().getString()), getContext()), S));
      Parser.Lex();
      return MatchOperand_Success;
  }
}

//===----------------------------------------------------------------------===//
// flat
//===----------------------------------------------------------------------===//

static const OptionalOperand FlatOptionalOps [] = {
  {"glc",    AMDGPUOperand::ImmTyGLC, true, 0, nullptr},
  {"slc",    AMDGPUOperand::ImmTySLC, true, 0, nullptr},
  {"tfe",    AMDGPUOperand::ImmTyTFE, true, 0, nullptr}
};

static const OptionalOperand FlatAtomicOptionalOps [] = {
  {"slc",    AMDGPUOperand::ImmTySLC, true, 0, nullptr},
  {"tfe",    AMDGPUOperand::ImmTyTFE, true, 0, nullptr}
};

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseFlatOptionalOps(OperandVector &Operands) {
  return parseOptionalOps(FlatOptionalOps, Operands);
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseFlatAtomicOptionalOps(OperandVector &Operands) {
  return parseOptionalOps(FlatAtomicOptionalOps, Operands);
}

void AMDGPUAsmParser::cvtFlat(MCInst &Inst,
                               const OperandVector &Operands) {
  std::map<AMDGPUOperand::ImmTy, unsigned> OptionalIdx;

  for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
    AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);

    // Add the register arguments
    if (Op.isReg()) {
      Op.addRegOperands(Inst, 1);
      continue;
    }

    // Handle 'glc' token which is sometimes hard-coded into the
    // asm string.  There are no MCInst operands for these.
    if (Op.isToken())
      continue;

    // Handle optional arguments
    OptionalIdx[Op.getImmTy()] = i;

  }

  // flat atomic instructions don't have a glc argument.
  if (OptionalIdx.count(AMDGPUOperand::ImmTyGLC)) {
    unsigned GLCIdx = OptionalIdx[AMDGPUOperand::ImmTyGLC];
    ((AMDGPUOperand &)*Operands[GLCIdx]).addImmOperands(Inst, 1);
  }

  unsigned SLCIdx = OptionalIdx[AMDGPUOperand::ImmTySLC];
  unsigned TFEIdx = OptionalIdx[AMDGPUOperand::ImmTyTFE];

  ((AMDGPUOperand &)*Operands[SLCIdx]).addImmOperands(Inst, 1);
  ((AMDGPUOperand &)*Operands[TFEIdx]).addImmOperands(Inst, 1);
}

//===----------------------------------------------------------------------===//
// mubuf
//===----------------------------------------------------------------------===//

static const OptionalOperand MubufOptionalOps [] = {
  {"offset", AMDGPUOperand::ImmTyOffset, false, 0, nullptr},
  {"glc",    AMDGPUOperand::ImmTyGLC, true, 0, nullptr},
  {"slc",    AMDGPUOperand::ImmTySLC, true, 0, nullptr},
  {"tfe",    AMDGPUOperand::ImmTyTFE, true, 0, nullptr}
};

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseMubufOptionalOps(OperandVector &Operands) {
  return parseOptionalOps(MubufOptionalOps, Operands);
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseOffset(OperandVector &Operands) {
  return parseIntWithPrefix("offset", Operands);
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseGLC(OperandVector &Operands) {
  return parseNamedBit("glc", Operands);
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseSLC(OperandVector &Operands) {
  return parseNamedBit("slc", Operands);
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseTFE(OperandVector &Operands) {
  return parseNamedBit("tfe", Operands);
}

bool AMDGPUOperand::isMubufOffset() const {
  return isImm() && isUInt<12>(getImm());
}

void AMDGPUAsmParser::cvtMubuf(MCInst &Inst,
                               const OperandVector &Operands) {
  std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;

  for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
    AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);

    // Add the register arguments
    if (Op.isReg()) {
      Op.addRegOperands(Inst, 1);
      continue;
    }

    // Handle the case where soffset is an immediate
    if (Op.isImm() && Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
      Op.addImmOperands(Inst, 1);
      continue;
    }

    // Handle tokens like 'offen' which are sometimes hard-coded into the
    // asm string.  There are no MCInst operands for these.
    if (Op.isToken()) {
      continue;
    }
    assert(Op.isImm());

    // Handle optional arguments
    OptionalIdx[Op.getImmTy()] = i;
  }

  assert(OptionalIdx.size() == 4);

  unsigned OffsetIdx = OptionalIdx[AMDGPUOperand::ImmTyOffset];
  unsigned GLCIdx = OptionalIdx[AMDGPUOperand::ImmTyGLC];
  unsigned SLCIdx = OptionalIdx[AMDGPUOperand::ImmTySLC];
  unsigned TFEIdx = OptionalIdx[AMDGPUOperand::ImmTyTFE];

  ((AMDGPUOperand &)*Operands[OffsetIdx]).addImmOperands(Inst, 1);
  ((AMDGPUOperand &)*Operands[GLCIdx]).addImmOperands(Inst, 1);
  ((AMDGPUOperand &)*Operands[SLCIdx]).addImmOperands(Inst, 1);
  ((AMDGPUOperand &)*Operands[TFEIdx]).addImmOperands(Inst, 1);
}

//===----------------------------------------------------------------------===//
// mimg
//===----------------------------------------------------------------------===//

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseDMask(OperandVector &Operands) {
  return parseIntWithPrefix("dmask", Operands);
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseUNorm(OperandVector &Operands) {
  return parseNamedBit("unorm", Operands);
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseR128(OperandVector &Operands) {
  return parseNamedBit("r128", Operands);
}

//===----------------------------------------------------------------------===//
// smrd
//===----------------------------------------------------------------------===//

bool AMDGPUOperand::isSMRDOffset() const {

  // FIXME: Support 20-bit offsets on VI.  We need to to pass subtarget
  // information here.
  return isImm() && isUInt<8>(getImm());
}

bool AMDGPUOperand::isSMRDLiteralOffset() const {
  // 32-bit literals are only supported on CI and we only want to use them
  // when the offset is > 8-bits.
  return isImm() && !isUInt<8>(getImm()) && isUInt<32>(getImm());
}

//===----------------------------------------------------------------------===//
// vop3
//===----------------------------------------------------------------------===//

static bool ConvertOmodMul(int64_t &Mul) {
  if (Mul != 1 && Mul != 2 && Mul != 4)
    return false;

  Mul >>= 1;
  return true;
}

static bool ConvertOmodDiv(int64_t &Div) {
  if (Div == 1) {
    Div = 0;
    return true;
  }

  if (Div == 2) {
    Div = 3;
    return true;
  }

  return false;
}

static const OptionalOperand VOP3OptionalOps [] = {
  {"clamp", AMDGPUOperand::ImmTyClamp, true, 0, nullptr},
  {"mul",   AMDGPUOperand::ImmTyOMod, false, 1, ConvertOmodMul},
  {"div",   AMDGPUOperand::ImmTyOMod, false, 1, ConvertOmodDiv},
};

static bool isVOP3(OperandVector &Operands) {
  if (operandsHaveModifiers(Operands))
    return true;

  AMDGPUOperand &DstOp = ((AMDGPUOperand&)*Operands[1]);

  if (DstOp.isReg() && DstOp.isRegClass(AMDGPU::SGPR_64RegClassID))
    return true;

  if (Operands.size() >= 5)
    return true;

  if (Operands.size() > 3) {
    AMDGPUOperand &Src1Op = ((AMDGPUOperand&)*Operands[3]);
    if (Src1Op.getReg() && (Src1Op.isRegClass(AMDGPU::SReg_32RegClassID) ||
                            Src1Op.isRegClass(AMDGPU::SReg_64RegClassID)))
      return true;
  }
  return false;
}

AMDGPUAsmParser::OperandMatchResultTy
AMDGPUAsmParser::parseVOP3OptionalOps(OperandVector &Operands) {

  // The value returned by this function may change after parsing
  // an operand so store the original value here.
  bool HasModifiers = operandsHaveModifiers(Operands);

  bool IsVOP3 = isVOP3(Operands);
  if (HasModifiers || IsVOP3 ||
      getLexer().isNot(AsmToken::EndOfStatement) ||
      getForcedEncodingSize() == 64) {

    AMDGPUAsmParser::OperandMatchResultTy Res =
        parseOptionalOps(VOP3OptionalOps, Operands);

    if (!HasModifiers && Res == MatchOperand_Success) {
      // We have added a modifier operation, so we need to make sure all
      // previous register operands have modifiers
      for (unsigned i = 2, e = Operands.size(); i != e; ++i) {
        AMDGPUOperand &Op = ((AMDGPUOperand&)*Operands[i]);
        if (Op.isReg())
          Op.setModifiers(0);
      }
    }
    return Res;
  }
  return MatchOperand_NoMatch;
}

void AMDGPUAsmParser::cvtVOP3(MCInst &Inst, const OperandVector &Operands) {

  unsigned i = 1;
  const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
  if (Desc.getNumDefs() > 0) {
    ((AMDGPUOperand &)*Operands[i++]).addRegOperands(Inst, 1);
  }

  std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;

  if (operandsHaveModifiers(Operands)) {
    for (unsigned e = Operands.size(); i != e; ++i) {
      AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);

      if (Op.isRegWithInputMods()) {
        ((AMDGPUOperand &)*Operands[i]).addRegWithInputModsOperands(Inst, 2);
        continue;
      }
      OptionalIdx[Op.getImmTy()] = i;
    }

    unsigned ClampIdx = OptionalIdx[AMDGPUOperand::ImmTyClamp];
    unsigned OModIdx = OptionalIdx[AMDGPUOperand::ImmTyOMod];

    ((AMDGPUOperand &)*Operands[ClampIdx]).addImmOperands(Inst, 1);
    ((AMDGPUOperand &)*Operands[OModIdx]).addImmOperands(Inst, 1);
  } else {
    for (unsigned e = Operands.size(); i != e; ++i)
      ((AMDGPUOperand &)*Operands[i]).addRegOrImmOperands(Inst, 1);
  }
}

/// Force static initialization.
extern "C" void LLVMInitializeAMDGPUAsmParser() {
  RegisterMCAsmParser<AMDGPUAsmParser> A(TheAMDGPUTarget);
  RegisterMCAsmParser<AMDGPUAsmParser> B(TheGCNTarget);
}

#define GET_REGISTER_MATCHER
#define GET_MATCHER_IMPLEMENTATION
#include "AMDGPUGenAsmMatcher.inc"

