//=== HexagonMCCompound.cpp - Hexagon Compound checker  -------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file is looks at a packet and tries to form compound insns
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/HexagonBaseInfo.h"
#include "MCTargetDesc/HexagonMCInstrInfo.h"
#include "MCTargetDesc/HexagonMCShuffler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>

using namespace llvm;
using namespace Hexagon;

#define DEBUG_TYPE "hexagon-mccompound"

enum OpcodeIndex {
  fp0_jump_nt = 0,
  fp0_jump_t,
  fp1_jump_nt,
  fp1_jump_t,
  tp0_jump_nt,
  tp0_jump_t,
  tp1_jump_nt,
  tp1_jump_t
};

static const unsigned tstBitOpcode[8] = {
    J4_tstbit0_fp0_jump_nt, J4_tstbit0_fp0_jump_t,  J4_tstbit0_fp1_jump_nt,
    J4_tstbit0_fp1_jump_t,  J4_tstbit0_tp0_jump_nt, J4_tstbit0_tp0_jump_t,
    J4_tstbit0_tp1_jump_nt, J4_tstbit0_tp1_jump_t};
static const unsigned cmpeqBitOpcode[8] = {
    J4_cmpeq_fp0_jump_nt, J4_cmpeq_fp0_jump_t,  J4_cmpeq_fp1_jump_nt,
    J4_cmpeq_fp1_jump_t,  J4_cmpeq_tp0_jump_nt, J4_cmpeq_tp0_jump_t,
    J4_cmpeq_tp1_jump_nt, J4_cmpeq_tp1_jump_t};
static const unsigned cmpgtBitOpcode[8] = {
    J4_cmpgt_fp0_jump_nt, J4_cmpgt_fp0_jump_t,  J4_cmpgt_fp1_jump_nt,
    J4_cmpgt_fp1_jump_t,  J4_cmpgt_tp0_jump_nt, J4_cmpgt_tp0_jump_t,
    J4_cmpgt_tp1_jump_nt, J4_cmpgt_tp1_jump_t};
static const unsigned cmpgtuBitOpcode[8] = {
    J4_cmpgtu_fp0_jump_nt, J4_cmpgtu_fp0_jump_t,  J4_cmpgtu_fp1_jump_nt,
    J4_cmpgtu_fp1_jump_t,  J4_cmpgtu_tp0_jump_nt, J4_cmpgtu_tp0_jump_t,
    J4_cmpgtu_tp1_jump_nt, J4_cmpgtu_tp1_jump_t};
static const unsigned cmpeqiBitOpcode[8] = {
    J4_cmpeqi_fp0_jump_nt, J4_cmpeqi_fp0_jump_t,  J4_cmpeqi_fp1_jump_nt,
    J4_cmpeqi_fp1_jump_t,  J4_cmpeqi_tp0_jump_nt, J4_cmpeqi_tp0_jump_t,
    J4_cmpeqi_tp1_jump_nt, J4_cmpeqi_tp1_jump_t};
static const unsigned cmpgtiBitOpcode[8] = {
    J4_cmpgti_fp0_jump_nt, J4_cmpgti_fp0_jump_t,  J4_cmpgti_fp1_jump_nt,
    J4_cmpgti_fp1_jump_t,  J4_cmpgti_tp0_jump_nt, J4_cmpgti_tp0_jump_t,
    J4_cmpgti_tp1_jump_nt, J4_cmpgti_tp1_jump_t};
static const unsigned cmpgtuiBitOpcode[8] = {
    J4_cmpgtui_fp0_jump_nt, J4_cmpgtui_fp0_jump_t,  J4_cmpgtui_fp1_jump_nt,
    J4_cmpgtui_fp1_jump_t,  J4_cmpgtui_tp0_jump_nt, J4_cmpgtui_tp0_jump_t,
    J4_cmpgtui_tp1_jump_nt, J4_cmpgtui_tp1_jump_t};
static const unsigned cmpeqn1BitOpcode[8] = {
    J4_cmpeqn1_fp0_jump_nt, J4_cmpeqn1_fp0_jump_t,  J4_cmpeqn1_fp1_jump_nt,
    J4_cmpeqn1_fp1_jump_t,  J4_cmpeqn1_tp0_jump_nt, J4_cmpeqn1_tp0_jump_t,
    J4_cmpeqn1_tp1_jump_nt, J4_cmpeqn1_tp1_jump_t};
