//===-- LanaiAsmParser.cpp - Parse Lanai assembly to MCInst instructions --===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "LanaiAluCode.h"
#include "LanaiCondCode.h"
#include "LanaiInstrInfo.h"
#include "MCTargetDesc/LanaiMCExpr.h"
#include "TargetInfo/LanaiTargetInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <memory>

using namespace llvm;

// Auto-generated by TableGen
static unsigned MatchRegisterName(StringRef Name);

namespace {

struct LanaiOperand;

class LanaiAsmParser : public MCTargetAsmParser {
  // Parse operands
  std::unique_ptr<LanaiOperand> parseRegister(bool RestoreOnFailure = false);

  std::unique_ptr<LanaiOperand> parseImmediate();

  std::unique_ptr<LanaiOperand> parseIdentifier();

  unsigned parseAluOperator(bool PreOp, bool PostOp);

  // Split the mnemonic stripping conditional code and quantifiers
  StringRef splitMnemonic(StringRef Name, SMLoc NameLoc,
                          OperandVector *Operands);

  bool parsePrePost(StringRef Type, int *OffsetValue);

  bool ParseDirective(AsmToken DirectiveID) override;

  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                        SMLoc NameLoc, OperandVector &Operands) override;

  bool ParseRegister(unsigned &RegNum, SMLoc &StartLoc, SMLoc &EndLoc) override;
  OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
                                        SMLoc &EndLoc) override;

  bool MatchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
                               OperandVector &Operands, MCStreamer &Out,
                               uint64_t &ErrorInfo,
                               bool MatchingInlineAsm) override;

// Auto-generated instruction matching functions
#define GET_ASSEMBLER_HEADER
#include "LanaiGenAsmMatcher.inc"

  OperandMatchResultTy parseOperand(OperandVector *Operands,
                                    StringRef Mnemonic);

  OperandMatchResultTy parseMemoryOperand(OperandVector &Operands);

public:
  LanaiAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
                 const MCInstrInfo &MII, const MCTargetOptions &Options)
      : MCTargetAsmParser(Options, STI, MII), Parser(Parser),
        Lexer(Parser.getLexer()), SubtargetInfo(STI) {
    setAvailableFeatures(
        ComputeAvailableFeatures(SubtargetInfo.getFeatureBits()));
  }

private:
  MCAsmParser &Parser;
  MCAsmLexer &Lexer;

  const MCSubtargetInfo &SubtargetInfo;
};

// LanaiOperand - Instances of this class represented a parsed machine
// instruction
struct LanaiOperand : public MCParsedAsmOperand {
  enum KindTy {
    TOKEN,
    REGISTER,
    IMMEDIATE,
    MEMORY_IMM,
    MEMORY_REG_IMM,
    MEMORY_REG_REG,
  } Kind;

  SMLoc StartLoc, EndLoc;

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

  struct RegOp {
    unsigned RegNum;
  };

  struct ImmOp {
    const MCExpr *Value;
  };

  struct MemOp {
    unsigned BaseReg;
    unsigned OffsetReg;
    unsigned AluOp;
    const MCExpr *Offset;
  };

  union {
    struct Token Tok;
    struct RegOp Reg;
    struct ImmOp Imm;
    struct MemOp Mem;
  };

  explicit LanaiOperand(KindTy Kind) : MCParsedAsmOperand(), Kind(Kind) {}

public:
  // The functions below are used by the autogenerated ASM matcher and hence to
  // be of the form expected.

  // getStartLoc - Gets location of the first token of this operand
  SMLoc getStartLoc() const override { return StartLoc; }

  // getEndLoc - Gets location of the last token of this operand
  SMLoc getEndLoc() const override { return EndLoc; }

  unsigned getReg() const override {
    assert(isReg() && "Invalid type access!");
    return Reg.RegNum;
  }

  const MCExpr *getImm() const {
    assert(isImm() && "Invalid type access!");
    return Imm.Value;
  }

  StringRef getToken() const {
    assert(isToken() && "Invalid type access!");
    return StringRef(Tok.Data, Tok.Length);
  }

  unsigned getMemBaseReg() const {
    assert(isMem() && "Invalid type access!");
    return Mem.BaseReg;
  }

  unsigned getMemOffsetReg() const {
    assert(isMem() && "Invalid type access!");
    return Mem.OffsetReg;
  }

  const MCExpr *getMemOffset() const {
    assert(isMem() && "Invalid type access!");
    return Mem.Offset;
  }

  unsigned getMemOp() const {
    assert(isMem() && "Invalid type access!");
    return Mem.AluOp;
  }

  // Functions for testing operand type
  bool isReg() const override { return Kind == REGISTER; }

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

