//===- HexagonBitTracker.cpp ----------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "HexagonBitTracker.h"
#include "Hexagon.h"
#include "HexagonInstrInfo.h"
#include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <utility>
#include <vector>

using namespace llvm;

using BT = BitTracker;

HexagonEvaluator::HexagonEvaluator(const HexagonRegisterInfo &tri,
                                   MachineRegisterInfo &mri,
                                   const HexagonInstrInfo &tii,
                                   MachineFunction &mf)
    : MachineEvaluator(tri, mri), MF(mf), MFI(mf.getFrameInfo()), TII(tii) {
  // Populate the VRX map (VR to extension-type).
  // Go over all the formal parameters of the function. If a given parameter
  // P is sign- or zero-extended, locate the virtual register holding that
  // parameter and create an entry in the VRX map indicating the type of ex-
  // tension (and the source type).
  // This is a bit complicated to do accurately, since the memory layout in-
  // formation is necessary to precisely determine whether an aggregate para-
  // meter will be passed in a register or in memory. What is given in MRI
  // is the association between the physical register that is live-in (i.e.
  // holds an argument), and the virtual register that this value will be
  // copied into. This, by itself, is not sufficient to map back the virtual
  // register to a formal parameter from Function (since consecutive live-ins
  // from MRI may not correspond to consecutive formal parameters from Func-
  // tion). To avoid the complications with in-memory arguments, only consi-
  // der the initial sequence of formal parameters that are known to be
  // passed via registers.
  unsigned InVirtReg, InPhysReg = 0;

  for (const Argument &Arg : MF.getFunction()->args()) {
    Type *ATy = Arg.getType();
    unsigned Width = 0;
    if (ATy->isIntegerTy())
      Width = ATy->getIntegerBitWidth();
    else if (ATy->isPointerTy())
      Width = 32;
    // If pointer size is not set through target data, it will default to
    // Module::AnyPointerSize.
    if (Width == 0 || Width > 64)
      break;
    if (Arg.hasAttribute(Attribute::ByVal))
      continue;
    InPhysReg = getNextPhysReg(InPhysReg, Width);
    if (!InPhysReg)
      break;
    InVirtReg = getVirtRegFor(InPhysReg);
    if (!InVirtReg)
      continue;
    if (Arg.hasAttribute(Attribute::SExt))
      VRX.insert(std::make_pair(InVirtReg, ExtType(ExtType::SExt, Width)));
    else if (Arg.hasAttribute(Attribute::ZExt))
      VRX.insert(std::make_pair(InVirtReg, ExtType(ExtType::ZExt, Width)));
  }
}

BT::BitMask HexagonEvaluator::mask(unsigned Reg, unsigned Sub) const {
  if (Sub == 0)
    return MachineEvaluator::mask(Reg, 0);
  const TargetRegisterClass &RC = *MRI.getRegClass(Reg);
  unsigned ID = RC.getID();
  uint16_t RW = getRegBitWidth(RegisterRef(Reg, Sub));
  auto &HRI = static_cast<const HexagonRegisterInfo&>(TRI);
  bool IsSubLo = (Sub == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_lo));
  switch (ID) {
    case Hexagon::DoubleRegsRegClassID:
    case Hexagon::HvxWRRegClassID:
      return IsSubLo ? BT::BitMask(0, RW-1)
                     : BT::BitMask(RW, 2*RW-1);
    default:
      break;
  }
#ifndef NDEBUG
  dbgs() << PrintReg(Reg, &TRI, Sub) << " in reg class "
         << TRI.getRegClassName(&RC) << '\n';
#endif
  llvm_unreachable("Unexpected register/subregister");
}

uint16_t HexagonEvaluator::getPhysRegBitWidth(unsigned Reg) const {
  assert(TargetRegisterInfo::isPhysicalRegister(Reg));

  using namespace Hexagon;
  for (auto &RC : {HvxVRRegClass, HvxWRRegClass, HvxQRRegClass})
    if (RC.contains(Reg))
      return TRI.getRegSizeInBits(RC);
  // Default treatment for other physical registers.
  if (const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg))
    return TRI.getRegSizeInBits(*RC);

  llvm_unreachable(
      (Twine("Unhandled physical register") + TRI.getName(Reg)).str().c_str());
}

const TargetRegisterClass &HexagonEvaluator::composeWithSubRegIndex(
      const TargetRegisterClass &RC, unsigned Idx) const {
  if (Idx == 0)
    return RC;

#ifndef NDEBUG
  const auto &HRI = static_cast<const HexagonRegisterInfo&>(TRI);
  bool IsSubLo = (Idx == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_lo));
  bool IsSubHi = (Idx == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_hi));
  assert(IsSubLo != IsSubHi && "Must refer to either low or high subreg");
#endif

  switch (RC.getID()) {
    case Hexagon::DoubleRegsRegClassID:
      return Hexagon::IntRegsRegClass;
    case Hexagon::HvxWRRegClassID:
      return Hexagon::HvxVRRegClass;
    default:
      break;
  }
#ifndef NDEBUG
  dbgs() << "Reg class id: " << RC.getID() << " idx: " << Idx << '\n';
#endif
  llvm_unreachable("Unimplemented combination of reg class/subreg idx");
}

namespace {

class RegisterRefs {
  std::vector<BT::RegisterRef> Vector;

public:
  RegisterRefs(const MachineInstr &MI) : Vector(MI.getNumOperands()) {
    for (unsigned i = 0, n = Vector.size(); i < n; ++i) {
      const MachineOperand &MO = MI.getOperand(i);
      if (MO.isReg())
        Vector[i] = BT::RegisterRef(MO);
      // For indices that don't correspond to registers, the entry will
      // remain constructed via the default constructor.
    }
  }

  size_t size() const { return Vector.size(); }

  const BT::RegisterRef &operator[](unsigned n) const {
    // The main purpose of this operator is to assert with bad argument.
    assert(n < Vector.size());
    return Vector[n];
  }
};

} // end anonymous namespace