static const unsigned cmpgtn1BitOpcode[8] = {
    J4_cmpgtn1_fp0_jump_nt, J4_cmpgtn1_fp0_jump_t,  J4_cmpgtn1_fp1_jump_nt,
    J4_cmpgtn1_fp1_jump_t,  J4_cmpgtn1_tp0_jump_nt, J4_cmpgtn1_tp0_jump_t,
    J4_cmpgtn1_tp1_jump_nt, J4_cmpgtn1_tp1_jump_t,
};

// enum HexagonII::CompoundGroup
static unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) {
  MCRegister DstReg, SrcReg, Src1Reg, Src2Reg;

  switch (MI.getOpcode()) {
  default:
    return HexagonII::HCG_None;
  //
  // Compound pairs.
  // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
  // "Rd16=#U6 ; jump #r9:2"
  // "Rd16=Rs16 ; jump #r9:2"
  //
  case Hexagon::C2_cmpeq:
  case Hexagon::C2_cmpgt:
  case Hexagon::C2_cmpgtu:
    if (IsExtended)
      return HexagonII::HCG_None;
    DstReg = MI.getOperand(0).getReg();
    Src1Reg = MI.getOperand(1).getReg();
    Src2Reg = MI.getOperand(2).getReg();
    if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
        HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
        HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg))
      return HexagonII::HCG_A;
    break;
  case Hexagon::C2_cmpeqi:
  case Hexagon::C2_cmpgti:
  case Hexagon::C2_cmpgtui:
    if (IsExtended)
      return HexagonII::HCG_None;
    // P0 = cmp.eq(Rs,#u2)
    DstReg = MI.getOperand(0).getReg();
    SrcReg = MI.getOperand(1).getReg();
    if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
        (HexagonMCInstrInfo::inRange<5>(MI, 2) ||
         HexagonMCInstrInfo::minConstant(MI, 2) == -1))
      return HexagonII::HCG_A;
    break;
  case Hexagon::A2_tfr:
    if (IsExtended)
      return HexagonII::HCG_None;
    // Rd = Rs
    DstReg = MI.getOperand(0).getReg();
    SrcReg = MI.getOperand(1).getReg();
    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg))
      return HexagonII::HCG_A;
    break;
  case Hexagon::A2_tfrsi:
    if (IsExtended)
      return HexagonII::HCG_None;
    // Rd = #u6
    DstReg = MI.getOperand(0).getReg();
    if (HexagonMCInstrInfo::minConstant(MI, 1) <= 63 &&
        HexagonMCInstrInfo::minConstant(MI, 1) >= 0 &&
        HexagonMCInstrInfo::isIntRegForSubInst(DstReg))
      return HexagonII::HCG_A;
    break;
  case Hexagon::S2_tstbit_i:
    if (IsExtended)
      return HexagonII::HCG_None;
    DstReg = MI.getOperand(0).getReg();
    Src1Reg = MI.getOperand(1).getReg();
    if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
        HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
        HexagonMCInstrInfo::minConstant(MI, 2) == 0)
      return HexagonII::HCG_A;
    break;
  // The fact that .new form is used pretty much guarantees
  // that predicate register will match. Nevertheless,
  // there could be some false positives without additional
  // checking.
  case Hexagon::J2_jumptnew:
  case Hexagon::J2_jumpfnew:
  case Hexagon::J2_jumptnewpt:
  case Hexagon::J2_jumpfnewpt:
    Src1Reg = MI.getOperand(0).getReg();
    if (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg)
      return HexagonII::HCG_B;
    break;
  // Transfer and jump:
  // Rd=#U6 ; jump #r9:2
  // Rd=Rs ; jump #r9:2
  // Do not test for jump range here.
  case Hexagon::J2_jump:
  case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
    return HexagonII::HCG_C;
    break;
  }

  return HexagonII::HCG_None;
}

/// getCompoundOp - Return the index from 0-7 into the above opcode lists.
static unsigned getCompoundOp(MCInst const &HMCI) {
  const MCOperand &Predicate = HMCI.getOperand(0);
  MCRegister PredReg = Predicate.getReg();

  assert((PredReg == Hexagon::P0) || (PredReg == Hexagon::P1) ||
         (PredReg == Hexagon::P2) || (PredReg == Hexagon::P3));

  switch (HMCI.getOpcode()) {
  default:
    llvm_unreachable("Expected match not found.\n");
    break;
  case Hexagon::J2_jumpfnew:
    return (PredReg == Hexagon::P0) ? fp0_jump_nt : fp1_jump_nt;
  case Hexagon::J2_jumpfnewpt:
    return (PredReg == Hexagon::P0) ? fp0_jump_t : fp1_jump_t;
  case Hexagon::J2_jumptnew:
    return (PredReg == Hexagon::P0) ? tp0_jump_nt : tp1_jump_nt;
  case Hexagon::J2_jumptnewpt:
    return (PredReg == Hexagon::P0) ? tp0_jump_t : tp1_jump_t;
  }
}