  bool isMem() const override {
    return isMemImm() || isMemRegImm() || isMemRegReg();
  }

  bool isMemImm() const { return Kind == MEMORY_IMM; }

  bool isMemRegImm() const { return Kind == MEMORY_REG_IMM; }

  bool isMemRegReg() const { return Kind == MEMORY_REG_REG; }

  bool isMemSpls() const { return isMemRegImm() || isMemRegReg(); }

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

  bool isBrImm() {
    if (!isImm())
      return false;

    // Constant case
    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm.Value);
    if (!MCE)
      return true;
    int64_t Value = MCE->getValue();
    // Check if value fits in 25 bits with 2 least significant bits 0.
    return isShiftedUInt<23, 2>(static_cast<int32_t>(Value));
  }

  bool isBrTarget() { return isBrImm() || isToken(); }

  bool isCallTarget() { return isImm() || isToken(); }

  bool isHiImm16() {
    if (!isImm())
      return false;

    // Constant case
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
      int64_t Value = ConstExpr->getValue();
      return Value != 0 && isShiftedUInt<16, 16>(Value);
    }

    // Symbolic reference expression
    if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
      return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI;

    // Binary expression
    if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
      if (const LanaiMCExpr *SymbolRefExpr =
              dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
        return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI;

    return false;
  }

  bool isHiImm16And() {
    if (!isImm())
      return false;

    const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
    if (ConstExpr) {
      int64_t Value = ConstExpr->getValue();
      // Check if in the form 0xXYZWffff
      return (Value != 0) && ((Value & ~0xffff0000) == 0xffff);
    }
    return false;
  }

  bool isLoImm16() {
    if (!isImm())
      return false;

    // Constant case
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
      int64_t Value = ConstExpr->getValue();
      // Check if value fits in 16 bits
      return isUInt<16>(static_cast<int32_t>(Value));
    }

    // Symbolic reference expression
    if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
      return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;

    // Binary expression
    if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
      if (const LanaiMCExpr *SymbolRefExpr =
              dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
        return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;

    return false;
  }

  bool isLoImm16Signed() {
    if (!isImm())
      return false;

    // Constant case
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
      int64_t Value = ConstExpr->getValue();
      // Check if value fits in 16 bits or value of the form 0xffffxyzw
      return isInt<16>(static_cast<int32_t>(Value));
    }

    // Symbolic reference expression
    if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
      return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;

    // Binary expression
    if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
      if (const LanaiMCExpr *SymbolRefExpr =
              dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
        return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;

    return false;
  }

  bool isLoImm16And() {
    if (!isImm())
      return false;

    const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
    if (ConstExpr) {
      int64_t Value = ConstExpr->getValue();
      // Check if in the form 0xffffXYZW
      return ((Value & ~0xffff) == 0xffff0000);
    }
    return false;
  }

  bool isImmShift() {
    if (!isImm())
      return false;

    const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
    if (!ConstExpr)
      return false;
    int64_t Value = ConstExpr->getValue();
    return (Value >= -31) && (Value <= 31);
  }

  bool isLoImm21() {
    if (!isImm())
      return false;

    // Constant case
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
      int64_t Value = ConstExpr->getValue();
      return isUInt<21>(Value);
    }

    // Symbolic reference expression
    if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
      return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
    if (const MCSymbolRefExpr *SymbolRefExpr =
            dyn_cast<MCSymbolRefExpr>(Imm.Value)) {
      return SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None;
    }

    // Binary expression
    if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value)) {
      if (const LanaiMCExpr *SymbolRefExpr =
              dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
        return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
      if (const MCSymbolRefExpr *SymbolRefExpr =
              dyn_cast<MCSymbolRefExpr>(BinaryExpr->getLHS()))
        return SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None;
    }

    return false;
  }

  bool isImm10() {
    if (!isImm())
      return false;

    const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
    if (!ConstExpr)
      return false;
    int64_t Value = ConstExpr->getValue();
    return isInt<10>(Value);
  }

  bool isCondCode() {
    if (!isImm())
      return false;

    const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
    if (!ConstExpr)
      return false;
    uint64_t Value = ConstExpr->getValue();
    // The condition codes are between 0 (ICC_T) and 15 (ICC_LE). If the
    // unsigned value of the immediate is less than LPCC::UNKNOWN (16) then
    // value corresponds to a valid condition code.
    return Value < LPCC::UNKNOWN;
  }

  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
    // Add as immediates where possible. Null MCExpr = 0
    if (Expr == nullptr)
      Inst.addOperand(MCOperand::createImm(0));
    else if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Expr))
      Inst.addOperand(
          MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
    else
      Inst.addOperand(MCOperand::createExpr(Expr));
  }

  void addRegOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    Inst.addOperand(MCOperand::createReg(getReg()));
  }

  void addImmOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    addExpr(Inst, getImm());
  }

  void addBrTargetOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    addExpr(Inst, getImm());
  }

  void addCallTargetOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    addExpr(Inst, getImm());
  }

  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    addExpr(Inst, getImm());
  }

  void addMemImmOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    const MCExpr *Expr = getMemOffset();
    addExpr(Inst, Expr);
  }

  void addMemRegImmOperands(MCInst &Inst, unsigned N) const {
    assert(N == 3 && "Invalid number of operands!");
    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
    const MCExpr *Expr = getMemOffset();
    addExpr(Inst, Expr);
    Inst.addOperand(MCOperand::createImm(getMemOp()));
  }

  void addMemRegRegOperands(MCInst &Inst, unsigned N) const {
    assert(N == 3 && "Invalid number of operands!");
    Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
    assert(getMemOffsetReg() != 0 && "Invalid offset");
    Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
    Inst.addOperand(MCOperand::createImm(getMemOp()));
  }

  void addMemSplsOperands(MCInst &Inst, unsigned N) const {
    if (isMemRegImm())
      addMemRegImmOperands(Inst, N);
    if (isMemRegReg())
      addMemRegRegOperands(Inst, N);
  }

  void addImmShiftOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    addExpr(Inst, getImm());
  }

  void addImm10Operands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    addExpr(Inst, getImm());
  }

  void addLoImm16Operands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
      Inst.addOperand(
          MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
    else if (isa<LanaiMCExpr>(getImm())) {
#ifndef NDEBUG
      const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
      assert(SymbolRefExpr &&
             SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO);
#endif
      Inst.addOperand(MCOperand::createExpr(getImm()));
    } else if (isa<MCBinaryExpr>(getImm())) {
#ifndef NDEBUG
      const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
      assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
             cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
                 LanaiMCExpr::VK_Lanai_ABS_LO);
#endif
      Inst.addOperand(MCOperand::createExpr(getImm()));
    } else
      assert(false && "Operand type not supported.");
  }

  void addLoImm16AndOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
      Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0xffff));
    else
      assert(false && "Operand type not supported.");
  }

  void addHiImm16Operands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
      Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
    else if (isa<LanaiMCExpr>(getImm())) {
#ifndef NDEBUG
      const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
      assert(SymbolRefExpr &&
             SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI);
#endif
      Inst.addOperand(MCOperand::createExpr(getImm()));
    } else if (isa<MCBinaryExpr>(getImm())) {
#ifndef NDEBUG
      const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
      assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
             cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
                 LanaiMCExpr::VK_Lanai_ABS_HI);