bool HexagonEvaluator::evaluate(const MachineInstr &MI,
                                const CellMapType &Inputs,
                                CellMapType &Outputs) const {
  using namespace Hexagon;

  unsigned NumDefs = 0;

  // Sanity verification: there should not be any defs with subregisters.
  for (const MachineOperand &MO : MI.operands()) {
    if (!MO.isReg() || !MO.isDef())
      continue;
    NumDefs++;
    assert(MO.getSubReg() == 0);
  }

  if (NumDefs == 0)
    return false;

  unsigned Opc = MI.getOpcode();

  if (MI.mayLoad()) {
    switch (Opc) {
      // These instructions may be marked as mayLoad, but they are generating
      // immediate values, so skip them.
      case CONST32:
      case CONST64:
        break;
      default:
        return evaluateLoad(MI, Inputs, Outputs);
    }
  }

  // Check COPY instructions that copy formal parameters into virtual
  // registers. Such parameters can be sign- or zero-extended at the
  // call site, and we should take advantage of this knowledge. The MRI
  // keeps a list of pairs of live-in physical and virtual registers,
  // which provides information about which virtual registers will hold
  // the argument values. The function will still contain instructions
  // defining those virtual registers, and in practice those are COPY
  // instructions from a physical to a virtual register. In such cases,
  // applying the argument extension to the virtual register can be seen
  // as simply mirroring the extension that had already been applied to
  // the physical register at the call site. If the defining instruction
  // was not a COPY, it would not be clear how to mirror that extension
  // on the callee's side. For that reason, only check COPY instructions
  // for potential extensions.
  if (MI.isCopy()) {
    if (evaluateFormalCopy(MI, Inputs, Outputs))
      return true;
  }

  // Beyond this point, if any operand is a global, skip that instruction.
  // The reason is that certain instructions that can take an immediate
  // operand can also have a global symbol in that operand. To avoid
  // checking what kind of operand a given instruction has individually
  // for each instruction, do it here. Global symbols as operands gene-
  // rally do not provide any useful information.
  for (const MachineOperand &MO : MI.operands()) {
    if (MO.isGlobal() || MO.isBlockAddress() || MO.isSymbol() || MO.isJTI() ||
        MO.isCPI())
      return false;
  }

  RegisterRefs Reg(MI);
#define op(i) MI.getOperand(i)
#define rc(i) RegisterCell::ref(getCell(Reg[i], Inputs))
#define im(i) MI.getOperand(i).getImm()

  // If the instruction has no register operands, skip it.
  if (Reg.size() == 0)
    return false;

  // Record result for register in operand 0.
  auto rr0 = [this,Reg] (const BT::RegisterCell &Val, CellMapType &Outputs)
        -> bool {
    putCell(Reg[0], Val, Outputs);
    return true;
  };
  // Get the cell corresponding to the N-th operand.
  auto cop = [this, &Reg, &MI, &Inputs](unsigned N,
                                        uint16_t W) -> BT::RegisterCell {
    const MachineOperand &Op = MI.getOperand(N);
    if (Op.isImm())
      return eIMM(Op.getImm(), W);
    if (!Op.isReg())
      return RegisterCell::self(0, W);
    assert(getRegBitWidth(Reg[N]) == W && "Register width mismatch");
    return rc(N);
  };
  // Extract RW low bits of the cell.
  auto lo = [this] (const BT::RegisterCell &RC, uint16_t RW)
        -> BT::RegisterCell {
    assert(RW <= RC.width());
    return eXTR(RC, 0, RW);
  };
  // Extract RW high bits of the cell.
  auto hi = [this] (const BT::RegisterCell &RC, uint16_t RW)
        -> BT::RegisterCell {
    uint16_t W = RC.width();
    assert(RW <= W);
    return eXTR(RC, W-RW, W);
  };
  // Extract N-th halfword (counting from the least significant position).
  auto half = [this] (const BT::RegisterCell &RC, unsigned N)
        -> BT::RegisterCell {
    assert(N*16+16 <= RC.width());
    return eXTR(RC, N*16, N*16+16);
  };
  // Shuffle bits (pick even/odd from cells and merge into result).
  auto shuffle = [this] (const BT::RegisterCell &Rs, const BT::RegisterCell &Rt,
                         uint16_t BW, bool Odd) -> BT::RegisterCell {
    uint16_t I = Odd, Ws = Rs.width();
    assert(Ws == Rt.width());
    RegisterCell RC = eXTR(Rt, I*BW, I*BW+BW).cat(eXTR(Rs, I*BW, I*BW+BW));
    I += 2;
    while (I*BW < Ws) {
      RC.cat(eXTR(Rt, I*BW, I*BW+BW)).cat(eXTR(Rs, I*BW, I*BW+BW));
      I += 2;
    }
    return RC;
  };

  // The bitwidth of the 0th operand. In most (if not all) of the
  // instructions below, the 0th operand is the defined register.
  // Pre-compute the bitwidth here, because it is needed in many cases
  // cases below.
  uint16_t W0 = (Reg[0].Reg != 0) ? getRegBitWidth(Reg[0]) : 0;

  // Register id of the 0th operand. It can be 0.
  unsigned Reg0 = Reg[0].Reg;

  switch (Opc) {
    // Transfer immediate:

    case A2_tfrsi:
    case A2_tfrpi:
    case CONST32:
    case CONST64:
      return rr0(eIMM(im(1), W0), Outputs);
    case PS_false:
      return rr0(RegisterCell(W0).fill(0, W0, BT::BitValue::Zero), Outputs);
    case PS_true:
      return rr0(RegisterCell(W0).fill(0, W0, BT::BitValue::One), Outputs);
    case PS_fi: {
      int FI = op(1).getIndex();
      int Off = op(2).getImm();
      unsigned A = MFI.getObjectAlignment(FI) + std::abs(Off);
      unsigned L = Log2_32(A);
      RegisterCell RC = RegisterCell::self(Reg[0].Reg, W0);
      RC.fill(0, L, BT::BitValue::Zero);
      return rr0(RC, Outputs);
    }

    // Transfer register:

    case A2_tfr:
    case A2_tfrp:
    case C2_pxfer_map:
      return rr0(rc(1), Outputs);
    case C2_tfrpr: {
      uint16_t RW = W0;
      uint16_t PW = 8; // XXX Pred size: getRegBitWidth(Reg[1]);
      assert(PW <= RW);
      RegisterCell PC = eXTR(rc(1), 0, PW);
      RegisterCell RC = RegisterCell(RW).insert(PC, BT::BitMask(0, PW-1));
      RC.fill(PW, RW, BT::BitValue::Zero);
      return rr0(RC, Outputs);
    }
    case C2_tfrrp: {
      RegisterCell RC = RegisterCell::self(Reg[0].Reg, W0);
      W0 = 8; // XXX Pred size
      return rr0(eINS(RC, eXTR(rc(1), 0, W0), 0), Outputs);
    }

    // Arithmetic:

    case A2_abs:
    case A2_absp:
      // TODO
      break;

    case A2_addsp: {
      uint16_t W1 = getRegBitWidth(Reg[1]);
      assert(W0 == 64 && W1 == 32);
      RegisterCell CW = RegisterCell(W0).insert(rc(1), BT::BitMask(0, W1-1));
      RegisterCell RC = eADD(eSXT(CW, W1), rc(2));
      return rr0(RC, Outputs);
    }
    case A2_add:
    case A2_addp:
      return rr0(eADD(rc(1), rc(2)), Outputs);
    case A2_addi:
      return rr0(eADD(rc(1), eIMM(im(2), W0)), Outputs);
    case S4_addi_asl_ri: {
      RegisterCell RC = eADD(eIMM(im(1), W0), eASL(rc(2), im(3)));
      return rr0(RC, Outputs);
    }
    case S4_addi_lsr_ri: {
      RegisterCell RC = eADD(eIMM(im(1), W0), eLSR(rc(2), im(3)));
      return rr0(RC, Outputs);
    }
    case S4_addaddi: {
      RegisterCell RC = eADD(rc(1), eADD(rc(2), eIMM(im(3), W0)));
      return rr0(RC, Outputs);
    }
    case M4_mpyri_addi: {
      RegisterCell M = eMLS(rc(2), eIMM(im(3), W0));
      RegisterCell RC = eADD(eIMM(im(1), W0), lo(M, W0));
      return rr0(RC, Outputs);
    }
    case M4_mpyrr_addi: {
      RegisterCell M = eMLS(rc(2), rc(3));
      RegisterCell RC = eADD(eIMM(im(1), W0), lo(M, W0));
      return rr0(RC, Outputs);
    }
    case M4_mpyri_addr_u2: {
      RegisterCell M = eMLS(eIMM(im(2), W0), rc(3));
      RegisterCell RC = eADD(rc(1), lo(M, W0));
      return rr0(RC, Outputs);
    }
    case M4_mpyri_addr: {
      RegisterCell M = eMLS(rc(2), eIMM(im(3), W0));
      RegisterCell RC = eADD(rc(1), lo(M, W0));
      return rr0(RC, Outputs);
    }
    case M4_mpyrr_addr: {
      RegisterCell M = eMLS(rc(2), rc(3));
      RegisterCell RC = eADD(rc(1), lo(M, W0));
      return rr0(RC, Outputs);
    }
    case S4_subaddi: {
      RegisterCell RC = eADD(rc(1), eSUB(eIMM(im(2), W0), rc(3)));
      return rr0(RC, Outputs);
    }
    case M2_accii: {
      RegisterCell RC = eADD(rc(1), eADD(rc(2), eIMM(im(3), W0)));
      return rr0(RC, Outputs);
    }
    case M2_acci: {
      RegisterCell RC = eADD(rc(1), eADD(rc(2), rc(3)));
      return rr0(RC, Outputs);
    }
    case M2_subacc: {
      RegisterCell RC = eADD(rc(1), eSUB(rc(2), rc(3)));
      return rr0(RC, Outputs);
    }
    case S2_addasl_rrri: {
      RegisterCell RC = eADD(rc(1), eASL(rc(2), im(3)));
      return rr0(RC, Outputs);
    }
    case C4_addipc: {
      RegisterCell RPC = RegisterCell::self(Reg[0].Reg, W0);
      RPC.fill(0, 2, BT::BitValue::Zero);
      return rr0(eADD(RPC, eIMM(im(2), W0)), Outputs);
    }
    case A2_sub:
    case A2_subp:
      return rr0(eSUB(rc(1), rc(2)), Outputs);
    case A2_subri:
      return rr0(eSUB(eIMM(im(1), W0), rc(2)), Outputs);
    case S4_subi_asl_ri: {
      RegisterCell RC = eSUB(eIMM(im(1), W0), eASL(rc(2), im(3)));
      return rr0(RC, Outputs);
    }
    case S4_subi_lsr_ri: {
      RegisterCell RC = eSUB(eIMM(im(1), W0), eLSR(rc(2), im(3)));
      return rr0(RC, Outputs);
    }
    case M2_naccii: {
      RegisterCell RC = eSUB(rc(1), eADD(rc(2), eIMM(im(3), W0)));
      return rr0(RC, Outputs);
    }
    case M2_nacci: {
      RegisterCell RC = eSUB(rc(1), eADD(rc(2), rc(3)));
      return rr0(RC, Outputs);
    }
    // 32-bit negation is done by "Rd = A2_subri 0, Rs"
    case A2_negp:
      return rr0(eSUB(eIMM(0, W0), rc(1)), Outputs);

    case M2_mpy_up: {
      RegisterCell M = eMLS(rc(1), rc(2));
      return rr0(hi(M, W0), Outputs);
    }
    case M2_dpmpyss_s0:
      return rr0(eMLS(rc(1), rc(2)), Outputs);
    case M2_dpmpyss_acc_s0:
      return rr0(eADD(rc(1), eMLS(rc(2), rc(3))), Outputs);
    case M2_dpmpyss_nac_s0:
      return rr0(eSUB(rc(1), eMLS(rc(2), rc(3))), Outputs);
    case M2_mpyi: {
      RegisterCell M = eMLS(rc(1), rc(2));
      return rr0(lo(M, W0), Outputs);
    }
    case M2_macsip: {
      RegisterCell M = eMLS(rc(2), eIMM(im(3), W0));
      RegisterCell RC = eADD(rc(1), lo(M, W0));
      return rr0(RC, Outputs);
    }
    case M2_macsin: {
      RegisterCell M = eMLS(rc(2), eIMM(im(3), W0));
      RegisterCell RC = eSUB(rc(1), lo(M, W0));
      return rr0(RC, Outputs);
    }
    case M2_maci: {
      RegisterCell M = eMLS(rc(2), rc(3));
      RegisterCell RC = eADD(rc(1), lo(M, W0));
      return rr0(RC, Outputs);
    }
    case M2_mpysmi: {
      RegisterCell M = eMLS(rc(1), eIMM(im(2), W0));
      return rr0(lo(M, 32), Outputs);
    }
    case M2_mpysin: {
      RegisterCell M = eMLS(rc(1), eIMM(-im(2), W0));
      return rr0(lo(M, 32), Outputs);
    }
    case M2_mpysip: {
      RegisterCell M = eMLS(rc(1), eIMM(im(2), W0));
      return rr0(lo(M, 32), Outputs);
    }
    case M2_mpyu_up: {
      RegisterCell M = eMLU(rc(1), rc(2));
      return rr0(hi(M, W0), Outputs);
    }
    case M2_dpmpyuu_s0:
      return rr0(eMLU(rc(1), rc(2)), Outputs);
    case M2_dpmpyuu_acc_s0:
      return rr0(eADD(rc(1), eMLU(rc(2), rc(3))), Outputs);
    case M2_dpmpyuu_nac_s0:
      return rr0(eSUB(rc(1), eMLU(rc(2), rc(3))), Outputs);
    //case M2_mpysu_up:

    // Logical/bitwise:

    case A2_andir:
      return rr0(eAND(rc(1), eIMM(im(2), W0)), Outputs);
    case A2_and:
    case A2_andp:
      return rr0(eAND(rc(1), rc(2)), Outputs);
    case A4_andn:
    case A4_andnp:
      return rr0(eAND(rc(1), eNOT(rc(2))), Outputs);
    case S4_andi_asl_ri: {
      RegisterCell RC = eAND(eIMM(im(1), W0), eASL(rc(2), im(3)));
      return rr0(RC, Outputs);
    }
    case S4_andi_lsr_ri: {
      RegisterCell RC = eAND(eIMM(im(1), W0), eLSR(rc(2), im(3)));
      return rr0(RC, Outputs);
    }
    case M4_and_and:
      return rr0(eAND(rc(1), eAND(rc(2), rc(3))), Outputs);
    case M4_and_andn:
      return rr0(eAND(rc(1), eAND(rc(2), eNOT(rc(3)))), Outputs);
    case M4_and_or:
      return rr0(eAND(rc(1), eORL(rc(2), rc(3))), Outputs);
    case M4_and_xor:
      return rr0(eAND(rc(1), eXOR(rc(2), rc(3))), Outputs);
    case A2_orir:
      return rr0(eORL(rc(1), eIMM(im(2), W0)), Outputs);
    case A2_or:
    case A2_orp:
      return rr0(eORL(rc(1), rc(2)), Outputs);
    case A4_orn:
    case A4_ornp:
      return rr0(eORL(rc(1), eNOT(rc(2))), Outputs);
    case S4_ori_asl_ri: {
      RegisterCell RC = eORL(eIMM(im(1), W0), eASL(rc(2), im(3)));
      return rr0(RC, Outputs);
    }
    case S4_ori_lsr_ri: {
      RegisterCell RC = eORL(eIMM(im(1), W0), eLSR(rc(2), im(3)));
      return rr0(RC, Outputs);
    }
    case M4_or_and:
      return rr0(eORL(rc(1), eAND(rc(2), rc(3))), Outputs);
    case M4_or_andn:
      return rr0(eORL(rc(1), eAND(rc(2), eNOT(rc(3)))), Outputs);
    case S4_or_andi:
    case S4_or_andix: {
      RegisterCell RC = eORL(rc(1), eAND(rc(2), eIMM(im(3), W0)));
      return rr0(RC, Outputs);
    }
    case S4_or_ori: {
      RegisterCell RC = eORL(rc(1), eORL(rc(2), eIMM(im(3), W0)));
      return rr0(RC, Outputs);
    }
    case M4_or_or:
      return rr0(eORL(rc(1), eORL(rc(2), rc(3))), Outputs);
    case M4_or_xor:
      return rr0(eORL(rc(1), eXOR(rc(2), rc(3))), Outputs);
    case A2_xor:
    case A2_xorp:
      return rr0(eXOR(rc(1), rc(2)), Outputs);
    case M4_xor_and:
      return rr0(eXOR(rc(1), eAND(rc(2), rc(3))), Outputs);
    case M4_xor_andn:
      return rr0(eXOR(rc(1), eAND(rc(2), eNOT(rc(3)))), Outputs);
    case M4_xor_or:
      return rr0(eXOR(rc(1), eORL(rc(2), rc(3))), Outputs);
    case M4_xor_xacc:
      return rr0(eXOR(rc(1), eXOR(rc(2), rc(3))), Outputs);
    case A2_not:
    case A2_notp:
      return rr0(eNOT(rc(1)), Outputs);

    case S2_asl_i_r:
    case S2_asl_i_p:
      return rr0(eASL(rc(1), im(2)), Outputs);
    case A2_aslh:
      return rr0(eASL(rc(1), 16), Outputs);
    case S2_asl_i_r_acc:
    case S2_asl_i_p_acc:
      return rr0(eADD(rc(1), eASL(rc(2), im(3))), Outputs);
    case S2_asl_i_r_nac:
    case S2_asl_i_p_nac:
      return rr0(eSUB(rc(1), eASL(rc(2), im(3))), Outputs);
    case S2_asl_i_r_and:
    case S2_asl_i_p_and:
      return rr0(eAND(rc(1), eASL(rc(2), im(3))), Outputs);
    case S2_asl_i_r_or:
    case S2_asl_i_p_or:
      return rr0(eORL(rc(1), eASL(rc(2), im(3))), Outputs);
    case S2_asl_i_r_xacc:
    case S2_asl_i_p_xacc:
      return rr0(eXOR(rc(1), eASL(rc(2), im(3))), Outputs);
    case S2_asl_i_vh:
    case S2_asl_i_vw:
      // TODO
      break;

    case S2_asr_i_r:
    case S2_asr_i_p:
      return rr0(eASR(rc(1), im(2)), Outputs);
    case A2_asrh:
      return rr0(eASR(rc(1), 16), Outputs);
    case S2_asr_i_r_acc:
    case S2_asr_i_p_acc:
      return rr0(eADD(rc(1), eASR(rc(2), im(3))), Outputs);
    case S2_asr_i_r_nac:
    case S2_asr_i_p_nac:
      return rr0(eSUB(rc(1), eASR(rc(2), im(3))), Outputs);
    case S2_asr_i_r_and:
    case S2_asr_i_p_and:
      return rr0(eAND(rc(1), eASR(rc(2), im(3))), Outputs);
    case S2_asr_i_r_or:
    case S2_asr_i_p_or:
      return rr0(eORL(rc(1), eASR(rc(2), im(3))), Outputs);
    case S2_asr_i_r_rnd: {
      // The input is first sign-extended to 64 bits, then the output
      // is truncated back to 32 bits.
      assert(W0 == 32);
      RegisterCell XC = eSXT(rc(1).cat(eIMM(0, W0)), W0);
      RegisterCell RC = eASR(eADD(eASR(XC, im(2)), eIMM(1, 2*W0)), 1);
      return rr0(eXTR(RC, 0, W0), Outputs);
    }
    case S2_asr_i_r_rnd_goodsyntax: {
      int64_t S = im(2);
      if (S == 0)
        return rr0(rc(1), Outputs);
      // Result: S2_asr_i_r_rnd Rs, u5-1
      RegisterCell XC = eSXT(rc(1).cat(eIMM(0, W0)), W0);
      RegisterCell RC = eLSR(eADD(eASR(XC, S-1), eIMM(1, 2*W0)), 1);
      return rr0(eXTR(RC, 0, W0), Outputs);
    }
    case S2_asr_r_vh:
    case S2_asr_i_vw:
    case S2_asr_i_svw_trun:
      // TODO
      break;

    case S2_lsr_i_r:
    case S2_lsr_i_p:
      return rr0(eLSR(rc(1), im(2)), Outputs);
    case S2_lsr_i_r_acc:
    case S2_lsr_i_p_acc:
      return rr0(eADD(rc(1), eLSR(rc(2), im(3))), Outputs);
    case S2_lsr_i_r_nac:
    case S2_lsr_i_p_nac:
      return rr0(eSUB(rc(1), eLSR(rc(2), im(3))), Outputs);
    case S2_lsr_i_r_and:
    case S2_lsr_i_p_and:
      return rr0(eAND(rc(1), eLSR(rc(2), im(3))), Outputs);
    case S2_lsr_i_r_or:
    case S2_lsr_i_p_or:
      return rr0(eORL(rc(1), eLSR(rc(2), im(3))), Outputs);
    case S2_lsr_i_r_xacc:
    case S2_lsr_i_p_xacc:
      return rr0(eXOR(rc(1), eLSR(rc(2), im(3))), Outputs);

    case S2_clrbit_i: {
      RegisterCell RC = rc(1);
      RC[im(2)] = BT::BitValue::Zero;
      return rr0(RC, Outputs);
    }
    case S2_setbit_i: {
      RegisterCell RC = rc(1);
      RC[im(2)] = BT::BitValue::One;
      return rr0(RC, Outputs);
    }
    case S2_togglebit_i: {
      RegisterCell RC = rc(1);
      uint16_t BX = im(2);
      RC[BX] = RC[BX].is(0) ? BT::BitValue::One
                            : RC[BX].is(1) ? BT::BitValue::Zero
                                           : BT::BitValue::self();
      return rr0(RC, Outputs);
    }

    case A4_bitspliti: {
      uint16_t W1 = getRegBitWidth(Reg[1]);
      uint16_t BX = im(2);
      // Res.uw[1] = Rs[bx+1:], Res.uw[0] = Rs[0:bx]
      const BT::BitValue Zero = BT::BitValue::Zero;
      RegisterCell RZ = RegisterCell(W0).fill(BX, W1, Zero)
                                        .fill(W1+(W1-BX), W0, Zero);
      RegisterCell BF1 = eXTR(rc(1), 0, BX), BF2 = eXTR(rc(1), BX, W1);
      RegisterCell RC = eINS(eINS(RZ, BF1, 0), BF2, W1);
      return rr0(RC, Outputs);
    }
    case S4_extract:
    case S4_extractp:
    case S2_extractu:
    case S2_extractup: {
      uint16_t Wd = im(2), Of = im(3);
      assert(Wd <= W0);
      if (Wd == 0)
        return rr0(eIMM(0, W0), Outputs);
      // If the width extends beyond the register size, pad the register
      // with 0 bits.
      RegisterCell Pad = (Wd+Of > W0) ? rc(1).cat(eIMM(0, Wd+Of-W0)) : rc(1);
      RegisterCell Ext = eXTR(Pad, Of, Wd+Of);
      // Ext is short, need to extend it with 0s or sign bit.
      RegisterCell RC = RegisterCell(W0).insert(Ext, BT::BitMask(0, Wd-1));
      if (Opc == S2_extractu || Opc == S2_extractup)
        return rr0(eZXT(RC, Wd), Outputs);
      return rr0(eSXT(RC, Wd), Outputs);
    }
    case S2_insert:
    case S2_insertp: {
      uint16_t Wd = im(3), Of = im(4);
      assert(Wd < W0 && Of < W0);
      // If Wd+Of exceeds W0, the inserted bits are truncated.
      if (Wd+Of > W0)
        Wd = W0-Of;
      if (Wd == 0)
        return rr0(rc(1), Outputs);
      return rr0(eINS(rc(1), eXTR(rc(2), 0, Wd), Of), Outputs);
    }

    // Bit permutations:

    case A2_combineii:
    case A4_combineii:
    case A4_combineir:
    case A4_combineri:
    case A2_combinew:
    case V6_vcombine:
      assert(W0 % 2 == 0);
      return rr0(cop(2, W0/2).cat(cop(1, W0/2)), Outputs);
    case A2_combine_ll:
    case A2_combine_lh:
    case A2_combine_hl:
    case A2_combine_hh: {
      assert(W0 == 32);
      assert(getRegBitWidth(Reg[1]) == 32 && getRegBitWidth(Reg[2]) == 32);
      // Low half in the output is 0 for _ll and _hl, 1 otherwise:
      unsigned LoH = !(Opc == A2_combine_ll || Opc == A2_combine_hl);
      // High half in the output is 0 for _ll and _lh, 1 otherwise:
      unsigned HiH = !(Opc == A2_combine_ll || Opc == A2_combine_lh);
      RegisterCell R1 = rc(1);
      RegisterCell R2 = rc(2);
      RegisterCell RC = half(R2, LoH).cat(half(R1, HiH));
      return rr0(RC, Outputs);
    }
    case S2_packhl: {
      assert(W0 == 64);
      assert(getRegBitWidth(Reg[1]) == 32 && getRegBitWidth(Reg[2]) == 32);
      RegisterCell R1 = rc(1);
      RegisterCell R2 = rc(2);
      RegisterCell RC = half(R2, 0).cat(half(R1, 0)).cat(half(R2, 1))
                                   .cat(half(R1, 1));
      return rr0(RC, Outputs);
    }
    case S2_shuffeb: {
      RegisterCell RC = shuffle(rc(1), rc(2), 8, false);
      return rr0(RC, Outputs);
    }
    case S2_shuffeh: {
      RegisterCell RC = shuffle(rc(1), rc(2), 16, false);
      return rr0(RC, Outputs);
    }
    case S2_shuffob: {
      RegisterCell RC = shuffle(rc(1), rc(2), 8, true);
      return rr0(RC, Outputs);
    }
    case S2_shuffoh: {
      RegisterCell RC = shuffle(rc(1), rc(2), 16, true);
      return rr0(RC, Outputs);
    }
    case C2_mask: {
      uint16_t WR = W0;
      uint16_t WP = 8; // XXX Pred size: getRegBitWidth(Reg[1]);
      assert(WR == 64 && WP == 8);
      RegisterCell R1 = rc(1);
      RegisterCell RC(WR);
      for (uint16_t i = 0; i < WP; ++i) {
        const BT::BitValue &V = R1[i];
        BT::BitValue F = (V.is(0) || V.is(1)) ? V : BT::BitValue::self();
        RC.fill(i*8, i*8+8, F);
      }
      return rr0(RC, Outputs);
    }

    // Mux:

    case C2_muxii:
    case C2_muxir:
    case C2_muxri:
    case C2_mux: {
      BT::BitValue PC0 = rc(1)[0];
      RegisterCell R2 = cop(2, W0);
      RegisterCell R3 = cop(3, W0);
      if (PC0.is(0) || PC0.is(1))
        return rr0(RegisterCell::ref(PC0 ? R2 : R3), Outputs);
      R2.meet(R3, Reg[0].Reg);
      return rr0(R2, Outputs);
    }
    case C2_vmux:
      // TODO
      break;

    // Sign- and zero-extension:

    case A2_sxtb:
      return rr0(eSXT(rc(1), 8), Outputs);
    case A2_sxth:
      return rr0(eSXT(rc(1), 16), Outputs);
    case A2_sxtw: {
      uint16_t W1 = getRegBitWidth(Reg[1]);
      assert(W0 == 64 && W1 == 32);
      RegisterCell RC = eSXT(rc(1).cat(eIMM(0, W1)), W1);
      return rr0(RC, Outputs);
    }
    case A2_zxtb:
      return rr0(eZXT(rc(1), 8), Outputs);
    case A2_zxth:
      return rr0(eZXT(rc(1), 16), Outputs);

    // Saturations

    case A2_satb:
      return rr0(eSXT(RegisterCell::self(0, W0).regify(Reg0), 8), Outputs);
    case A2_sath:
      return rr0(eSXT(RegisterCell::self(0, W0).regify(Reg0), 16), Outputs);
    case A2_satub:
      return rr0(eZXT(RegisterCell::self(0, W0).regify(Reg0), 8), Outputs);
    case A2_satuh:
      return rr0(eZXT(RegisterCell::self(0, W0).regify(Reg0), 16), Outputs);

    // Bit count:

    case S2_cl0:
    case S2_cl0p:
      // Always produce a 32-bit result.
      return rr0(eCLB(rc(1), false/*bit*/, 32), Outputs);
    case S2_cl1:
    case S2_cl1p:
      return rr0(eCLB(rc(1), true/*bit*/, 32), Outputs);
    case S2_clb:
    case S2_clbp: {
      uint16_t W1 = getRegBitWidth(Reg[1]);
      RegisterCell R1 = rc(1);
      BT::BitValue TV = R1[W1-1];
      if (TV.is(0) || TV.is(1))
        return rr0(eCLB(R1, TV, 32), Outputs);
      break;
    }
    case S2_ct0:
    case S2_ct0p:
      return rr0(eCTB(rc(1), false/*bit*/, 32), Outputs);
    case S2_ct1:
    case S2_ct1p:
      return rr0(eCTB(rc(1), true/*bit*/, 32), Outputs);
    case S5_popcountp:
      // TODO
      break;

    case C2_all8: {
      RegisterCell P1 = rc(1);
      bool Has0 = false, All1 = true;
      for (uint16_t i = 0; i < 8/*XXX*/; ++i) {
        if (!P1[i].is(1))
          All1 = false;
        if (!P1[i].is(0))
          continue;
        Has0 = true;
        break;
      }
      if (!Has0 && !All1)
        break;
      RegisterCell RC(W0);
      RC.fill(0, W0, (All1 ? BT::BitValue::One : BT::BitValue::Zero));
      return rr0(RC, Outputs);
    }
    case C2_any8: {
      RegisterCell P1 = rc(1);
      bool Has1 = false, All0 = true;
      for (uint16_t i = 0; i < 8/*XXX*/; ++i) {
        if (!P1[i].is(0))
          All0 = false;
        if (!P1[i].is(1))
          continue;
        Has1 = true;
        break;
      }
      if (!Has1 && !All0)
        break;
      RegisterCell RC(W0);
      RC.fill(0, W0, (Has1 ? BT::BitValue::One : BT::BitValue::Zero));
      return rr0(RC, Outputs);
    }
    case C2_and:
      return rr0(eAND(rc(1), rc(2)), Outputs);
    case C2_andn:
      return rr0(eAND(rc(1), eNOT(rc(2))), Outputs);
    case C2_not:
      return rr0(eNOT(rc(1)), Outputs);
    case C2_or:
      return rr0(eORL(rc(1), rc(2)), Outputs);
    case C2_orn:
      return rr0(eORL(rc(1), eNOT(rc(2))), Outputs);
    case C2_xor:
      return rr0(eXOR(rc(1), rc(2)), Outputs);
    case C4_and_and:
      return rr0(eAND(rc(1), eAND(rc(2), rc(3))), Outputs);
    case C4_and_andn:
      return rr0(eAND(rc(1), eAND(rc(2), eNOT(rc(3)))), Outputs);
    case C4_and_or:
      return rr0(eAND(rc(1), eORL(rc(2), rc(3))), Outputs);
    case C4_and_orn:
      return rr0(eAND(rc(1), eORL(rc(2), eNOT(rc(3)))), Outputs);
    case C4_or_and:
      return rr0(eORL(rc(1), eAND(rc(2), rc(3))), Outputs);
    case C4_or_andn:
      return rr0(eORL(rc(1), eAND(rc(2), eNOT(rc(3)))), Outputs);
    case C4_or_or:
      return rr0(eORL(rc(1), eORL(rc(2), rc(3))), Outputs);
    case C4_or_orn:
      return rr0(eORL(rc(1), eORL(rc(2), eNOT(rc(3)))), Outputs);
    case C2_bitsclr:
    case C2_bitsclri:
    case C2_bitsset:
    case C4_nbitsclr:
    case C4_nbitsclri:
    case C4_nbitsset:
      // TODO
      break;
    case S2_tstbit_i:
    case S4_ntstbit_i: {
      BT::BitValue V = rc(1)[im(2)];
      if (V.is(0) || V.is(1)) {
        // If instruction is S2_tstbit_i, test for 1, otherwise test for 0.
        bool TV = (Opc == S2_tstbit_i);
        BT::BitValue F = V.is(TV) ? BT::BitValue::One : BT::BitValue::Zero;
        return rr0(RegisterCell(W0).fill(0, W0, F), Outputs);
      }
      break;
    }

    default:
      return MachineEvaluator::evaluate(MI, Inputs, Outputs);
  }
  #undef im
  #undef rc
  #undef op
  return false;
}