static MCInst *getCompoundInsn(MCContext &Context, MCInst const &L,
                               MCInst const &R) {
  MCInst *CompoundInsn = nullptr;
  unsigned compoundOpcode;
  MCOperand Rs, Rt;
  int64_t Value;
  bool Success;

  switch (L.getOpcode()) {
  default:
    LLVM_DEBUG(dbgs() << "Possible compound ignored\n");
    return CompoundInsn;

  case Hexagon::A2_tfrsi:
    Rt = L.getOperand(0);
    compoundOpcode = J4_jumpseti;
    CompoundInsn = Context.createMCInst();
    CompoundInsn->setOpcode(compoundOpcode);

    CompoundInsn->addOperand(Rt);
    CompoundInsn->addOperand(L.getOperand(1)); // Immediate
    CompoundInsn->addOperand(R.getOperand(0)); // Jump target
    break;

  case Hexagon::A2_tfr:
    Rt = L.getOperand(0);
    Rs = L.getOperand(1);

    compoundOpcode = J4_jumpsetr;
    CompoundInsn = Context.createMCInst();
    CompoundInsn->setOpcode(compoundOpcode);
    CompoundInsn->addOperand(Rt);
    CompoundInsn->addOperand(Rs);
    CompoundInsn->addOperand(R.getOperand(0)); // Jump target.

    break;

  case Hexagon::C2_cmpeq:
    LLVM_DEBUG(dbgs() << "CX: C2_cmpeq\n");
    Rs = L.getOperand(1);
    Rt = L.getOperand(2);

    compoundOpcode = cmpeqBitOpcode[getCompoundOp(R)];
    CompoundInsn = Context.createMCInst();
    CompoundInsn->setOpcode(compoundOpcode);
    CompoundInsn->addOperand(Rs);
    CompoundInsn->addOperand(Rt);
    CompoundInsn->addOperand(R.getOperand(1));
    break;

  case Hexagon::C2_cmpgt:
    LLVM_DEBUG(dbgs() << "CX: C2_cmpgt\n");
    Rs = L.getOperand(1);
    Rt = L.getOperand(2);

    compoundOpcode = cmpgtBitOpcode[getCompoundOp(R)];
    CompoundInsn = Context.createMCInst();
    CompoundInsn->setOpcode(compoundOpcode);
    CompoundInsn->addOperand(Rs);
    CompoundInsn->addOperand(Rt);
    CompoundInsn->addOperand(R.getOperand(1));
    break;

  case Hexagon::C2_cmpgtu:
    LLVM_DEBUG(dbgs() << "CX: C2_cmpgtu\n");
    Rs = L.getOperand(1);
    Rt = L.getOperand(2);

    compoundOpcode = cmpgtuBitOpcode[getCompoundOp(R)];
    CompoundInsn = Context.createMCInst();
    CompoundInsn->setOpcode(compoundOpcode);
    CompoundInsn->addOperand(Rs);
    CompoundInsn->addOperand(Rt);
    CompoundInsn->addOperand(R.getOperand(1));
    break;

  case Hexagon::C2_cmpeqi:
    LLVM_DEBUG(dbgs() << "CX: C2_cmpeqi\n");
    Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
    (void)Success;
    assert(Success);
    if (Value == -1)
      compoundOpcode = cmpeqn1BitOpcode[getCompoundOp(R)];
    else
      compoundOpcode = cmpeqiBitOpcode[getCompoundOp(R)];

    Rs = L.getOperand(1);
    CompoundInsn = Context.createMCInst();
    CompoundInsn->setOpcode(compoundOpcode);
    CompoundInsn->addOperand(Rs);
    CompoundInsn->addOperand(L.getOperand(2));
    CompoundInsn->addOperand(R.getOperand(1));
    break;

  case Hexagon::C2_cmpgti:
    LLVM_DEBUG(dbgs() << "CX: C2_cmpgti\n");
    Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
    (void)Success;
    assert(Success);
    if (Value == -1)
      compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(R)];
    else
      compoundOpcode = cmpgtiBitOpcode[getCompoundOp(R)];

    Rs = L.getOperand(1);
    CompoundInsn = Context.createMCInst();
    CompoundInsn->setOpcode(compoundOpcode);
    CompoundInsn->addOperand(Rs);
    CompoundInsn->addOperand(L.getOperand(2));
    CompoundInsn->addOperand(R.getOperand(1));
    break;

  case Hexagon::C2_cmpgtui:
    LLVM_DEBUG(dbgs() << "CX: C2_cmpgtui\n");
    Rs = L.getOperand(1);
    compoundOpcode = cmpgtuiBitOpcode[getCompoundOp(R)];
    CompoundInsn = Context.createMCInst();
    CompoundInsn->setOpcode(compoundOpcode);
    CompoundInsn->addOperand(Rs);
    CompoundInsn->addOperand(L.getOperand(2));
    CompoundInsn->addOperand(R.getOperand(1));
    break;

  case Hexagon::S2_tstbit_i:
    LLVM_DEBUG(dbgs() << "CX: S2_tstbit_i\n");
    Rs = L.getOperand(1);
    compoundOpcode = tstBitOpcode[getCompoundOp(R)];
    CompoundInsn = Context.createMCInst();
    CompoundInsn->setOpcode(compoundOpcode);
    CompoundInsn->addOperand(Rs);
    CompoundInsn->addOperand(R.getOperand(1));
    break;
  }

  return CompoundInsn;
}