#endif
      Inst.addOperand(MCOperand::createExpr(getImm()));
    } else
      assert(false && "Operand type not supported.");
  }

  void addHiImm16AndOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
      Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
    else
      assert(false && "Operand type not supported.");
  }

  void addLoImm21Operands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
      Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0x1fffff));
    else if (isa<LanaiMCExpr>(getImm())) {
#ifndef NDEBUG
      const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
      assert(SymbolRefExpr &&
             SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
#endif
      Inst.addOperand(MCOperand::createExpr(getImm()));
    } else if (isa<MCSymbolRefExpr>(getImm())) {
#ifndef NDEBUG
      const MCSymbolRefExpr *SymbolRefExpr =
          dyn_cast<MCSymbolRefExpr>(getImm());
      assert(SymbolRefExpr &&
             SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None);
#endif
      Inst.addOperand(MCOperand::createExpr(getImm()));
    } else if (isa<MCBinaryExpr>(getImm())) {
#ifndef NDEBUG
      const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
      assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
             cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
                 LanaiMCExpr::VK_Lanai_None);
#endif
      Inst.addOperand(MCOperand::createExpr(getImm()));
    } else
      assert(false && "Operand type not supported.");
  }

  void print(raw_ostream &OS) const override {
    switch (Kind) {
    case IMMEDIATE:
      OS << "Imm: " << getImm() << "\n";
      break;
    case TOKEN:
      OS << "Token: " << getToken() << "\n";
      break;
    case REGISTER:
      OS << "Reg: %r" << getReg() << "\n";
      break;
    case MEMORY_IMM:
      OS << "MemImm: " << *getMemOffset() << "\n";
      break;
    case MEMORY_REG_IMM:
      OS << "MemRegImm: " << getMemBaseReg() << "+" << *getMemOffset() << "\n";
      break;
    case MEMORY_REG_REG:
      assert(getMemOffset() == nullptr);
      OS << "MemRegReg: " << getMemBaseReg() << "+"
         << "%r" << getMemOffsetReg() << "\n";
      break;
    }
  }

  static std::unique_ptr<LanaiOperand> CreateToken(StringRef Str, SMLoc Start) {
    auto Op = std::make_unique<LanaiOperand>(TOKEN);
    Op->Tok.Data = Str.data();
    Op->Tok.Length = Str.size();
    Op->StartLoc = Start;
    Op->EndLoc = Start;
    return Op;
  }

  static std::unique_ptr<LanaiOperand> createReg(unsigned RegNum, SMLoc Start,
                                                 SMLoc End) {
    auto Op = std::make_unique<LanaiOperand>(REGISTER);
    Op->Reg.RegNum = RegNum;
    Op->StartLoc = Start;
    Op->EndLoc = End;
    return Op;
  }

  static std::unique_ptr<LanaiOperand> createImm(const MCExpr *Value,
                                                 SMLoc Start, SMLoc End) {
    auto Op = std::make_unique<LanaiOperand>(IMMEDIATE);
    Op->Imm.Value = Value;
    Op->StartLoc = Start;
    Op->EndLoc = End;
    return Op;
  }

  static std::unique_ptr<LanaiOperand>
  MorphToMemImm(std::unique_ptr<LanaiOperand> Op) {
    const MCExpr *Imm = Op->getImm();
    Op->Kind = MEMORY_IMM;
    Op->Mem.BaseReg = 0;
    Op->Mem.AluOp = LPAC::ADD;
    Op->Mem.OffsetReg = 0;
    Op->Mem.Offset = Imm;
    return Op;
  }

  static std::unique_ptr<LanaiOperand>
  MorphToMemRegReg(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
                   unsigned AluOp) {
    unsigned OffsetReg = Op->getReg();
    Op->Kind = MEMORY_REG_REG;
    Op->Mem.BaseReg = BaseReg;
    Op->Mem.AluOp = AluOp;
    Op->Mem.OffsetReg = OffsetReg;
    Op->Mem.Offset = nullptr;
    return Op;
  }

  static std::unique_ptr<LanaiOperand>
  MorphToMemRegImm(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
                   unsigned AluOp) {
    const MCExpr *Imm = Op->getImm();
    Op->Kind = MEMORY_REG_IMM;
    Op->Mem.BaseReg = BaseReg;
    Op->Mem.AluOp = AluOp;
    Op->Mem.OffsetReg = 0;
    Op->Mem.Offset = Imm;
    return Op;
  }
};

} // end anonymous namespace