bool HexagonEvaluator::evaluate(const MachineInstr &BI,
                                const CellMapType &Inputs,
                                BranchTargetList &Targets,
                                bool &FallsThru) const {
  // We need to evaluate one branch at a time. TII::analyzeBranch checks
  // all the branches in a basic block at once, so we cannot use it.
  unsigned Opc = BI.getOpcode();
  bool SimpleBranch = false;
  bool Negated = false;
  switch (Opc) {
    case Hexagon::J2_jumpf:
    case Hexagon::J2_jumpfpt:
    case Hexagon::J2_jumpfnew:
    case Hexagon::J2_jumpfnewpt:
      Negated = true;
      LLVM_FALLTHROUGH;
    case Hexagon::J2_jumpt:
    case Hexagon::J2_jumptpt:
    case Hexagon::J2_jumptnew:
    case Hexagon::J2_jumptnewpt:
      // Simple branch:  if([!]Pn) jump ...
      // i.e. Op0 = predicate, Op1 = branch target.
      SimpleBranch = true;
      break;
    case Hexagon::J2_jump:
      Targets.insert(BI.getOperand(0).getMBB());
      FallsThru = false;
      return true;
    default:
      // If the branch is of unknown type, assume that all successors are
      // executable.
      return false;
  }

  if (!SimpleBranch)
    return false;

  // BI is a conditional branch if we got here.
  RegisterRef PR = BI.getOperand(0);
  RegisterCell PC = getCell(PR, Inputs);
  const BT::BitValue &Test = PC[0];

  // If the condition is neither true nor false, then it's unknown.
  if (!Test.is(0) && !Test.is(1))
    return false;

  // "Test.is(!Negated)" means "branch condition is true".
  if (!Test.is(!Negated)) {
    // Condition known to be false.
    FallsThru = true;
    return true;
  }

  Targets.insert(BI.getOperand(1).getMBB());
  FallsThru = false;
  return true;
}