/// Non-Symmetrical. See if these two instructions are fit for compound pair.
static bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
                                  MCInst const &MIb, bool IsExtendedB) {
  unsigned MIaG = getCompoundCandidateGroup(MIa, IsExtendedA);
  unsigned MIbG = getCompoundCandidateGroup(MIb, IsExtendedB);
  // We have two candidates - check that this is the same register
  // we are talking about.
  unsigned Opca = MIa.getOpcode();
  if (MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_C &&
      (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
    return true;
  return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) &&
          (MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg()));
}

static bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context,
                            MCInst &MCI) {
  assert(HexagonMCInstrInfo::isBundle(MCI));
  bool JExtended = false;
  for (MCInst::iterator J =
           MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
       J != MCI.end(); ++J) {
    MCInst const *JumpInst = J->getInst();
    if (HexagonMCInstrInfo::isImmext(*JumpInst)) {
      JExtended = true;
      continue;
    }
    if (HexagonMCInstrInfo::getType(MCII, *JumpInst) == HexagonII::TypeJ) {
      // Try to pair with another insn (B)undled with jump.
      bool BExtended = false;
      for (MCInst::iterator B =
               MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
           B != MCI.end(); ++B) {
        MCInst const *Inst = B->getInst();
        if (JumpInst == Inst) {
          BExtended = false;
          continue;
        }
        if (HexagonMCInstrInfo::isImmext(*Inst)) {
          BExtended = true;
          continue;
        }
        LLVM_DEBUG(dbgs() << "J,B: " << JumpInst->getOpcode() << ","
                          << Inst->getOpcode() << "\n");
        if (isOrderedCompoundPair(*Inst, BExtended, *JumpInst, JExtended)) {
          MCInst *CompoundInsn = getCompoundInsn(Context, *Inst, *JumpInst);
          if (CompoundInsn) {
            LLVM_DEBUG(dbgs() << "B: " << Inst->getOpcode() << ","
                              << JumpInst->getOpcode() << " Compounds to "
                              << CompoundInsn->getOpcode() << "\n");
            J->setInst(CompoundInsn);
            MCI.erase(B);
            return true;
          }
        }
        BExtended = false;
      }
    }
    JExtended = false;
  }
  return false;
}

/// tryCompound - Given a bundle check for compound insns when one
/// is found update the contents fo the bundle with the compound insn.
/// If a compound instruction is found then the bundle will have one
/// additional slot.
void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
                                     MCContext &Context, MCInst &MCI) {
  assert(HexagonMCInstrInfo::isBundle(MCI) &&
         "Non-Bundle where Bundle expected");

  // By definition a compound must have 2 insn.
  if (MCI.size() < 2)
    return;

  // Create a vector, needed to keep the order of jump instructions.
  MCInst CheckList(MCI);

  // Keep the last known good bundle around in case the shuffle fails.
  MCInst LastValidBundle(MCI);

  bool PreviouslyValid = llvm::HexagonMCShuffle(Context, false, MCII, STI, MCI);

  // Look for compounds until none are found, only update the bundle when
  // a compound is found.
  while (lookForCompound(MCII, Context, CheckList)) {
    // Need to update the bundle.
    MCI = CheckList;

    const bool IsValid = llvm::HexagonMCShuffle(Context, false, MCII, STI, MCI);
    if (PreviouslyValid && !IsValid) {
      LLVM_DEBUG(dbgs() << "Found ERROR\n");
      MCI = LastValidBundle;
    } else if (IsValid) {
      LastValidBundle = MCI;
      PreviouslyValid = true;
    }
  }
}