bool LanaiAsmParser::ParseDirective(AsmToken /*DirectiveId*/) { return true; }

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

  switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
  case Match_Success:
    Out.emitInstruction(Inst, SubtargetInfo);
    Opcode = Inst.getOpcode();
    return false;
  case Match_MissingFeature:
    return Error(IdLoc, "Instruction use requires option to be enabled");
  case Match_MnemonicFail:
    return Error(IdLoc, "Unrecognized instruction mnemonic");
  case Match_InvalidOperand: {
    ErrorLoc = IdLoc;
    if (ErrorInfo != ~0U) {
      if (ErrorInfo >= Operands.size())
        return Error(IdLoc, "Too few operands for instruction");

      ErrorLoc = ((LanaiOperand &)*Operands[ErrorInfo]).getStartLoc();
      if (ErrorLoc == SMLoc())
        ErrorLoc = IdLoc;
    }
    return Error(ErrorLoc, "Invalid operand for instruction");
  }
  default:
    break;
  }

  llvm_unreachable("Unknown match type detected!");
}

// Both '%rN' and 'rN' are parsed as valid registers. This was done to remain
// backwards compatible with GCC and the different ways inline assembly is
// handled.
// TODO: see if there isn't a better way to do this.
std::unique_ptr<LanaiOperand>
LanaiAsmParser::parseRegister(bool RestoreOnFailure) {
  SMLoc Start = Parser.getTok().getLoc();
  SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
  Optional<AsmToken> PercentTok;

  unsigned RegNum;
  // Eat the '%'.
  if (Lexer.getKind() == AsmToken::Percent) {
    PercentTok = Parser.getTok();
    Parser.Lex();
  }
  if (Lexer.getKind() == AsmToken::Identifier) {
    RegNum = MatchRegisterName(Lexer.getTok().getIdentifier());
    if (RegNum == 0) {
      if (PercentTok.hasValue() && RestoreOnFailure)
        Lexer.UnLex(PercentTok.getValue());
      return nullptr;
    }
    Parser.Lex(); // Eat identifier token
    return LanaiOperand::createReg(RegNum, Start, End);
  }
  if (PercentTok.hasValue() && RestoreOnFailure)
    Lexer.UnLex(PercentTok.getValue());
  return nullptr;
}