bool HexagonEvaluator::evaluateLoad(const MachineInstr &MI,
                                    const CellMapType &Inputs,
                                    CellMapType &Outputs) const {
  using namespace Hexagon;

  if (TII.isPredicated(MI))
    return false;
  assert(MI.mayLoad() && "A load that mayn't?");
  unsigned Opc = MI.getOpcode();

  uint16_t BitNum;
  bool SignEx;

  switch (Opc) {
    default:
      return false;

#if 0
    // memb_fifo
    case L2_loadalignb_pbr:
    case L2_loadalignb_pcr:
    case L2_loadalignb_pi:
    // memh_fifo
    case L2_loadalignh_pbr:
    case L2_loadalignh_pcr:
    case L2_loadalignh_pi:
    // membh
    case L2_loadbsw2_pbr:
    case L2_loadbsw2_pci:
    case L2_loadbsw2_pcr:
    case L2_loadbsw2_pi:
    case L2_loadbsw4_pbr:
    case L2_loadbsw4_pci:
    case L2_loadbsw4_pcr:
    case L2_loadbsw4_pi:
    // memubh
    case L2_loadbzw2_pbr:
    case L2_loadbzw2_pci:
    case L2_loadbzw2_pcr:
    case L2_loadbzw2_pi:
    case L2_loadbzw4_pbr:
    case L2_loadbzw4_pci:
    case L2_loadbzw4_pcr:
    case L2_loadbzw4_pi:
#endif

    case L2_loadrbgp:
    case L2_loadrb_io:
    case L2_loadrb_pbr:
    case L2_loadrb_pci:
    case L2_loadrb_pcr:
    case L2_loadrb_pi:
    case PS_loadrbabs:
    case L4_loadrb_ap:
    case L4_loadrb_rr:
    case L4_loadrb_ur:
      BitNum = 8;
      SignEx = true;
      break;

    case L2_loadrubgp:
    case L2_loadrub_io:
    case L2_loadrub_pbr:
    case L2_loadrub_pci:
    case L2_loadrub_pcr:
    case L2_loadrub_pi:
    case PS_loadrubabs:
    case L4_loadrub_ap:
    case L4_loadrub_rr:
    case L4_loadrub_ur:
      BitNum = 8;
      SignEx = false;
      break;

    case L2_loadrhgp:
    case L2_loadrh_io:
    case L2_loadrh_pbr:
    case L2_loadrh_pci:
    case L2_loadrh_pcr:
    case L2_loadrh_pi:
    case PS_loadrhabs:
    case L4_loadrh_ap:
    case L4_loadrh_rr:
    case L4_loadrh_ur:
      BitNum = 16;
      SignEx = true;
      break;

    case L2_loadruhgp:
    case L2_loadruh_io:
    case L2_loadruh_pbr:
    case L2_loadruh_pci:
    case L2_loadruh_pcr:
    case L2_loadruh_pi:
    case L4_loadruh_rr:
    case PS_loadruhabs:
    case L4_loadruh_ap:
    case L4_loadruh_ur:
      BitNum = 16;
      SignEx = false;
      break;

    case L2_loadrigp:
    case L2_loadri_io:
    case L2_loadri_pbr:
    case L2_loadri_pci:
    case L2_loadri_pcr:
    case L2_loadri_pi:
    case L2_loadw_locked:
    case PS_loadriabs:
    case L4_loadri_ap:
    case L4_loadri_rr:
    case L4_loadri_ur:
    case LDriw_pred:
      BitNum = 32;
      SignEx = true;
      break;

    case L2_loadrdgp:
    case L2_loadrd_io:
    case L2_loadrd_pbr:
    case L2_loadrd_pci:
    case L2_loadrd_pcr:
    case L2_loadrd_pi:
    case L4_loadd_locked:
    case PS_loadrdabs:
    case L4_loadrd_ap:
    case L4_loadrd_rr:
    case L4_loadrd_ur:
      BitNum = 64;
      SignEx = true;
      break;
  }

  const MachineOperand &MD = MI.getOperand(0);
  assert(MD.isReg() && MD.isDef());
  RegisterRef RD = MD;

  uint16_t W = getRegBitWidth(RD);
  assert(W >= BitNum && BitNum > 0);
  RegisterCell Res(W);

  for (uint16_t i = 0; i < BitNum; ++i)
    Res[i] = BT::BitValue::self(BT::BitRef(RD.Reg, i));

  if (SignEx) {
    const BT::BitValue &Sign = Res[BitNum-1];
    for (uint16_t i = BitNum; i < W; ++i)
      Res[i] = BT::BitValue::ref(Sign);
  } else {
    for (uint16_t i = BitNum; i < W; ++i)
      Res[i] = BT::BitValue::Zero;
  }

  putCell(RD, Res, Outputs);
  return true;
}

bool HexagonEvaluator::evaluateFormalCopy(const MachineInstr &MI,
                                          const CellMapType &Inputs,
                                          CellMapType &Outputs) const {
  // If MI defines a formal parameter, but is not a copy (loads are handled
  // in evaluateLoad), then it's not clear what to do.
  assert(MI.isCopy());

  RegisterRef RD = MI.getOperand(0);
  RegisterRef RS = MI.getOperand(1);
  assert(RD.Sub == 0);
  if (!TargetRegisterInfo::isPhysicalRegister(RS.Reg))
    return false;
  RegExtMap::const_iterator F = VRX.find(RD.Reg);
  if (F == VRX.end())
    return false;

  uint16_t EW = F->second.Width;
  // Store RD's cell into the map. This will associate the cell with a virtual
  // register, and make zero-/sign-extends possible (otherwise we would be ex-
  // tending "self" bit values, which will have no effect, since "self" values
  // cannot be references to anything).
  putCell(RD, getCell(RS, Inputs), Outputs);

  RegisterCell Res;
  // Read RD's cell from the outputs instead of RS's cell from the inputs:
  if (F->second.Type == ExtType::SExt)
    Res = eSXT(getCell(RD, Outputs), EW);
  else if (F->second.Type == ExtType::ZExt)
    Res = eZXT(getCell(RD, Outputs), EW);

  putCell(RD, Res, Outputs);
  return true;
}