bool LanaiAsmParser::ParseRegister(unsigned &RegNum, SMLoc &StartLoc,
                                   SMLoc &EndLoc) {
  const AsmToken &Tok = getParser().getTok();
  StartLoc = Tok.getLoc();
  EndLoc = Tok.getEndLoc();
  std::unique_ptr<LanaiOperand> Op = parseRegister(/*RestoreOnFailure=*/false);
  if (Op != nullptr)
    RegNum = Op->getReg();
  return (Op == nullptr);
}

OperandMatchResultTy LanaiAsmParser::tryParseRegister(unsigned &RegNum,
                                                      SMLoc &StartLoc,
                                                      SMLoc &EndLoc) {
  const AsmToken &Tok = getParser().getTok();
  StartLoc = Tok.getLoc();
  EndLoc = Tok.getEndLoc();
  std::unique_ptr<LanaiOperand> Op = parseRegister(/*RestoreOnFailure=*/true);
  if (Op == nullptr)
    return MatchOperand_NoMatch;
  RegNum = Op->getReg();
  return MatchOperand_Success;
}

std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
  SMLoc Start = Parser.getTok().getLoc();
  SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
  const MCExpr *Res, *RHS = nullptr;
  LanaiMCExpr::VariantKind Kind = LanaiMCExpr::VK_Lanai_None;

  if (Lexer.getKind() != AsmToken::Identifier)
    return nullptr;

  StringRef Identifier;
  if (Parser.parseIdentifier(Identifier))
    return nullptr;

  // Check if identifier has a modifier
  if (Identifier.equals_lower("hi"))
    Kind = LanaiMCExpr::VK_Lanai_ABS_HI;
  else if (Identifier.equals_lower("lo"))
    Kind = LanaiMCExpr::VK_Lanai_ABS_LO;

  // If the identifier corresponds to a variant then extract the real
  // identifier.
  if (Kind != LanaiMCExpr::VK_Lanai_None) {
    if (Lexer.getKind() != AsmToken::LParen) {
      Error(Lexer.getLoc(), "Expected '('");
      return nullptr;
    }
    Lexer.Lex(); // lex '('

    // Parse identifier
    if (Parser.parseIdentifier(Identifier))
      return nullptr;
  }

  // If addition parse the RHS.
  if (Lexer.getKind() == AsmToken::Plus && Parser.parseExpression(RHS))
    return nullptr;

  // For variants parse the final ')'
  if (Kind != LanaiMCExpr::VK_Lanai_None) {
    if (Lexer.getKind() != AsmToken::RParen) {
      Error(Lexer.getLoc(), "Expected ')'");
      return nullptr;
    }
    Lexer.Lex(); // lex ')'
  }

  End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
  MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
  Res = LanaiMCExpr::create(Kind, Expr, getContext());

  // Nest if this was an addition
  if (RHS)
    Res = MCBinaryExpr::createAdd(Res, RHS, getContext());

  return LanaiOperand::createImm(Res, Start, End);
}

std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() {
  SMLoc Start = Parser.getTok().getLoc();
  SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);

  const MCExpr *ExprVal;
  switch (Lexer.getKind()) {
  case AsmToken::Identifier:
    return parseIdentifier();
  case AsmToken::Plus:
  case AsmToken::Minus:
  case AsmToken::Integer:
  case AsmToken::Dot:
    if (!Parser.parseExpression(ExprVal))
      return LanaiOperand::createImm(ExprVal, Start, End);
    LLVM_FALLTHROUGH;
  default:
    return nullptr;
  }
}

static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp) {
  if (PreOp)
    return LPAC::makePreOp(AluCode);
  if (PostOp)
    return LPAC::makePostOp(AluCode);
  return AluCode;
}

unsigned LanaiAsmParser::parseAluOperator(bool PreOp, bool PostOp) {
  StringRef IdString;
  Parser.parseIdentifier(IdString);
  unsigned AluCode = LPAC::stringToLanaiAluCode(IdString);
  if (AluCode == LPAC::UNKNOWN) {
    Error(Parser.getTok().getLoc(), "Can't parse ALU operator");
    return 0;
  }
  return AluCode;
}

static int SizeForSuffix(StringRef T) {
  return StringSwitch<int>(T).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
}

bool LanaiAsmParser::parsePrePost(StringRef Type, int *OffsetValue) {
  bool PreOrPost = false;
  if (Lexer.getKind() == Lexer.peekTok(true).getKind()) {
    PreOrPost = true;
    if (Lexer.is(AsmToken::Minus))
      *OffsetValue = -SizeForSuffix(Type);
    else if (Lexer.is(AsmToken::Plus))
      *OffsetValue = SizeForSuffix(Type);
    else
      return false;

    // Eat the '-' '-' or '+' '+'
    Parser.Lex();
    Parser.Lex();
  } else if (Lexer.is(AsmToken::Star)) {
    Parser.Lex(); // Eat the '*'
    PreOrPost = true;
  }

  return PreOrPost;
}