unsigned HexagonEvaluator::getNextPhysReg(unsigned PReg, unsigned Width) const {
  using namespace Hexagon;

  bool Is64 = DoubleRegsRegClass.contains(PReg);
  assert(PReg == 0 || Is64 || IntRegsRegClass.contains(PReg));

  static const unsigned Phys32[] = { R0, R1, R2, R3, R4, R5 };
  static const unsigned Phys64[] = { D0, D1, D2 };
  const unsigned Num32 = sizeof(Phys32)/sizeof(unsigned);
  const unsigned Num64 = sizeof(Phys64)/sizeof(unsigned);

  // Return the first parameter register of the required width.
  if (PReg == 0)
    return (Width <= 32) ? Phys32[0] : Phys64[0];

  // Set Idx32, Idx64 in such a way that Idx+1 would give the index of the
  // next register.
  unsigned Idx32 = 0, Idx64 = 0;
  if (!Is64) {
    while (Idx32 < Num32) {
      if (Phys32[Idx32] == PReg)
        break;
      Idx32++;
    }
    Idx64 = Idx32/2;
  } else {
    while (Idx64 < Num64) {
      if (Phys64[Idx64] == PReg)
        break;
      Idx64++;
    }
    Idx32 = Idx64*2+1;
  }

  if (Width <= 32)
    return (Idx32+1 < Num32) ? Phys32[Idx32+1] : 0;
  return (Idx64+1 < Num64) ? Phys64[Idx64+1] : 0;
}

unsigned HexagonEvaluator::getVirtRegFor(unsigned PReg) const {
  for (std::pair<unsigned,unsigned> P : MRI.liveins())
    if (P.first == PReg)
      return P.second;
  return 0;
}