bool shouldBeSls(const LanaiOperand &Op) {
  // The instruction should be encoded as an SLS if the constant is word
  // aligned and will fit in 21 bits
  if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm())) {
    int64_t Value = ConstExpr->getValue();
    return (Value % 4 == 0) && (Value >= 0) && (Value <= 0x1fffff);
  }
  // The instruction should be encoded as an SLS if the operand is a symbolic
  // reference with no variant.
  if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Op.getImm()))
    return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
  // The instruction should be encoded as an SLS if the operand is a binary
  // expression with the left-hand side being a symbolic reference with no
  // variant.
  if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Op.getImm())) {
    const LanaiMCExpr *LHSSymbolRefExpr =
        dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
    return (LHSSymbolRefExpr &&
            LHSSymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
  }
  return false;
}

// Matches memory operand. Returns true if error encountered.
OperandMatchResultTy
LanaiAsmParser::parseMemoryOperand(OperandVector &Operands) {
  // Try to match a memory operand.
  // The memory operands are of the form:
  //  (1)  Register|Immediate|'' '[' '*'? Register '*'? ']' or
  //                            ^
  //  (2)  '[' '*'? Register '*'? AluOperator Register ']'
  //      ^
  //  (3)  '[' '--'|'++' Register '--'|'++' ']'
  //
  //  (4) '[' Immediate ']' (for SLS)

  // Store the type for use in parsing pre/post increment/decrement operators
  StringRef Type;
  if (Operands[0]->isToken())
    Type = static_cast<LanaiOperand *>(Operands[0].get())->getToken();

  // Use 0 if no offset given
  int OffsetValue = 0;
  unsigned BaseReg = 0;
  unsigned AluOp = LPAC::ADD;
  bool PostOp = false, PreOp = false;

  // Try to parse the offset
  std::unique_ptr<LanaiOperand> Op = parseRegister();
  if (!Op)
    Op = parseImmediate();

  // Only continue if next token is '['
  if (Lexer.isNot(AsmToken::LBrac)) {
    if (!Op)
      return MatchOperand_NoMatch;

    // The start of this custom parsing overlaps with register/immediate so
    // consider this as a successful match of an operand of that type as the
    // token stream can't be rewound to allow them to match separately.
    Operands.push_back(std::move(Op));
    return MatchOperand_Success;
  }

  Parser.Lex(); // Eat the '['.
  std::unique_ptr<LanaiOperand> Offset = nullptr;
  if (Op)
    Offset.swap(Op);

  // Determine if a pre operation
  PreOp = parsePrePost(Type, &OffsetValue);

  Op = parseRegister();
  if (!Op) {
    if (!Offset) {
      if ((Op = parseImmediate()) && Lexer.is(AsmToken::RBrac)) {
        Parser.Lex(); // Eat the ']'

        // Memory address operations aligned to word boundary are encoded as
        // SLS, the rest as RM.
        if (shouldBeSls(*Op)) {
          Operands.push_back(LanaiOperand::MorphToMemImm(std::move(Op)));
        } else {
          if (!Op->isLoImm16Signed()) {
            Error(Parser.getTok().getLoc(),
                  "Memory address is not word "
                  "aligned and larger than class RM can handle");
            return MatchOperand_ParseFail;
          }
          Operands.push_back(LanaiOperand::MorphToMemRegImm(
              Lanai::R0, std::move(Op), LPAC::ADD));
        }
        return MatchOperand_Success;
      }
    }

    Error(Parser.getTok().getLoc(),
          "Unknown operand, expected register or immediate");
    return MatchOperand_ParseFail;
  }
  BaseReg = Op->getReg();

  // Determine if a post operation
  if (!PreOp)
    PostOp = parsePrePost(Type, &OffsetValue);

  // If ] match form (1) else match form (2)
  if (Lexer.is(AsmToken::RBrac)) {
    Parser.Lex(); // Eat the ']'.
    if (!Offset) {
      SMLoc Start = Parser.getTok().getLoc();
      SMLoc End =
          SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
      const MCConstantExpr *OffsetConstExpr =
          MCConstantExpr::create(OffsetValue, getContext());
      Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End);
    }
  } else {
    if (Offset || OffsetValue != 0) {
      Error(Parser.getTok().getLoc(), "Expected ']'");
      return MatchOperand_ParseFail;
    }

    // Parse operator
    AluOp = parseAluOperator(PreOp, PostOp);

    // Second form requires offset register
    Offset = parseRegister();
    if (!BaseReg || Lexer.isNot(AsmToken::RBrac)) {
      Error(Parser.getTok().getLoc(), "Expected ']'");
      return MatchOperand_ParseFail;
    }
    Parser.Lex(); // Eat the ']'.
  }

  // First form has addition as operator. Add pre- or post-op indicator as
  // needed.
  AluOp = AluWithPrePost(AluOp, PreOp, PostOp);

  // Ensure immediate offset is not too large
  if (Offset->isImm() && !Offset->isLoImm16Signed()) {
    Error(Parser.getTok().getLoc(),
          "Memory address is not word "
          "aligned and larger than class RM can handle");
    return MatchOperand_ParseFail;
  }

  Operands.push_back(
      Offset->isImm()
          ? LanaiOperand::MorphToMemRegImm(BaseReg, std::move(Offset), AluOp)
          : LanaiOperand::MorphToMemRegReg(BaseReg, std::move(Offset), AluOp));

  return MatchOperand_Success;
}

// Looks at a token type and creates the relevant operand from this
// information, adding to operands.
// If operand was parsed, returns false, else true.
OperandMatchResultTy
LanaiAsmParser::parseOperand(OperandVector *Operands, StringRef Mnemonic) {
  // Check if the current operand has a custom associated parser, if so, try to
  // custom parse the operand, or fallback to the general approach.
  OperandMatchResultTy Result = MatchOperandParserImpl(*Operands, Mnemonic);

  if (Result == MatchOperand_Success)
    return Result;
  if (Result == MatchOperand_ParseFail) {
    Parser.eatToEndOfStatement();
    return Result;
  }

  // Attempt to parse token as register
  std::unique_ptr<LanaiOperand> Op = parseRegister();

  // Attempt to parse token as immediate
  if (!Op)
    Op = parseImmediate();

  // If the token could not be parsed then fail
  if (!Op) {
    Error(Parser.getTok().getLoc(), "Unknown operand");
    Parser.eatToEndOfStatement();
    return MatchOperand_ParseFail;
  }

  // Push back parsed operand into list of operands
  Operands->push_back(std::move(Op));

  return MatchOperand_Success;
}

// Split the mnemonic into ASM operand, conditional code and instruction
// qualifier (half-word, byte).
StringRef LanaiAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
                                        OperandVector *Operands) {
  size_t Next = Name.find('.');

  StringRef Mnemonic = Name;

  bool IsBRR = false;
  if (Name.endswith(".r")) {
    Mnemonic = Name.substr(0, Name.size() - 2);
    IsBRR = true;
  }

  // Match b?? and s?? (BR, BRR, and SCC instruction classes).
  if (Mnemonic[0] == 'b' ||
      (Mnemonic[0] == 's' && !Mnemonic.startswith("sel") &&
       !Mnemonic.startswith("st"))) {
    // Parse instructions with a conditional code. For example, 'bne' is
    // converted into two operands 'b' and 'ne'.
    LPCC::CondCode CondCode =
        LPCC::suffixToLanaiCondCode(Mnemonic.substr(1, Next));
    if (CondCode != LPCC::UNKNOWN) {
      Mnemonic = Mnemonic.slice(0, 1);
      Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
      Operands->push_back(LanaiOperand::createImm(
          MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
      if (IsBRR) {
        Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
      }
      return Mnemonic;
    }
  }

  // Parse other instructions with condition codes (RR instructions).
  // We ignore .f here and assume they are flag-setting operations, not
  // conditional codes (except for select instructions where flag-setting
  // variants are not yet implemented).
  if (Mnemonic.startswith("sel") ||
      (!Mnemonic.endswith(".f") && !Mnemonic.startswith("st"))) {
    LPCC::CondCode CondCode = LPCC::suffixToLanaiCondCode(Mnemonic);
    if (CondCode != LPCC::UNKNOWN) {
      size_t Next = Mnemonic.rfind('.', Name.size());
      // 'sel' doesn't use a predicate operand whose printer adds the period,
      // but instead has the period as part of the identifier (i.e., 'sel.' is
      // expected by the generated matcher). If the mnemonic starts with 'sel'
      // then include the period as part of the mnemonic, else don't include it
      // as part of the mnemonic.
      if (Mnemonic.startswith("sel")) {
        Mnemonic = Mnemonic.substr(0, Next + 1);
      } else {
        Mnemonic = Mnemonic.substr(0, Next);
      }
      Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
      Operands->push_back(LanaiOperand::createImm(
          MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
      return Mnemonic;
    }
  }

  Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
  if (IsBRR) {
    Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
  }

  return Mnemonic;
}

static bool IsMemoryAssignmentError(const OperandVector &Operands) {
  // Detects if a memory operation has an erroneous base register modification.
  // Memory operations are detected by matching the types of operands.
  //
  // TODO: This test is focussed on one specific instance (ld/st).
  // Extend it to handle more cases or be more robust.
  bool Modifies = false;

  int Offset = 0;

  if (Operands.size() < 5)
    return false;
  else if (Operands[0]->isToken() && Operands[1]->isReg() &&
           Operands[2]->isImm() && Operands[3]->isImm() && Operands[4]->isReg())
    Offset = 0;
  else if (Operands[0]->isToken() && Operands[1]->isToken() &&
           Operands[2]->isReg() && Operands[3]->isImm() &&
           Operands[4]->isImm() && Operands[5]->isReg())
    Offset = 1;
  else
    return false;

  int PossibleAluOpIdx = Offset + 3;
  int PossibleBaseIdx = Offset + 1;
  int PossibleDestIdx = Offset + 4;
  if (LanaiOperand *PossibleAluOp =
          static_cast<LanaiOperand *>(Operands[PossibleAluOpIdx].get()))
    if (PossibleAluOp->isImm())
      if (const MCConstantExpr *ConstExpr =
              dyn_cast<MCConstantExpr>(PossibleAluOp->getImm()))
        Modifies = LPAC::modifiesOp(ConstExpr->getValue());
  return Modifies && Operands[PossibleBaseIdx]->isReg() &&
         Operands[PossibleDestIdx]->isReg() &&
         Operands[PossibleBaseIdx]->getReg() ==
             Operands[PossibleDestIdx]->getReg();
}

static bool IsRegister(const MCParsedAsmOperand &op) {
  return static_cast<const LanaiOperand &>(op).isReg();
}

static bool MaybePredicatedInst(const OperandVector &Operands) {
  if (Operands.size() < 4 || !IsRegister(*Operands[1]) ||
      !IsRegister(*Operands[2]))
    return false;
  return StringSwitch<bool>(
             static_cast<const LanaiOperand &>(*Operands[0]).getToken())
      .StartsWith("addc", true)
      .StartsWith("add", true)
      .StartsWith("and", true)
      .StartsWith("sh", true)
      .StartsWith("subb", true)
      .StartsWith("sub", true)
      .StartsWith("or", true)
      .StartsWith("xor", true)
      .Default(false);
}

bool LanaiAsmParser::ParseInstruction(ParseInstructionInfo & /*Info*/,
                                      StringRef Name, SMLoc NameLoc,
                                      OperandVector &Operands) {
  // First operand is token for instruction
  StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);

  // If there are no more operands, then finish
  if (Lexer.is(AsmToken::EndOfStatement))
    return false;

  // Parse first operand
  if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
    return true;

  // If it is a st instruction with one 1 operand then it is a "store true".
  // Transform <"st"> to <"s">, <LPCC:ICC_T>
  if (Lexer.is(AsmToken::EndOfStatement) && Name == "st" &&
      Operands.size() == 2) {
    Operands.erase(Operands.begin(), Operands.begin() + 1);
    Operands.insert(Operands.begin(), LanaiOperand::CreateToken("s", NameLoc));
    Operands.insert(Operands.begin() + 1,
                    LanaiOperand::createImm(
                        MCConstantExpr::create(LPCC::ICC_T, getContext()),
                        NameLoc, NameLoc));
  }

  // If the instruction is a bt instruction with 1 operand (in assembly) then it
  // is an unconditional branch instruction and the first two elements of
  // operands need to be merged.
  if (Lexer.is(AsmToken::EndOfStatement) && Name.startswith("bt") &&
      Operands.size() == 3) {
    Operands.erase(Operands.begin(), Operands.begin() + 2);
    Operands.insert(Operands.begin(), LanaiOperand::CreateToken("bt", NameLoc));
  }

  // Parse until end of statement, consuming commas between operands
  while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.is(AsmToken::Comma)) {
    // Consume comma token
    Lex();

    // Parse next operand
    if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
      return true;
  }

  if (IsMemoryAssignmentError(Operands)) {
    Error(Parser.getTok().getLoc(),
          "the destination register can't equal the base register in an "
          "instruction that modifies the base register.");
    return true;
  }

  // Insert always true operand for instruction that may be predicated but
  // are not. Currently the autogenerated parser always expects a predicate.
  if (MaybePredicatedInst(Operands)) {
    Operands.insert(Operands.begin() + 1,
                    LanaiOperand::createImm(
                        MCConstantExpr::create(LPCC::ICC_T, getContext()),
                        NameLoc, NameLoc));
  }

  return false;
}

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

extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiAsmParser() {
  RegisterMCAsmParser<LanaiAsmParser> x(getTheLanaiTarget());
}
